@yefengr/pi-reach 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +62 -48
  2. package/dist/files/content-type.d.ts +16 -0
  3. package/dist/files/content-type.js +98 -0
  4. package/dist/files/content-type.js.map +1 -0
  5. package/dist/files/image-structure.d.ts +21 -0
  6. package/dist/files/image-structure.js +269 -0
  7. package/dist/files/image-structure.js.map +1 -0
  8. package/dist/files/publications.d.ts +26 -0
  9. package/dist/files/publications.js +136 -0
  10. package/dist/files/publications.js.map +1 -0
  11. package/dist/files/publish-tool.d.ts +23 -0
  12. package/dist/files/publish-tool.js +70 -0
  13. package/dist/files/publish-tool.js.map +1 -0
  14. package/dist/files/reader.d.ts +66 -0
  15. package/dist/files/reader.js +416 -0
  16. package/dist/files/reader.js.map +1 -0
  17. package/dist/files/safe-open.d.ts +22 -0
  18. package/dist/files/safe-open.js +119 -0
  19. package/dist/files/safe-open.js.map +1 -0
  20. package/dist/index.js +12 -17
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtime/file_binding.d.ts +25 -0
  23. package/dist/runtime/file_binding.js +49 -0
  24. package/dist/runtime/file_binding.js.map +1 -0
  25. package/dist/runtime/session_frame_router.d.ts +11 -0
  26. package/dist/runtime/session_frame_router.js +25 -0
  27. package/dist/runtime/session_frame_router.js.map +1 -0
  28. package/dist/timeline/runtime.d.ts +1 -1
  29. package/dist/timeline/runtime.js +26 -54
  30. package/dist/timeline/runtime.js.map +1 -1
  31. package/dist/timeline/system_event.d.ts +7 -0
  32. package/dist/timeline/system_event.js +58 -0
  33. package/dist/timeline/system_event.js.map +1 -0
  34. package/dist/timeline/tool_lifecycle.js +8 -2
  35. package/dist/timeline/tool_lifecycle.js.map +1 -1
  36. package/dist/timeline/v2_service.js +3 -0
  37. package/dist/timeline/v2_service.js.map +1 -1
  38. package/dist/vendor/protocol/session/files.d.ts +83 -0
  39. package/dist/vendor/protocol/session/files.js +162 -0
  40. package/dist/vendor/protocol/session/frames.d.ts +293 -18
  41. package/dist/vendor/protocol/session/frames.js +52 -2
  42. package/dist/vendor/protocol/session/index.d.ts +1 -0
  43. package/dist/vendor/protocol/session/index.js +1 -0
  44. package/dist/vendor/protocol/session/schema.d.ts +2 -2
  45. package/dist/vendor/protocol/session/schema.js +2 -0
  46. package/package.json +5 -4
