@serve.zone/interfaces 32.40.1 → 32.42.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/changelog.md +64 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/clusterrelaycredential.d.ts +72 -0
- package/dist_ts/data/clusterrelaycredential.js +82 -1
- package/dist_ts/data/corestorecontroltoken.d.ts +90 -0
- package/dist_ts/data/corestorecontroltoken.js +106 -0
- package/dist_ts/data/index.d.ts +2 -0
- package/dist_ts/data/index.js +3 -1
- package/dist_ts/data/networkaddressplan.js +3 -12
- package/dist_ts/data/networkauthority.d.ts +16 -0
- package/dist_ts/data/networkauthority.js +45 -1
- package/dist_ts/data/networkcredential.d.ts +12 -8
- package/dist_ts/data/networkcredential.js +18 -13
- package/dist_ts/data/networkegressretirement.d.ts +105 -0
- package/dist_ts/data/networkegressretirement.js +113 -0
- package/dist_ts/data/noderetirement.d.ts +24 -4
- package/dist_ts/data/noderetirement.js +20 -3
- package/dist_ts/private/networkcontract.d.ts +2 -0
- package/dist_ts/private/networkcontract.js +10 -1
- package/dist_ts/requests/cluster.d.ts +34 -0
- package/dist_ts/requests/corestorecontrol.d.ts +33 -0
- package/dist_ts/requests/corestorecontrol.js +2 -0
- package/dist_ts/requests/index.d.ts +2 -1
- package/dist_ts/requests/index.js +3 -2
- package/dist_ts/requests/node.d.ts +9 -1
- package/package.json +3 -3
- package/readme.md +176 -23
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/clusterrelaycredential.ts +149 -0
- package/ts/data/corestorecontroltoken.ts +195 -0
- package/ts/data/index.ts +2 -0
- package/ts/data/networkaddressplan.ts +3 -13
- package/ts/data/networkauthority.ts +46 -0
- package/ts/data/networkcredential.ts +17 -12
- package/ts/data/networkegressretirement.ts +195 -0
- package/ts/data/noderetirement.ts +41 -5
- package/ts/private/networkcontract.ts +9 -0
- package/ts/requests/cluster.ts +44 -0
- package/ts/requests/corestorecontrol.ts +43 -0
- package/ts/requests/index.ts +2 -0
- package/ts/requests/node.ts +9 -1
package/changelog.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-10-02 - 32.42.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- A cluster topology change no longer ends every node's managed VPN membership. The new
|
|
8
|
+
`continuesRuntimeNetworkProtection(previous, next)` states which protected-authority successor
|
|
9
|
+
only adds: the same authority, or exactly its next step that keeps every egress owner, pool,
|
|
10
|
+
resolver and platform endpoint unchanged and still covers every protected address.
|
|
11
|
+
`continuesRuntimeManagedVpnMembership` and `bindGetRuntimeManagedVpnCredentialSuccessor` accept
|
|
12
|
+
such a step where they required the same authority, so a node joining the egress or a cluster
|
|
13
|
+
hub joining the platform endpoints keeps each member's key pair and hub session. A step that
|
|
14
|
+
removes or changes anything, or skips a step, still ends the membership, and every egress owner
|
|
15
|
+
still acknowledges the new authority with its own protection receipt before an allocation binds
|
|
16
|
+
to it.
|
|
17
|
+
- An administrator can store the Corestore control token without an exec into Cloudly's process.
|
|
18
|
+
`requests.corestorecontrol.IReq_Admin_Cloudly_SetCorestoreControlToken`
|
|
19
|
+
(`setCorestoreControlToken { identity, token, expected }`) stores it for both Corestore provider
|
|
20
|
+
configs, fenced on the exact `data.TCorestoreControlTokenState` the administrator last read
|
|
21
|
+
(absent, or present at a revision), and answers the produced state and a value-free receipt
|
|
22
|
+
Cloudly writes with the token. `IReq_Admin_Cloudly_GetCorestoreControlTokenState` answers the
|
|
23
|
+
state and its most recent receipts. `data.corestoreControlTokenSetRefusals` names the refusals;
|
|
24
|
+
`bindCorestoreControlTokenSet` and the exact-keyed snapshots check an answer without ever
|
|
25
|
+
quoting the token, and the request reader admits only a token `isCorestoreControlToken` admits.
|
|
26
|
+
- An egress owner can now leave the protected authority. `IRuntimeNetworkEgressRetirement` is the
|
|
27
|
+
controller-owned fence for one owner, recorded against the exact authority it leaves: its node
|
|
28
|
+
retirement row, both node credentials revoked, every DNS and managed VPN window it was issued
|
|
29
|
+
ended, every handoff and workload lease quarantined, and every remaining owner's acknowledged
|
|
30
|
+
projection head free of its endpoints. `snapshotRuntimeNetworkEgressRetirement` reads it with exact
|
|
31
|
+
keys and `computeRuntimeNetworkEgressRetirementDigest` seals it.
|
|
32
|
+
`bindRuntimeNetworkProtectedAuthorityRetirement(previous, next, fences, retiredOwners)` is the pure,
|
|
33
|
+
fail-closed successor rule: an owner may be absent from `next` only behind a fence bound to the
|
|
34
|
+
exact `previous`, a fence for an owner still named refuses the step, a fenced owner never returns,
|
|
35
|
+
and pools, prefix coverage and — when an owner leaves — resolvers are kept. Owners may join in the
|
|
36
|
+
same step. Before this, an owner that left blocked every new allocation after the next protection
|
|
37
|
+
change, permanently.
|
|
38
|
+
- `INodeRuntimeRetirement` states its `disposition` (`withdrawn` or `lost`,
|
|
39
|
+
`nodeRuntimeRetirementDispositions`, `snapshotNodeRuntimeRetirementDisposition`), and
|
|
40
|
+
`retireClusterNode` takes an optional `disposition`: absent asks for `withdrawn`, the retirement
|
|
41
|
+
it always described, and `lost` escalates a `withdrawn` retirement still `retiring`. The new
|
|
42
|
+
refusal `node-still-reporting` refuses `lost` for a node that still reports. Cloudly serves
|
|
43
|
+
neither yet, so no stored row or caller is affected.
|
|
44
|
+
|
|
45
|
+
### Fixes
|
|
46
|
+
|
|
47
|
+
- Require `@push.rocks/smartlog` ^4.0.3, which reaches `@push.rocks/smartcrypto` 3 and no longer brings `node-forge` (advisory GHSA-86w9-cpqp-85rv, no patched release) into consumers' production trees.
|
|
48
|
+
|
|
49
|
+
### Maintenance
|
|
50
|
+
|
|
51
|
+
- Release tooling: `@git.zone/tsbuild` 5.1.1 and pnpm 12.7.0.
|
|
52
|
+
|
|
53
|
+
## 2026-10-02 - 32.41.0
|
|
54
|
+
|
|
55
|
+
### Features
|
|
56
|
+
|
|
57
|
+
- An administrator can export a cluster relay's bearer without an exec into Cloudly's process.
|
|
58
|
+
`exportClusterRelayAuthorization { identity, clusterId, expectedGeneration }` answers
|
|
59
|
+
`IClusterRelayAuthorizationExport`: the sealed relay credential at exactly that generation, the
|
|
60
|
+
bearer it delivered (`authorization`) and the audit `receipt` Cloudly writes before it answers.
|
|
61
|
+
Cloudly mints nothing to answer it; a new bearer is a `rotate` followed by an export.
|
|
62
|
+
`getClusterRelayAuthorizationExports { identity, clusterId }` answers the value-free receipts.
|
|
63
|
+
`data.clusterRelayAuthorizationExportRefusals` names the refusals, and
|
|
64
|
+
`bindClusterRelayAuthorizationExport`, `isClusterRelayAuthorization` and the exact-keyed
|
|
65
|
+
snapshots let a reader check an answer before it writes the bearer, without ever quoting it.
|
|
66
|
+
|
|
3
67
|
## 2026-10-02 - 32.40.1
|
|
4
68
|
|
|
5
69
|
### Fixes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '32.
|
|
6
|
+
version: '32.42.0',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
|
@@ -106,6 +106,50 @@ export interface IClusterLegacyRelayCredentialRetirementResult {
|
|
|
106
106
|
/** A replay returns the recorded invalidation; nothing is revoked twice. */
|
|
107
107
|
replayed: boolean;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* What an administrator names to export one cluster's relay bearer: the cluster, at exactly the
|
|
111
|
+
* generation `getClusterRelayCredential` answered. Never a minimum: a rotation that committed
|
|
112
|
+
* after that read is refused rather than answered with a bearer the operator did not ask for.
|
|
113
|
+
*/
|
|
114
|
+
export interface IClusterRelayAuthorizationExportRequest {
|
|
115
|
+
clusterId: string;
|
|
116
|
+
expectedGeneration: number;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The audit record of one answered export, which Cloudly writes before it answers the bearer.
|
|
120
|
+
*
|
|
121
|
+
* Append-only and value-free: it names who received which credential's bearer and when, never
|
|
122
|
+
* the bearer or a hash of it. Every answered export writes one, so a retried export is a second
|
|
123
|
+
* receipt rather than a replay: each is a separate handover of the same bearer.
|
|
124
|
+
*/
|
|
125
|
+
export interface IClusterRelayAuthorizationExportReceipt {
|
|
126
|
+
id: string;
|
|
127
|
+
clusterId: string;
|
|
128
|
+
/** The exact relay credential whose bearer was answered: identity, generation and digest. */
|
|
129
|
+
credential: IRuntimeAuthorityReference;
|
|
130
|
+
/** The administrator the bearer was answered to, read from the verified credential. */
|
|
131
|
+
actorId: string;
|
|
132
|
+
exportedAt: number;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* One cluster's relay bearer, answered to an administrator so it can be handed to the relay
|
|
136
|
+
* without reaching into Cloudly's process.
|
|
137
|
+
*
|
|
138
|
+
* The only member of this contract that carries a bearer. It is the delivered version the
|
|
139
|
+
* credential names, at the requested generation, proved against the hash that generation issued;
|
|
140
|
+
* Cloudly mints nothing to answer it. The reader owns the bytes: it writes them where the relay
|
|
141
|
+
* reads them and never logs, prints or persists them anywhere else.
|
|
142
|
+
*/
|
|
143
|
+
export interface IClusterRelayAuthorizationExport {
|
|
144
|
+
/** The relay credential the bearer authenticates as, at exactly the requested generation. */
|
|
145
|
+
credential: IClusterRelayCredential;
|
|
146
|
+
/**
|
|
147
|
+
* The bearer, byte for byte what the relay presents: `clusterRelayToken_`, the credential's
|
|
148
|
+
* 64-hex `id`, `_` and 64 hex characters, with no line terminator.
|
|
149
|
+
*/
|
|
150
|
+
authorization: string;
|
|
151
|
+
receipt: IClusterRelayAuthorizationExportReceipt;
|
|
152
|
+
}
|
|
109
153
|
export declare const clusterRelayCredentialContract: Readonly<{
|
|
110
154
|
readonly credentialDigestDomain: "serve.zone/cluster-relay-credential";
|
|
111
155
|
readonly legacyCredentialDigestDomain: "serve.zone/cluster-relay-legacy-credential";
|
|
@@ -114,6 +158,12 @@ export declare const clusterRelayCredentialContract: Readonly<{
|
|
|
114
158
|
/** Every reason Cloudly answers instead of mutating or retiring a cluster relay authority. */
|
|
115
159
|
export declare const clusterRelayCredentialRefusals: readonly ["relay-credential-absent", "legacy-credential-absent", "legacy-credential-already-retired", "legacy-retirement-replacement-not-current", "legacy-retirement-registration-not-current", "legacy-retirement-relay-not-live", "conflict"];
|
|
116
160
|
export type TClusterRelayCredentialRefusal = typeof clusterRelayCredentialRefusals[number];
|
|
161
|
+
/**
|
|
162
|
+
* Every reason Cloudly answers instead of a relay bearer. Its own family, because an export
|
|
163
|
+
* changes no record: it has no `conflict`, and a generation it was not asked for is a mismatch.
|
|
164
|
+
*/
|
|
165
|
+
export declare const clusterRelayAuthorizationExportRefusals: readonly ["relay-credential-absent", "relay-credential-generation-mismatch", "relay-authorization-missing", "relay-authorization-ambiguous"];
|
|
166
|
+
export type TClusterRelayAuthorizationExportRefusal = typeof clusterRelayAuthorizationExportRefusals[number];
|
|
117
167
|
/** Structural copy only; whether the record is the cluster's current one is Cloudly's to decide. */
|
|
118
168
|
export declare const snapshotClusterRelayCredential: (valueArg: unknown) => IClusterRelayCredential;
|
|
119
169
|
export declare const computeClusterRelayCredentialDigest: (valueArg: unknown) => Promise<TSha256Digest>;
|
|
@@ -138,4 +188,26 @@ export declare const bindClusterLegacyRelayCredentialInvalidation: (invalidation
|
|
|
138
188
|
legacyCredential: IClusterLegacyRelayCredential;
|
|
139
189
|
acceptedRegistration: IClusterRelayAcceptedRegistration;
|
|
140
190
|
}>;
|
|
191
|
+
/**
|
|
192
|
+
* Whether a value has the exact shape of a relay bearer: `clusterRelayToken_<64 hex>_<64 hex>`.
|
|
193
|
+
*
|
|
194
|
+
* Shape only: whether it authenticates is Cloudly's to decide against the hash it keeps.
|
|
195
|
+
*/
|
|
196
|
+
export declare const isClusterRelayAuthorization: (valueArg: unknown) => valueArg is string;
|
|
197
|
+
export declare const snapshotClusterRelayAuthorizationExportRequest: (valueArg: unknown) => IClusterRelayAuthorizationExportRequest;
|
|
198
|
+
export declare const snapshotClusterRelayAuthorizationExportReceipt: (valueArg: unknown) => IClusterRelayAuthorizationExportReceipt;
|
|
199
|
+
/**
|
|
200
|
+
* Structural copy of an export answer. A refusal never quotes the answer, because it carries a
|
|
201
|
+
* bearer: every failure is the contract's one value-free message.
|
|
202
|
+
*/
|
|
203
|
+
export declare const snapshotClusterRelayAuthorizationExport: (valueArg: unknown) => IClusterRelayAuthorizationExport;
|
|
204
|
+
/**
|
|
205
|
+
* Joins an export answer to the request it answers, before a reader writes a byte of the bearer.
|
|
206
|
+
*
|
|
207
|
+
* The credential is sealed with its own digest and is the requested cluster's at exactly the
|
|
208
|
+
* requested generation; the bearer names that credential; the receipt names that cluster and that
|
|
209
|
+
* exact credential. Content join only: whether the bearer authenticates is Cloudly's to prove,
|
|
210
|
+
* and Cloudly proves it before it answers.
|
|
211
|
+
*/
|
|
212
|
+
export declare const bindClusterRelayAuthorizationExport: (exportArg: unknown, requestArg: unknown) => Promise<IClusterRelayAuthorizationExport>;
|
|
141
213
|
export {};
|
|
@@ -22,6 +22,20 @@ export const clusterRelayCredentialRefusals = Object.freeze([
|
|
|
22
22
|
/** An expected generation was not the exact current one, or a mutation ID met a changed body. */
|
|
23
23
|
'conflict',
|
|
24
24
|
]);
|
|
25
|
+
/**
|
|
26
|
+
* Every reason Cloudly answers instead of a relay bearer. Its own family, because an export
|
|
27
|
+
* changes no record: it has no `conflict`, and a generation it was not asked for is a mismatch.
|
|
28
|
+
*/
|
|
29
|
+
export const clusterRelayAuthorizationExportRefusals = Object.freeze([
|
|
30
|
+
/** No relay credential is minted for the cluster. */
|
|
31
|
+
'relay-credential-absent',
|
|
32
|
+
/** The credential is at another generation than the one named, before the read or after it. */
|
|
33
|
+
'relay-credential-generation-mismatch',
|
|
34
|
+
/** The version the credential delivered is not stored as an active version. */
|
|
35
|
+
'relay-authorization-missing',
|
|
36
|
+
/** The secret's active version, or its bytes, are not what the credential issued. */
|
|
37
|
+
'relay-authorization-ambiguous',
|
|
38
|
+
]);
|
|
25
39
|
const fail = () => { throw new Error('Cluster relay credential contract rejected.'); };
|
|
26
40
|
const safe = (operationArg) => {
|
|
27
41
|
try {
|
|
@@ -189,4 +203,71 @@ export const bindClusterLegacyRelayCredentialInvalidation = async (invalidationA
|
|
|
189
203
|
return fail();
|
|
190
204
|
}
|
|
191
205
|
};
|
|
192
|
-
|
|
206
|
+
const clusterRelayAuthorizationPrefix = 'clusterRelayToken_';
|
|
207
|
+
const clusterRelayAuthorizationPattern = /^clusterRelayToken_[a-f0-9]{64}_[a-f0-9]{64}$/;
|
|
208
|
+
/**
|
|
209
|
+
* Whether a value has the exact shape of a relay bearer: `clusterRelayToken_<64 hex>_<64 hex>`.
|
|
210
|
+
*
|
|
211
|
+
* Shape only: whether it authenticates is Cloudly's to decide against the hash it keeps.
|
|
212
|
+
*/
|
|
213
|
+
export const isClusterRelayAuthorization = (valueArg) => typeof valueArg === 'string' && clusterRelayAuthorizationPattern.test(valueArg);
|
|
214
|
+
/** The credential identity a relay bearer names: the 64 hex characters after its prefix. */
|
|
215
|
+
const clusterRelayAuthorizationCredentialId = (authorizationArg) => authorizationArg.slice(clusterRelayAuthorizationPrefix.length, clusterRelayAuthorizationPrefix.length + 64);
|
|
216
|
+
export const snapshotClusterRelayAuthorizationExportRequest = (valueArg) => safe(() => {
|
|
217
|
+
const value = networkRecord(captureNetwork(valueArg), ['clusterId', 'expectedGeneration']);
|
|
218
|
+
return {
|
|
219
|
+
clusterId: networkId(value.clusterId),
|
|
220
|
+
expectedGeneration: networkCounter(value.expectedGeneration),
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
export const snapshotClusterRelayAuthorizationExportReceipt = (valueArg) => safe(() => {
|
|
224
|
+
const value = networkRecord(captureNetwork(valueArg), [
|
|
225
|
+
'id', 'clusterId', 'credential', 'actorId', 'exportedAt',
|
|
226
|
+
]);
|
|
227
|
+
return {
|
|
228
|
+
id: networkId(value.id),
|
|
229
|
+
clusterId: networkId(value.clusterId),
|
|
230
|
+
credential: networkReference(value.credential),
|
|
231
|
+
actorId: networkId(value.actorId),
|
|
232
|
+
exportedAt: networkCounter(value.exportedAt),
|
|
233
|
+
};
|
|
234
|
+
});
|
|
235
|
+
/**
|
|
236
|
+
* Structural copy of an export answer. A refusal never quotes the answer, because it carries a
|
|
237
|
+
* bearer: every failure is the contract's one value-free message.
|
|
238
|
+
*/
|
|
239
|
+
export const snapshotClusterRelayAuthorizationExport = (valueArg) => safe(() => {
|
|
240
|
+
const value = networkRecord(captureNetwork(valueArg), ['credential', 'authorization', 'receipt']);
|
|
241
|
+
requireNetwork(isClusterRelayAuthorization(value.authorization));
|
|
242
|
+
return {
|
|
243
|
+
credential: snapshotClusterRelayCredential(value.credential),
|
|
244
|
+
authorization: value.authorization,
|
|
245
|
+
receipt: snapshotClusterRelayAuthorizationExportReceipt(value.receipt),
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
/**
|
|
249
|
+
* Joins an export answer to the request it answers, before a reader writes a byte of the bearer.
|
|
250
|
+
*
|
|
251
|
+
* The credential is sealed with its own digest and is the requested cluster's at exactly the
|
|
252
|
+
* requested generation; the bearer names that credential; the receipt names that cluster and that
|
|
253
|
+
* exact credential. Content join only: whether the bearer authenticates is Cloudly's to prove,
|
|
254
|
+
* and Cloudly proves it before it answers.
|
|
255
|
+
*/
|
|
256
|
+
export const bindClusterRelayAuthorizationExport = async (exportArg, requestArg) => {
|
|
257
|
+
try {
|
|
258
|
+
const request = snapshotClusterRelayAuthorizationExportRequest(requestArg);
|
|
259
|
+
const answer = snapshotClusterRelayAuthorizationExport(exportArg);
|
|
260
|
+
if ((await validateClusterRelayCredential(answer.credential)).length)
|
|
261
|
+
fail();
|
|
262
|
+
requireNetwork(answer.credential.clusterId === request.clusterId
|
|
263
|
+
&& answer.credential.generation === request.expectedGeneration
|
|
264
|
+
&& clusterRelayAuthorizationCredentialId(answer.authorization) === answer.credential.id
|
|
265
|
+
&& answer.receipt.clusterId === request.clusterId
|
|
266
|
+
&& networkEqual(answer.receipt.credential, networkReferenceOf(answer.credential)));
|
|
267
|
+
return answer;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return fail();
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3RlcnJlbGF5Y3JlZGVudGlhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvY2x1c3RlcnJlbGF5Y3JlZGVudGlhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQ0wsd0NBQXdDLEVBQ3hDLHdDQUF3QyxHQUN6QyxNQUFNLGNBQWMsQ0FBQztBQUt0QixPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFDZCxhQUFhLEVBQ2IsWUFBWSxFQUNaLFdBQVcsRUFDWCxTQUFTLEVBQ1QsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsY0FBYyxHQUNmLE1BQU0sK0JBQStCLENBQUM7QUE2SnZDLE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUQsc0JBQXNCLEVBQUUscUNBQXFDO0lBQzdELDRCQUE0QixFQUFFLDRDQUE0QztJQUMxRSw4QkFBOEIsRUFBRSx5REFBeUQ7Q0FDakYsQ0FBQyxDQUFDO0FBRVosOEZBQThGO0FBQzlGLE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUQsbUVBQW1FO0lBQ25FLHlCQUF5QjtJQUN6QiwyRUFBMkU7SUFDM0UsMEJBQTBCO0lBQzFCLGlGQUFpRjtJQUNqRixtQ0FBbUM7SUFDbkMsNkZBQTZGO0lBQzdGLDJDQUEyQztJQUMzQyxpR0FBaUc7SUFDakcsNENBQTRDO0lBQzVDLHNGQUFzRjtJQUN0RixrQ0FBa0M7SUFDbEMsaUdBQWlHO0lBQ2pHLFVBQVU7Q0FDRixDQUFDLENBQUM7QUFJWjs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSx1Q0FBdUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ25FLHFEQUFxRDtJQUNyRCx5QkFBeUI7SUFDekIsK0ZBQStGO0lBQy9GLHNDQUFzQztJQUN0QywrRUFBK0U7SUFDL0UsNkJBQTZCO0lBQzdCLHFGQUFxRjtJQUNy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
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether Cloudly holds the Corestore control token, and at which revision. Value-free.
|
|
3
|
+
*
|
|
4
|
+
* There is one token for both Corestore provider configs, so this is one state rather than one per
|
|
5
|
+
* provider. `revision` is 1 for the first token ever stored and advances by exactly one with every
|
|
6
|
+
* accepted set, whichever path set it. No request removes a token, so a present token never turns
|
|
7
|
+
* absent again.
|
|
8
|
+
*/
|
|
9
|
+
export type TCorestoreControlTokenState = {
|
|
10
|
+
state: 'absent';
|
|
11
|
+
} | {
|
|
12
|
+
state: 'present';
|
|
13
|
+
revision: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* What an administrator names to store the Corestore control token: the token, and the state the
|
|
17
|
+
* administrator last read. Never a minimum: a set that committed after that read is refused rather
|
|
18
|
+
* than overwritten.
|
|
19
|
+
*
|
|
20
|
+
* `token` is the secret itself, the only member of this contract that carries it. A sender never
|
|
21
|
+
* logs, hooks or persists the request; Cloudly never answers or records the token.
|
|
22
|
+
*/
|
|
23
|
+
export interface ICorestoreControlTokenSetRequest {
|
|
24
|
+
token: string;
|
|
25
|
+
expected: TCorestoreControlTokenState;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Which path stored a token: an administrator's typed request, or the `secrets
|
|
29
|
+
* set-corestore-control-token` command run inside Cloudly's container.
|
|
30
|
+
*/
|
|
31
|
+
export type TCorestoreControlTokenSetPath = 'admin-request' | 'container-cli';
|
|
32
|
+
/**
|
|
33
|
+
* The audit record of one accepted set, which Cloudly writes in the transaction that stores the
|
|
34
|
+
* token. Append-only and value-free: it names which revision was stored, by whom, how and when,
|
|
35
|
+
* never the token or a hash of it.
|
|
36
|
+
*/
|
|
37
|
+
export interface ICorestoreControlTokenSetReceipt {
|
|
38
|
+
id: string;
|
|
39
|
+
/** The revision this set stored. */
|
|
40
|
+
revision: number;
|
|
41
|
+
via: TCorestoreControlTokenSetPath;
|
|
42
|
+
/** The administrator read from the verified credential, or `operator:secrets-cli`. */
|
|
43
|
+
actorId: string;
|
|
44
|
+
setAt: number;
|
|
45
|
+
}
|
|
46
|
+
/** What Cloudly answers to an accepted set: the state it produced and its receipt. Value-free. */
|
|
47
|
+
export interface ICorestoreControlTokenSetResult {
|
|
48
|
+
state: {
|
|
49
|
+
state: 'present';
|
|
50
|
+
revision: number;
|
|
51
|
+
};
|
|
52
|
+
receipt: ICorestoreControlTokenSetReceipt;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The token's state and its most recent receipts, oldest first: every receipt while the token has
|
|
56
|
+
* been set at most `corestoreControlTokenMaximumReceipts` times, the latest that many after. Value-free.
|
|
57
|
+
*/
|
|
58
|
+
export interface ICorestoreControlTokenStateRead {
|
|
59
|
+
state: TCorestoreControlTokenState;
|
|
60
|
+
receipts: ICorestoreControlTokenSetReceipt[];
|
|
61
|
+
}
|
|
62
|
+
/** Every reason Cloudly answers instead of storing a Corestore control token. */
|
|
63
|
+
export declare const corestoreControlTokenSetRefusals: readonly ["token-invalid", "token-present", "token-absent", "token-revision-mismatch", "provider-unavailable"];
|
|
64
|
+
export type TCorestoreControlTokenSetRefusal = typeof corestoreControlTokenSetRefusals[number];
|
|
65
|
+
/** The actor a receipt names when the in-container command stored the token. */
|
|
66
|
+
export declare const corestoreControlTokenContainerCliActorId: "operator:secrets-cli";
|
|
67
|
+
/** The most receipts one state read answers: the latest ones, once a token has been set more often. */
|
|
68
|
+
export declare const corestoreControlTokenMaximumReceipts = 4096;
|
|
69
|
+
export declare const snapshotCorestoreControlTokenState: (valueArg: unknown) => TCorestoreControlTokenState;
|
|
70
|
+
/**
|
|
71
|
+
* Structural copy of a set request. A refusal never quotes the request, because it carries the
|
|
72
|
+
* token: every failure is the contract's one value-free message.
|
|
73
|
+
*/
|
|
74
|
+
export declare const snapshotCorestoreControlTokenSetRequest: (valueArg: unknown) => ICorestoreControlTokenSetRequest;
|
|
75
|
+
export declare const snapshotCorestoreControlTokenSetReceipt: (valueArg: unknown) => ICorestoreControlTokenSetReceipt;
|
|
76
|
+
export declare const snapshotCorestoreControlTokenSetResult: (valueArg: unknown) => ICorestoreControlTokenSetResult;
|
|
77
|
+
/**
|
|
78
|
+
* Structural copy of a state read. No token stored means no receipt. A stored token's receipts are
|
|
79
|
+
* contiguous and end at its revision, and they start at revision 1 -- or at 2, because only a token
|
|
80
|
+
* stored before receipts existed reaches revision 1 without one -- unless the read is a full window
|
|
81
|
+
* of `corestoreControlTokenMaximumReceipts`, whose oldest receipt may name any later revision.
|
|
82
|
+
*/
|
|
83
|
+
export declare const snapshotCorestoreControlTokenStateRead: (valueArg: unknown) => ICorestoreControlTokenStateRead;
|
|
84
|
+
/**
|
|
85
|
+
* Joins a set answer to the request it answers. The answered state is the one the request
|
|
86
|
+
* produces -- revision 1 when no token was stored, the expected revision plus one otherwise -- and
|
|
87
|
+
* the receipt is an administrator's receipt for exactly that revision. Content join only: whether
|
|
88
|
+
* the token was stored is Cloudly's to prove, and the answer never carries it.
|
|
89
|
+
*/
|
|
90
|
+
export declare const bindCorestoreControlTokenSet: (resultArg: unknown, requestArg: unknown) => ICorestoreControlTokenSetResult;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isCorestoreControlToken } from '../runtime.corestore.js';
|
|
2
|
+
import { captureNetwork, networkCounter, networkId, networkList, networkRecord, requireNetwork, } from '../private/networkcontract.js';
|
|
3
|
+
/** Every reason Cloudly answers instead of storing a Corestore control token. */
|
|
4
|
+
export const corestoreControlTokenSetRefusals = Object.freeze([
|
|
5
|
+
/** The token is outside the contract: its length, encoding or whitespace (`isCorestoreControlToken`). */
|
|
6
|
+
'token-invalid',
|
|
7
|
+
/** `expected` said absent, and a token is stored. */
|
|
8
|
+
'token-present',
|
|
9
|
+
/** `expected` named a revision, and no token is stored. */
|
|
10
|
+
'token-absent',
|
|
11
|
+
/** `expected` named a revision, and the stored token is at another one. */
|
|
12
|
+
'token-revision-mismatch',
|
|
13
|
+
/** A Corestore provider config is missing or disabled, so there is nothing to store it under. */
|
|
14
|
+
'provider-unavailable',
|
|
15
|
+
]);
|
|
16
|
+
/** The actor a receipt names when the in-container command stored the token. */
|
|
17
|
+
export const corestoreControlTokenContainerCliActorId = 'operator:secrets-cli';
|
|
18
|
+
/** The most receipts one state read answers: the latest ones, once a token has been set more often. */
|
|
19
|
+
export const corestoreControlTokenMaximumReceipts = 4096;
|
|
20
|
+
const fail = () => { throw new Error('Corestore control token contract rejected.'); };
|
|
21
|
+
const safe = (operationArg) => {
|
|
22
|
+
try {
|
|
23
|
+
return operationArg();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return fail();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const readState = (valueArg) => {
|
|
30
|
+
const value = networkRecord(valueArg, ['state'], ['revision']);
|
|
31
|
+
if (value.state === 'absent') {
|
|
32
|
+
networkRecord(value, ['state']);
|
|
33
|
+
return { state: 'absent' };
|
|
34
|
+
}
|
|
35
|
+
requireNetwork(value.state === 'present');
|
|
36
|
+
return { state: 'present', revision: networkCounter(networkRecord(value, ['state', 'revision']).revision) };
|
|
37
|
+
};
|
|
38
|
+
export const snapshotCorestoreControlTokenState = (valueArg) => safe(() => readState(captureNetwork(valueArg)));
|
|
39
|
+
/**
|
|
40
|
+
* Structural copy of a set request. A refusal never quotes the request, because it carries the
|
|
41
|
+
* token: every failure is the contract's one value-free message.
|
|
42
|
+
*/
|
|
43
|
+
export const snapshotCorestoreControlTokenSetRequest = (valueArg) => safe(() => {
|
|
44
|
+
const value = networkRecord(captureNetwork(valueArg), ['token', 'expected']);
|
|
45
|
+
requireNetwork(isCorestoreControlToken(value.token));
|
|
46
|
+
return { token: value.token, expected: readState(value.expected) };
|
|
47
|
+
});
|
|
48
|
+
const readReceipt = (valueArg) => {
|
|
49
|
+
const value = networkRecord(valueArg, ['id', 'revision', 'via', 'actorId', 'setAt']);
|
|
50
|
+
requireNetwork(value.via === 'admin-request' || value.via === 'container-cli');
|
|
51
|
+
const actorId = networkId(value.actorId);
|
|
52
|
+
requireNetwork(value.via === 'admin-request'
|
|
53
|
+
? actorId !== corestoreControlTokenContainerCliActorId
|
|
54
|
+
: actorId === corestoreControlTokenContainerCliActorId);
|
|
55
|
+
return {
|
|
56
|
+
id: networkId(value.id),
|
|
57
|
+
revision: networkCounter(value.revision),
|
|
58
|
+
via: value.via,
|
|
59
|
+
actorId,
|
|
60
|
+
setAt: networkCounter(value.setAt),
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export const snapshotCorestoreControlTokenSetReceipt = (valueArg) => safe(() => readReceipt(captureNetwork(valueArg)));
|
|
64
|
+
export const snapshotCorestoreControlTokenSetResult = (valueArg) => safe(() => {
|
|
65
|
+
const value = networkRecord(captureNetwork(valueArg), ['state', 'receipt']);
|
|
66
|
+
const state = readState(value.state);
|
|
67
|
+
requireNetwork(state.state === 'present');
|
|
68
|
+
return { state, receipt: readReceipt(value.receipt) };
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Structural copy of a state read. No token stored means no receipt. A stored token's receipts are
|
|
72
|
+
* contiguous and end at its revision, and they start at revision 1 -- or at 2, because only a token
|
|
73
|
+
* stored before receipts existed reaches revision 1 without one -- unless the read is a full window
|
|
74
|
+
* of `corestoreControlTokenMaximumReceipts`, whose oldest receipt may name any later revision.
|
|
75
|
+
*/
|
|
76
|
+
export const snapshotCorestoreControlTokenStateRead = (valueArg) => safe(() => {
|
|
77
|
+
const value = networkRecord(captureNetwork(valueArg), ['state', 'receipts']);
|
|
78
|
+
const state = readState(value.state);
|
|
79
|
+
const receipts = networkList(value.receipts, corestoreControlTokenMaximumReceipts, readReceipt);
|
|
80
|
+
if (state.state === 'absent') {
|
|
81
|
+
requireNetwork(receipts.length === 0);
|
|
82
|
+
return { state, receipts };
|
|
83
|
+
}
|
|
84
|
+
const first = state.revision - receipts.length + 1;
|
|
85
|
+
requireNetwork(first >= 1
|
|
86
|
+
&& (first <= 2 || receipts.length === corestoreControlTokenMaximumReceipts)
|
|
87
|
+
&& receipts.every((receipt, index) => receipt.revision === first + index));
|
|
88
|
+
return { state, receipts };
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* Joins a set answer to the request it answers. The answered state is the one the request
|
|
92
|
+
* produces -- revision 1 when no token was stored, the expected revision plus one otherwise -- and
|
|
93
|
+
* the receipt is an administrator's receipt for exactly that revision. Content join only: whether
|
|
94
|
+
* the token was stored is Cloudly's to prove, and the answer never carries it.
|
|
95
|
+
*/
|
|
96
|
+
export const bindCorestoreControlTokenSet = (resultArg, requestArg) => safe(() => {
|
|
97
|
+
const request = snapshotCorestoreControlTokenSetRequest(requestArg);
|
|
98
|
+
const result = snapshotCorestoreControlTokenSetResult(resultArg);
|
|
99
|
+
const produced = request.expected.state === 'absent' ? 1 : request.expected.revision + 1;
|
|
100
|
+
requireNetwork(Number.isSafeInteger(produced)
|
|
101
|
+
&& result.state.revision === produced
|
|
102
|
+
&& result.receipt.revision === produced
|
|
103
|
+
&& result.receipt.via === 'admin-request');
|
|
104
|
+
return result;
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZXN0b3JlY29udHJvbHRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZGF0YS9jb3Jlc3RvcmVjb250cm9sdG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbEUsT0FBTyxFQUNMLGNBQWMsRUFDZCxjQUFjLEVBQ2QsU0FBUyxFQUNULFdBQVcsRUFDWCxhQUFhLEVBQ2IsY0FBYyxHQUNmLE1BQU0sK0JBQStCLENBQUM7QUErRHZDLGlGQUFpRjtBQUNqRixNQUFNLENBQUMsTUFBTSxnQ0FBZ0MsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzVELHlHQUF5RztJQUN6RyxlQUFlO0lBQ2YscURBQXFEO0lBQ3JELGVBQWU7SUFDZiwyREFBMkQ7SUFDM0QsY0FBYztJQUNkLDJFQUEyRTtJQUMzRSx5QkFBeUI7SUFDekIsaUdBQWlHO0lBQ2pHLHNCQUFzQjtDQUNkLENBQUMsQ0FBQztBQUlaLGdGQUFnRjtBQUNoRixNQUFNLENBQUMsTUFBTSx3Q0FBd0MsR0FBRyxzQkFBK0IsQ0FBQztBQUV4Rix1R0FBdUc7QUFDdkcsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQUcsSUFBSSxDQUFDO0FBRXpELE1BQU0sSUFBSSxHQUFHLEdBQVUsRUFBRSxHQUFHLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RixNQUFNLElBQUksR0FBRyxDQUFJLFlBQXFCLEVBQUssRUFBRTtJQUMzQyxJQUFJLENBQUM7UUFBQyxPQUFPLFlBQVksRUFBRSxDQUFDO0lBQUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFBQyxDQUFDO0FBQ3pELENBQUMsQ0FBQztBQUVGLE1BQU0sU0FBUyxHQUFHLENBQUMsUUFBaUIsRUFBK0IsRUFBRTtJQUNuRSxNQUFNLEtBQUssR0FB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
|
package/dist_ts/data/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './clusteringressdesignation.js';
|
|
|
7
7
|
export * from './clusterrelaycredential.js';
|
|
8
8
|
export * from './config.js';
|
|
9
9
|
export * from './corestore.js';
|
|
10
|
+
export * from './corestorecontroltoken.js';
|
|
10
11
|
export * from './corestorelegacyadoption.js';
|
|
11
12
|
export * from './coremail.js';
|
|
12
13
|
export * from './coremail.runtime.js';
|
|
@@ -38,6 +39,7 @@ export * from './networkaddressplan.js';
|
|
|
38
39
|
export * from './networkauthority.js';
|
|
39
40
|
export * from './networkcredential.js';
|
|
40
41
|
export * from './networkdelivery.js';
|
|
42
|
+
export * from './networkegressretirement.js';
|
|
41
43
|
export * from './networklease.js';
|
|
42
44
|
export * from './networknode.js';
|
|
43
45
|
export * from './networkprojection.js';
|
package/dist_ts/data/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from './clusteringressdesignation.js';
|
|
|
7
7
|
export * from './clusterrelaycredential.js';
|
|
8
8
|
export * from './config.js';
|
|
9
9
|
export * from './corestore.js';
|
|
10
|
+
export * from './corestorecontroltoken.js';
|
|
10
11
|
export * from './corestorelegacyadoption.js';
|
|
11
12
|
export * from './coremail.js';
|
|
12
13
|
export * from './coremail.runtime.js';
|
|
@@ -38,6 +39,7 @@ export * from './networkaddressplan.js';
|
|
|
38
39
|
export * from './networkauthority.js';
|
|
39
40
|
export * from './networkcredential.js';
|
|
40
41
|
export * from './networkdelivery.js';
|
|
42
|
+
export * from './networkegressretirement.js';
|
|
41
43
|
export * from './networklease.js';
|
|
42
44
|
export * from './networknode.js';
|
|
43
45
|
export * from './networkprojection.js';
|
|
@@ -77,4 +79,4 @@ export * from './traffic.js';
|
|
|
77
79
|
export * from './user.js';
|
|
78
80
|
export * from './version.js';
|
|
79
81
|
export * from './webpush.js';
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyxpQkFBaUIsQ0FBQztBQUNoQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLFVBQVUsQ0FBQztBQUN6QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLFdBQVcsQ0FBQztBQUMxQixjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyx3QkFBd0IsQ0FBQztBQUd2QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUc5RCxPQUFPLEVBQUUscUNBQXFDLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNwRixjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGtDQUFrQyxDQUFDO0FBQ2pELGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxXQUFXLENBQUM7QUFDMUIsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxjQUFjLENBQUMifQ==
|