@narumitw/pi-sync 0.54.3 → 0.57.0
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.
- package/README.md +38 -11
- package/dist/chunks/agent-candidate-3JN6DJKT.ts +26 -0
- package/dist/chunks/agent-plan-QCUJWBP4.ts +99 -0
- package/dist/chunks/agent-plan-QCUJWBP4.ts.map +7 -0
- package/dist/chunks/agent-runner-E2JU2VZ6.ts +182 -0
- package/dist/chunks/agent-runner-E2JU2VZ6.ts.map +7 -0
- package/dist/chunks/agent-store-A3F6IYWZ.ts +152 -0
- package/dist/chunks/agent-store-A3F6IYWZ.ts.map +7 -0
- package/dist/chunks/chunk-5Q5SSKNG.ts +128 -0
- package/dist/chunks/chunk-5Q5SSKNG.ts.map +7 -0
- package/dist/chunks/chunk-5XZOC7FD.ts +215 -0
- package/dist/chunks/chunk-5XZOC7FD.ts.map +7 -0
- package/dist/chunks/{chunk-GC3QOL6J.ts → chunk-AAEEHR7H.ts} +31 -87
- package/dist/chunks/chunk-AAEEHR7H.ts.map +7 -0
- package/dist/chunks/{chunk-R35N4CL3.ts → chunk-B4QZBDBT.ts} +2 -2
- package/dist/chunks/{chunk-KGE47GCZ.ts → chunk-CRKTAPSL.ts} +8 -8
- package/dist/chunks/chunk-DT7M4VQS.ts +69 -0
- package/dist/chunks/chunk-DT7M4VQS.ts.map +7 -0
- package/dist/chunks/chunk-ED3TYIVW.ts +229 -0
- package/dist/chunks/chunk-ED3TYIVW.ts.map +7 -0
- package/dist/chunks/{chunk-HMXUKU43.ts → chunk-EUMINX7L.ts} +6 -6
- package/dist/chunks/chunk-FQOSHGJ7.ts +215 -0
- package/dist/chunks/chunk-FQOSHGJ7.ts.map +7 -0
- package/dist/chunks/chunk-GNH73BJ5.ts +153 -0
- package/dist/chunks/chunk-GNH73BJ5.ts.map +7 -0
- package/dist/chunks/{chunk-YTHQEW35.ts → chunk-GP5DU62N.ts} +8 -9
- package/dist/chunks/chunk-GP5DU62N.ts.map +7 -0
- package/dist/chunks/{chunk-AAZDBIBJ.ts → chunk-GSNPASKB.ts} +2 -2
- package/dist/chunks/{chunk-E6ONFG57.ts → chunk-IWZH5KYS.ts} +11 -8
- package/dist/chunks/chunk-IWZH5KYS.ts.map +7 -0
- package/dist/chunks/{chunk-CAGJOKB7.ts → chunk-JJTARUSO.ts} +15 -14
- package/dist/chunks/chunk-JJTARUSO.ts.map +7 -0
- package/dist/chunks/{chunk-ITFR6NNQ.ts → chunk-NLWS55B6.ts} +2 -1
- package/dist/chunks/{chunk-ITFR6NNQ.ts.map → chunk-NLWS55B6.ts.map} +2 -2
- package/dist/chunks/{chunk-2FETCGGT.ts → chunk-OEWQVWLC.ts} +4 -4
- package/dist/chunks/{chunk-35GM6XKM.ts → chunk-OTZRCKYP.ts} +128 -382
- package/dist/chunks/chunk-OTZRCKYP.ts.map +7 -0
- package/dist/chunks/{chunk-XU2VXGQV.ts → chunk-OWBAZA6J.ts} +14 -8
- package/dist/chunks/chunk-OWBAZA6J.ts.map +7 -0
- package/dist/chunks/chunk-PRUEIIK7.ts +24 -0
- package/dist/chunks/chunk-PRUEIIK7.ts.map +7 -0
- package/dist/chunks/chunk-QGK445K7.ts +21 -0
- package/dist/chunks/chunk-QGK445K7.ts.map +7 -0
- package/dist/chunks/{chunk-KATKRR3D.ts → chunk-QO333NM4.ts} +32 -11
- package/dist/chunks/chunk-QO333NM4.ts.map +7 -0
- package/dist/chunks/{chunk-I4JYVFUS.ts → chunk-QSHMOL3I.ts} +21 -22
- package/dist/chunks/chunk-QSHMOL3I.ts.map +7 -0
- package/dist/chunks/chunk-S2FMH5FT.ts +97 -0
- package/dist/chunks/chunk-S2FMH5FT.ts.map +7 -0
- package/dist/chunks/{chunk-BVVP33U5.ts → chunk-SWRVXVFD.ts} +12 -9
- package/dist/chunks/chunk-SWRVXVFD.ts.map +7 -0
- package/dist/chunks/{chunk-ZX2Q6THB.ts → chunk-UBV24CG4.ts} +4 -5
- package/dist/chunks/chunk-UBV24CG4.ts.map +7 -0
- package/dist/chunks/chunk-UOHR7LRO.ts +70 -0
- package/dist/chunks/chunk-UOHR7LRO.ts.map +7 -0
- package/dist/chunks/{chunk-VCL7TZYW.ts → chunk-UPNVIUBN.ts} +3 -3
- package/dist/chunks/chunk-VJN7KU4J.ts +350 -0
- package/dist/chunks/chunk-VJN7KU4J.ts.map +7 -0
- package/dist/chunks/chunk-YHT4YTYG.ts +31 -0
- package/dist/chunks/chunk-YHT4YTYG.ts.map +7 -0
- package/dist/chunks/{chunk-A3TFXY4O.ts → chunk-YK52VDXG.ts} +6 -5
- package/dist/chunks/chunk-YK52VDXG.ts.map +7 -0
- package/dist/chunks/config-KGIYTTXQ.ts +37 -0
- package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts → conflict-artifacts-FXFIIBCB.ts} +8 -7
- package/dist/chunks/{conflict-review-ZOTOHL2E.ts → conflict-review-6WIEQLXW.ts} +31 -25
- package/dist/chunks/{conflict-review-ZOTOHL2E.ts.map → conflict-review-6WIEQLXW.ts.map} +1 -1
- package/dist/chunks/continuous-record-LFRVXQBD.ts +30 -0
- package/dist/chunks/continuous-sync-AWAAOXK2.ts +545 -0
- package/dist/chunks/continuous-sync-AWAAOXK2.ts.map +7 -0
- package/dist/chunks/{file-selection-UNHBVVON.ts → file-selection-3JJYOVNR.ts} +5 -5
- package/dist/chunks/{git-backend-FD7AVSK6.ts → git-backend-KYDZ673X.ts} +28 -32
- package/dist/chunks/git-backend-KYDZ673X.ts.map +7 -0
- package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts → manager-result-dispatcher-AGBBVDDS.ts} +10 -9
- package/dist/chunks/{manager-ui-ZIN4BUSF.ts → manager-ui-KRAW3NE2.ts} +184 -45
- package/dist/chunks/manager-ui-KRAW3NE2.ts.map +7 -0
- package/dist/chunks/{merge-baseline-store-ICXVTCML.ts → merge-baseline-store-RFCAH7KL.ts} +5 -5
- package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts → remote-selection-ui-5725JDNC.ts} +9 -8
- package/dist/chunks/remote-selection-ui-5725JDNC.ts.map +7 -0
- package/dist/chunks/{s3-backend-Y4P3O5B5.ts → s3-backend-Y7WSCLJI.ts} +38 -38
- package/dist/chunks/s3-backend-Y7WSCLJI.ts.map +7 -0
- package/dist/chunks/{setup-switch-ZMW5C4M7.ts → setup-switch-E7PHKI6J.ts} +7 -6
- package/dist/chunks/setup-switch-E7PHKI6J.ts.map +7 -0
- package/dist/chunks/{setup-wizard-VW7F3JN4.ts → setup-wizard-65DROCIJ.ts} +14 -13
- package/dist/chunks/setup-wizard-65DROCIJ.ts.map +7 -0
- package/dist/chunks/{sync-inspection-3EMS2J5B.ts → sync-inspection-XFJOAMJD.ts} +8 -8
- package/dist/chunks/sync-inspection-XFJOAMJD.ts.map +7 -0
- package/dist/chunks/{sync-operations-2CWST333.ts → sync-operations-HDUDT5PD.ts} +62 -63
- package/dist/chunks/sync-operations-HDUDT5PD.ts.map +7 -0
- package/dist/chunks/{webdav-backend-TBILVEQK.ts → webdav-backend-6K26F6LT.ts} +39 -48
- package/dist/chunks/webdav-backend-6K26F6LT.ts.map +7 -0
- package/dist/index.ts +165 -85
- package/dist/index.ts.map +3 -3
- package/docs/agent-mode-verification.md +99 -0
- package/docs/continuous-sync-verification.md +87 -0
- package/docs/settings.md +32 -247
- package/package.json +11 -5
- package/skills/configure-pi-sync/SKILL.md +54 -0
- package/skills/configure-pi-sync/references/configuration.md +650 -0
- package/src/backends/git/git-backend.ts +1 -4
- package/src/backends/git/git-runner.ts +1 -5
- package/src/backends/s3/s3-backend.ts +3 -25
- package/src/backends/s3/s3-client.ts +14 -2
- package/src/backends/snapshot-pointer.ts +27 -0
- package/src/backends/webdav/webdav-backend.ts +3 -29
- package/src/backends/webdav/webdav-client.ts +11 -7
- package/src/commands/command-execution.ts +5 -2
- package/src/commands/command-handler.ts +15 -3
- package/src/commands/command-types.ts +6 -0
- package/src/commands/command.ts +1 -0
- package/src/settings/config.ts +7 -0
- package/src/settings/settings-store.ts +0 -34
- package/src/settings/settings-types.ts +8 -0
- package/src/settings/settings-validation.ts +1 -1
- package/src/snapshot/snapshot-codec.ts +1 -5
- package/src/state/lock.ts +13 -10
- package/src/state/merge-baseline-store.ts +2 -2
- package/src/state/state-directory.ts +8 -1
- package/src/sync/agent-candidate.ts +251 -0
- package/src/sync/agent-plan.ts +87 -0
- package/src/sync/agent-policy.ts +13 -0
- package/src/sync/agent-request.ts +17 -0
- package/src/sync/agent-runner.ts +188 -0
- package/src/sync/agent-store.ts +151 -0
- package/src/sync/agent-sync.ts +91 -0
- package/src/sync/automatic-sync.ts +2 -1
- package/src/sync/continuous-errors.ts +85 -0
- package/src/sync/continuous-lease.ts +221 -0
- package/src/sync/continuous-record.ts +179 -0
- package/src/sync/continuous-storage.ts +55 -0
- package/src/sync/continuous-sync.ts +516 -0
- package/src/sync/continuous-watch.ts +59 -0
- package/src/sync/merged-sync.ts +70 -12
- package/src/sync/remote-snapshot.ts +2 -3
- package/src/sync/settings-merge.ts +19 -3
- package/src/sync/setup-switch.ts +1 -5
- package/src/sync/startup-check.ts +15 -11
- package/src/sync/sync-inspection.ts +8 -1
- package/src/sync/sync-mutations.ts +6 -17
- package/src/sync/sync-queries.ts +5 -0
- package/src/sync/text-merge.ts +3 -3
- package/src/sync-extension.ts +75 -19
- package/src/ui/agent-mode-setting.ts +91 -0
- package/src/ui/manager-state.ts +2 -0
- package/src/ui/remote-selection-ui.ts +5 -5
- package/src/ui/settings-ui.ts +83 -1
- package/src/ui/setup/s3-credentials-ui.ts +1 -5
- package/src/ui/setup/setup-name-ui.ts +2 -5
- package/src/ui/setup/setup-switcher.ts +2 -0
- package/src/ui/sync-setups-ui.ts +3 -5
- package/dist/chunks/chunk-26PMXY7E.ts +0 -362
- package/dist/chunks/chunk-26PMXY7E.ts.map +0 -7
- package/dist/chunks/chunk-35GM6XKM.ts.map +0 -7
- package/dist/chunks/chunk-A3TFXY4O.ts.map +0 -7
- package/dist/chunks/chunk-BVVP33U5.ts.map +0 -7
- package/dist/chunks/chunk-CAGJOKB7.ts.map +0 -7
- package/dist/chunks/chunk-E6ONFG57.ts.map +0 -7
- package/dist/chunks/chunk-GC3QOL6J.ts.map +0 -7
- package/dist/chunks/chunk-I4JYVFUS.ts.map +0 -7
- package/dist/chunks/chunk-KATKRR3D.ts.map +0 -7
- package/dist/chunks/chunk-XU2VXGQV.ts.map +0 -7
- package/dist/chunks/chunk-YTHQEW35.ts.map +0 -7
- package/dist/chunks/chunk-ZX2Q6THB.ts.map +0 -7
- package/dist/chunks/git-backend-FD7AVSK6.ts.map +0 -7
- package/dist/chunks/manager-ui-ZIN4BUSF.ts.map +0 -7
- package/dist/chunks/s3-backend-Y4P3O5B5.ts.map +0 -7
- package/dist/chunks/setup-wizard-VW7F3JN4.ts.map +0 -7
- package/dist/chunks/sync-operations-2CWST333.ts.map +0 -7
- package/dist/chunks/webdav-backend-TBILVEQK.ts.map +0 -7
- /package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts.map → agent-candidate-3JN6DJKT.ts.map} +0 -0
- /package/dist/chunks/{chunk-R35N4CL3.ts.map → chunk-B4QZBDBT.ts.map} +0 -0
- /package/dist/chunks/{chunk-KGE47GCZ.ts.map → chunk-CRKTAPSL.ts.map} +0 -0
- /package/dist/chunks/{chunk-HMXUKU43.ts.map → chunk-EUMINX7L.ts.map} +0 -0
- /package/dist/chunks/{chunk-AAZDBIBJ.ts.map → chunk-GSNPASKB.ts.map} +0 -0
- /package/dist/chunks/{chunk-2FETCGGT.ts.map → chunk-OEWQVWLC.ts.map} +0 -0
- /package/dist/chunks/{chunk-VCL7TZYW.ts.map → chunk-UPNVIUBN.ts.map} +0 -0
- /package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts.map → config-KGIYTTXQ.ts.map} +0 -0
- /package/dist/chunks/{merge-baseline-store-ICXVTCML.ts.map → conflict-artifacts-FXFIIBCB.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts.map → continuous-record-LFRVXQBD.ts.map} +0 -0
- /package/dist/chunks/{file-selection-UNHBVVON.ts.map → file-selection-3JJYOVNR.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-ZMW5C4M7.ts.map → manager-result-dispatcher-AGBBVDDS.ts.map} +0 -0
- /package/dist/chunks/{sync-inspection-3EMS2J5B.ts.map → merge-baseline-store-RFCAH7KL.ts.map} +0 -0
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import "./chunk-T2SJD3N7.ts";
|
|
8
|
-
import {
|
|
9
|
-
SyncBackendConflictError,
|
|
10
|
-
SyncBackendPublicationOutcomeUnknownError
|
|
11
|
-
} from "./chunk-YDVQYUHE.ts";
|
|
4
|
+
createLatestPointer,
|
|
5
|
+
remoteHistoryEntry
|
|
6
|
+
} from "./chunk-YHT4YTYG.ts";
|
|
12
7
|
import {
|
|
13
8
|
decodeSnapshot,
|
|
14
9
|
encodeSnapshot
|
|
15
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UBV24CG4.ts";
|
|
16
11
|
import {
|
|
17
12
|
syncErrorGuidance
|
|
18
13
|
} from "./chunk-G4RUXRWZ.ts";
|
|
19
14
|
import "./chunk-7D5SF7P3.ts";
|
|
15
|
+
import {
|
|
16
|
+
sessionTokenWarnings
|
|
17
|
+
} from "./chunk-QO333NM4.ts";
|
|
20
18
|
import {
|
|
21
19
|
validatePortableSnapshot
|
|
22
20
|
} from "./chunk-A6HU4ERM.ts";
|
|
21
|
+
import {
|
|
22
|
+
throwIfAborted
|
|
23
|
+
} from "./chunk-PWMWOJP4.ts";
|
|
24
|
+
import {
|
|
25
|
+
retryAfter
|
|
26
|
+
} from "./chunk-DT7M4VQS.ts";
|
|
27
|
+
import {
|
|
28
|
+
SyncBackendConflictError,
|
|
29
|
+
SyncBackendPublicationOutcomeUnknownError
|
|
30
|
+
} from "./chunk-YDVQYUHE.ts";
|
|
23
31
|
import {
|
|
24
32
|
portableSnapshotSelection
|
|
25
33
|
} from "./chunk-QOFMXPM5.ts";
|
|
26
34
|
import "./chunk-ZW5ZLGBI.ts";
|
|
35
|
+
import "./chunk-2JZFHNLM.ts";
|
|
36
|
+
import "./chunk-T2SJD3N7.ts";
|
|
27
37
|
import {
|
|
28
38
|
encodeKey,
|
|
29
39
|
posixJoin
|
|
@@ -61,12 +71,14 @@ var S3ObjectAlreadyExistsError = class extends Error {
|
|
|
61
71
|
key;
|
|
62
72
|
};
|
|
63
73
|
var S3HttpError = class extends Error {
|
|
64
|
-
constructor(message, status) {
|
|
74
|
+
constructor(message, status, retryAfterMs) {
|
|
65
75
|
super(message);
|
|
66
76
|
this.status = status;
|
|
77
|
+
this.retryAfterMs = retryAfterMs;
|
|
67
78
|
this.name = "S3HttpError";
|
|
68
79
|
}
|
|
69
80
|
status;
|
|
81
|
+
retryAfterMs;
|
|
70
82
|
};
|
|
71
83
|
var S3Client = class {
|
|
72
84
|
config;
|
|
@@ -106,7 +118,11 @@ var S3Client = class {
|
|
|
106
118
|
const object = await this.request("GET", key);
|
|
107
119
|
if (object.status === 404) return { missing: true };
|
|
108
120
|
if (!object.ok) {
|
|
109
|
-
throw new S3HttpError(
|
|
121
|
+
throw new S3HttpError(
|
|
122
|
+
`S3 GET failed (${object.status}): ${await this.readErrorText(object)}`,
|
|
123
|
+
object.status,
|
|
124
|
+
retryAfter(object)
|
|
125
|
+
);
|
|
110
126
|
}
|
|
111
127
|
const body = await readBoundedText(object, MAX_JSON_RESPONSE_BYTES, "S3 JSON response");
|
|
112
128
|
if (body.length > 0) {
|
|
@@ -130,7 +146,11 @@ var S3Client = class {
|
|
|
130
146
|
const object = await this.request("GET", key);
|
|
131
147
|
if (object.status === 404) return { missing: true };
|
|
132
148
|
if (!object.ok) {
|
|
133
|
-
throw new S3HttpError(
|
|
149
|
+
throw new S3HttpError(
|
|
150
|
+
`S3 GET failed (${object.status}): ${await this.readErrorText(object)}`,
|
|
151
|
+
object.status,
|
|
152
|
+
retryAfter(object)
|
|
153
|
+
);
|
|
134
154
|
}
|
|
135
155
|
const buffer = await readBoundedBuffer(object, MAX_SNAPSHOT_RESPONSE_BYTES, "S3 snapshot response");
|
|
136
156
|
if (buffer.length > 0) {
|
|
@@ -162,7 +182,8 @@ var S3Client = class {
|
|
|
162
182
|
if (!response.ok) {
|
|
163
183
|
throw new S3HttpError(
|
|
164
184
|
`S3 PUT failed (${response.status}): ${await this.readErrorText(response)}`,
|
|
165
|
-
response.status
|
|
185
|
+
response.status,
|
|
186
|
+
retryAfter(response)
|
|
166
187
|
);
|
|
167
188
|
}
|
|
168
189
|
await response.body?.cancel();
|
|
@@ -172,7 +193,8 @@ var S3Client = class {
|
|
|
172
193
|
if (!response.ok && response.status !== 404) {
|
|
173
194
|
throw new S3HttpError(
|
|
174
195
|
`S3 DELETE failed (${response.status}): ${await this.readErrorText(response)}`,
|
|
175
|
-
response.status
|
|
196
|
+
response.status,
|
|
197
|
+
retryAfter(response)
|
|
176
198
|
);
|
|
177
199
|
}
|
|
178
200
|
await response.body?.cancel();
|
|
@@ -665,16 +687,7 @@ function storageRoot(config) {
|
|
|
665
687
|
return config.destination.prefix === "./" ? "" : config.destination.prefix;
|
|
666
688
|
}
|
|
667
689
|
function pointerFor(config, snapshot, checksum) {
|
|
668
|
-
return
|
|
669
|
-
version: VERSION,
|
|
670
|
-
profile: config.destination.namespace,
|
|
671
|
-
snapshot: snapshot.id,
|
|
672
|
-
sha256: checksum,
|
|
673
|
-
createdAt: snapshot.createdAt,
|
|
674
|
-
machine: snapshot.machine,
|
|
675
|
-
syncSessions: snapshot.syncSessions === true || snapshot.files.some((file) => file.path.startsWith("sessions/")),
|
|
676
|
-
...snapshot.selection === void 0 ? {} : { selection: snapshot.selection }
|
|
677
|
-
};
|
|
690
|
+
return createLatestPointer(config.destination.namespace, snapshot, checksum);
|
|
678
691
|
}
|
|
679
692
|
function s3BackendIdentity(config) {
|
|
680
693
|
const destination = JSON.stringify([
|
|
@@ -707,15 +720,6 @@ function secretFreeEndpoint(value) {
|
|
|
707
720
|
function trimSlashes(value) {
|
|
708
721
|
return value.replace(/^\/+|\/+$/g, "");
|
|
709
722
|
}
|
|
710
|
-
function remoteHistoryEntry(pointer) {
|
|
711
|
-
return {
|
|
712
|
-
snapshotRef: pointer.snapshot,
|
|
713
|
-
snapshotId: pointer.snapshot,
|
|
714
|
-
createdAt: pointer.createdAt,
|
|
715
|
-
machine: pointer.machine,
|
|
716
|
-
syncSessions: pointer.syncSessions === true
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
723
|
function remoteHead(pointer, identity, etag) {
|
|
720
724
|
return {
|
|
721
725
|
snapshotRef: pointer.snapshot,
|
|
@@ -815,10 +819,6 @@ function hasControlCharacter(value) {
|
|
|
815
819
|
return code < 32 || code === 127;
|
|
816
820
|
});
|
|
817
821
|
}
|
|
818
|
-
function throwIfAborted(signal) {
|
|
819
|
-
if (!signal?.aborted) return;
|
|
820
|
-
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
821
|
-
}
|
|
822
822
|
function sha2562(value) {
|
|
823
823
|
return createHash2("sha256").update(value).digest("hex");
|
|
824
824
|
}
|
|
@@ -835,4 +835,4 @@ export {
|
|
|
835
835
|
snapshotKey,
|
|
836
836
|
storageRoot
|
|
837
837
|
};
|
|
838
|
-
//# sourceMappingURL=s3-backend-
|
|
838
|
+
//# sourceMappingURL=s3-backend-Y7WSCLJI.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backends/s3/s3-backend.ts", "../../src/backends/s3/s3-client.ts", "../../src/backends/s3/s3-conditions.ts"],
|
|
4
|
+
"sourcesContent": ["import { createHash } from \"node:crypto\";\nimport { encodeKey, posixJoin } from \"../../paths.js\";\nimport { sessionTokenWarnings } from \"../../settings/config.js\";\nimport { decodeSnapshot, encodeSnapshot } from \"../../snapshot/snapshot-codec.js\";\nimport type { Snapshot } from \"../../snapshot/snapshot-types.js\";\nimport { validatePortableSnapshot } from \"../../sync/local-fields.js\";\nimport { throwIfAborted } from \"../../sync/signals.js\";\nimport { syncErrorGuidance } from \"../../sync/sync-error-guidance.js\";\nimport { portableSnapshotSelection } from \"../../sync/sync-policy.js\";\nimport type { LatestPointer, RemoteObject, ResolvedS3Backend } from \"../backend-types.js\";\nimport { createLatestPointer, remoteHistoryEntry } from \"../snapshot-pointer.js\";\nimport {\n type BackendDiagnostic,\n type ExpectedRemoteHead,\n type PublishSnapshotOptions,\n type PublishSnapshotResult,\n type RemoteHead,\n type RemoteHistoryEntry,\n type SyncBackend,\n SyncBackendConflictError,\n SyncBackendPublicationOutcomeUnknownError,\n} from \"../sync-backend.js\";\nimport { S3Client, S3HttpError, S3ObjectAlreadyExistsError } from \"./s3-client.js\";\nimport { requireS3Etag, verifyS3Conditions } from \"./s3-conditions.js\";\n\nconst VERSION = 1;\nconst POST_COMMIT_TIMEOUT_MS = 30_000;\n\nexport class S3SyncBackend implements SyncBackend {\n readonly identity: string;\n readonly destination: string;\n readonly capability = \"conditional-required\" as const;\n private readonly checksums = new Map<string, string>();\n private recoveryHead?: { current: string; legacy: string };\n\n constructor(\n private readonly config: ResolvedS3Backend,\n private readonly postCommitTimeoutMs = POST_COMMIT_TIMEOUT_MS,\n ) {\n assertSafeDestination(config);\n this.identity = s3BackendIdentity(config);\n this.destination = s3Destination(config);\n }\n\n sameRevision(left: string, right: string) {\n return left === right;\n }\n\n matchesUncommittedRecoveryHead(current: RemoteHead, recorded: RemoteHead) {\n return (\n this.sameRevision(current.revision, recorded.revision) ||\n (current.snapshotId === recorded.snapshotId &&\n current.snapshotRef === recorded.snapshotRef &&\n current.revision === this.recoveryHead?.current &&\n recorded.revision === this.recoveryHead?.legacy)\n );\n }\n\n async readHead(signal?: AbortSignal): Promise<RemoteHead | undefined> {\n this.recoveryHead = undefined;\n const object = await new S3Client(this.config, signal).getJson<LatestPointer>(latestKey(this.config));\n throwIfAborted(signal);\n if (object.missing) return undefined;\n const pointer = requirePointer(\n object.value,\n \"Remote latest pointer is malformed.\",\n this.config.destination.namespace,\n );\n this.registerChecksum(pointer.snapshot, pointer.sha256);\n const head = remoteHead(pointer, this.identity, object.etag);\n if (object.etag && /^\"[^\"\\r\\n]+\"$/u.test(object.etag)) {\n // Old clients hashed R2's compression-weakened ETag. Bind the alias to the\n // exact current pointer and strong ETag, solely for inactive-journal retirement.\n this.recoveryHead = {\n current: head.revision,\n legacy: remoteHead(pointer, this.identity, `W/${object.etag}`).revision,\n };\n }\n return head;\n }\n\n async readSnapshot(reference: string, signal?: AbortSignal): Promise<Snapshot> {\n const expectedChecksum = this.checksums.get(reference) ?? (await this.resolveChecksum(reference, signal));\n const object = await new S3Client(this.config, signal).getBuffer(snapshotKey(this.config, reference));\n throwIfAborted(signal);\n if (!object.value) throw new Error(`Snapshot not found: ${reference}`);\n if (expectedChecksum && sha256(object.value) !== expectedChecksum) {\n throw new Error(\"Remote snapshot checksum mismatch.\");\n }\n const snapshot = await decodeSnapshot(object.value, { signal });\n if (snapshot.id !== reference || snapshot.profile !== this.config.destination.namespace) {\n throw new Error(\"Remote snapshot identity mismatch.\");\n }\n validateSnapshotBundle(snapshot);\n return snapshot;\n }\n\n async publishSnapshot(\n snapshot: Snapshot,\n expected: ExpectedRemoteHead,\n options: PublishSnapshotOptions = {},\n ): Promise<PublishSnapshotResult> {\n throwIfAborted(options.signal);\n assertSnapshotIdentity(snapshot, this.config.destination.namespace);\n await verifyS3Conditions(this.config, options.signal);\n throwIfAborted(options.signal);\n const stagedKey = snapshotKey(this.config, snapshot.id);\n const encoded = await encodeSnapshot(snapshot);\n throwIfAborted(options.signal);\n const pointer = pointerFor(this.config, snapshot, sha256(encoded));\n const cancellableClient = new S3Client(this.config, options.signal);\n try {\n await cancellableClient.putBuffer(stagedKey, encoded, \"application/gzip\", {\n ifAbsent: true,\n });\n } catch (error) {\n if (!(error instanceof S3ObjectAlreadyExistsError)) throw error;\n const existing = await cancellableClient.getBuffer(stagedKey);\n if (!existing.value || sha256(existing.value) !== pointer.sha256) {\n throw new SyncBackendConflictError(\n `Immutable snapshot id already exists with different content: ${snapshot.id}`,\n );\n }\n }\n const currentObject = await cancellableClient.getJson<LatestPointer>(latestKey(this.config));\n throwIfAborted(options.signal);\n let current: RemoteHead | undefined;\n if (!currentObject.missing) {\n const currentPointer = requirePointer(\n currentObject.value,\n \"Remote latest pointer is malformed.\",\n this.config.destination.namespace,\n );\n this.registerChecksum(currentPointer.snapshot, currentPointer.sha256);\n current = remoteHead(currentPointer, this.identity, currentObject.etag);\n }\n if (!matchesExpected(current, expected)) {\n throw new SyncBackendConflictError(\"Remote changed while pushing. Run /sync pull first, then retry.\", {\n currentHead: current,\n });\n }\n const condition = currentObject.missing ? { ifAbsent: true } : { ifMatch: requireS3Etag(currentObject.etag) };\n throwIfAborted(options.signal);\n options.onCommit?.();\n\n // The active-head PUT is the publication boundary. Do not bind it or its\n // verification to a user-cancellation signal after the boundary begins.\n const commitClient = new S3Client(this.config, AbortSignal.timeout(this.postCommitTimeoutMs));\n try {\n await commitClient.putJson(latestKey(this.config), pointer, condition);\n } catch (error) {\n if (\n error instanceof S3ObjectAlreadyExistsError ||\n (error instanceof S3HttpError && (error.status === 412 || error.status === 409))\n ) {\n throw new SyncBackendConflictError(\"Remote conditional publication was rejected; reread and retry.\", {\n cause: error,\n });\n }\n throw new SyncBackendPublicationOutcomeUnknownError(\n `Remote publication outcome is unknown: ${errorMessage(error)}`,\n { cause: error },\n );\n }\n\n let verifiedObject: RemoteObject<LatestPointer>;\n try {\n verifiedObject = await commitClient.getJson<LatestPointer>(latestKey(this.config));\n } catch (error) {\n throw new SyncBackendPublicationOutcomeUnknownError(\n `Remote snapshot may be active, but publication could not be verified: ${errorMessage(error)}`,\n { cause: error },\n );\n }\n let verifiedPointer: LatestPointer;\n try {\n verifiedPointer = requirePointer(\n verifiedObject.value,\n \"Remote latest pointer is malformed after publication.\",\n this.config.destination.namespace,\n );\n } catch (error) {\n throw new SyncBackendPublicationOutcomeUnknownError(\n `Remote snapshot may be active, but publication verification was malformed: ${errorMessage(error)}`,\n { cause: error },\n );\n }\n if (!samePointer(verifiedPointer, pointer)) {\n throw new SyncBackendConflictError(\n \"Remote latest changed immediately after push. Run /sync status before continuing.\",\n {\n phase: \"after-commit\",\n currentHead: remoteHead(verifiedPointer, this.identity, verifiedObject.etag),\n candidateMayHaveBeenActive: true,\n },\n );\n }\n this.registerChecksum(verifiedPointer.snapshot, verifiedPointer.sha256);\n const head = remoteHead(verifiedPointer, this.identity, verifiedObject.etag);\n const warning = await this.updateHistorySafely(commitClient, pointer);\n return { head, warnings: warning ? [warning] : [] };\n }\n\n async listHistory(signal?: AbortSignal): Promise<RemoteHistoryEntry[]> {\n const object = await new S3Client(this.config, signal).getJson<{\n version: number;\n snapshots: LatestPointer[];\n }>(historyKey(this.config));\n throwIfAborted(signal);\n if (object.missing) return [];\n const pointers = requireHistory(object.value, this.config.destination.namespace);\n for (const pointer of pointers) {\n const known = this.checksums.get(pointer.snapshot);\n if (known && known !== pointer.sha256) {\n throw new Error(\"Remote history conflicts with an already observed snapshot checksum.\");\n }\n }\n for (const pointer of pointers) this.registerChecksum(pointer.snapshot, pointer.sha256);\n return pointers.map(remoteHistoryEntry);\n }\n\n async diagnose(signal?: AbortSignal): Promise<BackendDiagnostic[]> {\n throwIfAborted(signal);\n const diagnostics: BackendDiagnostic[] = [\n {\n key: \"s3-config\",\n level: \"info\",\n message: `s3 config: ok (${this.config.destination.bucket}/${storageRoot(this.config)})`,\n },\n ...sessionTokenWarnings(this.config.profile).map((message) => ({\n key: \"s3-session-token\",\n level: \"warning\" as const,\n message,\n })),\n ];\n const deadline = AbortSignal.timeout(10_000);\n const probeSignal = signal ? AbortSignal.any([signal, deadline]) : deadline;\n try {\n const result = await new S3Client(this.config, probeSignal).diagnoseRead(latestKey(this.config));\n throwIfAborted(probeSignal);\n const messages = {\n readable: \"s3 remote read: HTTP success. Snapshot contents and write access are not tested.\",\n \"missing-key\":\n \"s3 remote read: no snapshot at this path (NoSuchKey). Write access is not tested; verify the bucket and path before first sync.\",\n \"missing-bucket\":\n \"s3 remote read: bucket not found (NoSuchBucket). Create the bucket with your provider or edit the setup's bucket name.\",\n \"unknown-404\":\n \"s3 remote read: HTTP 404; cannot confirm whether the bucket or snapshot is missing. Verify the endpoint, bucket, and path with your provider. Write access is not tested.\",\n };\n diagnostics.push({\n key: \"s3-read\",\n level: result === \"readable\" ? \"info\" : \"warning\",\n message: messages[result],\n });\n } catch (error) {\n throwIfAborted(signal);\n diagnostics.push({\n key: \"s3-read\",\n level: \"warning\",\n message: syncErrorGuidance(deadline.aborted ? new Error(\"S3 diagnostic request timed out.\") : error),\n });\n }\n return diagnostics;\n }\n\n private async resolveChecksum(reference: string, signal?: AbortSignal) {\n await this.readHead(signal);\n const headChecksum = this.checksums.get(reference);\n if (headChecksum) return headChecksum;\n await this.listHistory(signal);\n return this.checksums.get(reference);\n }\n\n private registerChecksum(reference: string, checksum: string) {\n const known = this.checksums.get(reference);\n if (known && known !== checksum) {\n throw new Error(\"Remote snapshot reference was rebound to a different checksum.\");\n }\n this.checksums.set(reference, checksum);\n }\n\n private async updateHistorySafely(client: S3Client, pointer: LatestPointer) {\n try {\n await this.updateHistory(client, pointer);\n return undefined;\n } catch (error) {\n return `Remote snapshot is active, but history could not be updated: ${errorMessage(error)}. Run /sync doctor before relying on history.`;\n }\n }\n\n private async updateHistory(client: S3Client, pointer: LatestPointer) {\n const object = await client.getJson<{ version: number; snapshots: LatestPointer[] }>(historyKey(this.config));\n const snapshots = object.missing ? [] : requireHistory(object.value, this.config.destination.namespace);\n const existing = snapshots.find((snapshot) => snapshot.snapshot === pointer.snapshot);\n if (existing) {\n if (!samePointer(existing, pointer)) throw new Error(\"Remote history rebound an immutable snapshot reference.\");\n return;\n }\n const next = [...snapshots, pointer].slice(-100);\n const condition = object.missing ? { ifAbsent: true } : { ifMatch: requireS3Etag(object.etag) };\n await client.putJson(historyKey(this.config), { version: VERSION, snapshots: next }, condition);\n }\n}\n\nexport function latestKey(config: ResolvedS3Backend) {\n return posixJoin(storageRoot(config), \"latest.json\");\n}\n\nexport function historyKey(config: ResolvedS3Backend) {\n return posixJoin(storageRoot(config), \"history.json\");\n}\n\nexport function snapshotKey(config: ResolvedS3Backend, id: string) {\n requireSnapshotReference(id);\n return posixJoin(storageRoot(config), \"snapshots\", `${id}.json.gz`);\n}\n\nexport function storageRoot(config: ResolvedS3Backend) {\n return config.destination.prefix === \"./\" ? \"\" : config.destination.prefix;\n}\n\nexport function pointerFor(config: ResolvedS3Backend, snapshot: Snapshot, checksum: string): LatestPointer {\n return createLatestPointer(config.destination.namespace, snapshot, checksum);\n}\n\nexport function s3BackendIdentity(config: ResolvedS3Backend) {\n const destination = JSON.stringify([\n secretFreeEndpoint(config.profile.endpoint),\n trimSlashes(config.destination.bucket),\n trimSlashes(config.destination.prefix),\n ]);\n return `s3:${sha256(Buffer.from(destination))}`;\n}\n\nfunction s3Destination(config: ResolvedS3Backend) {\n let host = secretFreeEndpoint(config.profile.endpoint);\n try {\n host = new URL(host).hostname;\n } catch {\n host = \"invalid S3 endpoint\";\n }\n return `${host} \u00B7 ${config.destination.bucket}/${storageRoot(config)}`;\n}\n\nfunction secretFreeEndpoint(value: string) {\n const normalized = value.trim();\n try {\n const url = new URL(normalized);\n url.username = \"\";\n url.password = \"\";\n return url.toString();\n } catch {\n return normalized.replace(/\\/\\/[^/@\\s]+@/u, \"//\");\n }\n}\n\nfunction trimSlashes(value: string) {\n return value.replace(/^\\/+|\\/+$/g, \"\");\n}\n\nfunction remoteHead(pointer: LatestPointer, identity: string, etag?: string): RemoteHead {\n return {\n snapshotRef: pointer.snapshot,\n snapshotId: pointer.snapshot,\n revision: `s3:${sha256(Buffer.from(canonicalJson([identity, etag ?? null, pointer])))}`,\n createdAt: pointer.createdAt,\n machine: pointer.machine,\n syncSessions: pointer.syncSessions === true,\n ...(pointer.selection === undefined ? {} : { selection: pointer.selection }),\n };\n}\n\nfunction samePointer(left: LatestPointer, right: LatestPointer) {\n return canonicalJson(left) === canonicalJson(right);\n}\n\nfunction canonicalJson(value: unknown) {\n return JSON.stringify(canonicalValue(value));\n}\n\nfunction canonicalValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalValue);\n if (!value || typeof value !== \"object\") return value;\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, canonicalValue((value as Record<string, unknown>)[key])]),\n );\n}\n\nfunction matchesExpected(head: RemoteHead | undefined, expected: ExpectedRemoteHead) {\n if (expected.kind === \"missing\") return head === undefined;\n return head?.revision === expected.revision;\n}\n\nfunction requirePointer(value: LatestPointer | undefined, message: string, expectedProfile: string) {\n if (\n !value ||\n value.version !== VERSION ||\n value.profile !== expectedProfile ||\n typeof value.snapshot !== \"string\" ||\n !isSafeSnapshotReference(value.snapshot) ||\n typeof value.sha256 !== \"string\" ||\n !/^[0-9a-f]{64}$/.test(value.sha256) ||\n typeof value.createdAt !== \"string\" ||\n !isSafeMetadata(value.createdAt, 64) ||\n typeof value.machine !== \"string\" ||\n !isSafeMetadata(value.machine, 256) ||\n (value.syncSessions !== undefined && typeof value.syncSessions !== \"boolean\")\n ) {\n throw new Error(message);\n }\n if (value.selection !== undefined) portableSnapshotSelection(value.selection);\n return value;\n}\n\nfunction requireHistory(value: { version: number; snapshots: LatestPointer[] } | undefined, expectedProfile: string) {\n if (!value || value.version !== VERSION || !Array.isArray(value.snapshots)) {\n throw new Error(\"Remote history is malformed.\");\n }\n const pointers = value.snapshots.map((pointer) =>\n requirePointer(pointer, \"Remote history entry is malformed.\", expectedProfile),\n );\n const references = new Set<string>();\n for (const pointer of pointers) {\n if (references.has(pointer.snapshot)) {\n throw new Error(\"Remote history contains duplicate snapshot references.\");\n }\n references.add(pointer.snapshot);\n }\n return pointers;\n}\n\nfunction assertSnapshotIdentity(snapshot: Snapshot, expectedProfile: string) {\n validatePortableSnapshot(snapshot);\n if (\n snapshot.profile !== expectedProfile ||\n !isSafeSnapshotReference(snapshot.id) ||\n !isSafeMetadata(snapshot.createdAt, 64) ||\n !isSafeMetadata(snapshot.machine, 256) ||\n !Array.isArray(snapshot.files)\n ) {\n throw new Error(\"Invalid snapshot identity for S3 publication.\");\n }\n}\n\nfunction validateSnapshotBundle(snapshot: Snapshot) {\n const paths = new Set<string>();\n for (const file of snapshot.files) {\n if (\n !file ||\n typeof file.path !== \"string\" ||\n typeof file.contentBase64 !== \"string\" ||\n typeof file.sha256 !== \"string\" ||\n !/^[0-9a-f]{64}$/.test(file.sha256) ||\n paths.has(file.path)\n ) {\n throw new Error(\"Remote snapshot bundle is malformed.\");\n }\n const content = Buffer.from(file.contentBase64, \"base64\");\n if (content.toString(\"base64\") !== file.contentBase64 || sha256(content) !== file.sha256) {\n throw new Error(\"Remote snapshot file checksum mismatch.\");\n }\n paths.add(file.path);\n }\n}\n\nfunction assertSafeDestination(config: ResolvedS3Backend) {\n for (const [label, value, allowEmpty] of [\n [\"bucket\", config.destination.bucket, false],\n [\"prefix\", config.destination.prefix, true],\n [\"namespace\", config.destination.namespace, false],\n ] as const) {\n if (label === \"prefix\" && value === \"./\") continue;\n if (\n (!allowEmpty && value.length === 0) ||\n value.includes(\"\\\\\") ||\n hasControlCharacter(value) ||\n value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n ) {\n throw new Error(`Invalid S3 storage location ${label}.`);\n }\n }\n}\n\nfunction requireSnapshotReference(reference: string) {\n if (!isSafeSnapshotReference(reference)) {\n throw new Error(\"Invalid S3 snapshot reference.\");\n }\n}\n\nfunction isSafeSnapshotReference(reference: string) {\n return (\n reference.length > 0 &&\n reference.length <= 512 &&\n reference !== \".\" &&\n reference !== \"..\" &&\n !reference.includes(\"/\") &&\n !reference.includes(\"\\\\\") &&\n !hasControlCharacter(reference)\n );\n}\n\nfunction isSafeMetadata(value: string, maxLength: number) {\n return value.length > 0 && value.length <= maxLength && !hasControlCharacter(value);\n}\n\nfunction hasControlCharacter(value: string) {\n return [...value].some((character) => {\n const code = character.codePointAt(0) ?? 0;\n return code < 0x20 || code === 0x7f;\n });\n}\n\nfunction sha256(value: Buffer) {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction errorMessage(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport { encodeKey };\n", "import { createHash, createHmac } from \"node:crypto\";\nimport { setTimeout as sleep } from \"node:timers/promises\";\nimport { encodeKey, posixJoin } from \"../../paths.js\";\nimport { retryAfter } from \"../../sync/continuous-errors.js\";\nimport type { RemoteObject, ResolvedS3Backend } from \"../backend-types.js\";\n\nconst MAX_JSON_RESPONSE_BYTES = 1024 * 1024;\nconst MAX_SNAPSHOT_RESPONSE_BYTES = 256 * 1024 * 1024;\nconst MAX_ERROR_RESPONSE_BYTES = 64 * 1024;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n\nfunction iso8601Basic(date: Date) {\n return date.toISOString().replace(/[:-]|\\.\\d{3}/g, \"\");\n}\n\nfunction isCloudflareR2Endpoint(endpoint: string | undefined) {\n const value = endpoint?.trim();\n if (!value) return false;\n try {\n const hostname = new URL(value).hostname.toLowerCase();\n return hostname === \"r2.cloudflarestorage.com\" || hostname.endsWith(\".r2.cloudflarestorage.com\");\n } catch {\n return false;\n }\n}\n\nexport class S3ObjectAlreadyExistsError extends Error {\n constructor(readonly key: string) {\n super(`S3 object already exists: ${key}`);\n this.name = \"S3ObjectAlreadyExistsError\";\n }\n}\n\nexport class S3HttpError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly retryAfterMs?: number,\n ) {\n super(message);\n this.name = \"S3HttpError\";\n }\n}\n\nexport class S3Client {\n private config: ResolvedS3Backend;\n private endpoint: URL;\n private signal?: AbortSignal;\n private requestTimeoutMs: number;\n private omitSessionTokenAfterRejection = false;\n\n constructor(config: ResolvedS3Backend, signal?: AbortSignal, requestTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) {\n this.config = config;\n this.endpoint = new URL(config.profile.endpoint);\n this.signal = signal;\n this.requestTimeoutMs = requestTimeoutMs;\n }\n\n /** Read-only access probe. A bare 404 cannot distinguish a missing key from a missing bucket. */\n async diagnoseRead(key: string): Promise<\"readable\" | \"missing-key\" | \"missing-bucket\" | \"unknown-404\"> {\n this.signal?.throwIfAborted();\n const response = await this.request(\"GET\", key);\n if (response.ok) {\n await response.body?.cancel();\n this.signal?.throwIfAborted();\n return \"readable\";\n }\n const detail = await this.readErrorText(response);\n this.signal?.throwIfAborted();\n if (response.status === 404) {\n const code = /<Code>\\s*([A-Za-z]+)\\s*<\\/Code>/u.exec(detail)?.[1];\n if (code === \"NoSuchBucket\") return \"missing-bucket\";\n if (code === \"NoSuchKey\") return \"missing-key\";\n return \"unknown-404\";\n }\n throw new S3HttpError(`S3 remote read failed (HTTP ${response.status}).`, response.status);\n }\n\n async getJson<T>(key: string): Promise<RemoteObject<T>> {\n const maxAttempts = 3;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const object = await this.request(\"GET\", key);\n if (object.status === 404) return { missing: true };\n if (!object.ok) {\n throw new S3HttpError(\n `S3 GET failed (${object.status}): ${await this.readErrorText(object)}`,\n object.status,\n retryAfter(object),\n );\n }\n const body = await readBoundedText(object, MAX_JSON_RESPONSE_BYTES, \"S3 JSON response\");\n // R2 can intermittently return an empty 200 body (read-after-write\n // inconsistency on a long-lived keep-alive connection), which makes\n // response.json() throw \"JSON Parse error: Unexpected EOF\" under Bun.\n // Retry so the transient blip is absorbed instead of surfacing as a\n // \"pi-sync auto sync skipped\" warning on every session start.\n if (body.length > 0) {\n return {\n value: JSON.parse(body) as T,\n etag: normalizeEtag(object.headers.get(\"etag\")),\n missing: false,\n };\n }\n lastError = new Error(`S3 GET returned an empty body for ${key}`);\n if (attempt < maxAttempts) {\n await sleep(250 * attempt, undefined, { signal: this.signal });\n }\n }\n throw lastError;\n }\n\n async getBuffer(key: string): Promise<RemoteObject<Buffer>> {\n const maxAttempts = 3;\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const object = await this.request(\"GET\", key);\n if (object.status === 404) return { missing: true };\n if (!object.ok) {\n throw new S3HttpError(\n `S3 GET failed (${object.status}): ${await this.readErrorText(object)}`,\n object.status,\n retryAfter(object),\n );\n }\n const buffer = await readBoundedBuffer(object, MAX_SNAPSHOT_RESPONSE_BYTES, \"S3 snapshot response\");\n // R2 can intermittently return an empty 200 body on a long-lived\n // keep-alive connection (same root cause as the getJson retry\n // above). getBuffer is only used for snapshot .json.gz payloads,\n // which are always non-empty, so an empty body is a transient\n // blip, not a legitimate response. Retry so the checksum guard\n // downstream doesn't surface it as \"Remote snapshot checksum\n // mismatch\".\n if (buffer.length > 0) {\n return { value: buffer, etag: normalizeEtag(object.headers.get(\"etag\")), missing: false };\n }\n lastError = new Error(`S3 GET returned an empty body for ${key}`);\n if (attempt < maxAttempts) {\n await sleep(250 * attempt, undefined, { signal: this.signal });\n }\n }\n throw lastError;\n }\n\n async putJson(key: string, value: unknown, options: { ifAbsent?: boolean; ifMatch?: string } = {}) {\n const body = Buffer.from(JSON.stringify(value, null, \"\\t\"), \"utf8\");\n await this.putBuffer(key, body, \"application/json\", options);\n }\n\n async putBuffer(\n key: string,\n body: Buffer,\n contentType: string,\n options: { ifAbsent?: boolean; ifMatch?: string } = {},\n ) {\n const headers: Record<string, string> = { \"content-type\": contentType };\n if (options.ifAbsent) headers[\"if-none-match\"] = \"*\";\n if (options.ifMatch) headers[\"if-match\"] = options.ifMatch;\n const response = await this.request(\"PUT\", key, body, headers);\n if ((options.ifAbsent || options.ifMatch) && (response.status === 412 || response.status === 409)) {\n await response.body?.cancel();\n if (options.ifAbsent && response.status === 412) throw new S3ObjectAlreadyExistsError(key);\n if (options.ifAbsent || options.ifMatch) {\n throw new S3HttpError(`S3 conditional PUT rejected (${response.status}).`, response.status);\n }\n }\n if (!response.ok) {\n throw new S3HttpError(\n `S3 PUT failed (${response.status}): ${await this.readErrorText(response)}`,\n response.status,\n retryAfter(response),\n );\n }\n await response.body?.cancel();\n }\n\n async delete(key: string) {\n const response = await this.request(\"DELETE\", key);\n if (!response.ok && response.status !== 404) {\n throw new S3HttpError(\n `S3 DELETE failed (${response.status}): ${await this.readErrorText(response)}`,\n response.status,\n retryAfter(response),\n );\n }\n await response.body?.cancel();\n }\n\n private async request(\n method: \"GET\" | \"PUT\" | \"DELETE\",\n key: string,\n body?: Buffer,\n extraHeaders: Record<string, string> = {},\n ) {\n const url = new URL(this.endpoint.toString());\n url.pathname = posixJoin(url.pathname, this.config.destination.bucket, encodeKey(key));\n const send = async (sessionToken: string | undefined) => {\n const transportSignal = this.transportSignal();\n const headers = await signedHeaders({\n method,\n url,\n body,\n // Transfer compression can weaken an object's ETag (R2 JSON responses).\n // Read the original representation for exact checksums and strong If-Match tokens.\n extraHeaders: method === \"GET\" ? { ...extraHeaders, \"accept-encoding\": \"identity\" } : extraHeaders,\n accessKeyId: this.config.profile.accessKeyId,\n secretAccessKey: this.config.profile.secretAccessKey,\n sessionToken,\n region: this.config.profile.region,\n });\n try {\n return await fetch(url, {\n method,\n headers,\n body: body ? new Uint8Array(body) : undefined,\n signal: transportSignal,\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") throw error;\n if (error instanceof Error && error.name === \"TimeoutError\") {\n throw new Error(\"S3 request timed out.\", { cause: error });\n }\n throw new Error(`S3 request failed: ${this.redact(errorMessage(error))}`, { cause: error });\n }\n };\n const sessionToken = this.omitSessionTokenAfterRejection ? undefined : this.config.profile.sessionToken;\n const response = await send(sessionToken);\n try {\n if (!(await this.shouldRetryWithoutSessionToken(response, sessionToken))) return response;\n } catch (error) {\n await response.body?.cancel().catch(() => undefined);\n throw error;\n }\n await response.body?.cancel();\n const retry = await send(undefined);\n if (retry.ok || retry.status === 404) this.omitSessionTokenAfterRejection = true;\n return retry;\n }\n\n private transportSignal() {\n const timeout = AbortSignal.timeout(this.requestTimeoutMs);\n return this.signal ? AbortSignal.any([this.signal, timeout]) : timeout;\n }\n\n private async shouldRetryWithoutSessionToken(response: Response, sessionToken: string | undefined) {\n if (\n !sessionToken ||\n !isCloudflareR2Endpoint(this.config.profile.endpoint) ||\n response.ok ||\n response.status !== 400\n ) {\n return false;\n }\n return isSecurityTokenInvalidArgument(\n await readBoundedText(response.clone(), MAX_ERROR_RESPONSE_BYTES, \"S3 error response\"),\n );\n }\n\n private async readErrorText(response: Response) {\n try {\n return this.redact(await readBoundedText(response, MAX_ERROR_RESPONSE_BYTES, \"S3 error response\"));\n } catch (error) {\n return this.redact(errorMessage(error));\n }\n }\n\n private redact(value: string) {\n let redacted = value;\n let endpointUsername: string | undefined;\n let endpointPassword: string | undefined;\n let endpointQueryValues: string[] = [];\n try {\n const endpoint = new URL(this.config.profile.endpoint);\n endpointUsername = endpoint.username;\n endpointPassword = endpoint.password;\n endpointQueryValues = [...endpoint.searchParams.values()];\n } catch {\n // The constructor already validates normal runtime endpoints.\n }\n for (const secret of [\n this.config.profile.accessKeyId,\n this.config.profile.secretAccessKey,\n this.config.profile.sessionToken,\n endpointUsername,\n endpointPassword,\n ...endpointQueryValues,\n ]) {\n if (secret) redacted = redacted.replaceAll(secret, \"[REDACTED]\");\n }\n return redacted;\n }\n}\n\nasync function readBoundedText(response: Response, limit: number, label: string) {\n return (await readBoundedBuffer(response, limit, label)).toString(\"utf8\");\n}\n\nasync function readBoundedBuffer(response: Response, limit: number, label: string) {\n const contentLength = Number(response.headers.get(\"content-length\"));\n if (Number.isFinite(contentLength) && contentLength > limit) {\n // Do not await cancellation of a cloned stream before its sibling can be released.\n void response.body?.cancel().catch(() => undefined);\n throw new Error(`${label} exceeds the ${limit}-byte limit.`);\n }\n if (!response.body) return Buffer.alloc(0);\n const reader = response.body.getReader();\n const chunks: Buffer[] = [];\n let total = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > limit) {\n void reader.cancel().catch(() => undefined);\n throw new Error(`${label} exceeds the ${limit}-byte limit.`);\n }\n chunks.push(Buffer.from(value));\n }\n } finally {\n reader.releaseLock();\n }\n return Buffer.concat(chunks, total);\n}\n\nfunction errorMessage(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n\nasync function signedHeaders(input: {\n method: string;\n url: URL;\n body?: Buffer;\n extraHeaders: Record<string, string>;\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string;\n region: string;\n}) {\n const now = new Date();\n const amzDate = iso8601Basic(now);\n const dateStamp = amzDate.slice(0, 8);\n const payloadHash = sha256(input.body ?? Buffer.alloc(0));\n const headers: Record<string, string> = {\n ...lowercaseKeys(input.extraHeaders),\n host: input.url.host,\n \"x-amz-content-sha256\": payloadHash,\n \"x-amz-date\": amzDate,\n };\n if (input.sessionToken) headers[\"x-amz-security-token\"] = input.sessionToken;\n const signedHeaderNames = Object.keys(headers).sort();\n const canonicalHeaders = signedHeaderNames.map((name) => `${name}:${headers[name]?.trim()}\\n`).join(\"\");\n const canonicalRequest = [\n input.method,\n input.url.pathname,\n input.url.searchParams.toString(),\n canonicalHeaders,\n signedHeaderNames.join(\";\"),\n payloadHash,\n ].join(\"\\n\");\n const scope = `${dateStamp}/${input.region}/s3/aws4_request`;\n const stringToSign = [\"AWS4-HMAC-SHA256\", amzDate, scope, sha256(Buffer.from(canonicalRequest))].join(\"\\n\");\n const signingKey = hmac(\n hmac(hmac(hmac(Buffer.from(`AWS4${input.secretAccessKey}`), dateStamp), input.region), \"s3\"),\n \"aws4_request\",\n );\n const signature = createHmac(\"sha256\", signingKey).update(stringToSign).digest(\"hex\");\n return {\n ...headers,\n authorization: `AWS4-HMAC-SHA256 Credential=${input.accessKeyId}/${scope}, SignedHeaders=${signedHeaderNames.join(\";\")}, Signature=${signature}`,\n };\n}\n\nfunction hmac(key: Buffer, value: string) {\n return createHmac(\"sha256\", key).update(value).digest();\n}\n\nfunction sha256(value: Buffer) {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction lowercaseKeys(value: Record<string, string>) {\n return Object.fromEntries(Object.entries(value).map(([key, item]) => [key.toLowerCase(), item]));\n}\n\nfunction normalizeEtag(value: string | null) {\n return value ?? undefined;\n}\n\nfunction isSecurityTokenInvalidArgument(text: string) {\n return text.includes(\"<Code>InvalidArgument</Code>\") && text.includes(\"<Message>X-Amz-Security-Token</Message>\");\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { posixJoin } from \"../../paths.js\";\nimport type { ResolvedS3Backend } from \"../backend-types.js\";\nimport { S3Client, S3HttpError, S3ObjectAlreadyExistsError } from \"./s3-client.js\";\n\nexport function requireS3Etag(value: string | undefined) {\n if (!value || !/^\"[^\"\\r\\n]+\"$/u.test(value)) throw new Error(\"S3 conditional publication requires a strong ETag.\");\n return value;\n}\n\n/** Never probe the active pointer or immutable snapshots; ignored conditions must not corrupt either. */\nexport async function verifyS3Conditions(config: ResolvedS3Backend, signal?: AbortSignal) {\n const key = posixJoin(\n config.destination.prefix === \"./\" ? \"\" : config.destination.prefix,\n \".pi-sync-probes\",\n randomUUID(),\n );\n const client = new S3Client(config, signal);\n let failure: unknown;\n let attempted = false;\n try {\n signal?.throwIfAborted();\n attempted = true;\n await client.putBuffer(key, Buffer.from(\"first\"), \"text/plain\", { ifAbsent: true });\n const first = await client.getBuffer(key);\n const etag = requireS3Etag(first.etag);\n if (!first.value?.equals(Buffer.from(\"first\"))) throw new Error(\"S3 conditional probe read did not match.\");\n await expectRejected(client.putBuffer(key, Buffer.from(\"ignored\"), \"text/plain\", { ifAbsent: true }));\n await expectRejected(client.putBuffer(key, Buffer.from(\"ignored\"), \"text/plain\", { ifMatch: '\"pi-sync-stale\"' }));\n const unchanged = await client.getBuffer(key);\n if (!unchanged.value?.equals(first.value) || unchanged.etag !== etag)\n throw new Error(\"S3 failed precondition changed the probe.\");\n await client.putBuffer(key, Buffer.from(\"second\"), \"text/plain\", { ifMatch: etag });\n const second = await client.getBuffer(key);\n if (!second.value?.equals(Buffer.from(\"second\")) || requireS3Etag(second.etag) === etag) {\n throw new Error(\"S3 conditional write did not rotate the probe ETag.\");\n }\n await expectRejected(client.putBuffer(key, Buffer.from(\"ignored\"), \"text/plain\", { ifMatch: etag }));\n const final = await client.getBuffer(key);\n if (!final.value?.equals(second.value) || final.etag !== second.etag)\n throw new Error(\"S3 stale ETag changed the probe.\");\n signal?.throwIfAborted();\n } catch (error) {\n failure = error;\n }\n // Cleanup has its own bounded deadline even when the owning session was cancelled.\n if (attempted) {\n try {\n await new S3Client(config, AbortSignal.timeout(10_000)).delete(key);\n } catch (error) {\n throw new Error(`S3 probe cleanup failed; remove ${key}.`, { cause: failure ?? error });\n }\n }\n if (failure) throw failure;\n signal?.throwIfAborted();\n}\n\nasync function expectRejected(operation: Promise<void>) {\n try {\n await operation;\n } catch (error) {\n // 409 is retryable contention, not proof that a failed condition was enforced.\n if (error instanceof S3ObjectAlreadyExistsError || (error instanceof S3HttpError && error.status === 412)) return;\n throw error;\n }\n throw new Error(\"S3 server ignored a write precondition; publication stopped for safety.\");\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,cAAAA,mBAAkB;;;ACA3B,SAAS,YAAY,kBAAkB;AACvC,SAAS,cAAc,aAAa;AAKpC,IAAM,0BAA0B,OAAO;AACvC,IAAM,8BAA8B,MAAM,OAAO;AACjD,IAAM,2BAA2B,KAAK;AACtC,IAAM,6BAA6B;AAEnC,SAAS,aAAa,MAAY;AAChC,SAAO,KAAK,YAAY,EAAE,QAAQ,iBAAiB,EAAE;AACvD;AAEA,SAAS,uBAAuB,UAA8B;AAC5D,QAAM,QAAQ,UAAU,KAAK;AAC7B,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,KAAK,EAAE,SAAS,YAAY;AACrD,WAAO,aAAa,8BAA8B,SAAS,SAAS,2BAA2B;AAAA,EACjG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,6BAAN,cAAyC,MAAM;AAAA,EACpD,YAAqB,KAAa;AAChC,UAAM,6BAA6B,GAAG,EAAE;AADrB;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAEO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YACE,SACS,QACA,cACT;AACA,UAAM,OAAO;AAHJ;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EALW;AAAA,EACA;AAKb;AAEO,IAAM,WAAN,MAAe;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iCAAiC;AAAA,EAEzC,YAAY,QAA2B,QAAsB,mBAAmB,4BAA4B;AAC1G,SAAK,SAAS;AACd,SAAK,WAAW,IAAI,IAAI,OAAO,QAAQ,QAAQ;AAC/C,SAAK,SAAS;AACd,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAGA,MAAM,aAAa,KAAqF;AACtG,SAAK,QAAQ,eAAe;AAC5B,UAAM,WAAW,MAAM,KAAK,QAAQ,OAAO,GAAG;AAC9C,QAAI,SAAS,IAAI;AACf,YAAM,SAAS,MAAM,OAAO;AAC5B,WAAK,QAAQ,eAAe;AAC5B,aAAO;AAAA,IACT;AACA,UAAM,SAAS,MAAM,KAAK,cAAc,QAAQ;AAChD,SAAK,QAAQ,eAAe;AAC5B,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,OAAO,mCAAmC,KAAK,MAAM,IAAI,CAAC;AAChE,UAAI,SAAS,eAAgB,QAAO;AACpC,UAAI,SAAS,YAAa,QAAO;AACjC,aAAO;AAAA,IACT;AACA,UAAM,IAAI,YAAY,+BAA+B,SAAS,MAAM,MAAM,SAAS,MAAM;AAAA,EAC3F;AAAA,EAEA,MAAM,QAAW,KAAuC;AACtD,UAAM,cAAc;AACpB,QAAI;AACJ,aAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,YAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,GAAG;AAC5C,UAAI,OAAO,WAAW,IAAK,QAAO,EAAE,SAAS,KAAK;AAClD,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI;AAAA,UACR,kBAAkB,OAAO,MAAM,MAAM,MAAM,KAAK,cAAc,MAAM,CAAC;AAAA,UACrE,OAAO;AAAA,UACP,WAAW,MAAM;AAAA,QACnB;AAAA,MACF;AACA,YAAM,OAAO,MAAM,gBAAgB,QAAQ,yBAAyB,kBAAkB;AAMtF,UAAI,KAAK,SAAS,GAAG;AACnB,eAAO;AAAA,UACL,OAAO,KAAK,MAAM,IAAI;AAAA,UACtB,MAAM,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC;AAAA,UAC9C,SAAS;AAAA,QACX;AAAA,MACF;AACA,kBAAY,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAChE,UAAI,UAAU,aAAa;AACzB,cAAM,MAAM,MAAM,SAAS,QAAW,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,MAC/D;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAAA,EAEA,MAAM,UAAU,KAA4C;AAC1D,UAAM,cAAc;AACpB,QAAI;AACJ,aAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,YAAM,SAAS,MAAM,KAAK,QAAQ,OAAO,GAAG;AAC5C,UAAI,OAAO,WAAW,IAAK,QAAO,EAAE,SAAS,KAAK;AAClD,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI;AAAA,UACR,kBAAkB,OAAO,MAAM,MAAM,MAAM,KAAK,cAAc,MAAM,CAAC;AAAA,UACrE,OAAO;AAAA,UACP,WAAW,MAAM;AAAA,QACnB;AAAA,MACF;AACA,YAAM,SAAS,MAAM,kBAAkB,QAAQ,6BAA6B,sBAAsB;AAQlG,UAAI,OAAO,SAAS,GAAG;AACrB,eAAO,EAAE,OAAO,QAAQ,MAAM,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,GAAG,SAAS,MAAM;AAAA,MAC1F;AACA,kBAAY,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAChE,UAAI,UAAU,aAAa;AACzB,cAAM,MAAM,MAAM,SAAS,QAAW,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,MAC/D;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAAA,EAEA,MAAM,QAAQ,KAAa,OAAgB,UAAoD,CAAC,GAAG;AACjG,UAAM,OAAO,OAAO,KAAK,KAAK,UAAU,OAAO,MAAM,GAAI,GAAG,MAAM;AAClE,UAAM,KAAK,UAAU,KAAK,MAAM,oBAAoB,OAAO;AAAA,EAC7D;AAAA,EAEA,MAAM,UACJ,KACA,MACA,aACA,UAAoD,CAAC,GACrD;AACA,UAAM,UAAkC,EAAE,gBAAgB,YAAY;AACtE,QAAI,QAAQ,SAAU,SAAQ,eAAe,IAAI;AACjD,QAAI,QAAQ,QAAS,SAAQ,UAAU,IAAI,QAAQ;AACnD,UAAM,WAAW,MAAM,KAAK,QAAQ,OAAO,KAAK,MAAM,OAAO;AAC7D,SAAK,QAAQ,YAAY,QAAQ,aAAa,SAAS,WAAW,OAAO,SAAS,WAAW,MAAM;AACjG,YAAM,SAAS,MAAM,OAAO;AAC5B,UAAI,QAAQ,YAAY,SAAS,WAAW,IAAK,OAAM,IAAI,2BAA2B,GAAG;AACzF,UAAI,QAAQ,YAAY,QAAQ,SAAS;AACvC,cAAM,IAAI,YAAY,gCAAgC,SAAS,MAAM,MAAM,SAAS,MAAM;AAAA,MAC5F;AAAA,IACF;AACA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,kBAAkB,SAAS,MAAM,MAAM,MAAM,KAAK,cAAc,QAAQ,CAAC;AAAA,QACzE,SAAS;AAAA,QACT,WAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AACA,UAAM,SAAS,MAAM,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAM,OAAO,KAAa;AACxB,UAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,GAAG;AACjD,QAAI,CAAC,SAAS,MAAM,SAAS,WAAW,KAAK;AAC3C,YAAM,IAAI;AAAA,QACR,qBAAqB,SAAS,MAAM,MAAM,MAAM,KAAK,cAAc,QAAQ,CAAC;AAAA,QAC5E,SAAS;AAAA,QACT,WAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AACA,UAAM,SAAS,MAAM,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAc,QACZ,QACA,KACA,MACA,eAAuC,CAAC,GACxC;AACA,UAAM,MAAM,IAAI,IAAI,KAAK,SAAS,SAAS,CAAC;AAC5C,QAAI,WAAW,UAAU,IAAI,UAAU,KAAK,OAAO,YAAY,QAAQ,UAAU,GAAG,CAAC;AACrF,UAAM,OAAO,OAAOC,kBAAqC;AACvD,YAAM,kBAAkB,KAAK,gBAAgB;AAC7C,YAAM,UAAU,MAAM,cAAc;AAAA,QAClC;AAAA,QACA;AAAA,QACA;AAAA;AAAA;AAAA,QAGA,cAAc,WAAW,QAAQ,EAAE,GAAG,cAAc,mBAAmB,WAAW,IAAI;AAAA,QACtF,aAAa,KAAK,OAAO,QAAQ;AAAA,QACjC,iBAAiB,KAAK,OAAO,QAAQ;AAAA,QACrC,cAAAA;AAAA,QACA,QAAQ,KAAK,OAAO,QAAQ;AAAA,MAC9B,CAAC;AACD,UAAI;AACF,eAAO,MAAM,MAAM,KAAK;AAAA,UACtB;AAAA,UACA;AAAA,UACA,MAAM,OAAO,IAAI,WAAW,IAAI,IAAI;AAAA,UACpC,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,iBAAiB,SAAS,MAAM,SAAS,aAAc,OAAM;AACjE,YAAI,iBAAiB,SAAS,MAAM,SAAS,gBAAgB;AAC3D,gBAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,MAAM,CAAC;AAAA,QAC3D;AACA,cAAM,IAAI,MAAM,sBAAsB,KAAK,OAAO,aAAa,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,MAC5F;AAAA,IACF;AACA,UAAM,eAAe,KAAK,iCAAiC,SAAY,KAAK,OAAO,QAAQ;AAC3F,UAAM,WAAW,MAAM,KAAK,YAAY;AACxC,QAAI;AACF,UAAI,CAAE,MAAM,KAAK,+BAA+B,UAAU,YAAY,EAAI,QAAO;AAAA,IACnF,SAAS,OAAO;AACd,YAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACnD,YAAM;AAAA,IACR;AACA,UAAM,SAAS,MAAM,OAAO;AAC5B,UAAM,QAAQ,MAAM,KAAK,MAAS;AAClC,QAAI,MAAM,MAAM,MAAM,WAAW,IAAK,MAAK,iCAAiC;AAC5E,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB;AACxB,UAAM,UAAU,YAAY,QAAQ,KAAK,gBAAgB;AACzD,WAAO,KAAK,SAAS,YAAY,IAAI,CAAC,KAAK,QAAQ,OAAO,CAAC,IAAI;AAAA,EACjE;AAAA,EAEA,MAAc,+BAA+B,UAAoB,cAAkC;AACjG,QACE,CAAC,gBACD,CAAC,uBAAuB,KAAK,OAAO,QAAQ,QAAQ,KACpD,SAAS,MACT,SAAS,WAAW,KACpB;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,MAAM,gBAAgB,SAAS,MAAM,GAAG,0BAA0B,mBAAmB;AAAA,IACvF;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,UAAoB;AAC9C,QAAI;AACF,aAAO,KAAK,OAAO,MAAM,gBAAgB,UAAU,0BAA0B,mBAAmB,CAAC;AAAA,IACnG,SAAS,OAAO;AACd,aAAO,KAAK,OAAO,aAAa,KAAK,CAAC;AAAA,IACxC;AAAA,EACF;AAAA,EAEQ,OAAO,OAAe;AAC5B,QAAI,WAAW;AACf,QAAI;AACJ,QAAI;AACJ,QAAI,sBAAgC,CAAC;AACrC,QAAI;AACF,YAAM,WAAW,IAAI,IAAI,KAAK,OAAO,QAAQ,QAAQ;AACrD,yBAAmB,SAAS;AAC5B,yBAAmB,SAAS;AAC5B,4BAAsB,CAAC,GAAG,SAAS,aAAa,OAAO,CAAC;AAAA,IAC1D,QAAQ;AAAA,IAER;AACA,eAAW,UAAU;AAAA,MACnB,KAAK,OAAO,QAAQ;AAAA,MACpB,KAAK,OAAO,QAAQ;AAAA,MACpB,KAAK,OAAO,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,GAAG;AACD,UAAI,OAAQ,YAAW,SAAS,WAAW,QAAQ,YAAY;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;AAEA,eAAe,gBAAgB,UAAoB,OAAe,OAAe;AAC/E,UAAQ,MAAM,kBAAkB,UAAU,OAAO,KAAK,GAAG,SAAS,MAAM;AAC1E;AAEA,eAAe,kBAAkB,UAAoB,OAAe,OAAe;AACjF,QAAM,gBAAgB,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC;AACnE,MAAI,OAAO,SAAS,aAAa,KAAK,gBAAgB,OAAO;AAE3D,SAAK,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAClD,UAAM,IAAI,MAAM,GAAG,KAAK,gBAAgB,KAAK,cAAc;AAAA,EAC7D;AACA,MAAI,CAAC,SAAS,KAAM,QAAO,OAAO,MAAM,CAAC;AACzC,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,eAAS,MAAM;AACf,UAAI,QAAQ,OAAO;AACjB,aAAK,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC1C,cAAM,IAAI,MAAM,GAAG,KAAK,gBAAgB,KAAK,cAAc;AAAA,MAC7D;AACA,aAAO,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,IAChC;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACA,SAAO,OAAO,OAAO,QAAQ,KAAK;AACpC;AAEA,SAAS,aAAa,OAAgB;AACpC,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,eAAe,cAAc,OAS1B;AACD,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,UAAU,aAAa,GAAG;AAChC,QAAM,YAAY,QAAQ,MAAM,GAAG,CAAC;AACpC,QAAM,cAAc,OAAO,MAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AACxD,QAAM,UAAkC;AAAA,IACtC,GAAG,cAAc,MAAM,YAAY;AAAA,IACnC,MAAM,MAAM,IAAI;AAAA,IAChB,wBAAwB;AAAA,IACxB,cAAc;AAAA,EAChB;AACA,MAAI,MAAM,aAAc,SAAQ,sBAAsB,IAAI,MAAM;AAChE,QAAM,oBAAoB,OAAO,KAAK,OAAO,EAAE,KAAK;AACpD,QAAM,mBAAmB,kBAAkB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,CAAC;AAAA,CAAI,EAAE,KAAK,EAAE;AACtG,QAAM,mBAAmB;AAAA,IACvB,MAAM;AAAA,IACN,MAAM,IAAI;AAAA,IACV,MAAM,IAAI,aAAa,SAAS;AAAA,IAChC;AAAA,IACA,kBAAkB,KAAK,GAAG;AAAA,IAC1B;AAAA,EACF,EAAE,KAAK,IAAI;AACX,QAAM,QAAQ,GAAG,SAAS,IAAI,MAAM,MAAM;AAC1C,QAAM,eAAe,CAAC,oBAAoB,SAAS,OAAO,OAAO,OAAO,KAAK,gBAAgB,CAAC,CAAC,EAAE,KAAK,IAAI;AAC1G,QAAM,aAAa;AAAA,IACjB,KAAK,KAAK,KAAK,OAAO,KAAK,OAAO,MAAM,eAAe,EAAE,GAAG,SAAS,GAAG,MAAM,MAAM,GAAG,IAAI;AAAA,IAC3F;AAAA,EACF;AACA,QAAM,YAAY,WAAW,UAAU,UAAU,EAAE,OAAO,YAAY,EAAE,OAAO,KAAK;AACpF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,eAAe,+BAA+B,MAAM,WAAW,IAAI,KAAK,mBAAmB,kBAAkB,KAAK,GAAG,CAAC,eAAe,SAAS;AAAA,EAChJ;AACF;AAEA,SAAS,KAAK,KAAa,OAAe;AACxC,SAAO,WAAW,UAAU,GAAG,EAAE,OAAO,KAAK,EAAE,OAAO;AACxD;AAEA,SAAS,OAAO,OAAe;AAC7B,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AACxD;AAEA,SAAS,cAAc,OAA+B;AACpD,SAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,IAAI,CAAC,CAAC;AACjG;AAEA,SAAS,cAAc,OAAsB;AAC3C,SAAO,SAAS;AAClB;AAEA,SAAS,+BAA+B,MAAc;AACpD,SAAO,KAAK,SAAS,8BAA8B,KAAK,KAAK,SAAS,yCAAyC;AACjH;;;ACvYA,SAAS,kBAAkB;AAKpB,SAAS,cAAc,OAA2B;AACvD,MAAI,CAAC,SAAS,CAAC,iBAAiB,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,oDAAoD;AACjH,SAAO;AACT;AAGA,eAAsB,mBAAmB,QAA2B,QAAsB;AACxF,QAAM,MAAM;AAAA,IACV,OAAO,YAAY,WAAW,OAAO,KAAK,OAAO,YAAY;AAAA,IAC7D;AAAA,IACA,WAAW;AAAA,EACb;AACA,QAAM,SAAS,IAAI,SAAS,QAAQ,MAAM;AAC1C,MAAI;AACJ,MAAI,YAAY;AAChB,MAAI;AACF,YAAQ,eAAe;AACvB,gBAAY;AACZ,UAAM,OAAO,UAAU,KAAK,OAAO,KAAK,OAAO,GAAG,cAAc,EAAE,UAAU,KAAK,CAAC;AAClF,UAAM,QAAQ,MAAM,OAAO,UAAU,GAAG;AACxC,UAAM,OAAO,cAAc,MAAM,IAAI;AACrC,QAAI,CAAC,MAAM,OAAO,OAAO,OAAO,KAAK,OAAO,CAAC,EAAG,OAAM,IAAI,MAAM,0CAA0C;AAC1G,UAAM,eAAe,OAAO,UAAU,KAAK,OAAO,KAAK,SAAS,GAAG,cAAc,EAAE,UAAU,KAAK,CAAC,CAAC;AACpG,UAAM,eAAe,OAAO,UAAU,KAAK,OAAO,KAAK,SAAS,GAAG,cAAc,EAAE,SAAS,kBAAkB,CAAC,CAAC;AAChH,UAAM,YAAY,MAAM,OAAO,UAAU,GAAG;AAC5C,QAAI,CAAC,UAAU,OAAO,OAAO,MAAM,KAAK,KAAK,UAAU,SAAS;AAC9D,YAAM,IAAI,MAAM,2CAA2C;AAC7D,UAAM,OAAO,UAAU,KAAK,OAAO,KAAK,QAAQ,GAAG,cAAc,EAAE,SAAS,KAAK,CAAC;AAClF,UAAM,SAAS,MAAM,OAAO,UAAU,GAAG;AACzC,QAAI,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,KAAK,cAAc,OAAO,IAAI,MAAM,MAAM;AACvF,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AACA,UAAM,eAAe,OAAO,UAAU,KAAK,OAAO,KAAK,SAAS,GAAG,cAAc,EAAE,SAAS,KAAK,CAAC,CAAC;AACnG,UAAM,QAAQ,MAAM,OAAO,UAAU,GAAG;AACxC,QAAI,CAAC,MAAM,OAAO,OAAO,OAAO,KAAK,KAAK,MAAM,SAAS,OAAO;AAC9D,YAAM,IAAI,MAAM,kCAAkC;AACpD,YAAQ,eAAe;AAAA,EACzB,SAAS,OAAO;AACd,cAAU;AAAA,EACZ;AAEA,MAAI,WAAW;AACb,QAAI;AACF,YAAM,IAAI,SAAS,QAAQ,YAAY,QAAQ,GAAM,CAAC,EAAE,OAAO,GAAG;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,mCAAmC,GAAG,KAAK,EAAE,OAAO,WAAW,MAAM,CAAC;AAAA,IACxF;AAAA,EACF;AACA,MAAI,QAAS,OAAM;AACnB,UAAQ,eAAe;AACzB;AAEA,eAAe,eAAe,WAA0B;AACtD,MAAI;AACF,UAAM;AAAA,EACR,SAAS,OAAO;AAEd,QAAI,iBAAiB,8BAA+B,iBAAiB,eAAe,MAAM,WAAW,IAAM;AAC3G,UAAM;AAAA,EACR;AACA,QAAM,IAAI,MAAM,yEAAyE;AAC3F;;;AFzCA,IAAM,UAAU;AAChB,IAAM,yBAAyB;AAExB,IAAM,gBAAN,MAA2C;AAAA,EAOhD,YACmB,QACA,sBAAsB,wBACvC;AAFiB;AACA;AAEjB,0BAAsB,MAAM;AAC5B,SAAK,WAAW,kBAAkB,MAAM;AACxC,SAAK,cAAc,cAAc,MAAM;AAAA,EACzC;AAAA,EANmB;AAAA,EACA;AAAA,EARV;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACL,YAAY,oBAAI,IAAoB;AAAA,EAC7C;AAAA,EAWR,aAAa,MAAc,OAAe;AACxC,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,+BAA+B,SAAqB,UAAsB;AACxE,WACE,KAAK,aAAa,QAAQ,UAAU,SAAS,QAAQ,KACpD,QAAQ,eAAe,SAAS,cAC/B,QAAQ,gBAAgB,SAAS,eACjC,QAAQ,aAAa,KAAK,cAAc,WACxC,SAAS,aAAa,KAAK,cAAc;AAAA,EAE/C;AAAA,EAEA,MAAM,SAAS,QAAuD;AACpE,SAAK,eAAe;AACpB,UAAM,SAAS,MAAM,IAAI,SAAS,KAAK,QAAQ,MAAM,EAAE,QAAuB,UAAU,KAAK,MAAM,CAAC;AACpG,mBAAe,MAAM;AACrB,QAAI,OAAO,QAAS,QAAO;AAC3B,UAAM,UAAU;AAAA,MACd,OAAO;AAAA,MACP;AAAA,MACA,KAAK,OAAO,YAAY;AAAA,IAC1B;AACA,SAAK,iBAAiB,QAAQ,UAAU,QAAQ,MAAM;AACtD,UAAM,OAAO,WAAW,SAAS,KAAK,UAAU,OAAO,IAAI;AAC3D,QAAI,OAAO,QAAQ,iBAAiB,KAAK,OAAO,IAAI,GAAG;AAGrD,WAAK,eAAe;AAAA,QAClB,SAAS,KAAK;AAAA,QACd,QAAQ,WAAW,SAAS,KAAK,UAAU,KAAK,OAAO,IAAI,EAAE,EAAE;AAAA,MACjE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,WAAmB,QAAyC;AAC7E,UAAM,mBAAmB,KAAK,UAAU,IAAI,SAAS,KAAM,MAAM,KAAK,gBAAgB,WAAW,MAAM;AACvG,UAAM,SAAS,MAAM,IAAI,SAAS,KAAK,QAAQ,MAAM,EAAE,UAAU,YAAY,KAAK,QAAQ,SAAS,CAAC;AACpG,mBAAe,MAAM;AACrB,QAAI,CAAC,OAAO,MAAO,OAAM,IAAI,MAAM,uBAAuB,SAAS,EAAE;AACrE,QAAI,oBAAoBC,QAAO,OAAO,KAAK,MAAM,kBAAkB;AACjE,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,UAAM,WAAW,MAAM,eAAe,OAAO,OAAO,EAAE,OAAO,CAAC;AAC9D,QAAI,SAAS,OAAO,aAAa,SAAS,YAAY,KAAK,OAAO,YAAY,WAAW;AACvF,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,2BAAuB,QAAQ;AAC/B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,UACA,UACA,UAAkC,CAAC,GACH;AAChC,mBAAe,QAAQ,MAAM;AAC7B,2BAAuB,UAAU,KAAK,OAAO,YAAY,SAAS;AAClE,UAAM,mBAAmB,KAAK,QAAQ,QAAQ,MAAM;AACpD,mBAAe,QAAQ,MAAM;AAC7B,UAAM,YAAY,YAAY,KAAK,QAAQ,SAAS,EAAE;AACtD,UAAM,UAAU,MAAM,eAAe,QAAQ;AAC7C,mBAAe,QAAQ,MAAM;AAC7B,UAAM,UAAU,WAAW,KAAK,QAAQ,UAAUA,QAAO,OAAO,CAAC;AACjE,UAAM,oBAAoB,IAAI,SAAS,KAAK,QAAQ,QAAQ,MAAM;AAClE,QAAI;AACF,YAAM,kBAAkB,UAAU,WAAW,SAAS,oBAAoB;AAAA,QACxE,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,4BAA6B,OAAM;AAC1D,YAAM,WAAW,MAAM,kBAAkB,UAAU,SAAS;AAC5D,UAAI,CAAC,SAAS,SAASA,QAAO,SAAS,KAAK,MAAM,QAAQ,QAAQ;AAChE,cAAM,IAAI;AAAA,UACR,gEAAgE,SAAS,EAAE;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AACA,UAAM,gBAAgB,MAAM,kBAAkB,QAAuB,UAAU,KAAK,MAAM,CAAC;AAC3F,mBAAe,QAAQ,MAAM;AAC7B,QAAI;AACJ,QAAI,CAAC,cAAc,SAAS;AAC1B,YAAM,iBAAiB;AAAA,QACrB,cAAc;AAAA,QACd;AAAA,QACA,KAAK,OAAO,YAAY;AAAA,MAC1B;AACA,WAAK,iBAAiB,eAAe,UAAU,eAAe,MAAM;AACpE,gBAAU,WAAW,gBAAgB,KAAK,UAAU,cAAc,IAAI;AAAA,IACxE;AACA,QAAI,CAAC,gBAAgB,SAAS,QAAQ,GAAG;AACvC,YAAM,IAAI,yBAAyB,mEAAmE;AAAA,QACpG,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AACA,UAAM,YAAY,cAAc,UAAU,EAAE,UAAU,KAAK,IAAI,EAAE,SAAS,cAAc,cAAc,IAAI,EAAE;AAC5G,mBAAe,QAAQ,MAAM;AAC7B,YAAQ,WAAW;AAInB,UAAM,eAAe,IAAI,SAAS,KAAK,QAAQ,YAAY,QAAQ,KAAK,mBAAmB,CAAC;AAC5F,QAAI;AACF,YAAM,aAAa,QAAQ,UAAU,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,IACvE,SAAS,OAAO;AACd,UACE,iBAAiB,8BAChB,iBAAiB,gBAAgB,MAAM,WAAW,OAAO,MAAM,WAAW,MAC3E;AACA,cAAM,IAAI,yBAAyB,kEAAkE;AAAA,UACnG,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,YAAM,IAAI;AAAA,QACR,0CAA0CC,cAAa,KAAK,CAAC;AAAA,QAC7D,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,aAAa,QAAuB,UAAU,KAAK,MAAM,CAAC;AAAA,IACnF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,yEAAyEA,cAAa,KAAK,CAAC;AAAA,QAC5F,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,wBAAkB;AAAA,QAChB,eAAe;AAAA,QACf;AAAA,QACA,KAAK,OAAO,YAAY;AAAA,MAC1B;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,8EAA8EA,cAAa,KAAK,CAAC;AAAA,QACjG,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,QAAI,CAAC,YAAY,iBAAiB,OAAO,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,aAAa,WAAW,iBAAiB,KAAK,UAAU,eAAe,IAAI;AAAA,UAC3E,4BAA4B;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AACA,SAAK,iBAAiB,gBAAgB,UAAU,gBAAgB,MAAM;AACtE,UAAM,OAAO,WAAW,iBAAiB,KAAK,UAAU,eAAe,IAAI;AAC3E,UAAM,UAAU,MAAM,KAAK,oBAAoB,cAAc,OAAO;AACpE,WAAO,EAAE,MAAM,UAAU,UAAU,CAAC,OAAO,IAAI,CAAC,EAAE;AAAA,EACpD;AAAA,EAEA,MAAM,YAAY,QAAqD;AACrE,UAAM,SAAS,MAAM,IAAI,SAAS,KAAK,QAAQ,MAAM,EAAE,QAGpD,WAAW,KAAK,MAAM,CAAC;AAC1B,mBAAe,MAAM;AACrB,QAAI,OAAO,QAAS,QAAO,CAAC;AAC5B,UAAM,WAAW,eAAe,OAAO,OAAO,KAAK,OAAO,YAAY,SAAS;AAC/E,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,KAAK,UAAU,IAAI,QAAQ,QAAQ;AACjD,UAAI,SAAS,UAAU,QAAQ,QAAQ;AACrC,cAAM,IAAI,MAAM,sEAAsE;AAAA,MACxF;AAAA,IACF;AACA,eAAW,WAAW,SAAU,MAAK,iBAAiB,QAAQ,UAAU,QAAQ,MAAM;AACtF,WAAO,SAAS,IAAI,kBAAkB;AAAA,EACxC;AAAA,EAEA,MAAM,SAAS,QAAoD;AACjE,mBAAe,MAAM;AACrB,UAAM,cAAmC;AAAA,MACvC;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,SAAS,kBAAkB,KAAK,OAAO,YAAY,MAAM,IAAI,YAAY,KAAK,MAAM,CAAC;AAAA,MACvF;AAAA,MACA,GAAG,qBAAqB,KAAK,OAAO,OAAO,EAAE,IAAI,CAAC,aAAa;AAAA,QAC7D,KAAK;AAAA,QACL,OAAO;AAAA,QACP;AAAA,MACF,EAAE;AAAA,IACJ;AACA,UAAM,WAAW,YAAY,QAAQ,GAAM;AAC3C,UAAM,cAAc,SAAS,YAAY,IAAI,CAAC,QAAQ,QAAQ,CAAC,IAAI;AACnE,QAAI;AACF,YAAM,SAAS,MAAM,IAAI,SAAS,KAAK,QAAQ,WAAW,EAAE,aAAa,UAAU,KAAK,MAAM,CAAC;AAC/F,qBAAe,WAAW;AAC1B,YAAM,WAAW;AAAA,QACf,UAAU;AAAA,QACV,eACE;AAAA,QACF,kBACE;AAAA,QACF,eACE;AAAA,MACJ;AACA,kBAAY,KAAK;AAAA,QACf,KAAK;AAAA,QACL,OAAO,WAAW,aAAa,SAAS;AAAA,QACxC,SAAS,SAAS,MAAM;AAAA,MAC1B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,qBAAe,MAAM;AACrB,kBAAY,KAAK;AAAA,QACf,KAAK;AAAA,QACL,OAAO;AAAA,QACP,SAAS,kBAAkB,SAAS,UAAU,IAAI,MAAM,kCAAkC,IAAI,KAAK;AAAA,MACrG,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,gBAAgB,WAAmB,QAAsB;AACrE,UAAM,KAAK,SAAS,MAAM;AAC1B,UAAM,eAAe,KAAK,UAAU,IAAI,SAAS;AACjD,QAAI,aAAc,QAAO;AACzB,UAAM,KAAK,YAAY,MAAM;AAC7B,WAAO,KAAK,UAAU,IAAI,SAAS;AAAA,EACrC;AAAA,EAEQ,iBAAiB,WAAmB,UAAkB;AAC5D,UAAM,QAAQ,KAAK,UAAU,IAAI,SAAS;AAC1C,QAAI,SAAS,UAAU,UAAU;AAC/B,YAAM,IAAI,MAAM,gEAAgE;AAAA,IAClF;AACA,SAAK,UAAU,IAAI,WAAW,QAAQ;AAAA,EACxC;AAAA,EAEA,MAAc,oBAAoB,QAAkB,SAAwB;AAC1E,QAAI;AACF,YAAM,KAAK,cAAc,QAAQ,OAAO;AACxC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,gEAAgEA,cAAa,KAAK,CAAC;AAAA,IAC5F;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,QAAkB,SAAwB;AACpE,UAAM,SAAS,MAAM,OAAO,QAAyD,WAAW,KAAK,MAAM,CAAC;AAC5G,UAAM,YAAY,OAAO,UAAU,CAAC,IAAI,eAAe,OAAO,OAAO,KAAK,OAAO,YAAY,SAAS;AACtG,UAAM,WAAW,UAAU,KAAK,CAAC,aAAa,SAAS,aAAa,QAAQ,QAAQ;AACpF,QAAI,UAAU;AACZ,UAAI,CAAC,YAAY,UAAU,OAAO,EAAG,OAAM,IAAI,MAAM,yDAAyD;AAC9G;AAAA,IACF;AACA,UAAM,OAAO,CAAC,GAAG,WAAW,OAAO,EAAE,MAAM,IAAI;AAC/C,UAAM,YAAY,OAAO,UAAU,EAAE,UAAU,KAAK,IAAI,EAAE,SAAS,cAAc,OAAO,IAAI,EAAE;AAC9F,UAAM,OAAO,QAAQ,WAAW,KAAK,MAAM,GAAG,EAAE,SAAS,SAAS,WAAW,KAAK,GAAG,SAAS;AAAA,EAChG;AACF;AAEO,SAAS,UAAU,QAA2B;AACnD,SAAO,UAAU,YAAY,MAAM,GAAG,aAAa;AACrD;AAEO,SAAS,WAAW,QAA2B;AACpD,SAAO,UAAU,YAAY,MAAM,GAAG,cAAc;AACtD;AAEO,SAAS,YAAY,QAA2B,IAAY;AACjE,2BAAyB,EAAE;AAC3B,SAAO,UAAU,YAAY,MAAM,GAAG,aAAa,GAAG,EAAE,UAAU;AACpE;AAEO,SAAS,YAAY,QAA2B;AACrD,SAAO,OAAO,YAAY,WAAW,OAAO,KAAK,OAAO,YAAY;AACtE;AAEO,SAAS,WAAW,QAA2B,UAAoB,UAAiC;AACzG,SAAO,oBAAoB,OAAO,YAAY,WAAW,UAAU,QAAQ;AAC7E;AAEO,SAAS,kBAAkB,QAA2B;AAC3D,QAAM,cAAc,KAAK,UAAU;AAAA,IACjC,mBAAmB,OAAO,QAAQ,QAAQ;AAAA,IAC1C,YAAY,OAAO,YAAY,MAAM;AAAA,IACrC,YAAY,OAAO,YAAY,MAAM;AAAA,EACvC,CAAC;AACD,SAAO,MAAMD,QAAO,OAAO,KAAK,WAAW,CAAC,CAAC;AAC/C;AAEA,SAAS,cAAc,QAA2B;AAChD,MAAI,OAAO,mBAAmB,OAAO,QAAQ,QAAQ;AACrD,MAAI;AACF,WAAO,IAAI,IAAI,IAAI,EAAE;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO,GAAG,IAAI,SAAM,OAAO,YAAY,MAAM,IAAI,YAAY,MAAM,CAAC;AACtE;AAEA,SAAS,mBAAmB,OAAe;AACzC,QAAM,aAAa,MAAM,KAAK;AAC9B,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,UAAU;AAC9B,QAAI,WAAW;AACf,QAAI,WAAW;AACf,WAAO,IAAI,SAAS;AAAA,EACtB,QAAQ;AACN,WAAO,WAAW,QAAQ,kBAAkB,IAAI;AAAA,EAClD;AACF;AAEA,SAAS,YAAY,OAAe;AAClC,SAAO,MAAM,QAAQ,cAAc,EAAE;AACvC;AAEA,SAAS,WAAW,SAAwB,UAAkB,MAA2B;AACvF,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,YAAY,QAAQ;AAAA,IACpB,UAAU,MAAMA,QAAO,OAAO,KAAK,cAAc,CAAC,UAAU,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;AAAA,IACrF,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ,iBAAiB;AAAA,IACvC,GAAI,QAAQ,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,QAAQ,UAAU;AAAA,EAC5E;AACF;AAEA,SAAS,YAAY,MAAqB,OAAsB;AAC9D,SAAO,cAAc,IAAI,MAAM,cAAc,KAAK;AACpD;AAEA,SAAS,cAAc,OAAgB;AACrC,SAAO,KAAK,UAAU,eAAe,KAAK,CAAC;AAC7C;AAEA,SAAS,eAAe,OAAyB;AAC/C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,cAAc;AACzD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,SAAO,OAAO;AAAA,IACZ,OAAO,KAAK,KAAK,EACd,KAAK,EACL,IAAI,CAAC,QAAQ,CAAC,KAAK,eAAgB,MAAkC,GAAG,CAAC,CAAC,CAAC;AAAA,EAChF;AACF;AAEA,SAAS,gBAAgB,MAA8B,UAA8B;AACnF,MAAI,SAAS,SAAS,UAAW,QAAO,SAAS;AACjD,SAAO,MAAM,aAAa,SAAS;AACrC;AAEA,SAAS,eAAe,OAAkC,SAAiB,iBAAyB;AAClG,MACE,CAAC,SACD,MAAM,YAAY,WAClB,MAAM,YAAY,mBAClB,OAAO,MAAM,aAAa,YAC1B,CAAC,wBAAwB,MAAM,QAAQ,KACvC,OAAO,MAAM,WAAW,YACxB,CAAC,iBAAiB,KAAK,MAAM,MAAM,KACnC,OAAO,MAAM,cAAc,YAC3B,CAAC,eAAe,MAAM,WAAW,EAAE,KACnC,OAAO,MAAM,YAAY,YACzB,CAAC,eAAe,MAAM,SAAS,GAAG,KACjC,MAAM,iBAAiB,UAAa,OAAO,MAAM,iBAAiB,WACnE;AACA,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACA,MAAI,MAAM,cAAc,OAAW,2BAA0B,MAAM,SAAS;AAC5E,SAAO;AACT;AAEA,SAAS,eAAe,OAAoE,iBAAyB;AACnH,MAAI,CAAC,SAAS,MAAM,YAAY,WAAW,CAAC,MAAM,QAAQ,MAAM,SAAS,GAAG;AAC1E,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,QAAM,WAAW,MAAM,UAAU;AAAA,IAAI,CAAC,YACpC,eAAe,SAAS,sCAAsC,eAAe;AAAA,EAC/E;AACA,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,WAAW,UAAU;AAC9B,QAAI,WAAW,IAAI,QAAQ,QAAQ,GAAG;AACpC,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,eAAW,IAAI,QAAQ,QAAQ;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,UAAoB,iBAAyB;AAC3E,2BAAyB,QAAQ;AACjC,MACE,SAAS,YAAY,mBACrB,CAAC,wBAAwB,SAAS,EAAE,KACpC,CAAC,eAAe,SAAS,WAAW,EAAE,KACtC,CAAC,eAAe,SAAS,SAAS,GAAG,KACrC,CAAC,MAAM,QAAQ,SAAS,KAAK,GAC7B;AACA,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACF;AAEA,SAAS,uBAAuB,UAAoB;AAClD,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,SAAS,OAAO;AACjC,QACE,CAAC,QACD,OAAO,KAAK,SAAS,YACrB,OAAO,KAAK,kBAAkB,YAC9B,OAAO,KAAK,WAAW,YACvB,CAAC,iBAAiB,KAAK,KAAK,MAAM,KAClC,MAAM,IAAI,KAAK,IAAI,GACnB;AACA,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,UAAM,UAAU,OAAO,KAAK,KAAK,eAAe,QAAQ;AACxD,QAAI,QAAQ,SAAS,QAAQ,MAAM,KAAK,iBAAiBA,QAAO,OAAO,MAAM,KAAK,QAAQ;AACxF,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AACA,UAAM,IAAI,KAAK,IAAI;AAAA,EACrB;AACF;AAEA,SAAS,sBAAsB,QAA2B;AACxD,aAAW,CAAC,OAAO,OAAO,UAAU,KAAK;AAAA,IACvC,CAAC,UAAU,OAAO,YAAY,QAAQ,KAAK;AAAA,IAC3C,CAAC,UAAU,OAAO,YAAY,QAAQ,IAAI;AAAA,IAC1C,CAAC,aAAa,OAAO,YAAY,WAAW,KAAK;AAAA,EACnD,GAAY;AACV,QAAI,UAAU,YAAY,UAAU,KAAM;AAC1C,QACG,CAAC,cAAc,MAAM,WAAW,KACjC,MAAM,SAAS,IAAI,KACnB,oBAAoB,KAAK,KACzB,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC,YAAY,YAAY,OAAO,YAAY,IAAI,GACtE;AACA,YAAM,IAAI,MAAM,+BAA+B,KAAK,GAAG;AAAA,IACzD;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,WAAmB;AACnD,MAAI,CAAC,wBAAwB,SAAS,GAAG;AACvC,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEA,SAAS,wBAAwB,WAAmB;AAClD,SACE,UAAU,SAAS,KACnB,UAAU,UAAU,OACpB,cAAc,OACd,cAAc,QACd,CAAC,UAAU,SAAS,GAAG,KACvB,CAAC,UAAU,SAAS,IAAI,KACxB,CAAC,oBAAoB,SAAS;AAElC;AAEA,SAAS,eAAe,OAAe,WAAmB;AACxD,SAAO,MAAM,SAAS,KAAK,MAAM,UAAU,aAAa,CAAC,oBAAoB,KAAK;AACpF;AAEA,SAAS,oBAAoB,OAAe;AAC1C,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,cAAc;AACpC,UAAM,OAAO,UAAU,YAAY,CAAC,KAAK;AACzC,WAAO,OAAO,MAAQ,SAAS;AAAA,EACjC,CAAC;AACH;AAEA,SAASA,QAAO,OAAe;AAC7B,SAAOE,YAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AACxD;AAEA,SAASD,cAAa,OAAgB;AACpC,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;",
|
|
6
|
+
"names": ["createHash", "sessionToken", "sha256", "errorMessage", "createHash"]
|
|
7
|
+
}
|
|
@@ -6,18 +6,19 @@ import {
|
|
|
6
6
|
setupSwitchActionFromLabel,
|
|
7
7
|
setupSwitchActionLabel,
|
|
8
8
|
useSyncSetup
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-GP5DU62N.ts";
|
|
10
|
+
import "./chunk-NLWS55B6.ts";
|
|
11
11
|
import "./chunk-AMJRUXFT.ts";
|
|
12
|
-
import "./chunk-KATKRR3D.ts";
|
|
13
|
-
import "./chunk-2JZFHNLM.ts";
|
|
14
|
-
import "./chunk-T2SJD3N7.ts";
|
|
15
12
|
import {
|
|
16
13
|
SetupPullRequiresUiError
|
|
17
14
|
} from "./chunk-7D5SF7P3.ts";
|
|
15
|
+
import "./chunk-QO333NM4.ts";
|
|
18
16
|
import "./chunk-A6HU4ERM.ts";
|
|
17
|
+
import "./chunk-PWMWOJP4.ts";
|
|
19
18
|
import "./chunk-QOFMXPM5.ts";
|
|
20
19
|
import "./chunk-ZW5ZLGBI.ts";
|
|
20
|
+
import "./chunk-2JZFHNLM.ts";
|
|
21
|
+
import "./chunk-T2SJD3N7.ts";
|
|
21
22
|
import "./chunk-HUZ5CR4W.ts";
|
|
22
23
|
export {
|
|
23
24
|
SETUP_SWITCH_ACTION_OPTIONS,
|
|
@@ -27,4 +28,4 @@ export {
|
|
|
27
28
|
setupSwitchActionLabel,
|
|
28
29
|
useSyncSetup
|
|
29
30
|
};
|
|
30
|
-
//# sourceMappingURL=setup-switch-
|
|
31
|
+
//# sourceMappingURL=setup-switch-E7PHKI6J.ts.map
|
|
@@ -5,26 +5,29 @@ import {
|
|
|
5
5
|
showGitSetup,
|
|
6
6
|
showS3Setup,
|
|
7
7
|
showWebDavSetup
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QSHMOL3I.ts";
|
|
9
|
+
import "./chunk-B4QZBDBT.ts";
|
|
9
10
|
import "./chunk-ECYCNZOE.ts";
|
|
10
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-NLWS55B6.ts";
|
|
11
12
|
import {
|
|
12
13
|
safeTerminalText
|
|
13
14
|
} from "./chunk-AMJRUXFT.ts";
|
|
14
|
-
import "./chunk-R35N4CL3.ts";
|
|
15
|
-
import {
|
|
16
|
-
localConfigPath,
|
|
17
|
-
validateConfigName
|
|
18
|
-
} from "./chunk-KATKRR3D.ts";
|
|
19
|
-
import "./chunk-2JZFHNLM.ts";
|
|
20
|
-
import "./chunk-T2SJD3N7.ts";
|
|
21
15
|
import "./chunk-G4RUXRWZ.ts";
|
|
22
16
|
import {
|
|
23
17
|
errorMessage
|
|
24
18
|
} from "./chunk-7D5SF7P3.ts";
|
|
19
|
+
import {
|
|
20
|
+
localConfigPath,
|
|
21
|
+
validateConfigName
|
|
22
|
+
} from "./chunk-QO333NM4.ts";
|
|
25
23
|
import "./chunk-A6HU4ERM.ts";
|
|
24
|
+
import {
|
|
25
|
+
throwIfAborted
|
|
26
|
+
} from "./chunk-PWMWOJP4.ts";
|
|
26
27
|
import "./chunk-QOFMXPM5.ts";
|
|
27
28
|
import "./chunk-ZW5ZLGBI.ts";
|
|
29
|
+
import "./chunk-2JZFHNLM.ts";
|
|
30
|
+
import "./chunk-T2SJD3N7.ts";
|
|
28
31
|
import "./chunk-HUZ5CR4W.ts";
|
|
29
32
|
|
|
30
33
|
// src/ui/setup/setup-name-ui.ts
|
|
@@ -34,9 +37,7 @@ async function promptInitialSetupName(ctx, signal) {
|
|
|
34
37
|
const guidance = ctx.mode === "tui" ? ctx.ui.theme.fg("muted", hint) : hint;
|
|
35
38
|
const value = await ctx.ui.input(`Sync setup name
|
|
36
39
|
${guidance}`, void 0, { signal });
|
|
37
|
-
|
|
38
|
-
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
39
|
-
}
|
|
40
|
+
throwIfAborted(signal);
|
|
40
41
|
if (value === void 0) return void 0;
|
|
41
42
|
const name = value.trim() || "default";
|
|
42
43
|
try {
|
|
@@ -89,4 +90,4 @@ async function showSetupWizard(ctx, signal) {
|
|
|
89
90
|
export {
|
|
90
91
|
showSetupWizard
|
|
91
92
|
};
|
|
92
|
-
//# sourceMappingURL=setup-wizard-
|
|
93
|
+
//# sourceMappingURL=setup-wizard-65DROCIJ.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/setup/setup-name-ui.ts", "../../src/ui/setup/setup-wizard.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { validateConfigName } from \"../../settings/settings-validation.js\";\nimport { throwIfAborted } from \"../../sync/signals.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\n\nexport async function promptInitialSetupName(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n while (!signal?.aborted) {\n const hint = \"For example: home or work. Leave blank for default.\";\n // Pi styles the whole input title as accent; give only the guidance a muted role.\n const guidance = ctx.mode === \"tui\" ? ctx.ui.theme.fg(\"muted\", hint) : hint;\n // This compact prompt owns its default hint; the general helper would repeat it.\n const value = await ctx.ui.input(`Sync setup name\\n${guidance}`, undefined, { signal });\n throwIfAborted(signal);\n if (value === undefined) return undefined;\n const name = value.trim() || \"default\";\n try {\n if (name.includes(\"<\") || name.includes(\">\")) {\n throw new Error(\"Replace example placeholders with your own name.\");\n }\n validateConfigName(name, \"sync setup\");\n return name;\n } catch (error) {\n ctx.ui.notify(\n `This name cannot be used for the sync setup. ${safeTerminalText(errorMessage(error))} Enter another name (for example, default).`,\n \"warning\",\n );\n }\n }\n return undefined;\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { refreshTargetCompletions } from \"../../commands/setup-completions.js\";\nimport { localConfigPath } from \"../../settings/config-file.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { showGitSetup } from \"./git-ui.js\";\nimport { showS3Setup } from \"./s3-ui.js\";\nimport { promptInitialSetupName } from \"./setup-name-ui.js\";\nimport { showWebDavSetup } from \"./webdav-ui.js\";\n\nexport async function showSetupWizard(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n if (ctx.mode !== \"tui\") {\n ctx.ui.notify(\n `Guided sync setup requires TUI mode for masked credential input. Create version 3 settings in ${safeTerminalText(localConfigPath())}.`,\n \"warning\",\n );\n return false;\n }\n const preset = await ctx.ui.select(\n \"Set up sync\\n\\nWhere will Pi settings be stored?\",\n [\"Cloudflare R2\", \"Other S3-compatible storage\", \"WebDAV\", \"Git\", \"Cancel\"],\n { signal },\n );\n if (signal?.aborted || !preset || preset === \"Cancel\") return false;\n const targetName = await promptInitialSetupName(ctx, signal);\n if (!targetName) return false;\n if (preset === \"WebDAV\") {\n const saved = await showWebDavSetup(ctx, targetName, signal);\n if (signal?.aborted) return false;\n if (saved) await refreshTargetCompletions();\n return saved;\n }\n if (preset === \"Git\") {\n const saved = await showGitSetup(ctx, targetName, signal);\n if (signal?.aborted) return false;\n if (saved) await refreshTargetCompletions();\n return saved;\n }\n return showS3Setup(ctx, preset, targetName, signal);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,eAAsB,uBAAuB,KAA8B,QAAsB;AAC/F,SAAO,CAAC,QAAQ,SAAS;AACvB,UAAM,OAAO;AAEb,UAAM,WAAW,IAAI,SAAS,QAAQ,IAAI,GAAG,MAAM,GAAG,SAAS,IAAI,IAAI;AAEvE,UAAM,QAAQ,MAAM,IAAI,GAAG,MAAM;AAAA,EAAoB,QAAQ,IAAI,QAAW,EAAE,OAAO,CAAC;AACtF,mBAAe,MAAM;AACrB,QAAI,UAAU,OAAW,QAAO;AAChC,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,QAAI;AACF,UAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;AAC5C,cAAM,IAAI,MAAM,kDAAkD;AAAA,MACpE;AACA,yBAAmB,MAAM,YAAY;AACrC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,GAAG;AAAA,QACL,gDAAgD,iBAAiB,aAAa,KAAK,CAAC,CAAC;AAAA,QACrF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACrBA,eAAsB,gBAAgB,KAA8B,QAAsB;AACxF,MAAI,IAAI,SAAS,OAAO;AACtB,QAAI,GAAG;AAAA,MACL,iGAAiG,iBAAiB,gBAAgB,CAAC,CAAC;AAAA,MACpI;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,IAAI,GAAG;AAAA,IAC1B;AAAA,IACA,CAAC,iBAAiB,+BAA+B,UAAU,OAAO,QAAQ;AAAA,IAC1E,EAAE,OAAO;AAAA,EACX;AACA,MAAI,QAAQ,WAAW,CAAC,UAAU,WAAW,SAAU,QAAO;AAC9D,QAAM,aAAa,MAAM,uBAAuB,KAAK,MAAM;AAC3D,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,WAAW,UAAU;AACvB,UAAM,QAAQ,MAAM,gBAAgB,KAAK,YAAY,MAAM;AAC3D,QAAI,QAAQ,QAAS,QAAO;AAC5B,QAAI,MAAO,OAAM,yBAAyB;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,WAAW,OAAO;AACpB,UAAM,QAAQ,MAAM,aAAa,KAAK,YAAY,MAAM;AACxD,QAAI,QAAQ,QAAS,QAAO;AAC5B,QAAI,MAAO,OAAM,yBAAyB;AAC1C,WAAO;AAAA,EACT;AACA,SAAO,YAAY,KAAK,QAAQ,YAAY,MAAM;AACpD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
inspectSync
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OWBAZA6J.ts";
|
|
6
|
+
import "./chunk-OEWQVWLC.ts";
|
|
6
7
|
import "./chunk-BDB4IDM3.ts";
|
|
7
|
-
import "./chunk-2FETCGGT.ts";
|
|
8
8
|
import "./chunk-UZPMDLTL.ts";
|
|
9
|
-
import "./chunk-PWMWOJP4.ts";
|
|
10
|
-
import "./chunk-VCL7TZYW.ts";
|
|
11
|
-
import "./chunk-BVVP33U5.ts";
|
|
12
|
-
import "./chunk-2JZFHNLM.ts";
|
|
13
|
-
import "./chunk-T2SJD3N7.ts";
|
|
14
9
|
import "./chunk-A6HU4ERM.ts";
|
|
10
|
+
import "./chunk-PWMWOJP4.ts";
|
|
15
11
|
import "./chunk-QOFMXPM5.ts";
|
|
16
12
|
import "./chunk-ZW5ZLGBI.ts";
|
|
13
|
+
import "./chunk-UPNVIUBN.ts";
|
|
14
|
+
import "./chunk-SWRVXVFD.ts";
|
|
15
|
+
import "./chunk-2JZFHNLM.ts";
|
|
16
|
+
import "./chunk-T2SJD3N7.ts";
|
|
17
17
|
import "./chunk-HUZ5CR4W.ts";
|
|
18
18
|
export {
|
|
19
19
|
inspectSync
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=sync-inspection-
|
|
21
|
+
//# sourceMappingURL=sync-inspection-XFJOAMJD.ts.map
|