@@ -0,0 +1,416 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { lstat, realpath } from "node:fs/promises";
3
+ import { basename, dirname, parse } from "node:path";
4
+ import { FILE_CHUNK_BYTES, FILE_MAX_BYTES } from "../vendor/protocol/session/index.js";
5
+ import { inspectFile } from "./content-type.js";
6
+ import { FileAccessError, openSourceFile } from "./safe-open.js";
7
+ const DEFAULT_IDLE_MS = 30_000;
8
+ const DEFAULT_MAX_RESOURCES = 8;
9
+ // reload 后仍持有的资源继续占额;共享账本只存租约,不复用实例回调或 scope。
10
+ const RESOURCE_LEDGER = Symbol.for("pi-reach:file-reader:resource-leases");
11
+ const processState = globalThis;
12
+ const processLeases = processState[RESOURCE_LEDGER] ??= new Set();
13
+ function sameFile(a, b) {
14
+ return a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.size === b.size
15
+ && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs;
16
+ }
17
+ function errorCode(error) {
18
+ return error instanceof FileAccessError ? error.code : "io_error";
19
+ }
20
+ function scopeKey(scope) {
21
+ return JSON.stringify([scope.ownerId, scope.channelId, scope.runtimeId, scope.sessionId, scope.generation]);
22
+ }
23
+ /** 所有异步任务共享额度;失效不等于内核 I/O 已停止或句柄已关闭。 */
24
+ export class FileReaderRuntime {
25
+ options;
26
+ resources = new Set();
27
+ opens = new Map();
28
+ idleMs;
29
+ maxResources;
30
+ timer;
31
+ timerDeadline;
32
+ disposed = false;
33
+ constructor(options) {
34
+ this.options = options;
35
+ this.idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
36
+ this.maxResources = options.maxResources ?? DEFAULT_MAX_RESOURCES;
37
+ if (!Number.isFinite(this.idleMs) || this.idleMs <= 0 || !Number.isInteger(this.maxResources)
38
+ || this.maxResources < 1 || this.maxResources > DEFAULT_MAX_RESOURCES)
39
+ throw new Error("invalid reader limits");
40
+ }
41
+ get resourceCount() { return this.resources.size; }
42
+ reserve(scope, key, publicationId) {
43
+ if (this.disposed)
44
+ throw new FileAccessError("not_available");
45
+ if (this.resources.size >= this.maxResources || processLeases.size >= DEFAULT_MAX_RESOURCES)
46
+ throw new ReaderError("busy");
47
+ let reject;
48
+ const cancelled = new Promise((_, failure) => { reject = failure; });
49
+ // 没有请求等待的 idle 取消也不能制造 unhandled rejection。
50
+ void cancelled.catch(() => undefined);
51
+ const resource = {
52
+ scope: scope && { ...scope }, key, publicationId, transferId: randomUUID(), lease: Symbol(), hash: createHash("sha256"),
53
+ offset: 0, invalid: false, active: true, lastUsed: Date.now(), cancelled,
54
+ cancel: (code) => reject(new ReaderError(code)),
55
+ };
56
+ processLeases.add(resource.lease);
57
+ this.resources.add(resource);
58
+ if (key)
59
+ this.opens.set(key, resource);
60
+ this.schedule();
61
+ return resource;
62
+ }
63
+ schedule() {
64
+ const deadline = this.resources.size ? Math.min(...[...this.resources].map((resource) => resource.invalid
65
+ ? resource.retryAt : resource.lastUsed + this.idleMs)) : undefined;
66
+ if (this.timer && this.timerDeadline === deadline)
67
+ return;
68
+ if (this.timer)
69
+ clearTimeout(this.timer);
70
+ this.timer = undefined;
71
+ this.timerDeadline = deadline;
72
+ if (deadline === undefined)
73
+ return;
74
+ this.timer = setTimeout(() => {
75
+ this.timer = undefined;
76
+ this.timerDeadline = undefined;
77
+ const now = Date.now();
78
+ for (const resource of this.resources) {
79
+ if (resource.invalid ? resource.retryAt <= now : resource.lastUsed + this.idleMs <= now) {
80
+ this.invalidate(resource);
81
+ // 失效且底层 I/O 未结束或关闭失败时,不能按已过期 idle deadline 忙循环。
82
+ resource.retryAt = now + this.idleMs;
83
+ if (!resource.active)
84
+ void this.cleanup(resource);
85
+ }
86
+ }
87
+ this.schedule();
88
+ }, Math.max(1, deadline - Date.now()));
89
+ this.timer.unref?.();
90
+ }
91
+ invalidate(resource, code = "invalid_transfer") {
92
+ resource.invalid = true;
93
+ resource.retryAt ??= Date.now() + this.idleMs;
94
+ resource.cancel(code);
95
+ }
96
+ assertCurrent(resource) {
97
+ if (resource.invalid || this.disposed || (resource.scope && !this.options.isCurrent(resource.scope))) {
98
+ throw new ReaderError("invalid_transfer");
99
+ }
100
+ }
101
+ async eligible(resource) {
102
+ this.assertCurrent(resource);
103
+ if (!resource.scope || !resource.publicationId)
104
+ return;
105
+ const publication = await this.options.resolve(resource.scope, resource.publicationId);
106
+ this.assertCurrent(resource);
107
+ if (!publication)
108
+ throw new FileAccessError("not_available");
109
+ if (resource.path && publication.sourcePath !== resource.path)
110
+ throw new FileAccessError("file_changed");
111
+ if (!resource.path)
112
+ resource.path = publication.sourcePath;
113
+ }
114
+ async checked(resource, operation, policy = "publication") {
115
+ if (policy === "publication")
116
+ await this.eligible(resource);
117
+ this.assertCurrent(resource);
118
+ const result = await operation();
119
+ this.assertCurrent(resource);
120
+ if (policy === "publication")
121
+ await this.eligible(resource);
122
+ return result;
123
+ }
124
+ release(resource) {
125
+ if (resource.active || resource.handle || resource.closing)
126
+ return;
127
+ if (this.resources.delete(resource))
128
+ processLeases.delete(resource.lease);
129
+ if (resource.key && this.opens.get(resource.key) === resource)
130
+ this.opens.delete(resource.key);
131
+ this.schedule();
132
+ }
133
+ async closeHandle(resource) {
134
+ if (resource.closing)
135
+ return resource.closing;
136
+ if (!resource.handle)
137
+ return;
138
+ const handle = resource.handle;
139
+ resource.closing = handle.close().then(() => { resource.handle = undefined; });
140
+ try {
141
+ await resource.closing;
142
+ resource.closeFailed = false;
143
+ }
144
+ catch (error) {
145
+ resource.closeFailed = true;
146
+ resource.retryAt = Date.now() + this.idleMs;
147
+ if (resource.invalid)
148
+ this.schedule();
149
+ throw error;
150
+ }
151
+ finally {
152
+ resource.closing = undefined;
153
+ }
154
+ }
155
+ async cleanup(resource) {
156
+ try {
157
+ await this.closeHandle(resource);
158
+ }
159
+ catch { /* 保留真实句柄和额度,下次取消/idle/dispose 重试。 */ }
160
+ this.release(resource);
161
+ this.schedule();
162
+ }
163
+ async finish(resource) {
164
+ resource.active = false;
165
+ resource.lastUsed = Date.now();
166
+ if (resource.invalid && !resource.closeFailed)
167
+ await this.cleanup(resource);
168
+ else
169
+ this.release(resource);
170
+ this.schedule();
171
+ }
172
+ reply(frame, scope) {
173
+ return { protocol_version: 2, target_channel_id: scope.channelId, session_id: scope.sessionId, in_reply_to: frame.id };
174
+ }
175
+ failure(frame, scope, error) {
176
+ const code = error instanceof ReaderError ? error.code : errorCode(error);
177
+ return { ...this.reply(frame, scope), type: "file_error", code,
178
+ ...("transfer_id" in frame ? { transfer_id: frame.transfer_id } : {}) };
179
+ }
180
+ async handle(frame, suppliedScope) {
181
+ const scope = { ...suppliedScope };
182
+ try {
183
+ if (this.disposed || !this.options.isCurrent(scope))
184
+ throw new ReaderError("invalid_transfer");
185
+ if (frame.type === "file_open")
186
+ return await this.open(frame, scope);
187
+ const resource = [...this.resources].find((item) => item.transferId === frame.transfer_id
188
+ && item.scope && scopeKey(item.scope) === scopeKey(scope));
189
+ if (!resource)
190
+ throw new ReaderError("invalid_transfer");
191
+ if (frame.type === "file_close") {
192
+ this.invalidate(resource);
193
+ if (resource.active)
194
+ throw new ReaderError("busy");
195
+ await this.closeHandle(resource);
196
+ this.release(resource);
197
+ if (this.disposed || !this.options.isCurrent(scope))
198
+ throw new ReaderError("invalid_transfer");
199
+ return { ...this.reply(frame, scope), type: "file_closed", transfer_id: frame.transfer_id };
200
+ }
201
+ this.assertCurrent(resource);
202
+ if (resource.active)
203
+ throw new ReaderError("busy");
204
+ if (frame.offset !== resource.offset)
205
+ throw new ReaderError("offset_mismatch");
206
+ resource.active = true;
207
+ resource.lastUsed = Date.now();
208
+ this.schedule();
209
+ const response = await Promise.race([this.readTask(resource, frame, scope), resource.cancelled]);
210
+ if (response.type !== "file_error")
211
+ this.assertCurrent(resource);
212
+ return response;
213
+ }
214
+ catch (error) {
215
+ return this.failure(frame, scope, error);
216
+ }
217
+ }
218
+ async open(frame, scope) {
219
+ const key = `${scopeKey(scope)}:${JSON.stringify(frame.id)}`;
220
+ const existing = this.opens.get(key);
221
+ if (existing) {
222
+ if (existing.publicationId !== frame.publication_id)
223
+ throw new ReaderError("invalid_transfer");
224
+ this.assertCurrent(existing);
225
+ const replay = async () => {
226
+ await this.eligible(existing);
227
+ return existing.opened ?? await existing.pending;
228
+ };
229
+ return this.openResponse(existing, replay());
230
+ }
231
+ const resource = this.reserve(scope, key, frame.publication_id);
232
+ resource.pending = this.openTask(resource, frame, scope);
233
+ return this.openResponse(resource, resource.pending);
234
+ }
235
+ async openResponse(resource, pending) {
236
+ try {
237
+ const response = await Promise.race([pending, resource.cancelled]);
238
+ if (response.type !== "file_error") {
239
+ await Promise.race([this.eligible(resource), resource.cancelled]);
240
+ this.assertCurrent(resource);
241
+ }
242
+ resource.lastUsed = Date.now();
243
+ this.schedule();
244
+ return response;
245
+ }
246
+ catch (error) {
247
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
248
+ if (!resource.active && !resource.closeFailed)
249
+ void this.cleanup(resource);
250
+ throw error;
251
+ }
252
+ }
253
+ async openTask(resource, frame, scope) {
254
+ try {
255
+ await this.eligible(resource);
256
+ this.assertCurrent(resource);
257
+ const opened = await openSourceFile(resource.path, { resolveLinks: false, maxBytes: FILE_MAX_BYTES });
258
+ // 迟到句柄必须先入账,再检查失效,不能由 Promise.race 丢失所有权。
259
+ resource.handle = opened.handle;
260
+ resource.stat = opened.stat;
261
+ this.assertCurrent(resource);
262
+ await this.eligible(resource);
263
+ const fileName = basename(opened.path);
264
+ if (!fileName || fileName.length > 255 || /\p{Cc}/u.test(fileName))
265
+ throw new FileAccessError("not_available");
266
+ const inspection = await this.checked(resource, () => inspectFile(opened.handle, Number(opened.stat.size), fileName));
267
+ await this.verify(resource);
268
+ this.assertCurrent(resource);
269
+ resource.opened = { ...this.reply(frame, scope), type: "file_opened", publication_id: frame.publication_id,
270
+ transfer_id: resource.transferId, file_name: fileName, byte_length: Number(opened.stat.size),
271
+ mime_type: inspection.mimeType, preview: inspection.preview };
272
+ return resource.opened;
273
+ }
274
+ catch (error) {
275
+ if (error instanceof FileAccessError && error.handle) {
276
+ resource.handle = error.handle;
277
+ resource.closeFailed = true;
278
+ }
279
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
280
+ return this.failure(frame, scope, error);
281
+ }
282
+ finally {
283
+ await this.finish(resource);
284
+ }
285
+ }
286
+ async verify(resource, policy = "publication") {
287
+ const current = await this.checked(resource, () => resource.handle.stat({ bigint: true }), policy);
288
+ if (!sameFile(resource.stat, current))
289
+ throw new FileAccessError("file_changed");
290
+ // 对父路径逐层拒绝后来引入的链接;同一句柄属性检查不能替代路径身份检查。
291
+ let parent = dirname(resource.path);
292
+ const root = parse(parent).root;
293
+ while (true) {
294
+ const stat = await this.checked(resource, () => lstat(parent, { bigint: true }), policy);
295
+ if (!stat.isDirectory() || stat.isSymbolicLink())
296
+ throw new FileAccessError("file_changed");
297
+ if (parent === root)
298
+ break;
299
+ parent = dirname(parent);
300
+ }
301
+ try {
302
+ const atPath = await this.checked(resource, () => lstat(resource.path, { bigint: true }), policy);
303
+ if (atPath.isSymbolicLink() || !sameFile(resource.stat, atPath))
304
+ throw new FileAccessError("file_changed");
305
+ const canonical = await this.checked(resource, () => realpath(resource.path), policy);
306
+ if (canonical !== resource.path)
307
+ throw new FileAccessError("file_changed");
308
+ }
309
+ catch (error) {
310
+ if (typeof error === "object" && error !== null && "code" in error && ["ENOENT", "ENOTDIR", "ELOOP"].includes(String(error.code))) {
311
+ throw new FileAccessError("file_changed");
312
+ }
313
+ throw error;
314
+ }
315
+ }
316
+ async readTask(resource, frame, scope) {
317
+ try {
318
+ // 分支发布索引只在请求入口和响应出口重建;底层 I/O 仍逐次检查 scope 和磁盘身份。
319
+ await this.eligible(resource);
320
+ const response = await this.read(resource, frame, scope);
321
+ if (response.type !== "file_error")
322
+ await this.eligible(resource);
323
+ return response;
324
+ }
325
+ catch (error) {
326
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
327
+ return this.failure(frame, scope, error);
328
+ }
329
+ finally {
330
+ await this.finish(resource);
331
+ }
332
+ }
333
+ async read(resource, frame, scope) {
334
+ try {
335
+ await this.verify(resource, "scope");
336
+ const total = Number(resource.stat.size);
337
+ const data = Buffer.alloc(Math.min(FILE_CHUNK_BYTES, total - resource.offset));
338
+ let count = 0;
339
+ while (count < data.length) {
340
+ const result = await this.checked(resource, () => resource.handle.read(data, count, data.length - count, resource.offset + count), "scope");
341
+ if (!result.bytesRead)
342
+ throw new FileAccessError("file_changed");
343
+ count += result.bytesRead;
344
+ }
345
+ await this.verify(resource, "scope");
346
+ resource.hash.update(data);
347
+ resource.offset += data.length;
348
+ const common = { ...this.reply(frame, scope), type: "file_chunk", transfer_id: resource.transferId,
349
+ offset: frame.offset, data_base64: data.toString("base64") };
350
+ if (resource.offset !== total)
351
+ return { ...common, final: false };
352
+ const sha256 = resource.hash.digest("hex");
353
+ await this.checked(resource, () => this.closeHandle(resource), "scope");
354
+ this.assertCurrent(resource);
355
+ return { ...common, final: true, total_bytes: total, sha256 };
356
+ }
357
+ catch (error) {
358
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
359
+ return this.failure(frame, scope, error);
360
+ }
361
+ }
362
+ async inspectForPublication(path) {
363
+ const resource = this.reserve();
364
+ const task = this.inspectTask(resource, path);
365
+ return Promise.race([task, resource.cancelled]);
366
+ }
367
+ async inspectTask(resource, path) {
368
+ try {
369
+ this.assertCurrent(resource);
370
+ const opened = await openSourceFile(path, { resolveLinks: true, maxBytes: FILE_MAX_BYTES });
371
+ resource.handle = opened.handle;
372
+ resource.path = opened.path;
373
+ resource.stat = opened.stat;
374
+ this.assertCurrent(resource);
375
+ const fileName = basename(opened.path);
376
+ if (!fileName || fileName.length > 255 || /\p{Cc}/u.test(fileName))
377
+ throw new FileAccessError("not_available");
378
+ const inspection = await this.checked(resource, () => inspectFile(opened.handle, Number(opened.stat.size), fileName));
379
+ await this.verify(resource);
380
+ await this.checked(resource, () => this.closeHandle(resource));
381
+ return { sourcePath: opened.path, fileName, mimeType: inspection.mimeType, byteLength: Number(opened.stat.size) };
382
+ }
383
+ catch (error) {
384
+ if (error instanceof FileAccessError && error.handle) {
385
+ resource.handle = error.handle;
386
+ resource.closeFailed = true;
387
+ }
388
+ this.invalidate(resource, error instanceof ReaderError ? error.code : errorCode(error));
389
+ throw error;
390
+ }
391
+ finally {
392
+ await this.finish(resource);
393
+ }
394
+ }
395
+ async closeWhere(predicate) {
396
+ const matches = [...this.resources].filter((resource) => resource.scope && predicate({ ...resource.scope }));
397
+ for (const resource of matches)
398
+ this.invalidate(resource);
399
+ await Promise.all(matches.filter((resource) => !resource.active).map((resource) => this.cleanup(resource)));
400
+ }
401
+ async dispose() {
402
+ this.disposed = true;
403
+ const resources = [...this.resources];
404
+ for (const resource of resources)
405
+ this.invalidate(resource);
406
+ await Promise.all(resources.filter((resource) => !resource.active).map((resource) => this.cleanup(resource)));
407
+ }
408
+ }
409
+ class ReaderError extends Error {
410
+ code;
411
+ constructor(code) {
412
+ super(code);
413
+ this.code = code;
414
+ }
415
+ }
416
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/files/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAa,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAmB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAA0D,MAAM,4BAA4B,CAAC;AACtI,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkBjE,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAChC,8CAA8C;AAC9C,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AAC3E,MAAM,YAAY,GAAG,UAA4E,CAAC;AAClG,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe,CAAC,KAAK,IAAI,GAAG,EAAU,CAAC;AAE1E,SAAS,QAAQ,CAAC,CAAc,EAAE,CAAc;IAC9C,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;WAC9E,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;AAC1D,CAAC;AACD,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;AACpE,CAAC;AACD,SAAS,QAAQ,CAAC,KAAgB;IAChC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC9G,CAAC;AAED,wCAAwC;AACxC,MAAM,OAAO,iBAAiB;IASC;IARZ,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;IAChC,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IACpC,MAAM,CAAS;IACf,YAAY,CAAS;IAC9B,KAAK,CAAiC;IACtC,aAAa,CAAU;IACvB,QAAQ,GAAG,KAAK,CAAC;IAEzB,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;QAC3C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,eAAe,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,qBAAqB,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;eACxF,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,IAAI,CAAC,YAAY,GAAG,qBAAqB;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACpH,CAAC;IAED,IAAI,aAAa,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnD,OAAO,CAAC,KAAiB,EAAE,GAAY,EAAE,aAAsB;QACrE,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC,IAAI,IAAI,qBAAqB;YAAE,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3H,IAAI,MAA+B,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,4CAA4C;QAC5C,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAa;YACzB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC;YACvH,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS;YACxE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;SAChD,CAAC;QACF,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,GAAG;YAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,QAAQ;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO;YACvG,CAAC,CAAC,QAAQ,CAAC,OAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,QAAQ;YAAE,OAAO;QAC1D,IAAI,IAAI,CAAC,KAAK;YAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACtC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;oBACzF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBAC1B,gDAAgD;oBAChD,QAAQ,CAAC,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;oBACrC,IAAI,CAAC,QAAQ,CAAC,MAAM;wBAAE,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;IAEO,UAAU,CAAC,QAAkB,EAAE,OAAsB,kBAAkB;QAC7E,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9C,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAEO,aAAa,CAAC,QAAkB;QACtC,IAAI,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACrG,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAkB;QACvC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,aAAa;YAAE,OAAO;QACvD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QACvF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,CAAC,WAAW;YAAE,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,IAAI,IAAI,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,IAAI;YAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;QACzG,IAAI,CAAC,QAAQ,CAAC,IAAI;YAAE,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;IAC7D,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,QAAkB,EAAE,SAA2B,EAAE,SAAkC,aAAa;QACvH,IAAI,MAAM,KAAK,aAAa;YAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,MAAM,KAAK,aAAa;YAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,OAAO,CAAC,QAAkB;QAChC,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO;QACnE,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1E,IAAI,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/F,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,QAAkB;QAC1C,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC;YAAC,MAAM,QAAQ,CAAC,OAAO,CAAC;YAAC,QAAQ,CAAC,WAAW,GAAG,KAAK,CAAC;QAAC,CAAC;QAC7D,OAAO,KAAK,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;YAC5C,IAAI,QAAQ,CAAC,OAAO;gBAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;gBACO,CAAC;YAAC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC;QAAC,CAAC;IAC3C,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,QAAkB;QACtC,IAAI,CAAC;YAAC,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,qCAAqC,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,QAAkB;QACrC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC;QACxB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;;YACvE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,KAAc,EAAE,KAAgB;QAC5C,OAAO,EAAE,gBAAgB,EAAE,CAAU,EAAE,iBAAiB,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;IAClI,CAAC;IAEO,OAAO,CAAC,KAAc,EAAE,KAAgB,EAAE,KAAc;QAC9D,MAAM,IAAI,GAAG,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1E,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI;YAC5D,GAAG,CAAC,aAAa,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAc,EAAE,aAAwB;QACnD,MAAM,KAAK,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;YAC/F,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,WAAW;mBACpF,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;YACzD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC1B,IAAI,QAAQ,CAAC,MAAM;oBAAE,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;gBACnD,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACvB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;oBAAE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;gBAC/F,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9F,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,IAAI,QAAQ,CAAC,MAAM;gBAAE,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;gBAAE,MAAM,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAAC;YAC/E,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;YACjG,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAAC,CAAC;IAC/D,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,KAA8C,EAAE,KAAgB;QACjF,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,QAAQ,CAAC,aAAa,KAAK,KAAK,CAAC,cAAc;gBAAE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC;YAC/F,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;gBACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC9B,OAAO,QAAQ,CAAC,MAAM,IAAI,MAAM,QAAQ,CAAC,OAAQ,CAAC;YACpD,CAAC,CAAC;YACF,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAChE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,QAAkB,EAAE,OAA0B;QACvE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;YACnE,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACnC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;gBAClE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;YACD,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW;gBAAE,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC3E,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAkB,EAAE,KAA8C,EAAE,KAAgB;QACzG,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,IAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;YACvG,0CAA0C;YAC1C,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAC7D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;YAC/G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;YACtH,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,QAAQ,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc;gBACxG,WAAW,EAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5F,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;YAChE,OAAO,QAAQ,CAAC,MAAM,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAAC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAAC,CAAC;YACtH,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,QAAkB,EAAE,SAAkC,aAAa;QACtF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QACpG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAK,EAAE,OAAO,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;QAClF,sCAAsC;QACtC,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;QAChC,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACzF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE;gBAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;YAC5F,IAAI,MAAM,KAAK,IAAI;gBAAE,MAAM;YAC3B,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACnG,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAK,EAAE,MAAM,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;YAC5G,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAK,CAAC,EAAE,MAAM,CAAC,CAAC;YACvF,IAAI,SAAS,KAAK,QAAQ,CAAC,IAAI;gBAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBAClI,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAkB,EAAE,KAA8C,EAAE,KAAgB;QACzG,IAAI,CAAC;YACH,gDAAgD;YAChD,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACzD,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAClE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,QAAkB,EAAE,KAA8C,EAAE,KAAgB;QACrG,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/E,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC7I,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,MAAM,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;gBACjE,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC;YAC5B,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3B,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;YAC/B,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,YAAqB,EAAE,WAAW,EAAE,QAAQ,CAAC,UAAU;gBACzG,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/D,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK;gBAAE,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAClE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YACxE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,IAAY;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,QAAkB,EAAE,IAAY;QACxD,IAAI,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;YAC5F,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAC1F,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;YAC/G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;YACtH,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAAC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAAC,CAAC;YACtH,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAwC;QACvD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,IAAI,SAAS,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7G,KAAK,MAAM,QAAQ,IAAI,OAAO;YAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9G,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,KAAK,MAAM,QAAQ,IAAI,SAAS;YAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChH,CAAC;CACF;AAED,MAAM,WAAY,SAAQ,KAAK;IACR;IAArB,YAAqB,IAAmB;QAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAAnC,SAAI,GAAJ,IAAI,CAAe;IAAiB,CAAC;CAC3D"}
@@ -0,0 +1,22 @@
1
+ import { type BigIntStats } from "node:fs";
2
+ import { type FileHandle } from "node:fs/promises";
3
+ export type FileAccessCode = "not_available" | "permission_denied" | "not_regular_file" | "too_large" | "file_changed" | "io_error";
4
+ export declare class FileAccessError extends Error {
5
+ readonly code: FileAccessCode;
6
+ /** 仅当关闭失败时由调用者接管并重试回收;不能把该资源计作已释放。 */
7
+ handle?: FileHandle;
8
+ closeError?: unknown;
9
+ constructor(code: FileAccessCode);
10
+ }
11
+ /**
12
+ * 返回的句柄由调用者关闭。路径检查不提供原子文件快照;后续读取仍须核验同一句柄属性。
13
+ * NONBLOCK 防普通文件被 FIFO 替换时阻塞,不提供恶意文件系统内核 I/O 的硬取消。
14
+ */
15
+ export declare function openSourceFile(path: string, options: {
16
+ resolveLinks: boolean;
17
+ maxBytes: number;
18
+ }): Promise<{
19
+ handle: FileHandle;
20
+ path: string;
21
+ stat: BigIntStats;
22
+ }>;
@@ -0,0 +1,119 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, open, realpath } from "node:fs/promises";
3
+ import { dirname, isAbsolute, parse, resolve, sep } from "node:path";
4
+ export class FileAccessError extends Error {
5
+ code;
6
+ /** 仅当关闭失败时由调用者接管并重试回收;不能把该资源计作已释放。 */
7
+ handle;
8
+ closeError;
9
+ constructor(code) {
10
+ super(code);
11
+ this.code = code;
12
+ this.name = "FileAccessError";
13
+ }
14
+ }
15
+ function nodeCode(error) {
16
+ if (typeof error !== "object" || error === null || !("code" in error))
17
+ return undefined;
18
+ return typeof error.code === "string" ? error.code : undefined;
19
+ }
20
+ function accessError(error) {
21
+ if (error instanceof FileAccessError)
22
+ return error;
23
+ switch (nodeCode(error)) {
24
+ case "EACCES":
25
+ case "EPERM": return new FileAccessError("permission_denied");
26
+ case "ENOENT":
27
+ case "ENOTDIR": return new FileAccessError("not_available");
28
+ case "ELOOP": return new FileAccessError("file_changed");
29
+ default: return new FileAccessError("io_error");
30
+ }
31
+ }
32
+ function sameIdentity(a, b) {
33
+ return a.dev === b.dev && a.ino === b.ino && a.mode === b.mode;
34
+ }
35
+ function sameFile(a, b) {
36
+ return sameIdentity(a, b) && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs;
37
+ }
38
+ async function parentIdentities(path) {
39
+ const directory = dirname(path);
40
+ let current = parse(directory).root;
41
+ const parents = [];
42
+ for (const part of ["", ...directory.slice(current.length).split(sep).filter(Boolean)]) {
43
+ if (part)
44
+ current = resolve(current, part);
45
+ const stat = await lstat(current, { bigint: true });
46
+ if (stat.isSymbolicLink() || !stat.isDirectory())
47
+ throw new FileAccessError("file_changed");
48
+ parents.push(stat);
49
+ }
50
+ return parents;
51
+ }
52
+ function assertRegular(stat, maxBytes) {
53
+ if (!stat.isFile())
54
+ throw new FileAccessError("not_regular_file");
55
+ if (stat.size > BigInt(maxBytes))
56
+ throw new FileAccessError("too_large");
57
+ }
58
+ async function verifyOpenedPath(path, before, parents, opened) {
59
+ try {
60
+ const afterParents = await parentIdentities(path);
61
+ if (afterParents.length !== parents.length || afterParents.some((stat, index) => !sameIdentity(stat, parents[index]))) {
62
+ throw new FileAccessError("file_changed");
63
+ }
64
+ const after = await lstat(path, { bigint: true });
65
+ if (after.isSymbolicLink() || !sameFile(before, opened) || !sameFile(opened, after) || await realpath(path) !== path) {
66
+ throw new FileAccessError("file_changed");
67
+ }
68
+ }
69
+ catch (error) {
70
+ if (["ENOENT", "ENOTDIR", "ELOOP"].includes(nodeCode(error) ?? ""))
71
+ throw new FileAccessError("file_changed");
72
+ throw error;
73
+ }
74
+ }
75
+ /**
76
+ * 返回的句柄由调用者关闭。路径检查不提供原子文件快照;后续读取仍须核验同一句柄属性。
77
+ * NONBLOCK 防普通文件被 FIFO 替换时阻塞,不提供恶意文件系统内核 I/O 的硬取消。
78
+ */
79
+ export async function openSourceFile(path, options) {
80
+ let handle;
81
+ try {
82
+ // Windows 的 Node 打开标志没有等价的 no-follow/non-block 保证,明确 fail closed。
83
+ if (!["darwin", "linux"].includes(process.platform) || !constants.O_NOFOLLOW || !constants.O_NONBLOCK) {
84
+ throw new FileAccessError("not_available");
85
+ }
86
+ if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0 || !path || path.includes("\0")) {
87
+ throw new FileAccessError("io_error");
88
+ }
89
+ if (!options.resolveLinks && (!isAbsolute(path) || resolve(path) !== path))
90
+ throw new FileAccessError("file_changed");
91
+ const canonical = await realpath(path);
92
+ if (!options.resolveLinks && canonical !== path)
93
+ throw new FileAccessError("file_changed");
94
+ const parents = await parentIdentities(canonical);
95
+ const before = await lstat(canonical, { bigint: true });
96
+ if (before.isSymbolicLink())
97
+ throw new FileAccessError("file_changed");
98
+ assertRegular(before, options.maxBytes);
99
+ handle = await open(canonical, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
100
+ const stat = await handle.stat({ bigint: true });
101
+ assertRegular(stat, options.maxBytes);
102
+ await verifyOpenedPath(canonical, before, parents, stat);
103
+ return { handle, path: canonical, stat };
104
+ }
105
+ catch (error) {
106
+ const failure = accessError(error);
107
+ if (handle) {
108
+ try {
109
+ await handle.close();
110
+ }
111
+ catch (closeError) {
112
+ failure.handle = handle;
113
+ failure.closeError = closeError;
114
+ }
115
+ }
116
+ throw failure;
117
+ }
118
+ }
119
+ //# sourceMappingURL=safe-open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-open.js","sourceRoot":"","sources":["../../src/files/safe-open.ts"],"names":[],"mappings":"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"}