@dcl/sdk 7.29.1-36591934525.commit-48aa9b5 → 7.29.1-36625469671.commit-2d5ffac

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/atom.d.ts +19 -0
  2. package/atom.js +83 -0
  3. package/future.d.ts +8 -0
  4. package/future.js +26 -0
  5. package/internal/transports/rendererTransport.js +5 -2
  6. package/network/binary-message-bus.d.ts +6 -3
  7. package/network/binary-message-bus.js +9 -5
  8. package/network/chunking.d.ts +5 -0
  9. package/network/chunking.js +38 -0
  10. package/network/events/implementation.d.ts +93 -0
  11. package/network/events/implementation.js +221 -0
  12. package/network/events/index.d.ts +42 -0
  13. package/network/events/index.js +43 -0
  14. package/network/events/protocol.d.ts +27 -0
  15. package/network/events/protocol.js +66 -0
  16. package/network/events/registry.d.ts +8 -0
  17. package/network/events/registry.js +3 -0
  18. package/network/index.d.ts +8 -2
  19. package/network/index.js +16 -3
  20. package/network/message-bus-sync.d.ts +16 -3
  21. package/network/message-bus-sync.js +164 -103
  22. package/network/server/index.d.ts +14 -0
  23. package/network/server/index.js +219 -0
  24. package/network/server/utils.d.ts +18 -0
  25. package/network/server/utils.js +135 -0
  26. package/network/state.js +3 -5
  27. package/package.json +6 -6
  28. package/server/env-var.d.ts +15 -0
  29. package/server/env-var.js +31 -0
  30. package/server/index.d.ts +2 -0
  31. package/server/index.js +3 -0
  32. package/server/storage/constants.d.ts +80 -0
  33. package/server/storage/constants.js +19 -0
  34. package/server/storage/error-message.d.ts +1 -0
  35. package/server/storage/error-message.js +9 -0
  36. package/server/storage/index.d.ts +54 -0
  37. package/server/storage/index.js +60 -0
  38. package/server/storage/player.d.ts +60 -0
  39. package/server/storage/player.js +244 -0
  40. package/server/storage/scene.d.ts +55 -0
  41. package/server/storage/scene.js +232 -0
  42. package/server/storage/serialize.d.ts +1 -0
  43. package/server/storage/serialize.js +135 -0
  44. package/server/storage/value-cache.d.ts +1 -0
  45. package/server/storage/value-cache.js +67 -0
  46. package/server/storage/write-queue.d.ts +1 -0
  47. package/server/storage/write-queue.js +113 -0
  48. package/server/storage-url.d.ts +13 -0
  49. package/server/storage-url.js +42 -0
  50. package/server/utils.d.ts +35 -0
  51. package/server/utils.js +69 -0
  52. package/src/atom.ts +98 -0
  53. package/src/future.ts +38 -0
  54. package/src/internal/transports/rendererTransport.ts +4 -1
  55. package/src/network/binary-message-bus.ts +9 -4
  56. package/src/network/chunking.ts +45 -0
  57. package/src/network/events/implementation.ts +271 -0
  58. package/src/network/events/index.ts +48 -0
  59. package/src/network/events/protocol.ts +94 -0
  60. package/src/network/events/registry.ts +18 -0
  61. package/src/network/index.ts +40 -3
  62. package/src/network/message-bus-sync.ts +180 -112
  63. package/src/network/server/index.ts +301 -0
  64. package/src/network/server/utils.ts +189 -0
  65. package/src/network/state.ts +3 -4
  66. package/src/server/env-var.ts +36 -0
  67. package/src/server/index.ts +12 -0
  68. package/src/server/storage/constants.ts +112 -0
  69. package/src/server/storage/error-message.ts +8 -0
  70. package/src/server/storage/index.ts +83 -0
  71. package/src/server/storage/player.ts +345 -0
  72. package/src/server/storage/scene.ts +324 -0
  73. package/src/server/storage/serialize.ts +132 -0
  74. package/src/server/storage/value-cache.ts +119 -0
  75. package/src/server/storage/write-queue.ts +174 -0
  76. package/src/server/storage-url.ts +49 -0
  77. package/src/server/utils.ts +83 -0
  78. package/explorer-ui/index.d.ts +0 -118
  79. package/explorer-ui/index.js +0 -235
  80. package/src/explorer-ui/index.ts +0 -398
