diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index b16ef0b..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true, - "node": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "rules": { - "indent": [ - "error", - 4, - { "SwitchCase": 1 } - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ], - "no-console": [ - "error", - { "allow": ["info", "error"] } - ], - "spaced-comment": [ - "error", - "always" - ] - } -} diff --git a/.gitignore b/.gitignore index 1acd131..7ad2a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/client.js -/server.js /node_modules +/dist +go.test diff --git a/Makefile b/Makefile index 06c54c1..9d2761c 100644 --- a/Makefile +++ b/Makefile @@ -4,30 +4,50 @@ # Install dependencies install: npm install + go get all -# Launch watch +# Update dependencies +update: + npm update + go get -u all + +# Launch client dev server +start: + npm run start + +# Launch client watcher watch: - npx webpack --watch --mode=development + npm run watch # Build lib build: - npx webpack --mode=production + npm run build -# Launch demo client -demo-client: - php -S 0.0.0.0:8000 -t . +# Launch NodeJS demo server +server-node: + node ./demo/server.js 8002 -# Launch demo server -demo-server: - node ./demo-server.js 8002 +## Launch Golang demo server +server-go: + go run demo/server.go # Lint and code style fix -lint: - npx eslint src/* --ext .js,.json --fix +lint: lint-js lint-go + +lint-js: + npm run lint + +lint-go: + gofmt -s -w . # Test -test: build - npx mocha +test: test-js test-go + +test-js: + npm run test + +test-go: + go test ./go/... # Publish package publish: build diff --git a/README.md b/README.md index f48bc8a..e7527fe 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,11 @@ Features: - ⚡️ Handle the binary encoding and decoding of your data, with performances in mind. - 📢 Listen for event dispatched over websocket with simple `on`/`off` event emitter system. - 💬 Fallback to JSON for easy debugging. +- 🌟 **NEW**: [experimental Golang port available](doc/go.md) ## Requirements -- Node >= v8.0.0 +- Node >= v24.0.0 ## Installation @@ -26,11 +27,10 @@ An event is defined by its _unique_ name and the corresponding codec, responsibl ```javascript // events.js -import Int8Codec from 'netcode/src/encoder/codec/Int8Codec'; -import StringCodec from 'netcode/src/encoder/codec/StringCodec'; +import { UInt8Codec, StringCodec } from 'netcode/encoder'; export default [ - ['id', new Int8Codec()], + ['id', new UInt8Codec()], ['say', new StringCodec()], ]; ``` @@ -53,8 +53,7 @@ We setup a server specifying the port and host on which the server will listen a Here we use a BinaryEncoder to communicate in binary over websocket, with the previously configured event list. ```javascript -import Server from 'netcode/src/server/Server'; -import BinaryEncoder from 'netcode/src/encoder/BinaryEncoder'; +import { Server, BinaryEncoder } from 'netcode/server'; import events from './events'; // Listen on localhost:8080 @@ -68,15 +67,14 @@ server.on('client:join', client => { Now we've got a server running at `localhost:8080` that listen for a `say` text event and send a `id` integer event to every client that connects. -_See an [full example of server setup](demo-server.js)._ +_See an [full example of server setup](demo/server.js)._ ### Write a Client Now we write a client, for the browser, that connects to our running server on `ws://localhost:8080` and use a BinaryEncoder with the same event list as the server. ```javascript -import Client from 'netcode/src/client/Client'; -import BinaryEncoder from 'netcode/src/encoder/BinaryEncoder'; +import { Client, BinaryEncoder } from 'netcode/client'; import events from './events'; const client = new Client('ws://localhost:8080', new BinaryEncoder(events)) @@ -91,7 +89,7 @@ Now we've got client that listen for the `id` event and sent a sentence in a `sa Connection is alive and well! -_See an [full example of client setup](demo-client.js)._ +_See an [full example of client setup](demo/client.js)._ ## Complete documentation diff --git a/demo-client.js b/demo-client.js deleted file mode 100644 index d5a2dd4..0000000 --- a/demo-client.js +++ /dev/null @@ -1,63 +0,0 @@ -window.addEventListener('load', () => { - const { Client, BinaryEncoder, Codec, Int8Codec, Int16Codec, LongIntCodec, BooleanCodec, StringCodec } = netcode; - - // Register your events - const encoder = new BinaryEncoder([ - ['id', new Int16Codec()], - ['ping', new LongIntCodec(6)], - ['pong', new LongIntCodec(6)], - ['inverse', new BooleanCodec()], - ['greeting', new StringCodec()], - ['total', new Int8Codec()], - ]); - - // Create the client - const client = new Client('ws://127.0.0.1:8002', encoder); - let ping; - - // Listen for a "pong" event - client.on('pong', ({ detail: pong }) => { - console.info('pong: %s ms', pong - ping); - }); - - // Listen for an "id" event - client.on('id', ({ detail: id }) => { - console.log('connected with id %s', id); - ping = Date.now(); - - // Send a "ping" event - client.send('ping', ping); - }); - - // Listen for a "total" event - client.on('total', ({ detail: total }) => { - console.log(`There is ${total} people connected.`) - }); - - // Listen for an "inverse" event - client.on('inverse', ({ detail: status }) => { - // Answer with an "inverse" event - client.send('inverse', !status); - console.log('Inverse received: %s', status); - - // Send a "greeting" event - client.send('greeting', 'Hello, I\'m client 😊!'); - }); - - // Listen for a "greeting" event - client.on('greeting', ({ detail: message }) => { - console.log('Servers geets you: "%s"', message); - }); - - // Listen for oppening connection - client.on('open', () => { - console.info('Connection open.'); - - setTimeout(() => client.close(), 20 * 1000); - }); - - // Listen for connection close - client.on('close', () => { - console.info('Connection closed.'); - }); -}); diff --git a/demo-server.js b/demo-server.js deleted file mode 100644 index 36aeec4..0000000 --- a/demo-server.js +++ /dev/null @@ -1,62 +0,0 @@ -const { Server, BinaryEncoder, Codec, Int8Codec, Int16Codec, LongIntCodec, BooleanCodec, StringCodec } = require('./server'); - -// Register your events -const encoder = new BinaryEncoder([ - ['id', new Int16Codec()], - ['ping', new LongIntCodec(6)], - ['pong', new LongIntCodec(6)], - ['inverse', new BooleanCodec()], - ['greeting', new StringCodec()], - ['total', new Int8Codec()], -]); - -// Create the server -const port = process.argv[2]; -const server = new Server(port, '127.0.0.1', encoder, 3); - -// Listen for new clients -server.on('client:join', client => { - console.log('Client %s joined.', client.id); - - // Listen for "ping" event - client.on('ping', ping => { - // Answer with a "pong" event - client.send('pong', Date.now()); - console.log('Client %s ping received: %s.', client.id, ping); - - // Send a "inverse" event - client.send('inverse', true); - }); - - // Listen for "inverse" event - client.on('inverse', status => { - console.log('Client %s inverse received: %s.', client.id, status); - }); - - // Listen for "greeting" event - client.on('greeting', message => { - console.log('Client %s geets you: "%s"', client.id, message); - // Send a "greeting" event - client.send('greeting', 'Hello, I\'m server 😊!'); - }); - - // Send event "id" to the client - client.send('id', client.id); - - broadcastTotal(); -}); - -// Listen for disconnecting clients -server.on('client:leave', client => { - console.log('Client %s left.', client.id); - broadcastTotal(); -}); - -server.on('ready', () => console.log('Listening on port %s', port)); - -function broadcastTotal() { - const { length } = server.clients; - server.clients.forEach(client => client.send('total', length)); -} - -module.exports = server; diff --git a/demo/client.js b/demo/client.js new file mode 100644 index 0000000..3e114cf --- /dev/null +++ b/demo/client.js @@ -0,0 +1,86 @@ +import { Client, BinaryEncoder, UInt8Codec, UIntLongCodec, Int16Codec, BooleanCodec, StringLongCodec } from 'netcode/client'; + +window.addEventListener('load', () => { + const target = document.getElementById('output'); + const { info } = console; + + console.info = (message, ...subst) => { + info(message, ...subst); + subst.forEach(sub => message = message.replace('%s', sub)); + const time = Date.now() - start; + output.innerText += `▸ ${time}ms | ${message}\n`; + } + + // Register your events + const encoder = new BinaryEncoder([ + ['id', new UInt8Codec()], + ['ping', new UIntLongCodec(6)], + ['pong', new UIntLongCodec(6)], + ['inverse', new BooleanCodec()], + ['greeting', new StringLongCodec()], + ['total', new UInt8Codec()], + ['int16', new Int16Codec()], + ]); + + + const server = 'ws://127.0.0.1:8002'; + const start = Date.now(); + console.info('Connecting to %s', server) + + // Create the client + const client = new Client(server, encoder); + let ping; + + // Listen for a "pong" event + client.on('pong', ({ detail: pong }) => { + console.info('pong: %s ms (%s - %s)', pong - ping, pong, ping); + }); + + // Listen for an "id" event + client.on('id', ({ detail: id }) => { + console.info('connected with id %s', id); + ping = Date.now(); + + console.info('sending ping: %s', ping); + + // Send a "ping" event + client.send('ping', ping); + }); + + // Listen for a "total" event + client.on('total', ({ detail: total }) => { + console.info(`There is ${total} people connected.`); + }); + + // Listen for a "int16" event + client.on('int16', ({ detail: value }) => { + console.info(`int16 codec: ${value}.`); + client.send('int16', -32768); + }); + + // Listen for an "inverse" event + client.on('inverse', ({ detail: status }) => { + // Answer with an "inverse" event + client.send('inverse', !status); + console.info('Inverse received: %s', status); + + // Send a "greeting" event + client.send('greeting', 'Hello, I\'m client 😊! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet molestie libero, ut sollicitudin tortor dignissim quis. Nulla iaculis nisi turpis, a malesuada nibh faucibus a. Nunc tellus lorem, varius sit amet tellus eu, dictum consectetur nulla.'); + }); + + // Listen for a "greeting" event + client.on('greeting', ({ detail: message }) => { + console.info('Servers geets you: "%s"', message); + }); + + // Listen for oppening connection + client.on('open', () => { + console.info('Connection open.'); + setTimeout(() => client.close(1000, 'All good :)'), 10 * 1000); + }); + + // Listen for connection close + client.on('close', (data) => { + console.info('Connection closed.', data); + }); +}); diff --git a/demo/server.go b/demo/server.go new file mode 100644 index 0000000..793b5f8 --- /dev/null +++ b/demo/server.go @@ -0,0 +1,108 @@ +package main + +import ( + "flag" + netcode "github.com/Tom32i/netcode/go" + "github.com/gorilla/websocket" + "log" + "math" + "net/http" + "time" +) + +type Demo struct { + sockets *netcode.Sockets +} + +func main() { + port := flag.Int("port", 8002, "Port to run on") + + flag.Parse() + + encoder := netcode.CreateBinaryEncoder([]*netcode.RegisteredCodec{ + {0, "id", netcode.UInt8Codec{}}, + {0, "ping", netcode.UIntLongCodec{6}}, + {0, "pong", netcode.UIntLongCodec{6}}, + {0, "inverse", netcode.BooleanCodec{}}, + {0, "greeting", netcode.StringLongCodec{}}, + {0, "total", netcode.UInt8Codec{}}, + {0, "int16", netcode.Int16Codec{}}, + }, netcode.UInt8Codec{}) + + d := Demo{ + netcode.CreateSockets(encoder, uint(math.Pow(2, 8))), + } + + go d.run() + + netcode.Start(*port, "/", d.SocketHandler, netcode.CheckOrigin, netcode.ErrorHandler) +} + +func (d *Demo) SocketHandler(w http.ResponseWriter, r *http.Request, c *websocket.Conn) { + socket, err := d.sockets.Add(c) + + if err != nil { + log.Fatal(err) + } + + netcode.CreateBeacon(socket, time.Second*3, func(ping time.Duration) { + log.Printf("Client #%d ping: %s.", socket.ID, ping) + }) + + d.onClientJoin(socket) +} + +func (d *Demo) run() { + log.Printf("Demo is running") + for { + select { + case m := <-d.sockets.In: + switch m.Message.Name { + case "ping": + d.handlePing(m.Socket, m.Message) + case "greeting": + d.handleGreeting(m.Socket, m.Message) + case "int16": + d.handleInt16(m.Socket, m.Message) + default: + log.Printf("[socket #%d] '%s': %v", m.Socket.ID, m.Message.Name, m.Message.Data) + } + case socket := <-d.sockets.Out: + d.onClientLeave(socket) + } + } +} + +func (d *Demo) broadcastTotal() { + d.sockets.SendAll( + &netcode.Message{"total", uint8(d.sockets.Count())}, + ) +} + +func (d *Demo) onClientJoin(s *netcode.Socket) { + log.Printf("Client #%d joined.", s.ID) + s.Send(&netcode.Message{"id", uint8(s.ID)}) + d.broadcastTotal() + + s.Send(&netcode.Message{"int16", int16(math.MaxInt16)}) +} + +func (d *Demo) onClientLeave(s *netcode.Socket) { + log.Printf("Client #%d left.", s.ID) + d.broadcastTotal() +} + +func (d *Demo) handlePing(s *netcode.Socket, m *netcode.Message) { + log.Printf("Client #%d ping: %d.", s.ID, m.Data.(uint)) + s.Send(&netcode.Message{"pong", uint(time.Now().UnixMilli())}) + s.Send(&netcode.Message{"inverse", true}) +} + +func (d *Demo) handleGreeting(s *netcode.Socket, m *netcode.Message) { + log.Printf("Client #%d greets you: '%s'.", s.ID, m.Data.(string)) + s.Send(&netcode.Message{"greeting", "Hello, I'm server! 😊 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet molestie libero, ut sollicitudin tortor dignissim quis. Nulla iaculis nisi turpis, a malesuada nibh faucibus a. Nunc tellus lorem, varius sit amet tellus eu, dictum consectetur nulla."}) +} + +func (d *Demo) handleInt16(s *netcode.Socket, m *netcode.Message) { + log.Printf("Client #%d sends int16: %d.", s.ID, m.Data.(int16)) +} diff --git a/demo/server.js b/demo/server.js new file mode 100644 index 0000000..5aae4a6 --- /dev/null +++ b/demo/server.js @@ -0,0 +1,79 @@ +import { + Server, + BinaryEncoder, + UInt8Codec, + UIntLongCodec, + Int16Codec, + BooleanCodec, + StringLongCodec, +} from 'netcode/server'; + +// Register your events +const encoder = new BinaryEncoder([ + ['id', new UInt8Codec()], + ['ping', new UIntLongCodec(6)], + ['pong', new UIntLongCodec(6)], + ['inverse', new BooleanCodec()], + ['greeting', new StringLongCodec()], + ['total', new UInt8Codec()], + ['int16', new Int16Codec()], +]); + +// Create the server +const port = process.argv[2] || 8002; +const server = new Server(port, '127.0.0.1', encoder, 3); + +// Listen for new clients +server.on('client:join', client => { + console.info('Client %s joined.', client.id); + + // Listen for "ping" event + client.on('ping', ping => { + // Answer with a "pong" event + client.send('pong', Date.now()); + console.info('Client %s ping received: %s.', client.id, ping); + + // Send a "inverse" event + client.send('inverse', true); + }); + + // Listen for "inverse" event + client.on('inverse', status => { + console.info('Client %s inverse received: %s.', client.id, status); + }); + + // Listen for "greeting" event + client.on('greeting', message => { + console.info('Client %s greets you: "%s"', client.id, message); + // Send a "greeting" event + client.send('greeting', 'Hello, I\'m server! 😊 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet molestie libero, ut sollicitudin tortor dignissim quis. Nulla iaculis nisi turpis, a malesuada nibh faucibus a. Nunc tellus lorem, varius sit amet tellus eu, dictum consectetur nulla.'); + }); + + // Listen for "int16" event + client.on('int16', message => { + console.info('Client %s sends int16: %s', client.id, message); + }); + + // Send event "id" to the client + client.send('id', client.id); + + broadcastTotal(); + + client.send('int16', 32767); +}); + +// Listen for disconnecting clients +server.on('client:leave', client => { + console.info('Client %s left.', client.id); + broadcastTotal(); +}); + +server.on('ping', ({ client }) => console.info('Client %s ping.', client.id)); +server.on('pong', ({ client, duration }) => console.info('Client %s ping: %sms', client.id, duration)); + +server.on('ready', () => console.info('Listening on port %s', port)); + +function broadcastTotal() { + const { length } = server.clients; + server.clients.forEach(client => client.send('total', length)); +} diff --git a/doc/API.md b/doc/API.md index ec01b30..3a4f050 100644 --- a/doc/API.md +++ b/doc/API.md @@ -9,9 +9,10 @@ The `Server` class takes the following arguments: | port | _Number_ | 8080 | Port to listen on. | | host | _String_ | 0.0.0.0 | Host to listen on. | | encoder | _BinaryEncoder \| JsonEncoder_ | new JsonEncoder() | Encoder to use to read/write event messages. | -| ping | _Number_ | 30 | Ping frequency in seconds (0 for no ping). | -| maxLength | _Number_ | 512 | Paquet max length in bit (should be a power of two). | -| protocols | _Array String[]_ | `['websocket']` | Protocols tu use | +| pingInterval | _Number_ | 30 | Ping frequency in seconds (0 for no ping). | +| maxPayload | _Number_ | 512 | Paquet max length in bit (should be a power of two). | +| clients | _ClientDirectory_ | `new MapClientDirectory()` | Client directory | +| autoStart | _Boolean_ | `true` | Should the server start listening immediatly? | ### Methods @@ -27,8 +28,6 @@ Listen for event. Remove listener for this event / callback. -_Note: If you're on node `< 10.0.0`, use `removeListener` method instead of `off`_ - ### Events | Name | Callback parameters | Description | @@ -76,4 +75,4 @@ _Note: If you're on node `< 10.0.0`, use `removeListener` method instead of `off | `close` | client _{Client_} | Client connection is closed. | | * | - eventData _{Number\|String\|Boolean\|Object}_
- client _Client_ | Every event sent through the websocket pipe will emit an event on the other end of the socket. | -_Note: `open`, `error` and `close` are reserved event names and the Encoder will throw an exeption if you define a custom event with either of these names._ \ No newline at end of file +_Note: `open`, `error` and `close` are reserved event names and the Encoder will throw an exeption if you define a custom event with either of these names._ diff --git a/doc/codecs.md b/doc/codecs.md index ea86bcc..cf1fe03 100644 --- a/doc/codecs.md +++ b/doc/codecs.md @@ -10,14 +10,20 @@ Packaged codecs are available in the `netcode/server` and `netcode/client` packa | Class | Data format | Example | Size (in byte) | | -------------------------- | ---------------------------------- | ------------------------------------------------------------ | ----------------------- | -| `Codec` | No data (just send the event name) | `['pause', new Codec()]`
`send('pause')` | 0 | -| `BooleanCodec` | `true\|false` | `['active', new BooleanCodec()]`
`send('active', true)` | 1 | +| `NullCodec` | No data (just send the event name) | `['pause', new NullCodec()]`
`send('pause')` | 0 | +| `BooleanCodec` | `true\|false` | `['active', new BooleanCodec()]`
`send('active', true)` | | +| `UInt8Codec` | Integer from 0 to 255 | `['id', new UInt8Codec()]`
`send('id', 42)` | 1 | +| `UInt16Codec` | Integer from 0 to 65536 | `['score', new UInt16Codec()]`
`send('score', 9999)` | 2 | +| `UInt32Codec` | Integer from 0 to 4294967295 | `['position', new UInt32Codec()]`
`send('position', 4294967295)` | 4 | +| `UIntLongCodec(byteLength)` | Integer encoded as string | `['timestamp', new UIntLongCodec(13)`]
`send('timestamp', Date.now())` | byteLength | +| `Int8Codec` | Integer from -128 to 127 | `['value', new Int8Codec()]`
`send('value', -42)` | 1 | +| `Int16Codec` | Integer from -32768 to 32767 | `['malus', new Int16Codec()]`
`send('malus', -999)` | 2 | +| `Int32Codec` | Integer from -2147483648 to 2147483647 | `['position', new Int32Codec()]`
`send('position', -123456)` | 4 |1 | +| `Float32Codec`
⚠ Subject to precision issues | Float on 32bit | `['position', new Float32Codec()]`
`send('position', 84.19999694824219)` | 4 | +| `Float64Codec` | Float on 64bit | `['position', new Float64Codec()]`
`send('position', -12456789.123456789087654321012345678901)` | 2 | +| `FloatPrecisionCodec(IntCodec, precision)` | Float encoded as int | `['position', FloatPrecisionCodec(Int8Codec, 3)]`
`send('position', -0.657)` | 2 | `StringCodec` | String up to 255 characters | `['player:name', new StringCodec()]`
`send('player:name', 'DarkShadow73')` | 1 + (String length * 2) | -| `LongStringCodec` | String up to 65536 characters | `['url', new LongStringCodec()]`
`send('url', 'https://my.long.url/hash/xxx...')` | 2 + (String length * 2) | -| `Int8Codec` | Integer from 0 to 255 | `['id', new Int8Codec()]`
`send('id', 42)` | 1 | -| `Int16Codec` | Integer from 0 to 65536 | `['score', new Int16Codec()]`
`send('score', 9999)` | 2 | -| `Int32Codec` | Integer from 0 to 4294967295 | `['position', new Int32Codec()]`
`send('position', 4294967295)` | 4 | -| `LongIntCodec(byteLength)` | Integer encoded as string | `['timestamp', new LongIntCodec(13)`]
`send('timestamp', Date.now())` | byteLength | +| `StringLongCodec` | String up to 65536 characters | `['url', new StringLongCodec()]`
`send('url', 'https://my.long.url/hash/xxx...')` | 2 + (String length * 2) | ## Custom codecs @@ -45,14 +51,14 @@ So the byte length of my event is fixed: 1 + 2 + 2 = 5 bytes. Full working example using composition: ```javascript -import { Codec, Int8Codec, Int16Codec } from 'netcode/src/encoder/codec'; +import { Codec, UInt8Codec, UInt16Codec } from 'netcode/src/encoder/codec'; export default class PositionCodec extends Codec { constructor() { super(); - this.int8Codec = new Int8Codec(); - this.int16Codec = new Int16Codec(); + this.int8Codec = new UInt8Codec(); + this.int16Codec = new UInt16Codec(); } /** diff --git a/doc/go.md b/doc/go.md new file mode 100644 index 0000000..08e9335 --- /dev/null +++ b/doc/go.md @@ -0,0 +1,18 @@ +# Go port + +Netcode server is also available in Golang. + +It's fully compatible with the netcode browser client. + +## Current features + +- [x] Server +- [x] Sockets (equivalent of Client / Client Directory) +- [x] Binary encoder +- [ ] Json encoder +- [x] Packaged codecs (compatible with javascript codec) +- [x] Beacon (ping at regular interval) + +## Notes + +Netcode in golang is relying on [github.com/gorilla/websocket](github.com/gorilla/websocket) for Websocket implementation. diff --git a/doc/packaging.md b/doc/packaging.md index 58e8e9e..afd98fc 100644 --- a/doc/packaging.md +++ b/doc/packaging.md @@ -13,7 +13,7 @@ On the server-side (node): const { Server, BinaryEncoder, - Int16Codec, + UInt16Codec, BooleanCodec, StringCodec, // ... @@ -25,12 +25,12 @@ And in the browser as well: ```html - + + ``` diff --git a/doc/webpack.config.js b/doc/webpack.config.js deleted file mode 100644 index 5ee6187..0000000 --- a/doc/webpack.config.js +++ /dev/null @@ -1,37 +0,0 @@ -const webpack = require('webpack'); - -const rules = [ - { - test: /\.js$/, - exclude: /node_modules/, - include: '/node_modules/netcode/src/', - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env'] - } - } - } -]; - -const clientConfig = { - target: 'web', - entry: './src/client.js', - output: { - filename: 'client.js', - path: `${__dirname}/dist/`, - }, - module: { rules } -}; - -const serverConfig = { - target: 'node', - entry: './src/server.js', - output: { - filename: 'server.js', - path: `${__dirname}/dist/server/`, - }, - module: { rules } -}; - -module.exports = [ serverConfig, clientConfig ]; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..c310f9d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,40 @@ +import globals from 'globals'; +import pluginJs from '@eslint/js'; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + {languageOptions: { globals: {...globals.browser, ...globals.node} }}, + pluginJs.configs.recommended, + { + rules: { + 'indent': [ + 'error', + 4, + { 'SwitchCase': 1 } + ], + 'linebreak-style': [ + 'error', + 'unix' + ], + 'quotes': [ + 'error', + 'single' + ], + 'semi': [ + 'error', + 'always' + ], + 'no-console': [ + 'error', + { 'allow': ['info', 'error'] } + ], + 'no-inline-comments': [ + 'error' + ], + 'spaced-comment': [ + 'error', + 'always' + ] + } + } +]; diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..69f263d --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/Tom32i/netcode + +go 1.22.4 + +require github.com/gorilla/websocket v1.5.3 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..25a9fc4 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= diff --git a/go/beacon.go b/go/beacon.go new file mode 100644 index 0000000..3f8e816 --- /dev/null +++ b/go/beacon.go @@ -0,0 +1,83 @@ +package netcode + +import ( + "strconv" + "sync" + "time" +) + +func CreateBeacon(socket *Socket, interval time.Duration, callback func(time.Duration)) *Beacon { + b := Beacon{ + socket: socket, + callback: callback, + interval: interval, + ticker: time.NewTicker(interval), + done: make(chan bool), + } + + b.ticker.Stop() + + socket.Conn.SetPongHandler(b.onPong) + + defer b.start() + + return &b +} + +type Beacon struct { + socket *Socket + callback func(time.Duration) + interval time.Duration + ticker *time.Ticker + done chan bool + ping time.Time + mu sync.RWMutex + running bool +} + +func (b *Beacon) start() { + if !b.running { + go b.run() + b.sendPing() + } +} + +func (b *Beacon) stop() { + if b.running { + b.done <- true + } +} + +func (b *Beacon) destroy() { + b.stop() + close(b.done) +} + +func (b *Beacon) run() { + defer b.ticker.Stop() + + b.ticker.Reset(b.interval) + + for { + select { + case <-b.done: + return + case <-b.ticker.C: + b.sendPing() + } + } +} + +func (b *Beacon) sendPing() { + b.socket.Ping(strconv.FormatInt(time.Now().UnixMicro(), 10)) +} + +func (b *Beacon) onPong(response string) error { + now := time.Now() + value, _ := strconv.ParseInt(response, 10, 64) + ping := time.UnixMicro(value) + + defer b.callback(now.Sub(ping)) + + return nil +} diff --git a/go/codec_boolean.go b/go/codec_boolean.go new file mode 100644 index 0000000..5bdceb3 --- /dev/null +++ b/go/codec_boolean.go @@ -0,0 +1,20 @@ +package netcode + +import ( + "bytes" +) + +type BooleanCodec struct { +} + +func (c BooleanCodec) Encode(buffer *bytes.Buffer, data any) { + if data.(bool) { + buffer.WriteByte(1) + } else { + buffer.WriteByte(0) + } +} + +func (c BooleanCodec) Decode(buffer *bytes.Buffer) any { + return buffer.Next(1)[0] > 0 +} diff --git a/go/codec_float32.go b/go/codec_float32.go new file mode 100644 index 0000000..9553566 --- /dev/null +++ b/go/codec_float32.go @@ -0,0 +1,18 @@ +package netcode + +import ( + "bytes" + "math" +) + +type Float32Codec struct { + codec UInt32Codec +} + +func (c Float32Codec) Encode(buffer *bytes.Buffer, data any) { + c.codec.Encode(buffer, math.Float32bits(data.(float32))) +} + +func (c Float32Codec) Decode(buffer *bytes.Buffer) any { + return math.Float32frombits(c.codec.Decode(buffer).(uint32)) +} diff --git a/go/codec_float64.go b/go/codec_float64.go new file mode 100644 index 0000000..e12603e --- /dev/null +++ b/go/codec_float64.go @@ -0,0 +1,18 @@ +package netcode + +import ( + "bytes" + "math" +) + +type Float64Codec struct { + codec UInt64Codec +} + +func (c Float64Codec) Encode(buffer *bytes.Buffer, data any) { + c.codec.Encode(buffer, math.Float64bits(data.(float64))) +} + +func (c Float64Codec) Decode(buffer *bytes.Buffer) any { + return math.Float64frombits(c.codec.Decode(buffer).(uint64)) +} diff --git a/go/codec_float_precision.go b/go/codec_float_precision.go new file mode 100644 index 0000000..75a65f7 --- /dev/null +++ b/go/codec_float_precision.go @@ -0,0 +1,24 @@ +package netcode + +import ( + "bytes" + "math" +) + +func CreateFloatPrecisionCodec[F float32 | float64, T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64](codec Codec, precision int) *FloatPrecisionCodec[F, T] { + return &FloatPrecisionCodec[F, T]{codec, F(math.Pow10(precision))} +} + +type FloatPrecisionCodec[F float32 | float64, T int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64] struct { + codec Codec + factor F +} + +func (c *FloatPrecisionCodec[F, T]) Encode(buffer *bytes.Buffer, data any) { + c.codec.Encode(buffer, T(c.factor*data.(F))) +} + +func (c *FloatPrecisionCodec[F, T]) Decode(buffer *bytes.Buffer) any { + value := c.codec.Decode(buffer).(T) + return F(value) / c.factor +} diff --git a/go/codec_int16.go b/go/codec_int16.go new file mode 100644 index 0000000..3a3d19a --- /dev/null +++ b/go/codec_int16.go @@ -0,0 +1,19 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +type Int16Codec struct { +} + +func (c Int16Codec) Encode(buffer *bytes.Buffer, data any) { + binary.Write(buffer, binary.BigEndian, data.(int16)) +} + +func (c Int16Codec) Decode(buffer *bytes.Buffer) any { + var data int16 + binary.Read(buffer, binary.BigEndian, &data) + return data +} diff --git a/go/codec_int32.go b/go/codec_int32.go new file mode 100644 index 0000000..75d3f97 --- /dev/null +++ b/go/codec_int32.go @@ -0,0 +1,19 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +type Int32Codec struct { +} + +func (c Int32Codec) Encode(buffer *bytes.Buffer, data any) { + binary.Write(buffer, binary.BigEndian, data.(int32)) +} + +func (c Int32Codec) Decode(buffer *bytes.Buffer) any { + var data int32 + binary.Read(buffer, binary.BigEndian, &data) + return data +} diff --git a/go/codec_int64.go b/go/codec_int64.go new file mode 100644 index 0000000..15ab839 --- /dev/null +++ b/go/codec_int64.go @@ -0,0 +1,16 @@ +package netcode + +import ( + "bytes" +) + +type Int64Codec struct { +} + +func (c Int64Codec) Encode(buffer *bytes.Buffer, data any) { + buffer.WriteByte(byte(data.(int64))) +} + +func (c Int64Codec) Decode(buffer *bytes.Buffer) any { + return int64(buffer.Next(1)[0]) +} diff --git a/go/codec_int8.go b/go/codec_int8.go new file mode 100644 index 0000000..90add4b --- /dev/null +++ b/go/codec_int8.go @@ -0,0 +1,16 @@ +package netcode + +import ( + "bytes" +) + +type Int8Codec struct { +} + +func (c Int8Codec) Encode(buffer *bytes.Buffer, data any) { + buffer.WriteByte(byte(data.(int8))) +} + +func (c Int8Codec) Decode(buffer *bytes.Buffer) any { + return int8(buffer.Next(1)[0]) +} diff --git a/go/codec_null.go b/go/codec_null.go new file mode 100644 index 0000000..3aef690 --- /dev/null +++ b/go/codec_null.go @@ -0,0 +1,15 @@ +package netcode + +import ( + "bytes" +) + +type NullCodec struct { +} + +func (c NullCodec) Encode(buffer *bytes.Buffer, data any) { +} + +func (c NullCodec) Decode(buffer *bytes.Buffer) any { + return nil +} diff --git a/go/codec_string.go b/go/codec_string.go new file mode 100644 index 0000000..cece506 --- /dev/null +++ b/go/codec_string.go @@ -0,0 +1,20 @@ +package netcode + +import ( + "bytes" +) + +type StringCodec struct { +} + +func (c StringCodec) Encode(buffer *bytes.Buffer, data any) { + length := len(data.(string)) + buffer.WriteByte(uint8(length)) + buffer.WriteString(data.(string)) +} + +func (c StringCodec) Decode(buffer *bytes.Buffer) any { + length := int(buffer.Next(1)[0]) + + return string(buffer.Next(length)) +} diff --git a/go/codec_string_long.go b/go/codec_string_long.go new file mode 100644 index 0000000..2937286 --- /dev/null +++ b/go/codec_string_long.go @@ -0,0 +1,25 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +type StringLongCodec struct { +} + +func (c StringLongCodec) Encode(buffer *bytes.Buffer, data any) { + length := len(data.(string)) + + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, uint16(length)) + buffer.Write(b) + + buffer.WriteString(data.(string)) +} + +func (c StringLongCodec) Decode(buffer *bytes.Buffer) any { + length := binary.BigEndian.Uint16(buffer.Next(2)) + + return string(buffer.Next(int(length))) +} diff --git a/go/codec_test.go b/go/codec_test.go new file mode 100644 index 0000000..3b72f01 --- /dev/null +++ b/go/codec_test.go @@ -0,0 +1,455 @@ +package netcode + +import ( + "bytes" + "math" + "testing" +) + +// Test BooleanCodec encode/decode. +func TestBooleanCodec(t *testing.T) { + var buffer bytes.Buffer + var want, got bool + codec := BooleanCodec{} + + want = false + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(bool) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = true + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(bool) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test Float32Codec encode/decode. +func TestFloat32Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got float32 + codec := Float32Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 1.123 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxFloat32 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test Float64Codec encode/decode. +func TestFloat64Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got float64 + codec := Float64Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 1.123 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = -12456789.123456789087654321012345678901 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxFloat64 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test FloatPrecisionCodec(Int8Codec, 2) encode/decode. +func TestFloatPrecisionCodecInt8(t *testing.T) { + var buffer bytes.Buffer + var want, got float32 + codec := CreateFloatPrecisionCodec[float32, int8](Int8Codec{}, 2) + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 0.99 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = -0.65 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 0.1 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 1.27 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = -1.28 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test FloatPrecisionCodec(UInt32Codec, 3) encode/decode. +func TestFloatPrecisionCodecUInt32Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got float64 + codec := CreateFloatPrecisionCodec[float64, uint32](UInt32Codec{}, 3) + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 4294967.295 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 123456.999 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 5.2 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(float64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test Int8Codec encode/decode. +func TestInt8Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got int8 + codec := Int8Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int8) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxInt8 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int8) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MinInt8 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int8) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test Int16Codec encode/decode. +func TestInt16Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got int16 + codec := Int16Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int16) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxInt16 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int16) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MinInt16 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int16) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test Int32Codec encode/decode. +func TestInt32Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got int32 + codec := Int32Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxInt32 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MinInt32 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(int32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test StringCodec encode/decode. +func TestStringCodec(t *testing.T) { + var buffer bytes.Buffer + var want, got string + codec := StringCodec{} + + want = "Hell0 wœrld$ 🌝 !" + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(string) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test StringLongCodec encode/decode. +func TestStringLongCodec(t *testing.T) { + var buffer bytes.Buffer + var want, got string + codec := StringLongCodec{} + + want = "data:image/jpeg;base64,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" + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(string) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test NullCodec encode/decode. +func TestNullCodec(t *testing.T) { + var buffer bytes.Buffer + var want, got any + codec := NullCodec{} + + want = nil + codec.Encode(&buffer, want) + got = codec.Decode(&buffer) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test UInt8Codec encode/decode. +func TestUInt8Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got uint8 + codec := UInt8Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint8) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxUint8 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint8) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test UInt16Codec encode/decode. +func TestUInt16Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got uint16 + codec := UInt16Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint16) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxUint16 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint16) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test UInt32Codec encode/decode. +func TestUInt32Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got uint32 + codec := UInt32Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxUint32 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint32) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test UInt64Codec encode/decode. +func TestUInt64Codec(t *testing.T) { + var buffer bytes.Buffer + var want, got uint64 + codec := UInt64Codec{} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = math.MaxUint64 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint64) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} + +// Test UIntLongCodec encode/decode. +func TestUIntLongCodec(t *testing.T) { + var buffer bytes.Buffer + var want, got uint + codec := UIntLongCodec{6} + + want = 0 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 127 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } + + want = 281474976710655 + codec.Encode(&buffer, want) + got = codec.Decode(&buffer).(uint) + + if got != want { + t.Fatalf(`Encode/Decode(%v) got %v, want %v`, want, got, want) + } +} diff --git a/go/codec_uint16.go b/go/codec_uint16.go new file mode 100644 index 0000000..71fdd79 --- /dev/null +++ b/go/codec_uint16.go @@ -0,0 +1,22 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +/** + * 16 bit unsigned Int codec (0 to 65535) + */ +type UInt16Codec struct { +} + +func (c UInt16Codec) Encode(buffer *bytes.Buffer, data any) { + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, data.(uint16)) + buffer.Write(b) +} + +func (c UInt16Codec) Decode(buffer *bytes.Buffer) any { + return binary.BigEndian.Uint16(buffer.Next(2)) +} diff --git a/go/codec_uint32.go b/go/codec_uint32.go new file mode 100644 index 0000000..c82ca94 --- /dev/null +++ b/go/codec_uint32.go @@ -0,0 +1,22 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +/** + * 16 bit unsigned Int codec (from 0 to 65535) + */ +type UInt32Codec struct { +} + +func (c UInt32Codec) Encode(buffer *bytes.Buffer, data any) { + b := make([]byte, 4) + binary.BigEndian.PutUint32(b, data.(uint32)) + buffer.Write(b) +} + +func (c UInt32Codec) Decode(buffer *bytes.Buffer) any { + return binary.BigEndian.Uint32(buffer.Next(4)) +} diff --git a/go/codec_uint64.go b/go/codec_uint64.go new file mode 100644 index 0000000..919ce6f --- /dev/null +++ b/go/codec_uint64.go @@ -0,0 +1,22 @@ +package netcode + +import ( + "bytes" + "encoding/binary" +) + +/* + * 64 bit unsigned Int codec (0 to 18446744073709551615) + */ +type UInt64Codec struct { +} + +func (c UInt64Codec) Encode(buffer *bytes.Buffer, data any) { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, data.(uint64)) + buffer.Write(b) +} + +func (c UInt64Codec) Decode(buffer *bytes.Buffer) any { + return binary.BigEndian.Uint64(buffer.Next(8)) +} diff --git a/go/codec_uint8.go b/go/codec_uint8.go new file mode 100644 index 0000000..e2377e1 --- /dev/null +++ b/go/codec_uint8.go @@ -0,0 +1,19 @@ +package netcode + +import ( + "bytes" +) + +/* + * 8 bit unsigned Int codec (0 to 255) + */ +type UInt8Codec struct { +} + +func (c UInt8Codec) Encode(buffer *bytes.Buffer, data any) { + buffer.WriteByte(data.(uint8)) +} + +func (c UInt8Codec) Decode(buffer *bytes.Buffer) any { + return buffer.Next(1)[0] +} diff --git a/go/codec_uint_long.go b/go/codec_uint_long.go new file mode 100644 index 0000000..f4b8d59 --- /dev/null +++ b/go/codec_uint_long.go @@ -0,0 +1,34 @@ +package netcode + +import ( + "bytes" + "fmt" + "strconv" +) + +type UIntLongCodec struct { + ByteLength int +} + +func (c UIntLongCodec) Encode(buffer *bytes.Buffer, data any) { + format := fmt.Sprintf("%%0%ds", c.ByteLength*8) + value := strconv.FormatUint(uint64(data.(uint)), 2) + value = fmt.Sprintf(format, value) + + for i := 0; i < c.ByteLength*8; i = i + 8 { + x, _ := strconv.ParseUint(value[i:i+8], 2, 8) + buffer.WriteByte(uint8(x)) + } +} + +func (c UIntLongCodec) Decode(buffer *bytes.Buffer) any { + var buf = new(bytes.Buffer) + parts := buffer.Next(c.ByteLength) + for _, x := range parts { + buf.WriteString(fmt.Sprintf("%08s", strconv.FormatUint(uint64(x), 2))) + } + + value, _ := strconv.ParseUint(buf.String(), 2, 64) + + return uint(value) +} diff --git a/go/encoder.go b/go/encoder.go new file mode 100644 index 0000000..9503148 --- /dev/null +++ b/go/encoder.go @@ -0,0 +1,75 @@ +package netcode + +import ( + "bytes" + "fmt" +) + +type BinaryEncoder struct { + idCodec Codec + codecsByName map[string]*RegisteredCodec + codecsById map[uint8]*RegisteredCodec +} + +type RegisteredCodec struct { + Id uint8 + Name string + Handler Codec +} + +type Codec interface { + Encode(buffer *bytes.Buffer, data any) + Decode(buffer *bytes.Buffer) any +} + +type Message struct { + Name string + Data any +} + +func CreateBinaryEncoder(codecs []*RegisteredCodec, idCodec Codec) *BinaryEncoder { + codecsByName := make(map[string]*RegisteredCodec) + codecsById := make(map[uint8]*RegisteredCodec) + + for id, codec := range codecs { + codec.Id = uint8(id) + codecsById[codec.Id] = codec + codecsByName[codec.Name] = codec + } + + return &BinaryEncoder{ + idCodec: idCodec, + codecsByName: codecsByName, + codecsById: codecsById, + } +} + +func (e BinaryEncoder) Encode(message *Message) ([]byte, error) { + var buffer bytes.Buffer + + codec, ok := e.codecsByName[message.Name] + + if !ok { + return buffer.Bytes(), fmt.Errorf(" %w: name \"%s\" could be not found", ErrCodecNotFound, message.Name) + } + + e.idCodec.Encode(&buffer, codec.Id) + codec.Handler.Encode(&buffer, message.Data) + + return buffer.Bytes(), nil +} + +func (e BinaryEncoder) Decode(data []byte) (*Message, error) { + var buffer = bytes.NewBuffer(data) + id := e.idCodec.Decode(buffer).(uint8) + codec, ok := e.codecsById[id] + + if !ok { + return nil, fmt.Errorf(" %w: id \"%d\" could be not found", ErrCodecNotFound, id) + } + + return &Message{ + Name: codec.Name, + Data: codec.Handler.Decode(buffer), + }, nil +} diff --git a/go/errors.go b/go/errors.go new file mode 100644 index 0000000..eedf380 --- /dev/null +++ b/go/errors.go @@ -0,0 +1,12 @@ +package netcode + +type ServerError string + +func (err ServerError) Error() string { + return string(err) +} + +const ( + ErrCodecNotFound = ServerError("codec not found") + ErrInternal = ServerError("internal error") +) diff --git a/go/server.go b/go/server.go new file mode 100644 index 0000000..9b8cfb8 --- /dev/null +++ b/go/server.go @@ -0,0 +1,40 @@ +package netcode + +import ( + "fmt" + "github.com/gorilla/websocket" + "log" + "net/http" +) + +func Start(port int, path string, onSocket func(w http.ResponseWriter, r *http.Request, c *websocket.Conn), checkOrigin func(r *http.Request) bool, errorHandler func(w http.ResponseWriter, r *http.Request, status int, reason error)) { + upgrader := &websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + Subprotocols: []string{"websocket"}, + Error: errorHandler, + CheckOrigin: checkOrigin, + } + + http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + s, err := upgrader.Upgrade(w, r, nil) + + if err == nil { + onSocket(w, r, s) + } + }) + + err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil) + + if err != nil { + log.Fatal(err) + } +} + +func CheckOrigin(r *http.Request) bool { + return true +} + +func ErrorHandler(w http.ResponseWriter, r *http.Request, status int, reason error) { + http.Error(w, reason.Error(), status) +} diff --git a/go/socket.go b/go/socket.go new file mode 100644 index 0000000..5af420b --- /dev/null +++ b/go/socket.go @@ -0,0 +1,79 @@ +package netcode + +import ( + "github.com/gorilla/websocket" + "log" + "sync" + "time" +) + +type Socket struct { + ID uint + In chan SocketMessage + Conn *websocket.Conn + Encoder *BinaryEncoder + mu sync.Mutex +} + +type SocketMessage struct { + Socket *Socket + Message *Message + Err error +} + +func (s *Socket) Send(message *Message) { + data, err := s.Encoder.Encode(message) + + if err == nil { + s.Write(data) + } +} + +func (s *Socket) Write(data []byte) { + s.mu.Lock() + defer s.mu.Unlock() + s.Conn.WriteMessage(websocket.BinaryMessage, data) +} + +func (s *Socket) Ping(message string) { + s.mu.Lock() + defer s.mu.Unlock() + s.Conn.WriteControl(websocket.PingMessage, []byte(message), time.Now().Add(time.Second*5)) +} + +func (s *Socket) Pong(message string) { + s.mu.Lock() + defer s.mu.Unlock() + s.Conn.WriteControl(websocket.PongMessage, []byte(message), time.Now().Add(time.Second*5)) +} + +func (s *Socket) Close(code int, message string) { + s.mu.Lock() + defer s.mu.Unlock() + s.Conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(code, message), time.Now().Add(time.Second*5)) +} + +func (s *Socket) Run(onClose func(*Socket)) { + defer func() { + s.Conn.Close() + onClose(s) + }() + + for { + _, data, err := s.Conn.ReadMessage() + + if err != nil { + if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure) { + log.Printf("Socket closed unexpectedly: %v", err) + } + return + } + + go s.Handle(data) + } +} + +func (s *Socket) Handle(data []byte) { + message, err := s.Encoder.Decode(data) + s.In <- SocketMessage{s, message, err} +} diff --git a/go/sockets.go b/go/sockets.go new file mode 100644 index 0000000..261b01c --- /dev/null +++ b/go/sockets.go @@ -0,0 +1,148 @@ +package netcode + +import ( + "errors" + "github.com/gorilla/websocket" + "log" + "sync" +) + +func CreateSockets(encoder *BinaryEncoder, max uint) *Sockets { + return &Sockets{ + Encoder: encoder, + In: make(chan SocketMessage), + Out: make(chan *Socket), + List: make(map[uint]*Socket), + max: max, + } +} + +type Sockets struct { + Encoder *BinaryEncoder + In chan SocketMessage + Out chan *Socket + List map[uint]*Socket + max uint + mu sync.RWMutex +} + +func (ss *Sockets) generateId() (uint, error) { + for id := uint(0); id < ss.max; id++ { + ss.mu.RLock() + _, ok := ss.List[id] + ss.mu.RUnlock() + + if !ok { + return id, nil + } + } + + return uint(0), errors.New("Socket limit reached!") +} + +func (ss *Sockets) Add(c *websocket.Conn) (*Socket, error) { + id, err := ss.generateId() + + if err != nil { + return nil, err + } + + socket := &Socket{ + ID: id, + Conn: c, + Encoder: ss.Encoder, + In: ss.In, + } + + ss.mu.Lock() + ss.List[socket.ID] = socket + ss.mu.Unlock() + + go socket.Run(ss.Remove) + + return socket, nil +} + +func (ss *Sockets) Remove(socket *Socket) { + ss.mu.Lock() + delete(ss.List, socket.ID) + ss.mu.Unlock() + + ss.Out <- socket +} + +func (ss *Sockets) Count() int { + return len(ss.List) +} + +func (ss *Sockets) ForEach(callback func(*Socket)) { + ss.mu.RLock() + defer ss.mu.RUnlock() + + for _, s := range ss.List { + callback(s) + } +} + +func (ss *Sockets) ForOther(socket *Socket, callback func(*Socket)) { + ss.mu.RLock() + defer ss.mu.RUnlock() + + for _, s := range ss.List { + if s.ID != socket.ID { + callback(s) + } + } +} + +func (ss *Sockets) WriteAll(data []byte) { + ss.mu.RLock() + defer ss.mu.RUnlock() + + for _, c := range ss.List { + c.Write(data) + } +} + +func (ss *Sockets) WriteOther(socket *Socket, data []byte) { + ss.mu.RLock() + defer ss.mu.RUnlock() + + for _, s := range ss.List { + if s.ID != socket.ID { + s.Write(data) + } + } +} + +func (ss *Sockets) Send(socket *Socket, message *Message) { + bytes, err := ss.Encoder.Encode(message) + if err == nil { + socket.Write(bytes) + } else { + log.Printf("Error: %v", err) + } +} + +func (ss *Sockets) SendAll(message *Message) { + bytes, err := ss.Encoder.Encode(message) + if err == nil { + ss.WriteAll(bytes) + } else { + log.Printf("Error: %v", err) + } +} + +func (ss *Sockets) SendOther(socket *Socket, message *Message) { + bytes, err := ss.Encoder.Encode(message) + if err == nil { + ss.WriteOther(socket, bytes) + } else { + log.Printf("Error: %v", err) + } +} + +func (ss *Sockets) Clear() { + close(ss.In) + close(ss.Out) +} diff --git a/index.html b/index.html index 444e6a0..d9998ce 100644 --- a/index.html +++ b/index.html @@ -1,9 +1,23 @@ - - - - Netcode Demo - - - - + + + + + Netcode + + + +

