velocious 1.0.489 → 1.0.492
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/build/application.js +3 -0
- package/build/cli/commands/db/tenants/create.js +7 -5
- package/build/cli/commands/db/tenants/drop.js +6 -6
- package/build/configuration-types.js +8 -0
- package/build/configuration.js +29 -0
- package/build/database/query/index.js +30 -0
- package/build/database/query/model-class-query.js +17 -0
- package/build/database/record/index.js +16 -0
- package/build/src/application.d.ts.map +1 -1
- package/build/src/application.js +3 -1
- package/build/src/cli/commands/db/tenants/create.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/create.js +8 -5
- package/build/src/cli/commands/db/tenants/drop.d.ts +1 -1
- package/build/src/cli/commands/db/tenants/drop.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/drop.js +7 -6
- package/build/src/configuration-types.d.ts +24 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +8 -1
- package/build/src/configuration.d.ts +6 -0
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +26 -1
- package/build/src/database/query/index.d.ts +25 -0
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +26 -1
- package/build/src/database/query/model-class-query.d.ts +10 -0
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +16 -1
- package/build/src/database/record/index.d.ts +7 -0
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +15 -1
- package/build/src/sync/query-scope.d.ts +18 -0
- package/build/src/sync/query-scope.d.ts.map +1 -0
- package/build/src/sync/query-scope.js +77 -0
- package/build/src/sync/server-change-feed.d.ts.map +1 -1
- package/build/src/sync/server-change-feed.js +2 -24
- package/build/src/sync/stable-json.d.ts +9 -0
- package/build/src/sync/stable-json.d.ts.map +1 -0
- package/build/src/sync/stable-json.js +27 -0
- package/build/src/sync/sync-api-client.d.ts +185 -5
- package/build/src/sync/sync-api-client.d.ts.map +1 -1
- package/build/src/sync/sync-api-client.js +309 -17
- package/build/src/sync/sync-api-controller.d.ts +8 -0
- package/build/src/sync/sync-api-controller.d.ts.map +1 -1
- package/build/src/sync/sync-api-controller.js +17 -1
- package/build/src/sync/sync-client-registry.d.ts +12 -0
- package/build/src/sync/sync-client-registry.d.ts.map +1 -0
- package/build/src/sync/sync-client-registry.js +27 -0
- package/build/src/sync/sync-client-types.d.ts +127 -0
- package/build/src/sync/sync-client-types.d.ts.map +1 -0
- package/build/src/sync/sync-client-types.js +3 -0
- package/build/src/sync/sync-client.d.ts +176 -0
- package/build/src/sync/sync-client.d.ts.map +1 -0
- package/build/src/sync/sync-client.js +380 -0
- package/build/src/sync/sync-envelope-replay-service.d.ts +38 -4
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +73 -6
- package/build/src/sync/sync-resource-base.d.ts +98 -0
- package/build/src/sync/sync-resource-base.d.ts.map +1 -0
- package/build/src/sync/sync-resource-base.js +122 -0
- package/build/src/sync/sync-scope-store.d.ts +128 -0
- package/build/src/sync/sync-scope-store.d.ts.map +1 -0
- package/build/src/sync/sync-scope-store.js +282 -0
- package/build/src/tenants/default-tenant-database-provisioning.d.ts +21 -0
- package/build/src/tenants/default-tenant-database-provisioning.d.ts.map +1 -0
- package/build/src/tenants/default-tenant-database-provisioning.js +106 -0
- package/build/src/tenants/tenant.d.ts.map +1 -1
- package/build/src/tenants/tenant.js +6 -5
- package/build/sync/query-scope.js +84 -0
- package/build/sync/server-change-feed.js +1 -25
- package/build/sync/stable-json.js +28 -0
- package/build/sync/sync-api-client.js +331 -17
- package/build/sync/sync-api-controller.js +20 -0
- package/build/sync/sync-client-registry.js +30 -0
- package/build/sync/sync-client-types.js +41 -0
- package/build/sync/sync-client.js +433 -0
- package/build/sync/sync-envelope-replay-service.js +77 -5
- package/build/sync/sync-resource-base.js +143 -0
- package/build/sync/sync-scope-store.js +327 -0
- package/build/tenants/default-tenant-database-provisioning.js +124 -0
- package/build/tenants/tenant.js +5 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/application.js +3 -0
- package/src/cli/commands/db/tenants/create.js +7 -5
- package/src/cli/commands/db/tenants/drop.js +6 -6
- package/src/configuration-types.js +8 -0
- package/src/configuration.js +29 -0
- package/src/database/query/index.js +30 -0
- package/src/database/query/model-class-query.js +17 -0
- package/src/database/record/index.js +16 -0
- package/src/sync/query-scope.js +84 -0
- package/src/sync/server-change-feed.js +1 -25
- package/src/sync/stable-json.js +28 -0
- package/src/sync/sync-api-client.js +331 -17
- package/src/sync/sync-api-controller.js +20 -0
- package/src/sync/sync-client-registry.js +30 -0
- package/src/sync/sync-client-types.js +41 -0
- package/src/sync/sync-client.js +433 -0
- package/src/sync/sync-envelope-replay-service.js +77 -5
- package/src/sync/sync-resource-base.js +143 -0
- package/src/sync/sync-scope-store.js +327 -0
- package/src/tenants/default-tenant-database-provisioning.js +124 -0
- package/src/tenants/tenant.js +5 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
import { optionalInteger } from "typanic";
|
|
2
|
+
import { optionalBoolean, optionalInteger } from "typanic";
|
|
3
|
+
const syncTaskPromises = new Map();
|
|
3
4
|
/** @typedef {import("./sync-api-client-types.js").SyncChangeApplyResult} SyncChangeApplyResult */
|
|
4
5
|
/** @typedef {import("./sync-api-client-types.js").SyncChangeEnvelope} SyncChangeEnvelope */
|
|
5
6
|
/** @typedef {import("./sync-api-client-types.js").SyncChangesRequest} SyncChangesRequest */
|
|
@@ -15,6 +16,77 @@ import { optionalInteger } from "typanic";
|
|
|
15
16
|
* persistence/auth hooks.
|
|
16
17
|
*/
|
|
17
18
|
export default class SyncApiClient {
|
|
19
|
+
/**
|
|
20
|
+
* Serializes sync work with the same key so callers do not have to keep app-local locks.
|
|
21
|
+
* @param {string} key - Lock key.
|
|
22
|
+
* @param {() => Promise<void>} callback - Work to run once previous work finished.
|
|
23
|
+
* @returns {Promise<void>}
|
|
24
|
+
*/
|
|
25
|
+
static async singleFlight(key, callback) {
|
|
26
|
+
while (syncTaskPromises.has(key)) {
|
|
27
|
+
try {
|
|
28
|
+
await syncTaskPromises.get(key);
|
|
29
|
+
}
|
|
30
|
+
catch (_error) {
|
|
31
|
+
// The failed flight's own caller observes that rejection; callers queued
|
|
32
|
+
// behind it still run their own work so pending rows retry after the lock clears.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const promise = callback();
|
|
36
|
+
syncTaskPromises.set(key, promise);
|
|
37
|
+
try {
|
|
38
|
+
await promise;
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
if (syncTaskPromises.get(key) === promise)
|
|
42
|
+
syncTaskPromises.delete(key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Pulls backend sync changes with a framework-managed cursor row.
|
|
47
|
+
* @param {object} args - Pull args.
|
|
48
|
+
* @param {string} args.authenticationToken - Auth token to send with change requests.
|
|
49
|
+
* @param {number} [args.batchSize] - Max syncs per request.
|
|
50
|
+
* @param {?} args.cursorModel - Model that responds to findBy/findOrInitializeBy for cursor persistence.
|
|
51
|
+
* @param {string} args.cursorKey - Cursor option key.
|
|
52
|
+
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
53
|
+
* @param {Record<string, SyncResourceConfig>} args.resources - Resource policies.
|
|
54
|
+
* @param {(progress: {pages: number, syncedCount: number}) => void} [args.onProgress] - Progress callback.
|
|
55
|
+
* @returns {Promise<SyncChangesResult>} Pull result.
|
|
56
|
+
*/
|
|
57
|
+
static async pullChangesWithCursor(args) {
|
|
58
|
+
return await this.pullChanges({
|
|
59
|
+
authenticationToken: args.authenticationToken,
|
|
60
|
+
batchSize: args.batchSize,
|
|
61
|
+
loadCursor: async () => await this.loadSyncCursor({ cursorKey: args.cursorKey, cursorModel: args.cursorModel }),
|
|
62
|
+
saveCursor: async (cursor) => await this.saveSyncCursor({ cursor, cursorKey: args.cursorKey, cursorModel: args.cursorModel }),
|
|
63
|
+
postChanges: args.postChanges,
|
|
64
|
+
applySync: this.resourceApplier(args.resources),
|
|
65
|
+
onProgress: args.onProgress
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Loads a persisted sync cursor from a model row with a value column.
|
|
70
|
+
* @param {{cursorKey: string, cursorModel: ?}} args - Cursor args.
|
|
71
|
+
* @returns {Promise<string | null>} Persisted cursor payload.
|
|
72
|
+
*/
|
|
73
|
+
static async loadSyncCursor({ cursorKey, cursorModel }) {
|
|
74
|
+
const option = await cursorModel.findBy({ key: cursorKey });
|
|
75
|
+
return option ? option.value() : null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Saves a persisted sync cursor to a model row with a value column.
|
|
79
|
+
* @param {{cursor: SyncCursor, cursorKey: string, cursorModel: ?}} args - Cursor args.
|
|
80
|
+
* @returns {Promise<void>}
|
|
81
|
+
*/
|
|
82
|
+
static async saveSyncCursor({ cursor, cursorKey, cursorModel }) {
|
|
83
|
+
if (!cursor)
|
|
84
|
+
return;
|
|
85
|
+
const option = await cursorModel.findOrInitializeBy({ key: cursorKey });
|
|
86
|
+
option.assign({ value: JSON.stringify(cursor) });
|
|
87
|
+
if (option.isChanged())
|
|
88
|
+
await option.save();
|
|
89
|
+
}
|
|
18
90
|
/**
|
|
19
91
|
* Pulls backend sync changes in stable pages, applies them locally, and stores
|
|
20
92
|
* the acknowledged cursor. Apps provide only auth, persistence, transport, and
|
|
@@ -166,50 +238,65 @@ export default class SyncApiClient {
|
|
|
166
238
|
* mechanics stay here; apps only declare which models/attributes/hooks are
|
|
167
239
|
* allowed for each resource type.
|
|
168
240
|
* @param {Record<string, SyncResourceConfig>} resources - Resource policy map.
|
|
241
|
+
* @param {(record: ?) => () => void} [onRecord] - Called with each record about to be written; returns a release callback invoked after the write (used for echo suppression).
|
|
169
242
|
* @returns {(sync: SyncChangeEnvelope) => Promise<SyncChangeApplyResult>} Sync apply callback.
|
|
170
243
|
*/
|
|
171
|
-
static resourceApplier(resources) {
|
|
172
|
-
return async (sync) => await this.applyResourceSync({ resources, sync });
|
|
244
|
+
static resourceApplier(resources, onRecord) {
|
|
245
|
+
return async (sync) => await this.applyResourceSync({ onRecord, resources, sync });
|
|
173
246
|
}
|
|
174
247
|
/**
|
|
175
248
|
* Applies one sync row using declarative resource policy.
|
|
176
|
-
* @param {{resources: Record<string, SyncResourceConfig>, sync: SyncChangeEnvelope}} args - Apply args.
|
|
249
|
+
* @param {{resources: Record<string, SyncResourceConfig>, sync: SyncChangeEnvelope, onRecord?: (record: ?) => () => void}} args - Apply args.
|
|
177
250
|
* @returns {Promise<SyncChangeApplyResult>} Apply result.
|
|
178
251
|
*/
|
|
179
|
-
static async applyResourceSync({ resources, sync }) {
|
|
252
|
+
static async applyResourceSync({ onRecord, resources, sync }) {
|
|
180
253
|
const resourceType = sync.resourceType();
|
|
181
254
|
const resource = resourceType ? resources[resourceType] : undefined;
|
|
182
255
|
if (!resource || !resource.enabled)
|
|
183
256
|
return { changed: false, resourceType };
|
|
184
257
|
if (sync.syncType() === "delete") {
|
|
185
|
-
return { changed: await this.destroySyncedResource({ resource, sync }), resourceType };
|
|
258
|
+
return { changed: await this.destroySyncedResource({ onRecord, resource, sync }), resourceType };
|
|
186
259
|
}
|
|
187
260
|
const data = this.syncData(sync);
|
|
188
261
|
const record = resource.findRecord ? await resource.findRecord({ data, resourceId: sync.resourceId(), sync }) : await resource.modelClass.findOrInitializeBy({ id: data.id ?? sync.resourceId() });
|
|
189
262
|
const attributes = await resource.attributes({ data, record, sync });
|
|
263
|
+
const releaseRecord = onRecord ? onRecord(record) : null;
|
|
190
264
|
let changed = false;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
265
|
+
try {
|
|
266
|
+
record.assign(attributes);
|
|
267
|
+
if (record.isChanged()) {
|
|
268
|
+
await record.save();
|
|
269
|
+
changed = true;
|
|
270
|
+
}
|
|
271
|
+
if (resource.afterApply) {
|
|
272
|
+
const hookChanged = await resource.afterApply({ attributes, data, record, sync });
|
|
273
|
+
changed ||= hookChanged === true;
|
|
274
|
+
}
|
|
195
275
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
276
|
+
finally {
|
|
277
|
+
if (releaseRecord)
|
|
278
|
+
releaseRecord();
|
|
199
279
|
}
|
|
200
280
|
return { changed, resourceType };
|
|
201
281
|
}
|
|
202
282
|
/**
|
|
203
283
|
* Destroys a synced resource via its declared model policy.
|
|
204
|
-
* @param {{resource: SyncResourceConfig, sync: SyncChangeEnvelope}} args - Destroy args.
|
|
284
|
+
* @param {{resource: SyncResourceConfig, sync: SyncChangeEnvelope, onRecord?: (record: ?) => () => void}} args - Destroy args.
|
|
205
285
|
* @returns {Promise<boolean>} Whether a local row was destroyed.
|
|
206
286
|
*/
|
|
207
|
-
static async destroySyncedResource({ resource, sync }) {
|
|
287
|
+
static async destroySyncedResource({ onRecord, resource, sync }) {
|
|
208
288
|
const id = sync.resourceId();
|
|
209
289
|
const record = resource.findRecordForDelete ? await resource.findRecordForDelete({ resourceId: id, sync }) : await resource.modelClass.findBy({ id });
|
|
210
290
|
if (!record)
|
|
211
291
|
return false;
|
|
212
|
-
|
|
292
|
+
const releaseRecord = onRecord ? onRecord(record) : null;
|
|
293
|
+
try {
|
|
294
|
+
await record.destroy();
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
if (releaseRecord)
|
|
298
|
+
releaseRecord();
|
|
299
|
+
}
|
|
213
300
|
return true;
|
|
214
301
|
}
|
|
215
302
|
/**
|
|
@@ -227,6 +314,211 @@ export default class SyncApiClient {
|
|
|
227
314
|
return /** @type {Record<string, unknown>} */ (data);
|
|
228
315
|
throw new Error(`Sync ${sync.id()} has invalid data`);
|
|
229
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Drains pending sync records from a local Velocious model in stable order.
|
|
319
|
+
* @param {object} args - Replay args.
|
|
320
|
+
* @param {string} args.authenticationToken - Auth token to send with replay requests.
|
|
321
|
+
* @param {number} [args.batchSize] - Max syncs per request.
|
|
322
|
+
* @param {?} args.syncModel - Local Sync model class.
|
|
323
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ?>>}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
324
|
+
* @returns {Promise<void>}
|
|
325
|
+
*/
|
|
326
|
+
static async replayLocalSyncs(args) {
|
|
327
|
+
const postedSnapshotsBySyncId = new Map();
|
|
328
|
+
await this.replayPending({
|
|
329
|
+
authenticationToken: args.authenticationToken,
|
|
330
|
+
batchSize: args.batchSize,
|
|
331
|
+
markSuccessful: async (sync) => {
|
|
332
|
+
const syncId = ( /** @type {{id: () => string | number | null | undefined}} */(sync)).id();
|
|
333
|
+
// Reload with the resource preloaded so rows relying on the resource-attributes
|
|
334
|
+
// fallback in localSyncData compare against the same snapshot they posted.
|
|
335
|
+
const currentSync = await args.syncModel.preload({ resource: true }).where({ id: syncId }).first();
|
|
336
|
+
if (!currentSync)
|
|
337
|
+
return;
|
|
338
|
+
// A row edited while its old payload was in flight stays pending, so the
|
|
339
|
+
// newer local change replays on the next drain instead of being lost.
|
|
340
|
+
if (this.localSyncReplaySnapshot(currentSync) !== postedSnapshotsBySyncId.get(String(syncId)))
|
|
341
|
+
return;
|
|
342
|
+
await currentSync.update({ state: "success" });
|
|
343
|
+
},
|
|
344
|
+
pendingSyncs: async () => await args.syncModel.preload({ resource: true }).where({ state: "pending" }).order("created_at").toArray(),
|
|
345
|
+
postReplay: args.postReplay,
|
|
346
|
+
syncId: (sync) => ( /** @type {{id: () => string | number | null | undefined}} */(sync)).id(),
|
|
347
|
+
syncPayload: (sync) => {
|
|
348
|
+
postedSnapshotsBySyncId.set(String(( /** @type {{id: () => string | number | null | undefined}} */(sync)).id()), this.localSyncReplaySnapshot(sync));
|
|
349
|
+
return this.localSyncPayload(sync);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Serializes the replay-relevant state of a local sync row for in-flight comparisons.
|
|
355
|
+
* @param {?} sync - Local sync row.
|
|
356
|
+
* @returns {string} Stable snapshot of the row's replayed payload.
|
|
357
|
+
*/
|
|
358
|
+
static localSyncReplaySnapshot(sync) {
|
|
359
|
+
return JSON.stringify({ data: this.localSyncData(sync), syncType: sync.syncType() });
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Builds one replay envelope from a local sync row.
|
|
363
|
+
* @param {?} sync - Local sync row.
|
|
364
|
+
* @returns {{clientUpdatedAt?: string, data: Record<string, unknown>, id: number, resourceId: string, resourceType: string, syncType: string}} Sync replay envelope.
|
|
365
|
+
*/
|
|
366
|
+
static localSyncPayload(sync) {
|
|
367
|
+
const clientUpdatedAt = sync.updatedAt() || sync.createdAt();
|
|
368
|
+
return {
|
|
369
|
+
clientUpdatedAt: clientUpdatedAt ? clientUpdatedAt.toISOString() : undefined,
|
|
370
|
+
data: this.localSyncData(sync),
|
|
371
|
+
id: /** @type {number} */ ( /** @type {unknown} */(sync.id())),
|
|
372
|
+
resourceId: String(sync.resourceId()),
|
|
373
|
+
resourceType: sync.resourceType() || "",
|
|
374
|
+
syncType: sync.syncType()
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Resolves one local sync row payload, falling back to preloaded resource attributes.
|
|
379
|
+
* @param {?} sync - Local sync row.
|
|
380
|
+
* @returns {Record<string, unknown>} Sync data.
|
|
381
|
+
*/
|
|
382
|
+
static localSyncData(sync) {
|
|
383
|
+
let syncData = /** @type {string | Record<string, unknown>} */ (sync.data() || {});
|
|
384
|
+
if (typeof syncData === "string") {
|
|
385
|
+
try {
|
|
386
|
+
syncData = /** @type {Record<string, unknown>} */ (JSON.parse(syncData));
|
|
387
|
+
}
|
|
388
|
+
catch (_error) {
|
|
389
|
+
syncData = {};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (Object.keys(syncData).length > 0)
|
|
393
|
+
return syncData;
|
|
394
|
+
try {
|
|
395
|
+
return /** @type {Record<string, unknown>} */ (sync.resource().attributes());
|
|
396
|
+
}
|
|
397
|
+
catch (_error) {
|
|
398
|
+
return {};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Queues a local sync row for a Velocious model resource.
|
|
403
|
+
* @param {object} args - Queue args.
|
|
404
|
+
* @param {?} args.resource - Resource being synced.
|
|
405
|
+
* @param {?} args.syncModel - Local Sync model class.
|
|
406
|
+
* @param {Record<string, unknown>} [args.data] - Explicit sync data.
|
|
407
|
+
* @param {string} [args.syncType] - Sync operation type.
|
|
408
|
+
* @param {string[]} [args.localOnlyAttributes] - Attributes to strip from queued payloads.
|
|
409
|
+
* @param {string[]} [args.booleanAttributes] - Attributes to coerce through sync boolean parsing.
|
|
410
|
+
* @param {(data: Record<string, unknown>) => Record<string, unknown>} [args.normalizeData] - App-specific data normalizer.
|
|
411
|
+
* @returns {Promise<?>} Local sync row.
|
|
412
|
+
*/
|
|
413
|
+
static async queueLocalSync(args) {
|
|
414
|
+
const resourceRecordId = args.resource.id();
|
|
415
|
+
const modelClass = args.resource.constructor;
|
|
416
|
+
if (typeof modelClass.getModelName !== "function") {
|
|
417
|
+
throw new Error("The resource model class must implement static getModelName() to queue sync data - class names are not stable across explicit model names and minified bundles");
|
|
418
|
+
}
|
|
419
|
+
const resourceType = modelClass.getModelName();
|
|
420
|
+
const syncData = this.queuedSyncData(args);
|
|
421
|
+
const syncType = args.syncType || "update";
|
|
422
|
+
if (!resourceRecordId)
|
|
423
|
+
throw new Error("resource.id() is required to queue sync data");
|
|
424
|
+
const resourceId = String(resourceRecordId);
|
|
425
|
+
const existingSync = await args.syncModel.findBy({ resourceId, resourceType });
|
|
426
|
+
if (existingSync) {
|
|
427
|
+
await existingSync.update({
|
|
428
|
+
data: syncData,
|
|
429
|
+
state: "pending",
|
|
430
|
+
syncType
|
|
431
|
+
});
|
|
432
|
+
return existingSync;
|
|
433
|
+
}
|
|
434
|
+
return await args.syncModel.create({
|
|
435
|
+
data: syncData,
|
|
436
|
+
resourceId,
|
|
437
|
+
resourceType,
|
|
438
|
+
state: "pending",
|
|
439
|
+
syncType
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Builds backend-safe queued sync data without mutating caller data.
|
|
444
|
+
* @param {{resource: ?, data?: Record<string, unknown>, localOnlyAttributes?: string[], booleanAttributes?: string[], normalizeData?: (data: Record<string, unknown>) => Record<string, unknown>}} args - Data args.
|
|
445
|
+
* @returns {Record<string, unknown>} Queued data.
|
|
446
|
+
*/
|
|
447
|
+
static queuedSyncData(args) {
|
|
448
|
+
const inputData = args.data ?? /** @type {Record<string, unknown>} */ (args.resource.attributes());
|
|
449
|
+
const normalizedData = args.normalizeData ? args.normalizeData(inputData) : inputData;
|
|
450
|
+
const syncData = { ...normalizedData };
|
|
451
|
+
for (const attributeName of args.localOnlyAttributes || [])
|
|
452
|
+
delete syncData[attributeName];
|
|
453
|
+
for (const attributeName of args.booleanAttributes || []) {
|
|
454
|
+
if (Object.hasOwn(syncData, attributeName))
|
|
455
|
+
syncData[attributeName] = this.optionalBooleanSyncValue(syncData[attributeName], attributeName);
|
|
456
|
+
}
|
|
457
|
+
return syncData;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Builds a small app-facing local sync queue facade from declarative model config.
|
|
461
|
+
* @param {object} args - Queue config.
|
|
462
|
+
* @param {?} args.syncModel - Local Sync model class.
|
|
463
|
+
* @param {string} args.singleFlightKey - Key used to serialize backend replay.
|
|
464
|
+
* @param {() => Promise<void>} args.syncPending - Backend replay callback.
|
|
465
|
+
* @param {(resource: ?) => string[]} [args.localOnlyAttributes] - Resource-specific local-only attributes.
|
|
466
|
+
* @param {(resource: ?) => string[]} [args.booleanAttributes] - Resource-specific SQLite boolean attributes.
|
|
467
|
+
* @returns {{queue: (queueArgs: {resource: ?, data?: Record<string, unknown>, syncType?: string}) => Promise<?>, syncPending: () => Promise<void>}} Configured local sync queue.
|
|
468
|
+
*/
|
|
469
|
+
static localSyncQueue(args) {
|
|
470
|
+
return {
|
|
471
|
+
queue: async (queueArgs) => await this.queueLocalSync({
|
|
472
|
+
...queueArgs,
|
|
473
|
+
booleanAttributes: args.booleanAttributes ? args.booleanAttributes(queueArgs.resource) : [],
|
|
474
|
+
localOnlyAttributes: args.localOnlyAttributes ? args.localOnlyAttributes(queueArgs.resource) : [],
|
|
475
|
+
syncModel: args.syncModel
|
|
476
|
+
}),
|
|
477
|
+
syncPending: async () => await this.singleFlight(args.singleFlightKey, args.syncPending)
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Parses booleans commonly used by SQLite/offline sync payloads.
|
|
482
|
+
* @param {unknown} value - Sync decision value.
|
|
483
|
+
* @param {string} [description] - Error context.
|
|
484
|
+
* @returns {boolean | null} Parsed boolean-like backend/local value.
|
|
485
|
+
*/
|
|
486
|
+
static optionalBooleanSyncValue(value, description = "sync boolean") {
|
|
487
|
+
if (value == null)
|
|
488
|
+
return null;
|
|
489
|
+
if (value === 1)
|
|
490
|
+
return true;
|
|
491
|
+
if (value === 0)
|
|
492
|
+
return false;
|
|
493
|
+
return optionalBoolean(value, description);
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Converts a boolean sync value to SQLite boolean storage.
|
|
497
|
+
* @param {boolean | null} value - Sync boolean value.
|
|
498
|
+
* @returns {0 | 1} SQLite-compatible boolean value.
|
|
499
|
+
*/
|
|
500
|
+
static sqliteBooleanSyncValue(value) {
|
|
501
|
+
return value === true ? 1 : 0;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Projects generic sync counters into app-specific result keys.
|
|
505
|
+
* @param {object} args - Result args.
|
|
506
|
+
* @param {SyncChangesResult} args.result - Generic Velocious sync result.
|
|
507
|
+
* @param {Record<string, {changedKey: string, countKey: string}>} args.resources - Resource result key map.
|
|
508
|
+
* @returns {Record<string, unknown>} Projected result.
|
|
509
|
+
*/
|
|
510
|
+
static syncResultForResources({ result, resources }) {
|
|
511
|
+
const syncResult = /** @type {Record<string, unknown>} */ ({
|
|
512
|
+
changed: result.changed,
|
|
513
|
+
pages: result.pages,
|
|
514
|
+
syncedCount: result.syncedCount
|
|
515
|
+
});
|
|
516
|
+
for (const [resourceType, keys] of Object.entries(resources)) {
|
|
517
|
+
syncResult[keys.countKey] = result.resourceCounts[resourceType] || 0;
|
|
518
|
+
syncResult[keys.changedKey] = result.resourceChanged[resourceType] || false;
|
|
519
|
+
}
|
|
520
|
+
return syncResult;
|
|
521
|
+
}
|
|
230
522
|
/**
|
|
231
523
|
* Drains pending sync records in stable order and marks acknowledged rows.
|
|
232
524
|
* @param {object} args - Replay args.
|
|
@@ -304,4 +596,4 @@ export default class SyncApiClient {
|
|
|
304
596
|
return Math.floor(batchSize);
|
|
305
597
|
}
|
|
306
598
|
}
|
|
307
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1hcGktY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N5bmMvc3luYy1hcGktY2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sU0FBUyxDQUFBO0FBRXZDLGtHQUFrRztBQUNsRyw0RkFBNEY7QUFDNUYsNEZBQTRGO0FBQzVGLDhGQUE4RjtBQUM5RiwwRkFBMEY7QUFDMUYsNEVBQTRFO0FBQzVFLG9GQUFvRjtBQUNwRiw0RkFBNEY7QUFDNUYsNEZBQTRGO0FBRTVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLGFBQWE7SUFDaEM7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUk7UUFDM0IsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUE7UUFDckUsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFBO1FBQ3JCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQTtRQUNiLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQTtRQUNuQixJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUE7UUFDbkIsTUFBTSxjQUFjLEdBQUcscUNBQXFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUNqRSxNQUFNLGVBQWUsR0FBRyxzQ0FBc0MsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ25FLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7UUFFMUQsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFDLEdBQUcsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFD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blxuaW1wb3J0IHtvcHRpb25hbEludGVnZXJ9IGZyb20gXCJ0eXBhbmljXCJcblxuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ2hhbmdlQXBwbHlSZXN1bHR9IFN5bmNDaGFuZ2VBcHBseVJlc3VsdCAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ2hhbmdlRW52ZWxvcGV9IFN5bmNDaGFuZ2VFbnZlbG9wZSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ2hhbmdlc1JlcXVlc3R9IFN5bmNDaGFuZ2VzUmVxdWVzdCAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ2hhbmdlc1Jlc3BvbnNlfSBTeW5jQ2hhbmdlc1Jlc3BvbnNlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vc3luYy1hcGktY2xpZW50LXR5cGVzLmpzXCIpLlN5bmNDaGFuZ2VzUmVzdWx0fSBTeW5jQ2hhbmdlc1Jlc3VsdCAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ3Vyc29yfSBTeW5jQ3Vyc29yICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vc3luYy1hcGktY2xpZW50LXR5cGVzLmpzXCIpLlN5bmNSZXBsYXlJdGVtfSBTeW5jUmVwbGF5SXRlbSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jUmVwbGF5UmVzcG9uc2V9IFN5bmNSZXBsYXlSZXNwb25zZSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jUmVzb3VyY2VDb25maWd9IFN5bmNSZXNvdXJjZUNvbmZpZyAqL1xuXG4vKipcbiAqIEdlbmVyaWMgY2xpZW50LXNpZGUgaGVscGVyIGZvciByZXBsYXlpbmcgcGVuZGluZyBzeW5jIGVudmVsb3BlcyB0aHJvdWdoIHRoZVxuICogZnJhbWV3b3JrLW93bmVkIGAvdmVsb2Npb3VzL3N5bmMvcmVwbGF5YCBlbmRwb2ludC4gQXBwcyBwcm92aWRlIG9ubHkgbG9jYWxcbiAqIHBlcnNpc3RlbmNlL2F1dGggaG9va3MuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNBcGlDbGllbnQge1xuICAvKipcbiAgICogUHVsbHMgYmFja2VuZCBzeW5jIGNoYW5nZXMgaW4gc3RhYmxlIHBhZ2VzLCBhcHBsaWVzIHRoZW0gbG9jYWxseSwgYW5kIHN0b3Jlc1xuICAgKiB0aGUgYWNrbm93bGVkZ2VkIGN1cnNvci4gQXBwcyBwcm92aWRlIG9ubHkgYXV0aCwgcGVyc2lzdGVuY2UsIHRyYW5zcG9ydCwgYW5kXG4gICAqIHJlc291cmNlIHBvbGljeSBob29rcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBQdWxsIGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW4gLSBBdXRoIHRva2VuIHRvIHNlbmQgd2l0aCBjaGFuZ2UgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy5iYXRjaFNpemVdIC0gTWF4IHN5bmNzIHBlciByZXF1ZXN0LiBEZWZhdWx0cyB0byAxMDAuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTxTeW5jQ3Vyc29yIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZD59IGFyZ3MubG9hZEN1cnNvciAtIExvYWRzIHRoZSBwZXJzaXN0ZWQgbG9jYWwgY3Vyc29yLlxuICAgKiBAcGFyYW0geyhjdXJzb3I6IFN5bmNDdXJzb3IpID0+IFByb21pc2U8dm9pZD59IGFyZ3Muc2F2ZUN1cnNvciAtIFBlcnNpc3RzIHRoZSBmaW5hbCBhY2tub3dsZWRnZWQgY3Vyc29yLlxuICAgKiBAcGFyYW0geyhwYXlsb2FkOiBTeW5jQ2hhbmdlc1JlcXVlc3QpID0+IFByb21pc2U8U3luY0NoYW5nZXNSZXNwb25zZT59IGFyZ3MucG9zdENoYW5nZXMgLSBQb3N0cyBvbmUgY2hhbmdlcyByZXF1ZXN0LlxuICAgKiBAcGFyYW0geyhzeW5jOiBTeW5jQ2hhbmdlRW52ZWxvcGUpID0+IFByb21pc2U8U3luY0NoYW5nZUFwcGx5UmVzdWx0Pn0gYXJncy5hcHBseVN5bmMgLSBBcHBsaWVzIG9uZSBub3JtYWxpemVkIHN5bmMgcm93IGxvY2FsbHkuXG4gICAqIEBwYXJhbSB7KHByb2dyZXNzOiB7cGFnZXM6IG51bWJlciwgc3luY2VkQ291bnQ6IG51bWJlcn0pID0+IHZvaWR9IFthcmdzLm9uUHJvZ3Jlc3NdIC0gUHJvZ3Jlc3MgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNDaGFuZ2VzUmVzdWx0Pn0gUHVsbCByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcHVsbENoYW5nZXMoYXJncykge1xuICAgIGxldCBhZnRlckN1cnNvciA9IHRoaXMuc3luY0N1cnNvckZyb21QYXlsb2FkKGF3YWl0IGFyZ3MubG9hZEN1cnNvcigpKVxuICAgIGxldCB1cFRvQ3Vyc29yID0gbnVsbFxuICAgIGxldCBwYWdlcyA9IDBcbiAgICBsZXQgc3luY2VkQ291bnQgPSAwXG4gICAgbGV0IGNoYW5nZWQgPSBmYWxzZVxuICAgIGNvbnN0IHJlc291cmNlQ291bnRzID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXI+fSAqLyAoe30pXG4gICAgY29uc3QgcmVzb3VyY2VDaGFuZ2VkID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBib29sZWFuPn0gKi8gKHt9KVxuICAgIGNvbnN0IGJhdGNoU2l6ZSA9IHRoaXMubm9ybWFsaXplZEJhdGNoU2l6ZShhcmdzLmJhdGNoU2l6ZSlcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCBjaGFuZ2VzUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNoYW5nZXNQYWdlKHsuLi5hcmdzLCBhZnRlckN1cnNvciwgYmF0Y2hTaXplLCB1cFRvQ3Vyc29yfSlcbiAgICAgIGNvbnN0IHN5bmNzID0gY2hhbmdlc1Jlc3BvbnNlLnN5bmNzXG5cbiAgICAgIGlmICghdXBUb0N1cnNvcikgdXBUb0N1cnNvciA9IGNoYW5nZXNSZXNwb25zZS51cFRvQ3Vyc29yXG4gICAgICBpZiAoc3luY3MubGVuZ3RoID09PSAwKSBicmVha1xuXG4gICAgICBwYWdlcyArPSAxXG5cbiAgICAgIGZvciAoY29uc3Qgc3luYyBvZiBzeW5jcykge1xuICAgICAgICBjb25zdCBhcHBseVJlc3VsdCA9IGF3YWl0IGFyZ3MuYXBwbHlTeW5jKHN5bmMpXG4gICAgICAgIGNvbnN0IHJlc291cmNlVHlwZSA9IGFwcGx5UmVzdWx0LnJlc291cmNlVHlwZSA/PyBzeW5jLnJlc291cmNlVHlwZSgpXG5cbiAgICAgICAgY2hhbmdlZCB8fD0gYXBwbHlSZXN1bHQuY2hhbmdlZCA9PT0gdHJ1ZVxuICAgICAgICBzeW5jZWRDb3VudCArPSAxXG5cbiAgICAgICAgaWYgKHJlc291cmNlVHlwZSkge1xuICAgICAgICAgIHJlc291cmNlQ291bnRzW3Jlc291cmNlVHlwZV0gPSAocmVzb3VyY2VDb3VudHNbcmVzb3VyY2VUeXBlXSB8fCAwKSArIDFcbiAgICAgICAgICByZXNvdXJjZUNoYW5nZWRbcmVzb3VyY2VUeXBlXSB8fD0gYXBwbHlSZXN1bHQuY2hhbmdlZCA9PT0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGFmdGVyQ3Vyc29yID0gY2hhbmdlc1Jlc3BvbnNlLm5leHRDdXJzb3JcblxuICAgICAgaWYgKGFyZ3Mub25Qcm9ncmVzcykgYXJncy5vblByb2dyZXNzKHtwYWdlcywgc3luY2VkQ291bnR9KVxuICAgICAgaWYgKHN5bmNzLmxlbmd0aCA8IGJhdGNoU2l6ZSkgYnJlYWtcbiAgICB9XG5cbiAgICBpZiAoYWZ0ZXJDdXJzb3IpIGF3YWl0IGFyZ3Muc2F2ZUN1cnNvcihhZnRlckN1cnNvcilcblxuICAgIHJldHVybiB7Y2hhbmdlZCwgcGFnZXMsIHJlc291cmNlQ2hhbmdlZCwgcmVzb3VyY2VDb3VudHMsIHN5bmNlZENvdW50fVxuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgYW5kIHZhbGlkYXRlcyBvbmUgYmFja2VuZCBzeW5jIGNoYW5nZXMgcGFnZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBQYWdlIGFyZ3MuXG4gICAqIEBwYXJhbSB7U3luY0N1cnNvcn0gYXJncy5hZnRlckN1cnNvciAtIExhc3QgYWNrbm93bGVkZ2VkIGN1cnNvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXV0aGVudGljYXRpb25Ub2tlbiAtIEF1dGggdG9rZW4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmJhdGNoU2l6ZSAtIFBhZ2Ugc2l6ZS5cbiAgICogQHBhcmFtIHsocGF5bG9hZDogU3luY0NoYW5nZXNSZXF1ZXN0KSA9PiBQcm9taXNlPFN5bmNDaGFuZ2VzUmVzcG9uc2U+fSBhcmdzLnBvc3RDaGFuZ2VzIC0gQ2hhbmdlcyBwb3N0ZXIuXG4gICAqIEBwYXJhbSB7U3luY0N1cnNvcn0gYXJncy51cFRvQ3Vyc29yIC0gU25hcHNob3QgdXBwZXItYm91bmQgY3Vyc29yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7bmV4dEN1cnNvcjogU3luY0N1cnNvciwgc3luY3M6IFN5bmNDaGFuZ2VFbnZlbG9wZVtdLCB1cFRvQ3Vyc29yOiBTeW5jQ3Vyc29yfT59IE5vcm1hbGl6ZWQgY2hhbmdlcyBwYWdlLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGNoYW5nZXNQYWdlKHthZnRlckN1cnNvciwgYXV0aGVudGljYXRpb25Ub2tlbiwgYmF0Y2hTaXplLCBwb3N0Q2hhbmdlcywgdXBUb0N1cnNvcn0pIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHBvc3RDaGFuZ2VzKHtcbiAgICAgIGF1dGhlbnRpY2F0aW9uVG9rZW4sXG4gICAgICBsaW1pdDogYmF0Y2hTaXplLFxuICAgICAgLi4udGhpcy5jdXJzb3JQYXlsb2FkKFwiYWZ0ZXJcIiwgYWZ0ZXJDdXJzb3IpLFxuICAgICAgLi4udGhpcy5jdXJzb3JQYXlsb2FkKFwidXBUb1wiLCB1cFRvQ3Vyc29yKVxuICAgIH0pXG5cbiAgICB0aGlzLmVuc3VyZVN1Y2Nlc3NmdWxDaGFuZ2VzUmVzcG9uc2UocmVzcG9uc2UpXG5cbiAgICBjb25zdCBzeW5jcyA9IC8qKiBAdHlwZSB7dW5rbm93bltdfSAqLyAocmVzcG9uc2Uuc3luY3MpXG5cbiAgICByZXR1cm4ge1xuICAgICAgbmV4dEN1cnNvcjogdGhpcy5zeW5jQ3Vyc29yRnJvbVBheWxvYWQocmVzcG9uc2UubmV4dEN1cnNvciA/PyBudWxsKSxcbiAgICAgIHN5bmNzOiBzeW5jcy5tYXAoKHN5bmNQYXlsb2FkKSA9PiB0aGlzLnN5bmNFbnZlbG9wZUZyb21QYXlsb2FkKHN5bmNQYXlsb2FkKSksXG4gICAgICB1cFRvQ3Vyc29yOiB0aGlzLnN5bmNDdXJzb3JGcm9tUGF5bG9hZChyZXNwb25zZS51cFRvQ3Vyc29yID8/IG51bGwpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBBUEkgcmVzcG9uc2Ugc3RhdHVzIGFuZCBzaGFwZSBmb3IgY2hhbmdlLWZlZWQgcHVsbHMuXG4gICAqIEBwYXJhbSB7U3luY0NoYW5nZXNSZXNwb25zZX0gcmVzcG9uc2UgLSBDaGFuZ2VzIHJlc3BvbnNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHN0YXRpYyBlbnN1cmVTdWNjZXNzZnVsQ2hhbmdlc1Jlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gXCJlcnJvclwiKSB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2UuZXJyb3JNZXNzYWdlIHx8IFwiU3luYyBjaGFuZ2VzIGZhaWxlZFwiKVxuICAgIGlmICghQXJyYXkuaXNBcnJheShyZXNwb25zZS5zeW5jcykpIHRocm93IG5ldyBFcnJvcihcIlN5bmMgY2hhbmdlcyByZXNwb25zZSBtaXNzaW5nIHN5bmNzXCIpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBjdXJzb3IgaW50byByZXF1ZXN0IHBhcmFtcyB3aXRoIHRoZSBnaXZlbiBwcmVmaXguXG4gICAqIEBwYXJhbSB7XCJhZnRlclwiIHwgXCJ1cFRvXCJ9IHByZWZpeCAtIFJlcXVlc3QgZmllbGQgcHJlZml4LlxuICAgKiBAcGFyYW0ge1N5bmNDdXJzb3J9IGN1cnNvciAtIEN1cnNvciB0byBzZXJpYWxpemUuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBudWxsPn0gUmVxdWVzdCBwYXJhbXMuXG4gICAqL1xuICBzdGF0aWMgY3Vyc29yUGF5bG9hZChwcmVmaXgsIGN1cnNvcikge1xuICAgIGlmICghY3Vyc29yKSByZXR1cm4ge31cblxuICAgIHJldHVybiB7XG4gICAgICBbYCR7cHJlZml4fUlkYF06IGN1cnNvci5pZCxcbiAgICAgIC4uLihjdXJzb3Iuc2VydmVyU2VxdWVuY2UgPyB7W2Ake3ByZWZpeH1TZXJ2ZXJTZXF1ZW5jZWBdOiBjdXJzb3Iuc2VydmVyU2VxdWVuY2V9IDoge30pLFxuICAgICAgW2Ake3ByZWZpeH1VcGRhdGVkQXRgXTogY3Vyc29yLnVwZGF0ZWRBdFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgYSBwZXJzaXN0ZWQgb3IgcmVzcG9uc2UgY3Vyc29yIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7U3luY0N1cnNvciB8IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsID8+IHwgbnVsbCB8IHVuZGVmaW5lZH0gcGF5bG9hZCAtIEN1cnNvciBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7U3luY0N1cnNvcn0gUGFyc2VkIGN1cnNvci5cbiAgICovXG4gIHN0YXRpYyBzeW5jQ3Vyc29yRnJvbVBheWxvYWQocGF5bG9hZCkge1xuICAgIGlmICghcGF5bG9hZCkgcmV0dXJuIG51bGxcblxuICAgIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY0N1cnNvckZyb21QYXlsb2FkKEpTT04ucGFyc2UocGF5bG9hZCkpXG4gICAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHtpZDogbnVsbCwgc2VydmVyU2VxdWVuY2U6IG51bGwsIHVwZGF0ZWRBdDogcGF5bG9hZH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHBheWxvYWQgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShwYXlsb2FkKSkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHVwZGF0ZWRBdCA9IHR5cGVvZiBwYXlsb2FkLnVwZGF0ZWRBdCA9PT0gXCJzdHJpbmdcIiA/IHBheWxvYWQudXBkYXRlZEF0IDogbnVsbFxuXG4gICAgaWYgKCF1cGRhdGVkQXQpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHBheWxvYWQuaWQgPT09IG51bGwgfHwgcGF5bG9hZC5pZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IFN0cmluZyhwYXlsb2FkLmlkKSxcbiAgICAgIHNlcnZlclNlcXVlbmNlOiBvcHRpb25hbEludGVnZXIocGF5bG9hZC5zZXJ2ZXJTZXF1ZW5jZSA9PT0gXCJcIiA/IG51bGwgOiBwYXlsb2FkLnNlcnZlclNlcXVlbmNlKSxcbiAgICAgIHVwZGF0ZWRBdFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBub3JtYWxpemVkIHN5bmMgcm93IGFkYXB0ZXIuXG4gICAqIEBwYXJhbSB7P30gcGF5bG9hZCAtIFJhdyBzeW5jIHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtTeW5jQ2hhbmdlRW52ZWxvcGV9IFN5bmMgcm93IGFkYXB0ZXIuXG4gICAqL1xuICBzdGF0aWMgc3luY0VudmVsb3BlRnJvbVBheWxvYWQocGF5bG9hZCkge1xuICAgIGlmICghcGF5bG9hZCB8fCB0eXBlb2YgcGF5bG9hZCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHBheWxvYWQpKSB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jIGNoYW5nZXMgZW50cnkgbXVzdCBiZSBhbiBvYmplY3RcIilcblxuICAgIGNvbnN0IHN5bmNQYXlsb2FkID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHBheWxvYWQpXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogKCkgPT4gc3luY1BheWxvYWQuZGF0YSxcbiAgICAgIGlkOiAoKSA9PiBzeW5jUGF5bG9hZC5pZCxcbiAgICAgIHJlc291cmNlSWQ6ICgpID0+IHN5bmNQYXlsb2FkLnJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZVR5cGU6ICgpID0+IHN5bmNQYXlsb2FkLnJlc291cmNlVHlwZSA9PT0gbnVsbCB8fCBzeW5jUGF5bG9hZC5yZXNvdXJjZVR5cGUgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBTdHJpbmcoc3luY1BheWxvYWQucmVzb3VyY2VUeXBlKSxcbiAgICAgIHN5bmNUeXBlOiAoKSA9PiBzeW5jUGF5bG9hZC5zeW5jVHlwZSA9PT0gbnVsbCB8fCBzeW5jUGF5bG9hZC5zeW5jVHlwZSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IFN0cmluZyhzeW5jUGF5bG9hZC5zeW5jVHlwZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGFuIGFwcC1jb25maWd1cmVkIHJlc291cmNlIGFwcGxpZXIgZm9yIHB1bGxlZCBzeW5jIHJvd3MuIFRoZSBzeW5jXG4gICAqIG1lY2hhbmljcyBzdGF5IGhlcmU7IGFwcHMgb25seSBkZWNsYXJlIHdoaWNoIG1vZGVscy9hdHRyaWJ1dGVzL2hvb2tzIGFyZVxuICAgKiBhbGxvd2VkIGZvciBlYWNoIHJlc291cmNlIHR5cGUuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgU3luY1Jlc291cmNlQ29uZmlnPn0gcmVzb3VyY2VzIC0gUmVzb3VyY2UgcG9saWN5IG1hcC5cbiAgICogQHJldHVybnMgeyhzeW5jOiBTeW5jQ2hhbmdlRW52ZWxvcGUpID0+IFByb21pc2U8U3luY0NoYW5nZUFwcGx5UmVzdWx0Pn0gU3luYyBhcHBseSBjYWxsYmFjay5cbiAgICovXG4gIHN0YXRpYyByZXNvdXJjZUFwcGxpZXIocmVzb3VyY2VzKSB7XG4gICAgcmV0dXJuIGFzeW5jIChzeW5jKSA9PiBhd2FpdCB0aGlzLmFwcGx5UmVzb3VyY2VTeW5jKHtyZXNvdXJjZXMsIHN5bmN9KVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgb25lIHN5bmMgcm93IHVzaW5nIGRlY2xhcmF0aXZlIHJlc291cmNlIHBvbGljeS5cbiAgICogQHBhcmFtIHt7cmVzb3VyY2VzOiBSZWNvcmQ8c3RyaW5nLCBTeW5jUmVzb3VyY2VDb25maWc+LCBzeW5jOiBTeW5jQ2hhbmdlRW52ZWxvcGV9fSBhcmdzIC0gQXBwbHkgYXJncy5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY0NoYW5nZUFwcGx5UmVzdWx0Pn0gQXBwbHkgcmVzdWx0LlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGFwcGx5UmVzb3VyY2VTeW5jKHtyZXNvdXJjZXMsIHN5bmN9KSB7XG4gICAgY29uc3QgcmVzb3VyY2VUeXBlID0gc3luYy5yZXNvdXJjZVR5cGUoKVxuICAgIGNvbnN0IHJlc291cmNlID0gcmVzb3VyY2VUeXBlID8gcmVzb3VyY2VzW3Jlc291cmNlVHlwZV0gOiB1bmRlZmluZWRcblxuICAgIGlmICghcmVzb3VyY2UgfHwgIXJlc291cmNlLmVuYWJsZWQpIHJldHVybiB7Y2hhbmdlZDogZmFsc2UsIHJlc291cmNlVHlwZX1cblxuICAgIGlmIChzeW5jLnN5bmNUeXBlKCkgPT09IFwiZGVsZXRlXCIpIHtcbiAgICAgIHJldHVybiB7Y2hhbmdlZDogYXdhaXQgdGhpcy5kZXN0cm95U3luY2VkUmVzb3VyY2Uoe3Jlc291cmNlLCBzeW5jfSksIHJlc291cmNlVHlwZX1cbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gdGhpcy5zeW5jRGF0YShzeW5jKVxuICAgIGNvbnN0IHJlY29yZCA9IHJlc291cmNlLmZpbmRSZWNvcmQgPyBhd2FpdCByZXNvdXJjZS5maW5kUmVjb3JkKHtkYXRhLCByZXNvdXJjZUlkOiBzeW5jLnJlc291cmNlSWQoKSwgc3luY30pIDogYXdhaXQgcmVzb3VyY2UubW9kZWxDbGFzcy5maW5kT3JJbml0aWFsaXplQnkoe2lkOiBkYXRhLmlkID8/IHN5bmMucmVzb3VyY2VJZCgpfSlcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gYXdhaXQgcmVzb3VyY2UuYXR0cmlidXRlcyh7ZGF0YSwgcmVjb3JkLCBzeW5jfSlcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlXG5cbiAgICByZWNvcmQuYXNzaWduKGF0dHJpYnV0ZXMpXG5cbiAgICBpZiAocmVjb3JkLmlzQ2hhbmdlZCgpKSB7XG4gICAgICBhd2FpdCByZWNvcmQuc2F2ZSgpXG4gICAgICBjaGFuZ2VkID0gdHJ1ZVxuICAgIH1cblxuICAgIGlmIChyZXNvdXJjZS5hZnRlckFwcGx5KSB7XG4gICAgICBjb25zdCBob29rQ2hhbmdlZCA9IGF3YWl0IHJlc291cmNlLmFmdGVyQXBwbHkoe2F0dHJpYnV0ZXMsIGRhdGEsIHJlY29yZCwgc3luY30pXG5cbiAgICAgIGNoYW5nZWQgfHw9IGhvb2tDaGFuZ2VkID09PSB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIHtjaGFuZ2VkLCByZXNvdXJjZVR5cGV9XG4gIH1cblxuICAvKipcbiAgICogRGVzdHJveXMgYSBzeW5jZWQgcmVzb3VyY2UgdmlhIGl0cyBkZWNsYXJlZCBtb2RlbCBwb2xpY3kuXG4gICAqIEBwYXJhbSB7e3Jlc291cmNlOiBTeW5jUmVzb3VyY2VDb25maWcsIHN5bmM6IFN5bmNDaGFuZ2VFbnZlbG9wZX19IGFyZ3MgLSBEZXN0cm95IGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBXaGV0aGVyIGEgbG9jYWwgcm93IHdhcyBkZXN0cm95ZWQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgZGVzdHJveVN5bmNlZFJlc291cmNlKHtyZXNvdXJjZSwgc3luY30pIHtcbiAgICBjb25zdCBpZCA9IHN5bmMucmVzb3VyY2VJZCgpXG4gICAgY29uc3QgcmVjb3JkID0gcmVzb3VyY2UuZmluZFJlY29yZEZvckRlbGV0ZSA/IGF3YWl0IHJlc291cmNlLmZpbmRSZWNvcmRGb3JEZWxldGUoe3Jlc291cmNlSWQ6IGlkLCBzeW5jfSkgOiBhd2FpdCByZXNvdXJjZS5tb2RlbENsYXNzLmZpbmRCeSh7aWR9KVxuXG4gICAgaWYgKCFyZWNvcmQpIHJldHVybiBmYWxzZVxuXG4gICAgYXdhaXQgcmVjb3JkLmRlc3Ryb3koKVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSBlbWJlZGRlZCBzeW5jIGRhdGEgSlNPTi9vYmplY3QuXG4gICAqIEBwYXJhbSB7U3luY0NoYW5nZUVudmVsb3BlfSBzeW5jIC0gU3luYyByb3cuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gU3luYyBkYXRhIG9iamVjdC5cbiAgICovXG4gIHN0YXRpYyBzeW5jRGF0YShzeW5jKSB7XG4gICAgY29uc3QgZGF0YSA9IHN5bmMuZGF0YSgpXG5cbiAgICBpZiAoIWRhdGEpIHRocm93IG5ldyBFcnJvcihgU3luYyAke3N5bmMuaWQoKX0gaXMgbWlzc2luZyBkYXRhYClcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoSlNPTi5wYXJzZShkYXRhKSlcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkpIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoZGF0YSlcblxuICAgIHRocm93IG5ldyBFcnJvcihgU3luYyAke3N5bmMuaWQoKX0gaGFzIGludmFsaWQgZGF0YWApXG4gIH1cblxuICAvKipcbiAgICogRHJhaW5zIHBlbmRpbmcgc3luYyByZWNvcmRzIGluIHN0YWJsZSBvcmRlciBhbmQgbWFya3MgYWNrbm93bGVkZ2VkIHJvd3MuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUmVwbGF5IGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW4gLSBBdXRoIHRva2VuIHRvIHNlbmQgd2l0aCByZXBsYXkgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy5iYXRjaFNpemVdIC0gTWF4IHN5bmNzIHBlciByZXF1ZXN0LiBEZWZhdWx0cyB0byAxMDAuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTxBcnJheTx1bmtub3duPj59IGFyZ3MucGVuZGluZ1N5bmNzIC0gTG9hZHMgcGVuZGluZyBsb2NhbCBzeW5jIHJvd3MgaW4gcmVwbGF5IG9yZGVyLlxuICAgKiBAcGFyYW0geyhzeW5jOiB1bmtub3duKSA9PiBzdHJpbmcgfCBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkfSBhcmdzLnN5bmNJZCAtIFJldHVybnMgdGhlIGxvY2FsIHN5bmMgaWQuXG4gICAqIEBwYXJhbSB7KHN5bmM6IHVua25vd24pID0+IFJlY29yZDxzdHJpbmcsID8+fSBhcmdzLnN5bmNQYXlsb2FkIC0gQnVpbGRzIHRoZSBBUEkgc3luYyBlbnZlbG9wZS5cbiAgICogQHBhcmFtIHsocGF5bG9hZDoge2F1dGhlbnRpY2F0aW9uVG9rZW46IHN0cmluZywgc3luY3M6IEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pn0pID0+IFByb21pc2U8U3luY1JlcGxheVJlc3BvbnNlPn0gYXJncy5wb3N0UmVwbGF5IC0gUG9zdHMgb25lIHJlcGxheSByZXF1ZXN0LlxuICAgKiBAcGFyYW0geyhzeW5jOiB1bmtub3duLCByZXNwb25zZTogU3luY1JlcGxheUl0ZW0pID0+IFByb21pc2U8dm9pZD59IGFyZ3MubWFya1N1Y2Nlc3NmdWwgLSBNYXJrcyBvbmUgc3luYyBhcyBzdWNjZXNzZnVsIGxvY2FsbHkuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyBhZnRlciBhbGwgYmF0Y2hlcyBhcmUgcmVwbGF5ZWQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVwbGF5UGVuZGluZyhhcmdzKSB7XG4gICAgY29uc3QgcGVuZGluZ1N5bmNzID0gYXdhaXQgYXJncy5wZW5kaW5nU3luY3MoKVxuICAgIGNvbnN0IGJhdGNoU2l6ZSA9IHRoaXMubm9ybWFsaXplZEJhdGNoU2l6ZShhcmdzLmJhdGNoU2l6ZSlcblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IHBlbmRpbmdTeW5jcy5sZW5ndGg7IG9mZnNldCArPSBiYXRjaFNpemUpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVwbGF5QmF0Y2goey4uLmFyZ3MsIHBlbmRpbmdTeW5jczogcGVuZGluZ1N5bmNzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmF0Y2hTaXplKX0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxheXMgb25lIGJhdGNoIG9mIHN5bmNzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFJlcGxheSBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5hdXRoZW50aWNhdGlvblRva2VuIC0gQXV0aCB0b2tlbi5cbiAgICogQHBhcmFtIHtBcnJheTx1bmtub3duPn0gYXJncy5wZW5kaW5nU3luY3MgLSBCYXRjaCBzeW5jcy5cbiAgICogQHBhcmFtIHsoc3luYzogdW5rbm93bikgPT4gc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZH0gYXJncy5zeW5jSWQgLSBTeW5jIGlkIGdldHRlci5cbiAgICogQHBhcmFtIHsoc3luYzogdW5rbm93bikgPT4gUmVjb3JkPHN0cmluZywgPz59IGFyZ3Muc3luY1BheWxvYWQgLSBQYXlsb2FkIGJ1aWxkZXIuXG4gICAqIEBwYXJhbSB7KHBheWxvYWQ6IHthdXRoZW50aWNhdGlvblRva2VuOiBzdHJpbmcsIHN5bmNzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59KSA9PiBQcm9taXNlPFN5bmNSZXBsYXlSZXNwb25zZT59IGFyZ3MucG9zdFJlcGxheSAtIFJlcGxheSBwb3N0ZXIuXG4gICAqIEBwYXJhbSB7KHN5bmM6IHVua25vd24sIHJlc3BvbnNlOiBTeW5jUmVwbGF5SXRlbSkgPT4gUHJvbWlzZTx2b2lkPn0gYXJncy5tYXJrU3VjY2Vzc2Z1bCAtIFN1Y2Nlc3MgaG9vay5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIGFmdGVyIHRoZSBiYXRjaCBpcyBhY2tub3dsZWRnZWQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVwbGF5QmF0Y2goYXJncykge1xuICAgIGNvbnN0IHthdXRoZW50aWNhdGlvblRva2VuLCBtYXJrU3VjY2Vzc2Z1bCwgcGVuZGluZ1N5bmNzLCBwb3N0UmVwbGF5LCBzeW5jSWQsIHN5bmNQYXlsb2FkfSA9IGFyZ3NcblxuICAgIGlmIChwZW5kaW5nU3luY3MubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IHN5bmNzQnlJZCA9IG5ldyBNYXAoKVxuXG4gICAgZm9yIChjb25zdCBzeW5jIG9mIHBlbmRpbmdTeW5jcykge1xuICAgICAgY29uc3QgaWQgPSBzeW5jSWQoc3luYylcblxuICAgICAgaWYgKGlkICE9PSB1bmRlZmluZWQgJiYgaWQgIT09IG51bGwpIHN5bmNzQnlJZC5zZXQoU3RyaW5nKGlkKSwgc3luYylcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHBvc3RSZXBsYXkoe1xuICAgICAgYXV0aGVudGljYXRpb25Ub2tlbixcbiAgICAgIHN5bmNzOiBwZW5kaW5nU3luY3MubWFwKChzeW5jKSA9PiBzeW5jUGF5bG9hZChzeW5jKSlcbiAgICB9KVxuXG4gICAgdGhpcy5lbnN1cmVTdWNjZXNzZnVsUmVzcG9uc2UocmVzcG9uc2UpXG5cbiAgICBmb3IgKGNvbnN0IHN5bmNSZXNwb25zZSBvZiByZXNwb25zZS5zeW5jcyB8fCBbXSkge1xuICAgICAgY29uc3Qgc3luYyA9IHN5bmNzQnlJZC5nZXQoU3RyaW5nKHN5bmNSZXNwb25zZS5pZCkpXG5cbiAgICAgIGlmICghc3luYykgY29udGludWVcbiAgICAgIGlmIChzeW5jUmVzcG9uc2Uuc3luY1N0YXRlICE9PSBcInN1Y2Nlc3NmdWxcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc3luYyBzdGF0ZSByZXR1cm5lZCBmb3Igc3luYyAke1N0cmluZyhzeW5jUmVzcG9uc2UuaWQpfTogJHtTdHJpbmcoc3luY1Jlc3BvbnNlLnN5bmNTdGF0ZSl9YClcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbWFya1N1Y2Nlc3NmdWwoc3luYywgc3luY1Jlc3BvbnNlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgQVBJIHJlc3BvbnNlIHN0YXR1cyBhbmQgc2hhcGUuXG4gICAqIEBwYXJhbSB7U3luY1JlcGxheVJlc3BvbnNlfSByZXNwb25zZSAtIFJlcGxheSByZXNwb25zZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgZW5zdXJlU3VjY2Vzc2Z1bFJlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gXCJlcnJvclwiKSB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2UuZXJyb3JNZXNzYWdlIHx8IFwiU3luYyBmYWlsZWRcIilcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVzcG9uc2Uuc3luY3MpKSB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jIHJlc3BvbnNlIG1pc3Npbmcgc3luY3NcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIGEgcG9zaXRpdmUgYmF0Y2ggc2l6ZS5cbiAgICogQHBhcmFtIHtudW1iZXIgfCB1bmRlZmluZWR9IGJhdGNoU2l6ZSAtIEJhdGNoIHNpemUuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFBvc2l0aXZlIGJhdGNoIHNpemUuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplZEJhdGNoU2l6ZShiYXRjaFNpemUpIHtcbiAgICBpZiAodHlwZW9mIGJhdGNoU2l6ZSAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzRmluaXRlKGJhdGNoU2l6ZSkgfHwgYmF0Y2hTaXplIDwgMSkgcmV0dXJuIDEwMFxuXG4gICAgcmV0dXJuIE1hdGguZmxvb3IoYmF0Y2hTaXplKVxuICB9XG59XG4iXX0=
|
|
599
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1hcGktY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N5bmMvc3luYy1hcGktY2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsZUFBZSxFQUFFLGVBQWUsRUFBQyxNQUFNLFNBQVMsQ0FBQTtBQUV4RCxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7QUFFbEMsa0dBQWtHO0FBQ2xHLDRGQUE0RjtBQUM1Riw0RkFBNEY7QUFDNUYsOEZBQThGO0FBQzlGLDBGQUEwRjtBQUMxRiw0RUFBNEU7QUFDNUUsb0ZBQW9GO0FBQ3BGLDRGQUE0RjtBQUM1Riw0RkFBNEY7QUFFNUY7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sYUFBYTtJQUNoQzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxRQUFRO1FBQ3JDLE9BQU8sZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDO2dCQUNILE1BQU0sZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2pDLENBQUM7WUFBQyxPQUFPLE1BQU0sRUFBRSxDQUFDO2dCQUNoQix5RUFBeUU7Z0JBQ3pFLGtGQUFrRjtZQUNwRixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLFFBQVEsRUFBRSxDQUFBO1FBQzFCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFFbEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLENBQUE7UUFDZixDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxPQUFPO2dCQUFFLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FB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SUFFRDs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLHdCQUF3QixDQUFDLFFBQVE7UUFDdEMsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLElBQUksYUFBYSxDQUFDLENBQUE7UUFDeEYsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtJQUNwRixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTO1FBQ2xDLElBQUksT0FBTyxTQUFTLEtBQUssUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLEdBQUcsQ0FBQztZQUFFLE9BQU8sR0FBRyxDQUFBO1FBRTdGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUM5QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtvcHRpb25hbEJvb2xlYW4sIG9wdGlvbmFsSW50ZWdlcn0gZnJvbSBcInR5cGFuaWNcIlxuXG5jb25zdCBzeW5jVGFza1Byb21pc2VzID0gbmV3IE1hcCgpXG5cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0NoYW5nZUFwcGx5UmVzdWx0fSBTeW5jQ2hhbmdlQXBwbHlSZXN1bHQgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0NoYW5nZUVudmVsb3BlfSBTeW5jQ2hhbmdlRW52ZWxvcGUgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0NoYW5nZXNSZXF1ZXN0fSBTeW5jQ2hhbmdlc1JlcXVlc3QgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0NoYW5nZXNSZXNwb25zZX0gU3luY0NoYW5nZXNSZXNwb25zZSAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jQ2hhbmdlc1Jlc3VsdH0gU3luY0NoYW5nZXNSZXN1bHQgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0N1cnNvcn0gU3luY0N1cnNvciAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3N5bmMtYXBpLWNsaWVudC10eXBlcy5qc1wiKS5TeW5jUmVwbGF5SXRlbX0gU3luY1JlcGxheUl0ZW0gKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY1JlcGxheVJlc3BvbnNlfSBTeW5jUmVwbGF5UmVzcG9uc2UgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY1Jlc291cmNlQ29uZmlnfSBTeW5jUmVzb3VyY2VDb25maWcgKi9cblxuLyoqXG4gKiBHZW5lcmljIGNsaWVudC1zaWRlIGhlbHBlciBmb3IgcmVwbGF5aW5nIHBlbmRpbmcgc3luYyBlbnZlbG9wZXMgdGhyb3VnaCB0aGVcbiAqIGZyYW1ld29yay1vd25lZCBgL3ZlbG9jaW91cy9zeW5jL3JlcGxheWAgZW5kcG9pbnQuIEFwcHMgcHJvdmlkZSBvbmx5IGxvY2FsXG4gKiBwZXJzaXN0ZW5jZS9hdXRoIGhvb2tzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTeW5jQXBpQ2xpZW50IHtcbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgc3luYyB3b3JrIHdpdGggdGhlIHNhbWUga2V5IHNvIGNhbGxlcnMgZG8gbm90IGhhdmUgdG8ga2VlcCBhcHAtbG9jYWwgbG9ja3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBMb2NrIGtleS5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIFdvcmsgdG8gcnVuIG9uY2UgcHJldmlvdXMgd29yayBmaW5pc2hlZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBzdGF0aWMgYXN5bmMgc2luZ2xlRmxpZ2h0KGtleSwgY2FsbGJhY2spIHtcbiAgICB3aGlsZSAoc3luY1Rhc2tQcm9taXNlcy5oYXMoa2V5KSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3luY1Rhc2tQcm9taXNlcy5nZXQoa2V5KVxuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIC8vIFRoZSBmYWlsZWQgZmxpZ2h0J3Mgb3duIGNhbGxlciBvYnNlcnZlcyB0aGF0IHJlamVjdGlvbjsgY2FsbGVycyBxdWV1ZWRcbiAgICAgICAgLy8gYmVoaW5kIGl0IHN0aWxsIHJ1biB0aGVpciBvd24gd29yayBzbyBwZW5kaW5nIHJvd3MgcmV0cnkgYWZ0ZXIgdGhlIGxvY2sgY2xlYXJzLlxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHByb21pc2UgPSBjYWxsYmFjaygpXG4gICAgc3luY1Rhc2tQcm9taXNlcy5zZXQoa2V5LCBwcm9taXNlKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHN5bmNUYXNrUHJvbWlzZXMuZ2V0KGtleSkgPT09IHByb21pc2UpIHN5bmNUYXNrUHJvbWlzZXMuZGVsZXRlKGtleSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVsbHMgYmFja2VuZCBzeW5jIGNoYW5nZXMgd2l0aCBhIGZyYW1ld29yay1tYW5hZ2VkIGN1cnNvciByb3cuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUHVsbCBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5hdXRoZW50aWNhdGlvblRva2VuIC0gQXV0aCB0b2tlbiB0byBzZW5kIHdpdGggY2hhbmdlIHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuYmF0Y2hTaXplXSAtIE1heCBzeW5jcyBwZXIgcmVxdWVzdC5cbiAgICogQHBhcmFtIHs/fSBhcmdzLmN1cnNvck1vZGVsIC0gTW9kZWwgdGhhdCByZXNwb25kcyB0byBmaW5kQnkvZmluZE9ySW5pdGlhbGl6ZUJ5IGZvciBjdXJzb3IgcGVyc2lzdGVuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmN1cnNvcktleSAtIEN1cnNvciBvcHRpb24ga2V5LlxuICAgKiBAcGFyYW0geyhwYXlsb2FkOiBTeW5jQ2hhbmdlc1JlcXVlc3QpID0+IFByb21pc2U8U3luY0NoYW5nZXNSZXNwb25zZT59IGFyZ3MucG9zdENoYW5nZXMgLSBQb3N0cyBvbmUgY2hhbmdlcyByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFN5bmNSZXNvdXJjZUNvbmZpZz59IGFyZ3MucmVzb3VyY2VzIC0gUmVzb3VyY2UgcG9saWNpZXMuXG4gICAqIEBwYXJhbSB7KHByb2dyZXNzOiB7cGFnZXM6IG51bWJlciwgc3luY2VkQ291bnQ6IG51bWJlcn0pID0+IHZvaWR9IFthcmdzLm9uUHJvZ3Jlc3NdIC0gUHJvZ3Jlc3MgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNDaGFuZ2VzUmVzdWx0Pn0gUHVsbCByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcHVsbENoYW5nZXNXaXRoQ3Vyc29yKGFyZ3MpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wdWxsQ2hhbmdlcyh7XG4gICAgICBhdXRoZW50aWNhdGlvblRva2VuOiBhcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW4sXG4gICAgICBiYXRjaFNpemU6IGFyZ3MuYmF0Y2hTaXplLFxuICAgICAgbG9hZEN1cnNvcjogYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5sb2FkU3luY0N1cnNvcih7Y3Vyc29yS2V5OiBhcmdzLmN1cnNvcktleSwgY3Vyc29yTW9kZWw6IGFyZ3MuY3Vyc29yTW9kZWx9KSxcbiAgICAgIHNhdmVDdXJzb3I6IGFzeW5jIChjdXJzb3IpID0+IGF3YWl0IHRoaXMuc2F2ZVN5bmNDdXJzb3Ioe2N1cnNvciwgY3Vyc29yS2V5OiBhcmdzLmN1cnNvcktleSwgY3Vyc29yTW9kZWw6IGFyZ3MuY3Vyc29yTW9kZWx9KSxcbiAgICAgIHBvc3RDaGFuZ2VzOiBhcmdzLnBvc3RDaGFuZ2VzLFxuICAgICAgYXBwbHlTeW5jOiB0aGlzLnJlc291cmNlQXBwbGllcihhcmdzLnJlc291cmNlcyksXG4gICAgICBvblByb2dyZXNzOiBhcmdzLm9uUHJvZ3Jlc3NcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIGEgcGVyc2lzdGVkIHN5bmMgY3Vyc29yIGZyb20gYSBtb2RlbCByb3cgd2l0aCBhIHZhbHVlIGNvbHVtbi5cbiAgICogQHBhcmFtIHt7Y3Vyc29yS2V5OiBzdHJpbmcsIGN1cnNvck1vZGVsOiA/fX0gYXJncyAtIEN1cnNvciBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBudWxsPn0gUGVyc2lzdGVkIGN1cnNvciBwYXlsb2FkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGxvYWRTeW5jQ3Vyc29yKHtjdXJzb3JLZXksIGN1cnNvck1vZGVsfSkge1xuICAgIGNvbnN0IG9wdGlvbiA9IGF3YWl0IGN1cnNvck1vZGVsLmZpbmRCeSh7a2V5OiBjdXJzb3JLZXl9KVxuXG4gICAgcmV0dXJuIG9wdGlvbiA/IG9wdGlvbi52YWx1ZSgpIDogbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgcGVyc2lzdGVkIHN5bmMgY3Vyc29yIHRvIGEgbW9kZWwgcm93IHdpdGggYSB2YWx1ZSBjb2x1bW4uXG4gICAqIEBwYXJhbSB7e2N1cnNvcjogU3luY0N1cnNvciwgY3Vyc29yS2V5OiBzdHJpbmcsIGN1cnNvck1vZGVsOiA/fX0gYXJncyAtIEN1cnNvciBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIHN0YXRpYyBhc3luYyBzYXZlU3luY0N1cnNvcih7Y3Vyc29yLCBjdXJzb3JLZXksIGN1cnNvck1vZGVsfSkge1xuICAgIGlmICghY3Vyc29yKSByZXR1cm5cblxuICAgIGNvbnN0IG9wdGlvbiA9IGF3YWl0IGN1cnNvck1vZGVsLmZpbmRPckluaXRpYWxpemVCeSh7a2V5OiBjdXJzb3JLZXl9KVxuXG4gICAgb3B0aW9uLmFzc2lnbih7dmFsdWU6IEpTT04uc3RyaW5naWZ5KGN1cnNvcil9KVxuICAgIGlmIChvcHRpb24uaXNDaGFuZ2VkKCkpIGF3YWl0IG9wdGlvbi5zYXZlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxscyBiYWNrZW5kIHN5bmMgY2hhbmdlcyBpbiBzdGFibGUgcGFnZXMsIGFwcGxpZXMgdGhlbSBsb2NhbGx5LCBhbmQgc3RvcmVzXG4gICAqIHRoZSBhY2tub3dsZWRnZWQgY3Vyc29yLiBBcHBzIHByb3ZpZGUgb25seSBhdXRoLCBwZXJzaXN0ZW5jZSwgdHJhbnNwb3J0LCBhbmRcbiAgICogcmVzb3VyY2UgcG9saWN5IGhvb2tzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFB1bGwgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXV0aGVudGljYXRpb25Ub2tlbiAtIEF1dGggdG9rZW4gdG8gc2VuZCB3aXRoIGNoYW5nZSByZXF1ZXN0cy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFthcmdzLmJhdGNoU2l6ZV0gLSBNYXggc3luY3MgcGVyIHJlcXVlc3QuIERlZmF1bHRzIHRvIDEwMC5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPFN5bmNDdXJzb3IgfCBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkPn0gYXJncy5sb2FkQ3Vyc29yIC0gTG9hZHMgdGhlIHBlcnNpc3RlZCBsb2NhbCBjdXJzb3IuXG4gICAqIEBwYXJhbSB7KGN1cnNvcjogU3luY0N1cnNvcikgPT4gUHJvbWlzZTx2b2lkPn0gYXJncy5zYXZlQ3Vyc29yIC0gUGVyc2lzdHMgdGhlIGZpbmFsIGFja25vd2xlZGdlZCBjdXJzb3IuXG4gICAqIEBwYXJhbSB7KHBheWxvYWQ6IFN5bmNDaGFuZ2VzUmVxdWVzdCkgPT4gUHJvbWlzZTxTeW5jQ2hhbmdlc1Jlc3BvbnNlPn0gYXJncy5wb3N0Q2hhbmdlcyAtIFBvc3RzIG9uZSBjaGFuZ2VzIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7KHN5bmM6IFN5bmNDaGFuZ2VFbnZlbG9wZSkgPT4gUHJvbWlzZTxTeW5jQ2hhbmdlQXBwbHlSZXN1bHQ+fSBhcmdzLmFwcGx5U3luYyAtIEFwcGxpZXMgb25lIG5vcm1hbGl6ZWQgc3luYyByb3cgbG9jYWxseS5cbiAgICogQHBhcmFtIHsocHJvZ3Jlc3M6IHtwYWdlczogbnVtYmVyLCBzeW5jZWRDb3VudDogbnVtYmVyfSkgPT4gdm9pZH0gW2FyZ3Mub25Qcm9ncmVzc10gLSBQcm9ncmVzcyBjYWxsYmFjay5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY0NoYW5nZXNSZXN1bHQ+fSBQdWxsIHJlc3VsdC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBwdWxsQ2hhbmdlcyhhcmdzKSB7XG4gICAgbGV0IGFmdGVyQ3Vyc29yID0gdGhpcy5zeW5jQ3Vyc29yRnJvbVBheWxvYWQoYXdhaXQgYXJncy5sb2FkQ3Vyc29yKCkpXG4gICAgbGV0IHVwVG9DdXJzb3IgPSBudWxsXG4gICAgbGV0IHBhZ2VzID0gMFxuICAgIGxldCBzeW5jZWRDb3VudCA9IDBcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlXG4gICAgY29uc3QgcmVzb3VyY2VDb3VudHMgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59ICovICh7fSlcbiAgICBjb25zdCByZXNvdXJjZUNoYW5nZWQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGJvb2xlYW4+fSAqLyAoe30pXG4gICAgY29uc3QgYmF0Y2hTaXplID0gdGhpcy5ub3JtYWxpemVkQmF0Y2hTaXplKGFyZ3MuYmF0Y2hTaXplKVxuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IGNoYW5nZXNSZXNwb25zZSA9IGF3YWl0IHRoaXMuY2hhbmdlc1BhZ2Uoey4uLmFyZ3MsIGFmdGVyQ3Vyc29yLCBiYXRjaFNpemUsIHVwVG9DdXJzb3J9KVxuICAgICAgY29uc3Qgc3luY3MgPSBjaGFuZ2VzUmVzcG9uc2Uuc3luY3NcblxuICAgICAgaWYgKCF1cFRvQ3Vyc29yKSB1cFRvQ3Vyc29yID0gY2hhbmdlc1Jlc3BvbnNlLnVwVG9DdXJzb3JcbiAgICAgIGlmIChzeW5jcy5sZW5ndGggPT09IDApIGJyZWFrXG5cbiAgICAgIHBhZ2VzICs9IDFcblxuICAgICAgZm9yIChjb25zdCBzeW5jIG9mIHN5bmNzKSB7XG4gICAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gYXdhaXQgYXJncy5hcHBseVN5bmMoc3luYylcbiAgICAgICAgY29uc3QgcmVzb3VyY2VUeXBlID0gYXBwbHlSZXN1bHQucmVzb3VyY2VUeXBlID8/IHN5bmMucmVzb3VyY2VUeXBlKClcblxuICAgICAgICBjaGFuZ2VkIHx8PSBhcHBseVJlc3VsdC5jaGFuZ2VkID09PSB0cnVlXG4gICAgICAgIHN5bmNlZENvdW50ICs9IDFcblxuICAgICAgICBpZiAocmVzb3VyY2VUeXBlKSB7XG4gICAgICAgICAgcmVzb3VyY2VDb3VudHNbcmVzb3VyY2VUeXBlXSA9IChyZXNvdXJjZUNvdW50c1tyZXNvdXJjZVR5cGVdIHx8IDApICsgMVxuICAgICAgICAgIHJlc291cmNlQ2hhbmdlZFtyZXNvdXJjZVR5cGVdIHx8PSBhcHBseVJlc3VsdC5jaGFuZ2VkID09PSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYWZ0ZXJDdXJzb3IgPSBjaGFuZ2VzUmVzcG9uc2UubmV4dEN1cnNvclxuXG4gICAgICBpZiAoYXJncy5vblByb2dyZXNzKSBhcmdzLm9uUHJvZ3Jlc3Moe3BhZ2VzLCBzeW5jZWRDb3VudH0pXG4gICAgICBpZiAoc3luY3MubGVuZ3RoIDwgYmF0Y2hTaXplKSBicmVha1xuICAgIH1cblxuICAgIGlmIChhZnRlckN1cnNvcikgYXdhaXQgYXJncy5zYXZlQ3Vyc29yKGFmdGVyQ3Vyc29yKVxuXG4gICAgcmV0dXJuIHtjaGFuZ2VkLCBwYWdlcywgcmVzb3VyY2VDaGFuZ2VkLCByZXNvdXJjZUNvdW50cywgc3luY2VkQ291bnR9XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2hlcyBhbmQgdmFsaWRhdGVzIG9uZSBiYWNrZW5kIHN5bmMgY2hhbmdlcyBwYWdlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFBhZ2UgYXJncy5cbiAgICogQHBhcmFtIHtTeW5jQ3Vyc29yfSBhcmdzLmFmdGVyQ3Vyc29yIC0gTGFzdCBhY2tub3dsZWRnZWQgY3Vyc29yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5hdXRoZW50aWNhdGlvblRva2VuIC0gQXV0aCB0b2tlbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuYmF0Y2hTaXplIC0gUGFnZSBzaXplLlxuICAgKiBAcGFyYW0geyhwYXlsb2FkOiBTeW5jQ2hhbmdlc1JlcXVlc3QpID0+IFByb21pc2U8U3luY0NoYW5nZXNSZXNwb25zZT59IGFyZ3MucG9zdENoYW5nZXMgLSBDaGFuZ2VzIHBvc3Rlci5cbiAgICogQHBhcmFtIHtTeW5jQ3Vyc29yfSBhcmdzLnVwVG9DdXJzb3IgLSBTbmFwc2hvdCB1cHBlci1ib3VuZCBjdXJzb3IuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHtuZXh0Q3Vyc29yOiBTeW5jQ3Vyc29yLCBzeW5jczogU3luY0NoYW5nZUVudmVsb3BlW10sIHVwVG9DdXJzb3I6IFN5bmNDdXJzb3J9Pn0gTm9ybWFsaXplZCBjaGFuZ2VzIHBhZ2UuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgY2hhbmdlc1BhZ2Uoe2FmdGVyQ3Vyc29yLCBhdXRoZW50aWNhdGlvblRva2VuLCBiYXRjaFNpemUsIHBvc3RDaGFuZ2VzLCB1cFRvQ3Vyc29yfSkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcG9zdENoYW5nZXMoe1xuICAgICAgYXV0aGVudGljYXRpb25Ub2tlbixcbiAgICAgIGxpbWl0OiBiYXRjaFNpemUsXG4gICAgICAuLi50aGlzLmN1cnNvclBheWxvYWQoXCJhZnRlclwiLCBhZnRlckN1cnNvciksXG4gICAgICAuLi50aGlzLmN1cnNvclBheWxvYWQoXCJ1cFRvXCIsIHVwVG9DdXJzb3IpXG4gICAgfSlcblxuICAgIHRoaXMuZW5zdXJlU3VjY2Vzc2Z1bENoYW5nZXNSZXNwb25zZShyZXNwb25zZSlcblxuICAgIGNvbnN0IHN5bmNzID0gLyoqIEB0eXBlIHt1bmtub3duW119ICovIChyZXNwb25zZS5zeW5jcylcblxuICAgIHJldHVybiB7XG4gICAgICBuZXh0Q3Vyc29yOiB0aGlzLnN5bmNDdXJzb3JGcm9tUGF5bG9hZChyZXNwb25zZS5uZXh0Q3Vyc29yID8/IG51bGwpLFxuICAgICAgc3luY3M6IHN5bmNzLm1hcCgoc3luY1BheWxvYWQpID0+IHRoaXMuc3luY0VudmVsb3BlRnJvbVBheWxvYWQoc3luY1BheWxvYWQpKSxcbiAgICAgIHVwVG9DdXJzb3I6IHRoaXMuc3luY0N1cnNvckZyb21QYXlsb2FkKHJlc3BvbnNlLnVwVG9DdXJzb3IgPz8gbnVsbClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIEFQSSByZXNwb25zZSBzdGF0dXMgYW5kIHNoYXBlIGZvciBjaGFuZ2UtZmVlZCBwdWxscy5cbiAgICogQHBhcmFtIHtTeW5jQ2hhbmdlc1Jlc3BvbnNlfSByZXNwb25zZSAtIENoYW5nZXMgcmVzcG9uc2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIGVuc3VyZVN1Y2Nlc3NmdWxDaGFuZ2VzUmVzcG9uc2UocmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSBcImVycm9yXCIpIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5lcnJvck1lc3NhZ2UgfHwgXCJTeW5jIGNoYW5nZXMgZmFpbGVkXCIpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJlc3BvbnNlLnN5bmNzKSkgdGhyb3cgbmV3IEVycm9yKFwiU3luYyBjaGFuZ2VzIHJlc3BvbnNlIG1pc3Npbmcgc3luY3NcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGN1cnNvciBpbnRvIHJlcXVlc3QgcGFyYW1zIHdpdGggdGhlIGdpdmVuIHByZWZpeC5cbiAgICogQHBhcmFtIHtcImFmdGVyXCIgfCBcInVwVG9cIn0gcHJlZml4IC0gUmVxdWVzdCBmaWVsZCBwcmVmaXguXG4gICAqIEBwYXJhbSB7U3luY0N1cnNvcn0gY3Vyc29yIC0gQ3Vyc29yIHRvIHNlcmlhbGl6ZS5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IG51bGw+fSBSZXF1ZXN0IHBhcmFtcy5cbiAgICovXG4gIHN0YXRpYyBjdXJzb3JQYXlsb2FkKHByZWZpeCwgY3Vyc29yKSB7XG4gICAgaWYgKCFjdXJzb3IpIHJldHVybiB7fVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIFtgJHtwcmVmaXh9SWRgXTogY3Vyc29yLmlkLFxuICAgICAgLi4uKGN1cnNvci5zZXJ2ZXJTZXF1ZW5jZSA/IHtbYCR7cHJlZml4fVNlcnZlclNlcXVlbmNlYF06IGN1cnNvci5zZXJ2ZXJTZXF1ZW5jZX0gOiB7fSksXG4gICAgICBbYCR7cHJlZml4fVVwZGF0ZWRBdGBdOiBjdXJzb3IudXBkYXRlZEF0XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBhIHBlcnNpc3RlZCBvciByZXNwb25zZSBjdXJzb3IgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtTeW5jQ3Vyc29yIHwgc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgPz4gfCBudWxsIHwgdW5kZWZpbmVkfSBwYXlsb2FkIC0gQ3Vyc29yIHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtTeW5jQ3Vyc29yfSBQYXJzZWQgY3Vyc29yLlxuICAgKi9cbiAgc3RhdGljIHN5bmNDdXJzb3JGcm9tUGF5bG9hZChwYXlsb2FkKSB7XG4gICAgaWYgKCFwYXlsb2FkKSByZXR1cm4gbnVsbFxuXG4gICAgaWYgKHR5cGVvZiBwYXlsb2FkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jQ3Vyc29yRnJvbVBheWxvYWQoSlNPTi5wYXJzZShwYXlsb2FkKSlcbiAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICByZXR1cm4ge2lkOiBudWxsLCBzZXJ2ZXJTZXF1ZW5jZTogbnVsbCwgdXBkYXRlZEF0OiBwYXlsb2FkfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcGF5bG9hZCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHBheWxvYWQpKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgdXBkYXRlZEF0ID0gdHlwZW9mIHBheWxvYWQudXBkYXRlZEF0ID09PSBcInN0cmluZ1wiID8gcGF5bG9hZC51cGRhdGVkQXQgOiBudWxsXG5cbiAgICBpZiAoIXVwZGF0ZWRBdCkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiB7XG4gICAgICBpZDogcGF5bG9hZC5pZCA9PT0gbnVsbCB8fCBwYXlsb2FkLmlkID09PSB1bmRlZmluZWQgPyBudWxsIDogU3RyaW5nKHBheWxvYWQuaWQpLFxuICAgICAgc2VydmVyU2VxdWVuY2U6IG9wdGlvbmFsSW50ZWdlcihwYXlsb2FkLnNlcnZlclNlcXVlbmNlID09PSBcIlwiID8gbnVsbCA6IHBheWxvYWQuc2VydmVyU2VxdWVuY2UpLFxuICAgICAgdXBkYXRlZEF0XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIG5vcm1hbGl6ZWQgc3luYyByb3cgYWRhcHRlci5cbiAgICogQHBhcmFtIHs/fSBwYXlsb2FkIC0gUmF3IHN5bmMgcGF5bG9hZC5cbiAgICogQHJldHVybnMge1N5bmNDaGFuZ2VFbnZlbG9wZX0gU3luYyByb3cgYWRhcHRlci5cbiAgICovXG4gIHN0YXRpYyBzeW5jRW52ZWxvcGVGcm9tUGF5bG9hZChwYXlsb2FkKSB7XG4gICAgaWYgKCFwYXlsb2FkIHx8IHR5cGVvZiBwYXlsb2FkICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocGF5bG9hZCkpIHRocm93IG5ldyBFcnJvcihcIlN5bmMgY2hhbmdlcyBlbnRyeSBtdXN0IGJlIGFuIG9iamVjdFwiKVxuXG4gICAgY29uc3Qgc3luY1BheWxvYWQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAocGF5bG9hZClcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiAoKSA9PiBzeW5jUGF5bG9hZC5kYXRhLFxuICAgICAgaWQ6ICgpID0+IHN5bmNQYXlsb2FkLmlkLFxuICAgICAgcmVzb3VyY2VJZDogKCkgPT4gc3luY1BheWxvYWQucmVzb3VyY2VJZCxcbiAgICAgIHJlc291cmNlVHlwZTogKCkgPT4gc3luY1BheWxvYWQucmVzb3VyY2VUeXBlID09PSBudWxsIHx8IHN5bmNQYXlsb2FkLnJlc291cmNlVHlwZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IFN0cmluZyhzeW5jUGF5bG9hZC5yZXNvdXJjZVR5cGUpLFxuICAgICAgc3luY1R5cGU6ICgpID0+IHN5bmNQYXlsb2FkLnN5bmNUeXBlID09PSBudWxsIHx8IHN5bmNQYXlsb2FkLnN5bmNUeXBlID09PSB1bmRlZmluZWQgPyBcIlwiIDogU3RyaW5nKHN5bmNQYXlsb2FkLnN5bmNUeXBlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYW4gYXBwLWNvbmZpZ3VyZWQgcmVzb3VyY2UgYXBwbGllciBmb3IgcHVsbGVkIHN5bmMgcm93cy4gVGhlIHN5bmNcbiAgICogbWVjaGFuaWNzIHN0YXkgaGVyZTsgYXBwcyBvbmx5IGRlY2xhcmUgd2hpY2ggbW9kZWxzL2F0dHJpYnV0ZXMvaG9va3MgYXJlXG4gICAqIGFsbG93ZWQgZm9yIGVhY2ggcmVzb3VyY2UgdHlwZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBTeW5jUmVzb3VyY2VDb25maWc+fSByZXNvdXJjZXMgLSBSZXNvdXJjZSBwb2xpY3kgbWFwLlxuICAgKiBAcGFyYW0geyhyZWNvcmQ6ID8pID0+ICgpID0+IHZvaWR9IFtvblJlY29yZF0gLSBDYWxsZWQgd2l0aCBlYWNoIHJlY29yZCBhYm91dCB0byBiZSB3cml0dGVuOyByZXR1cm5zIGEgcmVsZWFzZSBjYWxsYmFjayBpbnZva2VkIGFmdGVyIHRoZSB3cml0ZSAodXNlZCBmb3IgZWNobyBzdXBwcmVzc2lvbikuXG4gICAqIEByZXR1cm5zIHsoc3luYzogU3luY0NoYW5nZUVudmVsb3BlKSA9PiBQcm9taXNlPFN5bmNDaGFuZ2VBcHBseVJlc3VsdD59IFN5bmMgYXBwbHkgY2FsbGJhY2suXG4gICAqL1xuICBzdGF0aWMgcmVzb3VyY2VBcHBsaWVyKHJlc291cmNlcywgb25SZWNvcmQpIHtcbiAgICByZXR1cm4gYXN5bmMgKHN5bmMpID0+IGF3YWl0IHRoaXMuYXBwbHlSZXNvdXJjZVN5bmMoe29uUmVjb3JkLCByZXNvdXJjZXMsIHN5bmN9KVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgb25lIHN5bmMgcm93IHVzaW5nIGRlY2xhcmF0aXZlIHJlc291cmNlIHBvbGljeS5cbiAgICogQHBhcmFtIHt7cmVzb3VyY2VzOiBSZWNvcmQ8c3RyaW5nLCBTeW5jUmVzb3VyY2VDb25maWc+LCBzeW5jOiBTeW5jQ2hhbmdlRW52ZWxvcGUsIG9uUmVjb3JkPzogKHJlY29yZDogPykgPT4gKCkgPT4gdm9pZH19IGFyZ3MgLSBBcHBseSBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTeW5jQ2hhbmdlQXBwbHlSZXN1bHQ+fSBBcHBseSByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgYXBwbHlSZXNvdXJjZVN5bmMoe29uUmVjb3JkLCByZXNvdXJjZXMsIHN5bmN9KSB7XG4gICAgY29uc3QgcmVzb3VyY2VUeXBlID0gc3luYy5yZXNvdXJjZVR5cGUoKVxuICAgIGNvbnN0IHJlc291cmNlID0gcmVzb3VyY2VUeXBlID8gcmVzb3VyY2VzW3Jlc291cmNlVHlwZV0gOiB1bmRlZmluZWRcblxuICAgIGlmICghcmVzb3VyY2UgfHwgIXJlc291cmNlLmVuYWJsZWQpIHJldHVybiB7Y2hhbmdlZDogZmFsc2UsIHJlc291cmNlVHlwZX1cblxuICAgIGlmIChzeW5jLnN5bmNUeXBlKCkgPT09IFwiZGVsZXRlXCIpIHtcbiAgICAgIHJldHVybiB7Y2hhbmdlZDogYXdhaXQgdGhpcy5kZXN0cm95U3luY2VkUmVzb3VyY2Uoe29uUmVjb3JkLCByZXNvdXJjZSwgc3luY30pLCByZXNvdXJjZVR5cGV9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc3luY0RhdGEoc3luYylcbiAgICBjb25zdCByZWNvcmQgPSByZXNvdXJjZS5maW5kUmVjb3JkID8gYXdhaXQgcmVzb3VyY2UuZmluZFJlY29yZCh7ZGF0YSwgcmVzb3VyY2VJZDogc3luYy5yZXNvdXJjZUlkKCksIHN5bmN9KSA6IGF3YWl0IHJlc291cmNlLm1vZGVsQ2xhc3MuZmluZE9ySW5pdGlhbGl6ZUJ5KHtpZDogZGF0YS5pZCA/PyBzeW5jLnJlc291cmNlSWQoKX0pXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IGF3YWl0IHJlc291cmNlLmF0dHJpYnV0ZXMoe2RhdGEsIHJlY29yZCwgc3luY30pXG4gICAgY29uc3QgcmVsZWFzZVJlY29yZCA9IG9uUmVjb3JkID8gb25SZWNvcmQocmVjb3JkKSA6IG51bGxcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgcmVjb3JkLmFzc2lnbihhdHRyaWJ1dGVzKVxuXG4gICAgICBpZiAocmVjb3JkLmlzQ2hhbmdlZCgpKSB7XG4gICAgICAgIGF3YWl0IHJlY29yZC5zYXZlKClcbiAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc291cmNlLmFmdGVyQXBwbHkpIHtcbiAgICAgICAgY29uc3QgaG9va0NoYW5nZWQgPSBhd2FpdCByZXNvdXJjZS5hZnRlckFwcGx5KHthdHRyaWJ1dGVzLCBkYXRhLCByZWNvcmQsIHN5bmN9KVxuXG4gICAgICAgIGNoYW5nZWQgfHw9IGhvb2tDaGFuZ2VkID09PSB0cnVlXG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChyZWxlYXNlUmVjb3JkKSByZWxlYXNlUmVjb3JkKClcbiAgICB9XG5cbiAgICByZXR1cm4ge2NoYW5nZWQsIHJlc291cmNlVHlwZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyBhIHN5bmNlZCByZXNvdXJjZSB2aWEgaXRzIGRlY2xhcmVkIG1vZGVsIHBvbGljeS5cbiAgICogQHBhcmFtIHt7cmVzb3VyY2U6IFN5bmNSZXNvdXJjZUNvbmZpZywgc3luYzogU3luY0NoYW5nZUVudmVsb3BlLCBvblJlY29yZD86IChyZWNvcmQ6ID8pID0+ICgpID0+IHZvaWR9fSBhcmdzIC0gRGVzdHJveSBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciBhIGxvY2FsIHJvdyB3YXMgZGVzdHJveWVkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGRlc3Ryb3lTeW5jZWRSZXNvdXJjZSh7b25SZWNvcmQsIHJlc291cmNlLCBzeW5jfSkge1xuICAgIGNvbnN0IGlkID0gc3luYy5yZXNvdXJjZUlkKClcbiAgICBjb25zdCByZWNvcmQgPSByZXNvdXJjZS5maW5kUmVjb3JkRm9yRGVsZXRlID8gYXdhaXQgcmVzb3VyY2UuZmluZFJlY29yZEZvckRlbGV0ZSh7cmVzb3VyY2VJZDogaWQsIHN5bmN9KSA6IGF3YWl0IHJlc291cmNlLm1vZGVsQ2xhc3MuZmluZEJ5KHtpZH0pXG5cbiAgICBpZiAoIXJlY29yZCkgcmV0dXJuIGZhbHNlXG5cbiAgICBjb25zdCByZWxlYXNlUmVjb3JkID0gb25SZWNvcmQgPyBvblJlY29yZChyZWNvcmQpIDogbnVsbFxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHJlY29yZC5kZXN0cm95KClcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHJlbGVhc2VSZWNvcmQpIHJlbGVhc2VSZWNvcmQoKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSBlbWJlZGRlZCBzeW5jIGRhdGEgSlNPTi9vYmplY3QuXG4gICAqIEBwYXJhbSB7U3luY0NoYW5nZUVudmVsb3BlfSBzeW5jIC0gU3luYyByb3cuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gU3luYyBkYXRhIG9iamVjdC5cbiAgICovXG4gIHN0YXRpYyBzeW5jRGF0YShzeW5jKSB7XG4gICAgY29uc3QgZGF0YSA9IHN5bmMuZGF0YSgpXG5cbiAgICBpZiAoIWRhdGEpIHRocm93IG5ldyBFcnJvcihgU3luYyAke3N5bmMuaWQoKX0gaXMgbWlzc2luZyBkYXRhYClcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoSlNPTi5wYXJzZShkYXRhKSlcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkpIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoZGF0YSlcblxuICAgIHRocm93IG5ldyBFcnJvcihgU3luYyAke3N5bmMuaWQoKX0gaGFzIGludmFsaWQgZGF0YWApXG4gIH1cblxuICAvKipcbiAgICogRHJhaW5zIHBlbmRpbmcgc3luYyByZWNvcmRzIGZyb20gYSBsb2NhbCBWZWxvY2lvdXMgbW9kZWwgaW4gc3RhYmxlIG9yZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFJlcGxheSBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5hdXRoZW50aWNhdGlvblRva2VuIC0gQXV0aCB0b2tlbiB0byBzZW5kIHdpdGggcmVwbGF5IHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuYmF0Y2hTaXplXSAtIE1heCBzeW5jcyBwZXIgcmVxdWVzdC5cbiAgICogQHBhcmFtIHs/fSBhcmdzLnN5bmNNb2RlbCAtIExvY2FsIFN5bmMgbW9kZWwgY2xhc3MuXG4gICAqIEBwYXJhbSB7KHBheWxvYWQ6IHthdXRoZW50aWNhdGlvblRva2VuOiBzdHJpbmcsIHN5bmNzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59KSA9PiBQcm9taXNlPFN5bmNSZXBsYXlSZXNwb25zZT59IGFyZ3MucG9zdFJlcGxheSAtIFJlcGxheSBwb3N0ZXIuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHJlcGxheUxvY2FsU3luY3MoYXJncykge1xuICAgIGNvbnN0IHBvc3RlZFNuYXBzaG90c0J5U3luY0lkID0gbmV3IE1hcCgpXG5cbiAgICBhd2FpdCB0aGlzLnJlcGxheVBlbmRpbmcoe1xuICAgICAgYXV0aGVudGljYXRpb25Ub2tlbjogYXJncy5hdXRoZW50aWNhdGlvblRva2VuLFxuICAgICAgYmF0Y2hTaXplOiBhcmdzLmJhdGNoU2l6ZSxcbiAgICAgIG1hcmtTdWNjZXNzZnVsOiBhc3luYyAoc3luYykgPT4ge1xuICAgICAgICBjb25zdCBzeW5jSWQgPSAoLyoqIEB0eXBlIHt7aWQ6ICgpID0+IHN0cmluZyB8IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWR9fSAqLyAoc3luYykpLmlkKClcbiAgICAgICAgLy8gUmVsb2FkIHdpdGggdGhlIHJlc291cmNlIHByZWxvYWRlZCBzbyByb3dzIHJlbHlpbmcgb24gdGhlIHJlc291cmNlLWF0dHJpYnV0ZXNcbiAgICAgICAgLy8gZmFsbGJhY2sgaW4gbG9jYWxTeW5jRGF0YSBjb21wYXJlIGFnYWluc3QgdGhlIHNhbWUgc25hcHNob3QgdGhleSBwb3N0ZWQuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRTeW5jID0gYXdhaXQgYXJncy5zeW5jTW9kZWwucHJlbG9hZCh7cmVzb3VyY2U6IHRydWV9KS53aGVyZSh7aWQ6IHN5bmNJZH0pLmZpcnN0KClcblxuICAgICAgICBpZiAoIWN1cnJlbnRTeW5jKSByZXR1cm5cbiAgICAgICAgLy8gQSByb3cgZWRpdGVkIHdoaWxlIGl0cyBvbGQgcGF5bG9hZCB3YXMgaW4gZmxpZ2h0IHN0YXlzIHBlbmRpbmcsIHNvIHRoZVxuICAgICAgICAvLyBuZXdlciBsb2NhbCBjaGFuZ2UgcmVwbGF5cyBvbiB0aGUgbmV4dCBkcmFpbiBpbnN0ZWFkIG9mIGJlaW5nIGxvc3QuXG4gICAgICAgIGlmICh0aGlzLmxvY2FsU3luY1JlcGxheVNuYXBzaG90KGN1cnJlbnRTeW5jKSAhPT0gcG9zdGVkU25hcHNob3RzQnlTeW5jSWQuZ2V0KFN0cmluZyhzeW5jSWQpKSkgcmV0dXJuXG5cbiAgICAgICAgYXdhaXQgY3VycmVudFN5bmMudXBkYXRlKHtzdGF0ZTogXCJzdWNjZXNzXCJ9KVxuICAgICAgfSxcbiAgICAgIHBlbmRpbmdTeW5jczogYXN5bmMgKCkgPT4gYXdhaXQgYXJncy5zeW5jTW9kZWwucHJlbG9hZCh7cmVzb3VyY2U6IHRydWV9KS53aGVyZSh7c3RhdGU6IFwicGVuZGluZ1wifSkub3JkZXIoXCJjcmVhdGVkX2F0XCIpLnRvQXJyYXkoKSxcbiAgICAgIHBvc3RSZXBsYXk6IGFyZ3MucG9zdFJlcGxheSxcbiAgICAgIHN5bmNJZDogKHN5bmMpID0+ICgvKiogQHR5cGUge3tpZDogKCkgPT4gc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZH19ICovIChzeW5jKSkuaWQoKSxcbiAgICAgIHN5bmNQYXlsb2FkOiAoc3luYykgPT4ge1xuICAgICAgICBwb3N0ZWRTbmFwc2hvdHNCeVN5bmNJZC5zZXQoU3RyaW5nKCgvKiogQHR5cGUge3tpZDogKCkgPT4gc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZH19ICovIChzeW5jKSkuaWQoKSksIHRoaXMubG9jYWxTeW5jUmVwbGF5U25hcHNob3Qoc3luYykpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxTeW5jUGF5bG9hZChzeW5jKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogU2VyaWFsaXplcyB0aGUgcmVwbGF5LXJlbGV2YW50IHN0YXRlIG9mIGEgbG9jYWwgc3luYyByb3cgZm9yIGluLWZsaWdodCBjb21wYXJpc29ucy5cbiAgICogQHBhcmFtIHs/fSBzeW5jIC0gTG9jYWwgc3luYyByb3cuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFN0YWJsZSBzbmFwc2hvdCBvZiB0aGUgcm93J3MgcmVwbGF5ZWQgcGF5bG9hZC5cbiAgICovXG4gIHN0YXRpYyBsb2NhbFN5bmNSZXBsYXlTbmFwc2hvdChzeW5jKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtkYXRhOiB0aGlzLmxvY2FsU3luY0RhdGEoc3luYyksIHN5bmNUeXBlOiBzeW5jLnN5bmNUeXBlKCl9KVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBvbmUgcmVwbGF5IGVudmVsb3BlIGZyb20gYSBsb2NhbCBzeW5jIHJvdy5cbiAgICogQHBhcmFtIHs/fSBzeW5jIC0gTG9jYWwgc3luYyByb3cuXG4gICAqIEByZXR1cm5zIHt7Y2xpZW50VXBkYXRlZEF0Pzogc3RyaW5nLCBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgaWQ6IG51bWJlciwgcmVzb3VyY2VJZDogc3RyaW5nLCByZXNvdXJjZVR5cGU6IHN0cmluZywgc3luY1R5cGU6IHN0cmluZ319IFN5bmMgcmVwbGF5IGVudmVsb3BlLlxuICAgKi9cbiAgc3RhdGljIGxvY2FsU3luY1BheWxvYWQoc3luYykge1xuICAgIGNvbnN0IGNsaWVudFVwZGF0ZWRBdCA9IHN5bmMudXBkYXRlZEF0KCkgfHwgc3luYy5jcmVhdGVkQXQoKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsaWVudFVwZGF0ZWRBdDogY2xpZW50VXBkYXRlZEF0ID8gY2xpZW50VXBkYXRlZEF0LnRvSVNPU3RyaW5nKCkgOiB1bmRlZmluZWQsXG4gICAgICBkYXRhOiB0aGlzLmxvY2FsU3luY0RhdGEoc3luYyksXG4gICAgICBpZDogLyoqIEB0eXBlIHtudW1iZXJ9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChzeW5jLmlkKCkpKSxcbiAgICAgIHJlc291cmNlSWQ6IFN0cmluZyhzeW5jLnJlc291cmNlSWQoKSksXG4gICAgICByZXNvdXJjZVR5cGU6IHN5bmMucmVzb3VyY2VUeXBlKCkgfHwgXCJcIixcbiAgICAgIHN5bmNUeXBlOiBzeW5jLnN5bmNUeXBlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgb25lIGxvY2FsIHN5bmMgcm93IHBheWxvYWQsIGZhbGxpbmcgYmFjayB0byBwcmVsb2FkZWQgcmVzb3VyY2UgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHs/fSBzeW5jIC0gTG9jYWwgc3luYyByb3cuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gU3luYyBkYXRhLlxuICAgKi9cbiAgc3RhdGljIGxvY2FsU3luY0RhdGEoc3luYykge1xuICAgIGxldCBzeW5jRGF0YSA9IC8qKiBAdHlwZSB7c3RyaW5nIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovIChzeW5jLmRhdGEoKSB8fCB7fSlcblxuICAgIGlmICh0eXBlb2Ygc3luY0RhdGEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN5bmNEYXRhID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKEpTT04ucGFyc2Uoc3luY0RhdGEpKVxuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIHN5bmNEYXRhID0ge31cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoT2JqZWN0LmtleXMoc3luY0RhdGEpLmxlbmd0aCA+IDApIHJldHVybiBzeW5jRGF0YVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoc3luYy5yZXNvdXJjZSgpLmF0dHJpYnV0ZXMoKSlcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIHJldHVybiB7fVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBRdWV1ZXMgYSBsb2NhbCBzeW5jIHJvdyBmb3IgYSBWZWxvY2lvdXMgbW9kZWwgcmVzb3VyY2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUXVldWUgYXJncy5cbiAgICogQHBhcmFtIHs/fSBhcmdzLnJlc291cmNlIC0gUmVzb3VyY2UgYmVpbmcgc3luY2VkLlxuICAgKiBAcGFyYW0gez99IGFyZ3Muc3luY01vZGVsIC0gTG9jYWwgU3luYyBtb2RlbCBjbGFzcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gW2FyZ3MuZGF0YV0gLSBFeHBsaWNpdCBzeW5jIGRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5zeW5jVHlwZV0gLSBTeW5jIG9wZXJhdGlvbiB0eXBlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncy5sb2NhbE9ubHlBdHRyaWJ1dGVzXSAtIEF0dHJpYnV0ZXMgdG8gc3RyaXAgZnJvbSBxdWV1ZWQgcGF5bG9hZHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzLmJvb2xlYW5BdHRyaWJ1dGVzXSAtIEF0dHJpYnV0ZXMgdG8gY29lcmNlIHRocm91Z2ggc3luYyBib29sZWFuIHBhcnNpbmcuXG4gICAqIEBwYXJhbSB7KGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gW2FyZ3Mubm9ybWFsaXplRGF0YV0gLSBBcHAtc3BlY2lmaWMgZGF0YSBub3JtYWxpemVyLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gTG9jYWwgc3luYyByb3cuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcXVldWVMb2NhbFN5bmMoYXJncykge1xuICAgIGNvbnN0IHJlc291cmNlUmVjb3JkSWQgPSBhcmdzLnJlc291cmNlLmlkKClcbiAgICBjb25zdCBtb2RlbENsYXNzID0gYXJncy5yZXNvdXJjZS5jb25zdHJ1Y3RvclxuXG4gICAgaWYgKHR5cGVvZiBtb2RlbENsYXNzLmdldE1vZGVsTmFtZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcmVzb3VyY2UgbW9kZWwgY2xhc3MgbXVzdCBpbXBsZW1lbnQgc3RhdGljIGdldE1vZGVsTmFtZSgpIHRvIHF1ZXVlIHN5bmMgZGF0YSAtIGNsYXNzIG5hbWVzIGFyZSBub3Qgc3RhYmxlIGFjcm9zcyBleHBsaWNpdCBtb2RlbCBuYW1lcyBhbmQgbWluaWZpZWQgYnVuZGxlc1wiKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlVHlwZSA9IG1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lKClcbiAgICBjb25zdCBzeW5jRGF0YSA9IHRoaXMucXVldWVkU3luY0RhdGEoYXJncylcbiAgICBjb25zdCBzeW5jVHlwZSA9IGFyZ3Muc3luY1R5cGUgfHwgXCJ1cGRhdGVcIlxuXG4gICAgaWYgKCFyZXNvdXJjZVJlY29yZElkKSB0aHJvdyBuZXcgRXJyb3IoXCJyZXNvdXJjZS5pZCgpIGlzIHJlcXVpcmVkIHRvIHF1ZXVlIHN5bmMgZGF0YVwiKVxuXG4gICAgY29uc3QgcmVzb3VyY2VJZCA9IFN0cmluZyhyZXNvdXJjZVJlY29yZElkKVxuICAgIGNvbnN0IGV4aXN0aW5nU3luYyA9IGF3YWl0IGFyZ3Muc3luY01vZGVsLmZpbmRCeSh7cmVzb3VyY2VJZCwgcmVzb3VyY2VUeXBlfSlcblxuICAgIGlmIChleGlzdGluZ1N5bmMpIHtcbiAgICAgIGF3YWl0IGV4aXN0aW5nU3luYy51cGRhdGUoe1xuICAgICAgICBkYXRhOiBzeW5jRGF0YSxcbiAgICAgICAgc3RhdGU6IFwicGVuZGluZ1wiLFxuICAgICAgICBzeW5jVHlwZVxuICAgICAgfSlcblxuICAgICAgcmV0dXJuIGV4aXN0aW5nU3luY1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBhcmdzLnN5bmNNb2RlbC5jcmVhdGUoe1xuICAgICAgZGF0YTogc3luY0RhdGEsXG4gICAgICByZXNvdXJjZUlkLFxuICAgICAgcmVzb3VyY2VUeXBlLFxuICAgICAgc3RhdGU6IFwicGVuZGluZ1wiLFxuICAgICAgc3luY1R5cGVcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBiYWNrZW5kLXNhZmUgcXVldWVkIHN5bmMgZGF0YSB3aXRob3V0IG11dGF0aW5nIGNhbGxlciBkYXRhLlxuICAgKiBAcGFyYW0ge3tyZXNvdXJjZTogPywgZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBsb2NhbE9ubHlBdHRyaWJ1dGVzPzogc3RyaW5nW10sIGJvb2xlYW5BdHRyaWJ1dGVzPzogc3RyaW5nW10sIG5vcm1hbGl6ZURhdGE/OiAoZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+fX0gYXJncyAtIERhdGEgYXJncy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBRdWV1ZWQgZGF0YS5cbiAgICovXG4gIHN0YXRpYyBxdWV1ZWRTeW5jRGF0YShhcmdzKSB7XG4gICAgY29uc3QgaW5wdXREYXRhID0gYXJncy5kYXRhID8/IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovIChhcmdzLnJlc291cmNlLmF0dHJpYnV0ZXMoKSlcbiAgICBjb25zdCBub3JtYWxpemVkRGF0YSA9IGFyZ3Mubm9ybWFsaXplRGF0YSA/IGFyZ3Mubm9ybWFsaXplRGF0YShpbnB1dERhdGEpIDogaW5wdXREYXRhXG4gICAgY29uc3Qgc3luY0RhdGEgPSB7Li4ubm9ybWFsaXplZERhdGF9XG5cbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgYXJncy5sb2NhbE9ubHlBdHRyaWJ1dGVzIHx8IFtdKSBkZWxldGUgc3luY0RhdGFbYXR0cmlidXRlTmFtZV1cbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgYXJncy5ib29sZWFuQXR0cmlidXRlcyB8fCBbXSkge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd24oc3luY0RhdGEsIGF0dHJpYnV0ZU5hbWUpKSBzeW5jRGF0YVthdHRyaWJ1dGVOYW1lXSA9IHRoaXMub3B0aW9uYWxCb29sZWFuU3luY1ZhbHVlKHN5bmNEYXRhW2F0dHJpYnV0ZU5hbWVdLCBhdHRyaWJ1dGVOYW1lKVxuICAgIH1cblxuICAgIHJldHVybiBzeW5jRGF0YVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHNtYWxsIGFwcC1mYWNpbmcgbG9jYWwgc3luYyBxdWV1ZSBmYWNhZGUgZnJvbSBkZWNsYXJhdGl2ZSBtb2RlbCBjb25maWcuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUXVldWUgY29uZmlnLlxuICAgKiBAcGFyYW0gez99IGFyZ3Muc3luY01vZGVsIC0gTG9jYWwgU3luYyBtb2RlbCBjbGFzcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3Muc2luZ2xlRmxpZ2h0S2V5IC0gS2V5IHVzZWQgdG8gc2VyaWFsaXplIGJhY2tlbmQgcmVwbGF5LlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8dm9pZD59IGFyZ3Muc3luY1BlbmRpbmcgLSBCYWNrZW5kIHJlcGxheSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHsocmVzb3VyY2U6ID8pID0+IHN0cmluZ1tdfSBbYXJncy5sb2NhbE9ubHlBdHRyaWJ1dGVzXSAtIFJlc291cmNlLXNwZWNpZmljIGxvY2FsLW9ubHkgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHsocmVzb3VyY2U6ID8pID0+IHN0cmluZ1tdfSBbYXJncy5ib29sZWFuQXR0cmlidXRlc10gLSBSZXNvdXJjZS1zcGVjaWZpYyBTUUxpdGUgYm9vbGVhbiBhdHRyaWJ1dGVzLlxuICAgKiBAcmV0dXJucyB7e3F1ZXVlOiAocXVldWVBcmdzOiB7cmVzb3VyY2U6ID8sIGRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgc3luY1R5cGU/OiBzdHJpbmd9KSA9PiBQcm9taXNlPD8+LCBzeW5jUGVuZGluZzogKCkgPT4gUHJvbWlzZTx2b2lkPn19IENvbmZpZ3VyZWQgbG9jYWwgc3luYyBxdWV1ZS5cbiAgICovXG4gIHN0YXRpYyBsb2NhbFN5bmNRdWV1ZShhcmdzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHF1ZXVlOiBhc3luYyAocXVldWVBcmdzKSA9PiBhd2FpdCB0aGlzLnF1ZXVlTG9jYWxTeW5jKHtcbiAgICAgICAgLi4ucXVldWVBcmdzLFxuICAgICAgICBib29sZWFuQXR0cmlidXRlczogYXJncy5ib29sZWFuQXR0cmlidXRlcyA/IGFyZ3MuYm9vbGVhbkF0dHJpYnV0ZXMocXVldWVBcmdzLnJlc291cmNlKSA6IFtdLFxuICAgICAgICBsb2NhbE9ubHlBdHRyaWJ1dGVzOiBhcmdzLmxvY2FsT25seUF0dHJpYnV0ZXMgPyBhcmdzLmxvY2FsT25seUF0dHJpYnV0ZXMocXVldWVBcmdzLnJlc291cmNlKSA6IFtdLFxuICAgICAgICBzeW5jTW9kZWw6IGFyZ3Muc3luY01vZGVsXG4gICAgICB9KSxcbiAgICAgIHN5bmNQZW5kaW5nOiBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLnNpbmdsZUZsaWdodChhcmdzLnNpbmdsZUZsaWdodEtleSwgYXJncy5zeW5jUGVuZGluZylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGJvb2xlYW5zIGNvbW1vbmx5IHVzZWQgYnkgU1FMaXRlL29mZmxpbmUgc3luYyBwYXlsb2Fkcy5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFN5bmMgZGVjaXNpb24gdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGVzY3JpcHRpb25dIC0gRXJyb3IgY29udGV4dC5cbiAgICogQHJldHVybnMge2Jvb2xlYW4gfCBudWxsfSBQYXJzZWQgYm9vbGVhbi1saWtlIGJhY2tlbmQvbG9jYWwgdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgb3B0aW9uYWxCb29sZWFuU3luY1ZhbHVlKHZhbHVlLCBkZXNjcmlwdGlvbiA9IFwic3luYyBib29sZWFuXCIpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGxcbiAgICBpZiAodmFsdWUgPT09IDEpIHJldHVybiB0cnVlXG4gICAgaWYgKHZhbHVlID09PSAwKSByZXR1cm4gZmFsc2VcblxuICAgIHJldHVybiBvcHRpb25hbEJvb2xlYW4odmFsdWUsIGRlc2NyaXB0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgYm9vbGVhbiBzeW5jIHZhbHVlIHRvIFNRTGl0ZSBib29sZWFuIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbiB8IG51bGx9IHZhbHVlIC0gU3luYyBib29sZWFuIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7MCB8IDF9IFNRTGl0ZS1jb21wYXRpYmxlIGJvb2xlYW4gdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgc3FsaXRlQm9vbGVhblN5bmNWYWx1ZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gdHJ1ZSA/IDEgOiAwXG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgZ2VuZXJpYyBzeW5jIGNvdW50ZXJzIGludG8gYXBwLXNwZWNpZmljIHJlc3VsdCBrZXlzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFJlc3VsdCBhcmdzLlxuICAgKiBAcGFyYW0ge1N5bmNDaGFuZ2VzUmVzdWx0fSBhcmdzLnJlc3VsdCAtIEdlbmVyaWMgVmVsb2Npb3VzIHN5bmMgcmVzdWx0LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHtjaGFuZ2VkS2V5OiBzdHJpbmcsIGNvdW50S2V5OiBzdHJpbmd9Pn0gYXJncy5yZXNvdXJjZXMgLSBSZXNvdXJjZSByZXN1bHQga2V5IG1hcC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBQcm9qZWN0ZWQgcmVzdWx0LlxuICAgKi9cbiAgc3RhdGljIHN5bmNSZXN1bHRGb3JSZXNvdXJjZXMoe3Jlc3VsdCwgcmVzb3VyY2VzfSkge1xuICAgIGNvbnN0IHN5bmNSZXN1bHQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAoe1xuICAgICAgY2hhbmdlZDogcmVzdWx0LmNoYW5nZWQsXG4gICAgICBwYWdlczogcmVzdWx0LnBhZ2VzLFxuICAgICAgc3luY2VkQ291bnQ6IHJlc3VsdC5zeW5jZWRDb3VudFxuICAgIH0pXG5cbiAgICBmb3IgKGNvbnN0IFtyZXNvdXJjZVR5cGUsIGtleXNdIG9mIE9iamVjdC5lbnRyaWVzKHJlc291cmNlcykpIHtcbiAgICAgIHN5bmNSZXN1bHRba2V5cy5jb3VudEtleV0gPSByZXN1bHQucmVzb3VyY2VDb3VudHNbcmVzb3VyY2VUeXBlXSB8fCAwXG4gICAgICBzeW5jUmVzdWx0W2tleXMuY2hhbmdlZEtleV0gPSByZXN1bHQucmVzb3VyY2VDaGFuZ2VkW3Jlc291cmNlVHlwZV0gfHwgZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gc3luY1Jlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIERyYWlucyBwZW5kaW5nIHN5bmMgcmVjb3JkcyBpbiBzdGFibGUgb3JkZXIgYW5kIG1hcmtzIGFja25vd2xlZGdlZCByb3dzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFJlcGxheSBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5hdXRoZW50aWNhdGlvblRva2VuIC0gQXV0aCB0b2tlbiB0byBzZW5kIHdpdGggcmVwbGF5IHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuYmF0Y2hTaXplXSAtIE1heCBzeW5jcyBwZXIgcmVxdWVzdC4gRGVmYXVsdHMgdG8gMTAwLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8QXJyYXk8dW5rbm93bj4+fSBhcmdzLnBlbmRpbmdTeW5jcyAtIExvYWRzIHBlbmRpbmcgbG9jYWwgc3luYyByb3dzIGluIHJlcGxheSBvcmRlci5cbiAgICogQHBhcmFtIHsoc3luYzogdW5rbm93bikgPT4gc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZH0gYXJncy5zeW5jSWQgLSBSZXR1cm5zIHRoZSBsb2NhbCBzeW5jIGlkLlxuICAgKiBAcGFyYW0geyhzeW5jOiB1bmtub3duKSA9PiBSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5zeW5jUGF5bG9hZCAtIEJ1aWxkcyB0aGUgQVBJIHN5bmMgZW52ZWxvcGUuXG4gICAqIEBwYXJhbSB7KHBheWxvYWQ6IHthdXRoZW50aWNhdGlvblRva2VuOiBzdHJpbmcsIHN5bmNzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59KSA9PiBQcm9taXNlPFN5bmNSZXBsYXlSZXNwb25zZT59IGFyZ3MucG9zdFJlcGxheSAtIFBvc3RzIG9uZSByZXBsYXkgcmVxdWVzdC5cbiAgICogQHBhcmFtIHsoc3luYzogdW5rbm93biwgcmVzcG9uc2U6IFN5bmNSZXBsYXlJdGVtKSA9PiBQcm9taXNlPHZvaWQ+fSBhcmdzLm1hcmtTdWNjZXNzZnVsIC0gTWFya3Mgb25lIHN5bmMgYXMgc3VjY2Vzc2Z1bCBsb2NhbGx5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gUmVzb2x2ZXMgYWZ0ZXIgYWxsIGJhdGNoZXMgYXJlIHJlcGxheWVkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHJlcGxheVBlbmRpbmcoYXJncykge1xuICAgIGNvbnN0IHBlbmRpbmdTeW5jcyA9IGF3YWl0IGFyZ3MucGVuZGluZ1N5bmNzKClcbiAgICBjb25zdCBiYXRjaFNpemUgPSB0aGlzLm5vcm1hbGl6ZWRCYXRjaFNpemUoYXJncy5iYXRjaFNpemUpXG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBwZW5kaW5nU3luY3MubGVuZ3RoOyBvZmZzZXQgKz0gYmF0Y2hTaXplKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcGxheUJhdGNoKHsuLi5hcmdzLCBwZW5kaW5nU3luY3M6IHBlbmRpbmdTeW5jcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJhdGNoU2l6ZSl9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXlzIG9uZSBiYXRjaCBvZiBzeW5jcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBSZXBsYXkgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXV0aGVudGljYXRpb25Ub2tlbiAtIEF1dGggdG9rZW4uXG4gICAqIEBwYXJhbSB7QXJyYXk8dW5rbm93bj59IGFyZ3MucGVuZGluZ1N5bmNzIC0gQmF0Y2ggc3luY3MuXG4gICAqIEBwYXJhbSB7KHN5bmM6IHVua25vd24pID0+IHN0cmluZyB8IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWR9IGFyZ3Muc3luY0lkIC0gU3luYyBpZCBnZXR0ZXIuXG4gICAqIEBwYXJhbSB7KHN5bmM6IHVua25vd24pID0+IFJlY29yZDxzdHJpbmcsID8+fSBhcmdzLnN5bmNQYXlsb2FkIC0gUGF5bG9hZCBidWlsZGVyLlxuICAgKiBAcGFyYW0geyhwYXlsb2FkOiB7YXV0aGVudGljYXRpb25Ub2tlbjogc3RyaW5nLCBzeW5jczogQXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSkgPT4gUHJvbWlzZTxTeW5jUmVwbGF5UmVzcG9uc2U+fSBhcmdzLnBvc3RSZXBsYXkgLSBSZXBsYXkgcG9zdGVyLlxuICAgKiBAcGFyYW0geyhzeW5jOiB1bmtub3duLCByZXNwb25zZTogU3luY1JlcGxheUl0ZW0pID0+IFByb21pc2U8dm9pZD59IGFyZ3MubWFya1N1Y2Nlc3NmdWwgLSBTdWNjZXNzIGhvb2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyBhZnRlciB0aGUgYmF0Y2ggaXMgYWNrbm93bGVkZ2VkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHJlcGxheUJhdGNoKGFyZ3MpIHtcbiAgICBjb25zdCB7YXV0aGVudGljYXRpb25Ub2tlbiwgbWFya1N1Y2Nlc3NmdWwsIHBlbmRpbmdTeW5jcywgcG9zdFJlcGxheSwgc3luY0lkLCBzeW5jUGF5bG9hZH0gPSBhcmdzXG5cbiAgICBpZiAocGVuZGluZ1N5bmNzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBzeW5jc0J5SWQgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3Qgc3luYyBvZiBwZW5kaW5nU3luY3MpIHtcbiAgICAgIGNvbnN0IGlkID0gc3luY0lkKHN5bmMpXG5cbiAgICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkICYmIGlkICE9PSBudWxsKSBzeW5jc0J5SWQuc2V0KFN0cmluZyhpZCksIHN5bmMpXG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBwb3N0UmVwbGF5KHtcbiAgICAgIGF1dGhlbnRpY2F0aW9uVG9rZW4sXG4gICAgICBzeW5jczogcGVuZGluZ1N5bmNzLm1hcCgoc3luYykgPT4gc3luY1BheWxvYWQoc3luYykpXG4gICAgfSlcblxuICAgIHRoaXMuZW5zdXJlU3VjY2Vzc2Z1bFJlc3BvbnNlKHJlc3BvbnNlKVxuXG4gICAgZm9yIChjb25zdCBzeW5jUmVzcG9uc2Ugb2YgcmVzcG9uc2Uuc3luY3MgfHwgW10pIHtcbiAgICAgIGNvbnN0IHN5bmMgPSBzeW5jc0J5SWQuZ2V0KFN0cmluZyhzeW5jUmVzcG9uc2UuaWQpKVxuXG4gICAgICBpZiAoIXN5bmMpIGNvbnRpbnVlXG4gICAgICBpZiAoc3luY1Jlc3BvbnNlLnN5bmNTdGF0ZSAhPT0gXCJzdWNjZXNzZnVsXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHN5bmMgc3RhdGUgcmV0dXJuZWQgZm9yIHN5bmMgJHtTdHJpbmcoc3luY1Jlc3BvbnNlLmlkKX06ICR7U3RyaW5nKHN5bmNSZXNwb25zZS5zeW5jU3RhdGUpfWApXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IG1hcmtTdWNjZXNzZnVsKHN5bmMsIHN5bmNSZXNwb25zZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIEFQSSByZXNwb25zZSBzdGF0dXMgYW5kIHNoYXBlLlxuICAgKiBAcGFyYW0ge1N5bmNSZXBsYXlSZXNwb25zZX0gcmVzcG9uc2UgLSBSZXBsYXkgcmVzcG9uc2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIGVuc3VyZVN1Y2Nlc3NmdWxSZXNwb25zZShyZXNwb25zZSkge1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IFwiZXJyb3JcIikgdGhyb3cgbmV3IEVycm9yKHJlc3BvbnNlLmVycm9yTWVzc2FnZSB8fCBcIlN5bmMgZmFpbGVkXCIpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJlc3BvbnNlLnN5bmNzKSkgdGhyb3cgbmV3IEVycm9yKFwiU3luYyByZXNwb25zZSBtaXNzaW5nIHN5bmNzXCIpXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHBvc2l0aXZlIGJhdGNoIHNpemUuXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgdW5kZWZpbmVkfSBiYXRjaFNpemUgLSBCYXRjaCBzaXplLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBQb3NpdGl2ZSBiYXRjaCBzaXplLlxuICAgKi9cbiAgc3RhdGljIG5vcm1hbGl6ZWRCYXRjaFNpemUoYmF0Y2hTaXplKSB7XG4gICAgaWYgKHR5cGVvZiBiYXRjaFNpemUgIT09IFwibnVtYmVyXCIgfHwgIU51bWJlci5pc0Zpbml0ZShiYXRjaFNpemUpIHx8IGJhdGNoU2l6ZSA8IDEpIHJldHVybiAxMDBcblxuICAgIHJldHVybiBNYXRoLmZsb29yKGJhdGNoU2l6ZSlcbiAgfVxufVxuIl19
|
|
@@ -22,6 +22,14 @@ export default class SyncApiController extends Controller {
|
|
|
22
22
|
at?: string;
|
|
23
23
|
syncResourceClass?: import("../configuration-types.js").FrontendModelResourceClassType;
|
|
24
24
|
}): void;
|
|
25
|
+
/**
|
|
26
|
+
* Auto-mounts the sync endpoints configured through `sync.api` on a configuration.
|
|
27
|
+
* No-op when `sync.api` is absent; guarded so repeated server boots with the
|
|
28
|
+
* same configuration register the routes only once.
|
|
29
|
+
* @param {import("../configuration.js").default} configuration - Configuration instance.
|
|
30
|
+
* @returns {void}
|
|
31
|
+
*/
|
|
32
|
+
static mountFromConfiguration(configuration: import("../configuration.js").default): void;
|
|
25
33
|
/**
|
|
26
34
|
* Normalizes a sync mount path.
|
|
27
35
|
* @param {string} at - Mount path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-api-controller.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-api-controller.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-api-controller.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-api-controller.js"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH;IAsDE;;;;OAIG;IACH,4CAHW,OAAO,2BAA2B,EAAE,8BAA8B,GAChE,OAAO,iBAAiB,CAYpC;IAED;;;;OAIG;IACH,uBAHW;QAAC,aAAa,CAAC,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,2BAA2B,EAAE,8BAA8B,CAAA;KAAC,GAC1J,IAAI,CAahB;IAED;;;;;;OAMG;IACH,6CAHW,OAAO,qBAAqB,EAAE,OAAO,GACnC,IAAI,CAUhB;IAED;;;;OAIG;IACH,+BAHW,MAAM,GACJ,MAAM,CAQlB;IApHD;;;OAGG;IACH,UAFa,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;OAGG;IACH,WAFa,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;OAIG;IACH,qBAHW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrB,yBAAyB,CAoBrC;IAED;;;OAGG;IACH,qBAFa,OAAO,2BAA2B,EAAE,8BAA8B,CAI9E;IAmED;;;OAGG;IACH,4BAFa,OAAO,2BAA2B,EAAE,8BAA8B,CAI9E;IAED,kFAAkF;IAClF,sCAEC;IAED;;;OAGG;IACH,kBAFa,cAAc,6BAA6B,EAAE,OAAO,CAShE;IAED;;;OAGG;IACH,iBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,yCAHW,OAAO,2BAA2B,EAAE,8BAA8B,GAChE,OAAO,2BAA2B,EAAE,kCAAkC,CAOlF;CACF;uBAjLsB,kBAAkB;sCACH,6CAA6C"}
|