@openclaw/matrix 2026.7.2-beta.7 → 2026.8.1-beta.3
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/dist/{account-selection-kqquRzCf.js → account-selection-CWuhuFn1.js} +7 -8
- package/dist/{accounts-DfngqebB.js → accounts-BCzyubQt.js} +3 -3
- package/dist/api.js +8 -11
- package/dist/{approval-handler.runtime-DSeaIsGa.js → approval-handler.runtime-CSvueU9P.js} +7 -6
- package/dist/{approval-ids-BdJGPAJT.js → approval-ids-CEcf-EiM.js} +1 -1
- package/dist/{approval-reaction-auth-BjOpELxu.js → approval-reaction-auth-CziKXatm.js} +2 -2
- package/dist/{approval-reactions-D-BxBK_L.js → approval-reactions-tXh9KYrW.js} +2 -8
- package/dist/auth-presence.js +2 -2
- package/dist/{channel-vj788dNZ.js → channel-CzQw5OZN.js} +376 -148
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CLoF2S9T.js → channel.runtime-I9pBRQb3.js} +79 -55
- package/dist/{config-schema-Djxw3C6b.js → channel.setup-aNaa3Uyn.js} +51 -10
- package/dist/{cli-DMqfDE-q.js → cli-iR6QJ5U0.js} +16 -16
- package/dist/{cli-metadata-C7D53SND.js → cli-metadata-BmUYWjuM.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BBQdBG7t.js +799 -0
- package/dist/{client-6eRENr7k.js → client-D8XghqmX.js} +4 -4
- package/dist/{client-bootstrap-XsIkHNt0.js → client-bootstrap-Co3RlItb.js} +25 -61
- package/dist/client-support-DLj4vDeu.js +93 -0
- package/dist/config-update-Bor_Pjsv.js +150 -0
- package/dist/contract-api.js +2 -2
- package/dist/{credentials-W2EmwRhu.js → credentials-BdAaWuiR.js} +2 -1
- package/dist/credentials-read-B37cQknZ.js +51 -0
- package/dist/credentials-state-B3cuUFwZ.js +27 -0
- package/dist/{credentials-write.runtime-Be9zNSUw.js → credentials-write.runtime-nAV2-5uR.js} +1 -1
- package/dist/{crypto-runtime-D9_6J5tZ.js → crypto-runtime-Bnz3zEcS.js} +55 -32
- package/dist/direct-room-RinHjtqX.js +71 -0
- package/dist/{directory-live-C8dVBiCc.js → directory-live-DLQzel12.js} +2 -3
- package/dist/{doctor-CM8ijNpW.js → doctor-EWf9CDso.js} +2 -2
- package/dist/{doctor-contract-BMSJkkAE.js → doctor-contract-DEt4O4Zt.js} +2 -3
- package/dist/doctor-contract-api.js +209 -91
- package/dist/{draft-stream-CtvOXq0Z.js → draft-stream-DQ7QNC-l.js} +20 -23
- package/dist/{encryption-guidance-CbEFe38F.js → encryption-guidance-DmLY8NiO.js} +1 -1
- package/dist/{env-auth-CQsYbz-p.js → env-auth-MVS-Vv41.js} +4 -3
- package/dist/{env-vars-B0NxQnPk.js → env-vars-dGqak9dN.js} +1 -1
- package/dist/{errors-C47hvAF8.js → errors-DKVS3_DO.js} +2 -5
- package/dist/{file-sync-store-DiiFsayX.js → file-sync-store-DjskBX2o.js} +24 -3
- package/dist/helper-api.js +2 -2
- package/dist/{idb-persistence-B6x7dMsF.js → idb-persistence-BM0P27Zg.js} +3 -2
- package/dist/{inbound-dedupe-CaBLblef.js → inbound-dedupe-RvSLqdsz.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{logger-D0GCSDQq.js → logger-B_71hN6W.js} +1 -1
- package/dist/{logging-DV-p52N0.js → logging-DRjvUOIh.js} +1 -1
- package/dist/{media-text-BTwzADS_.js → media-text-Dh-DpTc3.js} +4 -1
- package/dist/{messages-DxQJkhxs.js → messages-DEqg7HVy.js} +31 -11
- package/dist/{monitor-VyWlSLwo.js → monitor-FNrfkuWL.js} +413 -405
- package/dist/plugin-entry.handlers.runtime.js +3 -3
- package/dist/probe.runtime-NIJZYqc2.js +2 -0
- package/dist/profile-D-Wubo0A.js +108 -0
- package/dist/{profile-update-CffmyW_4.js → profile-update-BQlE5s2J.js} +3 -2
- package/dist/{reaction-events-B00WSi98.js → reaction-events-BKOLlnCo.js} +10 -7
- package/dist/{recovery-key-store-BNnHvXdk.js → recovery-key-store-CognuDys.js} +5 -4
- package/dist/{resolve-targets-nm2L48sh.js → resolve-targets-e7AI0P75.js} +2 -2
- package/dist/{resolver.runtime-DS6uPaEe.js → resolver.runtime-V8u0pHEb.js} +1 -1
- package/dist/{room-info-CAFZ3Z9J.js → room-info-BXQA7y10.js} +12 -3
- package/dist/runtime-api.js +7 -4
- package/dist/{sdk-bUytQHx7.js → sdk-NxK3vzMa.js} +242 -119
- package/dist/{secret-contract-M3hRmGO-.js → secret-contract-CufozuyJ.js} +1 -1
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-BldGYG8g.js → send-ClHgDZLT.js} +1477 -1210
- package/dist/session-binding-contract-api.js +2 -3
- package/dist/{setup-bootstrap-Deleiibz.js → setup-bootstrap-BGPjbA5N.js} +4 -4
- package/dist/{setup-core-BVfBv2ai.js → setup-core-DigrLebY.js} +17 -266
- package/dist/setup-plugin-api.js +1 -44
- package/dist/{setup-surface-BBq3WeqX.js → setup-surface-Dtn8sAWs.js} +15 -16
- package/dist/{startup-verification-wm3_i88s.js → startup-verification-Cs08ca8u.js} +3 -3
- package/dist/{storage-BvAkgzvT.js → storage-BsGuHngK.js} +3 -3
- package/dist/subagent-hooks-CMoZaARG.js +48 -0
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{target-ids-B-5aQxwn.js → target-ids-Nwx7cMVE.js} +11 -1
- package/dist/{thread-binding-api-DRbBZlhS.js → thread-binding-api-CzkeLZCU.js} +1 -1
- package/dist/thread-binding-api.js +1 -1
- package/dist/{thread-bindings-DGbl3vDW.js → thread-bindings-BYEGfw3h.js} +17 -10
- package/dist/thread-bindings-runtime.js +1 -1
- package/dist/{thread-bindings-shared-CKnY4LSd.js → thread-bindings-shared-oNPiyMWY.js} +1 -6
- package/dist/{tool-actions.runtime-uu9blSqO.js → tool-actions.runtime-ck6IJyP0.js} +36 -19
- package/dist/{verification-DYMQ1QpI.js → verification-CabtBTtB.js} +2 -2
- package/openclaw.plugin.json +61 -1
- package/package.json +4 -4
- package/dist/active-client-DXvz2gCo.js +0 -20
- package/dist/client-Dbso3-0V.js +0 -30
- package/dist/create-client-BmSU-q-D.js +0 -61
- package/dist/credentials-read-DVmFCm7X.js +0 -77
- package/dist/exec-approval-resolver-BCgqRtZS.js +0 -16
- package/dist/preflight-audio.runtime-BZxxQsxY.js +0 -11
- package/dist/probe.runtime-BuieqmS3.js +0 -3
- package/dist/record-shared-CWWx6fvI.js +0 -2
- package/dist/route-DY6at4qJ.js +0 -161
- package/dist/shared-CUMWxcMz.js +0 -673
- package/dist/subagent-hooks-dkPAF6Et.js +0 -143
- package/dist/sync-state-CWbp0QSY.js +0 -12
- package/dist/{runtime-api-D1xI_cvh.js → runtime-api-BGO16Fu8.js} +3 -3
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { t as SqliteBackedMatrixSyncStore } from "./file-sync-store-
|
|
3
|
-
import { n as LogService, r as noop, t as ConsoleLogger } from "./logger-
|
|
1
|
+
import "./reaction-common-DkrQdBSZ.js";
|
|
2
|
+
import { t as SqliteBackedMatrixSyncStore } from "./file-sync-store-DjskBX2o.js";
|
|
3
|
+
import { n as LogService, r as noop, t as ConsoleLogger } from "./logger-B_71hN6W.js";
|
|
4
4
|
import { t as MATRIX_IDB_PERSIST_INTERVAL_MS } from "./idb-persistence-lock-DAJ49nZX.js";
|
|
5
|
-
import {
|
|
5
|
+
import { n as isMatrixNotFoundError, t as formatMatrixErrorReason } from "./errors-DKVS3_DO.js";
|
|
6
|
+
import { a as throwIfMatrixStartupAborted, r as createMatrixStartupAbortError } from "./client-BBQdBG7t.js";
|
|
6
7
|
import { a as matrixEventToRaw, n as createMatrixGuardedFetch, o as parseMxc, t as MatrixAuthedHttpClient } from "./http-client-CycYxU9-.js";
|
|
7
8
|
import { n as resolveMatrixRoomKeyBackupReadinessError } from "./backup-health-Dm_YMVFT.js";
|
|
8
|
-
import { t as createMatrixJsSdkClientLogger } from "./logging-
|
|
9
|
-
import {
|
|
10
|
-
import { n as isRepairableSecretStorageAccessError, t as MatrixRecoveryKeyStore } from "./recovery-key-store-
|
|
9
|
+
import { t as createMatrixJsSdkClientLogger } from "./logging-DRjvUOIh.js";
|
|
10
|
+
import { a as isMatrixAccessTokenInvalidatedError, c as resolveMatrixLocalTimeoutMs, f as isMatrixReadySyncState, i as createMatrixExplicitBootstrapOptions, l as unresolvedMatrixDeviceVerificationStatus, n as MATRIX_INITIAL_CRYPTO_BOOTSTRAP_OPTIONS, o as resolveMatrixDiagnostic, p as isMatrixTerminalSyncState, r as MATRIX_STATUS_DIAGNOSTIC_TIMEOUT_MS, s as resolveMatrixDiagnosticResult, t as MATRIX_AUTOMATIC_REPAIR_BOOTSTRAP_OPTIONS, u as unresolvedMatrixRoomKeyBackupStatus } from "./client-support-DLj4vDeu.js";
|
|
11
|
+
import { n as isRepairableSecretStorageAccessError, t as MatrixRecoveryKeyStore } from "./recovery-key-store-CognuDys.js";
|
|
12
|
+
import { createRequire } from "node:module";
|
|
11
13
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
12
14
|
import { normalizeNullableString, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
13
17
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
14
|
-
import { ClientEvent, Filter, MatrixEventEvent, Preset, createClient } from "matrix-js-sdk/lib/matrix.js";
|
|
18
|
+
import { ClientEvent, EventType, Filter, MatrixError, MatrixEventEvent, MsgType, Preset, createClient } from "matrix-js-sdk/lib/matrix.js";
|
|
15
19
|
import { EventEmitter } from "node:events";
|
|
16
20
|
import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
|
|
21
|
+
import { SyncApi, SyncState } from "matrix-js-sdk/lib/sync.js";
|
|
22
|
+
import { EventStatus } from "matrix-js-sdk/lib/models/event-status.js";
|
|
17
23
|
//#region extensions/matrix/src/matrix/sdk/client-device-info.ts
|
|
18
24
|
async function resolveMatrixCrossSigningPublicationStatus(params) {
|
|
19
25
|
if (!params.userId) return {
|
|
@@ -78,8 +84,8 @@ function registerMatrixClientBridge(params) {
|
|
|
78
84
|
});
|
|
79
85
|
params.client.on(ClientEvent.Room, params.emitMembershipForRoom);
|
|
80
86
|
params.client.on(ClientEvent.Sync, (state, prevState, data) => {
|
|
81
|
-
params.setCurrentSyncState(state);
|
|
82
87
|
const error = data && typeof data === "object" && "error" in data ? data.error : void 0;
|
|
88
|
+
params.setCurrentSyncState(state, error);
|
|
83
89
|
params.emitter.emit("sync.state", state, prevState, error);
|
|
84
90
|
});
|
|
85
91
|
params.client.on(ClientEvent.SyncUnexpectedError, (error) => {
|
|
@@ -115,89 +121,93 @@ function refreshMatrixDmRoomIds(direct, dmRoomIds) {
|
|
|
115
121
|
return true;
|
|
116
122
|
}
|
|
117
123
|
//#endregion
|
|
118
|
-
//#region extensions/matrix/src/matrix/sdk/client-
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return
|
|
124
|
+
//#region extensions/matrix/src/matrix/sdk/client-sync-quiesce.ts
|
|
125
|
+
const MATRIX_SYNC_QUIESCE_TIMEOUT_MS = 5e3;
|
|
126
|
+
const MATRIX_JS_SDK_SYNC_VERSION = "41.9.0";
|
|
127
|
+
const matrixJsSdkPackage = createRequire(import.meta.url)("matrix-js-sdk/package.json");
|
|
128
|
+
function requireMatrixClassicSyncInternals(syncApi) {
|
|
129
|
+
return syncApi;
|
|
124
130
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
activeVersion: null,
|
|
129
|
-
trusted: null,
|
|
130
|
-
matchesDecryptionKey: null,
|
|
131
|
-
decryptionKeyCached: null,
|
|
132
|
-
keyLoadAttempted: false,
|
|
133
|
-
keyLoadError: null
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function unresolvedMatrixDeviceVerificationStatus(params) {
|
|
137
|
-
return {
|
|
138
|
-
encryptionEnabled: true,
|
|
139
|
-
userId: params.userId,
|
|
140
|
-
deviceId: params.deviceId,
|
|
141
|
-
verified: false,
|
|
142
|
-
localVerified: false,
|
|
143
|
-
crossSigningVerified: false,
|
|
144
|
-
signedByOwner: false
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
async function resolveMatrixDiagnostic(promise, timeoutMs) {
|
|
148
|
-
return (await resolveMatrixDiagnosticResult(promise, timeoutMs)).value;
|
|
131
|
+
function assertMatrixJsSdkSyncVersion() {
|
|
132
|
+
const version = matrixJsSdkPackage.version;
|
|
133
|
+
if (version !== MATRIX_JS_SDK_SYNC_VERSION) throw new Error(`Matrix sync quiesce requires matrix-js-sdk ${MATRIX_JS_SDK_SYNC_VERSION}; found ${String(version)}`);
|
|
149
134
|
}
|
|
150
|
-
async function
|
|
151
|
-
|
|
135
|
+
async function quiesceMatrixClientSync(params) {
|
|
136
|
+
await params.syncStore?.freezeSyncCursorPersistence();
|
|
152
137
|
try {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
timeoutId.unref?.();
|
|
169
|
-
});
|
|
170
|
-
return await Promise.race([guarded, timeout]);
|
|
171
|
-
} finally {
|
|
172
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
138
|
+
assertMatrixJsSdkSyncVersion();
|
|
139
|
+
} catch (error) {
|
|
140
|
+
params.syncStore?.discardPendingSyncCursorPersistence();
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
const syncApi = params.client.syncApi;
|
|
144
|
+
if (syncApi === void 0 && !params.started) return;
|
|
145
|
+
if (!(syncApi instanceof SyncApi)) {
|
|
146
|
+
params.syncStore?.discardPendingSyncCursorPersistence();
|
|
147
|
+
throw new Error(syncApi === void 0 ? "Matrix sync quiesce requires the classic matrix-js-sdk SyncApi, but none is active" : "Matrix sync quiesce rejected a sliding or unknown matrix-js-sdk sync implementation");
|
|
148
|
+
}
|
|
149
|
+
const syncState = syncApi.getSyncState();
|
|
150
|
+
if (syncState === SyncState.Stopped) {
|
|
151
|
+
params.markStopped();
|
|
152
|
+
return;
|
|
173
153
|
}
|
|
154
|
+
const disconnectedBeforeStop = syncState === SyncState.Error || syncState === SyncState.Reconnecting;
|
|
155
|
+
const syncInternals = requireMatrixClassicSyncInternals(syncApi);
|
|
156
|
+
const keepaliveResolvers = disconnectedBeforeStop ? syncInternals.connectionReturnedResolvers : void 0;
|
|
157
|
+
await new Promise((resolve, reject) => {
|
|
158
|
+
let settled = false;
|
|
159
|
+
const settle = (error) => {
|
|
160
|
+
if (settled) return;
|
|
161
|
+
settled = true;
|
|
162
|
+
clearTimeout(timeout);
|
|
163
|
+
params.emitter.off("sync.state", onSyncState);
|
|
164
|
+
if (error) reject(error);
|
|
165
|
+
else {
|
|
166
|
+
params.markStopped();
|
|
167
|
+
resolve();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const onSyncState = (state) => {
|
|
171
|
+
if (state === "STOPPED") settle();
|
|
172
|
+
};
|
|
173
|
+
const timeout = setTimeout(() => {
|
|
174
|
+
params.syncStore?.discardPendingSyncCursorPersistence();
|
|
175
|
+
settle(/* @__PURE__ */ new Error(`Matrix classic sync did not reach STOPPED within 5000ms`));
|
|
176
|
+
}, MATRIX_SYNC_QUIESCE_TIMEOUT_MS);
|
|
177
|
+
timeout.unref?.();
|
|
178
|
+
params.emitter.on("sync.state", onSyncState);
|
|
179
|
+
try {
|
|
180
|
+
syncApi.stop();
|
|
181
|
+
if (keepaliveResolvers && syncInternals.connectionReturnedResolvers === keepaliveResolvers) {
|
|
182
|
+
syncInternals.connectionReturnedResolvers = void 0;
|
|
183
|
+
keepaliveResolvers.reject("SyncApi.stop() was called");
|
|
184
|
+
settle();
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
params.syncStore?.discardPendingSyncCursorPersistence();
|
|
188
|
+
settle(error instanceof Error ? error : new Error(String(error)));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
174
191
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
forceResetCrossSigning: true,
|
|
186
|
-
allowSecretStorageRecreateWithoutRecoveryKey: true,
|
|
187
|
-
strict: true
|
|
188
|
-
};
|
|
189
|
-
function createMatrixExplicitBootstrapOptions(params) {
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region extensions/matrix/src/matrix/sdk/client-base.ts
|
|
194
|
+
function resolveMessageWireDispatch(resource, init) {
|
|
195
|
+
if ((init?.method ?? (resource instanceof Request ? resource.method : "GET")).toUpperCase() !== "PUT") return null;
|
|
196
|
+
const rawUrl = typeof resource === "string" ? resource : resource instanceof URL ? resource.href : resource.url;
|
|
197
|
+
const segments = new URL(rawUrl).pathname.split("/").filter(Boolean);
|
|
198
|
+
const roomsIndex = segments.lastIndexOf("rooms");
|
|
199
|
+
if (roomsIndex < 0 || segments[roomsIndex + 2] !== "send" || segments.length !== roomsIndex + 5) return null;
|
|
200
|
+
const eventType = decodeURIComponent(segments[roomsIndex + 3] ?? "");
|
|
201
|
+
if (eventType !== "m.room.message" && eventType !== "m.room.encrypted") return null;
|
|
190
202
|
return {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
203
|
+
roomId: decodeURIComponent(segments[roomsIndex + 1] ?? ""),
|
|
204
|
+
eventType,
|
|
205
|
+
transactionId: decodeURIComponent(segments[roomsIndex + 4] ?? ""),
|
|
206
|
+
requestPath: new URL(rawUrl).pathname
|
|
195
207
|
};
|
|
196
208
|
}
|
|
197
|
-
//#endregion
|
|
198
|
-
//#region extensions/matrix/src/matrix/sdk/client-base.ts
|
|
199
209
|
let loadedMatrixCryptoRuntime = null;
|
|
200
|
-
const loadMatrixCryptoRuntime = createLazyRuntimeModule(() => import("./crypto-runtime-
|
|
210
|
+
const loadMatrixCryptoRuntime = createLazyRuntimeModule(() => import("./crypto-runtime-Bnz3zEcS.js").then((runtime) => {
|
|
201
211
|
loadedMatrixCryptoRuntime = runtime;
|
|
202
212
|
return runtime;
|
|
203
213
|
}));
|
|
@@ -210,9 +220,15 @@ var MatrixClientBase = class {
|
|
|
210
220
|
this.dmRoomIds = /* @__PURE__ */ new Set();
|
|
211
221
|
this.cryptoInitialized = false;
|
|
212
222
|
this.sendQueue = new KeyedAsyncQueue();
|
|
223
|
+
this.syncQuiescePromise = null;
|
|
213
224
|
this.stopPersistPromise = null;
|
|
214
225
|
this.verificationSummaryListenerBound = false;
|
|
215
226
|
this.currentSyncState = null;
|
|
227
|
+
this.currentSyncError = void 0;
|
|
228
|
+
this.transactionScopeId = null;
|
|
229
|
+
this.transactionScopePromise = null;
|
|
230
|
+
this.messageWireDispatchGuards = /* @__PURE__ */ new Map();
|
|
231
|
+
this.sdkStopped = false;
|
|
216
232
|
this.dms = {
|
|
217
233
|
update: async () => {
|
|
218
234
|
return await this.refreshDmCache();
|
|
@@ -220,6 +236,9 @@ var MatrixClientBase = class {
|
|
|
220
236
|
isDm: (roomId) => this.dmRoomIds.has(roomId)
|
|
221
237
|
};
|
|
222
238
|
this.idbPersistTimer = null;
|
|
239
|
+
this.transactionScopeHomeserver = homeserver;
|
|
240
|
+
this.transactionScopeAccessTokenHash = createHash("sha256").update(accessToken).digest("hex");
|
|
241
|
+
this.transactionScopeDeviceId = opts.deviceId?.trim() || null;
|
|
223
242
|
this.httpClient = new MatrixAuthedHttpClient({
|
|
224
243
|
homeserver,
|
|
225
244
|
accessToken,
|
|
@@ -239,6 +258,10 @@ var MatrixClientBase = class {
|
|
|
239
258
|
this.autoBootstrapCrypto = opts.autoBootstrapCrypto !== false;
|
|
240
259
|
this.recoveryKeyStore = new MatrixRecoveryKeyStore(opts.recoveryKeyPath);
|
|
241
260
|
const cryptoCallbacks = this.encryptionEnabled ? this.recoveryKeyStore.buildCryptoCallbacks() : void 0;
|
|
261
|
+
const guardedFetch = createMatrixGuardedFetch({
|
|
262
|
+
ssrfPolicy: opts.ssrfPolicy,
|
|
263
|
+
dispatcherPolicy: opts.dispatcherPolicy
|
|
264
|
+
});
|
|
242
265
|
this.client = createClient({
|
|
243
266
|
baseUrl: homeserver,
|
|
244
267
|
accessToken,
|
|
@@ -246,9 +269,10 @@ var MatrixClientBase = class {
|
|
|
246
269
|
deviceId: opts.deviceId,
|
|
247
270
|
logger: createMatrixJsSdkClientLogger("MatrixClient"),
|
|
248
271
|
localTimeoutMs: this.localTimeoutMs,
|
|
249
|
-
fetchFn:
|
|
250
|
-
|
|
251
|
-
|
|
272
|
+
fetchFn: (async (resource, init) => {
|
|
273
|
+
const dispatch = resolveMessageWireDispatch(resource, init);
|
|
274
|
+
if (dispatch) await this.messageWireDispatchGuards.get(dispatch.transactionId)?.(dispatch);
|
|
275
|
+
return await guardedFetch(resource, init);
|
|
252
276
|
}),
|
|
253
277
|
store: this.syncStore,
|
|
254
278
|
cryptoCallbacks,
|
|
@@ -260,6 +284,16 @@ var MatrixClientBase = class {
|
|
|
260
284
|
]
|
|
261
285
|
});
|
|
262
286
|
}
|
|
287
|
+
async withMessageWireDispatchGuard(params) {
|
|
288
|
+
if (!params.transactionId || !params.guard) return await params.run();
|
|
289
|
+
if (this.messageWireDispatchGuards.has(params.transactionId)) throw new Error(`Matrix transaction ${params.transactionId} already has a dispatch guard`);
|
|
290
|
+
this.messageWireDispatchGuards.set(params.transactionId, params.guard);
|
|
291
|
+
try {
|
|
292
|
+
return await params.run();
|
|
293
|
+
} finally {
|
|
294
|
+
this.messageWireDispatchGuards.delete(params.transactionId);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
263
297
|
on(eventName, listener) {
|
|
264
298
|
this.emitter.on(eventName, listener);
|
|
265
299
|
return this;
|
|
@@ -314,7 +348,7 @@ var MatrixClientBase = class {
|
|
|
314
348
|
client: this.client,
|
|
315
349
|
verificationManager: this.verificationManager,
|
|
316
350
|
recoveryKeyStore: this.recoveryKeyStore,
|
|
317
|
-
|
|
351
|
+
isRoomEncrypted: async (roomId) => await this.getMessageWireEventType(roomId) === "m.room.encrypted",
|
|
318
352
|
downloadContent: (mxcUrl, opts) => this.downloadContent(mxcUrl, opts)
|
|
319
353
|
});
|
|
320
354
|
if (!this.verificationSummaryListenerBound) {
|
|
@@ -334,6 +368,7 @@ var MatrixClientBase = class {
|
|
|
334
368
|
async waitForInitialSyncReady(params = {}) {
|
|
335
369
|
const timeoutMs = params.timeoutMs ?? 3e4;
|
|
336
370
|
if (isMatrixReadySyncState(this.currentSyncState)) return;
|
|
371
|
+
if (isMatrixAccessTokenInvalidatedError(this.currentSyncError)) throw this.currentSyncError instanceof Error ? this.currentSyncError : new Error("Matrix access token invalidated", { cause: this.currentSyncError });
|
|
337
372
|
if (isMatrixTerminalSyncState(this.currentSyncState)) throw new Error(`Matrix sync entered ${this.currentSyncState} during startup`);
|
|
338
373
|
await new Promise((resolve, reject) => {
|
|
339
374
|
let settled = false;
|
|
@@ -365,6 +400,10 @@ var MatrixClientBase = class {
|
|
|
365
400
|
settleResolve();
|
|
366
401
|
return;
|
|
367
402
|
}
|
|
403
|
+
if (isMatrixAccessTokenInvalidatedError(error)) {
|
|
404
|
+
settleReject(error instanceof Error ? error : /* @__PURE__ */ new Error("Matrix access token invalidated"));
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
368
407
|
if (isMatrixTerminalSyncState(state)) settleReject(new Error(error instanceof Error && error.message ? error.message : `Matrix sync entered ${state} during startup`));
|
|
369
408
|
};
|
|
370
409
|
const onUnexpectedError = (error) => {
|
|
@@ -388,6 +427,7 @@ var MatrixClientBase = class {
|
|
|
388
427
|
}
|
|
389
428
|
async startSyncSession(opts) {
|
|
390
429
|
if (this.started) return;
|
|
430
|
+
if (this.sdkStopped) throw new Error("Matrix client has been fully stopped and cannot be restarted; acquire a new shared client generation");
|
|
391
431
|
throwIfMatrixStartupAborted(opts.abortSignal);
|
|
392
432
|
await this.ensureCryptoSupportInitialized();
|
|
393
433
|
throwIfMatrixStartupAborted(opts.abortSignal);
|
|
@@ -425,43 +465,58 @@ var MatrixClientBase = class {
|
|
|
425
465
|
if (this.started) return;
|
|
426
466
|
await this.startSyncSession({ bootstrapCrypto: false });
|
|
427
467
|
}
|
|
428
|
-
|
|
468
|
+
stopSdkClient() {
|
|
469
|
+
if (this.sdkStopped) return;
|
|
429
470
|
if (this.idbPersistTimer) {
|
|
430
471
|
clearInterval(this.idbPersistTimer);
|
|
431
472
|
this.idbPersistTimer = null;
|
|
432
473
|
}
|
|
433
474
|
this.currentSyncState = null;
|
|
475
|
+
this.currentSyncError = void 0;
|
|
434
476
|
this.client.stopClient();
|
|
477
|
+
this.sdkStopped = true;
|
|
435
478
|
this.started = false;
|
|
436
479
|
}
|
|
480
|
+
async quiesceSync() {
|
|
481
|
+
this.syncQuiescePromise ??= quiesceMatrixClientSync({
|
|
482
|
+
client: this.client,
|
|
483
|
+
emitter: this.emitter,
|
|
484
|
+
markStopped: () => {
|
|
485
|
+
this.started = false;
|
|
486
|
+
},
|
|
487
|
+
started: this.started,
|
|
488
|
+
syncStore: this.syncStore
|
|
489
|
+
});
|
|
490
|
+
await this.syncQuiescePromise;
|
|
491
|
+
}
|
|
437
492
|
async drainPendingDecryptions(reason = "matrix client shutdown") {
|
|
438
493
|
await this.decryptBridge?.drainPendingDecryptions(reason);
|
|
439
494
|
}
|
|
440
495
|
stop() {
|
|
441
|
-
this.
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
this.stopPersistPromise = Promise.all([persistIdbToDisk({
|
|
447
|
-
snapshotPath: this.idbSnapshotPath,
|
|
448
|
-
databasePrefix: this.cryptoDatabasePrefix
|
|
449
|
-
}).catch(noop), this.syncStore?.flush().catch(noop)]).then(() => void 0);
|
|
496
|
+
this.stopAndPersist().catch(() => this.stopWithoutPersist()).catch(noop);
|
|
497
|
+
}
|
|
498
|
+
async stopAndPersist() {
|
|
499
|
+
if (this.stopPersistPromise) {
|
|
500
|
+
await this.stopPersistPromise;
|
|
450
501
|
return;
|
|
451
502
|
}
|
|
452
|
-
this.stopPersistPromise =
|
|
453
|
-
await
|
|
503
|
+
this.stopPersistPromise = (async () => {
|
|
504
|
+
await this.quiesceSync();
|
|
505
|
+
this.stopSdkClient();
|
|
506
|
+
this.decryptBridge?.stop();
|
|
507
|
+
await (loadedMatrixCryptoRuntime ?? await loadMatrixCryptoRuntime()).persistIdbToDisk({
|
|
454
508
|
snapshotPath: this.idbSnapshotPath,
|
|
455
|
-
databasePrefix: this.cryptoDatabasePrefix
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
509
|
+
databasePrefix: this.cryptoDatabasePrefix,
|
|
510
|
+
strict: true
|
|
511
|
+
});
|
|
512
|
+
this.syncStore?.markCleanShutdown();
|
|
513
|
+
await this.syncStore?.flush();
|
|
514
|
+
})();
|
|
461
515
|
await this.stopPersistPromise;
|
|
462
516
|
}
|
|
463
517
|
stopWithoutPersist() {
|
|
464
|
-
this.
|
|
518
|
+
this.syncStore?.discardPendingSyncCursorPersistence();
|
|
519
|
+
this.stopSdkClient();
|
|
465
520
|
this.decryptBridge?.stop();
|
|
466
521
|
this.stopPersistPromise = Promise.resolve();
|
|
467
522
|
}
|
|
@@ -537,6 +592,30 @@ var MatrixClientCore = class extends MatrixClientBase {
|
|
|
537
592
|
const joined = await this.doRequest("GET", "/_matrix/client/v3/joined_rooms");
|
|
538
593
|
return Array.isArray(joined.joined_rooms) ? joined.joined_rooms : [];
|
|
539
594
|
}
|
|
595
|
+
async getTransactionScopeId() {
|
|
596
|
+
if (this.transactionScopeId) return this.transactionScopeId;
|
|
597
|
+
const active = this.transactionScopePromise ?? (async () => {
|
|
598
|
+
const configuredUserId = this.client.getUserId()?.trim() || this.selfUserId;
|
|
599
|
+
const configuredDeviceId = this.transactionScopeDeviceId || this.client.getDeviceId()?.trim() || null;
|
|
600
|
+
const whoami = await this.doRequest("GET", "/_matrix/client/v3/account/whoami");
|
|
601
|
+
const userId = whoami.user_id?.trim() || null;
|
|
602
|
+
const deviceId = whoami.device_id?.trim() || null;
|
|
603
|
+
if (!userId) throw new Error("Matrix whoami did not return user_id");
|
|
604
|
+
if (configuredUserId && configuredUserId !== userId) throw new Error("Matrix access token user does not match the configured userId");
|
|
605
|
+
if (configuredDeviceId && deviceId && configuredDeviceId !== deviceId) throw new Error("Matrix access token device does not match the configured deviceId");
|
|
606
|
+
this.selfUserId = userId;
|
|
607
|
+
this.transactionScopeDeviceId = deviceId;
|
|
608
|
+
return createHash("sha256").update(this.transactionScopeHomeserver).update("\0").update(userId).update("\0").update(deviceId ?? "").update("\0").update(this.transactionScopeAccessTokenHash).digest("hex");
|
|
609
|
+
})();
|
|
610
|
+
this.transactionScopePromise = active;
|
|
611
|
+
try {
|
|
612
|
+
const resolved = await active;
|
|
613
|
+
this.transactionScopeId = resolved;
|
|
614
|
+
return resolved;
|
|
615
|
+
} finally {
|
|
616
|
+
if (this.transactionScopePromise === active) this.transactionScopePromise = null;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
540
619
|
async getJoinedRoomMembers(roomId) {
|
|
541
620
|
const joined = (await this.client.getJoinedRoomMembers(roomId))?.joined;
|
|
542
621
|
if (!joined || typeof joined !== "object") return [];
|
|
@@ -577,13 +656,56 @@ var MatrixClientCore = class extends MatrixClientBase {
|
|
|
577
656
|
initial_state: initialState
|
|
578
657
|
})).room_id;
|
|
579
658
|
}
|
|
580
|
-
async sendMessage(roomId, content) {
|
|
659
|
+
async sendMessage(roomId, content, transactionId, beforeWireDispatch) {
|
|
581
660
|
return await this.runSerializedRoomSend(roomId, async () => {
|
|
582
|
-
return
|
|
661
|
+
return await this.withMessageWireDispatchGuard({
|
|
662
|
+
transactionId,
|
|
663
|
+
guard: beforeWireDispatch,
|
|
664
|
+
run: async () => {
|
|
665
|
+
if (transactionId) {
|
|
666
|
+
const room = this.client.getRoom(roomId);
|
|
667
|
+
const existing = room?.getEventForTxnId?.(transactionId);
|
|
668
|
+
if (existing) {
|
|
669
|
+
const existingId = existing.getId();
|
|
670
|
+
if (existing.status === EventStatus.SENT && existingId && !existingId.startsWith("~")) return existingId;
|
|
671
|
+
if (existing.status === EventStatus.NOT_SENT && room) {
|
|
672
|
+
await this.prepareRoomForMessageSend(roomId, existing.getContent());
|
|
673
|
+
return (await this.client.resendEvent(existing, room)).event_id;
|
|
674
|
+
}
|
|
675
|
+
throw new Error(`Matrix transaction ${transactionId} is already active with status ${existing.status ?? "unknown"}`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
await this.prepareRoomForMessageSend(roomId, content);
|
|
679
|
+
return (await this.client.sendMessage(roomId, content, transactionId)).event_id;
|
|
680
|
+
}
|
|
681
|
+
});
|
|
583
682
|
});
|
|
584
683
|
}
|
|
684
|
+
async getMessageWireEventType(roomId) {
|
|
685
|
+
if (this.client.getRoom(roomId)?.hasEncryptionStateEvent() === true) return "m.room.encrypted";
|
|
686
|
+
const crypto = this.client.getCrypto();
|
|
687
|
+
if (crypto && await crypto.isEncryptionEnabledInRoom(roomId)) return "m.room.encrypted";
|
|
688
|
+
try {
|
|
689
|
+
await this.getRoomStateEvent(roomId, "m.room.encryption", "");
|
|
690
|
+
return "m.room.encrypted";
|
|
691
|
+
} catch (error) {
|
|
692
|
+
if (error instanceof MatrixError && error.httpStatus === 404 && error.errcode === "M_NOT_FOUND") return "m.room.message";
|
|
693
|
+
throw error;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
async prepareRoomForMessageSend(roomId, content) {
|
|
697
|
+
if (await this.getMessageWireEventType(roomId) === "m.room.message") return "m.room.message";
|
|
698
|
+
const crypto = this.client.getCrypto();
|
|
699
|
+
if (!crypto) throw new Error("Encrypted Matrix room: enable encryption before sending messages");
|
|
700
|
+
const room = this.client.getRoom(roomId);
|
|
701
|
+
if (!room || !room.hasEncryptionStateEvent() && !await crypto.isEncryptionEnabledInRoom(roomId)) throw new Error("Encrypted Matrix room is not ready: wait for room sync before sending");
|
|
702
|
+
if (content && ((content.msgtype === MsgType.Image || content.msgtype === MsgType.Audio || content.msgtype === MsgType.Video || content.msgtype === MsgType.File) && typeof content.url === "string" || content.info && "thumbnail_url" in content.info && typeof content.info.thumbnail_url === "string")) throw new Error("Encrypted Matrix room contains unencrypted media; retry the send");
|
|
703
|
+
return "m.room.encrypted";
|
|
704
|
+
}
|
|
585
705
|
async sendEvent(roomId, eventType, content) {
|
|
586
706
|
return await this.runSerializedRoomSend(roomId, async () => {
|
|
707
|
+
if (eventType === EventType.RoomMessageEncrypted.toString() || eventType === EventType.RoomRedaction.toString()) throw new Error(eventType === EventType.RoomRedaction.toString() ? "Matrix redaction wire events must use redactEvent" : "Matrix encrypted wire events must be generated by the SDK");
|
|
708
|
+
if (eventType !== "m.reaction") await this.prepareRoomForMessageSend(roomId, content);
|
|
587
709
|
return (await this.client.sendEvent(roomId, eventType, content)).event_id;
|
|
588
710
|
});
|
|
589
711
|
}
|
|
@@ -698,7 +820,7 @@ var MatrixClientCore = class extends MatrixClientBase {
|
|
|
698
820
|
};
|
|
699
821
|
//#endregion
|
|
700
822
|
//#region extensions/matrix/src/matrix/sdk/client-verification.ts
|
|
701
|
-
const
|
|
823
|
+
const normalizeNullableVerificationString = normalizeNullableString;
|
|
702
824
|
var MatrixClientVerification = class extends MatrixClientCore {
|
|
703
825
|
async getRoomKeyBackupStatus() {
|
|
704
826
|
if (!this.encryptionEnabled) return {
|
|
@@ -733,7 +855,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
|
|
|
733
855
|
try {
|
|
734
856
|
await crypto.loadSessionBackupPrivateKeyFromSecretStorage();
|
|
735
857
|
} catch (err) {
|
|
736
|
-
keyLoadError =
|
|
858
|
+
keyLoadError = formatErrorMessage(err);
|
|
737
859
|
}
|
|
738
860
|
} else keyLoadError = "Matrix crypto backend does not support loading backup keys from secret storage";
|
|
739
861
|
if (!keyLoadError) await this.enableTrustedRoomKeyBackupIfPossible(crypto);
|
|
@@ -830,7 +952,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
|
|
|
830
952
|
async resolveActiveRoomKeyBackupVersion(crypto) {
|
|
831
953
|
if (typeof crypto.getActiveSessionBackupVersion !== "function") return null;
|
|
832
954
|
const version = await crypto.getActiveSessionBackupVersion().catch(() => null);
|
|
833
|
-
return
|
|
955
|
+
return normalizeNullableVerificationString(version);
|
|
834
956
|
}
|
|
835
957
|
async resolveCachedRoomKeyBackupDecryptionKey(crypto) {
|
|
836
958
|
const read = Reflect.get(crypto, "getSessionBackupPrivateKey");
|
|
@@ -862,7 +984,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
|
|
|
862
984
|
let matchesDecryptionKey = null;
|
|
863
985
|
if (typeof crypto.getKeyBackupInfo === "function") {
|
|
864
986
|
const info = await crypto.getKeyBackupInfo().catch(() => null);
|
|
865
|
-
serverVersion =
|
|
987
|
+
serverVersion = normalizeNullableVerificationString(info?.version) ?? serverVersion;
|
|
866
988
|
if (info && typeof crypto.isKeyBackupTrusted === "function") {
|
|
867
989
|
const trustInfo = await crypto.isKeyBackupTrusted(info).catch(() => null);
|
|
868
990
|
trusted = typeof trustInfo?.trusted === "boolean" ? trustInfo.trusted : null;
|
|
@@ -883,7 +1005,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
|
|
|
883
1005
|
async resolveRoomKeyBackupVersion() {
|
|
884
1006
|
try {
|
|
885
1007
|
const response = await this.doRequest("GET", "/_matrix/client/v3/room_keys/version");
|
|
886
|
-
return
|
|
1008
|
+
return normalizeNullableVerificationString(response.version);
|
|
887
1009
|
} catch {
|
|
888
1010
|
return null;
|
|
889
1011
|
}
|
|
@@ -932,7 +1054,7 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
932
1054
|
keyId: stagedKeyId
|
|
933
1055
|
});
|
|
934
1056
|
} catch (err) {
|
|
935
|
-
return await fail(
|
|
1057
|
+
return await fail(formatErrorMessage(err));
|
|
936
1058
|
}
|
|
937
1059
|
const storedRecoveryKeyMatches = this.recoveryKeyStore.getRecoveryKeySummary()?.encodedPrivateKey?.trim() === trimmedRecoveryKey;
|
|
938
1060
|
if (backupUsableBeforeStagedRecovery && storedRecoveryKeyMatches) {
|
|
@@ -1033,7 +1155,7 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
1033
1155
|
};
|
|
1034
1156
|
} catch (err) {
|
|
1035
1157
|
this.recoveryKeyStore.discardStagedRecoveryKey();
|
|
1036
|
-
return await fail(
|
|
1158
|
+
return await fail(formatErrorMessage(err));
|
|
1037
1159
|
}
|
|
1038
1160
|
}
|
|
1039
1161
|
async restoreRoomKeyBackup(params = {}) {
|
|
@@ -1088,7 +1210,7 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
1088
1210
|
};
|
|
1089
1211
|
} catch (err) {
|
|
1090
1212
|
this.recoveryKeyStore.discardStagedRecoveryKey();
|
|
1091
|
-
return await fail(
|
|
1213
|
+
return await fail(formatErrorMessage(err));
|
|
1092
1214
|
}
|
|
1093
1215
|
}
|
|
1094
1216
|
async resetRoomKeyBackup(options = {}) {
|
|
@@ -1143,7 +1265,7 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
1143
1265
|
backup
|
|
1144
1266
|
};
|
|
1145
1267
|
} catch (err) {
|
|
1146
|
-
return await fail(
|
|
1268
|
+
return await fail(formatErrorMessage(err));
|
|
1147
1269
|
}
|
|
1148
1270
|
}
|
|
1149
1271
|
async getOwnCrossSigningPublicationStatus() {
|
|
@@ -1185,7 +1307,7 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
1185
1307
|
await this.ensureRoomKeyBackupEnabled(crypto);
|
|
1186
1308
|
} catch (err) {
|
|
1187
1309
|
this.recoveryKeyStore.discardStagedRecoveryKey();
|
|
1188
|
-
bootstrapError =
|
|
1310
|
+
bootstrapError = formatErrorMessage(err);
|
|
1189
1311
|
}
|
|
1190
1312
|
const verification = await this.getOwnDeviceVerificationStatus();
|
|
1191
1313
|
const crossSigning = await this.getOwnCrossSigningPublicationStatus();
|
|
@@ -1249,8 +1371,9 @@ var MatrixClient = class extends MatrixClientVerification {
|
|
|
1249
1371
|
emitter: this.emitter,
|
|
1250
1372
|
emitMembershipForRoom: (room) => this.emitMembershipForRoom(room),
|
|
1251
1373
|
getSelfUserId: () => this.client.getUserId() ?? this.selfUserId ?? "",
|
|
1252
|
-
setCurrentSyncState: (state) => {
|
|
1374
|
+
setCurrentSyncState: (state, error) => {
|
|
1253
1375
|
this.currentSyncState = state;
|
|
1376
|
+
this.currentSyncError = error;
|
|
1254
1377
|
}
|
|
1255
1378
|
});
|
|
1256
1379
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as getMatrixScopedEnvVarNames } from "./env-vars-
|
|
1
|
+
import { t as getMatrixScopedEnvVarNames } from "./env-vars-dGqak9dN.js";
|
|
2
2
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
3
3
|
import { collectSecretInputAssignment, createChannelSecretTargetRegistryEntries, getChannelSurface, hasConfiguredSecretInputValue, hasOwnProperty, normalizeSecretStringValue } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
4
4
|
//#region extensions/matrix/src/secret-contract.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-CufozuyJ.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|