Netcode logs

+ + + diff --git a/package-lock.json b/package-lock.json index 01448c8..5c27278 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3567 +1,1238 @@ { "name": "netcode", - "version": "2.1.0", + "version": "2.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "netcode", - "version": "2.1.0", + "version": "2.2.1", "license": "MIT", "dependencies": { - "tom32i-event-emitter.js": "^2.0.5", - "utf-8-validate": "^5.0.2", - "ws": "^8.2.0" + "tom32i-event-emitter.js": "^2.2.0", + "ws": "^8.19.0" }, "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/preset-env": "^7.14.0", - "babel-loader": "^8.2.2", - "eslint": "^7.26.0", - "mocha": "^10.2.0", - "webpack": "^5.36.0", - "webpack-cli": "^4.6.0" + "eslint": "^9.14.0", + "globals": "^15.11.0", + "vite": "^7.1.3", + "vitest": "^4.1.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=24.0.0" }, "optionalDependencies": { - "bufferutil": "^4.0.7", - "utf-8-validate": "^5.0.10" + "bufferutil": "^4.1.0", + "utf-8-validate": "^6.0.6" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=18" } }, - "node_modules/@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.20.7", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", - "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.20.7", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", - "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", - "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.20.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@eslint/core": "^0.17.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/parser": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", - "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, - "bin": { - "parser": "bin/babel-parser.js" + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" }, "engines": { - "node": ">=6.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", - "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.20.7" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=18" }, - "peerDependencies": { - "@babel/core": "^7.13.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", - "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", - "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.18.0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.18.0" } }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=12.22" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", - "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=18.18" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", - "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", - "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", - "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", - "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", - "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", - "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/template": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", - "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", - "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", - "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", - "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-identifier": "^7.19.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", - "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", - "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", - "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", - "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.11.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", - "dev": true, - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dev": true, - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001446", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz", - "integrity": "sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/core-js-compat": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", - "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], "dev": true, - "bin": { - "flat": "cli.js" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], "dev": true, - "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + ] }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=6.9.0" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], "dev": true, - "bin": { - "he": "bin/he" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], "dev": true, - "engines": { - "node": ">= 4" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], "dev": true, - "engines": { - "node": ">=0.8.19" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": ">= 0.10" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": ">=0.12.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, + "license": "MIT", "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/@vitest/expect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.0.tgz", + "integrity": "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.0", + "@vitest/utils": "4.1.0", + "chai": "^6.2.2", + "tinyrainbow": "^3.0.3" }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/@vitest/mocker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.0.tgz", + "integrity": "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" + "@vitest/spy": "4.1.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@vitest/pretty-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.0.tgz", + "integrity": "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==", "dev": true, + "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "tinyrainbow": "^3.0.3" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/@vitest/runner": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.0.tgz", + "integrity": "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.0", + "pathe": "^2.0.3" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/@vitest/snapshot": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.0.tgz", + "integrity": "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==", "dev": true, - "bin": { - "json5": "lib/cli.js" + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.0", + "@vitest/utils": "4.1.0", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/@vitest/spy": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.0.tgz", + "integrity": "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/@vitest/utils": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.0.tgz", + "integrity": "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==", "dev": true, + "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "@vitest/pretty-format": "4.1.0", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.0.3" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=8.9.0" + "node": ">=0.4.0" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3572,11 +1243,67 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-symbols/node_modules/chalk": { + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3588,11 +1315,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/log-symbols/node_modules/color-convert": { + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3600,165 +1328,122 @@ "node": ">=7.0.0" } }, - "node_modules/log-symbols/node_modules/color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } + "license": "MIT" }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 8" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "ms": "^2.1.3" }, "engines": { - "node": ">= 0.6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT" }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 14.0.0" + "node": ">=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" } }, - "node_modules/mocha/node_modules/escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3766,1224 +1451,1081 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, - "dependencies": { - "argparse": "^2.0.1" + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" }, "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "url": "https://eslint.org/donate" }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "p-limit": "^3.0.2" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, "engines": { - "node": ">=6" + "node": ">=0.10" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "callsites": "^3.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=6" + "node": ">=4.0" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=8" + "node": ">=12.0.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "license": "MIT" }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" + "node": ">=16" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/flatted": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", "dev": true, - "engines": { - "node": ">=0.4.0" - } + "license": "ISC" }, - "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "picomatch": "^2.2.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=8.10.0" + "node": ">=10.13.0" } }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, + "license": "MIT", "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" + "node": ">=18" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 4" } }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { - "jsesc": "~0.5.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, - "bin": { - "regjsparser": "bin/parser" + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "license": "MIT", + "engines": { + "node": ">=0.8.19" } }, - "node_modules/require-directory": { + "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "argparse": "^2.0.1" }, "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, - "engines": { - "node": ">=4" + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" + "p-locate": "^5.0.0" }, "engines": { - "node": ">= 8.9.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" - } + "license": "MIT" }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, + "license": "MIT", "dependencies": { - "randombytes": "^2.1.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, + "license": "ISC", "dependencies": { - "kind-of": "^6.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT" + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">= 0.8.0" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "callsites": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/strip-json-comments": { + "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "license": "MIT", + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=10.0.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "license": "MIT", + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" - }, - "engines": { - "node": ">= 10.13.0" + "@types/estree": "1.0.8" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "bin": { + "rollup": "dist/bin/rollup" }, - "peerDependencies": { - "webpack": "^5.1.0" + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" } }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">=8" } }, - "node_modules/terser/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, + "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-fast-properties": { + "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "ISC" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">=8.0" + "node": ">=0.10.0" } }, - "node_modules/tom32i-event-emitter.js": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/tom32i-event-emitter.js/-/tom32i-event-emitter.js-2.0.5.tgz", - "integrity": "sha512-7wYTrHfV3gWRZXZQniMLOO5hh01szsTVulTWwcNheESvRUrveQCKKEz2YMceYQZdfpmXMC8PGpzOpUcnfXSXiw==" + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/std-env": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", + "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } + "license": "MIT" }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "node_modules/tinyexec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, - "bin": { - "browserslist-lint": "cli.js" + "engines": { + "node": ">=12.0.0" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "license": "MIT", + "engines": { + "node": ">=14.0.0" } }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, - "optional": true, + "node_modules/tom32i-event-emitter.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tom32i-event-emitter.js/-/tom32i-event-emitter.js-2.2.0.tgz", + "integrity": "sha512-kKGts3H5Ug5Q77wDWQz4xKaSuBimYug1Rakmq/BqiTNuYWk9QOvTkTe+NgBf6jOaajBTBBDGP6MKnav3u/1jRQ==", + "license": "MIT" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", "dependencies": { - "node-gyp-build": "^4.3.0" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=6.14.2" + "node": ">= 0.8.0" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" + "punycode": "^2.1.0" } }, - "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { - "webpack": "bin/webpack.js" + "vite": "bin/vite.js" }, "engines": { - "node": ">=10.13.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { - "webpack-cli": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { "optional": true } } }, - "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "node_modules/vitest": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.0.tgz", + "integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==", "dev": true, + "license": "MIT", "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "cross-spawn": "^7.0.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" + "@vitest/expect": "4.1.0", + "@vitest/mocker": "4.1.0", + "@vitest/pretty-format": "4.1.0", + "@vitest/runner": "4.1.0", + "@vitest/snapshot": "4.1.0", + "@vitest/spy": "4.1.0", + "@vitest/utils": "4.1.0", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0", + "why-is-node-running": "^2.3.0" }, "bin": { - "webpack-cli": "bin/cli.js" + "vitest": "vitest.mjs" }, "engines": { - "node": ">=10.13.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.0", + "@vitest/browser-preview": "4.1.0", + "@vitest/browser-webdriverio": "4.1.0", + "@vitest/ui": "4.1.0", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" }, "peerDependenciesMeta": { - "@webpack-cli/generators": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { "optional": true }, - "@webpack-cli/migrate": { + "@vitest/ui": { "optional": true }, - "webpack-bundle-analyzer": { + "happy-dom": { "optional": true }, - "webpack-dev-server": { + "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4994,87 +2536,38 @@ "node": ">= 8" } }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" + "siginfo": "^2.0.0", + "stackback": "0.0.2" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" + "bin": { + "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, + "license": "MIT", "engines": { - "node": ">=7.0.0" + "node": ">=0.10.0" } }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -5091,68 +2584,12 @@ } } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index fc2347d..261191b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "netcode", - "version": "2.1.1", + "version": "2.2.1", "description": "NetCode for web video games", "author": "Thomas Jarrand (https://thomas.jarrand.fr)", "license": "MIT", @@ -14,34 +14,49 @@ "multiplayer" ], "scripts": { - "watch": "webpack --watch --mode=development", - "build": "webpack --mode=production", - "test": "mocha", + "start": "vite", + "watch": "vite build --watch", + "build": "vite build", + "test": "vitest --run", "lint": "eslint src/* --ext .js,.json --fix" }, "engines": { - "node": ">=8.0.0" + "node": ">=24.0.0" }, "files": [ - "src/*", - "client.js", - "server.js" + "src", + "dist" ], + "type": "module", + "main": "./dist/client/netcode.umd.cjs", + "module": "./dist/client/netcode.js", + "exports": { + ".": { + "import": "./dist/client/netcode.js", + "require": "./dist/client/netcode.umd.cjs" + }, + "./server": { + "import": "./src/server/index.js" + }, + "./client": { + "import": "./src/client/index.js" + }, + "./encoder": { + "import": "./src/encoder/index.js" + } + }, "dependencies": { - "tom32i-event-emitter.js": "^2.0.5", - "ws": "^8.2.0" + "tom32i-event-emitter.js": "^2.2.0", + "ws": "^8.19.0" }, "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/preset-env": "^7.14.0", - "babel-loader": "^8.2.2", - "eslint": "^7.26.0", - "mocha": "^10.2.0", - "webpack": "^5.36.0", - "webpack-cli": "^4.6.0" + "eslint": "^9.14.0", + "globals": "^15.11.0", + "vite": "^7.1.3", + "vitest": "^4.1.0" }, "optionalDependencies": { - "bufferutil": "^4.0.7", - "utf-8-validate": "^5.0.10" + "bufferutil": "^4.1.0", + "utf-8-validate": "^6.0.6" } } diff --git a/src/client/Client.js b/src/client/Client.js index b6bf81c..7d680d2 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -1,5 +1,5 @@ import EventEmitter from 'tom32i-event-emitter.js'; -import JsonEncoder from 'netcode/src/encoder/JsonEncoder'; +import JsonEncoder from '../encoder/JsonEncoder.js'; export default class Client extends EventEmitter { /** @@ -21,12 +21,23 @@ export default class Client extends EventEmitter { this.onError = this.onError.bind(this); this.onMessage = this.onMessage.bind(this); + this.attachEvents(); + } + + attachEvents() { this.socket.addEventListener('open', this.onOpen); this.socket.addEventListener('close', this.onClose); this.socket.addEventListener('error', this.onError); this.socket.addEventListener('message', this.onMessage); } + detachEvents() { + this.socket.removeEventListener('open', this.onOpen); + this.socket.removeEventListener('close', this.onClose); + this.socket.removeEventListener('error', this.onError); + this.socket.removeEventListener('message', this.onMessage); + } + /** * Send data over WebSocket * @@ -39,16 +50,19 @@ export default class Client extends EventEmitter { /** * Close connection + * + * @param {Number} code https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 + * @param {String} reason https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.6 */ - close() { - this.socket.close(); + close(code, reason) { + this.socket.close(code, reason); } /** * On connexion open */ - onOpen() { - this.emit('open', this); + onOpen(event) { + this.emit('open', event); } /** @@ -65,12 +79,9 @@ export default class Client extends EventEmitter { /** * On close */ - onClose() { - this.socket.removeEventListener('open', this.onOpen); - this.socket.removeEventListener('close', this.onClose); - this.socket.removeEventListener('error', this.onError); - this.socket.removeEventListener('message', this.onMessage); - this.emit('close', this); + onClose(event) { + this.emit('close', event); + this.detachEvents(); } /** @@ -79,6 +90,6 @@ export default class Client extends EventEmitter { * @param {Error} error */ onError(error) { - this.emit('error', error, this); + this.emit('error', error); } } diff --git a/src/client/index.js b/src/client/index.js index 1413e60..19e0008 100644 --- a/src/client/index.js +++ b/src/client/index.js @@ -1,25 +1,39 @@ -import Client from 'netcode/src/client/Client'; -import JsonEncoder from 'netcode/src/encoder/JsonEncoder'; -import BinaryEncoder from 'netcode/src/encoder/BinaryEncoder'; -import Codec from 'netcode/src/encoder/codec/Codec'; -import Int8Codec from 'netcode/src/encoder/codec/Int8Codec'; -import Int16Codec from 'netcode/src/encoder/codec/Int16Codec'; -import Int32Codec from 'netcode/src/encoder/codec/Int32Codec'; -import LongIntCodec from 'netcode/src/encoder/codec/LongIntCodec'; -import BooleanCodec from 'netcode/src/encoder/codec/BooleanCodec'; -import StringCodec from 'netcode/src/encoder/codec/StringCodec'; -import LongStringCodec from 'netcode/src/encoder/codec/LongStringCodec'; +import Client from './Client.js'; +import JsonEncoder from '../encoder/JsonEncoder.js'; +import BinaryEncoder from '../encoder/BinaryEncoder.js'; +import Codec from '../encoder/codec/Codec.js'; +import BooleanCodec from '../encoder/codec/BooleanCodec.js'; +import Float32Codec from '../encoder/codec/Float32Codec.js'; +import Float64Codec from '../encoder/codec/Float64Codec.js'; +import FloatPrecisionCodec from '../encoder/codec/FloatPrecisionCodec.js'; +import Int8Codec from '../encoder/codec/Int8Codec.js'; +import Int16Codec from '../encoder/codec/Int16Codec.js'; +import Int32Codec from '../encoder/codec/Int32Codec.js'; +import NullCodec from '../encoder/codec/NullCodec.js'; +import StringCodec from '../encoder/codec/StringCodec.js'; +import StringLongCodec from '../encoder/codec/StringLongCodec.js'; +import UInt8Codec from '../encoder/codec/UInt8Codec.js'; +import UInt16Codec from '../encoder/codec/UInt16Codec.js'; +import UInt32Codec from '../encoder/codec/UInt32Codec.js'; +import UIntLongCodec from '../encoder/codec/UIntLongCodec.js'; export { Client, JsonEncoder, BinaryEncoder, Codec, - Int8Codec, + BooleanCodec, + Float32Codec, + Float64Codec, + FloatPrecisionCodec, Int16Codec, Int32Codec, - LongIntCodec, - BooleanCodec, + Int8Codec, + NullCodec, StringCodec, - LongStringCodec, + StringLongCodec, + UInt16Codec, + UInt32Codec, + UInt8Codec, + UIntLongCodec, }; diff --git a/src/encoder/BinaryEncoder.js b/src/encoder/BinaryEncoder.js index c1615dc..ecfdb9c 100644 --- a/src/encoder/BinaryEncoder.js +++ b/src/encoder/BinaryEncoder.js @@ -1,4 +1,4 @@ -import Int8Codec from 'netcode/src/encoder/codec/Int8Codec'; +import UInt8Codec from './codec/UInt8Codec.js'; export default class BinaryEncoder { /** @@ -18,7 +18,7 @@ export default class BinaryEncoder { /** * @param {Array} handlers */ - constructor(handlers, idCodec = new Int8Codec()) { + constructor(handlers, idCodec = new UInt8Codec()) { this.idCodec = idCodec; this.handlersByName = new Map(handlers); this.handlersById = Array.from(this.handlersByName.values()); @@ -77,7 +77,10 @@ export default class BinaryEncoder { throw new Error(`No handler found at index "${id}"`); } - return { name: handler.name, data: handler.decode(buffer, this.idCodec.getByteLength()) }; + return { + name: handler.name, + data: handler.decode(buffer, this.idCodec.getByteLength()), + }; } } diff --git a/src/encoder/JsonEncoder.js b/src/encoder/JsonEncoder.js index 188d8ae..faadc5f 100644 --- a/src/encoder/JsonEncoder.js +++ b/src/encoder/JsonEncoder.js @@ -39,7 +39,7 @@ export default class JsonEncoder { decode(value) { try { return JSON.parse(value); - } catch(error) { + } catch { return null; } } diff --git a/src/encoder/codec/BooleanCodec.js b/src/encoder/codec/BooleanCodec.js index eebdc8f..f1e2f9c 100644 --- a/src/encoder/codec/BooleanCodec.js +++ b/src/encoder/codec/BooleanCodec.js @@ -1,4 +1,4 @@ -import Codec from './Codec'; +import Codec from './Codec.js'; /** * Boolean codec diff --git a/src/encoder/codec/Float32Codec.js b/src/encoder/codec/Float32Codec.js new file mode 100644 index 0000000..9b70e79 --- /dev/null +++ b/src/encoder/codec/Float32Codec.js @@ -0,0 +1,27 @@ +import Codec from './Codec.js'; + +/** + * 32 bit Float codec + */ +export default class Float32Codec extends Codec { + /** + * @type {Number} + */ + getByteLength() { + return BigUint64Array.BYTES_PER_ELEMENT / 2; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + new DataView(buffer).setFloat32(offset, data); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return new DataView(buffer).getFloat32(offset); + } +} diff --git a/src/encoder/codec/Float64Codec.js b/src/encoder/codec/Float64Codec.js new file mode 100644 index 0000000..25f9ec3 --- /dev/null +++ b/src/encoder/codec/Float64Codec.js @@ -0,0 +1,27 @@ +import Codec from './Codec.js'; + +/** + * 64 bit Float codec + */ +export default class Float64Codec extends Codec { + /** + * @type {Number} + */ + getByteLength() { + return BigUint64Array.BYTES_PER_ELEMENT; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + new DataView(buffer).setFloat64(offset, data); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return new DataView(buffer).getFloat64(offset); + } +} diff --git a/src/encoder/codec/FloatPrecisionCodec.js b/src/encoder/codec/FloatPrecisionCodec.js new file mode 100644 index 0000000..264bd35 --- /dev/null +++ b/src/encoder/codec/FloatPrecisionCodec.js @@ -0,0 +1,33 @@ +import Codec from './Codec.js'; + +/** + * Float precision codec + * - UInt8 with precision of 2: (-1.28 to 1.27) + * - Int32 with precision of 3: (0 to 4294967.295) + */ +export default class FloatPrecisionCodec extends Codec { + constructor(codec, precision) { + super(); + + this.codec = new codec(); + this.factor = 10**precision; + } + + getByteLength(data) { + return this.codec.getByteLength(data); + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + this.codec.encode(buffer, offset, data * this.factor); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return this.codec.decode(buffer, offset) / this.factor; + } +} diff --git a/src/encoder/codec/Int16Codec.js b/src/encoder/codec/Int16Codec.js index 1263e70..c7504f9 100644 --- a/src/encoder/codec/Int16Codec.js +++ b/src/encoder/codec/Int16Codec.js @@ -1,27 +1,27 @@ -import Codec from './Codec'; +import Codec from './Codec.js'; /** - * 16 bit Int codec (0 to 65535) + * 16 bit signed Int codec (-32768 to 32767) */ export default class Int16Codec extends Codec { /** * @type {Number} */ getByteLength() { - return Uint16Array.BYTES_PER_ELEMENT; + return Int16Array.BYTES_PER_ELEMENT; } /** * {@inheritdoc} */ encode(buffer, offset, data) { - new DataView(buffer).setUint16(offset, data); + new DataView(buffer).setInt16(offset, data); } /** * {@inheritdoc} */ decode(buffer, offset) { - return new DataView(buffer).getUint16(offset); + return new DataView(buffer).getInt16(offset); } } diff --git a/src/encoder/codec/Int32Codec.js b/src/encoder/codec/Int32Codec.js index 6791c98..74750ba 100644 --- a/src/encoder/codec/Int32Codec.js +++ b/src/encoder/codec/Int32Codec.js @@ -1,27 +1,27 @@ -import Codec from './Codec'; +import Codec from './Codec.js'; /** - * 32 bit Int codec (0 to 4294967295) + * 32 bit signed Int codec (-2147483648 to 2147483647) */ export default class Int32Codec extends Codec { /** * @type {Number} */ getByteLength() { - return Uint32Array.BYTES_PER_ELEMENT; + return Int32Array.BYTES_PER_ELEMENT; } /** * {@inheritdoc} */ encode(buffer, offset, data) { - new DataView(buffer).setUint32(offset, data); + new DataView(buffer).setInt32(offset, data); } /** * {@inheritdoc} */ decode(buffer, offset) { - return new DataView(buffer).getUint32(offset); + return new DataView(buffer).getInt32(offset); } } diff --git a/src/encoder/codec/Int8Codec.js b/src/encoder/codec/Int8Codec.js index 70cd511..e37b53d 100644 --- a/src/encoder/codec/Int8Codec.js +++ b/src/encoder/codec/Int8Codec.js @@ -1,27 +1,27 @@ -import Codec from './Codec'; +import Codec from './Codec.js'; /** - * 8 bit Int codec (0 to 255) + * 8 bit signed Int codec (-128 to 127) */ export default class Int8Codec extends Codec { /** * @type {Number} */ getByteLength() { - return Uint8Array.BYTES_PER_ELEMENT; + return Int8Array.BYTES_PER_ELEMENT; } /** * {@inheritdoc} */ encode(buffer, offset, data) { - new DataView(buffer).setUint8(offset, data); + new DataView(buffer).setInt8(offset, data); } /** * {@inheritdoc} */ decode(buffer, offset) { - return new DataView(buffer).getUint8(offset); + return new DataView(buffer).getInt8(offset); } } diff --git a/src/encoder/codec/LongIntCodec.js b/src/encoder/codec/LongIntCodec.js deleted file mode 100644 index ea21c42..0000000 --- a/src/encoder/codec/LongIntCodec.js +++ /dev/null @@ -1,39 +0,0 @@ -import { bytePad } from 'netcode/src/utils'; -import Codec from './Codec'; - -/** - * Boolean codec - */ -export default class LongIntCodec extends Codec { - /** - * @param {Number} byteLength - */ - constructor(byteLength) { - super(); - - this.byteLength = byteLength; - } - - getByteLength() { - return this.byteLength; - } - - /** - * {@inheritdoc} - */ - encode(buffer, offset, data) { - const view = new DataView(buffer, offset, this.byteLength); - const bin = bytePad(data.toString(2), this.byteLength).match(/.{8}/g); - - bin.forEach((value, index) => view.setUint8(index, parseInt(value, 2))); - } - - /** - * {@inheritdoc} - */ - decode(buffer, offset) { - const view = new Uint8Array(buffer, offset, this.byteLength); - - return parseInt(Array.from(view).map(value => bytePad(value.toString(2), 1)).join(''), 2); - } -} diff --git a/src/encoder/codec/LongStringCodec.js b/src/encoder/codec/LongStringCodec.js deleted file mode 100644 index f610c8e..0000000 --- a/src/encoder/codec/LongStringCodec.js +++ /dev/null @@ -1,42 +0,0 @@ -import Codec from './Codec'; - -/** - * String codec (limited to 65536 chars) - */ -export default class LongStringCodec extends Codec { - /** - * @type {Number} - */ - getByteLength(data) { - return 2 + (data || '').length * 2; - } - - /** - * {@inheritdoc} - */ - encode(buffer, offset, data) { - const view = new DataView(buffer, offset, this.getByteLength(data)); - const { length } = (data || ''); - - view.setUint16(0, length); - - for (var index = 0; index < length; index++) { - view.setUint16(2 + (index * 2), data[index].charCodeAt(0)); - } - } - - /** - * {@inheritdoc} - */ - decode(buffer, offset) { - const view = new DataView(buffer, offset); - const length = view.getUint16(0); - const chars = new Array(length); - - for (var index = 0; index < length; index++) { - chars[index] = view.getUint16(2 + index * 2); - } - - return String.fromCharCode(...chars); - } -} diff --git a/src/encoder/codec/NullCodec.js b/src/encoder/codec/NullCodec.js new file mode 100644 index 0000000..b8e334c --- /dev/null +++ b/src/encoder/codec/NullCodec.js @@ -0,0 +1,7 @@ +import Codec from './Codec.js'; + +/** + * Null codec (just a named event) + */ +export default class NullCodec extends Codec { +} diff --git a/src/encoder/codec/StringCodec.js b/src/encoder/codec/StringCodec.js index b757bae..b9db3b1 100644 --- a/src/encoder/codec/StringCodec.js +++ b/src/encoder/codec/StringCodec.js @@ -1,27 +1,35 @@ -import Codec from './Codec'; +import Codec from './Codec.js'; /** * String codec (limited to 255 chars) */ export default class StringCodec extends Codec { + constructor() { + super(); + + this.encoder = new TextEncoder(); + this.decoder = new TextDecoder(TextEncoder.encoding); + } + /** * @type {Number} */ getByteLength(data) { - return 1 + (data || '').length * 2; + return 1 + this.encoder.encode(data || '').length; } /** * {@inheritdoc} */ encode(buffer, offset, data) { - const view = new DataView(buffer, offset, this.getByteLength(data)); - const { length } = (data || ''); + const bytes = this.encoder.encode(data || ''); + const { length } = bytes; + const view = new DataView(buffer, offset, length + 1); view.setUint8(0, length); for (var index = 0; index < length; index++) { - view.setUint16(1 + (index * 2), data[index].charCodeAt(0)); + view.setUint8(index + 1, bytes[index]); } } @@ -31,12 +39,8 @@ export default class StringCodec extends Codec { decode(buffer, offset) { const view = new DataView(buffer, offset); const length = view.getUint8(0); - const chars = new Array(length); - - for (var index = 0; index < length; index++) { - chars[index] = view.getUint16(1 + index * 2); - } + const bytes = buffer.slice(offset + 1, offset + 1 + length); - return String.fromCharCode(...chars); + return this.decoder.decode(bytes); } } diff --git a/src/encoder/codec/StringLongCodec.js b/src/encoder/codec/StringLongCodec.js new file mode 100644 index 0000000..64518c4 --- /dev/null +++ b/src/encoder/codec/StringLongCodec.js @@ -0,0 +1,46 @@ +import Codec from './Codec.js'; + +/** + * Long String codec (limited to 65536 chars) + */ +export default class StringLongCodec extends Codec { + constructor() { + super(); + + this.encoder = new TextEncoder(); + this.decoder = new TextDecoder(TextEncoder.encoding); + } + + /** + * @type {Number} + */ + getByteLength(data) { + return 2 + this.encoder.encode(data || '').length; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + const bytes = this.encoder.encode(data || ''); + const { length } = bytes; + const view = new DataView(buffer, offset, length + 2); + + view.setUint16(0, length); + + for (var index = 0; index < length; index++) { + view.setUint8(index + 2, bytes[index]); + } + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + const view = new DataView(buffer, offset); + const length = view.getUint16(0); + const bytes = buffer.slice(offset + 2, offset + 2 + length); + + return this.decoder.decode(bytes); + } +} diff --git a/src/encoder/codec/UInt16Codec.js b/src/encoder/codec/UInt16Codec.js new file mode 100644 index 0000000..9d0896a --- /dev/null +++ b/src/encoder/codec/UInt16Codec.js @@ -0,0 +1,27 @@ +import Codec from './Codec.js'; + +/** + * 16 bit unsigned Int codec (0 to 65535) + */ +export default class UInt16Codec extends Codec { + /** + * @type {Number} + */ + getByteLength() { + return Uint16Array.BYTES_PER_ELEMENT; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + new DataView(buffer).setUint16(offset, data); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return new DataView(buffer).getUint16(offset); + } +} diff --git a/src/encoder/codec/UInt32Codec.js b/src/encoder/codec/UInt32Codec.js new file mode 100644 index 0000000..9e762f5 --- /dev/null +++ b/src/encoder/codec/UInt32Codec.js @@ -0,0 +1,27 @@ +import Codec from './Codec.js'; + +/** + * 32 bit unsigned Int codec (0 to 4294967295) + */ +export default class UInt32Codec extends Codec { + /** + * @type {Number} + */ + getByteLength() { + return Uint32Array.BYTES_PER_ELEMENT; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + new DataView(buffer).setUint32(offset, data); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return new DataView(buffer).getUint32(offset); + } +} diff --git a/src/encoder/codec/UInt8Codec.js b/src/encoder/codec/UInt8Codec.js new file mode 100644 index 0000000..03369aa --- /dev/null +++ b/src/encoder/codec/UInt8Codec.js @@ -0,0 +1,27 @@ +import Codec from './Codec.js'; + +/** + * 8 bit unsigned Int codec (0 to 255) + */ +export default class UInt8Codec extends Codec { + /** + * @type {Number} + */ + getByteLength() { + return Uint8Array.BYTES_PER_ELEMENT; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + new DataView(buffer).setUint8(offset, data); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + return new DataView(buffer).getUint8(offset); + } +} diff --git a/src/encoder/codec/UIntLongCodec.js b/src/encoder/codec/UIntLongCodec.js new file mode 100644 index 0000000..f5978f5 --- /dev/null +++ b/src/encoder/codec/UIntLongCodec.js @@ -0,0 +1,48 @@ +import Codec from './Codec.js'; + +/** + * Long unsigned int codec + */ +export default class UIntLongCodec extends Codec { + /** + * @param {Number} byteLength + */ + constructor(byteLength) { + super(); + + this.byteLength = byteLength; + } + + getByteLength() { + return this.byteLength; + } + + /** + * {@inheritdoc} + */ + encode(buffer, offset, data) { + const view = new DataView(buffer, offset, this.byteLength); + const bin = this.bytePad(data.toString(2), this.byteLength).match(/.{8}/g); + bin.forEach((value, index) => view.setUint8(index, parseInt(value, 2))); + } + + /** + * {@inheritdoc} + */ + decode(buffer, offset) { + const view = new Uint8Array(buffer, offset, this.byteLength); + return parseInt(Array.from(view).map(value => this.bytePad(value.toString(2), 1)).join(''), 2); + } + + /** + * Fill the binaryString with zeros to make whole bytes. + * + * @param {String} binaryString + * @param {Number} byteLength + * + * @return {String} + */ + bytePad(binaryString, byteLength) { + return '0'.repeat((8 * byteLength) - binaryString.length) + binaryString; + } +} diff --git a/src/encoder/codec/index.js b/src/encoder/codec/index.js index dd04f3a..b926dbb 100644 --- a/src/encoder/codec/index.js +++ b/src/encoder/codec/index.js @@ -1,19 +1,33 @@ -import Codec from 'netcode/src/encoder/codec/Codec'; -import BooleanCodec from 'netcode/src/encoder/codec/BooleanCodec'; -import Int8Codec from 'netcode/src/encoder/codec/Int8Codec'; -import Int16Codec from 'netcode/src/encoder/codec/Int16Codec'; -import Int32Codec from 'netcode/src/encoder/codec/Int32Codec'; -import LongIntCodec from 'netcode/src/encoder/codec/LongIntCodec'; -import StringCodec from 'netcode/src/encoder/codec/StringCodec'; -import LongStringCodec from 'netcode/src/encoder/codec/LongStringCodec'; +import Codec from './Codec.js'; +import BooleanCodec from './BooleanCodec.js'; +import Float32Codec from './Float32Codec.js'; +import Float64Codec from './Float64Codec.js'; +import FloatPrecisionCodec from './FloatPrecisionCodec.js'; +import Int16Codec from './Int16Codec.js'; +import Int32Codec from './Int32Codec.js'; +import Int8Codec from './Int8Codec.js'; +import NullCodec from './NullCodec.js'; +import StringCodec from './StringCodec.js'; +import StringLongCodec from './StringLongCodec.js'; +import UInt16Codec from './UInt16Codec.js'; +import UInt32Codec from './UInt32Codec.js'; +import UInt8Codec from './UInt8Codec.js'; +import UIntLongCodec from './UIntLongCodec.js'; export { Codec, BooleanCodec, - Int8Codec, + Float32Codec, + Float64Codec, + FloatPrecisionCodec, Int16Codec, Int32Codec, - LongIntCodec, + Int8Codec, + NullCodec, StringCodec, - LongStringCodec, + StringLongCodec, + UInt16Codec, + UInt32Codec, + UInt8Codec, + UIntLongCodec, }; diff --git a/src/encoder/index.js b/src/encoder/index.js new file mode 100644 index 0000000..91e3a4b --- /dev/null +++ b/src/encoder/index.js @@ -0,0 +1,35 @@ +import JsonEncoder from './JsonEncoder.js'; +import BinaryEncoder from './BinaryEncoder.js'; +import Codec from './codec/Codec.js'; +import BooleanCodec from './codec/BooleanCodec.js'; +import Float64Codec from './codec/Float64Codec.js'; +import FloatPrecisionCodec from './codec/FloatPrecisionCodec.js'; +import Int16Codec from './codec/Int16Codec.js'; +import Int32Codec from './codec/Int32Codec.js'; +import Int8Codec from './codec/Int8Codec.js'; +import NullCodec from './codec/NullCodec.js'; +import StringCodec from './codec/StringCodec.js'; +import StringLongCodec from './codec/StringLongCodec.js'; +import UInt16Codec from './codec/UInt16Codec.js'; +import UInt32Codec from './codec/UInt32Codec.js'; +import UInt8Codec from './codec/UInt8Codec.js'; +import UIntLongCodec from './codec/UIntLongCodec.js'; + +export { + JsonEncoder, + BinaryEncoder, + Codec, + BooleanCodec, + Float64Codec, + FloatPrecisionCodec, + Int16Codec, + Int32Codec, + Int8Codec, + NullCodec, + StringCodec, + StringLongCodec, + UInt16Codec, + UInt32Codec, + UInt8Codec, + UIntLongCodec, +}; diff --git a/src/server/Beacon.js b/src/server/Beacon.js index d17ac08..925fbd8 100644 --- a/src/server/Beacon.js +++ b/src/server/Beacon.js @@ -3,24 +3,21 @@ */ export default class Beacon { /** - * @param {Socket} socket + * @param {Client} client * @param {Number} frequency Frequency in second */ - constructor(socket, frequency = 30) { - this.socket = socket; + constructor(client, emit, frequency = 30) { + this.client = client; + this.socket = client.socket; + this.emit = emit; this.frequency = frequency * 1000; this.interval = null; - this.alive = true; this.start = this.start.bind(this); this.stop = this.stop.bind(this); - this.ping = this.ping.bind(this); - this.onPing = this.onPing.bind(this); + this.sendPing = this.sendPing.bind(this); this.onPong = this.onPong.bind(this); - this.socket.on('pong', this.onPong); - this.socket.on('close', this.stop); - if (this.socket.readyState === 1) { this.start(); } else { @@ -32,8 +29,13 @@ export default class Beacon { * Start ping interval */ start() { - if (!this.interval) { - this.interval = setInterval(this.ping, this.frequency); + this.socket.off('open', this.start); + + if (this.interval === null) { + this.socket.on('pong', this.onPong); + this.socket.on('close', this.stop); + this.interval = setInterval(this.sendPing, this.frequency); + setImmediate(this.sendPing); } } @@ -41,34 +43,27 @@ export default class Beacon { * Stop ping interval */ stop() { - if (this.interval) { + if (this.interval !== null) { clearInterval(this.interval); this.interval = null; + this.socket.off('pong', this.onPong); + this.socket.off('close', this.stop); } } /** - * Ping + * Send ping */ - ping() { - if (!this.alive) { - return this.socket.terminate(); - } - - this.alive = false; - this.socket.ping(this.onPing); + sendPing() { + this.socket.ping(performance.now()); } - /** - * On ping + * Receive pong */ - onPing() { - } + onPong(buffer) { + const now = performance.now(); + const ping = parseFloat(buffer.toString()); - /** - * On pong - */ - onPong() { - this.alive = true; + this.emit('pong', { client: this.client, duration: now - ping }); } } diff --git a/src/server/Client.js b/src/server/Client.js index a4876ee..65ff287 100644 --- a/src/server/Client.js +++ b/src/server/Client.js @@ -34,15 +34,6 @@ export default class Client extends EventEmitter { } } - /** - * Set id - * - * @param {Number|String} id - */ - setId(id) { - this.id = id; - } - /** * Send a message * @@ -98,7 +89,7 @@ export default class Client extends EventEmitter { /** * On close */ - onClose() { + onClose(data) { // eslint-disable-line no-unused-vars this.socket = null; this.emit('close', this); } diff --git a/src/server/MapClientDirectory.js b/src/server/MapClientDirectory.js index b5b5619..8063f40 100644 --- a/src/server/MapClientDirectory.js +++ b/src/server/MapClientDirectory.js @@ -4,7 +4,8 @@ * Re-use ids after client disconnection. */ export default class MapClientDirectory { - constructor() { + constructor(max = Math.pow(2, 16)) { + this.max = max; this.clients = new Map(); } @@ -23,13 +24,13 @@ export default class MapClientDirectory { * @return {Number|String} */ generateId() { - let id = 1; - - while (this.clients.has(id)) { - id++; + for (let id = 0; id < this.max; id++) { + if (!this.clients.has(id)) { + return id; + } } - return id; + throw new Error(`Max clients reached ${this.max}.`); } /** @@ -38,10 +39,7 @@ export default class MapClientDirectory { * @param {Client} client */ add(client) { - if (!client.id) { - client.id = this.generateId(); - } - + client.id = this.generateId(); this.clients.set(client.id, client); } diff --git a/src/server/Server.js b/src/server/Server.js index b8157d5..4ffc2bf 100644 --- a/src/server/Server.js +++ b/src/server/Server.js @@ -1,21 +1,30 @@ import http from 'http'; import EventEmitter from 'events'; import { WebSocketServer } from 'ws'; -import JsonEncoder from 'netcode/src/encoder/JsonEncoder'; -import MapClientDirectory from 'netcode/src/server/MapClientDirectory'; -import Client from 'netcode/src/server/Client'; -import Beacon from 'netcode/src/server/Beacon'; +import JsonEncoder from '../encoder/JsonEncoder.js'; +import MapClientDirectory from './MapClientDirectory.js'; +import Client from './Client.js'; +import Beacon from './Beacon.js'; export default class Server extends EventEmitter { /** * @param {Number} port Port to listen on * @param {String} host Host to listen on * @param {JsonEncoder|BinaryEncoder} encoder Encoder to use to read/write event messages - * @param {Number} ping Ping frequency in seconds (0 for no ping) - * @param {Number} maxPayload Paquet max length in bit + * @param {Number} pingInterval Ping frequency in seconds (0 for no ping) + * @param {Number} maxPayload Paquet max length in bit (should be a power of two) * @param {ClientDirectory} clients Clients directory + * @param {Boolean} autoStart Auto start server on construct */ - constructor(port = 8080, host = '0.0.0.0', encoder = new JsonEncoder(), ping = 30, maxPayload = Math.pow(2, 9), clients = new MapClientDirectory(), autoStart = true) { + constructor( + port = 8080, + host = '0.0.0.0', + encoder = new JsonEncoder(), + pingInterval = 30, + maxPayload = Math.pow(2, 9), + clients = new MapClientDirectory(), + autoStart = true + ) { super(); this.start = this.start.bind(this); @@ -24,6 +33,7 @@ export default class Server extends EventEmitter { this.onConnection = this.onConnection.bind(this); this.onListening = this.onListening.bind(this); this.removeClient = this.removeClient.bind(this); + this.emit = this.emit.bind(this); this.port = port; this.host = host; @@ -34,7 +44,7 @@ export default class Server extends EventEmitter { maxPayload }); this.clients = clients; - this.ping = ping; + this.pingInterval = pingInterval; this.server.on('request', this.onRequest); this.server.on('error', this.onError); @@ -47,15 +57,6 @@ export default class Server extends EventEmitter { } } - /** - * Generate a new unique id - * - * @return {Number|String} - */ - generateId() { - return this.clients.generateId(); - } - /** * Start listening for clients * @@ -73,7 +74,6 @@ export default class Server extends EventEmitter { * @param {Request} request */ addClient(client, request) { - client.setId(this.generateId()); this.clients.add(client); client.on('close', this.removeClient); this.emit('client:join', client, request); @@ -105,14 +105,12 @@ export default class Server extends EventEmitter { */ onConnection(socket, request) { const ip = request.headers['x-real-ip'] || request.headers['x-forwarded-for'] || request.connection.remoteAddress; + const client = new Client(socket, ip, this.encoder); - this.addClient( - new Client(socket, ip, this.encoder), - request - ); + this.addClient(client, request); - if (this.ping) { - new Beacon(socket, this.ping); + if (this.pingInterval) { + new Beacon(client, this.emit, this.pingInterval); } } diff --git a/src/server/index.js b/src/server/index.js index d1bc444..07e7fcf 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -1,25 +1,45 @@ -import Server from 'netcode/src/server/Server'; -import JsonEncoder from 'netcode/src/encoder/JsonEncoder'; -import BinaryEncoder from 'netcode/src/encoder/BinaryEncoder'; -import Codec from 'netcode/src/encoder/codec/Codec'; -import Int8Codec from 'netcode/src/encoder/codec/Int8Codec'; -import Int16Codec from 'netcode/src/encoder/codec/Int16Codec'; -import Int32Codec from 'netcode/src/encoder/codec/Int32Codec'; -import LongIntCodec from 'netcode/src/encoder/codec/LongIntCodec'; -import BooleanCodec from 'netcode/src/encoder/codec/BooleanCodec'; -import StringCodec from 'netcode/src/encoder/codec/StringCodec'; -import LongStringCodec from 'netcode/src/encoder/codec/LongStringCodec'; +import Server from './Server.js'; +import Beacon from './Beacon.js'; +import Client from './Client.js'; +import MapClientDirectory from './MapClientDirectory.js'; +import JsonEncoder from '../encoder/JsonEncoder.js'; +import BinaryEncoder from '../encoder/BinaryEncoder.js'; +import Codec from '../encoder/codec/Codec.js'; +import BooleanCodec from '../encoder/codec/BooleanCodec.js'; +import Float32Codec from '../encoder/codec/Float32Codec.js'; +import Float64Codec from '../encoder/codec/Float64Codec.js'; +import FloatPrecisionCodec from '../encoder/codec/FloatPrecisionCodec.js'; +import Int16Codec from '../encoder/codec/Int16Codec.js'; +import Int32Codec from '../encoder/codec/Int32Codec.js'; +import Int8Codec from '../encoder/codec/Int8Codec.js'; +import NullCodec from '../encoder/codec/NullCodec.js'; +import StringCodec from '../encoder/codec/StringCodec.js'; +import StringLongCodec from '../encoder/codec/StringLongCodec.js'; +import UInt16Codec from '../encoder/codec/UInt16Codec.js'; +import UInt32Codec from '../encoder/codec/UInt32Codec.js'; +import UInt8Codec from '../encoder/codec/UInt8Codec.js'; +import UIntLongCodec from '../encoder/codec/UIntLongCodec.js'; export { Server, + Beacon, + Client, + MapClientDirectory, JsonEncoder, BinaryEncoder, Codec, - Int8Codec, + BooleanCodec, + Float32Codec, + Float64Codec, + FloatPrecisionCodec, Int16Codec, Int32Codec, - BooleanCodec, - LongIntCodec, + Int8Codec, + NullCodec, StringCodec, - LongStringCodec, + StringLongCodec, + UInt16Codec, + UInt32Codec, + UInt8Codec, + UIntLongCodec, }; diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index 3305496..0000000 --- a/src/utils.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Fill the binaryString with zeros to make whole bytes. - * - * @param {String} binaryString - * @param {Number} byteLength - * - * @return {String} - */ -export function bytePad(binaryString, byteLength) { - return '0'.repeat((8 * byteLength) - binaryString.length) + binaryString; -} diff --git a/test/codecs.js b/test/codecs.js deleted file mode 100644 index bff55a1..0000000 --- a/test/codecs.js +++ /dev/null @@ -1,100 +0,0 @@ -const assert = require('assert'); -const { - Int8Codec, - Int16Codec, - Int32Codec, - BooleanCodec, - LongIntCodec, - StringCodec, - LongStringCodec, -} = require('../server'); - -describe('Int8Codec', () => { - const codec = new Int8Codec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength()); - - it('Should encode/decode 0', () => { - codec.encode(buffer, 1, 0); - assert.equal(codec.decode(buffer, 1), 0); - }); - - it('Should encode/decode 255', () => { - codec.encode(buffer, 1, 255); - assert.equal(codec.decode(buffer, 1), 255); - }); -}); - -describe('Int16Codec', () => { - const codec = new Int16Codec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength()); - - it('Should encode/decode 0', () => { - codec.encode(buffer, 1, 0); - assert.equal(codec.decode(buffer, 1), 0); - }); - - it('Should encode/decode 65535', () => { - codec.encode(buffer, 1, 65535); - assert.equal(codec.decode(buffer, 1), 65535); - }); -}); - -describe('Int32Codec', () => { - const codec = new Int32Codec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength()); - - it('Should encode/decode 0', () => { - codec.encode(buffer, 1, 0); - assert.equal(codec.decode(buffer, 1), 0); - }); - - it('Should encode/decode 131071', () => { - codec.encode(buffer, 1, 131071); - assert.equal(codec.decode(buffer, 1), 131071); - }); -}); - -describe('LongIntCodec', () => { - const codec = new LongIntCodec(5); - const buffer = new ArrayBuffer(1 + codec.getByteLength()); - - it('Should encode/decode 623804400001', () => { - codec.encode(buffer, 1, 623804400001); - assert.equal(codec.decode(buffer, 1), 623804400001); - }); -}); - -describe('BooleanCodec', () => { - const codec = new BooleanCodec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength()); - - it('Should encode/decode true', () => { - codec.encode(buffer, 1, true); - assert.equal(codec.decode(buffer, 1), true); - }); - - it('Should encode/decode false', () => { - codec.encode(buffer, 1, false); - assert.equal(codec.decode(buffer, 1), false); - }); -}); - -describe('StringCodec', () => { - const codec = new StringCodec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength('Hell0 wœrld$ 🌝 !')); - - it('Should encode/decode "Hell0 wœrld$ 🌝 !"', () => { - codec.encode(buffer, 1, 'Hell0 wœrld$ 🌝 !'); - assert.equal(codec.decode(buffer, 1), 'Hell0 wœrld$ 🌝 !'); - }); -}); - -describe('LongStringCodec', () => { - const codec = new LongStringCodec(); - const buffer = new ArrayBuffer(1 + codec.getByteLength('data:image/jpeg;base64,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')); - - it('Should encode/decode a long string', () => { - codec.encode(buffer, 1, 'data:image/jpeg;base64,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'); - assert.equal(codec.decode(buffer, 1), 'data:image/jpeg;base64,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'); - }); -}); diff --git a/test/encoder.test.js b/test/encoder.test.js new file mode 100644 index 0000000..41ee713 --- /dev/null +++ b/test/encoder.test.js @@ -0,0 +1,289 @@ +import { describe, test, expect } from 'vitest'; +import { + BooleanCodec, + Float32Codec, + Float64Codec, + FloatPrecisionCodec, + Int16Codec, + Int32Codec, + Int8Codec, + NullCodec, + StringCodec, + StringLongCodec, + UInt16Codec, + UInt32Codec, + UInt8Codec, + UIntLongCodec, +} from 'netcode'; + + +describe('BooleanCodec', () => { + const codec = new BooleanCodec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode true', () => { + codec.encode(buffer, 1, true); + expect(codec.decode(buffer, 1)).toBe(true); + }); + + test('Should encode/decode false', () => { + codec.encode(buffer, 1, false); + expect(codec.decode(buffer, 1)).toBe(false); + }); +}); + +describe('Float32Codec', () => { + const codec = new Float32Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 84.2', () => { + codec.encode(buffer, 1, 84.2); + expect(codec.decode(buffer, 1)).toBe(84.19999694824219); + }); + + test('Should encode/decode 1.123', () => { + codec.encode(buffer, 1, 1.123); + // Known float32 javascript bug + expect(codec.decode(buffer, 1)).toBe(1.1230000257492065); + }); +}); + +describe('Float64Codec', () => { + const codec = new Float64Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 1.123', () => { + codec.encode(buffer, 1, 1.123); + expect(codec.decode(buffer, 1)).toBe(1.123); + }); + + test('Should encode/decode -12456789.123456789087654321012345678901', () => { + codec.encode(buffer, 1, -12456789.123456789087654321012345678901); + expect(codec.decode(buffer, 1)).toBe(-12456789.123456789087654321012345678901); + }); +}); + +describe('FloatPrecisionCodec(Int8Codec, 2)', () => { + const codec = new FloatPrecisionCodec(Int8Codec, 2); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 0.99', () => { + codec.encode(buffer, 1, 0.99); + expect(codec.decode(buffer, 1)).toBe(0.99); + }); + + test('Should encode/decode -0.65', () => { + codec.encode(buffer, 1, -0.65); + expect(codec.decode(buffer, 1)).toBe(-0.65); + }); + + test('Should encode/decode 0.1', () => { + codec.encode(buffer, 1, 0.1); + expect(codec.decode(buffer, 1)).toBe(0.1); + }); + + test('Should encode/decode 1.27', () => { + codec.encode(buffer, 1, 1.27); + expect(codec.decode(buffer, 1)).toBe(1.27); + }); + + test('Should encode/decode -1.28', () => { + codec.encode(buffer, 1, -1.28); + expect(codec.decode(buffer, 1)).toBe(-1.28); + }); +}); + +describe('FloatPrecisionCodec(UInt32Codec, 3)', () => { + const codec = new FloatPrecisionCodec(UInt32Codec, 3); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 4294967.295', () => { + codec.encode(buffer, 1, 4294967.295); + expect(codec.decode(buffer, 1)).toBe(4294967.295); + }); + + test('Should encode/decode 123456.999', () => { + codec.encode(buffer, 1, 123456.999); + expect(codec.decode(buffer, 1)).toBe(123456.999); + }); + + test('Should encode/decode 5.2', () => { + codec.encode(buffer, 1, 5.2); + expect(codec.decode(buffer, 1)).toBe(5.2); + }); +}); + +describe('Int8Codec', () => { + const codec = new Int8Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode -128', () => { + codec.encode(buffer, 1, -128); + expect(codec.decode(buffer, 1)).toBe(-128); + }); + + test('Should encode/decode 127', () => { + codec.encode(buffer, 1, 127); + expect(codec.decode(buffer, 1)).toBe(127); + }); +}); + +describe('Int16Codec', () => { + const codec = new Int16Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode -32768', () => { + codec.encode(buffer, 1, -32768); + expect(codec.decode(buffer, 1)).toBe(-32768); + }); + + test('Should encode/decode 32767', () => { + codec.encode(buffer, 1, 32767); + expect(codec.decode(buffer, 1)).toBe(32767); + }); +}); + +describe('Int32Codec', () => { + const codec = new Int32Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode -2147483648', () => { + codec.encode(buffer, 1, -2147483648); + expect(codec.decode(buffer, 1)).toBe(-2147483648); + }); + + test('Should encode/decode 2147483647', () => { + codec.encode(buffer, 1, 2147483647); + expect(codec.decode(buffer, 1)).toBe(2147483647); + }); +}); + +describe('StringCodec', () => { + const codec = new StringCodec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength('Hell0 wœrld$ 🌝 !')); + + test('Should encode/decode "Hell0 wœrld$ 🌝 !"', () => { + codec.encode(buffer, 1, 'Hell0 wœrld$ 🌝 !'); + expect(codec.decode(buffer, 1)).toBe('Hell0 wœrld$ 🌝 !'); + }); +}); + +describe('StringLongCodec', () => { + const codec = new StringLongCodec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength('data:image/jpeg;base64,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')); + + test('Should encode/decode a long string', () => { + codec.encode(buffer, 1, 'data:image/jpeg;base64,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'); + expect(codec.decode(buffer, 1)).toBe('data:image/jpeg;base64,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'); + }); +}); + +describe('NullCodec', () => { + const codec = new NullCodec(); + const buffer = new ArrayBuffer(1); + + test('Should encode/decode a null value', () => { + codec.encode(buffer, 1, null); + expect(codec.decode(buffer, 1)).toBe(null); + }); +}); + +describe('UInt8Codec', () => { + const codec = new UInt8Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 255', () => { + codec.encode(buffer, 1, 255); + expect(codec.decode(buffer, 1)).toBe(255); + }); +}); + +describe('UInt16Codec', () => { + const codec = new UInt16Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 65535', () => { + codec.encode(buffer, 1, 65535); + expect(codec.decode(buffer, 1)).toBe(65535); + }); +}); + +describe('UInt32Codec', () => { + const codec = new UInt32Codec(); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 0', () => { + codec.encode(buffer, 1, 0); + expect(codec.decode(buffer, 1)).toBe(0); + }); + + test('Should encode/decode 131071', () => { + codec.encode(buffer, 1, 131071); + expect(codec.decode(buffer, 1)).toBe(131071); + }); +}); + +describe('UIntLongCodec(5)', () => { + const codec = new UIntLongCodec(5); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 623804400001', () => { + codec.encode(buffer, 1, 623804400001); + expect(codec.decode(buffer, 1)).toBe(623804400001); + }); +}); + +describe('UIntLongCodec(6)', () => { + const codec = new UIntLongCodec(6); + const buffer = new ArrayBuffer(1 + codec.getByteLength()); + + test('Should encode/decode 281474976710655', () => { + codec.encode(buffer, 1, 281474976710655); + expect(codec.decode(buffer, 1)).toBe(281474976710655); + }); +}); diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..ce2b041 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,20 @@ +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { defineConfig } from 'vite'; + +const __dirname = dirname(fileURLToPath(import.meta.url)) + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/client/index.js'), + name: 'netcode', + fileName: 'netcode', + }, + outDir: 'dist/client', + }, + server: { + host: true, + port: 8001, + }, +}) diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 9fc54a2..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,55 +0,0 @@ -const resolve = { - alias: { - 'netcode': `${__dirname}/`, - } -} - -const clientConfig = { - target: 'web', - entry: './src/client/index.js', - output: { - filename: 'client.js', - path: __dirname, - library: 'netcode', - libraryTarget: 'umd' - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { presets: ['@babel/preset-env'] } - } - } - ] - }, - resolve, -}; - -const serverConfig = { - target: 'node', - entry: './src/server/index.js', - output: { - filename: 'server.js', - path: `${__dirname}`, - library: 'netcode', - libraryTarget: 'umd' - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { presets: [[ '@babel/preset-env', { targets: { node: true } } ]] } - } - } - ] - }, - resolve, -}; - -module.exports = [ serverConfig, clientConfig ];