@@ -0,0 +1,55 @@
1
+ import { GetOptions, GetValuesOptions, GetValuesResult, SetOptions } from './constants';
2
+ /**
3
+ * Scene-scoped storage interface for key-value pairs from the Server Side Storage service.
4
+ * This is NOT filesystem storage - data is stored in the remote storage service.
5
+ */
6
+ export interface ISceneStorage {
7
+ /**
8
+ * Retrieves a value from scene storage by key from the Server Side Storage service.
9
+ *
10
+ * By default (cacheReads), values read or written during the last cacheMaxAgeMs
11
+ * are served from a local cache without a network request, including confirmed
12
+ * "not found" results. Concurrent gets for the same key share one request.
13
+ * Out-of-band writers (e.g. CLI storage commands) may not be visible for up to
14
+ * cacheMaxAgeMs — pass { fresh: true } to force a network read.
15
+ * A read first waits for writes to the same key that were pending when it was
16
+ * issued, so it reflects every write issued before it.
17
+ * @param key - The key to retrieve
18
+ * @param options - Optional { fresh } to bypass the read cache
19
+ * @returns A promise that resolves to the parsed JSON value, or null if not found
20
+ * @throws Error if the read fails, so a failure is never mistaken for a missing key
21
+ * @throws TypeError if the key is invalid
22
+ */
23
+ get<T = unknown>(key: string, options?: GetOptions): Promise<T | null>;
24
+ /**
25
+ * Stores a value in scene storage in the Server Side Storage service.
26
+ * @param key - The key to store the value under
27
+ * @param value - The value to store (will be JSON serialized)
28
+ * @param options - Optional { skipIfUnchanged } to skip the network write when the value is already stored
29
+ * @returns true once stored, or once a newer write that replaced this one lands
30
+ * (rapid writes coalesce); false if the write, or its replacement, fails
31
+ * @throws TypeError if the key is invalid, or the value cannot be stored unchanged: undefined,
32
+ * circular, a BigInt, or containing a function, a symbol, a non-finite number, an undefined array
33
+ * element or hole, a Map, Set, typed array or other built-in with no JSON form, or text with an
34
+ * unpaired surrogate or a NUL character. An undefined object property is dropped; a Date is
35
+ * stored as its ISO string and a class instance as its own enumerable data.
36
+ */
37
+ set<T = unknown>(key: string, value: T, options?: SetOptions): Promise<boolean>;
38
+ /**
39
+ * Deletes a value from scene storage in the Server Side Storage service.
40
+ * @param key - The key to delete
41
+ * @returns true once applied, or once a newer write that replaced it lands;
42
+ * false only for a confirmed 404
43
+ * @throws Error if the delete, or its replacement, fails; a failure is never reported as absence
44
+ * @throws TypeError if the key is invalid
45
+ */
46
+ delete(key: string): Promise<boolean>;
47
+ /**
48
+ * Returns key-value entries from scene storage, optionally filtered by prefix.
49
+ * Supports pagination via limit and offset.
50
+ * @param options - Optional { prefix, limit, offset } for filtering and pagination.
51
+ * @returns A promise that resolves to { data, pagination: { offset, total } } for pagination UI
52
+ * @throws Error if the read fails, so a failure is never mistaken for an empty page
53
+ */
54
+ getValues(options?: GetValuesOptions): Promise<GetValuesResult>;
55
+ }
@@ -0,0 +1,232 @@
1
+ import { getStorageServerUrl } from '../storage-url';
2
+ import { assertIsServer, wrapSignedFetch } from '../utils';
3
+ import { createStorageConfig, MODULE_NAME } from './constants';
4
+ import { createValueCache } from './value-cache';
5
+ import { errorMessage } from './error-message';
6
+ import { assertStorageKey, serializeStorageValue } from './serialize';
7
+ import { createWriteQueue, SupersedingWriteFailed } from './write-queue';
8
+ /**
9
+ * Creates scene-scoped storage that provides methods to interact with
10
+ * scene-specific key-value pairs from the Server Side Storage service.
11
+ * This module only works when running on server-side scenes.
12
+ * @internal
13
+ */
14
+ export const createSceneStorage = (config = createStorageConfig()) => {
15
+ const cache = createValueCache(config);
16
+ // Each in-flight GET is tracked by a wrapper object whose identity marks
17
+ // ownership: a landed write detaches the pending GET so its stale response is not cached.
18
+ const inflightGets = new Map();
19
+ // Writes to the same key are serialized (and rapid ones coalesced to the
20
+ // latest value) so the service commits them in issue order — overlapping
21
+ // PUTs would otherwise leave both the kept value and the cached value to
22
+ // response-order chance.
23
+ const writes = createWriteQueue();
24
+ async function executeSet(key, body) {
25
+ let baseUrl;
26
+ try {
27
+ baseUrl = await getStorageServerUrl();
28
+ }
29
+ catch (error) {
30
+ cache.delete(key);
31
+ console.error(`Failed to set storage value '${key}': ${errorMessage(error)}`);
32
+ return false;
33
+ }
34
+ const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
35
+ const [error] = await wrapSignedFetch({
36
+ url,
37
+ init: {
38
+ method: 'PUT',
39
+ headers: {
40
+ 'content-type': 'application/json'
41
+ },
42
+ body
43
+ }
44
+ });
45
+ // Either way the entry changed server-side (or may have): detach any
46
+ // overlapping in-flight GET so its stale response is not cached.
47
+ inflightGets.delete(key);
48
+ if (error) {
49
+ // The PUT may have reached the server, so the cached body is no
50
+ // longer reliable.
51
+ cache.delete(key);
52
+ return false;
53
+ }
54
+ cache.set(key, { body });
55
+ return true;
56
+ }
57
+ async function executeDelete(key) {
58
+ let baseUrl;
59
+ try {
60
+ baseUrl = await getStorageServerUrl();
61
+ }
62
+ catch (error) {
63
+ cache.delete(key);
64
+ throw new Error(`Failed to delete storage value '${key}': ${errorMessage(error)}`);
65
+ }
66
+ const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
67
+ const [error, , status] = await wrapSignedFetch({
68
+ url,
69
+ init: {
70
+ method: 'DELETE',
71
+ headers: {}
72
+ }
73
+ });
74
+ // Detach again: a GET may have started while the DELETE was in flight.
75
+ inflightGets.delete(key);
76
+ if (error) {
77
+ // A 404 still confirms the key is absent server-side.
78
+ if (status === 404) {
79
+ cache.setAbsent(key);
80
+ return false;
81
+ }
82
+ // The DELETE may have reached the server, so the cached body is unreliable.
83
+ cache.delete(key);
84
+ throw new Error(`Failed to delete storage value '${key}': ${errorMessage(error)}`);
85
+ }
86
+ cache.setAbsent(key);
87
+ return true;
88
+ }
89
+ return {
90
+ async get(key, options) {
91
+ assertIsServer(MODULE_NAME);
92
+ assertStorageKey(key, 'Storage.get()');
93
+ if (writes.isPending(key))
94
+ await writes.settled(key);
95
+ if (config.cacheReads && !options?.fresh) {
96
+ const entry = cache.get(key);
97
+ if (entry?.absent)
98
+ return null;
99
+ // Parse per hit so each caller gets a fresh object (no shared mutation).
100
+ if (entry?.body !== undefined)
101
+ return JSON.parse(entry.body).value;
102
+ }
103
+ // Coalesce concurrent gets (even fresh ones: an in-flight response is
104
+ // milliseconds old, not TTL-stale) into a single network request.
105
+ const joined = inflightGets.get(key);
106
+ if (joined)
107
+ return joined.promise;
108
+ const inflight = {};
109
+ inflight.promise = (async () => {
110
+ try {
111
+ let baseUrl;
112
+ try {
113
+ baseUrl = await getStorageServerUrl();
114
+ }
115
+ catch (error) {
116
+ throw new Error(`Failed to get storage value '${key}': ${errorMessage(error)}`);
117
+ }
118
+ const url = `${baseUrl}/values/${encodeURIComponent(key)}`;
119
+ const [error, data, status] = await wrapSignedFetch({ url });
120
+ const isOwner = inflightGets.get(key) === inflight;
121
+ if (error) {
122
+ // A confirmed 404 is a first-class "absent" outcome, not a failure.
123
+ if (status === 404) {
124
+ if (isOwner)
125
+ cache.setAbsent(key);
126
+ return null;
127
+ }
128
+ throw new Error(`Failed to get storage value '${key}': ${errorMessage(error)}`);
129
+ }
130
+ // wrapSignedFetch parses an empty 2xx body as {}: a missing value is a fault, not an absence.
131
+ if (!data || data.value === undefined) {
132
+ throw new Error(`Failed to get storage value '${key}': response carried no value`);
133
+ }
134
+ // Same serialization shape as set()'s PUT body, so a read followed by
135
+ // an unchanged write can be skipped.
136
+ const body = JSON.stringify({ value: data.value });
137
+ if (isOwner)
138
+ cache.set(key, { body });
139
+ return data.value;
140
+ }
141
+ finally {
142
+ if (inflightGets.get(key) === inflight)
143
+ inflightGets.delete(key);
144
+ }
145
+ })();
146
+ inflightGets.set(key, inflight);
147
+ return inflight.promise;
148
+ },
149
+ async set(key, value, options) {
150
+ assertIsServer(MODULE_NAME);
151
+ assertStorageKey(key, 'Storage.set()');
152
+ const body = serializeStorageValue(value, `Storage.set('${key}')`);
153
+ const skipIfUnchanged = options?.skipIfUnchanged ?? config.skipIfUnchanged;
154
+ // Dedup against confirmed state only while no write is pending — a
155
+ // pending write makes the cache momentarily stale; enqueue() coalesces
156
+ // against pending writes instead.
157
+ if (skipIfUnchanged && writes.pending(key) === undefined && cache.get(key)?.body === body) {
158
+ return true;
159
+ }
160
+ return writes.enqueue(key, body, (b) => executeSet(key, b), skipIfUnchanged);
161
+ },
162
+ async delete(key) {
163
+ assertIsServer(MODULE_NAME);
164
+ assertStorageKey(key, 'Storage.delete()');
165
+ return writes
166
+ .enqueue(key, null, () => executeDelete(key), true)
167
+ .catch((error) => {
168
+ if (error instanceof SupersedingWriteFailed) {
169
+ throw new Error(`Failed to delete storage value '${key}': ${error.message}`);
170
+ }
171
+ throw error;
172
+ });
173
+ },
174
+ async getValues(options) {
175
+ assertIsServer(MODULE_NAME);
176
+ const { prefix, limit, offset } = options ?? {};
177
+ let baseUrl;
178
+ try {
179
+ baseUrl = await getStorageServerUrl();
180
+ }
181
+ catch (error) {
182
+ throw new Error(`Failed to get storage values: ${errorMessage(error)}`);
183
+ }
184
+ const parts = [];
185
+ if (!!prefix) {
186
+ parts.push(`prefix=${encodeURIComponent(prefix)}`);
187
+ }
188
+ if (!!limit) {
189
+ parts.push(`limit=${limit}`);
190
+ }
191
+ if (!!offset) {
192
+ parts.push(`offset=${offset}`);
193
+ }
194
+ const query = parts.join('&');
195
+ const url = query ? `${baseUrl}/values?${query}` : `${baseUrl}/values`;
196
+ const watcher = cache.watch();
197
+ const [error, response] = await wrapSignedFetch({ url });
198
+ watcher.stop();
199
+ if (error) {
200
+ throw new Error(`Failed to get storage values: ${errorMessage(error)}`);
201
+ }
202
+ const data = response?.data;
203
+ if (!Array.isArray(data)) {
204
+ throw new Error('Failed to get storage values: response carried no data array');
205
+ }
206
+ if (data.some((entry) => typeof entry?.key !== 'string' || entry.value === undefined)) {
207
+ throw new Error('Failed to get storage values: response carried a malformed entry');
208
+ }
209
+ // Seed the per-key cache so subsequent get()/set() on returned keys can
210
+ // skip the network. Only keys with no live entry and no pending write
211
+ // are seeded: existing per-key state comes from a confirmed operation
212
+ // that this page snapshot — whose request started earlier — must not
213
+ // clobber with stale data. Absence is never seeded (prefix/pagination
214
+ // make it non-authoritative). A page larger than cacheMaxEntries churns
215
+ // the cache; entries repopulate lazily.
216
+ for (const entry of data) {
217
+ if (watcher.mutated(entry.key) || writes.isPending(entry.key) || inflightGets.has(entry.key))
218
+ continue;
219
+ if (cache.get(entry.key) === undefined) {
220
+ cache.set(entry.key, { body: JSON.stringify({ value: entry.value }) });
221
+ }
222
+ }
223
+ const requestedOffset = offset ?? 0;
224
+ const pagination = {
225
+ offset: response.pagination?.offset ?? requestedOffset,
226
+ total: response.pagination?.total ?? data.length
227
+ };
228
+ return { data, pagination };
229
+ }
230
+ };
231
+ };
232
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NlbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmVyL3N0b3JhZ2Uvc2NlbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDMUQsT0FBTyxFQUNMLG1CQUFtQixFQUluQixXQUFXLEVBR1osTUFBTSxhQUFhLENBQUE7QUFDcEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sZUFBZSxDQUFBO0FBNER4RTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsU0FBNkIsbUJBQW1CLEVBQUUsRUFBaUIsRUFBRTtJQUN0RyxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUN0Qyx5RUFBeUU7SUFDekUsMEZBQTBGO0lBQzFGLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxFQUF5QyxDQUFBO0lBQ3JFLHlFQUF5RTtJQUN6RSx5RUFBeUU7SUFDekUseUVBQXlFO0lBQ3pFLHlCQUF5QjtJQUN6QixNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRSxDQUFBO0lBRWpDLEtBQUssVUFBVSxVQUFVLENBQUMsR0FBVyxFQUFFLElBQVk7UUFDakQsSUFBSSxPQUFlLENBQUE7UUFDbkIsSUFBSTtZQUNGLE9BQU8sR0FBRyxNQUFNLG1CQUFtQixFQUFFLENBQUE7U0FDdEM7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLEtBQUssQ0FB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SUFBSSxDQUFDLENBQUE7WUFDbkMsTUFBTSxVQUFVLEdBQUc7Z0JBQ2pCLE1BQU0sRUFBRSxRQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sSUFBSSxlQUFlO2dCQUN2RCxLQUFLLEVBQUUsUUFBUyxDQUFDLFVBQVUsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU07YUFDbEQsQ0FBQTtZQUVELE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUE7UUFDN0IsQ0FBQztLQUNGLENBQUE7QUFDSCxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRTdG9yYWdlU2VydmVyVXJsIH0gZnJvbSAnLi4vc3RvcmFnZS11cmwnXG5pbXBvcnQgeyBhc3NlcnRJc1NlcnZlciwgd3JhcFNpZ25lZEZldGNoIH0gZnJvbSAnLi4vdXRpbHMnXG5pbXBvcnQge1xuICBjcmVhdGVTdG9yYWdlQ29uZmlnLFxuICBHZXRPcHRpb25zLFxuICBHZXRWYWx1ZXNPcHRpb25zLFxuICBHZXRWYWx1ZXNSZXN1bHQsXG4gIE1PRFVMRV9OQU1FLFxuICBTZXRPcHRpb25zLFxuICBTdG9yYWdlQ29uZmlnU3RhdGVcbn0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBjcmVhdGVWYWx1ZUNhY2hlIH0gZnJvbSAnLi92YWx1ZS1jYWNoZSdcbmltcG9ydCB7IGVycm9yTWVzc2FnZSB9IGZyb20gJy4vZXJyb3ItbWVzc2FnZSdcbmltcG9ydCB7IGFzc2VydFN0b3JhZ2VLZXksIHNlcmlhbGl6ZVN0b3JhZ2VWYWx1ZSB9IGZyb20gJy4vc2VyaWFsaXplJ1xuaW1wb3J0IHsgY3JlYXRlV3JpdGVRdWV1ZSwgU3VwZXJzZWRpbmdXcml0ZUZhaWxlZCB9IGZyb20gJy4vd3JpdGUtcXVldWUnXG5cbi8qKlxuICogU2NlbmUtc2NvcGVkIHN0b3JhZ2UgaW50ZXJmYWNlIGZvciBrZXktdmFsdWUgcGFpcnMgZnJvbSB0aGUgU2VydmVyIFNpZGUgU3RvcmFnZSBzZXJ2aWNlLlxuICogVGhpcyBpcyBOT1QgZmlsZXN5c3RlbSBzdG9yYWdlIC0gZGF0YSBpcyBzdG9yZWQgaW4gdGhlIHJlbW90ZSBzdG9yYWdlIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVNjZW5lU3RvcmFnZSB7XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHNjZW5lIHN0b3JhZ2UgYnkga2V5IGZyb20gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAgICpcbiAgICogQnkgZGVmYXVsdCAoY2FjaGVSZWFkcyksIHZhbHVlcyByZWFkIG9yIHdyaXR0ZW4gZHVyaW5nIHRoZSBsYXN0IGNhY2hlTWF4QWdlTXNcbiAgICogYXJlIHNlcnZlZCBmcm9tIGEgbG9jYWwgY2FjaGUgd2l0aG91dCBhIG5ldHdvcmsgcmVxdWVzdCwgaW5jbHVkaW5nIGNvbmZpcm1lZFxuICAgKiBcIm5vdCBmb3VuZFwiIHJlc3VsdHMuIENvbmN1cnJlbnQgZ2V0cyBmb3IgdGhlIHNhbWUga2V5IHNoYXJlIG9uZSByZXF1ZXN0LlxuICAgKiBPdXQtb2YtYmFuZCB3cml0ZXJzIChlLmcuIENMSSBzdG9yYWdlIGNvbW1hbmRzKSBtYXkgbm90IGJlIHZpc2libGUgZm9yIHVwIHRvXG4gICAqIGNhY2hlTWF4QWdlTXMg4oCUIHBhc3MgeyBmcmVzaDogdHJ1ZSB9IHRvIGZvcmNlIGEgbmV0d29yayByZWFkLlxuICAgKiBBIHJlYWQgZmlyc3Qgd2FpdHMgZm9yIHdyaXRlcyB0byB0aGUgc2FtZSBrZXkgdGhhdCB3ZXJlIHBlbmRpbmcgd2hlbiBpdCB3YXNcbiAgICogaXNzdWVkLCBzbyBpdCByZWZsZWN0cyBldmVyeSB3cml0ZSBpc3N1ZWQgYmVmb3JlIGl0LlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSB0byByZXRyaWV2ZVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHsgZnJlc2ggfSB0byBieXBhc3MgdGhlIHJlYWQgY2FjaGVcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHBhcnNlZCBKU09OIHZhbHVlLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSByZWFkIGZhaWxzLCBzbyBhIGZhaWx1cmUgaXMgbmV2ZXIgbWlzdGFrZW4gZm9yIGEgbWlzc2luZyBrZXlcbiAgICogQHRocm93cyBUeXBlRXJyb3IgaWYgdGhlIGtleSBpcyBpbnZhbGlkXG4gICAqL1xuICBnZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBvcHRpb25zPzogR2V0T3B0aW9ucyk6IFByb21pc2U8VCB8IG51bGw+XG5cbiAgLyoqXG4gICAqIFN0b3JlcyBhIHZhbHVlIGluIHNjZW5lIHN0b3JhZ2UgaW4gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAgICogQHBhcmFtIGtleSAtIFRoZSBrZXkgdG8gc3RvcmUgdGhlIHZhbHVlIHVuZGVyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBzdG9yZSAod2lsbCBiZSBKU09OIHNlcmlhbGl6ZWQpXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwgeyBza2lwSWZVbmNoYW5nZWQgfSB0byBza2lwIHRoZSBuZXR3b3JrIHdyaXRlIHdoZW4gdGhlIHZhbHVlIGlzIGFscmVhZHkgc3RvcmVkXG4gICAqIEByZXR1cm5zIHRydWUgb25jZSBzdG9yZWQsIG9yIG9uY2UgYSBuZXdlciB3cml0ZSB0aGF0IHJlcGxhY2VkIHRoaXMgb25lIGxhbmRzXG4gICAqIChyYXBpZCB3cml0ZXMgY29hbGVzY2UpOyBmYWxzZSBpZiB0aGUgd3JpdGUsIG9yIGl0cyByZXBsYWNlbWVudCwgZmFpbHNcbiAgICogQHRocm93cyBUeXBlRXJyb3IgaWYgdGhlIGtleSBpcyBpbnZhbGlkLCBvciB0aGUgdmFsdWUgY2Fubm90IGJlIHN0b3JlZCB1bmNoYW5nZWQ6IHVuZGVmaW5lZCxcbiAgICogY2lyY3VsYXIsIGEgQmlnSW50LCBvciBjb250YWluaW5nIGEgZnVuY3Rpb24sIGEgc3ltYm9sLCBhIG5vbi1maW5pdGUgbnVtYmVyLCBhbiB1bmRlZmluZWQgYXJyYXlcbiAgICogZWxlbWVudCBvciBob2xlLCBhIE1hcCwgU2V0LCB0eXBlZCBhcnJheSBvciBvdGhlciBidWlsdC1pbiB3aXRoIG5vIEpTT04gZm9ybSwgb3IgdGV4dCB3aXRoIGFuXG4gICAqIHVucGFpcmVkIHN1cnJvZ2F0ZSBvciBhIE5VTCBjaGFyYWN0ZXIuIEFuIHVuZGVmaW5lZCBvYmplY3QgcHJvcGVydHkgaXMgZHJvcHBlZDsgYSBEYXRlIGlzXG4gICAqIHN0b3JlZCBhcyBpdHMgSVNPIHN0cmluZyBhbmQgYSBjbGFzcyBpbnN0YW5jZSBhcyBpdHMgb3duIGVudW1lcmFibGUgZGF0YS5cbiAgICovXG4gIHNldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIHZhbHVlOiBULCBvcHRpb25zPzogU2V0T3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj5cblxuICAvKipcbiAgICogRGVsZXRlcyBhIHZhbHVlIGZyb20gc2NlbmUgc3RvcmFnZSBpbiB0aGUgU2VydmVyIFNpZGUgU3RvcmFnZSBzZXJ2aWNlLlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSB0byBkZWxldGVcbiAgICogQHJldHVybnMgdHJ1ZSBvbmNlIGFwcGxpZWQsIG9yIG9uY2UgYSBuZXdlciB3cml0ZSB0aGF0IHJlcGxhY2VkIGl0IGxhbmRzO1xuICAgKiBmYWxzZSBvbmx5IGZvciBhIGNvbmZpcm1lZCA0MDRcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgZGVsZXRlLCBvciBpdHMgcmVwbGFjZW1lbnQsIGZhaWxzOyBhIGZhaWx1cmUgaXMgbmV2ZXIgcmVwb3J0ZWQgYXMgYWJzZW5jZVxuICAgKiBAdGhyb3dzIFR5cGVFcnJvciBpZiB0aGUga2V5IGlzIGludmFsaWRcbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj5cblxuICAvKipcbiAgICogUmV0dXJucyBrZXktdmFsdWUgZW50cmllcyBmcm9tIHNjZW5lIHN0b3JhZ2UsIG9wdGlvbmFsbHkgZmlsdGVyZWQgYnkgcHJlZml4LlxuICAgKiBTdXBwb3J0cyBwYWdpbmF0aW9uIHZpYSBsaW1pdCBhbmQgb2Zmc2V0LlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHsgcHJlZml4LCBsaW1pdCwgb2Zmc2V0IH0gZm9yIGZpbHRlcmluZyBhbmQgcGFnaW5hdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8geyBkYXRhLCBwYWdpbmF0aW9uOiB7IG9mZnNldCwgdG90YWwgfSB9IGZvciBwYWdpbmF0aW9uIFVJXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIHJlYWQgZmFpbHMsIHNvIGEgZmFpbHVyZSBpcyBuZXZlciBtaXN0YWtlbiBmb3IgYW4gZW1wdHkgcGFnZVxuICAgKi9cbiAgZ2V0VmFsdWVzKG9wdGlvbnM/OiBHZXRWYWx1ZXNPcHRpb25zKTogUHJvbWlzZTxHZXRWYWx1ZXNSZXN1bHQ+XG59XG5cbi8qKlxuICogQ3JlYXRlcyBzY2VuZS1zY29wZWQgc3RvcmFnZSB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgdG8gaW50ZXJhY3Qgd2l0aFxuICogc2NlbmUtc3BlY2lmaWMga2V5LXZhbHVlIHBhaXJzIGZyb20gdGhlIFNlcnZlciBTaWRlIFN0b3JhZ2Ugc2VydmljZS5cbiAqIFRoaXMgbW9kdWxlIG9ubHkgd29ya3Mgd2hlbiBydW5uaW5nIG9uIHNlcnZlci1zaWRlIHNjZW5lcy5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU2NlbmVTdG9yYWdlID0gKGNvbmZpZzogU3RvcmFnZUNvbmZpZ1N0YXRlID0gY3JlYXRlU3RvcmFnZUNvbmZpZygpKTogSVNjZW5lU3RvcmFnZSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gY3JlYXRlVmFsdWVDYWNoZShjb25maWcpXG4gIC8vIEVhY2ggaW4tZmxpZ2h0IEdFVCBpcyB0cmFja2VkIGJ5IGEgd3JhcHBlciBvYmplY3Qgd2hvc2UgaWRlbnRpdHkgbWFya3NcbiAgLy8gb3duZXJzaGlwOiBhIGxhbmRlZCB3cml0ZSBkZXRhY2hlcyB0aGUgcGVuZGluZyBHRVQgc28gaXRzIHN0YWxlIHJlc3BvbnNlIGlzIG5vdCBjYWNoZWQuXG4gIGNvbnN0IGluZmxpZ2h0R2V0cyA9IG5ldyBNYXA8c3RyaW5nLCB7IHByb21pc2U6IFByb21pc2U8dW5rbm93bj4gfT4oKVxuICAvLyBXcml0ZXMgdG8gdGhlIHNhbWUga2V5IGFyZSBzZXJpYWxpemVkIChhbmQgcmFwaWQgb25lcyBjb2FsZXNjZWQgdG8gdGhlXG4gIC8vIGxhdGVzdCB2YWx1ZSkgc28gdGhlIHNlcnZpY2UgY29tbWl0cyB0aGVtIGluIGlzc3VlIG9yZGVyIOKAlCBvdmVybGFwcGluZ1xuICAvLyBQVVRzIHdvdWxkIG90aGVyd2lzZSBsZWF2ZSBib3RoIHRoZSBrZXB0IHZhbHVlIGFuZCB0aGUgY2FjaGVkIHZhbHVlIHRvXG4gIC8vIHJlc3BvbnNlLW9yZGVyIGNoYW5jZS5cbiAgY29uc3Qgd3JpdGVzID0gY3JlYXRlV3JpdGVRdWV1ZSgpXG5cbiAgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZVNldChrZXk6IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbGV0IGJhc2VVcmw6IHN0cmluZ1xuICAgIHRyeSB7XG4gICAgICBiYXNlVXJsID0gYXdhaXQgZ2V0U3RvcmFnZVNlcnZlclVybCgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhY2hlLmRlbGV0ZShrZXkpXG4gICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gc2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGNvbnN0IHVybCA9IGAke2Jhc2VVcmx9L3ZhbHVlcy8ke2VuY29kZVVSSUNvbXBvbmVudChrZXkpfWBcblxuICAgIGNvbnN0IFtlcnJvcl0gPSBhd2FpdCB3cmFwU2lnbmVkRmV0Y2goe1xuICAgICAgdXJsLFxuICAgICAgaW5pdDoge1xuICAgICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9LFxuICAgICAgICBib2R5XG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIEVpdGhlciB3YXkgdGhlIGVudHJ5IGNoYW5nZWQgc2VydmVyLXNpZGUgKG9yIG1heSBoYXZlKTogZGV0YWNoIGFueVxuICAgIC8vIG92ZXJsYXBwaW5nIGluLWZsaWdodCBHRVQgc28gaXRzIHN0YWxlIHJlc3BvbnNlIGlzIG5vdCBjYWNoZWQuXG4gICAgaW5mbGlnaHRHZXRzLmRlbGV0ZShrZXkpXG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIC8vIFRoZSBQVVQgbWF5IGhhdmUgcmVhY2hlZCB0aGUgc2VydmVyLCBzbyB0aGUgY2FjaGVkIGJvZHkgaXMgbm9cbiAgICAgIC8vIGxvbmdlciByZWxpYWJsZS5cbiAgICAgIGNhY2hlLmRlbGV0ZShrZXkpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjYWNoZS5zZXQoa2V5LCB7IGJvZHkgfSlcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZURlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxldCBiYXNlVXJsOiBzdHJpbmdcbiAgICB0cnkge1xuICAgICAgYmFzZVVybCA9IGF3YWl0IGdldFN0b3JhZ2VTZXJ2ZXJVcmwoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYWNoZS5kZWxldGUoa2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZGVsZXRlIHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgIH1cbiAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfS92YWx1ZXMvJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX1gXG5cbiAgICBjb25zdCBbZXJyb3IsICwgc3RhdHVzXSA9IGF3YWl0IHdyYXBTaWduZWRGZXRjaCh7XG4gICAgICB1cmwsXG4gICAgICBpbml0OiB7XG4gICAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICAgIGhlYWRlcnM6IHt9XG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIERldGFjaCBhZ2FpbjogYSBHRVQgbWF5IGhhdmUgc3RhcnRlZCB3aGlsZSB0aGUgREVMRVRFIHdhcyBpbiBmbGlnaHQuXG4gICAgaW5mbGlnaHRHZXRzLmRlbGV0ZShrZXkpXG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIC8vIEEgNDA0IHN0aWxsIGNvbmZpcm1zIHRoZSBrZXkgaXMgYWJzZW50IHNlcnZlci1zaWRlLlxuICAgICAgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgIGNhY2hlLnNldEFic2VudChrZXkpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgLy8gVGhlIERFTEVURSBtYXkgaGF2ZSByZWFjaGVkIHRoZSBzZXJ2ZXIsIHNvIHRoZSBjYWNoZWQgYm9keSBpcyB1bnJlbGlhYmxlLlxuICAgICAgY2FjaGUuZGVsZXRlKGtleSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBzdG9yYWdlIHZhbHVlICcke2tleX0nOiAke2Vycm9yTWVzc2FnZShlcnJvcil9YClcbiAgICB9XG5cbiAgICBjYWNoZS5zZXRBYnNlbnQoa2V5KVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiBHZXRPcHRpb25zKTogUHJvbWlzZTxUIHwgbnVsbD4ge1xuICAgICAgYXNzZXJ0SXNTZXJ2ZXIoTU9EVUxFX05BTUUpXG4gICAgICBhc3NlcnRTdG9yYWdlS2V5KGtleSwgJ1N0b3JhZ2UuZ2V0KCknKVxuXG4gICAgICBpZiAod3JpdGVzLmlzUGVuZGluZyhrZXkpKSBhd2FpdCB3cml0ZXMuc2V0dGxlZChrZXkpXG5cbiAgICAgIGlmIChjb25maWcuY2FjaGVSZWFkcyAmJiAhb3B0aW9ucz8uZnJlc2gpIHtcbiAgICAgICAgY29uc3QgZW50cnkgPSBjYWNoZS5nZXQoa2V5KVxuICAgICAgICBpZiAoZW50cnk/LmFic2VudCkgcmV0dXJuIG51bGxcbiAgICAgICAgLy8gUGFyc2UgcGVyIGhpdCBzbyBlYWNoIGNhbGxlciBnZXRzIGEgZnJlc2ggb2JqZWN0IChubyBzaGFyZWQgbXV0YXRpb24pLlxuICAgICAgICBpZiAoZW50cnk/LmJvZHkgIT09IHVuZGVmaW5lZCkgcmV0dXJuIEpTT04ucGFyc2UoZW50cnkuYm9keSkudmFsdWUgYXMgVFxuICAgICAgfVxuXG4gICAgICAvLyBDb2FsZXNjZSBjb25jdXJyZW50IGdldHMgKGV2ZW4gZnJlc2ggb25lczogYW4gaW4tZmxpZ2h0IHJlc3BvbnNlIGlzXG4gICAgICAvLyBtaWxsaXNlY29uZHMgb2xkLCBub3QgVFRMLXN0YWxlKSBpbnRvIGEgc2luZ2xlIG5ldHdvcmsgcmVxdWVzdC5cbiAgICAgIGNvbnN0IGpvaW5lZCA9IGluZmxpZ2h0R2V0cy5nZXQoa2V5KVxuICAgICAgaWYgKGpvaW5lZCkgcmV0dXJuIGpvaW5lZC5wcm9taXNlIGFzIFByb21pc2U8VCB8IG51bGw+XG5cbiAgICAgIGNvbnN0IGluZmxpZ2h0ID0ge30gYXMgeyBwcm9taXNlOiBQcm9taXNlPFQgfCBudWxsPiB9XG4gICAgICBpbmZsaWdodC5wcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgYmFzZVVybDogc3RyaW5nXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGJhc2VVcmwgPSBhd2FpdCBnZXRTdG9yYWdlU2VydmVyVXJsKClcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfS92YWx1ZXMvJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX1gXG5cbiAgICAgICAgICBjb25zdCBbZXJyb3IsIGRhdGEsIHN0YXR1c10gPSBhd2FpdCB3cmFwU2lnbmVkRmV0Y2g8eyB2YWx1ZTogVCB9Pih7IHVybCB9KVxuXG4gICAgICAgICAgY29uc3QgaXNPd25lciA9IGluZmxpZ2h0R2V0cy5nZXQoa2V5KSA9PT0gaW5mbGlnaHRcblxuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgLy8gQSBjb25maXJtZWQgNDA0IGlzIGEgZmlyc3QtY2xhc3MgXCJhYnNlbnRcIiBvdXRjb21lLCBub3QgYSBmYWlsdXJlLlxuICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgICAgIGlmIChpc093bmVyKSBjYWNoZS5zZXRBYnNlbnQoa2V5KVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWUgJyR7a2V5fSc6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHdyYXBTaWduZWRGZXRjaCBwYXJzZXMgYW4gZW1wdHkgMnh4IGJvZHkgYXMge306IGEgbWlzc2luZyB2YWx1ZSBpcyBhIGZhdWx0LCBub3QgYW4gYWJzZW5jZS5cbiAgICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZSAnJHtrZXl9JzogcmVzcG9uc2UgY2FycmllZCBubyB2YWx1ZWApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2FtZSBzZXJpYWxpemF0aW9uIHNoYXBlIGFzIHNldCgpJ3MgUFVUIGJvZHksIHNvIGEgcmVhZCBmb2xsb3dlZCBieVxuICAgICAgICAgIC8vIGFuIHVuY2hhbmdlZCB3cml0ZSBjYW4gYmUgc2tpcHBlZC5cbiAgICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkoeyB2YWx1ZTogZGF0YS52YWx1ZSB9KVxuICAgICAgICAgIGlmIChpc093bmVyKSBjYWNoZS5zZXQoa2V5LCB7IGJvZHkgfSlcbiAgICAgICAgICByZXR1cm4gZGF0YS52YWx1ZVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGlmIChpbmZsaWdodEdldHMuZ2V0KGtleSkgPT09IGluZmxpZ2h0KSBpbmZsaWdodEdldHMuZGVsZXRlKGtleSlcbiAgICAgICAgfVxuICAgICAgfSkoKVxuXG4gICAgICBpbmZsaWdodEdldHMuc2V0KGtleSwgaW5mbGlnaHQpXG4gICAgICByZXR1cm4gaW5mbGlnaHQucHJvbWlzZVxuICAgIH0sXG5cbiAgICBhc3luYyBzZXQ8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCB2YWx1ZTogVCwgb3B0aW9ucz86IFNldE9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuICAgICAgYXNzZXJ0U3RvcmFnZUtleShrZXksICdTdG9yYWdlLnNldCgpJylcblxuICAgICAgY29uc3QgYm9keSA9IHNlcmlhbGl6ZVN0b3JhZ2VWYWx1ZSh2YWx1ZSwgYFN0b3JhZ2Uuc2V0KCcke2tleX0nKWApXG4gICAgICBjb25zdCBza2lwSWZVbmNoYW5nZWQgPSBvcHRpb25zPy5za2lwSWZVbmNoYW5nZWQgPz8gY29uZmlnLnNraXBJZlVuY2hhbmdlZFxuXG4gICAgICAvLyBEZWR1cCBhZ2FpbnN0IGNvbmZpcm1lZCBzdGF0ZSBvbmx5IHdoaWxlIG5vIHdyaXRlIGlzIHBlbmRpbmcg4oCUIGFcbiAgICAgIC8vIHBlbmRpbmcgd3JpdGUgbWFrZXMgdGhlIGNhY2hlIG1vbWVudGFyaWx5IHN0YWxlOyBlbnF1ZXVlKCkgY29hbGVzY2VzXG4gICAgICAvLyBhZ2FpbnN0IHBlbmRpbmcgd3JpdGVzIGluc3RlYWQuXG4gICAgICBpZiAoc2tpcElmVW5jaGFuZ2VkICYmIHdyaXRlcy5wZW5kaW5nKGtleSkgPT09IHVuZGVmaW5lZCAmJiBjYWNoZS5nZXQoa2V5KT8uYm9keSA9PT0gYm9keSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gd3JpdGVzLmVucXVldWUoa2V5LCBib2R5LCAoYikgPT4gZXhlY3V0ZVNldChrZXksIGIgYXMgc3RyaW5nKSwgc2tpcElmVW5jaGFuZ2VkKVxuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGUoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuICAgICAgYXNzZXJ0U3RvcmFnZUtleShrZXksICdTdG9yYWdlLmRlbGV0ZSgpJylcblxuICAgICAgcmV0dXJuIHdyaXRlc1xuICAgICAgICAuZW5xdWV1ZShrZXksIG51bGwsICgpID0+IGV4ZWN1dGVEZWxldGUoa2V5KSwgdHJ1ZSlcbiAgICAgICAgLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFN1cGVyc2VkaW5nV3JpdGVGYWlsZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBzdG9yYWdlIHZhbHVlICcke2tleX0nOiAke2Vycm9yLm1lc3NhZ2V9YClcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VmFsdWVzKG9wdGlvbnM/OiBHZXRWYWx1ZXNPcHRpb25zKTogUHJvbWlzZTxHZXRWYWx1ZXNSZXN1bHQ+IHtcbiAgICAgIGFzc2VydElzU2VydmVyKE1PRFVMRV9OQU1FKVxuXG4gICAgICBjb25zdCB7IHByZWZpeCwgbGltaXQsIG9mZnNldCB9ID0gb3B0aW9ucyA/PyB7fVxuICAgICAgbGV0IGJhc2VVcmw6IHN0cmluZ1xuICAgICAgdHJ5IHtcbiAgICAgICAgYmFzZVVybCA9IGF3YWl0IGdldFN0b3JhZ2VTZXJ2ZXJVcmwoKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHN0b3JhZ2UgdmFsdWVzOiAke2Vycm9yTWVzc2FnZShlcnJvcil9YClcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICAgIGlmICghIXByZWZpeCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBwcmVmaXg9JHtlbmNvZGVVUklDb21wb25lbnQocHJlZml4KX1gKVxuICAgICAgfVxuXG4gICAgICBpZiAoISFsaW1pdCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBsaW1pdD0ke2xpbWl0fWApXG4gICAgICB9XG5cbiAgICAgIGlmICghIW9mZnNldCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGBvZmZzZXQ9JHtvZmZzZXR9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcXVlcnkgPSBwYXJ0cy5qb2luKCcmJylcbiAgICAgIGNvbnN0IHVybCA9IHF1ZXJ5ID8gYCR7YmFzZVVybH0vdmFsdWVzPyR7cXVlcnl9YCA6IGAke2Jhc2VVcmx9L3ZhbHVlc2BcblxuICAgICAgY29uc3Qgd2F0Y2hlciA9IGNhY2hlLndhdGNoKClcbiAgICAgIGNvbnN0IFtlcnJvciwgcmVzcG9uc2VdID0gYXdhaXQgd3JhcFNpZ25lZEZldGNoPEdldFZhbHVlc1Jlc3VsdD4oeyB1cmwgfSlcbiAgICAgIHdhdGNoZXIuc3RvcCgpXG5cbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZXM6ICR7ZXJyb3JNZXNzYWdlKGVycm9yKX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRhID0gcmVzcG9uc2U/LmRhdGFcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgc3RvcmFnZSB2YWx1ZXM6IHJlc3BvbnNlIGNhcnJpZWQgbm8gZGF0YSBhcnJheScpXG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5zb21lKChlbnRyeSkgPT4gdHlwZW9mIGVudHJ5Py5rZXkgIT09ICdzdHJpbmcnIHx8IGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCBzdG9yYWdlIHZhbHVlczogcmVzcG9uc2UgY2FycmllZCBhIG1hbGZvcm1lZCBlbnRyeScpXG4gICAgICB9XG5cbiAgICAgIC8vIFNlZWQgdGhlIHBlci1rZXkgY2FjaGUgc28gc3Vic2VxdWVudCBnZXQoKS9zZXQoKSBvbiByZXR1cm5lZCBrZXlzIGNhblxuICAgICAgLy8gc2tpcCB0aGUgbmV0d29yay4gT25seSBrZXlzIHdpdGggbm8gbGl2ZSBlbnRyeSBhbmQgbm8gcGVuZGluZyB3cml0ZVxuICAgICAgLy8gYXJlIHNlZWRlZDogZXhpc3RpbmcgcGVyLWtleSBzdGF0ZSBjb21lcyBmcm9tIGEgY29uZmlybWVkIG9wZXJhdGlvblxuICAgICAgLy8gdGhhdCB0aGlzIHBhZ2Ugc25hcHNob3Qg4oCUIHdob3NlIHJlcXVlc3Qgc3RhcnRlZCBlYXJsaWVyIOKAlCBtdXN0IG5vdFxuICAgICAgLy8gY2xvYmJlciB3aXRoIHN0YWxlIGRhdGEuIEFic2VuY2UgaXMgbmV2ZXIgc2VlZGVkIChwcmVmaXgvcGFnaW5hdGlvblxuICAgICAgLy8gbWFrZSBpdCBub24tYXV0aG9yaXRhdGl2ZSkuIEEgcGFnZSBsYXJnZXIgdGhhbiBjYWNoZU1heEVudHJpZXMgY2h1cm5zXG4gICAgICAvLyB0aGUgY2FjaGU7IGVudHJpZXMgcmVwb3B1bGF0ZSBsYXppbHkuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGRhdGEpIHtcbiAgICAgICAgaWYgKHdhdGNoZXIubXV0YXRlZChlbnRyeS5rZXkpIHx8IHdyaXRlcy5pc1BlbmRpbmcoZW50cnkua2V5KSB8fCBpbmZsaWdodEdldHMuaGFzKGVudHJ5LmtleSkpIGNvbnRpbnVlXG4gICAgICAgIGlmIChjYWNoZS5nZXQoZW50cnkua2V5KSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY2FjaGUuc2V0KGVudHJ5LmtleSwgeyBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHZhbHVlOiBlbnRyeS52YWx1ZSB9KSB9KVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcXVlc3RlZE9mZnNldCA9IG9mZnNldCA/PyAwXG4gICAgICBjb25zdCBwYWdpbmF0aW9uID0ge1xuICAgICAgICBvZmZzZXQ6IHJlc3BvbnNlIS5wYWdpbmF0aW9uPy5vZmZzZXQgPz8gcmVxdWVzdGVkT2Zmc2V0LFxuICAgICAgICB0b3RhbDogcmVzcG9uc2UhLnBhZ2luYXRpb24/LnRvdGFsID8/IGRhdGEubGVuZ3RoXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IGRhdGEsIHBhZ2luYXRpb24gfVxuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,135 @@
1
+ const LONE_SURROGATE = /[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;
2
+ const UNSTORABLE_TEXT = /\u0000/;
3
+ const MAX_KEY_LENGTH = 255;
4
+ /**
5
+ * JSON.stringify always writes NUL as `\u0000` and an unpaired surrogate as a `\udXXX` escape (ES2019),
6
+ * while paired surrogates stay raw; an escaped backslash in front means the text is literal.
7
+ */
8
+ const ESCAPED_UNSTORABLE_TEXT = /(?<!\\)(?:\\\\)*\\u(?:0000|d[89a-f][0-9a-f]{2})/i;
9
+ /** Raised from inside the replacer, so it is not mistaken for an engine error. */
10
+ class UnstorableValueError extends TypeError {
11
+ }
12
+ /**
13
+ * The `{ value }` PUT body. Rejects, at any depth, what JSON would drop or change: functions,
14
+ * symbols, non-finite numbers, `undefined` array elements and holes, built-ins with no JSON form
15
+ * (Map, Set, typed arrays, RegExp, Error, ...), and text the service cannot store. An `undefined`
16
+ * object property is dropped, as it reads back the same.
17
+ * @internal
18
+ */
19
+ export function serializeStorageValue(value, callSite) {
20
+ const body = stringify(value, callSite, fastReason);
21
+ // Text is checked once on the output; only a rejection pays for locating the offending item.
22
+ if (ESCAPED_UNSTORABLE_TEXT.test(body)) {
23
+ stringify(value, callSite, unstorable);
24
+ throw new TypeError(`${callSite}: value must not contain an unpaired surrogate or a NUL character.`);
25
+ }
26
+ if (body === '{}') {
27
+ throw new TypeError(`${callSite}: value must be JSON-serializable. Use delete() to remove a key.`);
28
+ }
29
+ return body;
30
+ }
31
+ function stringify(value, callSite, reason) {
32
+ const envelope = { value };
33
+ try {
34
+ return JSON.stringify(envelope, function (property, item) {
35
+ const why = reason(this, property, item);
36
+ if (why) {
37
+ const where = this === envelope ? 'the value' : `"${property}"`;
38
+ throw new UnstorableValueError(`${callSite}: value must be JSON-serializable, but ${where} ${why}. Use delete() to remove a key.`);
39
+ }
40
+ return item;
41
+ });
42
+ }
43
+ catch (error) {
44
+ if (error instanceof UnstorableValueError)
45
+ throw error;
46
+ const cause = error instanceof Error ? error.message.split('\n')[0] : String(error);
47
+ throw new TypeError(`${callSite}: value must be JSON-serializable (${cause}). Use delete() to remove a key.`);
48
+ }
49
+ }
50
+ /** Everything but the text checks, with plain objects and arrays skipping the built-in check. */
51
+ function fastReason(holder, property, item) {
52
+ switch (typeof item) {
53
+ case 'function':
54
+ case 'symbol':
55
+ return `is a ${typeof item}`;
56
+ case 'number':
57
+ return Number.isFinite(item) ? undefined : `is the non-finite number ${item}`;
58
+ case 'undefined':
59
+ if (Array.isArray(holder))
60
+ return 'is undefined or a hole in an array';
61
+ return holder[property] !== undefined ? 'has a toJSON() that returns undefined' : undefined;
62
+ case 'object': {
63
+ if (item === null || Array.isArray(item))
64
+ return undefined;
65
+ const prototype = Object.getPrototypeOf(item);
66
+ return prototype === Object.prototype || prototype === null ? undefined : builtInReason(item);
67
+ }
68
+ default:
69
+ return undefined;
70
+ }
71
+ }
72
+ /** Every check, per item: used to name the item a text rejection comes from. */
73
+ function unstorable(holder, property, item) {
74
+ const fast = fastReason(holder, property, item);
75
+ if (fast)
76
+ return fast;
77
+ if (typeof item === 'string' && (LONE_SURROGATE.test(item) || UNSTORABLE_TEXT.test(item))) {
78
+ return 'contains an unpaired surrogate or a NUL character';
79
+ }
80
+ if (!Array.isArray(holder) && (LONE_SURROGATE.test(property) || UNSTORABLE_TEXT.test(property))) {
81
+ return 'is a key with an unpaired surrogate or a NUL character';
82
+ }
83
+ return undefined;
84
+ }
85
+ function builtInReason(item) {
86
+ const builtIn = builtInName(item);
87
+ return builtIn ? `is ${/^[AEIO]/.test(builtIn) ? 'an' : 'a'} ${builtIn}, which has no JSON form` : undefined;
88
+ }
89
+ function builtInName(item) {
90
+ if (item === null || typeof item !== 'object')
91
+ return undefined;
92
+ if (item instanceof Map)
93
+ return 'Map';
94
+ if (item instanceof Set)
95
+ return 'Set';
96
+ if (item instanceof WeakMap)
97
+ return 'WeakMap';
98
+ if (item instanceof WeakSet)
99
+ return 'WeakSet';
100
+ if (item instanceof RegExp)
101
+ return 'RegExp';
102
+ if (item instanceof Error)
103
+ return 'Error';
104
+ if (item instanceof Promise)
105
+ return 'Promise';
106
+ if (item instanceof ArrayBuffer)
107
+ return 'ArrayBuffer';
108
+ if (ArrayBuffer.isView(item))
109
+ return item.constructor?.name ?? 'typed array';
110
+ return undefined;
111
+ }
112
+ /**
113
+ * Keys and player addresses go into the request path, where `.`, `..` and an empty segment are
114
+ * resolved away by URL parsing, so they would address a different resource.
115
+ * @internal
116
+ */
117
+ export function assertStorageKey(key, callSite) {
118
+ if (typeof key !== 'string' || key === '' || key === '.' || key === '..') {
119
+ throw new TypeError(`${callSite}: key must be a non-empty string other than "." and "..".`);
120
+ }
121
+ if (LONE_SURROGATE.test(key) || UNSTORABLE_TEXT.test(key)) {
122
+ throw new TypeError(`${callSite}: key must not contain an unpaired surrogate or a NUL character.`);
123
+ }
124
+ // Counted in characters, as the service counts them.
125
+ if ([...key].length > MAX_KEY_LENGTH) {
126
+ throw new TypeError(`${callSite}: key must be at most ${MAX_KEY_LENGTH} characters.`);
127
+ }
128
+ }
129
+ /** @internal */
130
+ export function assertPlayerAddress(address, callSite) {
131
+ if (typeof address !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(address)) {
132
+ throw new TypeError(`${callSite}: address must be a 0x-prefixed 20-byte hex address.`);
133
+ }
134
+ }
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXplLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZlci9zdG9yYWdlL3NlcmlhbGl6ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLGNBQWMsR0FBRyx3RUFBd0UsQ0FBQTtBQUMvRixNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUE7QUFDaEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFBO0FBRTFCOzs7R0FHRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsa0RBQWtELENBQUE7QUFFbEYsa0ZBQWtGO0FBQ2xGLE1BQU0sb0JBQXFCLFNBQVEsU0FBUztDQUFHO0FBSS9DOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFjLEVBQUUsUUFBZ0I7SUFDcEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDbkQsNkZBQTZGO0lBQzdGLElBQUksdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3RDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFBO1FBQ3RDLE1BQU0sSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLG9FQUFvRSxDQUFDLENBQUE7S0FDckc7SUFDRCxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUU7UUFDakIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxHQUFHLFFBQVEsa0VBQWtFLENBQUMsQ0FBQTtLQUNuRztJQUNELE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEtBQWMsRUFBRSxRQUFnQixFQUFFLE1BQWM7SUFDakUsTUFBTSxRQUFRLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQTtJQUMxQixJQUFJO1FBQ0YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxVQUF5QyxRQUFRLEVBQUUsSUFBSTtZQUNyRixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQTtZQUN4QyxJQUFJLEdBQUcsRUFBRTtnQkFDUCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksUUFBUSxHQUFHLENBQUE7Z0JBQy9ELE1BQU0sSUFBSSxvQkFBb0IsQ0FDNUIsR0FBRyxRQUFRLDBDQUEwQyxLQUFLLElBQUksR0FBRyxpQ0FBaUMsQ0FDbkcsQ0FBQTthQUNGO1lBQ0QsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDLENBQUMsQ0FBQTtLQUNIO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxJQUFJLEtBQUssWUFBWSxvQkFBb0I7WUFBRSxNQUFNLEtBQUssQ0FBQTtRQUN0RCxNQUFNLEtBQUssR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25GLE1BQU0sSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLHNDQUFzQyxLQUFLLGtDQUFrQyxDQUFDLENBQUE7S0FDOUc7QUFDSCxDQUFDO0FBRUQsaUdBQWlHO0FBQ2pHLFNBQVMsVUFBVSxDQUFDLE1BQStCLEVBQUUsUUFBZ0IsRUFBRSxJQUFhO0lBQ2xGLFFBQVEsT0FBTyxJQUFJLEVBQUU7UUFDbkIsS0FBSyxVQUFVLENBQUM7UUFDaEIsS0FBSyxRQUFRO1lBQ1gsT0FBTyxRQUFRLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFDOUIsS0FBSyxRQUFRO1lBQ1gsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLDRCQUE0QixJQUFJLEVBQUUsQ0FBQTtRQUMvRSxLQUFLLFdBQVc7WUFDZCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUFFLE9BQU8sb0NBQW9DLENBQUE7WUFDdEUsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO1FBQzdGLEtBQUssUUFBUSxDQUFDLENBQUM7WUFDYixJQUFJLElBQUksS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQUUsT0FBTyxTQUFTLENBQUE7WUFDMUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUM3QyxPQUFPLFNBQVMsS0FBSyxNQUFNLENBQUMsU0FBUyxJQUFJLFNBQVMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQzlGO1FBQ0Q7WUFDRSxPQUFPLFNBQVMsQ0FBQTtLQUNuQjtBQUNILENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsU0FBUyxVQUFVLENBQUMsTUFBK0IsRUFBRSxRQUFnQixFQUFFLElBQWE7SUFDbEYsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDL0MsSUFBSSxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDckIsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRTtRQUN6RixPQUFPLG1EQUFtRCxDQUFBO0tBQzNEO0lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRTtRQUMvRixPQUFPLHdEQUF3RCxDQUFBO0tBQ2hFO0lBQ0QsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLElBQWE7SUFDbEMsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2pDLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLE9BQU8sMEJBQTBCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtBQUM5RyxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsSUFBYTtJQUNoQyxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUTtRQUFFLE9BQU8sU0FBUyxDQUFBO0lBQy9ELElBQUksSUFBSSxZQUFZLEdBQUc7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUNyQyxJQUFJLElBQUksWUFBWSxHQUFHO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDckMsSUFBSSxJQUFJLFlBQVksT0FBTztRQUFFLE9BQU8sU0FBUyxDQUFBO0lBQzdDLElBQUksSUFBSSxZQUFZLE9BQU87UUFBRSxPQUFPLFNBQVMsQ0FBQTtJQUM3QyxJQUFJLElBQUksWUFBWSxNQUFNO1FBQUUsT0FBTyxRQUFRLENBQUE7SUFDM0MsSUFBSSxJQUFJLFlBQVksS0FBSztRQUFFLE9BQU8sT0FBTyxDQUFBO0lBQ3pDLElBQUksSUFBSSxZQUFZLE9BQU87UUFBRSxPQUFPLFNBQVMsQ0FBQTtJQUM3QyxJQUFJLElBQUksWUFBWSxXQUFXO1FBQUUsT0FBTyxhQUFhLENBQUE7SUFDckQsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLElBQUksYUFBYSxDQUFBO0lBQzVFLE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEdBQVksRUFBRSxRQUFnQjtJQUM3RCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLElBQUksRUFBRTtRQUN4RSxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsUUFBUSwyREFBMkQsQ0FBQyxDQUFBO0tBQzVGO0lBQ0QsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDekQsTUFBTSxJQUFJLFNBQVMsQ0FBQyxHQUFHLFFBQVEsa0VBQWtFLENBQUMsQ0FBQTtLQUNuRztJQUNELHFEQUFxRDtJQUNyRCxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsY0FBYyxFQUFFO1FBQ3BDLE1BQU0sSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLHlCQUF5QixjQUFjLGNBQWMsQ0FBQyxDQUFBO0tBQ3RGO0FBQ0gsQ0FBQztBQUVELGdCQUFnQjtBQUNoQixNQUFNLFVBQVUsbUJBQW1CLENBQUMsT0FBZ0IsRUFBRSxRQUFnQjtJQUNwRSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN2RSxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsUUFBUSxzREFBc0QsQ0FBQyxDQUFBO0tBQ3ZGO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IExPTkVfU1VSUk9HQVRFID0gL1tcXHVkODAwLVxcdWRiZmZdKD8hW1xcdWRjMDAtXFx1ZGZmZl0pfCg/PCFbXFx1ZDgwMC1cXHVkYmZmXSlbXFx1ZGMwMC1cXHVkZmZmXS9cbmNvbnN0IFVOU1RPUkFCTEVfVEVYVCA9IC9cXHUwMDAwL1xuY29uc3QgTUFYX0tFWV9MRU5HVEggPSAyNTVcblxuLyoqXG4gKiBKU09OLnN0cmluZ2lmeSBhbHdheXMgd3JpdGVzIE5VTCBhcyBgXFx1MDAwMGAgYW5kIGFuIHVucGFpcmVkIHN1cnJvZ2F0ZSBhcyBhIGBcXHVkWFhYYCBlc2NhcGUgKEVTMjAxOSksXG4gKiB3aGlsZSBwYWlyZWQgc3Vycm9nYXRlcyBzdGF5IHJhdzsgYW4gZXNjYXBlZCBiYWNrc2xhc2ggaW4gZnJvbnQgbWVhbnMgdGhlIHRleHQgaXMgbGl0ZXJhbC5cbiAqL1xuY29uc3QgRVNDQVBFRF9VTlNUT1JBQkxFX1RFWFQgPSAvKD88IVxcXFwpKD86XFxcXFxcXFwpKlxcXFx1KD86MDAwMHxkWzg5YS1mXVswLTlhLWZdezJ9KS9pXG5cbi8qKiBSYWlzZWQgZnJvbSBpbnNpZGUgdGhlIHJlcGxhY2VyLCBzbyBpdCBpcyBub3QgbWlzdGFrZW4gZm9yIGFuIGVuZ2luZSBlcnJvci4gKi9cbmNsYXNzIFVuc3RvcmFibGVWYWx1ZUVycm9yIGV4dGVuZHMgVHlwZUVycm9yIHt9XG5cbnR5cGUgUmVhc29uID0gKGhvbGRlcjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHByb3BlcnR5OiBzdHJpbmcsIGl0ZW06IHVua25vd24pID0+IHN0cmluZyB8IHVuZGVmaW5lZFxuXG4vKipcbiAqIFRoZSBgeyB2YWx1ZSB9YCBQVVQgYm9keS4gUmVqZWN0cywgYXQgYW55IGRlcHRoLCB3aGF0IEpTT04gd291bGQgZHJvcCBvciBjaGFuZ2U6IGZ1bmN0aW9ucyxcbiAqIHN5bWJvbHMsIG5vbi1maW5pdGUgbnVtYmVycywgYHVuZGVmaW5lZGAgYXJyYXkgZWxlbWVudHMgYW5kIGhvbGVzLCBidWlsdC1pbnMgd2l0aCBubyBKU09OIGZvcm1cbiAqIChNYXAsIFNldCwgdHlwZWQgYXJyYXlzLCBSZWdFeHAsIEVycm9yLCAuLi4pLCBhbmQgdGV4dCB0aGUgc2VydmljZSBjYW5ub3Qgc3RvcmUuIEFuIGB1bmRlZmluZWRgXG4gKiBvYmplY3QgcHJvcGVydHkgaXMgZHJvcHBlZCwgYXMgaXQgcmVhZHMgYmFjayB0aGUgc2FtZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplU3RvcmFnZVZhbHVlKHZhbHVlOiB1bmtub3duLCBjYWxsU2l0ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgYm9keSA9IHN0cmluZ2lmeSh2YWx1ZSwgY2FsbFNpdGUsIGZhc3RSZWFzb24pXG4gIC8vIFRleHQgaXMgY2hlY2tlZCBvbmNlIG9uIHRoZSBvdXRwdXQ7IG9ubHkgYSByZWplY3Rpb24gcGF5cyBmb3IgbG9jYXRpbmcgdGhlIG9mZmVuZGluZyBpdGVtLlxuICBpZiAoRVNDQVBFRF9VTlNUT1JBQkxFX1RFWFQudGVzdChib2R5KSkge1xuICAgIHN0cmluZ2lmeSh2YWx1ZSwgY2FsbFNpdGUsIHVuc3RvcmFibGUpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IHZhbHVlIG11c3Qgbm90IGNvbnRhaW4gYW4gdW5wYWlyZWQgc3Vycm9nYXRlIG9yIGEgTlVMIGNoYXJhY3Rlci5gKVxuICB9XG4gIGlmIChib2R5ID09PSAne30nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IHZhbHVlIG11c3QgYmUgSlNPTi1zZXJpYWxpemFibGUuIFVzZSBkZWxldGUoKSB0byByZW1vdmUgYSBrZXkuYClcbiAgfVxuICByZXR1cm4gYm9keVxufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnkodmFsdWU6IHVua25vd24sIGNhbGxTaXRlOiBzdHJpbmcsIHJlYXNvbjogUmVhc29uKTogc3RyaW5nIHtcbiAgY29uc3QgZW52ZWxvcGUgPSB7IHZhbHVlIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUsIGZ1bmN0aW9uICh0aGlzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgcHJvcGVydHksIGl0ZW0pIHtcbiAgICAgIGNvbnN0IHdoeSA9IHJlYXNvbih0aGlzLCBwcm9wZXJ0eSwgaXRlbSlcbiAgICAgIGlmICh3aHkpIHtcbiAgICAgICAgY29uc3Qgd2hlcmUgPSB0aGlzID09PSBlbnZlbG9wZSA/ICd0aGUgdmFsdWUnIDogYFwiJHtwcm9wZXJ0eX1cImBcbiAgICAgICAgdGhyb3cgbmV3IFVuc3RvcmFibGVWYWx1ZUVycm9yKFxuICAgICAgICAgIGAke2NhbGxTaXRlfTogdmFsdWUgbXVzdCBiZSBKU09OLXNlcmlhbGl6YWJsZSwgYnV0ICR7d2hlcmV9ICR7d2h5fS4gVXNlIGRlbGV0ZSgpIHRvIHJlbW92ZSBhIGtleS5gXG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVtXG4gICAgfSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBVbnN0b3JhYmxlVmFsdWVFcnJvcikgdGhyb3cgZXJyb3JcbiAgICBjb25zdCBjYXVzZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlLnNwbGl0KCdcXG4nKVswXSA6IFN0cmluZyhlcnJvcilcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NhbGxTaXRlfTogdmFsdWUgbXVzdCBiZSBKU09OLXNlcmlhbGl6YWJsZSAoJHtjYXVzZX0pLiBVc2UgZGVsZXRlKCkgdG8gcmVtb3ZlIGEga2V5LmApXG4gIH1cbn1cblxuLyoqIEV2ZXJ5dGhpbmcgYnV0IHRoZSB0ZXh0IGNoZWNrcywgd2l0aCBwbGFpbiBvYmplY3RzIGFuZCBhcnJheXMgc2tpcHBpbmcgdGhlIGJ1aWx0LWluIGNoZWNrLiAqL1xuZnVuY3Rpb24gZmFzdFJlYXNvbihob2xkZXI6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBwcm9wZXJ0eTogc3RyaW5nLCBpdGVtOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgc3dpdGNoICh0eXBlb2YgaXRlbSkge1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgcmV0dXJuIGBpcyBhICR7dHlwZW9mIGl0ZW19YFxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKGl0ZW0pID8gdW5kZWZpbmVkIDogYGlzIHRoZSBub24tZmluaXRlIG51bWJlciAke2l0ZW19YFxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShob2xkZXIpKSByZXR1cm4gJ2lzIHVuZGVmaW5lZCBvciBhIGhvbGUgaW4gYW4gYXJyYXknXG4gICAgICByZXR1cm4gaG9sZGVyW3Byb3BlcnR5XSAhPT0gdW5kZWZpbmVkID8gJ2hhcyBhIHRvSlNPTigpIHRoYXQgcmV0dXJucyB1bmRlZmluZWQnIDogdW5kZWZpbmVkXG4gICAgY2FzZSAnb2JqZWN0Jzoge1xuICAgICAgaWYgKGl0ZW0gPT09IG51bGwgfHwgQXJyYXkuaXNBcnJheShpdGVtKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgY29uc3QgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGl0ZW0pXG4gICAgICByZXR1cm4gcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvdHlwZSA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJ1aWx0SW5SZWFzb24oaXRlbSlcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxufVxuXG4vKiogRXZlcnkgY2hlY2ssIHBlciBpdGVtOiB1c2VkIHRvIG5hbWUgdGhlIGl0ZW0gYSB0ZXh0IHJlamVjdGlvbiBjb21lcyBmcm9tLiAqL1xuZnVuY3Rpb24gdW5zdG9yYWJsZShob2xkZXI6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBwcm9wZXJ0eTogc3RyaW5nLCBpdGVtOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZmFzdCA9IGZhc3RSZWFzb24oaG9sZGVyLCBwcm9wZXJ0eSwgaXRlbSlcbiAgaWYgKGZhc3QpIHJldHVybiBmYXN0XG4gIGlmICh0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycgJiYgKExPTkVfU1VSUk9HQVRFLnRlc3QoaXRlbSkgfHwgVU5TVE9SQUJMRV9URVhULnRlc3QoaXRlbSkpKSB7XG4gICAgcmV0dXJuICdjb250YWlucyBhbiB1bnBhaXJlZCBzdXJyb2dhdGUgb3IgYSBOVUwgY2hhcmFjdGVyJ1xuICB9XG4gIGlmICghQXJyYXkuaXNBcnJheShob2xkZXIpICYmIChMT05FX1NVUlJPR0FURS50ZXN0KHByb3BlcnR5KSB8fCBVTlNUT1JBQkxFX1RFWFQudGVzdChwcm9wZXJ0eSkpKSB7XG4gICAgcmV0dXJuICdpcyBhIGtleSB3aXRoIGFuIHVucGFpcmVkIHN1cnJvZ2F0ZSBvciBhIE5VTCBjaGFyYWN0ZXInXG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBidWlsdEluUmVhc29uKGl0ZW06IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBidWlsdEluID0gYnVpbHRJbk5hbWUoaXRlbSlcbiAgcmV0dXJuIGJ1aWx0SW4gPyBgaXMgJHsvXltBRUlPXS8udGVzdChidWlsdEluKSA/ICdhbicgOiAnYSd9ICR7YnVpbHRJbn0sIHdoaWNoIGhhcyBubyBKU09OIGZvcm1gIDogdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGJ1aWx0SW5OYW1lKGl0ZW06IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoaXRlbSA9PT0gbnVsbCB8fCB0eXBlb2YgaXRlbSAhPT0gJ29iamVjdCcpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBNYXApIHJldHVybiAnTWFwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFNldCkgcmV0dXJuICdTZXQnXG4gIGlmIChpdGVtIGluc3RhbmNlb2YgV2Vha01hcCkgcmV0dXJuICdXZWFrTWFwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFdlYWtTZXQpIHJldHVybiAnV2Vha1NldCdcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiAnUmVnRXhwJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gJ0Vycm9yJ1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFByb21pc2UpIHJldHVybiAnUHJvbWlzZSdcbiAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgcmV0dXJuICdBcnJheUJ1ZmZlcidcbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhpdGVtKSkgcmV0dXJuIGl0ZW0uY29uc3RydWN0b3I/Lm5hbWUgPz8gJ3R5cGVkIGFycmF5J1xuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogS2V5cyBhbmQgcGxheWVyIGFkZHJlc3NlcyBnbyBpbnRvIHRoZSByZXF1ZXN0IHBhdGgsIHdoZXJlIGAuYCwgYC4uYCBhbmQgYW4gZW1wdHkgc2VnbWVudCBhcmVcbiAqIHJlc29sdmVkIGF3YXkgYnkgVVJMIHBhcnNpbmcsIHNvIHRoZXkgd291bGQgYWRkcmVzcyBhIGRpZmZlcmVudCByZXNvdXJjZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0U3RvcmFnZUtleShrZXk6IHVua25vd24sIGNhbGxTaXRlOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnIHx8IGtleSA9PT0gJycgfHwga2V5ID09PSAnLicgfHwga2V5ID09PSAnLi4nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IGtleSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZyBvdGhlciB0aGFuIFwiLlwiIGFuZCBcIi4uXCIuYClcbiAgfVxuICBpZiAoTE9ORV9TVVJST0dBVEUudGVzdChrZXkpIHx8IFVOU1RPUkFCTEVfVEVYVC50ZXN0KGtleSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NhbGxTaXRlfToga2V5IG11c3Qgbm90IGNvbnRhaW4gYW4gdW5wYWlyZWQgc3Vycm9nYXRlIG9yIGEgTlVMIGNoYXJhY3Rlci5gKVxuICB9XG4gIC8vIENvdW50ZWQgaW4gY2hhcmFjdGVycywgYXMgdGhlIHNlcnZpY2UgY291bnRzIHRoZW0uXG4gIGlmIChbLi4ua2V5XS5sZW5ndGggPiBNQVhfS0VZX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y2FsbFNpdGV9OiBrZXkgbXVzdCBiZSBhdCBtb3N0ICR7TUFYX0tFWV9MRU5HVEh9IGNoYXJhY3RlcnMuYClcbiAgfVxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UGxheWVyQWRkcmVzcyhhZGRyZXNzOiB1bmtub3duLCBjYWxsU2l0ZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgYWRkcmVzcyAhPT0gJ3N0cmluZycgfHwgIS9eMHhbMC05YS1mQS1GXXs0MH0kLy50ZXN0KGFkZHJlc3MpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjYWxsU2l0ZX06IGFkZHJlc3MgbXVzdCBiZSBhIDB4LXByZWZpeGVkIDIwLWJ5dGUgaGV4IGFkZHJlc3MuYClcbiAgfVxufVxuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ import { DEFAULT_STORAGE_CONFIG } from './constants';
2
+ /**
3
+ * Creates the bounded value cache shared by a storage scope.
4
+ * @internal
5
+ */
6
+ export function createValueCache(config) {
7
+ const entries = new Map();
8
+ const watchers = new Set();
9
+ function noteMutation(key) {
10
+ for (const seen of watchers)
11
+ seen.add(key);
12
+ }
13
+ function insert(key, entry) {
14
+ noteMutation(key);
15
+ // Delete + re-insert moves refreshed keys to the end of the Map's
16
+ // insertion order, so eviction below drops the least-recently-written.
17
+ entries.delete(key);
18
+ entries.set(key, { ...entry, storedAt: Date.now() });
19
+ // Guard against misconfiguration: a negative bound would loop forever on
20
+ // an empty map, and a NaN bound would silently disable eviction.
21
+ const maxEntries = !Number.isNaN(config.cacheMaxEntries)
22
+ ? Math.max(0, config.cacheMaxEntries)
23
+ : DEFAULT_STORAGE_CONFIG.cacheMaxEntries;
24
+ while (entries.size > maxEntries) {
25
+ entries.delete(entries.keys().next().value);
26
+ }
27
+ }
28
+ return {
29
+ get(key) {
30
+ const entry = entries.get(key);
31
+ if (!entry)
32
+ return undefined;
33
+ // Guard against misconfiguration, mirroring cacheMaxEntries: a NaN
34
+ // bound would silently disable expiry (NaN comparisons are false).
35
+ // Negative values need no guard — they just expire everything.
36
+ const maxAgeMs = !Number.isNaN(config.cacheMaxAgeMs) ? config.cacheMaxAgeMs : DEFAULT_STORAGE_CONFIG.cacheMaxAgeMs;
37
+ // Lazy max-age expiry: storedAt is never refreshed on hits, so the age
38
+ // bounds the time since the last actual network confirmation.
39
+ if (Date.now() - entry.storedAt > maxAgeMs) {
40
+ entries.delete(key);
41
+ return undefined;
42
+ }
43
+ return entry;
44
+ },
45
+ set(key, entry) {
46
+ insert(key, entry);
47
+ },
48
+ setAbsent(key) {
49
+ insert(key, { absent: true });
50
+ },
51
+ delete(key) {
52
+ noteMutation(key);
53
+ entries.delete(key);
54
+ },
55
+ watch() {
56
+ const seen = new Set();
57
+ watchers.add(seen);
58
+ return {
59
+ mutated: (key) => seen.has(key),
60
+ stop: () => {
61
+ watchers.delete(seen);
62
+ }
63
+ };
64
+ }
65
+ };
66
+ }
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsdWUtY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmVyL3N0b3JhZ2UvdmFsdWUtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHNCQUFzQixFQUFzQixNQUFNLGFBQWEsQ0FBQTtBQTRDeEU7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE1BQTBCO0lBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFBO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFlLENBQUE7SUFFdkMsU0FBUyxZQUFZLENBQUMsR0FBVztRQUMvQixLQUFLLE1BQU0sSUFBSSxJQUFJLFFBQVE7WUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCxTQUFTLE1BQU0sQ0FBQyxHQUFXLEVBQUUsS0FBaUI7UUFDNUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2pCLGtFQUFrRTtRQUNsRSx1RUFBdUU7UUFDdkUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRXBELHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUM7WUFDdEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxlQUFlLENBQUM7WUFDckMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQTtRQUUxQyxPQUFPLE9BQU8sQ0FBQyxJQUFJLEdBQUcsVUFBVSxFQUFFO1lBQ2hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQU0sQ0FBQyxDQUFBO1NBQzdDO0lBQ0gsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLENBQUMsR0FBVztZQUNiLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDOUIsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxTQUFTLENBQUE7WUFFNUIsbUVBQW1FO1lBQ25FLG1FQUFtRTtZQUNuRSwrREFBK0Q7WUFDL0QsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFBO1lBRWxILHVFQUF1RTtZQUN2RSw4REFBOEQ7WUFDOUQsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsR0FBRyxRQUFRLEVBQUU7Z0JBQzFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ25CLE9BQU8sU0FBUyxDQUFBO2FBQ2pCO1lBRUQsT0FBTyxLQUFLLENBQUE7UUFDZCxDQUFDO1FBRUQsR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUF1QjtZQUN0QyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFBO1FBQ3BCLENBQUM7UUFFRCxTQUFTLENBQUMsR0FBVztZQUNuQixNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDL0IsQ0FBQztRQUVELE1BQU0sQ0FBQyxHQUFXO1lBQ2hCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNqQixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3JCLENBQUM7UUFFRCxLQUFLO1lBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQTtZQUM5QixRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2xCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLEdBQUcsRUFBRTtvQkFDVCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO2dCQUN2QixDQUFDO2FBQ0YsQ0FBQTtRQUNILENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERFRkFVTFRfU1RPUkFHRV9DT05GSUcsIFN0b3JhZ2VDb25maWdTdGF0ZSB9IGZyb20gJy4vY29uc3RhbnRzJ1xuXG4vKipcbiAqIEEgY2FjaGVkIGZhY3QgYWJvdXQgYSBrZXkncyBzZXJ2ZXItc2lkZSBzdGF0ZS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlRW50cnkge1xuICAvKipcbiAgICogU2VyaWFsaXplZCBgeyB2YWx1ZSB9YCBib2R5OyBhYnNlbnQgZm9yIG5lZ2F0aXZlIGVudHJpZXMuIFBhcnNlZCBwZXIgcmVhZFxuICAgKiBoaXQgc28gY2FsbGVycyBuZXZlciBzaGFyZSBvYmplY3QgcmVmZXJlbmNlcywgYW5kIGNvbXBhcmVkIHZlcmJhdGltIGZvclxuICAgKiB3cml0ZSBkZWR1cCAoZXhhY3QgZXF1YWxpdHkg4oCUIG5vIGhhc2gtY29sbGlzaW9uIHJpc2spLlxuICAgKi9cbiAgYm9keT86IHN0cmluZ1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBzZXJ2ZXIgY29uZmlybWVkIHRoZSBrZXkgZG9lcyBub3QgZXhpc3QgKEdFVCA0MDQgb3Igc3VjY2Vzc2Z1bCBERUxFVEUpLiAqL1xuICBhYnNlbnQ/OiBib29sZWFuXG59XG5cbi8qKlxuICogQm91bmRlZCwgbGF6aWx5LWV4cGlyaW5nIGNhY2hlIG9mIGtleSBzdGF0ZXMsIGJhY2tpbmcgYm90aCB3cml0ZSBkZWR1cFxuICogKHNraXAgc3RvcmFnZSB3cml0ZXMgd2hvc2UgdmFsdWUgaXMgYWxyZWFkeSBrbm93biB0byBiZSBzdG9yZWQpIGFuZCByZWFkXG4gKiBjYWNoaW5nIChzZXJ2ZSBnZXQoKSB3aXRob3V0IGEgbmV0d29yayByZXF1ZXN0IHdpdGhpbiB0aGUgVFRMKS5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbHVlQ2FjaGUge1xuICAvKiogUmV0dXJucyB0aGUgZW50cnkgaWYgcHJlc2VudCBhbmQgZnJlc2g7IGxhemlseSBldmljdHMgZXhwaXJlZCBlbnRyaWVzLiAqL1xuICBnZXQoa2V5OiBzdHJpbmcpOiBDYWNoZUVudHJ5IHwgdW5kZWZpbmVkXG4gIC8qKiBTdG9yZXMgb3IgcmVmcmVzaGVzIGEga25vd24gdmFsdWUgKHNlcmlhbGl6ZWQgYm9keSk7IG92ZXJ3cml0ZXMgbmVnYXRpdmUgZW50cmllcy4gKi9cbiAgc2V0KGtleTogc3RyaW5nLCBlbnRyeTogeyBib2R5OiBzdHJpbmcgfSk6IHZvaWRcbiAgLyoqIFN0b3JlcyBhIGNvbmZpcm1lZC1hYnNlbnQgKG5lZ2F0aXZlKSBlbnRyeSwgcmVwbGFjaW5nIGFueSB2YWx1ZSBlbnRyeS4gKi9cbiAgc2V0QWJzZW50KGtleTogc3RyaW5nKTogdm9pZFxuICBkZWxldGUoa2V5OiBzdHJpbmcpOiB2b2lkXG4gIC8qKiBTdGFydHMgcmVjb3JkaW5nIG11dGF0ZWQga2V5cywgc28gYSByZWFkIGlzc3VlZCBlYXJsaWVyIGNhbiB0ZWxsIGl0cyBzbmFwc2hvdCB3ZW50IHN0YWxlLiAqL1xuICB3YXRjaCgpOiBDYWNoZVdhdGNoZXJcbn1cblxuLyoqXG4gKiBLZXlzIG11dGF0ZWQgc2luY2UgdGhlIHdhdGNoIHN0YXJ0ZWQuIEFsd2F5cyBzdG9wKCkgaXQsIG9yIGl0IGtlZXBzIGNvbGxlY3RpbmcuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWNoZVdhdGNoZXIge1xuICBtdXRhdGVkKGtleTogc3RyaW5nKTogYm9vbGVhblxuICBzdG9wKCk6IHZvaWRcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBib3VuZGVkIHZhbHVlIGNhY2hlIHNoYXJlZCBieSBhIHN0b3JhZ2Ugc2NvcGUuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVZhbHVlQ2FjaGUoY29uZmlnOiBTdG9yYWdlQ29uZmlnU3RhdGUpOiBWYWx1ZUNhY2hlIHtcbiAgY29uc3QgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBDYWNoZUVudHJ5ICYgeyBzdG9yZWRBdDogbnVtYmVyIH0+KClcbiAgY29uc3Qgd2F0Y2hlcnMgPSBuZXcgU2V0PFNldDxzdHJpbmc+PigpXG5cbiAgZnVuY3Rpb24gbm90ZU11dGF0aW9uKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBzZWVuIG9mIHdhdGNoZXJzKSBzZWVuLmFkZChrZXkpXG4gIH1cblxuICBmdW5jdGlvbiBpbnNlcnQoa2V5OiBzdHJpbmcsIGVudHJ5OiBDYWNoZUVudHJ5KTogdm9pZCB7XG4gICAgbm90ZU11dGF0aW9uKGtleSlcbiAgICAvLyBEZWxldGUgKyByZS1pbnNlcnQgbW92ZXMgcmVmcmVzaGVkIGtleXMgdG8gdGhlIGVuZCBvZiB0aGUgTWFwJ3NcbiAgICAvLyBpbnNlcnRpb24gb3JkZXIsIHNvIGV2aWN0aW9uIGJlbG93IGRyb3BzIHRoZSBsZWFzdC1yZWNlbnRseS13cml0dGVuLlxuICAgIGVudHJpZXMuZGVsZXRlKGtleSlcbiAgICBlbnRyaWVzLnNldChrZXksIHsgLi4uZW50cnksIHN0b3JlZEF0OiBEYXRlLm5vdygpIH0pXG5cbiAgICAvLyBHdWFyZCBhZ2FpbnN0IG1pc2NvbmZpZ3VyYXRpb246IGEgbmVnYXRpdmUgYm91bmQgd291bGQgbG9vcCBmb3JldmVyIG9uXG4gICAgLy8gYW4gZW1wdHkgbWFwLCBhbmQgYSBOYU4gYm91bmQgd291bGQgc2lsZW50bHkgZGlzYWJsZSBldmljdGlvbi5cbiAgICBjb25zdCBtYXhFbnRyaWVzID0gIU51bWJlci5pc05hTihjb25maWcuY2FjaGVNYXhFbnRyaWVzKVxuICAgICAgPyBNYXRoLm1heCgwLCBjb25maWcuY2FjaGVNYXhFbnRyaWVzKVxuICAgICAgOiBERUZBVUxUX1NUT1JBR0VfQ09ORklHLmNhY2hlTWF4RW50cmllc1xuXG4gICAgd2hpbGUgKGVudHJpZXMuc2l6ZSA+IG1heEVudHJpZXMpIHtcbiAgICAgIGVudHJpZXMuZGVsZXRlKGVudHJpZXMua2V5cygpLm5leHQoKS52YWx1ZSEpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBnZXQoa2V5OiBzdHJpbmcpOiBDYWNoZUVudHJ5IHwgdW5kZWZpbmVkIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gZW50cmllcy5nZXQoa2V5KVxuICAgICAgaWYgKCFlbnRyeSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgICAvLyBHdWFyZCBhZ2FpbnN0IG1pc2NvbmZpZ3VyYXRpb24sIG1pcnJvcmluZyBjYWNoZU1heEVudHJpZXM6IGEgTmFOXG4gICAgICAvLyBib3VuZCB3b3VsZCBzaWxlbnRseSBkaXNhYmxlIGV4cGlyeSAoTmFOIGNvbXBhcmlzb25zIGFyZSBmYWxzZSkuXG4gICAgICAvLyBOZWdhdGl2ZSB2YWx1ZXMgbmVlZCBubyBndWFyZCDigJQgdGhleSBqdXN0IGV4cGlyZSBldmVyeXRoaW5nLlxuICAgICAgY29uc3QgbWF4QWdlTXMgPSAhTnVtYmVyLmlzTmFOKGNvbmZpZy5jYWNoZU1heEFnZU1zKSA/IGNvbmZpZy5jYWNoZU1heEFnZU1zIDogREVGQVVMVF9TVE9SQUdFX0NPTkZJRy5jYWNoZU1heEFnZU1zXG5cbiAgICAgIC8vIExhenkgbWF4LWFnZSBleHBpcnk6IHN0b3JlZEF0IGlzIG5ldmVyIHJlZnJlc2hlZCBvbiBoaXRzLCBzbyB0aGUgYWdlXG4gICAgICAvLyBib3VuZHMgdGhlIHRpbWUgc2luY2UgdGhlIGxhc3QgYWN0dWFsIG5ldHdvcmsgY29uZmlybWF0aW9uLlxuICAgICAgaWYgKERhdGUubm93KCkgLSBlbnRyeS5zdG9yZWRBdCA+IG1heEFnZU1zKSB7XG4gICAgICAgIGVudHJpZXMuZGVsZXRlKGtleSlcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZW50cnlcbiAgICB9LFxuXG4gICAgc2V0KGtleTogc3RyaW5nLCBlbnRyeTogeyBib2R5OiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgaW5zZXJ0KGtleSwgZW50cnkpXG4gICAgfSxcblxuICAgIHNldEFic2VudChrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgaW5zZXJ0KGtleSwgeyBhYnNlbnQ6IHRydWUgfSlcbiAgICB9LFxuXG4gICAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgICBub3RlTXV0YXRpb24oa2V5KVxuICAgICAgZW50cmllcy5kZWxldGUoa2V5KVxuICAgIH0sXG5cbiAgICB3YXRjaCgpOiBDYWNoZVdhdGNoZXIge1xuICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gICAgICB3YXRjaGVycy5hZGQoc2VlbilcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG11dGF0ZWQ6IChrZXk6IHN0cmluZykgPT4gc2Vlbi5oYXMoa2V5KSxcbiAgICAgICAgc3RvcDogKCkgPT4ge1xuICAgICAgICAgIHdhdGNoZXJzLmRlbGV0ZShzZWVuKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -0,0 +1 @@
1
+ export {};