├── .editorconfig ├── .gitignore ├── JavaScript ├── 1-collection.js ├── 2-wait-a-bit.js ├── 3-async-await.js ├── 4-refresh.js └── 5-cluster.js ├── LICENSE ├── README.md ├── eslint.config.js ├── package-lock.json ├── package.json └── prettier.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [{*.js,*.mjs,*.ts,*.json,*.yml}] 11 | indent_size = 2 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /JavaScript/1-collection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | const connections = new Map(); 5 | 6 | const SERVER_PORT = 8000; 7 | const LONG_RESPONSE = 60000; 8 | 9 | const server = http.createServer((req, res) => { 10 | console.log('New request'); 11 | connections.set(res.connection, res); 12 | setTimeout(() => { 13 | res.end('Example output'); 14 | }, LONG_RESPONSE); 15 | }); 16 | 17 | server.on('connection', (connection) => { 18 | console.log('New connection'); 19 | connection.on('close', () => { 20 | console.log('Close'); 21 | connections.delete(connection); 22 | }); 23 | }); 24 | 25 | server.listen(SERVER_PORT); 26 | 27 | const showConnections = () => { 28 | console.log('Connection:', [...connections.values()].length); 29 | for (const connection of connections.keys()) { 30 | const { remoteAddress, remotePort } = connection; 31 | console.log(` ${remoteAddress}:${remotePort}`); 32 | } 33 | }; 34 | 35 | const closeConnections = () => { 36 | for (const [connection, res] of connections.entries()) { 37 | connections.delete(connection); 38 | res.end('Server stopped'); 39 | connection.destroy(); 40 | } 41 | }; 42 | 43 | const freeResources = (callback) => { 44 | console.log('Free resources'); 45 | callback(); 46 | }; 47 | 48 | const gracefulShutdown = (callback) => { 49 | server.close((error) => { 50 | if (error) { 51 | console.log(error); 52 | process.exit(1); 53 | } 54 | freeResources(callback); 55 | }); 56 | closeConnections(); 57 | }; 58 | 59 | process.on('SIGINT', () => { 60 | console.log(); 61 | console.log('Graceful shutdown'); 62 | showConnections(); 63 | gracefulShutdown(() => { 64 | showConnections(); 65 | console.log('Bye'); 66 | process.exit(0); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /JavaScript/2-wait-a-bit.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | const connections = new Map(); 5 | 6 | const SERVER_PORT = 8000; 7 | const LONG_RESPONSE = 60000; 8 | const SHUTDOWN_TIMEOUT = 5000; 9 | 10 | const server = http.createServer((req, res) => { 11 | console.log('New request'); 12 | connections.set(res.connection, res); 13 | setTimeout(() => { 14 | res.end('Example output'); 15 | }, LONG_RESPONSE); 16 | }); 17 | 18 | server.on('connection', (connection) => { 19 | console.log('New connection'); 20 | connection.on('close', () => { 21 | console.log('Close'); 22 | connections.delete(connection); 23 | }); 24 | }); 25 | 26 | server.listen(SERVER_PORT); 27 | 28 | const showConnections = () => { 29 | console.log('Connection:', [...connections.values()].length); 30 | for (const connection of connections.keys()) { 31 | const { remoteAddress, remotePort } = connection; 32 | console.log(` ${remoteAddress}:${remotePort}`); 33 | } 34 | }; 35 | 36 | const closeConnections = () => { 37 | for (const [connection, res] of connections.entries()) { 38 | connections.delete(connection); 39 | res.end('Server stopped'); 40 | connection.destroy(); 41 | } 42 | }; 43 | 44 | const freeResources = (callback) => { 45 | console.log('Free resources'); 46 | callback(); 47 | }; 48 | 49 | const gracefulShutdown = (callback) => { 50 | server.close((error) => { 51 | if (error) { 52 | console.log(error); 53 | process.exit(1); 54 | } 55 | }); 56 | setTimeout(() => { 57 | freeResources(() => { 58 | closeConnections(); 59 | callback(); 60 | }); 61 | }, SHUTDOWN_TIMEOUT); 62 | }; 63 | 64 | process.on('SIGINT', () => { 65 | console.log(); 66 | console.log('Graceful shutdown'); 67 | showConnections(); 68 | gracefulShutdown(() => { 69 | showConnections(); 70 | console.log('Bye'); 71 | process.exit(0); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /JavaScript/3-async-await.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | const timers = require('node:timers/promises'); 5 | 6 | const connections = new Map(); 7 | 8 | const SERVER_PORT = 8000; 9 | const LONG_RESPONSE = 60000; 10 | const SHUTDOWN_TIMEOUT = 5000; 11 | 12 | const server = http.createServer(async (req, res) => { 13 | console.log('New request'); 14 | connections.set(res.connection, res); 15 | await timers.setTimeout(LONG_RESPONSE); 16 | res.end('Example output'); 17 | }); 18 | 19 | server.on('connection', (connection) => { 20 | console.log('New connection'); 21 | connection.on('close', () => { 22 | console.log('Close'); 23 | connections.delete(connection); 24 | }); 25 | }); 26 | 27 | server.listen(SERVER_PORT); 28 | 29 | const showConnections = () => { 30 | console.log('Connection:', [...connections.values()].length); 31 | for (const connection of connections.keys()) { 32 | const { remoteAddress, remotePort } = connection; 33 | console.log(` ${remoteAddress}:${remotePort}`); 34 | } 35 | }; 36 | 37 | const closeConnections = async () => { 38 | for (const [connection, res] of connections.entries()) { 39 | connections.delete(connection); 40 | res.end('Server stopped'); 41 | connection.destroy(); 42 | } 43 | }; 44 | 45 | const freeResources = async () => { 46 | console.log('Free resources'); 47 | }; 48 | 49 | const gracefulShutdown = async () => { 50 | server.close((error) => { 51 | if (error) { 52 | console.log(error); 53 | process.exit(1); 54 | } 55 | }); 56 | await timers.setTimeout(SHUTDOWN_TIMEOUT); 57 | await freeResources(); 58 | await closeConnections(); 59 | }; 60 | 61 | process.on('SIGINT', async () => { 62 | console.log(); 63 | console.log('Graceful shutdown'); 64 | showConnections(); 65 | await gracefulShutdown(); 66 | showConnections(); 67 | console.log('Bye'); 68 | process.exit(0); 69 | }); 70 | -------------------------------------------------------------------------------- /JavaScript/4-refresh.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('node:http'); 4 | const timers = require('node:timers/promises'); 5 | const connections = new Map(); 6 | 7 | const SERVER_PORT = 8000; 8 | const LONG_RESPONSE = 60000; 9 | const SHUTDOWN_TIMEOUT = 5000; 10 | const HTTP_REFRESH = { 11 | 'Content-Type': 'text/html', 12 | Refresh: '5', 13 | }; 14 | 15 | const server = http.createServer(async (req, res) => { 16 | console.log('New request'); 17 | connections.set(res.connection, res); 18 | await timers.setTimeout(LONG_RESPONSE); 19 | res.end('Example output'); 20 | }); 21 | 22 | server.on('connection', (connection) => { 23 | console.log('New connection'); 24 | connection.on('close', () => { 25 | console.log('Close'); 26 | connections.delete(connection); 27 | }); 28 | }); 29 | 30 | server.listen(SERVER_PORT); 31 | 32 | const showConnections = () => { 33 | console.log('Connection:', [...connections.values()].length); 34 | for (const connection of connections.keys()) { 35 | const { remoteAddress, remotePort } = connection; 36 | console.log(` ${remoteAddress}:${remotePort}`); 37 | } 38 | }; 39 | 40 | const closeConnections = async () => { 41 | for (const [connection, res] of connections.entries()) { 42 | connections.delete(connection); 43 | res.writeHead(503, HTTP_REFRESH); 44 | res.end('Service is unavailable'); 45 | connection.destroy(); 46 | } 47 | }; 48 | 49 | const freeResources = async () => { 50 | console.log('Free resources'); 51 | }; 52 | 53 | const gracefulShutdown = async () => { 54 | server.close((error) => { 55 | if (error) { 56 | console.log(error); 57 | process.exit(1); 58 | } 59 | }); 60 | await timers.setTimeout(SHUTDOWN_TIMEOUT); 61 | await freeResources(); 62 | await closeConnections(); 63 | }; 64 | 65 | process.on('SIGINT', async () => { 66 | console.log(); 67 | console.log('Graceful shutdown'); 68 | showConnections(); 69 | await gracefulShutdown(); 70 | showConnections(); 71 | console.log('Bye'); 72 | process.exit(0); 73 | }); 74 | -------------------------------------------------------------------------------- /JavaScript/5-cluster.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cluster = require('node:cluster'); 4 | const timers = require('node:timers/promises'); 5 | const http = require('node:http'); 6 | 7 | const connections = new Map(); 8 | let server = null; 9 | let child = null; 10 | 11 | const SERVER_PORT = 8000; 12 | const LONG_RESPONSE = 60000; 13 | const SHUTDOWN_TIMEOUT = 5000; 14 | const HTTP_REFRESH = { 15 | 'Content-Type': 'text/html', 16 | Refresh: '5', 17 | }; 18 | 19 | const start = () => { 20 | console.log('Fork process'); 21 | child = cluster.fork('./5-cluster.js'); 22 | child.on('message', (message) => { 23 | if (message.status === 'restarted') { 24 | console.log('Restart worker'); 25 | start(); 26 | } 27 | }); 28 | }; 29 | 30 | const showConnections = () => { 31 | console.log('Connection:', [...connections.values()].length); 32 | for (const connection of connections.keys()) { 33 | const { remoteAddress, remotePort } = connection; 34 | console.log(` ${remoteAddress}:${remotePort}`); 35 | } 36 | }; 37 | 38 | const closeConnections = async () => { 39 | for (const [connection, res] of connections.entries()) { 40 | connections.delete(connection); 41 | res.writeHead(503, HTTP_REFRESH); 42 | res.end('Service is unavailable'); 43 | connection.destroy(); 44 | } 45 | }; 46 | 47 | const freeResources = async () => { 48 | console.log('Free resources'); 49 | }; 50 | 51 | const gracefulShutdown = async () => { 52 | process.send({ status: 'restarted' }); 53 | server.close((error) => { 54 | console.log('Detach from HTTP listener'); 55 | if (error) { 56 | console.log(error); 57 | process.exit(1); 58 | } 59 | process.exit(0); 60 | }); 61 | await timers.setTimeout(SHUTDOWN_TIMEOUT); 62 | await freeResources(); 63 | await closeConnections(); 64 | }; 65 | 66 | if (cluster.isPrimary) { 67 | start(); 68 | 69 | process.on('SIGINT', async () => { 70 | child.send({ status: 'restart' }); 71 | }); 72 | } else { 73 | server = http.createServer(async (req, res) => { 74 | console.log('New request'); 75 | connections.set(res.connection, res); 76 | await timers.setTimeout(LONG_RESPONSE); 77 | res.end('Example output'); 78 | }); 79 | 80 | server.on('connection', (connection) => { 81 | console.log('New connection'); 82 | connection.on('close', () => { 83 | console.log('Close'); 84 | connections.delete(connection); 85 | }); 86 | }); 87 | 88 | server.listen(SERVER_PORT); 89 | server.on('listening', () => { 90 | console.log('Attach to HTTP listener'); 91 | }); 92 | 93 | process.on('message', async (message) => { 94 | if (message.status === 'restart') { 95 | console.log(); 96 | console.log('Graceful shutdown'); 97 | showConnections(); 98 | await gracefulShutdown(); 99 | showConnections(); 100 | console.log('Worker exited'); 101 | } 102 | }); 103 | 104 | process.on('SIGINT', () => {}); 105 | } 106 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 How.Programming.Works contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graceful shutdown for network servers 2 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const init = require('eslint-config-metarhia'); 4 | 5 | module.exports = init; 6 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patterns", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "patterns", 9 | "version": "1.0.0", 10 | "dependencies": { 11 | "eslint": "^9.12.0", 12 | "eslint-config-metarhia": "^9.1.0", 13 | "prettier": "^3.3.3" 14 | } 15 | }, 16 | "node_modules/@eslint-community/eslint-utils": { 17 | "version": "4.4.1", 18 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", 19 | "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", 20 | "license": "MIT", 21 | "dependencies": { 22 | "eslint-visitor-keys": "^3.4.3" 23 | }, 24 | "engines": { 25 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 26 | }, 27 | "funding": { 28 | "url": "https://opencollective.com/eslint" 29 | }, 30 | "peerDependencies": { 31 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 32 | } 33 | }, 34 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 35 | "version": "3.4.3", 36 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 37 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 38 | "license": "Apache-2.0", 39 | "engines": { 40 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 41 | }, 42 | "funding": { 43 | "url": "https://opencollective.com/eslint" 44 | } 45 | }, 46 | "node_modules/@eslint-community/regexpp": { 47 | "version": "4.12.1", 48 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 49 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 50 | "license": "MIT", 51 | "engines": { 52 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 53 | } 54 | }, 55 | "node_modules/@eslint/config-array": { 56 | "version": "0.19.1", 57 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", 58 | "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", 59 | "license": "Apache-2.0", 60 | "dependencies": { 61 | "@eslint/object-schema": "^2.1.5", 62 | "debug": "^4.3.1", 63 | "minimatch": "^3.1.2" 64 | }, 65 | "engines": { 66 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 67 | } 68 | }, 69 | "node_modules/@eslint/core": { 70 | "version": "0.9.1", 71 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", 72 | "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", 73 | "license": "Apache-2.0", 74 | "dependencies": { 75 | "@types/json-schema": "^7.0.15" 76 | }, 77 | "engines": { 78 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 79 | } 80 | }, 81 | "node_modules/@eslint/eslintrc": { 82 | "version": "3.2.0", 83 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", 84 | "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", 85 | "license": "MIT", 86 | "dependencies": { 87 | "ajv": "^6.12.4", 88 | "debug": "^4.3.2", 89 | "espree": "^10.0.1", 90 | "globals": "^14.0.0", 91 | "ignore": "^5.2.0", 92 | "import-fresh": "^3.2.1", 93 | "js-yaml": "^4.1.0", 94 | "minimatch": "^3.1.2", 95 | "strip-json-comments": "^3.1.1" 96 | }, 97 | "engines": { 98 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 99 | }, 100 | "funding": { 101 | "url": "https://opencollective.com/eslint" 102 | } 103 | }, 104 | "node_modules/@eslint/js": { 105 | "version": "9.17.0", 106 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", 107 | "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", 108 | "license": "MIT", 109 | "engines": { 110 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 111 | } 112 | }, 113 | "node_modules/@eslint/object-schema": { 114 | "version": "2.1.5", 115 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", 116 | "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", 117 | "license": "Apache-2.0", 118 | "engines": { 119 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 120 | } 121 | }, 122 | "node_modules/@eslint/plugin-kit": { 123 | "version": "0.2.4", 124 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", 125 | "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", 126 | "license": "Apache-2.0", 127 | "dependencies": { 128 | "levn": "^0.4.1" 129 | }, 130 | "engines": { 131 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 132 | } 133 | }, 134 | "node_modules/@humanfs/core": { 135 | "version": "0.19.1", 136 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 137 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 138 | "license": "Apache-2.0", 139 | "engines": { 140 | "node": ">=18.18.0" 141 | } 142 | }, 143 | "node_modules/@humanfs/node": { 144 | "version": "0.16.6", 145 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 146 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 147 | "license": "Apache-2.0", 148 | "dependencies": { 149 | "@humanfs/core": "^0.19.1", 150 | "@humanwhocodes/retry": "^0.3.0" 151 | }, 152 | "engines": { 153 | "node": ">=18.18.0" 154 | } 155 | }, 156 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 157 | "version": "0.3.1", 158 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 159 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 160 | "license": "Apache-2.0", 161 | "engines": { 162 | "node": ">=18.18" 163 | }, 164 | "funding": { 165 | "type": "github", 166 | "url": "https://github.com/sponsors/nzakas" 167 | } 168 | }, 169 | "node_modules/@humanwhocodes/module-importer": { 170 | "version": "1.0.1", 171 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 172 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 173 | "license": "Apache-2.0", 174 | "engines": { 175 | "node": ">=12.22" 176 | }, 177 | "funding": { 178 | "type": "github", 179 | "url": "https://github.com/sponsors/nzakas" 180 | } 181 | }, 182 | "node_modules/@humanwhocodes/retry": { 183 | "version": "0.4.1", 184 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", 185 | "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", 186 | "license": "Apache-2.0", 187 | "engines": { 188 | "node": ">=18.18" 189 | }, 190 | "funding": { 191 | "type": "github", 192 | "url": "https://github.com/sponsors/nzakas" 193 | } 194 | }, 195 | "node_modules/@pkgr/core": { 196 | "version": "0.1.1", 197 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", 198 | "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", 199 | "license": "MIT", 200 | "engines": { 201 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 202 | }, 203 | "funding": { 204 | "url": "https://opencollective.com/unts" 205 | } 206 | }, 207 | "node_modules/@types/estree": { 208 | "version": "1.0.6", 209 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 210 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 211 | "license": "MIT" 212 | }, 213 | "node_modules/@types/json-schema": { 214 | "version": "7.0.15", 215 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 216 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 217 | "license": "MIT" 218 | }, 219 | "node_modules/acorn": { 220 | "version": "8.14.0", 221 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 222 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 223 | "license": "MIT", 224 | "bin": { 225 | "acorn": "bin/acorn" 226 | }, 227 | "engines": { 228 | "node": ">=0.4.0" 229 | } 230 | }, 231 | "node_modules/acorn-jsx": { 232 | "version": "5.3.2", 233 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 234 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 235 | "license": "MIT", 236 | "peerDependencies": { 237 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 238 | } 239 | }, 240 | "node_modules/ajv": { 241 | "version": "6.12.6", 242 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 243 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 244 | "license": "MIT", 245 | "dependencies": { 246 | "fast-deep-equal": "^3.1.1", 247 | "fast-json-stable-stringify": "^2.0.0", 248 | "json-schema-traverse": "^0.4.1", 249 | "uri-js": "^4.2.2" 250 | }, 251 | "funding": { 252 | "type": "github", 253 | "url": "https://github.com/sponsors/epoberezkin" 254 | } 255 | }, 256 | "node_modules/ansi-styles": { 257 | "version": "4.3.0", 258 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 259 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 260 | "license": "MIT", 261 | "dependencies": { 262 | "color-convert": "^2.0.1" 263 | }, 264 | "engines": { 265 | "node": ">=8" 266 | }, 267 | "funding": { 268 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 269 | } 270 | }, 271 | "node_modules/argparse": { 272 | "version": "2.0.1", 273 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 274 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 275 | "license": "Python-2.0" 276 | }, 277 | "node_modules/balanced-match": { 278 | "version": "1.0.2", 279 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 280 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 281 | "license": "MIT" 282 | }, 283 | "node_modules/brace-expansion": { 284 | "version": "1.1.11", 285 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 286 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 287 | "license": "MIT", 288 | "dependencies": { 289 | "balanced-match": "^1.0.0", 290 | "concat-map": "0.0.1" 291 | } 292 | }, 293 | "node_modules/callsites": { 294 | "version": "3.1.0", 295 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 296 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 297 | "license": "MIT", 298 | "engines": { 299 | "node": ">=6" 300 | } 301 | }, 302 | "node_modules/chalk": { 303 | "version": "4.1.2", 304 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 305 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 306 | "license": "MIT", 307 | "dependencies": { 308 | "ansi-styles": "^4.1.0", 309 | "supports-color": "^7.1.0" 310 | }, 311 | "engines": { 312 | "node": ">=10" 313 | }, 314 | "funding": { 315 | "url": "https://github.com/chalk/chalk?sponsor=1" 316 | } 317 | }, 318 | "node_modules/color-convert": { 319 | "version": "2.0.1", 320 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 321 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 322 | "license": "MIT", 323 | "dependencies": { 324 | "color-name": "~1.1.4" 325 | }, 326 | "engines": { 327 | "node": ">=7.0.0" 328 | } 329 | }, 330 | "node_modules/color-name": { 331 | "version": "1.1.4", 332 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 333 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 334 | "license": "MIT" 335 | }, 336 | "node_modules/concat-map": { 337 | "version": "0.0.1", 338 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 339 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 340 | "license": "MIT" 341 | }, 342 | "node_modules/cross-spawn": { 343 | "version": "7.0.6", 344 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 345 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 346 | "license": "MIT", 347 | "dependencies": { 348 | "path-key": "^3.1.0", 349 | "shebang-command": "^2.0.0", 350 | "which": "^2.0.1" 351 | }, 352 | "engines": { 353 | "node": ">= 8" 354 | } 355 | }, 356 | "node_modules/debug": { 357 | "version": "4.4.0", 358 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 359 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 360 | "license": "MIT", 361 | "dependencies": { 362 | "ms": "^2.1.3" 363 | }, 364 | "engines": { 365 | "node": ">=6.0" 366 | }, 367 | "peerDependenciesMeta": { 368 | "supports-color": { 369 | "optional": true 370 | } 371 | } 372 | }, 373 | "node_modules/deep-is": { 374 | "version": "0.1.4", 375 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 376 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 377 | "license": "MIT" 378 | }, 379 | "node_modules/escape-string-regexp": { 380 | "version": "4.0.0", 381 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 382 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 383 | "license": "MIT", 384 | "engines": { 385 | "node": ">=10" 386 | }, 387 | "funding": { 388 | "url": "https://github.com/sponsors/sindresorhus" 389 | } 390 | }, 391 | "node_modules/eslint": { 392 | "version": "9.17.0", 393 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", 394 | "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", 395 | "license": "MIT", 396 | "dependencies": { 397 | "@eslint-community/eslint-utils": "^4.2.0", 398 | "@eslint-community/regexpp": "^4.12.1", 399 | "@eslint/config-array": "^0.19.0", 400 | "@eslint/core": "^0.9.0", 401 | "@eslint/eslintrc": "^3.2.0", 402 | "@eslint/js": "9.17.0", 403 | "@eslint/plugin-kit": "^0.2.3", 404 | "@humanfs/node": "^0.16.6", 405 | "@humanwhocodes/module-importer": "^1.0.1", 406 | "@humanwhocodes/retry": "^0.4.1", 407 | "@types/estree": "^1.0.6", 408 | "@types/json-schema": "^7.0.15", 409 | "ajv": "^6.12.4", 410 | "chalk": "^4.0.0", 411 | "cross-spawn": "^7.0.6", 412 | "debug": "^4.3.2", 413 | "escape-string-regexp": "^4.0.0", 414 | "eslint-scope": "^8.2.0", 415 | "eslint-visitor-keys": "^4.2.0", 416 | "espree": "^10.3.0", 417 | "esquery": "^1.5.0", 418 | "esutils": "^2.0.2", 419 | "fast-deep-equal": "^3.1.3", 420 | "file-entry-cache": "^8.0.0", 421 | "find-up": "^5.0.0", 422 | "glob-parent": "^6.0.2", 423 | "ignore": "^5.2.0", 424 | "imurmurhash": "^0.1.4", 425 | "is-glob": "^4.0.0", 426 | "json-stable-stringify-without-jsonify": "^1.0.1", 427 | "lodash.merge": "^4.6.2", 428 | "minimatch": "^3.1.2", 429 | "natural-compare": "^1.4.0", 430 | "optionator": "^0.9.3" 431 | }, 432 | "bin": { 433 | "eslint": "bin/eslint.js" 434 | }, 435 | "engines": { 436 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 437 | }, 438 | "funding": { 439 | "url": "https://eslint.org/donate" 440 | }, 441 | "peerDependencies": { 442 | "jiti": "*" 443 | }, 444 | "peerDependenciesMeta": { 445 | "jiti": { 446 | "optional": true 447 | } 448 | } 449 | }, 450 | "node_modules/eslint-config-metarhia": { 451 | "version": "9.1.1", 452 | "resolved": "https://registry.npmjs.org/eslint-config-metarhia/-/eslint-config-metarhia-9.1.1.tgz", 453 | "integrity": "sha512-PPJBiv+kFg7+0kkjHWp1k37TovG5prxIwiryiX8vQ6m2Jt4u4yIBjEjDd3P/RGXK7yrbMiiSyI2Z/GTWDS0C/Q==", 454 | "license": "MIT", 455 | "dependencies": { 456 | "eslint": "^9.10.0", 457 | "eslint-config-prettier": "^9.1.0", 458 | "eslint-plugin-prettier": "^5.2.1", 459 | "prettier": "^3.3.3" 460 | }, 461 | "engines": { 462 | "node": "18 || 20 || 21 || 22 || 23" 463 | }, 464 | "funding": { 465 | "type": "patreon", 466 | "url": "https://www.patreon.com/tshemsedinov" 467 | } 468 | }, 469 | "node_modules/eslint-config-prettier": { 470 | "version": "9.1.0", 471 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", 472 | "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", 473 | "license": "MIT", 474 | "bin": { 475 | "eslint-config-prettier": "bin/cli.js" 476 | }, 477 | "peerDependencies": { 478 | "eslint": ">=7.0.0" 479 | } 480 | }, 481 | "node_modules/eslint-plugin-prettier": { 482 | "version": "5.2.1", 483 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", 484 | "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", 485 | "license": "MIT", 486 | "dependencies": { 487 | "prettier-linter-helpers": "^1.0.0", 488 | "synckit": "^0.9.1" 489 | }, 490 | "engines": { 491 | "node": "^14.18.0 || >=16.0.0" 492 | }, 493 | "funding": { 494 | "url": "https://opencollective.com/eslint-plugin-prettier" 495 | }, 496 | "peerDependencies": { 497 | "@types/eslint": ">=8.0.0", 498 | "eslint": ">=8.0.0", 499 | "eslint-config-prettier": "*", 500 | "prettier": ">=3.0.0" 501 | }, 502 | "peerDependenciesMeta": { 503 | "@types/eslint": { 504 | "optional": true 505 | }, 506 | "eslint-config-prettier": { 507 | "optional": true 508 | } 509 | } 510 | }, 511 | "node_modules/eslint-scope": { 512 | "version": "8.2.0", 513 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", 514 | "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", 515 | "license": "BSD-2-Clause", 516 | "dependencies": { 517 | "esrecurse": "^4.3.0", 518 | "estraverse": "^5.2.0" 519 | }, 520 | "engines": { 521 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 522 | }, 523 | "funding": { 524 | "url": "https://opencollective.com/eslint" 525 | } 526 | }, 527 | "node_modules/eslint-visitor-keys": { 528 | "version": "4.2.0", 529 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 530 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 531 | "license": "Apache-2.0", 532 | "engines": { 533 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 534 | }, 535 | "funding": { 536 | "url": "https://opencollective.com/eslint" 537 | } 538 | }, 539 | "node_modules/espree": { 540 | "version": "10.3.0", 541 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 542 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 543 | "license": "BSD-2-Clause", 544 | "dependencies": { 545 | "acorn": "^8.14.0", 546 | "acorn-jsx": "^5.3.2", 547 | "eslint-visitor-keys": "^4.2.0" 548 | }, 549 | "engines": { 550 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 551 | }, 552 | "funding": { 553 | "url": "https://opencollective.com/eslint" 554 | } 555 | }, 556 | "node_modules/esquery": { 557 | "version": "1.6.0", 558 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 559 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 560 | "license": "BSD-3-Clause", 561 | "dependencies": { 562 | "estraverse": "^5.1.0" 563 | }, 564 | "engines": { 565 | "node": ">=0.10" 566 | } 567 | }, 568 | "node_modules/esrecurse": { 569 | "version": "4.3.0", 570 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 571 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 572 | "license": "BSD-2-Clause", 573 | "dependencies": { 574 | "estraverse": "^5.2.0" 575 | }, 576 | "engines": { 577 | "node": ">=4.0" 578 | } 579 | }, 580 | "node_modules/estraverse": { 581 | "version": "5.3.0", 582 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 583 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 584 | "license": "BSD-2-Clause", 585 | "engines": { 586 | "node": ">=4.0" 587 | } 588 | }, 589 | "node_modules/esutils": { 590 | "version": "2.0.3", 591 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 592 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 593 | "license": "BSD-2-Clause", 594 | "engines": { 595 | "node": ">=0.10.0" 596 | } 597 | }, 598 | "node_modules/fast-deep-equal": { 599 | "version": "3.1.3", 600 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 601 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 602 | "license": "MIT" 603 | }, 604 | "node_modules/fast-diff": { 605 | "version": "1.3.0", 606 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", 607 | "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", 608 | "license": "Apache-2.0" 609 | }, 610 | "node_modules/fast-json-stable-stringify": { 611 | "version": "2.1.0", 612 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 613 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 614 | "license": "MIT" 615 | }, 616 | "node_modules/fast-levenshtein": { 617 | "version": "2.0.6", 618 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 619 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 620 | "license": "MIT" 621 | }, 622 | "node_modules/file-entry-cache": { 623 | "version": "8.0.0", 624 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 625 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 626 | "license": "MIT", 627 | "dependencies": { 628 | "flat-cache": "^4.0.0" 629 | }, 630 | "engines": { 631 | "node": ">=16.0.0" 632 | } 633 | }, 634 | "node_modules/find-up": { 635 | "version": "5.0.0", 636 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 637 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 638 | "license": "MIT", 639 | "dependencies": { 640 | "locate-path": "^6.0.0", 641 | "path-exists": "^4.0.0" 642 | }, 643 | "engines": { 644 | "node": ">=10" 645 | }, 646 | "funding": { 647 | "url": "https://github.com/sponsors/sindresorhus" 648 | } 649 | }, 650 | "node_modules/flat-cache": { 651 | "version": "4.0.1", 652 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 653 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 654 | "license": "MIT", 655 | "dependencies": { 656 | "flatted": "^3.2.9", 657 | "keyv": "^4.5.4" 658 | }, 659 | "engines": { 660 | "node": ">=16" 661 | } 662 | }, 663 | "node_modules/flatted": { 664 | "version": "3.3.2", 665 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", 666 | "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", 667 | "license": "ISC" 668 | }, 669 | "node_modules/glob-parent": { 670 | "version": "6.0.2", 671 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 672 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 673 | "license": "ISC", 674 | "dependencies": { 675 | "is-glob": "^4.0.3" 676 | }, 677 | "engines": { 678 | "node": ">=10.13.0" 679 | } 680 | }, 681 | "node_modules/globals": { 682 | "version": "14.0.0", 683 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 684 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 685 | "license": "MIT", 686 | "engines": { 687 | "node": ">=18" 688 | }, 689 | "funding": { 690 | "url": "https://github.com/sponsors/sindresorhus" 691 | } 692 | }, 693 | "node_modules/has-flag": { 694 | "version": "4.0.0", 695 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 696 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 697 | "license": "MIT", 698 | "engines": { 699 | "node": ">=8" 700 | } 701 | }, 702 | "node_modules/ignore": { 703 | "version": "5.3.2", 704 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 705 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 706 | "license": "MIT", 707 | "engines": { 708 | "node": ">= 4" 709 | } 710 | }, 711 | "node_modules/import-fresh": { 712 | "version": "3.3.0", 713 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 714 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 715 | "license": "MIT", 716 | "dependencies": { 717 | "parent-module": "^1.0.0", 718 | "resolve-from": "^4.0.0" 719 | }, 720 | "engines": { 721 | "node": ">=6" 722 | }, 723 | "funding": { 724 | "url": "https://github.com/sponsors/sindresorhus" 725 | } 726 | }, 727 | "node_modules/imurmurhash": { 728 | "version": "0.1.4", 729 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 730 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 731 | "license": "MIT", 732 | "engines": { 733 | "node": ">=0.8.19" 734 | } 735 | }, 736 | "node_modules/is-extglob": { 737 | "version": "2.1.1", 738 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 739 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 740 | "license": "MIT", 741 | "engines": { 742 | "node": ">=0.10.0" 743 | } 744 | }, 745 | "node_modules/is-glob": { 746 | "version": "4.0.3", 747 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 748 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 749 | "license": "MIT", 750 | "dependencies": { 751 | "is-extglob": "^2.1.1" 752 | }, 753 | "engines": { 754 | "node": ">=0.10.0" 755 | } 756 | }, 757 | "node_modules/isexe": { 758 | "version": "2.0.0", 759 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 760 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 761 | "license": "ISC" 762 | }, 763 | "node_modules/js-yaml": { 764 | "version": "4.1.0", 765 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 766 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 767 | "license": "MIT", 768 | "dependencies": { 769 | "argparse": "^2.0.1" 770 | }, 771 | "bin": { 772 | "js-yaml": "bin/js-yaml.js" 773 | } 774 | }, 775 | "node_modules/json-buffer": { 776 | "version": "3.0.1", 777 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 778 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 779 | "license": "MIT" 780 | }, 781 | "node_modules/json-schema-traverse": { 782 | "version": "0.4.1", 783 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 784 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 785 | "license": "MIT" 786 | }, 787 | "node_modules/json-stable-stringify-without-jsonify": { 788 | "version": "1.0.1", 789 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 790 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 791 | "license": "MIT" 792 | }, 793 | "node_modules/keyv": { 794 | "version": "4.5.4", 795 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 796 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 797 | "license": "MIT", 798 | "dependencies": { 799 | "json-buffer": "3.0.1" 800 | } 801 | }, 802 | "node_modules/levn": { 803 | "version": "0.4.1", 804 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 805 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 806 | "license": "MIT", 807 | "dependencies": { 808 | "prelude-ls": "^1.2.1", 809 | "type-check": "~0.4.0" 810 | }, 811 | "engines": { 812 | "node": ">= 0.8.0" 813 | } 814 | }, 815 | "node_modules/locate-path": { 816 | "version": "6.0.0", 817 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 818 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 819 | "license": "MIT", 820 | "dependencies": { 821 | "p-locate": "^5.0.0" 822 | }, 823 | "engines": { 824 | "node": ">=10" 825 | }, 826 | "funding": { 827 | "url": "https://github.com/sponsors/sindresorhus" 828 | } 829 | }, 830 | "node_modules/lodash.merge": { 831 | "version": "4.6.2", 832 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 833 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 834 | "license": "MIT" 835 | }, 836 | "node_modules/minimatch": { 837 | "version": "3.1.2", 838 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 839 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 840 | "license": "ISC", 841 | "dependencies": { 842 | "brace-expansion": "^1.1.7" 843 | }, 844 | "engines": { 845 | "node": "*" 846 | } 847 | }, 848 | "node_modules/ms": { 849 | "version": "2.1.3", 850 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 851 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 852 | "license": "MIT" 853 | }, 854 | "node_modules/natural-compare": { 855 | "version": "1.4.0", 856 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 857 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 858 | "license": "MIT" 859 | }, 860 | "node_modules/optionator": { 861 | "version": "0.9.4", 862 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 863 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 864 | "license": "MIT", 865 | "dependencies": { 866 | "deep-is": "^0.1.3", 867 | "fast-levenshtein": "^2.0.6", 868 | "levn": "^0.4.1", 869 | "prelude-ls": "^1.2.1", 870 | "type-check": "^0.4.0", 871 | "word-wrap": "^1.2.5" 872 | }, 873 | "engines": { 874 | "node": ">= 0.8.0" 875 | } 876 | }, 877 | "node_modules/p-limit": { 878 | "version": "3.1.0", 879 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 880 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 881 | "license": "MIT", 882 | "dependencies": { 883 | "yocto-queue": "^0.1.0" 884 | }, 885 | "engines": { 886 | "node": ">=10" 887 | }, 888 | "funding": { 889 | "url": "https://github.com/sponsors/sindresorhus" 890 | } 891 | }, 892 | "node_modules/p-locate": { 893 | "version": "5.0.0", 894 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 895 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 896 | "license": "MIT", 897 | "dependencies": { 898 | "p-limit": "^3.0.2" 899 | }, 900 | "engines": { 901 | "node": ">=10" 902 | }, 903 | "funding": { 904 | "url": "https://github.com/sponsors/sindresorhus" 905 | } 906 | }, 907 | "node_modules/parent-module": { 908 | "version": "1.0.1", 909 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 910 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 911 | "license": "MIT", 912 | "dependencies": { 913 | "callsites": "^3.0.0" 914 | }, 915 | "engines": { 916 | "node": ">=6" 917 | } 918 | }, 919 | "node_modules/path-exists": { 920 | "version": "4.0.0", 921 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 922 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 923 | "license": "MIT", 924 | "engines": { 925 | "node": ">=8" 926 | } 927 | }, 928 | "node_modules/path-key": { 929 | "version": "3.1.1", 930 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 931 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 932 | "license": "MIT", 933 | "engines": { 934 | "node": ">=8" 935 | } 936 | }, 937 | "node_modules/prelude-ls": { 938 | "version": "1.2.1", 939 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 940 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 941 | "license": "MIT", 942 | "engines": { 943 | "node": ">= 0.8.0" 944 | } 945 | }, 946 | "node_modules/prettier": { 947 | "version": "3.4.2", 948 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", 949 | "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", 950 | "license": "MIT", 951 | "bin": { 952 | "prettier": "bin/prettier.cjs" 953 | }, 954 | "engines": { 955 | "node": ">=14" 956 | }, 957 | "funding": { 958 | "url": "https://github.com/prettier/prettier?sponsor=1" 959 | } 960 | }, 961 | "node_modules/prettier-linter-helpers": { 962 | "version": "1.0.0", 963 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 964 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 965 | "license": "MIT", 966 | "dependencies": { 967 | "fast-diff": "^1.1.2" 968 | }, 969 | "engines": { 970 | "node": ">=6.0.0" 971 | } 972 | }, 973 | "node_modules/punycode": { 974 | "version": "2.3.1", 975 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 976 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 977 | "license": "MIT", 978 | "engines": { 979 | "node": ">=6" 980 | } 981 | }, 982 | "node_modules/resolve-from": { 983 | "version": "4.0.0", 984 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 985 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 986 | "license": "MIT", 987 | "engines": { 988 | "node": ">=4" 989 | } 990 | }, 991 | "node_modules/shebang-command": { 992 | "version": "2.0.0", 993 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 994 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 995 | "license": "MIT", 996 | "dependencies": { 997 | "shebang-regex": "^3.0.0" 998 | }, 999 | "engines": { 1000 | "node": ">=8" 1001 | } 1002 | }, 1003 | "node_modules/shebang-regex": { 1004 | "version": "3.0.0", 1005 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1006 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1007 | "license": "MIT", 1008 | "engines": { 1009 | "node": ">=8" 1010 | } 1011 | }, 1012 | "node_modules/strip-json-comments": { 1013 | "version": "3.1.1", 1014 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1015 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1016 | "license": "MIT", 1017 | "engines": { 1018 | "node": ">=8" 1019 | }, 1020 | "funding": { 1021 | "url": "https://github.com/sponsors/sindresorhus" 1022 | } 1023 | }, 1024 | "node_modules/supports-color": { 1025 | "version": "7.2.0", 1026 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1027 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1028 | "license": "MIT", 1029 | "dependencies": { 1030 | "has-flag": "^4.0.0" 1031 | }, 1032 | "engines": { 1033 | "node": ">=8" 1034 | } 1035 | }, 1036 | "node_modules/synckit": { 1037 | "version": "0.9.2", 1038 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", 1039 | "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", 1040 | "license": "MIT", 1041 | "dependencies": { 1042 | "@pkgr/core": "^0.1.0", 1043 | "tslib": "^2.6.2" 1044 | }, 1045 | "engines": { 1046 | "node": "^14.18.0 || >=16.0.0" 1047 | }, 1048 | "funding": { 1049 | "url": "https://opencollective.com/unts" 1050 | } 1051 | }, 1052 | "node_modules/tslib": { 1053 | "version": "2.8.1", 1054 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1055 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 1056 | "license": "0BSD" 1057 | }, 1058 | "node_modules/type-check": { 1059 | "version": "0.4.0", 1060 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1061 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1062 | "license": "MIT", 1063 | "dependencies": { 1064 | "prelude-ls": "^1.2.1" 1065 | }, 1066 | "engines": { 1067 | "node": ">= 0.8.0" 1068 | } 1069 | }, 1070 | "node_modules/uri-js": { 1071 | "version": "4.4.1", 1072 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1073 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1074 | "license": "BSD-2-Clause", 1075 | "dependencies": { 1076 | "punycode": "^2.1.0" 1077 | } 1078 | }, 1079 | "node_modules/which": { 1080 | "version": "2.0.2", 1081 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1082 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1083 | "license": "ISC", 1084 | "dependencies": { 1085 | "isexe": "^2.0.0" 1086 | }, 1087 | "bin": { 1088 | "node-which": "bin/node-which" 1089 | }, 1090 | "engines": { 1091 | "node": ">= 8" 1092 | } 1093 | }, 1094 | "node_modules/word-wrap": { 1095 | "version": "1.2.5", 1096 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 1097 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 1098 | "license": "MIT", 1099 | "engines": { 1100 | "node": ">=0.10.0" 1101 | } 1102 | }, 1103 | "node_modules/yocto-queue": { 1104 | "version": "0.1.0", 1105 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1106 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1107 | "license": "MIT", 1108 | "engines": { 1109 | "node": ">=10" 1110 | }, 1111 | "funding": { 1112 | "url": "https://github.com/sponsors/sindresorhus" 1113 | } 1114 | } 1115 | } 1116 | } 1117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patterns", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "lint": "eslint . && prettier -c \"**/*.js\"", 6 | "fix": "eslint . --fix && prettier --write \"**/*.js\"" 7 | }, 8 | "author": "Timur Shemsedinov", 9 | "private": true, 10 | "dependencies": { 11 | "eslint": "^9.12.0", 12 | "eslint-config-metarhia": "^9.1.0", 13 | "prettier": "^3.3.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | printWidth: 80, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | tabWidth: 2, 8 | useTabs: false, 9 | semi: true, 10 | }; 11 | --------------------------------------------------------------------------------