stnh70 commited on
Commit
c235523
·
verified ·
1 Parent(s): cd7900e

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +20 -0
  2. fly.toml +23 -0
  3. package-lock.json +1803 -0
  4. package.json +20 -0
  5. server.js +317 -0
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the latest Playwright image that includes all browsers
2
+ FROM mcr.microsoft.com/playwright:v1.52.0
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy package.json and package-lock.json
8
+ COPY package*.json ./
9
+
10
+ # Install dependencies
11
+ RUN npm install
12
+
13
+ # Copy source files
14
+ COPY . .
15
+
16
+ # Expose port (match your app port)
17
+ EXPOSE 3000
18
+
19
+ # Start app
20
+ CMD ["npm", "start"]
fly.toml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # fly.toml app configuration file generated for vidsrc-scraper on 2025-06-07T18:32:30Z
2
+ #
3
+ # See https://fly.io/docs/reference/configuration/ for information about how to use this file.
4
+ #
5
+
6
+ app = 'vidsrc-scraper'
7
+ primary_region = 'jnb'
8
+
9
+ [build]
10
+
11
+ [http_service]
12
+ internal_port = 3000
13
+ force_https = true
14
+ auto_stop_machines = 'stop'
15
+ auto_start_machines = true
16
+ min_machines_running = 0
17
+ processes = ['app']
18
+
19
+ [[vm]]
20
+ memory = '1gb'
21
+ cpu_kind = 'shared'
22
+ cpus = 8
23
+ memory_mb = 2048
package-lock.json ADDED
@@ -0,0 +1,1803 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "m3u8-scraper",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "m3u8-scraper",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "cors": "^2.8.5",
13
+ "express": "^5.1.0",
14
+ "p-limit": "^6.2.0",
15
+ "playwright": "^1.52.0",
16
+ "puppeteer": "^24.10.0"
17
+ }
18
+ },
19
+ "node_modules/@babel/code-frame": {
20
+ "version": "7.27.1",
21
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
22
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
23
+ "dependencies": {
24
+ "@babel/helper-validator-identifier": "^7.27.1",
25
+ "js-tokens": "^4.0.0",
26
+ "picocolors": "^1.1.1"
27
+ },
28
+ "engines": {
29
+ "node": ">=6.9.0"
30
+ }
31
+ },
32
+ "node_modules/@babel/helper-validator-identifier": {
33
+ "version": "7.27.1",
34
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
35
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
36
+ "engines": {
37
+ "node": ">=6.9.0"
38
+ }
39
+ },
40
+ "node_modules/@puppeteer/browsers": {
41
+ "version": "2.10.5",
42
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.5.tgz",
43
+ "integrity": "sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==",
44
+ "dependencies": {
45
+ "debug": "^4.4.1",
46
+ "extract-zip": "^2.0.1",
47
+ "progress": "^2.0.3",
48
+ "proxy-agent": "^6.5.0",
49
+ "semver": "^7.7.2",
50
+ "tar-fs": "^3.0.8",
51
+ "yargs": "^17.7.2"
52
+ },
53
+ "bin": {
54
+ "browsers": "lib/cjs/main-cli.js"
55
+ },
56
+ "engines": {
57
+ "node": ">=18"
58
+ }
59
+ },
60
+ "node_modules/@tootallnate/quickjs-emscripten": {
61
+ "version": "0.23.0",
62
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
63
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
64
+ },
65
+ "node_modules/@types/node": {
66
+ "version": "22.15.30",
67
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz",
68
+ "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==",
69
+ "optional": true,
70
+ "dependencies": {
71
+ "undici-types": "~6.21.0"
72
+ }
73
+ },
74
+ "node_modules/@types/yauzl": {
75
+ "version": "2.10.3",
76
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
77
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
78
+ "optional": true,
79
+ "dependencies": {
80
+ "@types/node": "*"
81
+ }
82
+ },
83
+ "node_modules/accepts": {
84
+ "version": "2.0.0",
85
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
86
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
87
+ "dependencies": {
88
+ "mime-types": "^3.0.0",
89
+ "negotiator": "^1.0.0"
90
+ },
91
+ "engines": {
92
+ "node": ">= 0.6"
93
+ }
94
+ },
95
+ "node_modules/agent-base": {
96
+ "version": "7.1.3",
97
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
98
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
99
+ "engines": {
100
+ "node": ">= 14"
101
+ }
102
+ },
103
+ "node_modules/ansi-regex": {
104
+ "version": "5.0.1",
105
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
106
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
107
+ "engines": {
108
+ "node": ">=8"
109
+ }
110
+ },
111
+ "node_modules/ansi-styles": {
112
+ "version": "4.3.0",
113
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
114
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
115
+ "dependencies": {
116
+ "color-convert": "^2.0.1"
117
+ },
118
+ "engines": {
119
+ "node": ">=8"
120
+ },
121
+ "funding": {
122
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
123
+ }
124
+ },
125
+ "node_modules/argparse": {
126
+ "version": "2.0.1",
127
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
128
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
129
+ },
130
+ "node_modules/ast-types": {
131
+ "version": "0.13.4",
132
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
133
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
134
+ "dependencies": {
135
+ "tslib": "^2.0.1"
136
+ },
137
+ "engines": {
138
+ "node": ">=4"
139
+ }
140
+ },
141
+ "node_modules/b4a": {
142
+ "version": "1.6.7",
143
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
144
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg=="
145
+ },
146
+ "node_modules/bare-events": {
147
+ "version": "2.5.4",
148
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
149
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
150
+ "optional": true
151
+ },
152
+ "node_modules/bare-fs": {
153
+ "version": "4.1.5",
154
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz",
155
+ "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==",
156
+ "optional": true,
157
+ "dependencies": {
158
+ "bare-events": "^2.5.4",
159
+ "bare-path": "^3.0.0",
160
+ "bare-stream": "^2.6.4"
161
+ },
162
+ "engines": {
163
+ "bare": ">=1.16.0"
164
+ },
165
+ "peerDependencies": {
166
+ "bare-buffer": "*"
167
+ },
168
+ "peerDependenciesMeta": {
169
+ "bare-buffer": {
170
+ "optional": true
171
+ }
172
+ }
173
+ },
174
+ "node_modules/bare-os": {
175
+ "version": "3.6.1",
176
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
177
+ "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
178
+ "optional": true,
179
+ "engines": {
180
+ "bare": ">=1.14.0"
181
+ }
182
+ },
183
+ "node_modules/bare-path": {
184
+ "version": "3.0.0",
185
+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
186
+ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
187
+ "optional": true,
188
+ "dependencies": {
189
+ "bare-os": "^3.0.1"
190
+ }
191
+ },
192
+ "node_modules/bare-stream": {
193
+ "version": "2.6.5",
194
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
195
+ "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
196
+ "optional": true,
197
+ "dependencies": {
198
+ "streamx": "^2.21.0"
199
+ },
200
+ "peerDependencies": {
201
+ "bare-buffer": "*",
202
+ "bare-events": "*"
203
+ },
204
+ "peerDependenciesMeta": {
205
+ "bare-buffer": {
206
+ "optional": true
207
+ },
208
+ "bare-events": {
209
+ "optional": true
210
+ }
211
+ }
212
+ },
213
+ "node_modules/basic-ftp": {
214
+ "version": "5.0.5",
215
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
216
+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
217
+ "engines": {
218
+ "node": ">=10.0.0"
219
+ }
220
+ },
221
+ "node_modules/body-parser": {
222
+ "version": "2.2.0",
223
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
224
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
225
+ "dependencies": {
226
+ "bytes": "^3.1.2",
227
+ "content-type": "^1.0.5",
228
+ "debug": "^4.4.0",
229
+ "http-errors": "^2.0.0",
230
+ "iconv-lite": "^0.6.3",
231
+ "on-finished": "^2.4.1",
232
+ "qs": "^6.14.0",
233
+ "raw-body": "^3.0.0",
234
+ "type-is": "^2.0.0"
235
+ },
236
+ "engines": {
237
+ "node": ">=18"
238
+ }
239
+ },
240
+ "node_modules/buffer-crc32": {
241
+ "version": "0.2.13",
242
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
243
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
244
+ "engines": {
245
+ "node": "*"
246
+ }
247
+ },
248
+ "node_modules/bytes": {
249
+ "version": "3.1.2",
250
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
251
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
252
+ "engines": {
253
+ "node": ">= 0.8"
254
+ }
255
+ },
256
+ "node_modules/call-bind-apply-helpers": {
257
+ "version": "1.0.2",
258
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
259
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
260
+ "dependencies": {
261
+ "es-errors": "^1.3.0",
262
+ "function-bind": "^1.1.2"
263
+ },
264
+ "engines": {
265
+ "node": ">= 0.4"
266
+ }
267
+ },
268
+ "node_modules/call-bound": {
269
+ "version": "1.0.4",
270
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
271
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
272
+ "dependencies": {
273
+ "call-bind-apply-helpers": "^1.0.2",
274
+ "get-intrinsic": "^1.3.0"
275
+ },
276
+ "engines": {
277
+ "node": ">= 0.4"
278
+ },
279
+ "funding": {
280
+ "url": "https://github.com/sponsors/ljharb"
281
+ }
282
+ },
283
+ "node_modules/callsites": {
284
+ "version": "3.1.0",
285
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
286
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
287
+ "engines": {
288
+ "node": ">=6"
289
+ }
290
+ },
291
+ "node_modules/chromium-bidi": {
292
+ "version": "5.1.0",
293
+ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-5.1.0.tgz",
294
+ "integrity": "sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==",
295
+ "dependencies": {
296
+ "mitt": "^3.0.1",
297
+ "zod": "^3.24.1"
298
+ },
299
+ "peerDependencies": {
300
+ "devtools-protocol": "*"
301
+ }
302
+ },
303
+ "node_modules/cliui": {
304
+ "version": "8.0.1",
305
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
306
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
307
+ "dependencies": {
308
+ "string-width": "^4.2.0",
309
+ "strip-ansi": "^6.0.1",
310
+ "wrap-ansi": "^7.0.0"
311
+ },
312
+ "engines": {
313
+ "node": ">=12"
314
+ }
315
+ },
316
+ "node_modules/color-convert": {
317
+ "version": "2.0.1",
318
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
319
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
320
+ "dependencies": {
321
+ "color-name": "~1.1.4"
322
+ },
323
+ "engines": {
324
+ "node": ">=7.0.0"
325
+ }
326
+ },
327
+ "node_modules/color-name": {
328
+ "version": "1.1.4",
329
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
330
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
331
+ },
332
+ "node_modules/content-disposition": {
333
+ "version": "1.0.0",
334
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
335
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
336
+ "dependencies": {
337
+ "safe-buffer": "5.2.1"
338
+ },
339
+ "engines": {
340
+ "node": ">= 0.6"
341
+ }
342
+ },
343
+ "node_modules/content-type": {
344
+ "version": "1.0.5",
345
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
346
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
347
+ "engines": {
348
+ "node": ">= 0.6"
349
+ }
350
+ },
351
+ "node_modules/cookie": {
352
+ "version": "0.7.2",
353
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
354
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
355
+ "engines": {
356
+ "node": ">= 0.6"
357
+ }
358
+ },
359
+ "node_modules/cookie-signature": {
360
+ "version": "1.2.2",
361
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
362
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
363
+ "engines": {
364
+ "node": ">=6.6.0"
365
+ }
366
+ },
367
+ "node_modules/cors": {
368
+ "version": "2.8.5",
369
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
370
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
371
+ "dependencies": {
372
+ "object-assign": "^4",
373
+ "vary": "^1"
374
+ },
375
+ "engines": {
376
+ "node": ">= 0.10"
377
+ }
378
+ },
379
+ "node_modules/cosmiconfig": {
380
+ "version": "9.0.0",
381
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
382
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
383
+ "dependencies": {
384
+ "env-paths": "^2.2.1",
385
+ "import-fresh": "^3.3.0",
386
+ "js-yaml": "^4.1.0",
387
+ "parse-json": "^5.2.0"
388
+ },
389
+ "engines": {
390
+ "node": ">=14"
391
+ },
392
+ "funding": {
393
+ "url": "https://github.com/sponsors/d-fischer"
394
+ },
395
+ "peerDependencies": {
396
+ "typescript": ">=4.9.5"
397
+ },
398
+ "peerDependenciesMeta": {
399
+ "typescript": {
400
+ "optional": true
401
+ }
402
+ }
403
+ },
404
+ "node_modules/data-uri-to-buffer": {
405
+ "version": "6.0.2",
406
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
407
+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
408
+ "engines": {
409
+ "node": ">= 14"
410
+ }
411
+ },
412
+ "node_modules/debug": {
413
+ "version": "4.4.1",
414
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
415
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
416
+ "dependencies": {
417
+ "ms": "^2.1.3"
418
+ },
419
+ "engines": {
420
+ "node": ">=6.0"
421
+ },
422
+ "peerDependenciesMeta": {
423
+ "supports-color": {
424
+ "optional": true
425
+ }
426
+ }
427
+ },
428
+ "node_modules/degenerator": {
429
+ "version": "5.0.1",
430
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
431
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
432
+ "dependencies": {
433
+ "ast-types": "^0.13.4",
434
+ "escodegen": "^2.1.0",
435
+ "esprima": "^4.0.1"
436
+ },
437
+ "engines": {
438
+ "node": ">= 14"
439
+ }
440
+ },
441
+ "node_modules/depd": {
442
+ "version": "2.0.0",
443
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
444
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
445
+ "engines": {
446
+ "node": ">= 0.8"
447
+ }
448
+ },
449
+ "node_modules/devtools-protocol": {
450
+ "version": "0.0.1452169",
451
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1452169.tgz",
452
+ "integrity": "sha512-FOFDVMGrAUNp0dDKsAU1TorWJUx2JOU1k9xdgBKKJF3IBh/Uhl2yswG5r3TEAOrCiGY2QRp1e6LVDQrCsTKO4g=="
453
+ },
454
+ "node_modules/dunder-proto": {
455
+ "version": "1.0.1",
456
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
457
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
458
+ "dependencies": {
459
+ "call-bind-apply-helpers": "^1.0.1",
460
+ "es-errors": "^1.3.0",
461
+ "gopd": "^1.2.0"
462
+ },
463
+ "engines": {
464
+ "node": ">= 0.4"
465
+ }
466
+ },
467
+ "node_modules/ee-first": {
468
+ "version": "1.1.1",
469
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
470
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
471
+ },
472
+ "node_modules/emoji-regex": {
473
+ "version": "8.0.0",
474
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
475
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
476
+ },
477
+ "node_modules/encodeurl": {
478
+ "version": "2.0.0",
479
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
480
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
481
+ "engines": {
482
+ "node": ">= 0.8"
483
+ }
484
+ },
485
+ "node_modules/end-of-stream": {
486
+ "version": "1.4.4",
487
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
488
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
489
+ "dependencies": {
490
+ "once": "^1.4.0"
491
+ }
492
+ },
493
+ "node_modules/env-paths": {
494
+ "version": "2.2.1",
495
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
496
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
497
+ "engines": {
498
+ "node": ">=6"
499
+ }
500
+ },
501
+ "node_modules/error-ex": {
502
+ "version": "1.3.2",
503
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
504
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
505
+ "dependencies": {
506
+ "is-arrayish": "^0.2.1"
507
+ }
508
+ },
509
+ "node_modules/es-define-property": {
510
+ "version": "1.0.1",
511
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
512
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
513
+ "engines": {
514
+ "node": ">= 0.4"
515
+ }
516
+ },
517
+ "node_modules/es-errors": {
518
+ "version": "1.3.0",
519
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
520
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
521
+ "engines": {
522
+ "node": ">= 0.4"
523
+ }
524
+ },
525
+ "node_modules/es-object-atoms": {
526
+ "version": "1.1.1",
527
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
528
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
529
+ "dependencies": {
530
+ "es-errors": "^1.3.0"
531
+ },
532
+ "engines": {
533
+ "node": ">= 0.4"
534
+ }
535
+ },
536
+ "node_modules/escalade": {
537
+ "version": "3.2.0",
538
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
539
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
540
+ "engines": {
541
+ "node": ">=6"
542
+ }
543
+ },
544
+ "node_modules/escape-html": {
545
+ "version": "1.0.3",
546
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
547
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
548
+ },
549
+ "node_modules/escodegen": {
550
+ "version": "2.1.0",
551
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
552
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
553
+ "dependencies": {
554
+ "esprima": "^4.0.1",
555
+ "estraverse": "^5.2.0",
556
+ "esutils": "^2.0.2"
557
+ },
558
+ "bin": {
559
+ "escodegen": "bin/escodegen.js",
560
+ "esgenerate": "bin/esgenerate.js"
561
+ },
562
+ "engines": {
563
+ "node": ">=6.0"
564
+ },
565
+ "optionalDependencies": {
566
+ "source-map": "~0.6.1"
567
+ }
568
+ },
569
+ "node_modules/esprima": {
570
+ "version": "4.0.1",
571
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
572
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
573
+ "bin": {
574
+ "esparse": "bin/esparse.js",
575
+ "esvalidate": "bin/esvalidate.js"
576
+ },
577
+ "engines": {
578
+ "node": ">=4"
579
+ }
580
+ },
581
+ "node_modules/estraverse": {
582
+ "version": "5.3.0",
583
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
584
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
585
+ "engines": {
586
+ "node": ">=4.0"
587
+ }
588
+ },
589
+ "node_modules/esutils": {
590
+ "version": "2.0.3",
591
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
592
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
593
+ "engines": {
594
+ "node": ">=0.10.0"
595
+ }
596
+ },
597
+ "node_modules/etag": {
598
+ "version": "1.8.1",
599
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
600
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
601
+ "engines": {
602
+ "node": ">= 0.6"
603
+ }
604
+ },
605
+ "node_modules/express": {
606
+ "version": "5.1.0",
607
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
608
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
609
+ "dependencies": {
610
+ "accepts": "^2.0.0",
611
+ "body-parser": "^2.2.0",
612
+ "content-disposition": "^1.0.0",
613
+ "content-type": "^1.0.5",
614
+ "cookie": "^0.7.1",
615
+ "cookie-signature": "^1.2.1",
616
+ "debug": "^4.4.0",
617
+ "encodeurl": "^2.0.0",
618
+ "escape-html": "^1.0.3",
619
+ "etag": "^1.8.1",
620
+ "finalhandler": "^2.1.0",
621
+ "fresh": "^2.0.0",
622
+ "http-errors": "^2.0.0",
623
+ "merge-descriptors": "^2.0.0",
624
+ "mime-types": "^3.0.0",
625
+ "on-finished": "^2.4.1",
626
+ "once": "^1.4.0",
627
+ "parseurl": "^1.3.3",
628
+ "proxy-addr": "^2.0.7",
629
+ "qs": "^6.14.0",
630
+ "range-parser": "^1.2.1",
631
+ "router": "^2.2.0",
632
+ "send": "^1.1.0",
633
+ "serve-static": "^2.2.0",
634
+ "statuses": "^2.0.1",
635
+ "type-is": "^2.0.1",
636
+ "vary": "^1.1.2"
637
+ },
638
+ "engines": {
639
+ "node": ">= 18"
640
+ },
641
+ "funding": {
642
+ "type": "opencollective",
643
+ "url": "https://opencollective.com/express"
644
+ }
645
+ },
646
+ "node_modules/extract-zip": {
647
+ "version": "2.0.1",
648
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
649
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
650
+ "dependencies": {
651
+ "debug": "^4.1.1",
652
+ "get-stream": "^5.1.0",
653
+ "yauzl": "^2.10.0"
654
+ },
655
+ "bin": {
656
+ "extract-zip": "cli.js"
657
+ },
658
+ "engines": {
659
+ "node": ">= 10.17.0"
660
+ },
661
+ "optionalDependencies": {
662
+ "@types/yauzl": "^2.9.1"
663
+ }
664
+ },
665
+ "node_modules/fast-fifo": {
666
+ "version": "1.3.2",
667
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
668
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
669
+ },
670
+ "node_modules/fd-slicer": {
671
+ "version": "1.1.0",
672
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
673
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
674
+ "dependencies": {
675
+ "pend": "~1.2.0"
676
+ }
677
+ },
678
+ "node_modules/finalhandler": {
679
+ "version": "2.1.0",
680
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
681
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
682
+ "dependencies": {
683
+ "debug": "^4.4.0",
684
+ "encodeurl": "^2.0.0",
685
+ "escape-html": "^1.0.3",
686
+ "on-finished": "^2.4.1",
687
+ "parseurl": "^1.3.3",
688
+ "statuses": "^2.0.1"
689
+ },
690
+ "engines": {
691
+ "node": ">= 0.8"
692
+ }
693
+ },
694
+ "node_modules/forwarded": {
695
+ "version": "0.2.0",
696
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
697
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
698
+ "engines": {
699
+ "node": ">= 0.6"
700
+ }
701
+ },
702
+ "node_modules/fresh": {
703
+ "version": "2.0.0",
704
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
705
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
706
+ "engines": {
707
+ "node": ">= 0.8"
708
+ }
709
+ },
710
+ "node_modules/fsevents": {
711
+ "version": "2.3.2",
712
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
713
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
714
+ "hasInstallScript": true,
715
+ "optional": true,
716
+ "os": [
717
+ "darwin"
718
+ ],
719
+ "engines": {
720
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
721
+ }
722
+ },
723
+ "node_modules/function-bind": {
724
+ "version": "1.1.2",
725
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
726
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
727
+ "funding": {
728
+ "url": "https://github.com/sponsors/ljharb"
729
+ }
730
+ },
731
+ "node_modules/get-caller-file": {
732
+ "version": "2.0.5",
733
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
734
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
735
+ "engines": {
736
+ "node": "6.* || 8.* || >= 10.*"
737
+ }
738
+ },
739
+ "node_modules/get-intrinsic": {
740
+ "version": "1.3.0",
741
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
742
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
743
+ "dependencies": {
744
+ "call-bind-apply-helpers": "^1.0.2",
745
+ "es-define-property": "^1.0.1",
746
+ "es-errors": "^1.3.0",
747
+ "es-object-atoms": "^1.1.1",
748
+ "function-bind": "^1.1.2",
749
+ "get-proto": "^1.0.1",
750
+ "gopd": "^1.2.0",
751
+ "has-symbols": "^1.1.0",
752
+ "hasown": "^2.0.2",
753
+ "math-intrinsics": "^1.1.0"
754
+ },
755
+ "engines": {
756
+ "node": ">= 0.4"
757
+ },
758
+ "funding": {
759
+ "url": "https://github.com/sponsors/ljharb"
760
+ }
761
+ },
762
+ "node_modules/get-proto": {
763
+ "version": "1.0.1",
764
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
765
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
766
+ "dependencies": {
767
+ "dunder-proto": "^1.0.1",
768
+ "es-object-atoms": "^1.0.0"
769
+ },
770
+ "engines": {
771
+ "node": ">= 0.4"
772
+ }
773
+ },
774
+ "node_modules/get-stream": {
775
+ "version": "5.2.0",
776
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
777
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
778
+ "dependencies": {
779
+ "pump": "^3.0.0"
780
+ },
781
+ "engines": {
782
+ "node": ">=8"
783
+ },
784
+ "funding": {
785
+ "url": "https://github.com/sponsors/sindresorhus"
786
+ }
787
+ },
788
+ "node_modules/get-uri": {
789
+ "version": "6.0.4",
790
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
791
+ "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
792
+ "dependencies": {
793
+ "basic-ftp": "^5.0.2",
794
+ "data-uri-to-buffer": "^6.0.2",
795
+ "debug": "^4.3.4"
796
+ },
797
+ "engines": {
798
+ "node": ">= 14"
799
+ }
800
+ },
801
+ "node_modules/gopd": {
802
+ "version": "1.2.0",
803
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
804
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
805
+ "engines": {
806
+ "node": ">= 0.4"
807
+ },
808
+ "funding": {
809
+ "url": "https://github.com/sponsors/ljharb"
810
+ }
811
+ },
812
+ "node_modules/has-symbols": {
813
+ "version": "1.1.0",
814
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
815
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
816
+ "engines": {
817
+ "node": ">= 0.4"
818
+ },
819
+ "funding": {
820
+ "url": "https://github.com/sponsors/ljharb"
821
+ }
822
+ },
823
+ "node_modules/hasown": {
824
+ "version": "2.0.2",
825
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
826
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
827
+ "dependencies": {
828
+ "function-bind": "^1.1.2"
829
+ },
830
+ "engines": {
831
+ "node": ">= 0.4"
832
+ }
833
+ },
834
+ "node_modules/http-errors": {
835
+ "version": "2.0.0",
836
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
837
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
838
+ "dependencies": {
839
+ "depd": "2.0.0",
840
+ "inherits": "2.0.4",
841
+ "setprototypeof": "1.2.0",
842
+ "statuses": "2.0.1",
843
+ "toidentifier": "1.0.1"
844
+ },
845
+ "engines": {
846
+ "node": ">= 0.8"
847
+ }
848
+ },
849
+ "node_modules/http-errors/node_modules/statuses": {
850
+ "version": "2.0.1",
851
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
852
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
853
+ "engines": {
854
+ "node": ">= 0.8"
855
+ }
856
+ },
857
+ "node_modules/http-proxy-agent": {
858
+ "version": "7.0.2",
859
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
860
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
861
+ "dependencies": {
862
+ "agent-base": "^7.1.0",
863
+ "debug": "^4.3.4"
864
+ },
865
+ "engines": {
866
+ "node": ">= 14"
867
+ }
868
+ },
869
+ "node_modules/https-proxy-agent": {
870
+ "version": "7.0.6",
871
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
872
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
873
+ "dependencies": {
874
+ "agent-base": "^7.1.2",
875
+ "debug": "4"
876
+ },
877
+ "engines": {
878
+ "node": ">= 14"
879
+ }
880
+ },
881
+ "node_modules/iconv-lite": {
882
+ "version": "0.6.3",
883
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
884
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
885
+ "dependencies": {
886
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
887
+ },
888
+ "engines": {
889
+ "node": ">=0.10.0"
890
+ }
891
+ },
892
+ "node_modules/import-fresh": {
893
+ "version": "3.3.1",
894
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
895
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
896
+ "dependencies": {
897
+ "parent-module": "^1.0.0",
898
+ "resolve-from": "^4.0.0"
899
+ },
900
+ "engines": {
901
+ "node": ">=6"
902
+ },
903
+ "funding": {
904
+ "url": "https://github.com/sponsors/sindresorhus"
905
+ }
906
+ },
907
+ "node_modules/inherits": {
908
+ "version": "2.0.4",
909
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
910
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
911
+ },
912
+ "node_modules/ip-address": {
913
+ "version": "9.0.5",
914
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
915
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
916
+ "dependencies": {
917
+ "jsbn": "1.1.0",
918
+ "sprintf-js": "^1.1.3"
919
+ },
920
+ "engines": {
921
+ "node": ">= 12"
922
+ }
923
+ },
924
+ "node_modules/ipaddr.js": {
925
+ "version": "1.9.1",
926
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
927
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
928
+ "engines": {
929
+ "node": ">= 0.10"
930
+ }
931
+ },
932
+ "node_modules/is-arrayish": {
933
+ "version": "0.2.1",
934
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
935
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
936
+ },
937
+ "node_modules/is-fullwidth-code-point": {
938
+ "version": "3.0.0",
939
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
940
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
941
+ "engines": {
942
+ "node": ">=8"
943
+ }
944
+ },
945
+ "node_modules/is-promise": {
946
+ "version": "4.0.0",
947
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
948
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
949
+ },
950
+ "node_modules/js-tokens": {
951
+ "version": "4.0.0",
952
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
953
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
954
+ },
955
+ "node_modules/js-yaml": {
956
+ "version": "4.1.0",
957
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
958
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
959
+ "dependencies": {
960
+ "argparse": "^2.0.1"
961
+ },
962
+ "bin": {
963
+ "js-yaml": "bin/js-yaml.js"
964
+ }
965
+ },
966
+ "node_modules/jsbn": {
967
+ "version": "1.1.0",
968
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
969
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
970
+ },
971
+ "node_modules/json-parse-even-better-errors": {
972
+ "version": "2.3.1",
973
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
974
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
975
+ },
976
+ "node_modules/lines-and-columns": {
977
+ "version": "1.2.4",
978
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
979
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
980
+ },
981
+ "node_modules/lru-cache": {
982
+ "version": "7.18.3",
983
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
984
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
985
+ "engines": {
986
+ "node": ">=12"
987
+ }
988
+ },
989
+ "node_modules/math-intrinsics": {
990
+ "version": "1.1.0",
991
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
992
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
993
+ "engines": {
994
+ "node": ">= 0.4"
995
+ }
996
+ },
997
+ "node_modules/media-typer": {
998
+ "version": "1.1.0",
999
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
1000
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
1001
+ "engines": {
1002
+ "node": ">= 0.8"
1003
+ }
1004
+ },
1005
+ "node_modules/merge-descriptors": {
1006
+ "version": "2.0.0",
1007
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
1008
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
1009
+ "engines": {
1010
+ "node": ">=18"
1011
+ },
1012
+ "funding": {
1013
+ "url": "https://github.com/sponsors/sindresorhus"
1014
+ }
1015
+ },
1016
+ "node_modules/mime-db": {
1017
+ "version": "1.54.0",
1018
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
1019
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
1020
+ "engines": {
1021
+ "node": ">= 0.6"
1022
+ }
1023
+ },
1024
+ "node_modules/mime-types": {
1025
+ "version": "3.0.1",
1026
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
1027
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
1028
+ "dependencies": {
1029
+ "mime-db": "^1.54.0"
1030
+ },
1031
+ "engines": {
1032
+ "node": ">= 0.6"
1033
+ }
1034
+ },
1035
+ "node_modules/mitt": {
1036
+ "version": "3.0.1",
1037
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
1038
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
1039
+ },
1040
+ "node_modules/ms": {
1041
+ "version": "2.1.3",
1042
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1043
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1044
+ },
1045
+ "node_modules/negotiator": {
1046
+ "version": "1.0.0",
1047
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
1048
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
1049
+ "engines": {
1050
+ "node": ">= 0.6"
1051
+ }
1052
+ },
1053
+ "node_modules/netmask": {
1054
+ "version": "2.0.2",
1055
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
1056
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
1057
+ "engines": {
1058
+ "node": ">= 0.4.0"
1059
+ }
1060
+ },
1061
+ "node_modules/object-assign": {
1062
+ "version": "4.1.1",
1063
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1064
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1065
+ "engines": {
1066
+ "node": ">=0.10.0"
1067
+ }
1068
+ },
1069
+ "node_modules/object-inspect": {
1070
+ "version": "1.13.4",
1071
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
1072
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
1073
+ "engines": {
1074
+ "node": ">= 0.4"
1075
+ },
1076
+ "funding": {
1077
+ "url": "https://github.com/sponsors/ljharb"
1078
+ }
1079
+ },
1080
+ "node_modules/on-finished": {
1081
+ "version": "2.4.1",
1082
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1083
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1084
+ "dependencies": {
1085
+ "ee-first": "1.1.1"
1086
+ },
1087
+ "engines": {
1088
+ "node": ">= 0.8"
1089
+ }
1090
+ },
1091
+ "node_modules/once": {
1092
+ "version": "1.4.0",
1093
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1094
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1095
+ "dependencies": {
1096
+ "wrappy": "1"
1097
+ }
1098
+ },
1099
+ "node_modules/p-limit": {
1100
+ "version": "6.2.0",
1101
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz",
1102
+ "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==",
1103
+ "dependencies": {
1104
+ "yocto-queue": "^1.1.1"
1105
+ },
1106
+ "engines": {
1107
+ "node": ">=18"
1108
+ },
1109
+ "funding": {
1110
+ "url": "https://github.com/sponsors/sindresorhus"
1111
+ }
1112
+ },
1113
+ "node_modules/pac-proxy-agent": {
1114
+ "version": "7.2.0",
1115
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz",
1116
+ "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",
1117
+ "dependencies": {
1118
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
1119
+ "agent-base": "^7.1.2",
1120
+ "debug": "^4.3.4",
1121
+ "get-uri": "^6.0.1",
1122
+ "http-proxy-agent": "^7.0.0",
1123
+ "https-proxy-agent": "^7.0.6",
1124
+ "pac-resolver": "^7.0.1",
1125
+ "socks-proxy-agent": "^8.0.5"
1126
+ },
1127
+ "engines": {
1128
+ "node": ">= 14"
1129
+ }
1130
+ },
1131
+ "node_modules/pac-resolver": {
1132
+ "version": "7.0.1",
1133
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
1134
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
1135
+ "dependencies": {
1136
+ "degenerator": "^5.0.0",
1137
+ "netmask": "^2.0.2"
1138
+ },
1139
+ "engines": {
1140
+ "node": ">= 14"
1141
+ }
1142
+ },
1143
+ "node_modules/parent-module": {
1144
+ "version": "1.0.1",
1145
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1146
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1147
+ "dependencies": {
1148
+ "callsites": "^3.0.0"
1149
+ },
1150
+ "engines": {
1151
+ "node": ">=6"
1152
+ }
1153
+ },
1154
+ "node_modules/parse-json": {
1155
+ "version": "5.2.0",
1156
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
1157
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
1158
+ "dependencies": {
1159
+ "@babel/code-frame": "^7.0.0",
1160
+ "error-ex": "^1.3.1",
1161
+ "json-parse-even-better-errors": "^2.3.0",
1162
+ "lines-and-columns": "^1.1.6"
1163
+ },
1164
+ "engines": {
1165
+ "node": ">=8"
1166
+ },
1167
+ "funding": {
1168
+ "url": "https://github.com/sponsors/sindresorhus"
1169
+ }
1170
+ },
1171
+ "node_modules/parseurl": {
1172
+ "version": "1.3.3",
1173
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1174
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1175
+ "engines": {
1176
+ "node": ">= 0.8"
1177
+ }
1178
+ },
1179
+ "node_modules/path-to-regexp": {
1180
+ "version": "8.2.0",
1181
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
1182
+ "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
1183
+ "engines": {
1184
+ "node": ">=16"
1185
+ }
1186
+ },
1187
+ "node_modules/pend": {
1188
+ "version": "1.2.0",
1189
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
1190
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
1191
+ },
1192
+ "node_modules/picocolors": {
1193
+ "version": "1.1.1",
1194
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1195
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
1196
+ },
1197
+ "node_modules/playwright": {
1198
+ "version": "1.52.0",
1199
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
1200
+ "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
1201
+ "dependencies": {
1202
+ "playwright-core": "1.52.0"
1203
+ },
1204
+ "bin": {
1205
+ "playwright": "cli.js"
1206
+ },
1207
+ "engines": {
1208
+ "node": ">=18"
1209
+ },
1210
+ "optionalDependencies": {
1211
+ "fsevents": "2.3.2"
1212
+ }
1213
+ },
1214
+ "node_modules/playwright-core": {
1215
+ "version": "1.52.0",
1216
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
1217
+ "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
1218
+ "bin": {
1219
+ "playwright-core": "cli.js"
1220
+ },
1221
+ "engines": {
1222
+ "node": ">=18"
1223
+ }
1224
+ },
1225
+ "node_modules/progress": {
1226
+ "version": "2.0.3",
1227
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
1228
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
1229
+ "engines": {
1230
+ "node": ">=0.4.0"
1231
+ }
1232
+ },
1233
+ "node_modules/proxy-addr": {
1234
+ "version": "2.0.7",
1235
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1236
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1237
+ "dependencies": {
1238
+ "forwarded": "0.2.0",
1239
+ "ipaddr.js": "1.9.1"
1240
+ },
1241
+ "engines": {
1242
+ "node": ">= 0.10"
1243
+ }
1244
+ },
1245
+ "node_modules/proxy-agent": {
1246
+ "version": "6.5.0",
1247
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
1248
+ "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
1249
+ "dependencies": {
1250
+ "agent-base": "^7.1.2",
1251
+ "debug": "^4.3.4",
1252
+ "http-proxy-agent": "^7.0.1",
1253
+ "https-proxy-agent": "^7.0.6",
1254
+ "lru-cache": "^7.14.1",
1255
+ "pac-proxy-agent": "^7.1.0",
1256
+ "proxy-from-env": "^1.1.0",
1257
+ "socks-proxy-agent": "^8.0.5"
1258
+ },
1259
+ "engines": {
1260
+ "node": ">= 14"
1261
+ }
1262
+ },
1263
+ "node_modules/proxy-from-env": {
1264
+ "version": "1.1.0",
1265
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
1266
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
1267
+ },
1268
+ "node_modules/pump": {
1269
+ "version": "3.0.2",
1270
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
1271
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
1272
+ "dependencies": {
1273
+ "end-of-stream": "^1.1.0",
1274
+ "once": "^1.3.1"
1275
+ }
1276
+ },
1277
+ "node_modules/puppeteer": {
1278
+ "version": "24.10.0",
1279
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.10.0.tgz",
1280
+ "integrity": "sha512-Oua9VkGpj0S2psYu5e6mCer6W9AU9POEQh22wRgSXnLXASGH+MwLUVWgLCLeP9QPHHcJ7tySUlg4Sa9OJmaLpw==",
1281
+ "hasInstallScript": true,
1282
+ "dependencies": {
1283
+ "@puppeteer/browsers": "2.10.5",
1284
+ "chromium-bidi": "5.1.0",
1285
+ "cosmiconfig": "^9.0.0",
1286
+ "devtools-protocol": "0.0.1452169",
1287
+ "puppeteer-core": "24.10.0",
1288
+ "typed-query-selector": "^2.12.0"
1289
+ },
1290
+ "bin": {
1291
+ "puppeteer": "lib/cjs/puppeteer/node/cli.js"
1292
+ },
1293
+ "engines": {
1294
+ "node": ">=18"
1295
+ }
1296
+ },
1297
+ "node_modules/puppeteer-core": {
1298
+ "version": "24.10.0",
1299
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.10.0.tgz",
1300
+ "integrity": "sha512-xX0QJRc8t19iAwRDsAOR38Q/Zx/W6WVzJCEhKCAwp2XMsaWqfNtQ+rBfQW9PlF+Op24d7c8Zlgq9YNmbnA7hdQ==",
1301
+ "dependencies": {
1302
+ "@puppeteer/browsers": "2.10.5",
1303
+ "chromium-bidi": "5.1.0",
1304
+ "debug": "^4.4.1",
1305
+ "devtools-protocol": "0.0.1452169",
1306
+ "typed-query-selector": "^2.12.0",
1307
+ "ws": "^8.18.2"
1308
+ },
1309
+ "engines": {
1310
+ "node": ">=18"
1311
+ }
1312
+ },
1313
+ "node_modules/qs": {
1314
+ "version": "6.14.0",
1315
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
1316
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
1317
+ "dependencies": {
1318
+ "side-channel": "^1.1.0"
1319
+ },
1320
+ "engines": {
1321
+ "node": ">=0.6"
1322
+ },
1323
+ "funding": {
1324
+ "url": "https://github.com/sponsors/ljharb"
1325
+ }
1326
+ },
1327
+ "node_modules/range-parser": {
1328
+ "version": "1.2.1",
1329
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1330
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1331
+ "engines": {
1332
+ "node": ">= 0.6"
1333
+ }
1334
+ },
1335
+ "node_modules/raw-body": {
1336
+ "version": "3.0.0",
1337
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
1338
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
1339
+ "dependencies": {
1340
+ "bytes": "3.1.2",
1341
+ "http-errors": "2.0.0",
1342
+ "iconv-lite": "0.6.3",
1343
+ "unpipe": "1.0.0"
1344
+ },
1345
+ "engines": {
1346
+ "node": ">= 0.8"
1347
+ }
1348
+ },
1349
+ "node_modules/require-directory": {
1350
+ "version": "2.1.1",
1351
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1352
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1353
+ "engines": {
1354
+ "node": ">=0.10.0"
1355
+ }
1356
+ },
1357
+ "node_modules/resolve-from": {
1358
+ "version": "4.0.0",
1359
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
1360
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
1361
+ "engines": {
1362
+ "node": ">=4"
1363
+ }
1364
+ },
1365
+ "node_modules/router": {
1366
+ "version": "2.2.0",
1367
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
1368
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
1369
+ "dependencies": {
1370
+ "debug": "^4.4.0",
1371
+ "depd": "^2.0.0",
1372
+ "is-promise": "^4.0.0",
1373
+ "parseurl": "^1.3.3",
1374
+ "path-to-regexp": "^8.0.0"
1375
+ },
1376
+ "engines": {
1377
+ "node": ">= 18"
1378
+ }
1379
+ },
1380
+ "node_modules/safe-buffer": {
1381
+ "version": "5.2.1",
1382
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1383
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1384
+ "funding": [
1385
+ {
1386
+ "type": "github",
1387
+ "url": "https://github.com/sponsors/feross"
1388
+ },
1389
+ {
1390
+ "type": "patreon",
1391
+ "url": "https://www.patreon.com/feross"
1392
+ },
1393
+ {
1394
+ "type": "consulting",
1395
+ "url": "https://feross.org/support"
1396
+ }
1397
+ ]
1398
+ },
1399
+ "node_modules/safer-buffer": {
1400
+ "version": "2.1.2",
1401
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1402
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1403
+ },
1404
+ "node_modules/semver": {
1405
+ "version": "7.7.2",
1406
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
1407
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
1408
+ "bin": {
1409
+ "semver": "bin/semver.js"
1410
+ },
1411
+ "engines": {
1412
+ "node": ">=10"
1413
+ }
1414
+ },
1415
+ "node_modules/send": {
1416
+ "version": "1.2.0",
1417
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
1418
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
1419
+ "dependencies": {
1420
+ "debug": "^4.3.5",
1421
+ "encodeurl": "^2.0.0",
1422
+ "escape-html": "^1.0.3",
1423
+ "etag": "^1.8.1",
1424
+ "fresh": "^2.0.0",
1425
+ "http-errors": "^2.0.0",
1426
+ "mime-types": "^3.0.1",
1427
+ "ms": "^2.1.3",
1428
+ "on-finished": "^2.4.1",
1429
+ "range-parser": "^1.2.1",
1430
+ "statuses": "^2.0.1"
1431
+ },
1432
+ "engines": {
1433
+ "node": ">= 18"
1434
+ }
1435
+ },
1436
+ "node_modules/serve-static": {
1437
+ "version": "2.2.0",
1438
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
1439
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
1440
+ "dependencies": {
1441
+ "encodeurl": "^2.0.0",
1442
+ "escape-html": "^1.0.3",
1443
+ "parseurl": "^1.3.3",
1444
+ "send": "^1.2.0"
1445
+ },
1446
+ "engines": {
1447
+ "node": ">= 18"
1448
+ }
1449
+ },
1450
+ "node_modules/setprototypeof": {
1451
+ "version": "1.2.0",
1452
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1453
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1454
+ },
1455
+ "node_modules/side-channel": {
1456
+ "version": "1.1.0",
1457
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
1458
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
1459
+ "dependencies": {
1460
+ "es-errors": "^1.3.0",
1461
+ "object-inspect": "^1.13.3",
1462
+ "side-channel-list": "^1.0.0",
1463
+ "side-channel-map": "^1.0.1",
1464
+ "side-channel-weakmap": "^1.0.2"
1465
+ },
1466
+ "engines": {
1467
+ "node": ">= 0.4"
1468
+ },
1469
+ "funding": {
1470
+ "url": "https://github.com/sponsors/ljharb"
1471
+ }
1472
+ },
1473
+ "node_modules/side-channel-list": {
1474
+ "version": "1.0.0",
1475
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
1476
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
1477
+ "dependencies": {
1478
+ "es-errors": "^1.3.0",
1479
+ "object-inspect": "^1.13.3"
1480
+ },
1481
+ "engines": {
1482
+ "node": ">= 0.4"
1483
+ },
1484
+ "funding": {
1485
+ "url": "https://github.com/sponsors/ljharb"
1486
+ }
1487
+ },
1488
+ "node_modules/side-channel-map": {
1489
+ "version": "1.0.1",
1490
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
1491
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
1492
+ "dependencies": {
1493
+ "call-bound": "^1.0.2",
1494
+ "es-errors": "^1.3.0",
1495
+ "get-intrinsic": "^1.2.5",
1496
+ "object-inspect": "^1.13.3"
1497
+ },
1498
+ "engines": {
1499
+ "node": ">= 0.4"
1500
+ },
1501
+ "funding": {
1502
+ "url": "https://github.com/sponsors/ljharb"
1503
+ }
1504
+ },
1505
+ "node_modules/side-channel-weakmap": {
1506
+ "version": "1.0.2",
1507
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
1508
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
1509
+ "dependencies": {
1510
+ "call-bound": "^1.0.2",
1511
+ "es-errors": "^1.3.0",
1512
+ "get-intrinsic": "^1.2.5",
1513
+ "object-inspect": "^1.13.3",
1514
+ "side-channel-map": "^1.0.1"
1515
+ },
1516
+ "engines": {
1517
+ "node": ">= 0.4"
1518
+ },
1519
+ "funding": {
1520
+ "url": "https://github.com/sponsors/ljharb"
1521
+ }
1522
+ },
1523
+ "node_modules/smart-buffer": {
1524
+ "version": "4.2.0",
1525
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
1526
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
1527
+ "engines": {
1528
+ "node": ">= 6.0.0",
1529
+ "npm": ">= 3.0.0"
1530
+ }
1531
+ },
1532
+ "node_modules/socks": {
1533
+ "version": "2.8.4",
1534
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
1535
+ "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
1536
+ "dependencies": {
1537
+ "ip-address": "^9.0.5",
1538
+ "smart-buffer": "^4.2.0"
1539
+ },
1540
+ "engines": {
1541
+ "node": ">= 10.0.0",
1542
+ "npm": ">= 3.0.0"
1543
+ }
1544
+ },
1545
+ "node_modules/socks-proxy-agent": {
1546
+ "version": "8.0.5",
1547
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
1548
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
1549
+ "dependencies": {
1550
+ "agent-base": "^7.1.2",
1551
+ "debug": "^4.3.4",
1552
+ "socks": "^2.8.3"
1553
+ },
1554
+ "engines": {
1555
+ "node": ">= 14"
1556
+ }
1557
+ },
1558
+ "node_modules/source-map": {
1559
+ "version": "0.6.1",
1560
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1561
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1562
+ "optional": true,
1563
+ "engines": {
1564
+ "node": ">=0.10.0"
1565
+ }
1566
+ },
1567
+ "node_modules/sprintf-js": {
1568
+ "version": "1.1.3",
1569
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
1570
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
1571
+ },
1572
+ "node_modules/statuses": {
1573
+ "version": "2.0.2",
1574
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
1575
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
1576
+ "engines": {
1577
+ "node": ">= 0.8"
1578
+ }
1579
+ },
1580
+ "node_modules/streamx": {
1581
+ "version": "2.22.1",
1582
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz",
1583
+ "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==",
1584
+ "dependencies": {
1585
+ "fast-fifo": "^1.3.2",
1586
+ "text-decoder": "^1.1.0"
1587
+ },
1588
+ "optionalDependencies": {
1589
+ "bare-events": "^2.2.0"
1590
+ }
1591
+ },
1592
+ "node_modules/string-width": {
1593
+ "version": "4.2.3",
1594
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1595
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1596
+ "dependencies": {
1597
+ "emoji-regex": "^8.0.0",
1598
+ "is-fullwidth-code-point": "^3.0.0",
1599
+ "strip-ansi": "^6.0.1"
1600
+ },
1601
+ "engines": {
1602
+ "node": ">=8"
1603
+ }
1604
+ },
1605
+ "node_modules/strip-ansi": {
1606
+ "version": "6.0.1",
1607
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1608
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1609
+ "dependencies": {
1610
+ "ansi-regex": "^5.0.1"
1611
+ },
1612
+ "engines": {
1613
+ "node": ">=8"
1614
+ }
1615
+ },
1616
+ "node_modules/tar-fs": {
1617
+ "version": "3.0.9",
1618
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz",
1619
+ "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==",
1620
+ "dependencies": {
1621
+ "pump": "^3.0.0",
1622
+ "tar-stream": "^3.1.5"
1623
+ },
1624
+ "optionalDependencies": {
1625
+ "bare-fs": "^4.0.1",
1626
+ "bare-path": "^3.0.0"
1627
+ }
1628
+ },
1629
+ "node_modules/tar-stream": {
1630
+ "version": "3.1.7",
1631
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
1632
+ "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
1633
+ "dependencies": {
1634
+ "b4a": "^1.6.4",
1635
+ "fast-fifo": "^1.2.0",
1636
+ "streamx": "^2.15.0"
1637
+ }
1638
+ },
1639
+ "node_modules/text-decoder": {
1640
+ "version": "1.2.3",
1641
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
1642
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
1643
+ "dependencies": {
1644
+ "b4a": "^1.6.4"
1645
+ }
1646
+ },
1647
+ "node_modules/toidentifier": {
1648
+ "version": "1.0.1",
1649
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1650
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1651
+ "engines": {
1652
+ "node": ">=0.6"
1653
+ }
1654
+ },
1655
+ "node_modules/tslib": {
1656
+ "version": "2.8.1",
1657
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1658
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
1659
+ },
1660
+ "node_modules/type-is": {
1661
+ "version": "2.0.1",
1662
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1663
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1664
+ "dependencies": {
1665
+ "content-type": "^1.0.5",
1666
+ "media-typer": "^1.1.0",
1667
+ "mime-types": "^3.0.0"
1668
+ },
1669
+ "engines": {
1670
+ "node": ">= 0.6"
1671
+ }
1672
+ },
1673
+ "node_modules/typed-query-selector": {
1674
+ "version": "2.12.0",
1675
+ "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
1676
+ "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg=="
1677
+ },
1678
+ "node_modules/undici-types": {
1679
+ "version": "6.21.0",
1680
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
1681
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
1682
+ "optional": true
1683
+ },
1684
+ "node_modules/unpipe": {
1685
+ "version": "1.0.0",
1686
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1687
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1688
+ "engines": {
1689
+ "node": ">= 0.8"
1690
+ }
1691
+ },
1692
+ "node_modules/vary": {
1693
+ "version": "1.1.2",
1694
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1695
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1696
+ "engines": {
1697
+ "node": ">= 0.8"
1698
+ }
1699
+ },
1700
+ "node_modules/wrap-ansi": {
1701
+ "version": "7.0.0",
1702
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1703
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1704
+ "dependencies": {
1705
+ "ansi-styles": "^4.0.0",
1706
+ "string-width": "^4.1.0",
1707
+ "strip-ansi": "^6.0.0"
1708
+ },
1709
+ "engines": {
1710
+ "node": ">=10"
1711
+ },
1712
+ "funding": {
1713
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1714
+ }
1715
+ },
1716
+ "node_modules/wrappy": {
1717
+ "version": "1.0.2",
1718
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1719
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1720
+ },
1721
+ "node_modules/ws": {
1722
+ "version": "8.18.2",
1723
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
1724
+ "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
1725
+ "engines": {
1726
+ "node": ">=10.0.0"
1727
+ },
1728
+ "peerDependencies": {
1729
+ "bufferutil": "^4.0.1",
1730
+ "utf-8-validate": ">=5.0.2"
1731
+ },
1732
+ "peerDependenciesMeta": {
1733
+ "bufferutil": {
1734
+ "optional": true
1735
+ },
1736
+ "utf-8-validate": {
1737
+ "optional": true
1738
+ }
1739
+ }
1740
+ },
1741
+ "node_modules/y18n": {
1742
+ "version": "5.0.8",
1743
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1744
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1745
+ "engines": {
1746
+ "node": ">=10"
1747
+ }
1748
+ },
1749
+ "node_modules/yargs": {
1750
+ "version": "17.7.2",
1751
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
1752
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
1753
+ "dependencies": {
1754
+ "cliui": "^8.0.1",
1755
+ "escalade": "^3.1.1",
1756
+ "get-caller-file": "^2.0.5",
1757
+ "require-directory": "^2.1.1",
1758
+ "string-width": "^4.2.3",
1759
+ "y18n": "^5.0.5",
1760
+ "yargs-parser": "^21.1.1"
1761
+ },
1762
+ "engines": {
1763
+ "node": ">=12"
1764
+ }
1765
+ },
1766
+ "node_modules/yargs-parser": {
1767
+ "version": "21.1.1",
1768
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
1769
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
1770
+ "engines": {
1771
+ "node": ">=12"
1772
+ }
1773
+ },
1774
+ "node_modules/yauzl": {
1775
+ "version": "2.10.0",
1776
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
1777
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
1778
+ "dependencies": {
1779
+ "buffer-crc32": "~0.2.3",
1780
+ "fd-slicer": "~1.1.0"
1781
+ }
1782
+ },
1783
+ "node_modules/yocto-queue": {
1784
+ "version": "1.2.1",
1785
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
1786
+ "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
1787
+ "engines": {
1788
+ "node": ">=12.20"
1789
+ },
1790
+ "funding": {
1791
+ "url": "https://github.com/sponsors/sindresorhus"
1792
+ }
1793
+ },
1794
+ "node_modules/zod": {
1795
+ "version": "3.25.56",
1796
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.56.tgz",
1797
+ "integrity": "sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==",
1798
+ "funding": {
1799
+ "url": "https://github.com/sponsors/colinhacks"
1800
+ }
1801
+ }
1802
+ }
1803
+ }
package.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "m3u8-scraper",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "node server.js"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "cors": "^2.8.5",
14
+ "express": "^5.1.0",
15
+ "p-limit": "^6.2.0",
16
+ "playwright": "^1.52.0",
17
+ "puppeteer": "^24.10.0"
18
+ },
19
+ "type": "module"
20
+ }
server.js ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express, { json } from "express";
2
+ import cors from "cors";
3
+ import { chromium } from "playwright";
4
+ import pLimit from "p-limit";
5
+ import BrowserPool from './pool/BrowserPool.js';
6
+ import LRU from 'lru-cache';
7
+
8
+ const app = express();
9
+ const PORT = process.env.PORT || 3000;
10
+
11
+ app.use(cors());
12
+ app.use(json());
13
+
14
+ const PROVIDERS = [
15
+ "https://vidsrc.xyz",
16
+ "https://vidsrc.in",
17
+ "https://vidsrc.pm",
18
+ "https://vidsrc.net",
19
+ "https://vidsrc.io",
20
+ "https://vidsrc.vc",
21
+ ];
22
+
23
+
24
+ let browserPool;
25
+
26
+ const cache = new LRU({
27
+ max: 500,
28
+ ttl: 15 * 60 * 1000,
29
+ });
30
+
31
+ const limit = pLimit(2);
32
+
33
+ // [MODIFIED] scrapeProvider now accepts an AbortSignal to enable cancellation
34
+ async function scrapeProvider(domain, url, signal) {
35
+ // 初始检查
36
+ if (signal.aborted) {
37
+ throw new Error('Scraping aborted before starting.');
38
+ }
39
+
40
+ console.log(`\n[${domain}] Starting scrape for URL: ${url}`);
41
+
42
+ let hlsUrl = null;
43
+ const subtitles = [];
44
+ let browserInstance = null;
45
+ let context = null;
46
+ let page = null;
47
+
48
+ const cleanup = async () => {
49
+ if (page && !page.isClosed()) {
50
+ page.removeAllListeners();
51
+ await page.close().catch(() => {});
52
+ }
53
+ if (context) {
54
+ await context.close().catch(() => {});
55
+ }
56
+ if (browserInstance) {
57
+ console.log(`${url} Releasing browser ${browserInstance.id} back to pool.`);
58
+ await browserPool.release(browserInstance);
59
+ }
60
+ };
61
+
62
+ try {
63
+ // 检查是否已取消
64
+ if (signal.aborted) {
65
+ throw new Error('Scraping aborted.');
66
+ }
67
+
68
+ browserInstance = await browserPool.get();
69
+ const browser = browserInstance.browser;
70
+ console.log(`${url} Acquired browser ${browserInstance.id}`);
71
+
72
+ // 再次检查
73
+ if (signal.aborted) {
74
+ throw new Error('Scraping aborted.');
75
+ }
76
+
77
+ context = await browser.newContext({
78
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
79
+ ignoreHTTPSErrors: true
80
+ });
81
+
82
+ page = await context.newPage();
83
+
84
+ // 设置网络拦截
85
+ await page.route("**/*", (route) => {
86
+ // 在网络拦截中也检查 abort 状态
87
+ if (signal.aborted) {
88
+ route.abort();
89
+ return;
90
+ }
91
+
92
+ const reqUrl = route.request().url();
93
+ if (!hlsUrl && reqUrl.includes(".m3u8")) {
94
+ hlsUrl = reqUrl;
95
+ console.log(`[${domain}] Found HLS URL: ${hlsUrl}`);
96
+ }
97
+ if (reqUrl.endsWith(".vtt") || reqUrl.endsWith(".srt") || reqUrl.includes(".vtt") || reqUrl.includes(".srt")) {
98
+ if (!subtitles.some(s => s.url === reqUrl)) {
99
+ subtitles.push(reqUrl);
100
+ console.log(`[${domain}] Found subtitle URL: ${reqUrl}`);
101
+ }
102
+ }
103
+ route.continue();
104
+ });
105
+
106
+ // 改进 frame 监听
107
+ page.on("frameattached", (frame) => {
108
+ const frameUrl = frame.url() || "about:blank";
109
+ console.log(`[${domain}] Frame attached: ${frameUrl}`);
110
+
111
+ // 监听 frame 加载完成
112
+ // frame.on("load", () => {
113
+ // if (frame.url() !== "about:blank") {
114
+ // console.log(`[${domain}] Frame loaded: ${frame.url()}`);
115
+ // }
116
+ // });
117
+ });
118
+
119
+ // 检查后再导航
120
+ if (signal.aborted) {
121
+ throw new Error('Scraping aborted.');
122
+ }
123
+
124
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 20000, signal });
125
+ console.log(`[${domain}] Page loaded`);
126
+
127
+ // 检查后再查找元素
128
+ if (signal.aborted) {
129
+ throw new Error('Scraping aborted.');
130
+ }
131
+
132
+ const frameDiv = await page.waitForSelector("#the_frame", {
133
+ timeout: 10000,
134
+ signal,
135
+ });
136
+
137
+ if (frameDiv) {
138
+ // 检查后再点击
139
+ if (signal.aborted) {
140
+ throw new Error('Scraping aborted.');
141
+ }
142
+
143
+ const box = await frameDiv.boundingBox();
144
+ if (box) {
145
+ const clickX = box.x + box.width / 2;
146
+ const clickY = box.y + box.height / 2;
147
+ console.log(`[${domain}] Clicking at (${clickX.toFixed(1)}, ${clickY.toFixed(1)})`);
148
+ await page.mouse.move(clickX, clickY);
149
+ await page.mouse.click(clickX, clickY);
150
+ } else {
151
+ console.warn(`[${domain}] Fallback: clicking via JS`);
152
+ await page.evaluate(() => {
153
+ document.querySelector("#the_frame")?.click();
154
+ });
155
+ }
156
+
157
+ // 检查后再等待响应
158
+ if (signal.aborted) {
159
+ throw new Error('Scraping aborted.');
160
+ }
161
+
162
+ if (!hlsUrl) {
163
+ await page
164
+ .waitForResponse((resp) => resp.url().includes(".m3u8"), {
165
+ timeout: 5000,
166
+ signal,
167
+ })
168
+ .catch((error) => {
169
+ if (signal.aborted || error.name === 'AbortError') {
170
+ console.warn(`[${domain}] .m3u8 wait was aborted.`);
171
+ throw new Error('Scraping aborted.');
172
+ } else {
173
+ console.warn(`[${domain}] .m3u8 request not detected within 5s`);
174
+ }
175
+ });
176
+ }
177
+ } else {
178
+ throw new Error(`#the_frame div not found`);
179
+ }
180
+
181
+ // 最终检查
182
+ if (signal.aborted) {
183
+ throw new Error('Scraping aborted.');
184
+ }
185
+
186
+ if (!hlsUrl) {
187
+ throw new Error("HLS URL not found");
188
+ }
189
+
190
+ return { source_domain: domain, hls_url: hlsUrl, subtitles, error: null };
191
+
192
+ } catch (error) {
193
+ if (error.name === 'AbortError' || error.message.includes('aborted') || (signal && signal.aborted)) {
194
+ console.log(`[${domain}] Scraping was aborted.`);
195
+ throw error;
196
+ }
197
+ console.error(`[${domain}] Error in scrapeProvider: ${error.message}`);
198
+ throw error;
199
+ } finally {
200
+ await cleanup();
201
+ }
202
+ }
203
+
204
+ // [MODIFIED] /extract route now uses Promise.any and AbortController
205
+ app.get("/extract", async (req, res) => {
206
+ const type = req.query.type || "movie";
207
+ const tmdb_id = req.query.tmdb_id;
208
+ const season = req.query.season ? parseInt(req.query.season) : undefined;
209
+ const episode = req.query.episode ? parseInt(req.query.episode) : undefined;
210
+
211
+ if (!tmdb_id) {
212
+ return res.status(400).json({
213
+ success: false,
214
+ error: "tmdb_id query param is required",
215
+ });
216
+ }
217
+
218
+ if (type === "tv" && (season == null || episode == null)) {
219
+ return res.status(400).json({
220
+ success: false,
221
+ error: "season and episode query params are required for TV shows",
222
+ });
223
+ }
224
+
225
+ const cacheKey = JSON.stringify(req.query);
226
+ const cached = cache.get(cacheKey);
227
+
228
+ if (cached) {
229
+ console.log("Serving from cache");
230
+ return res.json(cached);
231
+ }
232
+
233
+ const urls = PROVIDERS.reduce((acc, domain) => {
234
+ acc[domain] =
235
+ type === "tv"
236
+ ? `${domain}/embed/tv?tmdb=${tmdb_id}&season=${season}&episode=${episode}`
237
+ : `${domain}/embed/movie/${tmdb_id}`;
238
+ return acc;
239
+ }, {});
240
+
241
+ // Create an AbortController to signal cancellation to other tasks.
242
+ const controller = new AbortController();
243
+ const signal = controller.signal;
244
+
245
+ try {
246
+ const promises = Object.entries(urls).map(([domain, url]) =>
247
+ limit(() => {
248
+ // Pass the signal to each scrapeProvider task.
249
+ return scrapeProvider(domain, url, signal);
250
+ })
251
+ );
252
+
253
+ // Promise.any waits for the first promise to be fulfilled (resolve).
254
+ const firstSuccessfulResult = await Promise.any(promises);
255
+
256
+ // As soon as we have a winner, abort all other ongoing scrape tasks.
257
+ console.log(`\nSuccess from [${firstSuccessfulResult.source_domain}]. Aborting other scrapers.`);
258
+ controller.abort();
259
+
260
+ // The response structure is simplified to show the single successful result.
261
+ const response = {
262
+ success: true,
263
+ result: firstSuccessfulResult
264
+ };
265
+
266
+ cache.set(cacheKey, response);
267
+ res.json(response);
268
+
269
+ } catch (err) {
270
+ // This block is reached if ALL promises are rejected.
271
+ if (err instanceof AggregateError) {
272
+ console.error("All providers failed to find a link.");
273
+ res.status(404).json({
274
+ success: false,
275
+ error: "Could not find the video from any provider.",
276
+ });
277
+ } else {
278
+ // Handle other unexpected errors.
279
+ console.error("An unexpected server error occurred:", err);
280
+ res.status(500).json({
281
+ success: false,
282
+ error: "Unexpected server error",
283
+ });
284
+ }
285
+ }
286
+ });
287
+
288
+ // The startup and shutdown logic remains unchanged as it is already well-structured.
289
+ (async () => {
290
+ try {
291
+ browserPool = new BrowserPool({
292
+ chromium: chromium,
293
+ minSize: 1,
294
+ maxSize: 5,
295
+ maxUsage: 100,
296
+ });
297
+ await browserPool.initialize();
298
+
299
+ console.log("Browser pool initialized successfully.");
300
+
301
+ app.listen(PORT, () => console.log(`🚀 Universal Video Extractor running at http://localhost:${PORT}`));
302
+ } catch (error) {
303
+ console.error("Failed to initialize browser pool:", error);
304
+ process.exit(1);
305
+ }
306
+ })();
307
+
308
+ process.on("SIGINT", async () => {
309
+ console.log("Shutting down gracefully...");
310
+ if (browserPool) await browserPool.shutdown();
311
+ process.exit(0);
312
+ });
313
+ process.on("SIGTERM", async () => {
314
+ console.log("Shutting down gracefully...");
315
+ if (browserPool) await browserPool.shutdown();
316
+ process.exit(0);
317
+ });