├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── config.json ├── http-client.env.json ├── jest.config.js ├── package-lock.json ├── package.json ├── patches └── @ulixee+hero-core+2.0.0-alpha.28.patch ├── playground.http ├── src ├── clases │ ├── Logger.ts │ ├── Task.ts │ ├── TasksPoolHandler.ts │ ├── Timings.ts │ └── WebServer.ts ├── enums │ └── TaskStatus.ts ├── exceptions │ └── TaskSessionTimeout.ts ├── helpers │ ├── AsyncFuncion.ts │ ├── EnvHelper.ts │ ├── ErrorHelper.ts │ ├── ISODate.ts │ └── OSHelper.ts ├── index.ts ├── plugins │ └── .gitkeep └── types │ ├── .gitkeep │ ├── ITaskOptions.ts │ ├── ITasksPoolHandler.ts │ └── IWebServerConfig.ts ├── tests ├── scenarios │ ├── ExampleTitle.js │ ├── FetchTest.js │ └── UnhandledRejection.js ├── simulation_test.sh └── test.js ├── tsconfig.json └── windwos_generate_stamp.bat /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Private environment variables 107 | http-client.private.env.json -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20.17-slim 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | # Fonts as packages 6 | RUN echo "deb http://httpredir.debian.org/debian buster main contrib non-free" > /etc/apt/sources.list \ 7 | && echo "deb http://httpredir.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list \ 8 | && echo "deb http://security.debian.org/ buster/updates main contrib non-free" >> /etc/apt/sources.list \ 9 | && echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections \ 10 | && apt-get update 11 | 12 | 13 | #libudev1 - hot fix downgade for chrome 109, remove when install dep will be fixed 14 | RUN apt-get install -y --allow-downgrades \ 15 | wget \ 16 | fonts-arphic-ukai \ 17 | fonts-arphic-uming \ 18 | fonts-ipafont-mincho \ 19 | fonts-thai-tlwg \ 20 | fonts-kacst \ 21 | fonts-ipafont-gothic \ 22 | fonts-unfonts-core \ 23 | ttf-wqy-zenhei \ 24 | ttf-mscorefonts-installer \ 25 | fonts-freefont-ttf \ 26 | libudev1=241-7~deb10u8 \ 27 | && apt-get clean \ 28 | && apt-get autoremove -y \ 29 | && rm -rf /var/lib/apt/lists/* 30 | 31 | ## Fonts from google 32 | #RUN wget -O /tmp/master.tar.gz "https://github.com/google/fonts/archive/main.tar.gz" -q --progress=bar; \ 33 | # mkdir -p /tmp/google-fonts/fonts; \ 34 | # tar -zxf /tmp/master.tar.gz -C /tmp/google-fonts/fonts; \ 35 | # find /tmp/google-fonts/fonts/ -type f -name "*.ttf" -exec cp {} "/usr/local/share/fonts/" \\\;; \ 36 | # rm -f /tmp/master.tar.gz; \ 37 | # rm -rf /tmp/google-fonts; 38 | 39 | WORKDIR /app/www 40 | RUN mkdir -p /opt/bin && chmod +x /dev/shm 41 | 42 | RUN npm install -g npm@latest 43 | RUN npm config set update-notifier false 44 | 45 | COPY ./config.json /app/www 46 | COPY ./tsconfig.json /app/www 47 | COPY ./package.json /app/www 48 | COPY ./package-lock.json /app/www 49 | RUN npm install -ci 50 | 51 | RUN sh $(npx install-browser-deps) 52 | 53 | COPY ./src /app/www/src 54 | RUN npm run build 55 | 56 | #ENV ULX_DEBUG true 57 | #ENV DEBUG true 58 | 59 | #for testing on low memory machines 60 | #ENV CONCURRENCY_DISABLE_MEM_LIMITER true 61 | 62 | ENV NODE_ENV production 63 | ENV ULX_NO_CHROME_SANDBOX true 64 | 65 | RUN rm -rf /app/www/src 66 | 67 | EXPOSE 8080 68 | CMD ["npm", "run", "start"] 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 LuKa 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 | # Headless Task Server 2 | 3 | A headless browser task server based on [Hero](https://github.com/ulixee/hero). 4 | 5 | - Hero is a web browser that's built for scraping. 6 | - This task server allow you to process multiple task simultaneously on single server instance 7 | - Has [Helper](https://github.com/luka-dev/headless-task-server-php#helpers) for PHP to make request easy 8 | 9 | # Install 10 | 11 | - Install dependencies 12 | 13 | ```bash 14 | npm install 15 | ``` 16 | 17 | - Make build 18 | 19 | ```bash 20 | npm run build 21 | ``` 22 | 23 | - Now we can run it directly on machine 24 | > NOTE: Viewing browser and replays will work only on machine 25 | 26 | - Docker way 27 | > 28 | > - Build Docker image 29 | > ```bash 30 | > docker build -t headless-task-server:latest . 31 | > ``` 32 | > - Run Docker image 33 | > ```bash 34 | > docker run -p 8080:8080 headless-task-server:latest 35 | > ``` 36 | 37 | - Directly on machine way 38 | > - Run task server 39 | > 40 | > ```bash 41 | > npm run start 42 | > ``` 43 | 44 | - #### Enjoy 45 | 46 | ### Additional ENVs: 47 | - `AUTH_KEY` - Auth key for requests, default `null` 48 | - `SERVER_PORT` - Server port, default `8080` 49 | - `UPSTREAM_PROXY_URL` - Default proxy for script, default `null`, also can be set personally for each task in options `upstreamProxyUrl` 50 | - `QUEUE_TIMEOUT` - Max queue waiting time. Ends when task moved from `queue` to `pool`, default `30000` (30 sec) 51 | - `INIT_TIMEOUT` - Max waiting time, to launch new chrome context for task. Runs when task moved to `pool`, default `15000` (15 sec) 52 | - `SESSION_TIMEOUT` - Max task script execution time inside `pool`/ Counts only after context created, default `60000` (1 min) 53 | - `MAX_CONCURRENCY` - Limit of concurrent tasks, default `5` 54 | > NOTE: If you want to calculate custom value, you can use this formula `MAX_CONCURRENCY = (FREE_RAM - 1.5GB) / 0.5GB`, also to prevent stuttering avg formula for CPU is `MAX_CONCURRENCY = CPU_CORES_COUNT * 2` 55 | - `CONCURRENCY_DISABLE_MEM_LIMITER` - Memory limiter for concurrency, can be disabled with `true`. 56 | > NOTE: If free memory less than 500MB, new task wouldn't be runned until memory will be free.\ 57 | > For example, when chrome instance will be closed after finishing tasks, memory will be free.\ 58 | > Due to chrome/chromium specific behavior, memory can't be freed immediately, so we need to wait for it. 59 | - `TELEGRAM_TOKEN` & `TELEGRAM_CHAT_ID` - Telegram bot token and chat id for sending logs on crash or restart, default `null` 60 | - `DEBUG` & `ULX_DEBUG` - Enable debug mode, default `false` 61 | - `SHOW_CHROME` - Show browser window, default `false`. Works only on systems with GUI 62 | > NOTE: On non GUI systems will crash! If you want to see browser window, you need to set `SHOW_CHROME` to `true` and run server directly on machine, not in Docker. 63 | 64 | 65 | 66 | # Usage 67 | 68 | > Example IP `127.0.0.1`. 69 | > 70 | > Auth work via header `Authorization`. 71 | > 72 | > Auth key loading from `config.json` and overwriting with env `AUTH_KEY` 73 | 74 | - Health Check 75 | 76 | > ```http request 77 | > GET http://127.0.0.1:8080/ 78 | > ``` 79 | > 80 | > ```json 81 | > {"health": "ok"} 82 | > ``` 83 | 84 | - Stats info 85 | > ```http request 86 | > Authorization: MySecretAuthKey_IfNoKey_RemoveThisHeader 87 | > GET http://127.0.0.1:8080/stats 88 | > ``` 89 | > 90 | > 91 | > ```jsonc 92 | > { 93 | > "timestamp": { 94 | > "build": "2023-02-23T11:22:04", 95 | > "run": "2023-02-23T11:22:07" 96 | > }, 97 | > "task": { 98 | > "timeout": { 99 | > "session": 60000, //timeout task script execution 100 | > "queue": 30000, //max time waiting in queue 101 | > "init": 15000 //timeout for waiting for new chrome context 102 | > }, 103 | > "concurrency": 1, 104 | > "pool": 0, 105 | > "queue": 0, 106 | > "counter": { 107 | > "total": 4, 108 | > "resolve": 1, //reports when script passed successfully 109 | > "reject": 2, //if task script find thats it's not possible to continue, script will report reject 110 | > "throw": 1, //thrown by task script, but not catched inside. For example, goto timeout 111 | > "init_error": 0, //if chrome context throw error. Usualy, proxy is not valid or dead 112 | > "bad_args": 0 //if post params is not valid 113 | > "queue_timeout": 0, 114 | > "init_timeout": 0, 115 | > "session_timeout": 0 116 | > } 117 | > }, 118 | > "server": { 119 | > "uptime": 316034, 120 | > "platform": "darwin", 121 | > "arch": "x64", 122 | > "cores": 8, 123 | > "ram": { 124 | > "total": 8192, 125 | > "free": 98, 126 | > "used": 8093 127 | > } 128 | > } 129 | > } 130 | 131 | 132 | - Last 1000 logs 133 | > ```http request 134 | > Authorization: MySecretAuthKey_IfNoKey_RemoveThisHeader 135 | > GET http://127.0.0.1:8080/logs 136 | > ``` 137 | > 138 | > 139 | > ```json 140 | > [ 141 | > "Runned on port:8080", 142 | > "APP Runned in InSecure mode!", 143 | > "Browser Handler runned" 144 | > ] 145 | > ``` 146 | 147 | 148 | - Create Task 149 | > ```http request 150 | > Authorization: MySecretAuthKey_IfNoKey_RemoveThisHeader 151 | > Content-Type: application/json 152 | > POST http://127.0.0.1:8080/task 153 | > 154 | > { 155 | > "options": { 156 | > "upstreamProxyUrl": "http://username:password@proxy.com:80" 157 | > }, 158 | > "script": "await agent.goto('https://example.com/'); resolve(await agent.document.title);" 159 | > } 160 | > ``` 161 | > > NOTE: Example proxy `upstreamProxyUrl` didn't work, you can use any proxy that support HTTP/SOCKS5 protocol, or you can remove this option to use without proxy. 162 | > - Contain next script 163 | > ```js 164 | > await agent.goto('https://example.com/'); 165 | > resolve(await agent.document.title); 166 | > ``` 167 | > - Expected Output 168 | > ```jsonc 169 | > "Example Domain" 170 | > ``` 171 | > - Whole Response 172 | > ```jsonc 173 | > { 174 | > "status": "RESOLVE", //Look at TaskStatus.ts 175 | > "timings": { 176 | > "begin_at": "2022-01-31T12:46:54", 177 | > "end_at": "2022-01-31T12:46:56", 178 | > "created_at": "2022-01-31T12:46:52" 179 | > }, 180 | > "options": {}, //Options that you provided 181 | > "profile": { //Profile of faked user and browser, can be saved for future use as same user. 182 | > "cookies": [], 183 | > "storage": { 184 | > "https://example.com": { 185 | > "indexedDB": [], 186 | > "localStorage": [], 187 | > "sessionStorage": [] 188 | > } 189 | > }, 190 | > "userAgentString": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", 191 | > "deviceProfile": { 192 | > "deviceMemory": 4, 193 | > "videoDevice": { 194 | > "deviceId": "b77e4f6d9c9949f7941d53eb325ed152449b0941ba9268d75cae92f181f4995c", 195 | > "groupId": "ea79bf7882892b623152146391861a55a91a3269f74d1bfd09eaaf316669cb1e" 196 | > }, 197 | > "maxHeapSize": 2172649472, 198 | > "webGlParameters": { 199 | > "37445": "Intel Inc.", 200 | > "37446": "Intel Iris OpenGL Engine" 201 | > } 202 | > } 203 | > }, 204 | > "output": "Example Domain", //Output from script 205 | > "error": null //Error if any 206 | > } 207 | > ``` 208 | 209 | # How to write custom script? 210 | Welcome to official [DOCS of Hero](https://ulixee.org/docs/hero/basic-client/hero), your script should be in payload, property `script` as a `string`.\ 211 | In payload, you can provide any [options](https://ulixee.org/docs/hero/basic-client/hero#constructor) for `Hero`.\ 212 | Script starts in isolated `async` context, with const named `agent`, its your per-request `Hero` instance.\ 213 | All output from script should be passed into `resolve` function.\ 214 | If you want to pass error, use `reject` function. -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "AUTH_KEY": null, 3 | "SERVER_PORT": 8080, 4 | "DEFAULT_MAX_CONCURRENCY": 5, 5 | "DEFAULT_QUEUE_TIMEOUT": 30000, 6 | "DEFAULT_INIT_TIMEOUT": 15000, 7 | "DEFAULT_SESSION_TIMEOUT": 60000, 8 | "DEFAULT_UPSTREAM_PROXY_URL": null, 9 | "DEFAULT_BLOCKED_RESOURCE_TYPES": ["BlockCssAssets", "BlockImages"] 10 | } -------------------------------------------------------------------------------- /http-client.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "host": "http://127.0.0.1:8080", 4 | "auth_key": "" 5 | } 6 | } -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node' 5 | }; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "headless-task-server", 3 | "version": "1.4.4", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "headless-task-server", 9 | "version": "1.4.4", 10 | "hasInstallScript": true, 11 | "license": "MIT", 12 | "dependencies": { 13 | "@ulixee/execute-js-plugin": "^2.0.0-alpha.28", 14 | "@ulixee/hero": "^2.0.0-alpha.28", 15 | "@ulixee/hero-core": "^2.0.0-alpha.28", 16 | "axios": "^1.3.4", 17 | "cors": "^2.8.5", 18 | "express": "^4.17.1", 19 | "form-data": "^4.0.0", 20 | "fs": "^0.0.2", 21 | "helmet": "^5.0.2", 22 | "os": "^0.1.2", 23 | "patch-package": "^6.5.1", 24 | "run-script-os": "^1.1.6" 25 | }, 26 | "devDependencies": { 27 | "@types/cli-progress": "^3.11.0", 28 | "@types/command-line-args": "^5.2.0", 29 | "@types/cors": "^2.8.12", 30 | "@types/express": "^4.17.13", 31 | "@types/node": "^17.0.23", 32 | "rimraf": "^3.0.2", 33 | "ts-node": "^10.4.0", 34 | "typescript": "^4.5.2" 35 | }, 36 | "engines": { 37 | "node": ">=18.13" 38 | } 39 | }, 40 | "node_modules/@cspotcode/source-map-support": { 41 | "version": "0.8.1", 42 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 43 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 44 | "dev": true, 45 | "dependencies": { 46 | "@jridgewell/trace-mapping": "0.3.9" 47 | }, 48 | "engines": { 49 | "node": ">=12" 50 | } 51 | }, 52 | "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { 53 | "version": "0.3.9", 54 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 55 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 56 | "dev": true, 57 | "dependencies": { 58 | "@jridgewell/resolve-uri": "^3.0.3", 59 | "@jridgewell/sourcemap-codec": "^1.4.10" 60 | } 61 | }, 62 | "node_modules/@jridgewell/resolve-uri": { 63 | "version": "3.1.2", 64 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 65 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 66 | "engines": { 67 | "node": ">=6.0.0" 68 | } 69 | }, 70 | "node_modules/@jridgewell/sourcemap-codec": { 71 | "version": "1.4.15", 72 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 73 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" 74 | }, 75 | "node_modules/@jridgewell/trace-mapping": { 76 | "version": "0.3.25", 77 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 78 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 79 | "dependencies": { 80 | "@jridgewell/resolve-uri": "^3.1.0", 81 | "@jridgewell/sourcemap-codec": "^1.4.14" 82 | } 83 | }, 84 | "node_modules/@leichtgewicht/ip-codec": { 85 | "version": "2.0.4", 86 | "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", 87 | "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" 88 | }, 89 | "node_modules/@tsconfig/node10": { 90 | "version": "1.0.9", 91 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", 92 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", 93 | "dev": true 94 | }, 95 | "node_modules/@tsconfig/node12": { 96 | "version": "1.0.11", 97 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 98 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", 99 | "dev": true 100 | }, 101 | "node_modules/@tsconfig/node14": { 102 | "version": "1.0.3", 103 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 104 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", 105 | "dev": true 106 | }, 107 | "node_modules/@tsconfig/node16": { 108 | "version": "1.0.4", 109 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 110 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", 111 | "dev": true 112 | }, 113 | "node_modules/@types/body-parser": { 114 | "version": "1.19.5", 115 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", 116 | "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", 117 | "dev": true, 118 | "dependencies": { 119 | "@types/connect": "*", 120 | "@types/node": "*" 121 | } 122 | }, 123 | "node_modules/@types/cli-progress": { 124 | "version": "3.11.5", 125 | "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.5.tgz", 126 | "integrity": "sha512-D4PbNRbviKyppS5ivBGyFO29POlySLmA2HyUFE4p5QGazAMM3CwkKWcvTl8gvElSuxRh6FPKL8XmidX873ou4g==", 127 | "dev": true, 128 | "dependencies": { 129 | "@types/node": "*" 130 | } 131 | }, 132 | "node_modules/@types/command-line-args": { 133 | "version": "5.2.3", 134 | "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", 135 | "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", 136 | "dev": true 137 | }, 138 | "node_modules/@types/connect": { 139 | "version": "3.4.38", 140 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", 141 | "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", 142 | "dev": true, 143 | "dependencies": { 144 | "@types/node": "*" 145 | } 146 | }, 147 | "node_modules/@types/cors": { 148 | "version": "2.8.17", 149 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", 150 | "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", 151 | "dev": true, 152 | "dependencies": { 153 | "@types/node": "*" 154 | } 155 | }, 156 | "node_modules/@types/express": { 157 | "version": "4.17.21", 158 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", 159 | "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", 160 | "dev": true, 161 | "dependencies": { 162 | "@types/body-parser": "*", 163 | "@types/express-serve-static-core": "^4.17.33", 164 | "@types/qs": "*", 165 | "@types/serve-static": "*" 166 | } 167 | }, 168 | "node_modules/@types/express-serve-static-core": { 169 | "version": "4.17.43", 170 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", 171 | "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", 172 | "dev": true, 173 | "dependencies": { 174 | "@types/node": "*", 175 | "@types/qs": "*", 176 | "@types/range-parser": "*", 177 | "@types/send": "*" 178 | } 179 | }, 180 | "node_modules/@types/http-errors": { 181 | "version": "2.0.4", 182 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", 183 | "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", 184 | "dev": true 185 | }, 186 | "node_modules/@types/mime": { 187 | "version": "1.3.5", 188 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", 189 | "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", 190 | "dev": true 191 | }, 192 | "node_modules/@types/node": { 193 | "version": "17.0.45", 194 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", 195 | "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", 196 | "dev": true 197 | }, 198 | "node_modules/@types/qs": { 199 | "version": "6.9.13", 200 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.13.tgz", 201 | "integrity": "sha512-iLR+1vTTJ3p0QaOUq6ACbY1mzKTODFDT/XedZI8BksOotFmL4ForwDfRQ/DZeuTHR7/2i4lI1D203gdfxuqTlA==", 202 | "dev": true 203 | }, 204 | "node_modules/@types/range-parser": { 205 | "version": "1.2.7", 206 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", 207 | "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", 208 | "dev": true 209 | }, 210 | "node_modules/@types/send": { 211 | "version": "0.17.4", 212 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", 213 | "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", 214 | "dev": true, 215 | "dependencies": { 216 | "@types/mime": "^1", 217 | "@types/node": "*" 218 | } 219 | }, 220 | "node_modules/@types/serve-static": { 221 | "version": "1.15.5", 222 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", 223 | "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", 224 | "dev": true, 225 | "dependencies": { 226 | "@types/http-errors": "*", 227 | "@types/mime": "*", 228 | "@types/node": "*" 229 | } 230 | }, 231 | "node_modules/@ulixee/awaited-dom": { 232 | "version": "1.4.2", 233 | "resolved": "https://registry.npmjs.org/@ulixee/awaited-dom/-/awaited-dom-1.4.2.tgz", 234 | "integrity": "sha512-o32b+rBzB+6qPVzLK7wB0+TcPJ0BqM81zGmZ+dCCxDMGHo030ip0bW7TBf212YvCIEFDWJNIhrLTZ8SYZd1Dkw==", 235 | "dependencies": { 236 | "@ulixee/js-path": "^2.0.0-alpha.18" 237 | } 238 | }, 239 | "node_modules/@ulixee/chrome-121-0": { 240 | "version": "6167.185.8", 241 | "resolved": "https://registry.npmjs.org/@ulixee/chrome-121-0/-/chrome-121-0-6167.185.8.tgz", 242 | "integrity": "sha512-GSD0wNxE+dNSEOUNlmyOrKe4bjuTm6g/jXgtxpkFfxHIPDzlJB1vjZ9S3TrnPRVwKOlNuV0rRXgVp1u/+V9D6A==", 243 | "hasInstallScript": true, 244 | "dependencies": { 245 | "@ulixee/chrome-app": "^1.0.3" 246 | } 247 | }, 248 | "node_modules/@ulixee/chrome-app": { 249 | "version": "1.0.3", 250 | "resolved": "https://registry.npmjs.org/@ulixee/chrome-app/-/chrome-app-1.0.3.tgz", 251 | "integrity": "sha512-VhotXRa364M2aym8urvEJ0e1o55dV4gWttAVb0M20xWjpUCIpyBfvO6mz69J40+K/SAVa6ne9mXkiFBFz6g/8g==", 252 | "dependencies": { 253 | "https-proxy-agent": "^5.0.0", 254 | "progress": "^2.0.3", 255 | "tar": "^6.1.11" 256 | }, 257 | "bin": { 258 | "install-browser-deps": "bin/installDeps.js" 259 | } 260 | }, 261 | "node_modules/@ulixee/commons": { 262 | "version": "2.0.0-alpha.28", 263 | "resolved": "https://registry.npmjs.org/@ulixee/commons/-/commons-2.0.0-alpha.28.tgz", 264 | "integrity": "sha512-/WXy+4yRr7GMCZYuYiqpiv4qEhfOrgDL8jZ85H4I+uyPIxgSTk8TWujHp5XkieE/4AbIwb8I4Q/lE+0TKKPGUQ==", 265 | "dependencies": { 266 | "@jridgewell/trace-mapping": "^0.3.18", 267 | "bech32": "^2.0.0", 268 | "devtools-protocol": "^0.0.1137505", 269 | "https-proxy-agent": "^5.0.0", 270 | "semver": "^7.3.7" 271 | }, 272 | "engines": { 273 | "node": ">=18.0.0" 274 | } 275 | }, 276 | "node_modules/@ulixee/default-browser-emulator": { 277 | "version": "2.0.0-alpha.28", 278 | "resolved": "https://registry.npmjs.org/@ulixee/default-browser-emulator/-/default-browser-emulator-2.0.0-alpha.28.tgz", 279 | "integrity": "sha512-5ZoKUgvl4wZ3whaXg8gdTUvswJFky4WtxWW19UJqadoJVgo/CI8DPmAc5cUfF3mMyBYViiRUi6/3lOxfyUCksw==", 280 | "dependencies": { 281 | "@ulixee/chrome-app": "^1.0.3", 282 | "@ulixee/commons": "2.0.0-alpha.28", 283 | "@ulixee/real-user-agents": "2.0.0-alpha.28", 284 | "@ulixee/unblocked-agent-mitm-socket": "2.0.0-alpha.28", 285 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 286 | "compare-versions": "^6.1.0", 287 | "nanoid": "^3.3.6", 288 | "tough-cookie": "^4.1.3", 289 | "ua-parser-js": "^1.0.37" 290 | }, 291 | "engines": { 292 | "node": ">=18" 293 | } 294 | }, 295 | "node_modules/@ulixee/default-human-emulator": { 296 | "version": "2.0.0-alpha.28", 297 | "resolved": "https://registry.npmjs.org/@ulixee/default-human-emulator/-/default-human-emulator-2.0.0-alpha.28.tgz", 298 | "integrity": "sha512-6vQmBiTaiWEpMDKYjt6dowUsa5aXrBg6Pok0SQAC/GWSQdkz0VFeE/7BCsrt4hPnwZfhadX3PS/MQXRoe2Hk+w==", 299 | "dependencies": { 300 | "@ulixee/commons": "2.0.0-alpha.28", 301 | "@ulixee/unblocked-specification": "2.0.0-alpha.28" 302 | }, 303 | "engines": { 304 | "node": ">=18" 305 | } 306 | }, 307 | "node_modules/@ulixee/execute-js-plugin": { 308 | "version": "2.0.0-alpha.28", 309 | "resolved": "https://registry.npmjs.org/@ulixee/execute-js-plugin/-/execute-js-plugin-2.0.0-alpha.28.tgz", 310 | "integrity": "sha512-idjNBYrBlDZ+YbS5Kg+4fOohXZTV3uAKEZnw/Ow+XFw0JsrL19jiHFy60iBOT1ol+q+BcGQAJPsK5HSu6M8OBA==", 311 | "dependencies": { 312 | "@ulixee/hero-interfaces": "2.0.0-alpha.28", 313 | "@ulixee/hero-plugin-utils": "2.0.0-alpha.28" 314 | }, 315 | "engines": { 316 | "node": ">=18" 317 | } 318 | }, 319 | "node_modules/@ulixee/hero": { 320 | "version": "2.0.0-alpha.28", 321 | "resolved": "https://registry.npmjs.org/@ulixee/hero/-/hero-2.0.0-alpha.28.tgz", 322 | "integrity": "sha512-5ITUaJrA4h/qdiNuDsNO0nkilCiAr85JY4PnBp7kwtkjY9bBptFO1+mTjafyOyUhoxDrEJGEjebeS9zZtYc2rA==", 323 | "dependencies": { 324 | "@ulixee/awaited-dom": "1.4.2", 325 | "@ulixee/commons": "2.0.0-alpha.28", 326 | "@ulixee/hero-interfaces": "2.0.0-alpha.28", 327 | "@ulixee/hero-plugin-utils": "2.0.0-alpha.28", 328 | "@ulixee/js-path": "2.0.0-alpha.28", 329 | "@ulixee/net": "2.0.0-alpha.28", 330 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 331 | "linkedom": "^0.14.11" 332 | }, 333 | "engines": { 334 | "node": ">=18" 335 | } 336 | }, 337 | "node_modules/@ulixee/hero-core": { 338 | "version": "2.0.0-alpha.28", 339 | "resolved": "https://registry.npmjs.org/@ulixee/hero-core/-/hero-core-2.0.0-alpha.28.tgz", 340 | "integrity": "sha512-4VyAktzxT2s7MKu0W9rvvXo8r2jlfutnW0IQcXE+YVKbQoY5vHSZ0xp/nWw56ki5o+vHSi3zhTDjiqD7IjLKZA==", 341 | "dependencies": { 342 | "@ulixee/awaited-dom": "1.4.2", 343 | "@ulixee/commons": "2.0.0-alpha.28", 344 | "@ulixee/default-browser-emulator": "2.0.0-alpha.28", 345 | "@ulixee/default-human-emulator": "2.0.0-alpha.28", 346 | "@ulixee/hero-interfaces": "2.0.0-alpha.28", 347 | "@ulixee/hero-plugin-utils": "2.0.0-alpha.28", 348 | "@ulixee/hero-timetravel": "2.0.0-alpha.28", 349 | "@ulixee/js-path": "2.0.0-alpha.28", 350 | "@ulixee/net": "2.0.0-alpha.28", 351 | "@ulixee/unblocked-agent": "2.0.0-alpha.28", 352 | "@ulixee/unblocked-agent-mitm": "2.0.0-alpha.28", 353 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 354 | "better-sqlite3": "^9.4.3", 355 | "moment": "^2.29.4", 356 | "nanoid": "^3.3.6", 357 | "ws": "^7.5.9" 358 | }, 359 | "engines": { 360 | "node": ">=18" 361 | } 362 | }, 363 | "node_modules/@ulixee/hero-interfaces": { 364 | "version": "2.0.0-alpha.28", 365 | "resolved": "https://registry.npmjs.org/@ulixee/hero-interfaces/-/hero-interfaces-2.0.0-alpha.28.tgz", 366 | "integrity": "sha512-/R59Qt7W/u7eu//CpOrmX22kJgBSJMRi5dHcAL6ms8IYTf+azttz4NfvSnv6cK6Vxe3D2KI2j+bvECfCOEysLg==", 367 | "dependencies": { 368 | "@ulixee/awaited-dom": "1.4.2", 369 | "@ulixee/commons": "2.0.0-alpha.28", 370 | "@ulixee/js-path": "2.0.0-alpha.28", 371 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 372 | "devtools-protocol": "^0.0.1137505" 373 | }, 374 | "engines": { 375 | "node": ">=18" 376 | } 377 | }, 378 | "node_modules/@ulixee/hero-plugin-utils": { 379 | "version": "2.0.0-alpha.28", 380 | "resolved": "https://registry.npmjs.org/@ulixee/hero-plugin-utils/-/hero-plugin-utils-2.0.0-alpha.28.tgz", 381 | "integrity": "sha512-EdGFcxz15CEvQRb6dtSLcQ3ytIMxVjp3TsowAepOwg2eDj8wsDqnfA5LZ2BUqB1s9epf7+qTTNulnADqh/OwMg==", 382 | "dependencies": { 383 | "@ulixee/commons": "2.0.0-alpha.28", 384 | "@ulixee/hero-interfaces": "2.0.0-alpha.28", 385 | "@ulixee/unblocked-specification": "2.0.0-alpha.28" 386 | }, 387 | "engines": { 388 | "node": ">=18" 389 | } 390 | }, 391 | "node_modules/@ulixee/hero-timetravel": { 392 | "version": "2.0.0-alpha.28", 393 | "resolved": "https://registry.npmjs.org/@ulixee/hero-timetravel/-/hero-timetravel-2.0.0-alpha.28.tgz", 394 | "integrity": "sha512-VRxbUF9/BZ4/3ccZxCa+emWZJxbO0uG0T5feNOacVG7MXbKtaHIRB0mZIhU1kA6bPp0rtMfLZI28H/6ZdTryfA==", 395 | "dependencies": { 396 | "@ulixee/commons": "2.0.0-alpha.28", 397 | "@ulixee/hero-core": "2.0.0-alpha.28", 398 | "@ulixee/hero-interfaces": "2.0.0-alpha.28", 399 | "@ulixee/unblocked-agent": "2.0.0-alpha.28", 400 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 401 | "nanoid": "^3.3.6" 402 | }, 403 | "engines": { 404 | "node": ">=18" 405 | } 406 | }, 407 | "node_modules/@ulixee/js-path": { 408 | "version": "2.0.0-alpha.28", 409 | "resolved": "https://registry.npmjs.org/@ulixee/js-path/-/js-path-2.0.0-alpha.28.tgz", 410 | "integrity": "sha512-wn05oPwSq3g4+pjmP1EKAf5BgzZswnYEkjm5SB7pfLgASgHiYfkKTTjhCz1PUs+JN+KVW1RmvQCjetPXD9EW7A==", 411 | "engines": { 412 | "node": ">=18" 413 | } 414 | }, 415 | "node_modules/@ulixee/net": { 416 | "version": "2.0.0-alpha.28", 417 | "resolved": "https://registry.npmjs.org/@ulixee/net/-/net-2.0.0-alpha.28.tgz", 418 | "integrity": "sha512-BsEaZPv9mGbS7jrq+LjUuRBt0qVRg5OVidlHRTKgKKU22vY2AOsIRw/HYm+ZXUV8qj3cKGTiqjhLT246VUxLCQ==", 419 | "dependencies": { 420 | "@ulixee/commons": "2.0.0-alpha.28", 421 | "ws": "^7.5.9" 422 | }, 423 | "engines": { 424 | "node": ">=18.0.0" 425 | } 426 | }, 427 | "node_modules/@ulixee/real-user-agents": { 428 | "version": "2.0.0-alpha.28", 429 | "resolved": "https://registry.npmjs.org/@ulixee/real-user-agents/-/real-user-agents-2.0.0-alpha.28.tgz", 430 | "integrity": "sha512-Zxlua5Mnhpe7254rWS8AF7DqPNiKSneBR/E/k8COQdlR+wiCiNord95Gvbigf/cLdQO0ShiDLodY/vCnnaHYeQ==", 431 | "dependencies": { 432 | "@ulixee/commons": "2.0.0-alpha.28", 433 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 434 | "compare-versions": "^6.1.0", 435 | "ua-parser-js": "^1.0.37" 436 | }, 437 | "engines": { 438 | "node": ">=18" 439 | } 440 | }, 441 | "node_modules/@ulixee/unblocked-agent": { 442 | "version": "2.0.0-alpha.28", 443 | "resolved": "https://registry.npmjs.org/@ulixee/unblocked-agent/-/unblocked-agent-2.0.0-alpha.28.tgz", 444 | "integrity": "sha512-XvM5HcGzQRD9q9uAThIZA/w5GkhkC6GcTGQoG90HkNzTRK6/qBPT9qe6GidBf5cCBCZINnsuYfcUoAUf0876Qg==", 445 | "dependencies": { 446 | "@ulixee/chrome-121-0": "^6167.86.8", 447 | "@ulixee/chrome-app": "^1.0.3", 448 | "@ulixee/commons": "2.0.0-alpha.28", 449 | "@ulixee/js-path": "2.0.0-alpha.28", 450 | "@ulixee/unblocked-agent-mitm": "2.0.0-alpha.28", 451 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 452 | "devtools-protocol": "^0.0.1137505", 453 | "nanoid": "^3.3.6", 454 | "tough-cookie": "^4.1.3" 455 | }, 456 | "engines": { 457 | "node": ">=18" 458 | } 459 | }, 460 | "node_modules/@ulixee/unblocked-agent-mitm": { 461 | "version": "2.0.0-alpha.28", 462 | "resolved": "https://registry.npmjs.org/@ulixee/unblocked-agent-mitm/-/unblocked-agent-mitm-2.0.0-alpha.28.tgz", 463 | "integrity": "sha512-qcqvzZhUzpbJVhLN+k9lddKM9QmN8PmvZ7udaDnCaDgNhms3rsDsownSfY3hd02gta1sH5Y1Nfnt7rQRSa7jdg==", 464 | "dependencies": { 465 | "@ulixee/commons": "2.0.0-alpha.28", 466 | "@ulixee/unblocked-agent-mitm-socket": "2.0.0-alpha.28", 467 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 468 | "dns-packet": "^5.2.4", 469 | "moment": "^2.29.4" 470 | }, 471 | "engines": { 472 | "node": ">=18" 473 | } 474 | }, 475 | "node_modules/@ulixee/unblocked-agent-mitm-socket": { 476 | "version": "2.0.0-alpha.28", 477 | "resolved": "https://registry.npmjs.org/@ulixee/unblocked-agent-mitm-socket/-/unblocked-agent-mitm-socket-2.0.0-alpha.28.tgz", 478 | "integrity": "sha512-ruURECwbObKAJjsru6KipV0HZ9FXV+s9YxGfzyzLLmYHNTnALNxqa05id7DLrt9RgI2HAwZaWwZsOvmYWfJQUg==", 479 | "hasInstallScript": true, 480 | "dependencies": { 481 | "@ulixee/commons": "2.0.0-alpha.28", 482 | "@ulixee/unblocked-specification": "2.0.0-alpha.28", 483 | "nanoid": "^3.3.6" 484 | }, 485 | "engines": { 486 | "node": ">=18" 487 | } 488 | }, 489 | "node_modules/@ulixee/unblocked-specification": { 490 | "version": "2.0.0-alpha.28", 491 | "resolved": "https://registry.npmjs.org/@ulixee/unblocked-specification/-/unblocked-specification-2.0.0-alpha.28.tgz", 492 | "integrity": "sha512-5BFYwyT6GBiy8yVw/piFNSACgv2FBJvJzDTVnSCnW9PSKTjIu6H7w7T/0uhCGVsW8hS91v+SjMLlaEv0c1GKqg==", 493 | "dependencies": { 494 | "@ulixee/js-path": "2.0.0-alpha.28", 495 | "devtools-protocol": "^0.0.1137505" 496 | }, 497 | "engines": { 498 | "node": ">=18" 499 | } 500 | }, 501 | "node_modules/@yarnpkg/lockfile": { 502 | "version": "1.1.0", 503 | "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", 504 | "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" 505 | }, 506 | "node_modules/accepts": { 507 | "version": "1.3.8", 508 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 509 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 510 | "dependencies": { 511 | "mime-types": "~2.1.34", 512 | "negotiator": "0.6.3" 513 | }, 514 | "engines": { 515 | "node": ">= 0.6" 516 | } 517 | }, 518 | "node_modules/acorn": { 519 | "version": "8.11.3", 520 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 521 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 522 | "dev": true, 523 | "bin": { 524 | "acorn": "bin/acorn" 525 | }, 526 | "engines": { 527 | "node": ">=0.4.0" 528 | } 529 | }, 530 | "node_modules/acorn-walk": { 531 | "version": "8.3.2", 532 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 533 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 534 | "dev": true, 535 | "engines": { 536 | "node": ">=0.4.0" 537 | } 538 | }, 539 | "node_modules/agent-base": { 540 | "version": "6.0.2", 541 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 542 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 543 | "dependencies": { 544 | "debug": "4" 545 | }, 546 | "engines": { 547 | "node": ">= 6.0.0" 548 | } 549 | }, 550 | "node_modules/agent-base/node_modules/debug": { 551 | "version": "4.3.4", 552 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 553 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 554 | "dependencies": { 555 | "ms": "2.1.2" 556 | }, 557 | "engines": { 558 | "node": ">=6.0" 559 | }, 560 | "peerDependenciesMeta": { 561 | "supports-color": { 562 | "optional": true 563 | } 564 | } 565 | }, 566 | "node_modules/agent-base/node_modules/ms": { 567 | "version": "2.1.2", 568 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 569 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 570 | }, 571 | "node_modules/ansi-styles": { 572 | "version": "4.3.0", 573 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 574 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 575 | "dependencies": { 576 | "color-convert": "^2.0.1" 577 | }, 578 | "engines": { 579 | "node": ">=8" 580 | }, 581 | "funding": { 582 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 583 | } 584 | }, 585 | "node_modules/arg": { 586 | "version": "4.1.3", 587 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 588 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 589 | "dev": true 590 | }, 591 | "node_modules/array-flatten": { 592 | "version": "1.1.1", 593 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 594 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 595 | }, 596 | "node_modules/asynckit": { 597 | "version": "0.4.0", 598 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 599 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 600 | }, 601 | "node_modules/at-least-node": { 602 | "version": "1.0.0", 603 | "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", 604 | "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", 605 | "engines": { 606 | "node": ">= 4.0.0" 607 | } 608 | }, 609 | "node_modules/axios": { 610 | "version": "1.6.8", 611 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", 612 | "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", 613 | "dependencies": { 614 | "follow-redirects": "^1.15.6", 615 | "form-data": "^4.0.0", 616 | "proxy-from-env": "^1.1.0" 617 | } 618 | }, 619 | "node_modules/balanced-match": { 620 | "version": "1.0.2", 621 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 622 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 623 | }, 624 | "node_modules/base64-js": { 625 | "version": "1.5.1", 626 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 627 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 628 | "funding": [ 629 | { 630 | "type": "github", 631 | "url": "https://github.com/sponsors/feross" 632 | }, 633 | { 634 | "type": "patreon", 635 | "url": "https://www.patreon.com/feross" 636 | }, 637 | { 638 | "type": "consulting", 639 | "url": "https://feross.org/support" 640 | } 641 | ] 642 | }, 643 | "node_modules/bech32": { 644 | "version": "2.0.0", 645 | "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", 646 | "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" 647 | }, 648 | "node_modules/better-sqlite3": { 649 | "version": "9.4.3", 650 | "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.4.3.tgz", 651 | "integrity": "sha512-ud0bTmD9O3uWJGuXDltyj3R47Nz0OHX8iqPOT5PMspGqlu/qQFn+5S2eFBUCrySpavTjFXbi4EgrfVvPAHlImw==", 652 | "hasInstallScript": true, 653 | "dependencies": { 654 | "bindings": "^1.5.0", 655 | "prebuild-install": "^7.1.1" 656 | } 657 | }, 658 | "node_modules/bindings": { 659 | "version": "1.5.0", 660 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 661 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 662 | "dependencies": { 663 | "file-uri-to-path": "1.0.0" 664 | } 665 | }, 666 | "node_modules/bl": { 667 | "version": "4.1.0", 668 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 669 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 670 | "dependencies": { 671 | "buffer": "^5.5.0", 672 | "inherits": "^2.0.4", 673 | "readable-stream": "^3.4.0" 674 | } 675 | }, 676 | "node_modules/body-parser": { 677 | "version": "1.20.2", 678 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", 679 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", 680 | "dependencies": { 681 | "bytes": "3.1.2", 682 | "content-type": "~1.0.5", 683 | "debug": "2.6.9", 684 | "depd": "2.0.0", 685 | "destroy": "1.2.0", 686 | "http-errors": "2.0.0", 687 | "iconv-lite": "0.4.24", 688 | "on-finished": "2.4.1", 689 | "qs": "6.11.0", 690 | "raw-body": "2.5.2", 691 | "type-is": "~1.6.18", 692 | "unpipe": "1.0.0" 693 | }, 694 | "engines": { 695 | "node": ">= 0.8", 696 | "npm": "1.2.8000 || >= 1.4.16" 697 | } 698 | }, 699 | "node_modules/boolbase": { 700 | "version": "1.0.0", 701 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 702 | "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" 703 | }, 704 | "node_modules/brace-expansion": { 705 | "version": "1.1.11", 706 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 707 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 708 | "dependencies": { 709 | "balanced-match": "^1.0.0", 710 | "concat-map": "0.0.1" 711 | } 712 | }, 713 | "node_modules/braces": { 714 | "version": "3.0.2", 715 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 716 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 717 | "dependencies": { 718 | "fill-range": "^7.0.1" 719 | }, 720 | "engines": { 721 | "node": ">=8" 722 | } 723 | }, 724 | "node_modules/buffer": { 725 | "version": "5.7.1", 726 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 727 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 728 | "funding": [ 729 | { 730 | "type": "github", 731 | "url": "https://github.com/sponsors/feross" 732 | }, 733 | { 734 | "type": "patreon", 735 | "url": "https://www.patreon.com/feross" 736 | }, 737 | { 738 | "type": "consulting", 739 | "url": "https://feross.org/support" 740 | } 741 | ], 742 | "dependencies": { 743 | "base64-js": "^1.3.1", 744 | "ieee754": "^1.1.13" 745 | } 746 | }, 747 | "node_modules/bytes": { 748 | "version": "3.1.2", 749 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 750 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 751 | "engines": { 752 | "node": ">= 0.8" 753 | } 754 | }, 755 | "node_modules/call-bind": { 756 | "version": "1.0.7", 757 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 758 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 759 | "dependencies": { 760 | "es-define-property": "^1.0.0", 761 | "es-errors": "^1.3.0", 762 | "function-bind": "^1.1.2", 763 | "get-intrinsic": "^1.2.4", 764 | "set-function-length": "^1.2.1" 765 | }, 766 | "engines": { 767 | "node": ">= 0.4" 768 | }, 769 | "funding": { 770 | "url": "https://github.com/sponsors/ljharb" 771 | } 772 | }, 773 | "node_modules/chalk": { 774 | "version": "4.1.2", 775 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 776 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 777 | "dependencies": { 778 | "ansi-styles": "^4.1.0", 779 | "supports-color": "^7.1.0" 780 | }, 781 | "engines": { 782 | "node": ">=10" 783 | }, 784 | "funding": { 785 | "url": "https://github.com/chalk/chalk?sponsor=1" 786 | } 787 | }, 788 | "node_modules/chownr": { 789 | "version": "2.0.0", 790 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 791 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", 792 | "engines": { 793 | "node": ">=10" 794 | } 795 | }, 796 | "node_modules/ci-info": { 797 | "version": "2.0.0", 798 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", 799 | "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" 800 | }, 801 | "node_modules/color-convert": { 802 | "version": "2.0.1", 803 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 804 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 805 | "dependencies": { 806 | "color-name": "~1.1.4" 807 | }, 808 | "engines": { 809 | "node": ">=7.0.0" 810 | } 811 | }, 812 | "node_modules/color-name": { 813 | "version": "1.1.4", 814 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 815 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 816 | }, 817 | "node_modules/combined-stream": { 818 | "version": "1.0.8", 819 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 820 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 821 | "dependencies": { 822 | "delayed-stream": "~1.0.0" 823 | }, 824 | "engines": { 825 | "node": ">= 0.8" 826 | } 827 | }, 828 | "node_modules/compare-versions": { 829 | "version": "6.1.0", 830 | "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", 831 | "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==" 832 | }, 833 | "node_modules/concat-map": { 834 | "version": "0.0.1", 835 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 836 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 837 | }, 838 | "node_modules/content-disposition": { 839 | "version": "0.5.4", 840 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 841 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 842 | "dependencies": { 843 | "safe-buffer": "5.2.1" 844 | }, 845 | "engines": { 846 | "node": ">= 0.6" 847 | } 848 | }, 849 | "node_modules/content-type": { 850 | "version": "1.0.5", 851 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 852 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 853 | "engines": { 854 | "node": ">= 0.6" 855 | } 856 | }, 857 | "node_modules/cookie": { 858 | "version": "0.5.0", 859 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 860 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 861 | "engines": { 862 | "node": ">= 0.6" 863 | } 864 | }, 865 | "node_modules/cookie-signature": { 866 | "version": "1.0.6", 867 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 868 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 869 | }, 870 | "node_modules/cors": { 871 | "version": "2.8.5", 872 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 873 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 874 | "dependencies": { 875 | "object-assign": "^4", 876 | "vary": "^1" 877 | }, 878 | "engines": { 879 | "node": ">= 0.10" 880 | } 881 | }, 882 | "node_modules/create-require": { 883 | "version": "1.1.1", 884 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 885 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 886 | "dev": true 887 | }, 888 | "node_modules/cross-spawn": { 889 | "version": "6.0.5", 890 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 891 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 892 | "dependencies": { 893 | "nice-try": "^1.0.4", 894 | "path-key": "^2.0.1", 895 | "semver": "^5.5.0", 896 | "shebang-command": "^1.2.0", 897 | "which": "^1.2.9" 898 | }, 899 | "engines": { 900 | "node": ">=4.8" 901 | } 902 | }, 903 | "node_modules/cross-spawn/node_modules/semver": { 904 | "version": "5.7.2", 905 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", 906 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", 907 | "bin": { 908 | "semver": "bin/semver" 909 | } 910 | }, 911 | "node_modules/css-select": { 912 | "version": "5.1.0", 913 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", 914 | "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", 915 | "dependencies": { 916 | "boolbase": "^1.0.0", 917 | "css-what": "^6.1.0", 918 | "domhandler": "^5.0.2", 919 | "domutils": "^3.0.1", 920 | "nth-check": "^2.0.1" 921 | }, 922 | "funding": { 923 | "url": "https://github.com/sponsors/fb55" 924 | } 925 | }, 926 | "node_modules/css-what": { 927 | "version": "6.1.0", 928 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", 929 | "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", 930 | "engines": { 931 | "node": ">= 6" 932 | }, 933 | "funding": { 934 | "url": "https://github.com/sponsors/fb55" 935 | } 936 | }, 937 | "node_modules/cssom": { 938 | "version": "0.5.0", 939 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", 940 | "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" 941 | }, 942 | "node_modules/debug": { 943 | "version": "2.6.9", 944 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 945 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 946 | "dependencies": { 947 | "ms": "2.0.0" 948 | } 949 | }, 950 | "node_modules/decompress-response": { 951 | "version": "6.0.0", 952 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 953 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 954 | "dependencies": { 955 | "mimic-response": "^3.1.0" 956 | }, 957 | "engines": { 958 | "node": ">=10" 959 | }, 960 | "funding": { 961 | "url": "https://github.com/sponsors/sindresorhus" 962 | } 963 | }, 964 | "node_modules/deep-extend": { 965 | "version": "0.6.0", 966 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 967 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 968 | "engines": { 969 | "node": ">=4.0.0" 970 | } 971 | }, 972 | "node_modules/define-data-property": { 973 | "version": "1.1.4", 974 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 975 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 976 | "dependencies": { 977 | "es-define-property": "^1.0.0", 978 | "es-errors": "^1.3.0", 979 | "gopd": "^1.0.1" 980 | }, 981 | "engines": { 982 | "node": ">= 0.4" 983 | }, 984 | "funding": { 985 | "url": "https://github.com/sponsors/ljharb" 986 | } 987 | }, 988 | "node_modules/delayed-stream": { 989 | "version": "1.0.0", 990 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 991 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 992 | "engines": { 993 | "node": ">=0.4.0" 994 | } 995 | }, 996 | "node_modules/depd": { 997 | "version": "2.0.0", 998 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 999 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 1000 | "engines": { 1001 | "node": ">= 0.8" 1002 | } 1003 | }, 1004 | "node_modules/destroy": { 1005 | "version": "1.2.0", 1006 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 1007 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 1008 | "engines": { 1009 | "node": ">= 0.8", 1010 | "npm": "1.2.8000 || >= 1.4.16" 1011 | } 1012 | }, 1013 | "node_modules/detect-libc": { 1014 | "version": "2.0.3", 1015 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", 1016 | "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", 1017 | "engines": { 1018 | "node": ">=8" 1019 | } 1020 | }, 1021 | "node_modules/devtools-protocol": { 1022 | "version": "0.0.1137505", 1023 | "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1137505.tgz", 1024 | "integrity": "sha512-etlSdcQy8DiTCw5oV/AaQiEqEDMCHTGRcMpsqzlKUQQdC/AKadVNbN7GTVAwFOKtMo4i907DczhNkXebiZe85g==" 1025 | }, 1026 | "node_modules/diff": { 1027 | "version": "4.0.2", 1028 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 1029 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 1030 | "dev": true, 1031 | "engines": { 1032 | "node": ">=0.3.1" 1033 | } 1034 | }, 1035 | "node_modules/dns-packet": { 1036 | "version": "5.6.1", 1037 | "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", 1038 | "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", 1039 | "dependencies": { 1040 | "@leichtgewicht/ip-codec": "^2.0.1" 1041 | }, 1042 | "engines": { 1043 | "node": ">=6" 1044 | } 1045 | }, 1046 | "node_modules/dom-serializer": { 1047 | "version": "2.0.0", 1048 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 1049 | "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 1050 | "dependencies": { 1051 | "domelementtype": "^2.3.0", 1052 | "domhandler": "^5.0.2", 1053 | "entities": "^4.2.0" 1054 | }, 1055 | "funding": { 1056 | "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" 1057 | } 1058 | }, 1059 | "node_modules/domelementtype": { 1060 | "version": "2.3.0", 1061 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 1062 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 1063 | "funding": [ 1064 | { 1065 | "type": "github", 1066 | "url": "https://github.com/sponsors/fb55" 1067 | } 1068 | ] 1069 | }, 1070 | "node_modules/domhandler": { 1071 | "version": "5.0.3", 1072 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 1073 | "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 1074 | "dependencies": { 1075 | "domelementtype": "^2.3.0" 1076 | }, 1077 | "engines": { 1078 | "node": ">= 4" 1079 | }, 1080 | "funding": { 1081 | "url": "https://github.com/fb55/domhandler?sponsor=1" 1082 | } 1083 | }, 1084 | "node_modules/domutils": { 1085 | "version": "3.1.0", 1086 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", 1087 | "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", 1088 | "dependencies": { 1089 | "dom-serializer": "^2.0.0", 1090 | "domelementtype": "^2.3.0", 1091 | "domhandler": "^5.0.3" 1092 | }, 1093 | "funding": { 1094 | "url": "https://github.com/fb55/domutils?sponsor=1" 1095 | } 1096 | }, 1097 | "node_modules/ee-first": { 1098 | "version": "1.1.1", 1099 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1100 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 1101 | }, 1102 | "node_modules/encodeurl": { 1103 | "version": "1.0.2", 1104 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1105 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 1106 | "engines": { 1107 | "node": ">= 0.8" 1108 | } 1109 | }, 1110 | "node_modules/end-of-stream": { 1111 | "version": "1.4.4", 1112 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 1113 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 1114 | "dependencies": { 1115 | "once": "^1.4.0" 1116 | } 1117 | }, 1118 | "node_modules/entities": { 1119 | "version": "4.5.0", 1120 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 1121 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1122 | "engines": { 1123 | "node": ">=0.12" 1124 | }, 1125 | "funding": { 1126 | "url": "https://github.com/fb55/entities?sponsor=1" 1127 | } 1128 | }, 1129 | "node_modules/es-define-property": { 1130 | "version": "1.0.0", 1131 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 1132 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 1133 | "dependencies": { 1134 | "get-intrinsic": "^1.2.4" 1135 | }, 1136 | "engines": { 1137 | "node": ">= 0.4" 1138 | } 1139 | }, 1140 | "node_modules/es-errors": { 1141 | "version": "1.3.0", 1142 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 1143 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 1144 | "engines": { 1145 | "node": ">= 0.4" 1146 | } 1147 | }, 1148 | "node_modules/escape-html": { 1149 | "version": "1.0.3", 1150 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1151 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 1152 | }, 1153 | "node_modules/etag": { 1154 | "version": "1.8.1", 1155 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1156 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 1157 | "engines": { 1158 | "node": ">= 0.6" 1159 | } 1160 | }, 1161 | "node_modules/expand-template": { 1162 | "version": "2.0.3", 1163 | "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", 1164 | "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", 1165 | "engines": { 1166 | "node": ">=6" 1167 | } 1168 | }, 1169 | "node_modules/express": { 1170 | "version": "4.18.3", 1171 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", 1172 | "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", 1173 | "dependencies": { 1174 | "accepts": "~1.3.8", 1175 | "array-flatten": "1.1.1", 1176 | "body-parser": "1.20.2", 1177 | "content-disposition": "0.5.4", 1178 | "content-type": "~1.0.4", 1179 | "cookie": "0.5.0", 1180 | "cookie-signature": "1.0.6", 1181 | "debug": "2.6.9", 1182 | "depd": "2.0.0", 1183 | "encodeurl": "~1.0.2", 1184 | "escape-html": "~1.0.3", 1185 | "etag": "~1.8.1", 1186 | "finalhandler": "1.2.0", 1187 | "fresh": "0.5.2", 1188 | "http-errors": "2.0.0", 1189 | "merge-descriptors": "1.0.1", 1190 | "methods": "~1.1.2", 1191 | "on-finished": "2.4.1", 1192 | "parseurl": "~1.3.3", 1193 | "path-to-regexp": "0.1.7", 1194 | "proxy-addr": "~2.0.7", 1195 | "qs": "6.11.0", 1196 | "range-parser": "~1.2.1", 1197 | "safe-buffer": "5.2.1", 1198 | "send": "0.18.0", 1199 | "serve-static": "1.15.0", 1200 | "setprototypeof": "1.2.0", 1201 | "statuses": "2.0.1", 1202 | "type-is": "~1.6.18", 1203 | "utils-merge": "1.0.1", 1204 | "vary": "~1.1.2" 1205 | }, 1206 | "engines": { 1207 | "node": ">= 0.10.0" 1208 | } 1209 | }, 1210 | "node_modules/file-uri-to-path": { 1211 | "version": "1.0.0", 1212 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 1213 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 1214 | }, 1215 | "node_modules/fill-range": { 1216 | "version": "7.0.1", 1217 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1218 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1219 | "dependencies": { 1220 | "to-regex-range": "^5.0.1" 1221 | }, 1222 | "engines": { 1223 | "node": ">=8" 1224 | } 1225 | }, 1226 | "node_modules/finalhandler": { 1227 | "version": "1.2.0", 1228 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 1229 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 1230 | "dependencies": { 1231 | "debug": "2.6.9", 1232 | "encodeurl": "~1.0.2", 1233 | "escape-html": "~1.0.3", 1234 | "on-finished": "2.4.1", 1235 | "parseurl": "~1.3.3", 1236 | "statuses": "2.0.1", 1237 | "unpipe": "~1.0.0" 1238 | }, 1239 | "engines": { 1240 | "node": ">= 0.8" 1241 | } 1242 | }, 1243 | "node_modules/find-yarn-workspace-root": { 1244 | "version": "2.0.0", 1245 | "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", 1246 | "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", 1247 | "dependencies": { 1248 | "micromatch": "^4.0.2" 1249 | } 1250 | }, 1251 | "node_modules/follow-redirects": { 1252 | "version": "1.15.6", 1253 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", 1254 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", 1255 | "funding": [ 1256 | { 1257 | "type": "individual", 1258 | "url": "https://github.com/sponsors/RubenVerborgh" 1259 | } 1260 | ], 1261 | "engines": { 1262 | "node": ">=4.0" 1263 | }, 1264 | "peerDependenciesMeta": { 1265 | "debug": { 1266 | "optional": true 1267 | } 1268 | } 1269 | }, 1270 | "node_modules/form-data": { 1271 | "version": "4.0.0", 1272 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 1273 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 1274 | "dependencies": { 1275 | "asynckit": "^0.4.0", 1276 | "combined-stream": "^1.0.8", 1277 | "mime-types": "^2.1.12" 1278 | }, 1279 | "engines": { 1280 | "node": ">= 6" 1281 | } 1282 | }, 1283 | "node_modules/forwarded": { 1284 | "version": "0.2.0", 1285 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1286 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 1287 | "engines": { 1288 | "node": ">= 0.6" 1289 | } 1290 | }, 1291 | "node_modules/fresh": { 1292 | "version": "0.5.2", 1293 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1294 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 1295 | "engines": { 1296 | "node": ">= 0.6" 1297 | } 1298 | }, 1299 | "node_modules/fs": { 1300 | "version": "0.0.2", 1301 | "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz", 1302 | "integrity": "sha512-YAiVokMCrSIFZiroB1oz51hPiPRVcUtSa4x2U5RYXyhS9VAPdiFigKbPTnOSq7XY8wd3FIVPYmXpo5lMzFmxgg==" 1303 | }, 1304 | "node_modules/fs-constants": { 1305 | "version": "1.0.0", 1306 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 1307 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 1308 | }, 1309 | "node_modules/fs-extra": { 1310 | "version": "9.1.0", 1311 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", 1312 | "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", 1313 | "dependencies": { 1314 | "at-least-node": "^1.0.0", 1315 | "graceful-fs": "^4.2.0", 1316 | "jsonfile": "^6.0.1", 1317 | "universalify": "^2.0.0" 1318 | }, 1319 | "engines": { 1320 | "node": ">=10" 1321 | } 1322 | }, 1323 | "node_modules/fs-minipass": { 1324 | "version": "2.1.0", 1325 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 1326 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 1327 | "dependencies": { 1328 | "minipass": "^3.0.0" 1329 | }, 1330 | "engines": { 1331 | "node": ">= 8" 1332 | } 1333 | }, 1334 | "node_modules/fs-minipass/node_modules/minipass": { 1335 | "version": "3.3.6", 1336 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 1337 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 1338 | "dependencies": { 1339 | "yallist": "^4.0.0" 1340 | }, 1341 | "engines": { 1342 | "node": ">=8" 1343 | } 1344 | }, 1345 | "node_modules/fs.realpath": { 1346 | "version": "1.0.0", 1347 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1348 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 1349 | }, 1350 | "node_modules/function-bind": { 1351 | "version": "1.1.2", 1352 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1353 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1354 | "funding": { 1355 | "url": "https://github.com/sponsors/ljharb" 1356 | } 1357 | }, 1358 | "node_modules/get-intrinsic": { 1359 | "version": "1.2.4", 1360 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 1361 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 1362 | "dependencies": { 1363 | "es-errors": "^1.3.0", 1364 | "function-bind": "^1.1.2", 1365 | "has-proto": "^1.0.1", 1366 | "has-symbols": "^1.0.3", 1367 | "hasown": "^2.0.0" 1368 | }, 1369 | "engines": { 1370 | "node": ">= 0.4" 1371 | }, 1372 | "funding": { 1373 | "url": "https://github.com/sponsors/ljharb" 1374 | } 1375 | }, 1376 | "node_modules/github-from-package": { 1377 | "version": "0.0.0", 1378 | "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 1379 | "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" 1380 | }, 1381 | "node_modules/glob": { 1382 | "version": "7.2.3", 1383 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1384 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1385 | "dependencies": { 1386 | "fs.realpath": "^1.0.0", 1387 | "inflight": "^1.0.4", 1388 | "inherits": "2", 1389 | "minimatch": "^3.1.1", 1390 | "once": "^1.3.0", 1391 | "path-is-absolute": "^1.0.0" 1392 | }, 1393 | "engines": { 1394 | "node": "*" 1395 | }, 1396 | "funding": { 1397 | "url": "https://github.com/sponsors/isaacs" 1398 | } 1399 | }, 1400 | "node_modules/gopd": { 1401 | "version": "1.0.1", 1402 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 1403 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 1404 | "dependencies": { 1405 | "get-intrinsic": "^1.1.3" 1406 | }, 1407 | "funding": { 1408 | "url": "https://github.com/sponsors/ljharb" 1409 | } 1410 | }, 1411 | "node_modules/graceful-fs": { 1412 | "version": "4.2.11", 1413 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1414 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 1415 | }, 1416 | "node_modules/has-flag": { 1417 | "version": "4.0.0", 1418 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1419 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1420 | "engines": { 1421 | "node": ">=8" 1422 | } 1423 | }, 1424 | "node_modules/has-property-descriptors": { 1425 | "version": "1.0.2", 1426 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 1427 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 1428 | "dependencies": { 1429 | "es-define-property": "^1.0.0" 1430 | }, 1431 | "funding": { 1432 | "url": "https://github.com/sponsors/ljharb" 1433 | } 1434 | }, 1435 | "node_modules/has-proto": { 1436 | "version": "1.0.3", 1437 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 1438 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 1439 | "engines": { 1440 | "node": ">= 0.4" 1441 | }, 1442 | "funding": { 1443 | "url": "https://github.com/sponsors/ljharb" 1444 | } 1445 | }, 1446 | "node_modules/has-symbols": { 1447 | "version": "1.0.3", 1448 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1449 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1450 | "engines": { 1451 | "node": ">= 0.4" 1452 | }, 1453 | "funding": { 1454 | "url": "https://github.com/sponsors/ljharb" 1455 | } 1456 | }, 1457 | "node_modules/hasown": { 1458 | "version": "2.0.2", 1459 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1460 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1461 | "dependencies": { 1462 | "function-bind": "^1.1.2" 1463 | }, 1464 | "engines": { 1465 | "node": ">= 0.4" 1466 | } 1467 | }, 1468 | "node_modules/helmet": { 1469 | "version": "5.1.1", 1470 | "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.1.tgz", 1471 | "integrity": "sha512-/yX0oVZBggA9cLJh8aw3PPCfedBnbd7J2aowjzsaWwZh7/UFY0nccn/aHAggIgWUFfnykX8GKd3a1pSbrmlcVQ==", 1472 | "engines": { 1473 | "node": ">=12.0.0" 1474 | } 1475 | }, 1476 | "node_modules/html-escaper": { 1477 | "version": "3.0.3", 1478 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", 1479 | "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" 1480 | }, 1481 | "node_modules/htmlparser2": { 1482 | "version": "8.0.2", 1483 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", 1484 | "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", 1485 | "funding": [ 1486 | "https://github.com/fb55/htmlparser2?sponsor=1", 1487 | { 1488 | "type": "github", 1489 | "url": "https://github.com/sponsors/fb55" 1490 | } 1491 | ], 1492 | "dependencies": { 1493 | "domelementtype": "^2.3.0", 1494 | "domhandler": "^5.0.3", 1495 | "domutils": "^3.0.1", 1496 | "entities": "^4.4.0" 1497 | } 1498 | }, 1499 | "node_modules/http-errors": { 1500 | "version": "2.0.0", 1501 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1502 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1503 | "dependencies": { 1504 | "depd": "2.0.0", 1505 | "inherits": "2.0.4", 1506 | "setprototypeof": "1.2.0", 1507 | "statuses": "2.0.1", 1508 | "toidentifier": "1.0.1" 1509 | }, 1510 | "engines": { 1511 | "node": ">= 0.8" 1512 | } 1513 | }, 1514 | "node_modules/https-proxy-agent": { 1515 | "version": "5.0.1", 1516 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", 1517 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", 1518 | "dependencies": { 1519 | "agent-base": "6", 1520 | "debug": "4" 1521 | }, 1522 | "engines": { 1523 | "node": ">= 6" 1524 | } 1525 | }, 1526 | "node_modules/https-proxy-agent/node_modules/debug": { 1527 | "version": "4.3.4", 1528 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1529 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1530 | "dependencies": { 1531 | "ms": "2.1.2" 1532 | }, 1533 | "engines": { 1534 | "node": ">=6.0" 1535 | }, 1536 | "peerDependenciesMeta": { 1537 | "supports-color": { 1538 | "optional": true 1539 | } 1540 | } 1541 | }, 1542 | "node_modules/https-proxy-agent/node_modules/ms": { 1543 | "version": "2.1.2", 1544 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1545 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1546 | }, 1547 | "node_modules/iconv-lite": { 1548 | "version": "0.4.24", 1549 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1550 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1551 | "dependencies": { 1552 | "safer-buffer": ">= 2.1.2 < 3" 1553 | }, 1554 | "engines": { 1555 | "node": ">=0.10.0" 1556 | } 1557 | }, 1558 | "node_modules/ieee754": { 1559 | "version": "1.2.1", 1560 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 1561 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 1562 | "funding": [ 1563 | { 1564 | "type": "github", 1565 | "url": "https://github.com/sponsors/feross" 1566 | }, 1567 | { 1568 | "type": "patreon", 1569 | "url": "https://www.patreon.com/feross" 1570 | }, 1571 | { 1572 | "type": "consulting", 1573 | "url": "https://feross.org/support" 1574 | } 1575 | ] 1576 | }, 1577 | "node_modules/inflight": { 1578 | "version": "1.0.6", 1579 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1580 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1581 | "dependencies": { 1582 | "once": "^1.3.0", 1583 | "wrappy": "1" 1584 | } 1585 | }, 1586 | "node_modules/inherits": { 1587 | "version": "2.0.4", 1588 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1589 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1590 | }, 1591 | "node_modules/ini": { 1592 | "version": "1.3.8", 1593 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", 1594 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" 1595 | }, 1596 | "node_modules/ipaddr.js": { 1597 | "version": "1.9.1", 1598 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1599 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1600 | "engines": { 1601 | "node": ">= 0.10" 1602 | } 1603 | }, 1604 | "node_modules/is-ci": { 1605 | "version": "2.0.0", 1606 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", 1607 | "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", 1608 | "dependencies": { 1609 | "ci-info": "^2.0.0" 1610 | }, 1611 | "bin": { 1612 | "is-ci": "bin.js" 1613 | } 1614 | }, 1615 | "node_modules/is-docker": { 1616 | "version": "2.2.1", 1617 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", 1618 | "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", 1619 | "bin": { 1620 | "is-docker": "cli.js" 1621 | }, 1622 | "engines": { 1623 | "node": ">=8" 1624 | }, 1625 | "funding": { 1626 | "url": "https://github.com/sponsors/sindresorhus" 1627 | } 1628 | }, 1629 | "node_modules/is-number": { 1630 | "version": "7.0.0", 1631 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1632 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1633 | "engines": { 1634 | "node": ">=0.12.0" 1635 | } 1636 | }, 1637 | "node_modules/is-wsl": { 1638 | "version": "2.2.0", 1639 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", 1640 | "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", 1641 | "dependencies": { 1642 | "is-docker": "^2.0.0" 1643 | }, 1644 | "engines": { 1645 | "node": ">=8" 1646 | } 1647 | }, 1648 | "node_modules/isexe": { 1649 | "version": "2.0.0", 1650 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1651 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" 1652 | }, 1653 | "node_modules/jsonfile": { 1654 | "version": "6.1.0", 1655 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", 1656 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", 1657 | "dependencies": { 1658 | "universalify": "^2.0.0" 1659 | }, 1660 | "optionalDependencies": { 1661 | "graceful-fs": "^4.1.6" 1662 | } 1663 | }, 1664 | "node_modules/klaw-sync": { 1665 | "version": "6.0.0", 1666 | "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", 1667 | "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", 1668 | "dependencies": { 1669 | "graceful-fs": "^4.1.11" 1670 | } 1671 | }, 1672 | "node_modules/linkedom": { 1673 | "version": "0.14.26", 1674 | "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.26.tgz", 1675 | "integrity": "sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==", 1676 | "dependencies": { 1677 | "css-select": "^5.1.0", 1678 | "cssom": "^0.5.0", 1679 | "html-escaper": "^3.0.3", 1680 | "htmlparser2": "^8.0.1", 1681 | "uhyphen": "^0.2.0" 1682 | } 1683 | }, 1684 | "node_modules/lru-cache": { 1685 | "version": "6.0.0", 1686 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1687 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1688 | "dependencies": { 1689 | "yallist": "^4.0.0" 1690 | }, 1691 | "engines": { 1692 | "node": ">=10" 1693 | } 1694 | }, 1695 | "node_modules/make-error": { 1696 | "version": "1.3.6", 1697 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 1698 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 1699 | "dev": true 1700 | }, 1701 | "node_modules/media-typer": { 1702 | "version": "0.3.0", 1703 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1704 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 1705 | "engines": { 1706 | "node": ">= 0.6" 1707 | } 1708 | }, 1709 | "node_modules/merge-descriptors": { 1710 | "version": "1.0.1", 1711 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1712 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1713 | }, 1714 | "node_modules/methods": { 1715 | "version": "1.1.2", 1716 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1717 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1718 | "engines": { 1719 | "node": ">= 0.6" 1720 | } 1721 | }, 1722 | "node_modules/micromatch": { 1723 | "version": "4.0.5", 1724 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1725 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1726 | "dependencies": { 1727 | "braces": "^3.0.2", 1728 | "picomatch": "^2.3.1" 1729 | }, 1730 | "engines": { 1731 | "node": ">=8.6" 1732 | } 1733 | }, 1734 | "node_modules/mime": { 1735 | "version": "1.6.0", 1736 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1737 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1738 | "bin": { 1739 | "mime": "cli.js" 1740 | }, 1741 | "engines": { 1742 | "node": ">=4" 1743 | } 1744 | }, 1745 | "node_modules/mime-db": { 1746 | "version": "1.52.0", 1747 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1748 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1749 | "engines": { 1750 | "node": ">= 0.6" 1751 | } 1752 | }, 1753 | "node_modules/mime-types": { 1754 | "version": "2.1.35", 1755 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1756 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1757 | "dependencies": { 1758 | "mime-db": "1.52.0" 1759 | }, 1760 | "engines": { 1761 | "node": ">= 0.6" 1762 | } 1763 | }, 1764 | "node_modules/mimic-response": { 1765 | "version": "3.1.0", 1766 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 1767 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 1768 | "engines": { 1769 | "node": ">=10" 1770 | }, 1771 | "funding": { 1772 | "url": "https://github.com/sponsors/sindresorhus" 1773 | } 1774 | }, 1775 | "node_modules/minimatch": { 1776 | "version": "3.1.2", 1777 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1778 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1779 | "dependencies": { 1780 | "brace-expansion": "^1.1.7" 1781 | }, 1782 | "engines": { 1783 | "node": "*" 1784 | } 1785 | }, 1786 | "node_modules/minimist": { 1787 | "version": "1.2.8", 1788 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1789 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1790 | "funding": { 1791 | "url": "https://github.com/sponsors/ljharb" 1792 | } 1793 | }, 1794 | "node_modules/minipass": { 1795 | "version": "5.0.0", 1796 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", 1797 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", 1798 | "engines": { 1799 | "node": ">=8" 1800 | } 1801 | }, 1802 | "node_modules/minizlib": { 1803 | "version": "2.1.2", 1804 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 1805 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 1806 | "dependencies": { 1807 | "minipass": "^3.0.0", 1808 | "yallist": "^4.0.0" 1809 | }, 1810 | "engines": { 1811 | "node": ">= 8" 1812 | } 1813 | }, 1814 | "node_modules/minizlib/node_modules/minipass": { 1815 | "version": "3.3.6", 1816 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 1817 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 1818 | "dependencies": { 1819 | "yallist": "^4.0.0" 1820 | }, 1821 | "engines": { 1822 | "node": ">=8" 1823 | } 1824 | }, 1825 | "node_modules/mkdirp": { 1826 | "version": "1.0.4", 1827 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 1828 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 1829 | "bin": { 1830 | "mkdirp": "bin/cmd.js" 1831 | }, 1832 | "engines": { 1833 | "node": ">=10" 1834 | } 1835 | }, 1836 | "node_modules/mkdirp-classic": { 1837 | "version": "0.5.3", 1838 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 1839 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" 1840 | }, 1841 | "node_modules/moment": { 1842 | "version": "2.30.1", 1843 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", 1844 | "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", 1845 | "engines": { 1846 | "node": "*" 1847 | } 1848 | }, 1849 | "node_modules/ms": { 1850 | "version": "2.0.0", 1851 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1852 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1853 | }, 1854 | "node_modules/nanoid": { 1855 | "version": "3.3.7", 1856 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 1857 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 1858 | "funding": [ 1859 | { 1860 | "type": "github", 1861 | "url": "https://github.com/sponsors/ai" 1862 | } 1863 | ], 1864 | "bin": { 1865 | "nanoid": "bin/nanoid.cjs" 1866 | }, 1867 | "engines": { 1868 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1869 | } 1870 | }, 1871 | "node_modules/napi-build-utils": { 1872 | "version": "1.0.2", 1873 | "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", 1874 | "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" 1875 | }, 1876 | "node_modules/negotiator": { 1877 | "version": "0.6.3", 1878 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1879 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1880 | "engines": { 1881 | "node": ">= 0.6" 1882 | } 1883 | }, 1884 | "node_modules/nice-try": { 1885 | "version": "1.0.5", 1886 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1887 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" 1888 | }, 1889 | "node_modules/node-abi": { 1890 | "version": "3.56.0", 1891 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", 1892 | "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", 1893 | "dependencies": { 1894 | "semver": "^7.3.5" 1895 | }, 1896 | "engines": { 1897 | "node": ">=10" 1898 | } 1899 | }, 1900 | "node_modules/nth-check": { 1901 | "version": "2.1.1", 1902 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", 1903 | "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", 1904 | "dependencies": { 1905 | "boolbase": "^1.0.0" 1906 | }, 1907 | "funding": { 1908 | "url": "https://github.com/fb55/nth-check?sponsor=1" 1909 | } 1910 | }, 1911 | "node_modules/object-assign": { 1912 | "version": "4.1.1", 1913 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1914 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1915 | "engines": { 1916 | "node": ">=0.10.0" 1917 | } 1918 | }, 1919 | "node_modules/object-inspect": { 1920 | "version": "1.13.1", 1921 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 1922 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 1923 | "funding": { 1924 | "url": "https://github.com/sponsors/ljharb" 1925 | } 1926 | }, 1927 | "node_modules/on-finished": { 1928 | "version": "2.4.1", 1929 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1930 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1931 | "dependencies": { 1932 | "ee-first": "1.1.1" 1933 | }, 1934 | "engines": { 1935 | "node": ">= 0.8" 1936 | } 1937 | }, 1938 | "node_modules/once": { 1939 | "version": "1.4.0", 1940 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1941 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1942 | "dependencies": { 1943 | "wrappy": "1" 1944 | } 1945 | }, 1946 | "node_modules/open": { 1947 | "version": "7.4.2", 1948 | "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", 1949 | "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", 1950 | "dependencies": { 1951 | "is-docker": "^2.0.0", 1952 | "is-wsl": "^2.1.1" 1953 | }, 1954 | "engines": { 1955 | "node": ">=8" 1956 | }, 1957 | "funding": { 1958 | "url": "https://github.com/sponsors/sindresorhus" 1959 | } 1960 | }, 1961 | "node_modules/os": { 1962 | "version": "0.1.2", 1963 | "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", 1964 | "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==" 1965 | }, 1966 | "node_modules/os-tmpdir": { 1967 | "version": "1.0.2", 1968 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1969 | "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", 1970 | "engines": { 1971 | "node": ">=0.10.0" 1972 | } 1973 | }, 1974 | "node_modules/parseurl": { 1975 | "version": "1.3.3", 1976 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1977 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1978 | "engines": { 1979 | "node": ">= 0.8" 1980 | } 1981 | }, 1982 | "node_modules/patch-package": { 1983 | "version": "6.5.1", 1984 | "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", 1985 | "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", 1986 | "dependencies": { 1987 | "@yarnpkg/lockfile": "^1.1.0", 1988 | "chalk": "^4.1.2", 1989 | "cross-spawn": "^6.0.5", 1990 | "find-yarn-workspace-root": "^2.0.0", 1991 | "fs-extra": "^9.0.0", 1992 | "is-ci": "^2.0.0", 1993 | "klaw-sync": "^6.0.0", 1994 | "minimist": "^1.2.6", 1995 | "open": "^7.4.2", 1996 | "rimraf": "^2.6.3", 1997 | "semver": "^5.6.0", 1998 | "slash": "^2.0.0", 1999 | "tmp": "^0.0.33", 2000 | "yaml": "^1.10.2" 2001 | }, 2002 | "bin": { 2003 | "patch-package": "index.js" 2004 | }, 2005 | "engines": { 2006 | "node": ">=10", 2007 | "npm": ">5" 2008 | } 2009 | }, 2010 | "node_modules/patch-package/node_modules/rimraf": { 2011 | "version": "2.7.1", 2012 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 2013 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 2014 | "dependencies": { 2015 | "glob": "^7.1.3" 2016 | }, 2017 | "bin": { 2018 | "rimraf": "bin.js" 2019 | } 2020 | }, 2021 | "node_modules/patch-package/node_modules/semver": { 2022 | "version": "5.7.2", 2023 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", 2024 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", 2025 | "bin": { 2026 | "semver": "bin/semver" 2027 | } 2028 | }, 2029 | "node_modules/path-is-absolute": { 2030 | "version": "1.0.1", 2031 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2032 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 2033 | "engines": { 2034 | "node": ">=0.10.0" 2035 | } 2036 | }, 2037 | "node_modules/path-key": { 2038 | "version": "2.0.1", 2039 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 2040 | "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", 2041 | "engines": { 2042 | "node": ">=4" 2043 | } 2044 | }, 2045 | "node_modules/path-to-regexp": { 2046 | "version": "0.1.7", 2047 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 2048 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 2049 | }, 2050 | "node_modules/picomatch": { 2051 | "version": "2.3.1", 2052 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2053 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2054 | "engines": { 2055 | "node": ">=8.6" 2056 | }, 2057 | "funding": { 2058 | "url": "https://github.com/sponsors/jonschlinkert" 2059 | } 2060 | }, 2061 | "node_modules/prebuild-install": { 2062 | "version": "7.1.2", 2063 | "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", 2064 | "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", 2065 | "dependencies": { 2066 | "detect-libc": "^2.0.0", 2067 | "expand-template": "^2.0.3", 2068 | "github-from-package": "0.0.0", 2069 | "minimist": "^1.2.3", 2070 | "mkdirp-classic": "^0.5.3", 2071 | "napi-build-utils": "^1.0.1", 2072 | "node-abi": "^3.3.0", 2073 | "pump": "^3.0.0", 2074 | "rc": "^1.2.7", 2075 | "simple-get": "^4.0.0", 2076 | "tar-fs": "^2.0.0", 2077 | "tunnel-agent": "^0.6.0" 2078 | }, 2079 | "bin": { 2080 | "prebuild-install": "bin.js" 2081 | }, 2082 | "engines": { 2083 | "node": ">=10" 2084 | } 2085 | }, 2086 | "node_modules/progress": { 2087 | "version": "2.0.3", 2088 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 2089 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 2090 | "engines": { 2091 | "node": ">=0.4.0" 2092 | } 2093 | }, 2094 | "node_modules/proxy-addr": { 2095 | "version": "2.0.7", 2096 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 2097 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 2098 | "dependencies": { 2099 | "forwarded": "0.2.0", 2100 | "ipaddr.js": "1.9.1" 2101 | }, 2102 | "engines": { 2103 | "node": ">= 0.10" 2104 | } 2105 | }, 2106 | "node_modules/proxy-from-env": { 2107 | "version": "1.1.0", 2108 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 2109 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 2110 | }, 2111 | "node_modules/psl": { 2112 | "version": "1.9.0", 2113 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", 2114 | "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" 2115 | }, 2116 | "node_modules/pump": { 2117 | "version": "3.0.0", 2118 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 2119 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 2120 | "dependencies": { 2121 | "end-of-stream": "^1.1.0", 2122 | "once": "^1.3.1" 2123 | } 2124 | }, 2125 | "node_modules/punycode": { 2126 | "version": "2.3.1", 2127 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 2128 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 2129 | "engines": { 2130 | "node": ">=6" 2131 | } 2132 | }, 2133 | "node_modules/qs": { 2134 | "version": "6.11.0", 2135 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 2136 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 2137 | "dependencies": { 2138 | "side-channel": "^1.0.4" 2139 | }, 2140 | "engines": { 2141 | "node": ">=0.6" 2142 | }, 2143 | "funding": { 2144 | "url": "https://github.com/sponsors/ljharb" 2145 | } 2146 | }, 2147 | "node_modules/querystringify": { 2148 | "version": "2.2.0", 2149 | "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", 2150 | "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" 2151 | }, 2152 | "node_modules/range-parser": { 2153 | "version": "1.2.1", 2154 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 2155 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 2156 | "engines": { 2157 | "node": ">= 0.6" 2158 | } 2159 | }, 2160 | "node_modules/raw-body": { 2161 | "version": "2.5.2", 2162 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 2163 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 2164 | "dependencies": { 2165 | "bytes": "3.1.2", 2166 | "http-errors": "2.0.0", 2167 | "iconv-lite": "0.4.24", 2168 | "unpipe": "1.0.0" 2169 | }, 2170 | "engines": { 2171 | "node": ">= 0.8" 2172 | } 2173 | }, 2174 | "node_modules/rc": { 2175 | "version": "1.2.8", 2176 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 2177 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 2178 | "dependencies": { 2179 | "deep-extend": "^0.6.0", 2180 | "ini": "~1.3.0", 2181 | "minimist": "^1.2.0", 2182 | "strip-json-comments": "~2.0.1" 2183 | }, 2184 | "bin": { 2185 | "rc": "cli.js" 2186 | } 2187 | }, 2188 | "node_modules/readable-stream": { 2189 | "version": "3.6.2", 2190 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 2191 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 2192 | "dependencies": { 2193 | "inherits": "^2.0.3", 2194 | "string_decoder": "^1.1.1", 2195 | "util-deprecate": "^1.0.1" 2196 | }, 2197 | "engines": { 2198 | "node": ">= 6" 2199 | } 2200 | }, 2201 | "node_modules/requires-port": { 2202 | "version": "1.0.0", 2203 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 2204 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" 2205 | }, 2206 | "node_modules/rimraf": { 2207 | "version": "3.0.2", 2208 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 2209 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 2210 | "dev": true, 2211 | "dependencies": { 2212 | "glob": "^7.1.3" 2213 | }, 2214 | "bin": { 2215 | "rimraf": "bin.js" 2216 | }, 2217 | "funding": { 2218 | "url": "https://github.com/sponsors/isaacs" 2219 | } 2220 | }, 2221 | "node_modules/run-script-os": { 2222 | "version": "1.1.6", 2223 | "resolved": "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz", 2224 | "integrity": "sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==", 2225 | "bin": { 2226 | "run-os": "index.js", 2227 | "run-script-os": "index.js" 2228 | } 2229 | }, 2230 | "node_modules/safe-buffer": { 2231 | "version": "5.2.1", 2232 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2233 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 2234 | "funding": [ 2235 | { 2236 | "type": "github", 2237 | "url": "https://github.com/sponsors/feross" 2238 | }, 2239 | { 2240 | "type": "patreon", 2241 | "url": "https://www.patreon.com/feross" 2242 | }, 2243 | { 2244 | "type": "consulting", 2245 | "url": "https://feross.org/support" 2246 | } 2247 | ] 2248 | }, 2249 | "node_modules/safer-buffer": { 2250 | "version": "2.1.2", 2251 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2252 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2253 | }, 2254 | "node_modules/semver": { 2255 | "version": "7.6.0", 2256 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", 2257 | "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", 2258 | "dependencies": { 2259 | "lru-cache": "^6.0.0" 2260 | }, 2261 | "bin": { 2262 | "semver": "bin/semver.js" 2263 | }, 2264 | "engines": { 2265 | "node": ">=10" 2266 | } 2267 | }, 2268 | "node_modules/send": { 2269 | "version": "0.18.0", 2270 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 2271 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 2272 | "dependencies": { 2273 | "debug": "2.6.9", 2274 | "depd": "2.0.0", 2275 | "destroy": "1.2.0", 2276 | "encodeurl": "~1.0.2", 2277 | "escape-html": "~1.0.3", 2278 | "etag": "~1.8.1", 2279 | "fresh": "0.5.2", 2280 | "http-errors": "2.0.0", 2281 | "mime": "1.6.0", 2282 | "ms": "2.1.3", 2283 | "on-finished": "2.4.1", 2284 | "range-parser": "~1.2.1", 2285 | "statuses": "2.0.1" 2286 | }, 2287 | "engines": { 2288 | "node": ">= 0.8.0" 2289 | } 2290 | }, 2291 | "node_modules/send/node_modules/ms": { 2292 | "version": "2.1.3", 2293 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2294 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 2295 | }, 2296 | "node_modules/serve-static": { 2297 | "version": "1.15.0", 2298 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 2299 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 2300 | "dependencies": { 2301 | "encodeurl": "~1.0.2", 2302 | "escape-html": "~1.0.3", 2303 | "parseurl": "~1.3.3", 2304 | "send": "0.18.0" 2305 | }, 2306 | "engines": { 2307 | "node": ">= 0.8.0" 2308 | } 2309 | }, 2310 | "node_modules/set-function-length": { 2311 | "version": "1.2.2", 2312 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 2313 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 2314 | "dependencies": { 2315 | "define-data-property": "^1.1.4", 2316 | "es-errors": "^1.3.0", 2317 | "function-bind": "^1.1.2", 2318 | "get-intrinsic": "^1.2.4", 2319 | "gopd": "^1.0.1", 2320 | "has-property-descriptors": "^1.0.2" 2321 | }, 2322 | "engines": { 2323 | "node": ">= 0.4" 2324 | } 2325 | }, 2326 | "node_modules/setprototypeof": { 2327 | "version": "1.2.0", 2328 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 2329 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 2330 | }, 2331 | "node_modules/shebang-command": { 2332 | "version": "1.2.0", 2333 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2334 | "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", 2335 | "dependencies": { 2336 | "shebang-regex": "^1.0.0" 2337 | }, 2338 | "engines": { 2339 | "node": ">=0.10.0" 2340 | } 2341 | }, 2342 | "node_modules/shebang-regex": { 2343 | "version": "1.0.0", 2344 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2345 | "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", 2346 | "engines": { 2347 | "node": ">=0.10.0" 2348 | } 2349 | }, 2350 | "node_modules/side-channel": { 2351 | "version": "1.0.6", 2352 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", 2353 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", 2354 | "dependencies": { 2355 | "call-bind": "^1.0.7", 2356 | "es-errors": "^1.3.0", 2357 | "get-intrinsic": "^1.2.4", 2358 | "object-inspect": "^1.13.1" 2359 | }, 2360 | "engines": { 2361 | "node": ">= 0.4" 2362 | }, 2363 | "funding": { 2364 | "url": "https://github.com/sponsors/ljharb" 2365 | } 2366 | }, 2367 | "node_modules/simple-concat": { 2368 | "version": "1.0.1", 2369 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 2370 | "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", 2371 | "funding": [ 2372 | { 2373 | "type": "github", 2374 | "url": "https://github.com/sponsors/feross" 2375 | }, 2376 | { 2377 | "type": "patreon", 2378 | "url": "https://www.patreon.com/feross" 2379 | }, 2380 | { 2381 | "type": "consulting", 2382 | "url": "https://feross.org/support" 2383 | } 2384 | ] 2385 | }, 2386 | "node_modules/simple-get": { 2387 | "version": "4.0.1", 2388 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", 2389 | "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", 2390 | "funding": [ 2391 | { 2392 | "type": "github", 2393 | "url": "https://github.com/sponsors/feross" 2394 | }, 2395 | { 2396 | "type": "patreon", 2397 | "url": "https://www.patreon.com/feross" 2398 | }, 2399 | { 2400 | "type": "consulting", 2401 | "url": "https://feross.org/support" 2402 | } 2403 | ], 2404 | "dependencies": { 2405 | "decompress-response": "^6.0.0", 2406 | "once": "^1.3.1", 2407 | "simple-concat": "^1.0.0" 2408 | } 2409 | }, 2410 | "node_modules/slash": { 2411 | "version": "2.0.0", 2412 | "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", 2413 | "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", 2414 | "engines": { 2415 | "node": ">=6" 2416 | } 2417 | }, 2418 | "node_modules/statuses": { 2419 | "version": "2.0.1", 2420 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 2421 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 2422 | "engines": { 2423 | "node": ">= 0.8" 2424 | } 2425 | }, 2426 | "node_modules/string_decoder": { 2427 | "version": "1.3.0", 2428 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 2429 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 2430 | "dependencies": { 2431 | "safe-buffer": "~5.2.0" 2432 | } 2433 | }, 2434 | "node_modules/strip-json-comments": { 2435 | "version": "2.0.1", 2436 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 2437 | "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", 2438 | "engines": { 2439 | "node": ">=0.10.0" 2440 | } 2441 | }, 2442 | "node_modules/supports-color": { 2443 | "version": "7.2.0", 2444 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2445 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2446 | "dependencies": { 2447 | "has-flag": "^4.0.0" 2448 | }, 2449 | "engines": { 2450 | "node": ">=8" 2451 | } 2452 | }, 2453 | "node_modules/tar": { 2454 | "version": "6.2.0", 2455 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", 2456 | "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", 2457 | "dependencies": { 2458 | "chownr": "^2.0.0", 2459 | "fs-minipass": "^2.0.0", 2460 | "minipass": "^5.0.0", 2461 | "minizlib": "^2.1.1", 2462 | "mkdirp": "^1.0.3", 2463 | "yallist": "^4.0.0" 2464 | }, 2465 | "engines": { 2466 | "node": ">=10" 2467 | } 2468 | }, 2469 | "node_modules/tar-fs": { 2470 | "version": "2.1.1", 2471 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 2472 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 2473 | "dependencies": { 2474 | "chownr": "^1.1.1", 2475 | "mkdirp-classic": "^0.5.2", 2476 | "pump": "^3.0.0", 2477 | "tar-stream": "^2.1.4" 2478 | } 2479 | }, 2480 | "node_modules/tar-fs/node_modules/chownr": { 2481 | "version": "1.1.4", 2482 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 2483 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 2484 | }, 2485 | "node_modules/tar-stream": { 2486 | "version": "2.2.0", 2487 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 2488 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 2489 | "dependencies": { 2490 | "bl": "^4.0.3", 2491 | "end-of-stream": "^1.4.1", 2492 | "fs-constants": "^1.0.0", 2493 | "inherits": "^2.0.3", 2494 | "readable-stream": "^3.1.1" 2495 | }, 2496 | "engines": { 2497 | "node": ">=6" 2498 | } 2499 | }, 2500 | "node_modules/tmp": { 2501 | "version": "0.0.33", 2502 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2503 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2504 | "dependencies": { 2505 | "os-tmpdir": "~1.0.2" 2506 | }, 2507 | "engines": { 2508 | "node": ">=0.6.0" 2509 | } 2510 | }, 2511 | "node_modules/to-regex-range": { 2512 | "version": "5.0.1", 2513 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2514 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2515 | "dependencies": { 2516 | "is-number": "^7.0.0" 2517 | }, 2518 | "engines": { 2519 | "node": ">=8.0" 2520 | } 2521 | }, 2522 | "node_modules/toidentifier": { 2523 | "version": "1.0.1", 2524 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2525 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2526 | "engines": { 2527 | "node": ">=0.6" 2528 | } 2529 | }, 2530 | "node_modules/tough-cookie": { 2531 | "version": "4.1.3", 2532 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", 2533 | "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", 2534 | "dependencies": { 2535 | "psl": "^1.1.33", 2536 | "punycode": "^2.1.1", 2537 | "universalify": "^0.2.0", 2538 | "url-parse": "^1.5.3" 2539 | }, 2540 | "engines": { 2541 | "node": ">=6" 2542 | } 2543 | }, 2544 | "node_modules/tough-cookie/node_modules/universalify": { 2545 | "version": "0.2.0", 2546 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", 2547 | "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", 2548 | "engines": { 2549 | "node": ">= 4.0.0" 2550 | } 2551 | }, 2552 | "node_modules/ts-node": { 2553 | "version": "10.9.2", 2554 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", 2555 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", 2556 | "dev": true, 2557 | "dependencies": { 2558 | "@cspotcode/source-map-support": "^0.8.0", 2559 | "@tsconfig/node10": "^1.0.7", 2560 | "@tsconfig/node12": "^1.0.7", 2561 | "@tsconfig/node14": "^1.0.0", 2562 | "@tsconfig/node16": "^1.0.2", 2563 | "acorn": "^8.4.1", 2564 | "acorn-walk": "^8.1.1", 2565 | "arg": "^4.1.0", 2566 | "create-require": "^1.1.0", 2567 | "diff": "^4.0.1", 2568 | "make-error": "^1.1.1", 2569 | "v8-compile-cache-lib": "^3.0.1", 2570 | "yn": "3.1.1" 2571 | }, 2572 | "bin": { 2573 | "ts-node": "dist/bin.js", 2574 | "ts-node-cwd": "dist/bin-cwd.js", 2575 | "ts-node-esm": "dist/bin-esm.js", 2576 | "ts-node-script": "dist/bin-script.js", 2577 | "ts-node-transpile-only": "dist/bin-transpile.js", 2578 | "ts-script": "dist/bin-script-deprecated.js" 2579 | }, 2580 | "peerDependencies": { 2581 | "@swc/core": ">=1.2.50", 2582 | "@swc/wasm": ">=1.2.50", 2583 | "@types/node": "*", 2584 | "typescript": ">=2.7" 2585 | }, 2586 | "peerDependenciesMeta": { 2587 | "@swc/core": { 2588 | "optional": true 2589 | }, 2590 | "@swc/wasm": { 2591 | "optional": true 2592 | } 2593 | } 2594 | }, 2595 | "node_modules/tunnel-agent": { 2596 | "version": "0.6.0", 2597 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2598 | "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", 2599 | "dependencies": { 2600 | "safe-buffer": "^5.0.1" 2601 | }, 2602 | "engines": { 2603 | "node": "*" 2604 | } 2605 | }, 2606 | "node_modules/type-is": { 2607 | "version": "1.6.18", 2608 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2609 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2610 | "dependencies": { 2611 | "media-typer": "0.3.0", 2612 | "mime-types": "~2.1.24" 2613 | }, 2614 | "engines": { 2615 | "node": ">= 0.6" 2616 | } 2617 | }, 2618 | "node_modules/typescript": { 2619 | "version": "4.9.5", 2620 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", 2621 | "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", 2622 | "dev": true, 2623 | "bin": { 2624 | "tsc": "bin/tsc", 2625 | "tsserver": "bin/tsserver" 2626 | }, 2627 | "engines": { 2628 | "node": ">=4.2.0" 2629 | } 2630 | }, 2631 | "node_modules/ua-parser-js": { 2632 | "version": "1.0.37", 2633 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", 2634 | "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", 2635 | "funding": [ 2636 | { 2637 | "type": "opencollective", 2638 | "url": "https://opencollective.com/ua-parser-js" 2639 | }, 2640 | { 2641 | "type": "paypal", 2642 | "url": "https://paypal.me/faisalman" 2643 | }, 2644 | { 2645 | "type": "github", 2646 | "url": "https://github.com/sponsors/faisalman" 2647 | } 2648 | ], 2649 | "engines": { 2650 | "node": "*" 2651 | } 2652 | }, 2653 | "node_modules/uhyphen": { 2654 | "version": "0.2.0", 2655 | "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", 2656 | "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==" 2657 | }, 2658 | "node_modules/universalify": { 2659 | "version": "2.0.1", 2660 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", 2661 | "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", 2662 | "engines": { 2663 | "node": ">= 10.0.0" 2664 | } 2665 | }, 2666 | "node_modules/unpipe": { 2667 | "version": "1.0.0", 2668 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2669 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 2670 | "engines": { 2671 | "node": ">= 0.8" 2672 | } 2673 | }, 2674 | "node_modules/url-parse": { 2675 | "version": "1.5.10", 2676 | "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", 2677 | "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", 2678 | "dependencies": { 2679 | "querystringify": "^2.1.1", 2680 | "requires-port": "^1.0.0" 2681 | } 2682 | }, 2683 | "node_modules/util-deprecate": { 2684 | "version": "1.0.2", 2685 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2686 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 2687 | }, 2688 | "node_modules/utils-merge": { 2689 | "version": "1.0.1", 2690 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2691 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 2692 | "engines": { 2693 | "node": ">= 0.4.0" 2694 | } 2695 | }, 2696 | "node_modules/v8-compile-cache-lib": { 2697 | "version": "3.0.1", 2698 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 2699 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", 2700 | "dev": true 2701 | }, 2702 | "node_modules/vary": { 2703 | "version": "1.1.2", 2704 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2705 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 2706 | "engines": { 2707 | "node": ">= 0.8" 2708 | } 2709 | }, 2710 | "node_modules/which": { 2711 | "version": "1.3.1", 2712 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2713 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2714 | "dependencies": { 2715 | "isexe": "^2.0.0" 2716 | }, 2717 | "bin": { 2718 | "which": "bin/which" 2719 | } 2720 | }, 2721 | "node_modules/wrappy": { 2722 | "version": "1.0.2", 2723 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2724 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 2725 | }, 2726 | "node_modules/ws": { 2727 | "version": "7.5.9", 2728 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", 2729 | "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", 2730 | "engines": { 2731 | "node": ">=8.3.0" 2732 | }, 2733 | "peerDependencies": { 2734 | "bufferutil": "^4.0.1", 2735 | "utf-8-validate": "^5.0.2" 2736 | }, 2737 | "peerDependenciesMeta": { 2738 | "bufferutil": { 2739 | "optional": true 2740 | }, 2741 | "utf-8-validate": { 2742 | "optional": true 2743 | } 2744 | } 2745 | }, 2746 | "node_modules/yallist": { 2747 | "version": "4.0.0", 2748 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2749 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 2750 | }, 2751 | "node_modules/yaml": { 2752 | "version": "1.10.2", 2753 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 2754 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 2755 | "engines": { 2756 | "node": ">= 6" 2757 | } 2758 | }, 2759 | "node_modules/yn": { 2760 | "version": "3.1.1", 2761 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 2762 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 2763 | "dev": true, 2764 | "engines": { 2765 | "node": ">=6" 2766 | } 2767 | } 2768 | } 2769 | } 2770 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "headless-task-server", 3 | "version": "1.4.4", 4 | "description": "A headless browser task manager based on Hero", 5 | "main": "dist/index.js", 6 | "engines": { 7 | "node": ">=18.13" 8 | }, 9 | "scripts": { 10 | "clean": "rimraf dist && rimraf tsconfig.tsbuildinfo", 11 | "stamp": "run-script-os", 12 | "stamp:nix": "date -u +%Y-%m-%dT%H:%M:%S > ./dist/buildtimestamp", 13 | "stamp:win32": "windwos_generate_stamp.bat > ./dist/buildtimestamp", 14 | "postinstall": "patch-package", 15 | "pretest": "node ./tests/pretest.js", 16 | "build": "tsc && npm run stamp", 17 | "start": "node ./dist/index.js" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/luka-dev/headless-task-server.git" 22 | }, 23 | "keywords": [ 24 | "headless", 25 | "browser", 26 | "playwright", 27 | "puppeteer", 28 | "task", 29 | "automation", 30 | "cluster", 31 | "scrape", 32 | "crawl", 33 | "chrome", 34 | "chromium", 35 | "parse", 36 | "hero", 37 | "secret-agent", 38 | "sa", 39 | "render", 40 | "js", 41 | "php" 42 | ], 43 | "author": "luka-dev", 44 | "license": "MIT", 45 | "bugs": { 46 | "url": "https://github.com/luka-dev/headless-task-server/issues" 47 | }, 48 | "homepage": "https://github.com/luka-dev/headless-task-server#readme", 49 | "devDependencies": { 50 | "@types/cli-progress": "^3.11.0", 51 | "@types/command-line-args": "^5.2.0", 52 | "@types/cors": "^2.8.12", 53 | "@types/express": "^4.17.13", 54 | "@types/node": "^17.0.23", 55 | "rimraf": "^3.0.2", 56 | "ts-node": "^10.4.0", 57 | "typescript": "^4.5.2" 58 | }, 59 | "dependencies": { 60 | "@ulixee/hero": "^2.0.0-alpha.28", 61 | "@ulixee/hero-core": "^2.0.0-alpha.28", 62 | "@ulixee/execute-js-plugin": "^2.0.0-alpha.28", 63 | "axios": "^1.3.4", 64 | "cors": "^2.8.5", 65 | "express": "^4.17.1", 66 | "form-data": "^4.0.0", 67 | "fs": "^0.0.2", 68 | "helmet": "^5.0.2", 69 | "os": "^0.1.2", 70 | "patch-package": "^6.5.1", 71 | "run-script-os": "^1.1.6" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /patches/@ulixee+hero-core+2.0.0-alpha.28.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/@ulixee/hero-core/injected-scripts/Fetcher.js b/node_modules/@ulixee/hero-core/injected-scripts/Fetcher.js 2 | index 9f20d00..b6cf48a 100644 3 | --- a/node_modules/@ulixee/hero-core/injected-scripts/Fetcher.js 4 | +++ b/node_modules/@ulixee/hero-core/injected-scripts/Fetcher.js 5 | @@ -18,7 +18,18 @@ class Fetcher { 6 | if (typeof input === 'number') { 7 | requestOrUrl = NodeTracker.getWatchedNodeWithId(input); 8 | } 9 | + let timer = null; 10 | + if (typeof init === 'object' && init.hasOwnProperty('timeout') && typeof init.timeout === 'number' && init.timeout > 0) { 11 | + const controller = new AbortController(); 12 | + timer = setTimeout(() => controller.abort(), init.timeout); 13 | + init = { 14 | + ...init, 15 | + timeout: undefined, 16 | + signal: controller.signal, 17 | + }; 18 | + } 19 | const response = await fetch(requestOrUrl, init); 20 | + clearTimeout(timer); 21 | const nodeId = NodeTracker.watchNode(response); 22 | return { 23 | id: nodeId, 24 | -------------------------------------------------------------------------------- /playground.http: -------------------------------------------------------------------------------- 1 | ### Example Domain 2 | POST {{host}}/task 3 | Content-Type: application/json 4 | Authorization: {{auth_key}} 5 | 6 | { 7 | "script": "await agent.goto('https://example.com/'); resolve(await agent.document.title);" 8 | } 9 | 10 | > {% 11 | client.test("Check title", function() { 12 | client.assert(response.body.output === "Example Domain", "ERROR! Title isn't correct"); 13 | }); 14 | %} 15 | 16 | ### Test Error Handling Waiting for not-existed-element 17 | POST {{host}}/task 18 | Content-Type: application/json 19 | Authorization: {{auth_key}} 20 | 21 | { 22 | "script": "await agent.goto('https://example.com/'); await agent.waitForElement('#no-existed-element', {timeoutMs: 10000}); resolve(await agent.document.title);" 23 | } 24 | 25 | > {% 26 | client.test("Check Error", function () { 27 | client.assert(response.body.error.includes('Timeout waiting for element to exist'), "ERROR! TimeoutError has different message"); 28 | }); 29 | %} 30 | 31 | ### Test Error Handling for SyntaxError 32 | POST {{host}}/task 33 | Content-Type: application/json 34 | Authorization: {{auth_key}} 35 | 36 | { 37 | "script": "this SCRIPT IS BAD///////////;;;; NOT WORKING" 38 | } 39 | 40 | > {% 41 | client.test("SyntaxError", function () { 42 | client.assert(response.body.error.includes('SyntaxError'), "ERROR! SyntaxError has different message"); 43 | }); 44 | %} 45 | 46 | ### CreepJS Score 47 | POST {{host}}/task 48 | Content-Type: application/json 49 | Authorization: {{auth_key}} 50 | 51 | { 52 | "script": "await agent.goto('https://abrahamjuliot.github.io/creepjs/'); await agent.waitForPaintingStable(); const { document } = agent.activeTab; const element = document.querySelector('#fingerprint-data > div.visitor-info > div > div:nth-child(2) > div:nth-child(2) > span'); await agent.waitForElement(element, {waitForVisible: true}); resolve(parseFloat((await element.textContent)?.replace('%', '').trim() ?? '0'));" 53 | } 54 | 55 | > {% 56 | client.test("Check Error", function () { 57 | client.assert(response.body.output >= 50, "WARNING! CreepJS trust score missing or less than 50%"); 58 | }); 59 | %} 60 | 61 | 62 | ### Check handler for UnhandledRejection 63 | POST {{host}}/task 64 | Content-Type: application/json 65 | Authorization: {{auth_key}} 66 | 67 | < ./tests/UnhandledRejection.json 68 | 69 | ### Check Fetch plugin 70 | POST {{host}}/task 71 | Content-Type: application/json 72 | Authorization: {{auth_key}} 73 | 74 | < ./tests/FetchTest.json -------------------------------------------------------------------------------- /src/clases/Logger.ts: -------------------------------------------------------------------------------- 1 | import FormData from "form-data"; 2 | import axios from "axios"; 3 | import {envString} from "../helpers/EnvHelper"; 4 | export default class Logger { 5 | private static rows: string[] = []; 6 | 7 | private static refLog: ((message?: any, ...optionalParams: any[]) => void) | undefined = undefined; 8 | private static refWarn: ((message?: any, ...optionalParams: any[]) => void) | undefined = undefined; 9 | private static refError: ((message?: any, ...optionalParams: any[]) => void) | undefined = undefined; 10 | 11 | private static onMessage(ref: (message?: any, ...optionalParams: any[]) => void, ...messages: any[]): void { 12 | ref(...messages); 13 | for (const message of messages) { 14 | if (message instanceof Error) { 15 | Logger.rows.push(message.stack?.toString() ?? message.toString()); 16 | } else { 17 | Logger.rows.push(message?.toString()); 18 | } 19 | } 20 | Logger.rows.slice(-1000); 21 | } 22 | 23 | public static hook(): void { 24 | Logger.refLog = console.log; 25 | Logger.refWarn = console.warn; 26 | Logger.refError = console.error; 27 | console.log = (...messages: any[]) => { 28 | Logger.onMessage(Logger.refLog!, ...messages); 29 | } 30 | console.warn = (...messages: any[]) => { 31 | Logger.onMessage(Logger.refWarn!, ...messages); 32 | } 33 | console.error = (...messages: any[]) => { 34 | Logger.onMessage(Logger.refError!, ...messages); 35 | } 36 | } 37 | 38 | public static unhook(): void { 39 | console.log = Logger.refLog!; 40 | console.warn = Logger.refWarn!; 41 | console.error = Logger.refError!; 42 | } 43 | 44 | public static clear(): void { 45 | Logger.rows = []; 46 | } 47 | public static sendLogs(): Promise { 48 | return new Promise((resolve, reject) => { 49 | if (envString('TELEGRAM_TOKEN') && envString('TELEGRAM_CHAT_ID')) { 50 | const form = new FormData(); 51 | form.append('chat_id', envString('TELEGRAM_CHAT_ID')); 52 | form.append('caption', '#HERO CRASHED'); 53 | form.append('document', Buffer.from(Logger.rows.join('\n'), 'utf-8'), {filename: 'crash.log'}); 54 | 55 | axios.post( 56 | `https://api.telegram.org/bot${envString('TELEGRAM_TOKEN')}/sendDocument`, 57 | form, 58 | { 59 | headers: { 60 | ...form.getHeaders(), 61 | 'Content-Type': 'multipart/form-data', 62 | }, 63 | } 64 | ) 65 | .then(() => { 66 | console.log('Log sent'); 67 | resolve(); 68 | }) 69 | .catch((error) => { 70 | console.error('Error sending log', error); 71 | reject(); 72 | }); 73 | } else { 74 | reject(); 75 | } 76 | }); 77 | } 78 | 79 | public static getRows(): string[] { 80 | return Logger.rows; 81 | } 82 | } -------------------------------------------------------------------------------- /src/clases/Task.ts: -------------------------------------------------------------------------------- 1 | import {TaskStatus} from "../enums/TaskStatus"; 2 | import Timings from "./Timings"; 3 | import ITaskOptions from "../types/ITaskOptions"; 4 | import IUserProfile from "@ulixee/hero-interfaces/IUserProfile"; 5 | import Hero from "@ulixee/hero"; 6 | import AsyncFunction from "../helpers/AsyncFuncion"; 7 | import {findEvalDetailsFromError} from "../helpers/ErrorHelper"; 8 | import TaskSessionTimeout from "../exceptions/TaskSessionTimeout"; 9 | 10 | export default class Task { 11 | private readonly script: string; 12 | public readonly options: ITaskOptions; 13 | public profile: IUserProfile; 14 | public readonly timings: Timings; 15 | public status: TaskStatus; 16 | public output: any = null; 17 | public error: any = null; 18 | private isFulfilled: boolean = false; 19 | public timer: NodeJS.Timeout|null = null; 20 | public promise: (agent: Hero) => Promise; 21 | private readonly callback: (task: Task) => void; 22 | public constructor(script: string, options: ITaskOptions = {}, profile: IUserProfile = {}, callback: (task: Task) => void) { 23 | this.script = script; 24 | this.options = options; 25 | this.profile = profile; 26 | this.timings = new Timings(); 27 | this.status = TaskStatus.CREATED; 28 | this.callback = callback; 29 | 30 | this.promise = (agent: Hero) => { 31 | let fulfilledCheckInterval: NodeJS.Timer|null = null; 32 | 33 | const exportProfile = async (): Promise => { 34 | try { 35 | return await agent.exportUserProfile(); 36 | } catch (error) { 37 | if (error instanceof Error) { 38 | console.warn('Task: Script: exportUserProfile: ' + error.name + ': ' + error.message); 39 | } else { 40 | console.warn('Task: Script: exportUserProfile: ' + error) 41 | } 42 | } 43 | return this.profile; 44 | } 45 | 46 | const promise = new Promise((resolve, reject) => { 47 | fulfilledCheckInterval = setInterval(() => { 48 | if (this.isFulfilled) { 49 | reject(new TaskSessionTimeout()); 50 | clearInterval(fulfilledCheckInterval!); 51 | } 52 | }, 10); 53 | 54 | //TODO: suppress console.log in user scripts 55 | return new AsyncFunction( 56 | 'resolve', 'reject', 'agent', 57 | `try {\n` + 58 | `${this.script};\n` + 59 | `resolve(); } catch(e) { e.name = 'TaskOuterCatch' ; reject(e); }` 60 | ) 61 | (resolve, reject, agent) 62 | } 63 | ); 64 | 65 | promise 66 | .finally(() => { 67 | clearInterval(fulfilledCheckInterval!); 68 | }) 69 | .then(async (output) => { 70 | this.fulfill(TaskStatus.RESOLVE, output, null, await exportProfile()); 71 | }) 72 | .catch(async (error) => { 73 | if (error instanceof Error) { 74 | console.warn(('Task: Script: ' + error.name + ': ' + error.message + '\n' + findEvalDetailsFromError(error)).trim()); 75 | } else { 76 | console.warn('Task: Script: ' + error); 77 | } 78 | this.fulfill( 79 | (error instanceof Error && error.name === 'TaskOuterCatch') ? TaskStatus.THROW : TaskStatus.REJECT, 80 | null, 81 | error, 82 | await exportProfile() 83 | ); 84 | }); 85 | 86 | return promise; 87 | } 88 | } 89 | 90 | public fulfill(status: TaskStatus, output: any = null, error: any = null, profile: IUserProfile|null = null): void { 91 | if (this.isFulfilled) { 92 | console.warn('Task: already fulfilled'); 93 | return; 94 | } 95 | 96 | this.isFulfilled = true; 97 | this.timings.end(); 98 | this.status = status; 99 | this.output = output; 100 | this.error = error; 101 | this.profile = profile ?? this.profile; 102 | 103 | this.callback(this); 104 | } 105 | 106 | public getIsFulfilled(): boolean { 107 | return this.isFulfilled; 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /src/clases/TasksPoolHandler.ts: -------------------------------------------------------------------------------- 1 | import {TaskStatus} from "../enums/TaskStatus"; 2 | 3 | import Hero, {BlockedResourceType, ConnectionToHeroCore} from '@ulixee/hero'; 4 | import HeroCore from '@ulixee/hero-core'; 5 | import {TransportBridge} from '@ulixee/net'; 6 | 7 | import Task from "./Task"; 8 | import * as OS from "os"; 9 | import {bytesToMegabytes} from "../helpers/OSHelper"; 10 | import {envBool, envInt, envString} from "../helpers/EnvHelper"; 11 | import {IpLookupServices} from "@ulixee/default-browser-emulator/lib/helpers/lookupPublicIp"; 12 | import TimeoutError from "@ulixee/commons/interfaces/TimeoutError"; 13 | import Logger from "./Logger"; 14 | import {clearTimeout} from "timers"; 15 | 16 | import ExecuteJsPlugin from '@ulixee/execute-js-plugin'; 17 | 18 | export default class TasksPoolHandler { 19 | private readonly maxConcurrency: number; 20 | private readonly queueTimeout: number; 21 | private readonly initTimeout: number; 22 | private readonly sessionTimeout: number; 23 | private readonly upstreamProxyUrl: string|null; 24 | private readonly blockedResourceTypes: BlockedResourceType[]; 25 | private readonly core: HeroCore; 26 | private isRunning: boolean = false; 27 | private timer?: NodeJS.Timer; 28 | private readonly connectionToCore: ConnectionToHeroCore; 29 | private pool: Task[] = []; 30 | private queue: Task[] = []; 31 | private counter = { 32 | resolve: 0, 33 | reject: 0, 34 | throw: 0, 35 | init_error: 0, 36 | bad_args: 0, 37 | queue_timeout: 0, 38 | init_timeout: 0, 39 | session_timeout: 0, 40 | }; 41 | public constructor( 42 | maxConcurrency: number, 43 | queueTimeout: number = 30000, 44 | initTimeout: number = 15000, 45 | sessionTimeout: number = 60000, 46 | upstreamProxyUrl: string | null = null, 47 | blockedResourceTypes: BlockedResourceType[] = [] 48 | ) { 49 | this.maxConcurrency = envInt('MAX_CONCURRENCY') ?? maxConcurrency; 50 | 51 | //Timeouts 52 | this.queueTimeout = envInt('QUEUE_TIMEOUT') ?? queueTimeout; 53 | this.initTimeout = envInt('INIT_TIMEOUT') ?? initTimeout; 54 | this.sessionTimeout = envInt('SESSION_TIMEOUT') ?? sessionTimeout; 55 | 56 | this.upstreamProxyUrl = envString('UPSTREAM_PROXY_URL') ?? upstreamProxyUrl; 57 | this.blockedResourceTypes = blockedResourceTypes; 58 | 59 | this.core = new HeroCore(); 60 | 61 | const bridge = new TransportBridge(); 62 | this.connectionToCore = new ConnectionToHeroCore(bridge.transportToCore, { 63 | instanceTimeoutMillis: this.sessionTimeout, 64 | maxConcurrency: this.maxConcurrency * 4 65 | }); 66 | this.connectionToCore.on('disconnected', () => this.onDisconnected()); 67 | this.core.addConnection(bridge.transportToClient); 68 | this.core.use(ExecuteJsPlugin); 69 | } 70 | 71 | public push(task: Task): void { 72 | task.status = TaskStatus.QUEUE; 73 | 74 | //QUEUE_TIMEOUT Watchdog 75 | task.timer = setTimeout(async () => { 76 | const isInPool = this.pool.includes(task); 77 | const message = `TaskPool: ${isInPool ? 'Init' : 'Queue'} Timeout, pool: ${this.pool.length}, queue: ${this.queue.length}`; 78 | console.warn(message); 79 | task.fulfill(TaskStatus.QUEUE_TIMEOUT, null, message); 80 | this.counter.queue_timeout++; 81 | 82 | clearTimeout(task.timer!); 83 | }, this.queueTimeout); 84 | 85 | this.queue.push(task); 86 | } 87 | 88 | private async execute(task: Task): Promise { 89 | task.status = TaskStatus.RUNNING; 90 | 91 | //INIT_TIMEOUT Watchdog 92 | clearTimeout(task.timer!); 93 | task.timer = setTimeout(async () => { 94 | task.fulfill(TaskStatus.INIT_TIMEOUT, null, 'TaskPool: Agent: Too long Hero init'); 95 | this.counter.init_timeout++; 96 | clearTimeout(task.timer!); 97 | }, this.initTimeout); 98 | 99 | let instance: Hero | null = null; 100 | try { 101 | instance = new Hero({ 102 | blockedResourceTypes: this.blockedResourceTypes, 103 | upstreamProxyUrl: this.upstreamProxyUrl ?? undefined, 104 | upstreamProxyIpMask: { 105 | ipLookupService: IpLookupServices.aws, 106 | }, 107 | ...task.options, 108 | showChrome: envBool('SHOW_CHROME'), 109 | userProfile: task.profile, 110 | connectionToCore: this.connectionToCore 111 | }); 112 | instance.use(ExecuteJsPlugin); 113 | 114 | clearTimeout(task.timer!); 115 | if (task.getIsFulfilled()) { 116 | await instance.close(); 117 | return; 118 | } 119 | 120 | //SESSION_TIMEOUT Watchdog 121 | task.timer = setTimeout(async () => { 122 | this.counter.session_timeout++; 123 | task.fulfill(TaskStatus.SESSION_TIMEOUT, null, 'Task: Script: Session Timeout'); 124 | clearTimeout(task.timer!); 125 | }, this.sessionTimeout); 126 | 127 | //@ts-ignore we have Omit, but to reduce complexity we represent as Hero 128 | task.promise(instance) 129 | .then(async () => { 130 | this.counter.resolve++; 131 | }) 132 | .catch(async (error) => { 133 | if (!task.getIsFulfilled()) { 134 | (error instanceof Error && error.name === 'TaskOuterCatch') ? this.counter.throw++ : this.counter.reject++; 135 | } 136 | }) 137 | .finally(async () => { 138 | clearTimeout(task.timer!); 139 | await instance?.close(); 140 | }); 141 | } 142 | catch (error: any) { 143 | clearTimeout(task.timer!); 144 | 145 | //TimeoutError while connecting IpLookupServices for proxy check 146 | //Possible error in proxy or target is down 147 | if (error instanceof TimeoutError && error.message.includes('Timeout connecting to')) { 148 | task.fulfill(TaskStatus.INIT_ERROR, null, `TaskPool: Agent: Proxy: ${error.name}: ${error.message}`); 149 | await instance?.close(); 150 | } 151 | //HttpProxyConnectError: Http Proxy Connect Error connection refused (404) 152 | //form "@ulixee/unblocked-agent-mitm-socket" not exported 153 | else if (error instanceof Error && error.name == 'HttpProxyConnectError') { 154 | task.fulfill(TaskStatus.INIT_ERROR, null, `TaskPool: Agent: Proxy: ${error.name}: ${error.message}`); 155 | await instance?.close(); 156 | } 157 | //Socks5ProxyConnectError, same as HttpProxyConnectError above 158 | else if (error instanceof Error && error.name == 'Socks5ProxyConnectError') { 159 | task.fulfill(TaskStatus.INIT_ERROR, null, `TaskPool: Agent: Proxy: ${error.name}: ${error.message}`); 160 | await instance?.close(); 161 | } 162 | //handle fatal error, recommend to close all agents and restart app 163 | else { 164 | console.error(`TaskPool: Hero Core Init Error: ${error.name}: ${error.message}`); 165 | task.fulfill(TaskStatus.INIT_ERROR, null, `TaskPool: Agent: ${error.name}: ${error.message}`); 166 | this.close(); 167 | await instance?.close(); 168 | console.warn('TaskPool: Hero Core Shutdown, waiting for pool to finish'); 169 | this.onDisconnected() 170 | } 171 | } 172 | } 173 | 174 | private tick(): void { 175 | this.pool = this.pool.filter((task) => [TaskStatus.RUNNING, TaskStatus.QUEUE].includes(task.status)) 176 | this.queue = this.queue.filter((task) => TaskStatus.QUEUE_TIMEOUT !== task.status); 177 | 178 | if (this.pool.length < this.maxConcurrency && this.queue.length > 0) { 179 | const freeMemory = bytesToMegabytes(OS.freemem()); 180 | //Hard limit to avoid crash 181 | if (freeMemory < 500 && !envBool('CONCURRENCY_DISABLE_MEM_LIMITER')) { 182 | console.warn(`TaskPool: Tick: Low on free memory alert ${freeMemory}MB`); 183 | return; 184 | } 185 | 186 | const task = this.queue.shift()!; 187 | this.pool.push(task); 188 | this.execute(task); 189 | } 190 | } 191 | 192 | public async start(): Promise { 193 | await this.core.start(); 194 | this.isRunning = true; 195 | this.timer = setInterval(() => this.tick(), 10); 196 | } 197 | 198 | public async close(): Promise { 199 | clearInterval(this.timer); 200 | await this.core.close(); 201 | this.isRunning = false; 202 | 203 | console.warn('TaskPool: Queue: Stopped'); 204 | console.warn('TaskPool: Queue: Clearing queue'); 205 | 206 | this.queue.forEach((task: Task) => { 207 | task.fulfill(TaskStatus.INIT_ERROR, null, 'TaskPool: Queue: Hero Core Shutdown'); 208 | }); 209 | 210 | } 211 | 212 | public onDisconnected() { 213 | new Promise((resolve) => { 214 | setInterval(() => { 215 | this.pool = this.pool.filter((task) => [TaskStatus.RUNNING, TaskStatus.QUEUE].includes(task.status)) 216 | if (this.pool.length === 0) { 217 | resolve(); 218 | } 219 | }, 10); 220 | }) 221 | .finally(() => { 222 | console.warn('TaskPool: Hero Core Shutdown, pool finished'); 223 | Logger.sendLogs() 224 | .finally(() => { 225 | console.warn('TaskPool: Logger: Hero Core Shutdown, logs sent'); 226 | process.exit(1); 227 | }); 228 | }) 229 | } 230 | 231 | public poolLength(): number { 232 | return this.pool.length; 233 | } 234 | public queueLength(): number { 235 | return this.queue.length; 236 | } 237 | public getCounter() { 238 | return this.counter; 239 | } 240 | public getCounterTotal(): number { 241 | return Object.values(this.counter).reduce((a, b) => a + b, 0); 242 | } 243 | 244 | public getIsRunning(): boolean { 245 | return this.isRunning; 246 | } 247 | 248 | public incrementCounterBadArgs() : void { 249 | this.counter.bad_args++; 250 | } 251 | 252 | } -------------------------------------------------------------------------------- /src/clases/Timings.ts: -------------------------------------------------------------------------------- 1 | import {ISODate} from "../helpers/ISODate"; 2 | 3 | export default class Timings { 4 | public readonly created_at: ISODate; 5 | public begin_at: ISODate | null = null; 6 | public end_at: ISODate | null = null; 7 | 8 | public constructor() { 9 | this.created_at = new ISODate(); 10 | } 11 | 12 | public begin(): void { 13 | this.begin_at = new ISODate(); 14 | } 15 | 16 | public end(): void { 17 | this.end_at = new ISODate(); 18 | } 19 | } -------------------------------------------------------------------------------- /src/clases/WebServer.ts: -------------------------------------------------------------------------------- 1 | import express, {Express, Request, Response, NextFunction} from "express"; 2 | import helmet from "helmet"; 3 | import cors from "cors"; 4 | import http from "http"; 5 | import {envInt, envString} from "../helpers/EnvHelper"; 6 | 7 | export interface RouteCallback { 8 | (request: Request, response: Response, next: NextFunction): void; 9 | } 10 | 11 | export default class WebServer { 12 | private authKey: string | null = null; 13 | private readonly port: number | null; 14 | private app: Express; 15 | 16 | private server: http.Server | null = null; 17 | 18 | public constructor(port: number = 8080, useCors: boolean = true) { 19 | this.port = envInt('SERVER_PORT') ?? port; 20 | 21 | this.app = express(); 22 | 23 | this.app.use(helmet()); 24 | this.app.use(express.json()); 25 | this.app.use(express.urlencoded({extended: true})); 26 | 27 | if (useCors) { 28 | this.app.use(cors()) 29 | } 30 | } 31 | 32 | public setAuthKey(key: string | null = null): void { 33 | this.authKey = envString('AUTH_KEY') ?? key; 34 | } 35 | 36 | public checkAuth(request: Request): boolean { 37 | if (this.authKey === null) { 38 | return true; 39 | } 40 | 41 | return request.get('Authorization') === this.authKey; 42 | } 43 | 44 | public start(): http.Server { 45 | if (this.server === null) { 46 | this.server = this.app.listen(this.port); 47 | console.log(`Runned on port:${this.port}`); 48 | if (this.authKey === null) { 49 | console.log('APP Runned in InSecure mode!'); 50 | } else { 51 | this.app.all('*', (request, response, next) => { 52 | if (request.url !== '/' && !this.checkAuth(request)) { 53 | response.send(401); 54 | } 55 | return next(); 56 | }); 57 | } 58 | } 59 | 60 | return this.server; 61 | } 62 | 63 | public stop(): void { 64 | if (this.server !== null) { 65 | this.server.close(); 66 | this.server = null; 67 | } 68 | } 69 | 70 | public all(route: string, callback: RouteCallback): void { 71 | this.app.all(route, callback) 72 | } 73 | 74 | public get(route: string, callback: RouteCallback): void { 75 | this.app.get(route, callback) 76 | } 77 | 78 | public post(route: string, callback: RouteCallback): void { 79 | this.app.post(route, callback) 80 | } 81 | 82 | public put(route: string, callback: RouteCallback): void { 83 | this.app.put(route, callback) 84 | } 85 | 86 | public delete(route: string, callback: RouteCallback): void { 87 | this.app.delete(route, callback) 88 | } 89 | 90 | public patch(route: string, callback: RouteCallback): void { 91 | this.app.patch(route, callback) 92 | } 93 | 94 | public options(route: string, callback: RouteCallback): void { 95 | this.app.options(route, callback) 96 | } 97 | 98 | public head(route: string, callback: RouteCallback): void { 99 | this.app.head(route, callback) 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/enums/TaskStatus.ts: -------------------------------------------------------------------------------- 1 | export enum TaskStatus { 2 | //Under processing statuses 3 | CREATED = 'CREATED', 4 | QUEUE = 'QUEUE', 5 | RUNNING = 'RUNNING', 6 | 7 | //Final statuses 8 | RESOLVE = 'RESOLVE', 9 | REJECT = 'REJECT', 10 | THROW = 'THROW', 11 | INIT_ERROR = 'INIT_ERROR', 12 | BAD_ARGS = 'BAD_ARGS', 13 | QUEUE_TIMEOUT = 'QUEUE_TIMEOUT', 14 | INIT_TIMEOUT = 'INIT_TIMEOUT', 15 | SESSION_TIMEOUT = 'SESSION_TIMEOUT', 16 | } -------------------------------------------------------------------------------- /src/exceptions/TaskSessionTimeout.ts: -------------------------------------------------------------------------------- 1 | export default class TaskSessionTimeout extends Error { 2 | constructor() { 3 | super('Execution: fulfilled before execution ended, aborting.'); 4 | this.name = 'TaskSessionTimeout'; 5 | } 6 | } -------------------------------------------------------------------------------- /src/helpers/AsyncFuncion.ts: -------------------------------------------------------------------------------- 1 | export default Object.getPrototypeOf(async function(){}).constructor -------------------------------------------------------------------------------- /src/helpers/EnvHelper.ts: -------------------------------------------------------------------------------- 1 | export function envInt(key: string): number | null { 2 | const value = parseInt(process.env[key] ?? ''); 3 | return isNaN(value) ? null : value; 4 | } 5 | 6 | export function envBool(key: string): boolean { 7 | return process.env[key] === 'true' || process.env[key] === '1'; 8 | } 9 | 10 | export function envString(key: string): string | null { 11 | const env = process.env[key]; 12 | return (env !== undefined && env.length) ? env : null; 13 | } -------------------------------------------------------------------------------- /src/helpers/ErrorHelper.ts: -------------------------------------------------------------------------------- 1 | export function findEvalDetailsFromError(error: Error): string { 2 | const stack = (error.stack ?? '').split('\n'); 3 | const evalLines = stack.filter(line => line.includes('eval at ') && line.includes('Task.js')); 4 | return evalLines.map((line) => { 5 | line = line.trim(); 6 | line = line.replace(/ \(.+\), /gm, ''); 7 | 8 | //Change line numbers t o prevent line number mismatch due to try/catch overhead 9 | const number = [...line.matchAll(/(\d+):(\d+)/gm)][0] ?? []; 10 | if (number.length == 3) { 11 | line = line.replace(number[0], `${parseInt(number[1]) - 3}:${number[2]}`); 12 | } 13 | 14 | return line; 15 | } 16 | ).join('\n'); 17 | } -------------------------------------------------------------------------------- /src/helpers/ISODate.ts: -------------------------------------------------------------------------------- 1 | export class ISODate extends Date 2 | { 3 | toJSON(key?: any): string { 4 | return this.toString() 5 | } 6 | 7 | toString(): string { 8 | return this.toISOString().split('.')[0]; 9 | } 10 | } -------------------------------------------------------------------------------- /src/helpers/OSHelper.ts: -------------------------------------------------------------------------------- 1 | export function bytesToMegabytes(bytes: number): number { 2 | return Math.floor(bytes / 1024 / 1024); 3 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import TasksPoolHandler from "./clases/TasksPoolHandler"; 2 | import {TaskStatus} from "./enums/TaskStatus"; 3 | import {ISODate} from "./helpers/ISODate"; 4 | import WebServer from "./clases/WebServer"; 5 | import {readFileSync} from "fs"; 6 | import * as OS from "os"; 7 | import ITasksPoolHandler from "./types/ITasksPoolHandler"; 8 | import IWebServerConfig from "./types/IWebServerConfig"; 9 | import Task from "./clases/Task"; 10 | import {envInt} from "./helpers/EnvHelper"; 11 | import {bytesToMegabytes} from "./helpers/OSHelper"; 12 | import Logger from "./clases/Logger"; 13 | import {findEvalDetailsFromError} from "./helpers/ErrorHelper"; 14 | 15 | Logger.hook(); 16 | 17 | // process.on('warning', e => console.warn(e.stack)); 18 | // process.on('uncaughtException', e => console.warn(e.stack)) 19 | 20 | const config: IWebServerConfig & ITasksPoolHandler = JSON.parse(readFileSync(__dirname + '/../config.json', 'utf8')); 21 | 22 | const webServer = new WebServer(config.SERVER_PORT); 23 | webServer.setAuthKey(config.AUTH_KEY); 24 | 25 | webServer.start() 26 | .on('listening', async () => { 27 | 28 | const tasksHandler = new TasksPoolHandler( 29 | config.DEFAULT_MAX_CONCURRENCY, 30 | config.DEFAULT_INIT_TIMEOUT, 31 | config.DEFAULT_QUEUE_TIMEOUT, 32 | config.DEFAULT_SESSION_TIMEOUT, 33 | config.DEFAULT_UPSTREAM_PROXY_URL, 34 | config.DEFAULT_BLOCKED_RESOURCE_TYPES 35 | ); 36 | await tasksHandler.start(); 37 | console.log('Browser Handler runned'); 38 | 39 | const buildTimeStamp: string | null = readFileSync('./dist/buildtimestamp', 'utf8').trim() ?? null; 40 | const runTimeStamp: string | null = (new ISODate()).toString(); 41 | 42 | webServer.get('/', (request, response) => { 43 | response.json({ 44 | health: 'ok', 45 | }); 46 | }); 47 | 48 | webServer.get('/stats', (request, response) => { 49 | const freeMem = OS.freemem(); 50 | response.json({ 51 | timestamp: { 52 | build: buildTimeStamp, 53 | run: runTimeStamp 54 | }, 55 | task: { 56 | timeout: { 57 | queue: envInt('QUEUE_TIMEOUT') ?? config.DEFAULT_QUEUE_TIMEOUT, 58 | init: envInt('INIT_TIMEOUT') ?? config.DEFAULT_INIT_TIMEOUT, 59 | session: envInt('SESSION_TIMEOUT') ?? config.DEFAULT_SESSION_TIMEOUT, 60 | }, 61 | concurrency: envInt('MAX_CONCURRENCY') ?? config.DEFAULT_MAX_CONCURRENCY, 62 | pool: tasksHandler.poolLength(), 63 | queue: tasksHandler.queueLength(), 64 | counter: { 65 | total: tasksHandler.getCounterTotal(), 66 | ...tasksHandler.getCounter() 67 | } 68 | }, 69 | server: { 70 | uptime: Math.round(OS.uptime()), 71 | platform: OS.platform(), 72 | arch: OS.arch(), 73 | cores: OS.cpus().length, 74 | ram: { 75 | total: bytesToMegabytes(OS.totalmem()), 76 | free: bytesToMegabytes(freeMem), 77 | used: bytesToMegabytes(OS.totalmem() - freeMem), 78 | } 79 | } 80 | }); 81 | }); 82 | 83 | webServer.get('/logs', (request, response) => { 84 | response.json(Logger.getRows()); 85 | }) 86 | 87 | webServer.get('/restart', async (request, response) => { 88 | await tasksHandler.close(); 89 | response.json('restarting...'); 90 | tasksHandler.onDisconnected(); 91 | } 92 | ) 93 | 94 | webServer.post(`/task`, async (request, response) => { 95 | if (typeof request.body.script === 'string' 96 | && (typeof request.body.options === 'undefined' || typeof request.body.options === 'object') 97 | && (typeof request.body.profile === 'undefined' || typeof request.body.profile === 'object') 98 | ) { 99 | const callback = (task: Task) => { 100 | response 101 | .status(200) 102 | .json({ 103 | status: task.status, 104 | timings: task.timings, 105 | options: task.options ?? {}, 106 | profile: task.profile ?? {}, 107 | output: task.output ?? null, 108 | error: ((task.error instanceof Error) ? task.error.name + ': ' + task.error.message + '\n' + findEvalDetailsFromError(task.error) : null) 109 | ?? task.error?.toString() 110 | ?? null 111 | }); 112 | }; 113 | 114 | const task = new Task( 115 | request.body.script, 116 | request.body.options ?? {}, 117 | request.body.profile ?? {}, 118 | callback 119 | ); 120 | 121 | if (tasksHandler.getIsRunning()) { 122 | tasksHandler.push(task); 123 | } 124 | else { 125 | task.fulfill(TaskStatus.INIT_ERROR, null, 'TaskPool: Queue: Hero Core Shutdown'); 126 | } 127 | 128 | } else { 129 | tasksHandler.incrementCounterBadArgs(); 130 | response 131 | .status(500) 132 | .json({ 133 | status: TaskStatus.BAD_ARGS, 134 | timings: null, 135 | options: null, 136 | profile: null, 137 | output: null, 138 | error: 'Bad arguments' 139 | }) 140 | } 141 | }); 142 | }) 143 | .on('error',() => { 144 | console.error('Process stopped, port is busy.'); 145 | process.exit(1); 146 | }) 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luka-dev/headless-task-server/ec97bd22e7c11d86d91999611c0de253089523ca/src/plugins/.gitkeep -------------------------------------------------------------------------------- /src/types/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luka-dev/headless-task-server/ec97bd22e7c11d86d91999611c0de253089523ca/src/types/.gitkeep -------------------------------------------------------------------------------- /src/types/ITaskOptions.ts: -------------------------------------------------------------------------------- 1 | import IEmulationProfile from '@ulixee/unblocked-specification/plugin/IEmulationProfile'; 2 | import ISessionCreateOptions from '@ulixee/hero-interfaces/ISessionCreateOptions'; 3 | export default interface ITaskOptions extends 4 | Pick, 5 | Pick 6 | { 7 | 8 | } -------------------------------------------------------------------------------- /src/types/ITasksPoolHandler.ts: -------------------------------------------------------------------------------- 1 | import {BlockedResourceType} from "@ulixee/hero"; 2 | 3 | export default interface ITasksPoolHandler { 4 | DEFAULT_MAX_CONCURRENCY: number; 5 | DEFAULT_QUEUE_TIMEOUT: number; 6 | DEFAULT_INIT_TIMEOUT: number; 7 | DEFAULT_SESSION_TIMEOUT: number; 8 | DEFAULT_UPSTREAM_PROXY_URL: string | null; 9 | DEFAULT_BLOCKED_RESOURCE_TYPES: BlockedResourceType[]; 10 | } -------------------------------------------------------------------------------- /src/types/IWebServerConfig.ts: -------------------------------------------------------------------------------- 1 | export default interface IWebServerConfig { 2 | "AUTH_KEY": string|null, 3 | "SERVER_PORT": number, 4 | } 5 | -------------------------------------------------------------------------------- /tests/scenarios/ExampleTitle.js: -------------------------------------------------------------------------------- 1 | await agent.goto("https://example.com/"); 2 | resolve(await agent.document.title); -------------------------------------------------------------------------------- /tests/scenarios/FetchTest.js: -------------------------------------------------------------------------------- 1 | await agent.goto('https://developer.mozilla.org/'); 2 | await agent.waitForPaintingStable(); 3 | await agent.waitForMillis(10000); 4 | const response = await agent.fetch('https://developer.mozilla.org/api/v1/whoami', {timeout: 10000}); 5 | await agent.waitForMillis(10000); 6 | resolve(await response.json()); -------------------------------------------------------------------------------- /tests/scenarios/UnhandledRejection.js: -------------------------------------------------------------------------------- 1 | new Promise((resolve, reject) => { 2 | throw new Error('Simulated UnhandledRejection'); 3 | }); 4 | 5 | await agent.waitForMillis(10000); -------------------------------------------------------------------------------- /tests/simulation_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is used to simulate a load test on the task server 4 | # We have 2 parameters, the first one is the host, second Authorization token 5 | 6 | if [[ ! -n $1 ]]; 7 | then 8 | echo "No HOST provided" 9 | exit 1 10 | fi 11 | 12 | for i in `seq 1 40` 13 | do 14 | curl \ 15 | -X POST "$1/task" \ 16 | -H 'Content-Type: application/json' \ 17 | -H "Authorization: $2" \ 18 | -d '{"script": "await agent.goto(\"https://example.com/\"); await agent.waitForMillis(10000); resolve(await agent.document.title);"}' \ 19 | > /dev/null & 20 | done 21 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | 4 | const dirPath = __dirname + '/scenarios'; 5 | fs.readdir(dirPath, function (err, files) { 6 | //handling error 7 | if (err) { 8 | return console.log('Unable to scan directory: ' + err); 9 | } 10 | //listing all files using forEach 11 | files.forEach(function (file) { 12 | //Skip if not a js file 13 | if (!file.includes('.js')) { 14 | return; 15 | } 16 | 17 | //Ignore json files (its an options) 18 | if (file.includes('.json')) { 19 | return; 20 | } 21 | 22 | const name = file.slice(0, -3); 23 | 24 | //Read the file content 25 | const content = fs.readFileSync(path.join(dirPath, file), {encoding: 'utf8', flag: 'r'}); 26 | let options = {}; 27 | 28 | //Check if the file exists in the same directory 29 | if (fs.existsSync(path.join(dirPath, name + '.json'))) { 30 | options = JSON.parse(fs.readFileSync(path.join(dirPath, name + '.json'), {encoding: 'utf8', flag: 'r'})) 31 | } 32 | 33 | //TODO: Run the scenarios, in single thread 34 | }); 35 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./src/**/*"], 3 | "exclude": ["node_modules"], 4 | "compilerOptions": { 5 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 6 | 7 | /* Basic Options */ 8 | "incremental": true, /* Enable incremental compilation */ 9 | "target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 10 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 11 | "lib": ["ES2019", "DOM", "DOM.Iterable"], /* Specify library files to be included in the compilation. */ 12 | // "allowJs": true, /* Allow javascript files to be compiled. */ 13 | // "checkJs": true, /* Report errors in .js files. */ 14 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 15 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 16 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 17 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 18 | // "outFile": "./", /* Concatenate and emit output to single file. */ 19 | "outDir": "./dist", /* Redirect output structure to the directory. */ 20 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 21 | // "composite": true, /* Enable project compilation */ 22 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 23 | // "removeComments": true, /* Do not emit comments to output. */ 24 | // "noEmit": true, /* Do not emit outputs. */ 25 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 26 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 27 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 28 | 29 | /* Strict Type-Checking Options */ 30 | "strict": true, /* Enable all strict type-checking options. */ 31 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 32 | // "strictNullChecks": true, /* Enable strict null checks. */ 33 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 34 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 35 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 36 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 37 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 38 | 39 | /* Additional Checks */ 40 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 41 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 42 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 43 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 44 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 45 | 46 | /* Module Resolution Options */ 47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 51 | // "typeRoots": [], /* List of folders to include type definitions from. */ 52 | // "types": [], /* Type declaration files to be included in compilation. */ 53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 54 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 55 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 56 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 57 | 58 | /* Source Map Options */ 59 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 61 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 62 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 63 | 64 | /* Experimental Options */ 65 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 66 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 67 | 68 | /* Advanced Options */ 69 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 71 | } 72 | } -------------------------------------------------------------------------------- /windwos_generate_stamp.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a" 3 | set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%" 4 | set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" 5 | rem set "datestamp=%YY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" 6 | set "datestamp=%YYYY%-%MM%-%DD%" 7 | set "timestamp=%HH%:%Min%:%Sec%" 8 | set unique_number=%datestamp%T%timestamp% 9 | echo %unique_number% --------------------------------------------------------------------------------