velocious 1.0.492 → 1.0.493
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/src/sync/sync-envelope-replay-service.d.ts +116 -7
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +103 -10
- package/build/src/sync/sync-replay-upsert-applier.d.ts +102 -0
- package/build/src/sync/sync-replay-upsert-applier.d.ts.map +1 -0
- package/build/src/sync/sync-replay-upsert-applier.js +158 -0
- package/build/sync/sync-envelope-replay-service.js +114 -9
- package/build/sync/sync-replay-upsert-applier.js +179 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/sync/sync-envelope-replay-service.js +114 -9
- package/src/sync/sync-replay-upsert-applier.js +179 -0
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One declarative broadcast fanned out after a mutation applies.
|
|
3
|
+
* @typedef {object} SyncReplayBroadcast
|
|
4
|
+
* @property {string | ((args: Record<string, ?>) => string)} channel - Channel name or resolver.
|
|
5
|
+
* @property {(args: Record<string, ?>) => Record<string, ?>} broadcastParams - Channel routing params.
|
|
6
|
+
* @property {(args: Record<string, ?>) => ?} body - Broadcast body.
|
|
7
|
+
* @property {(args: Record<string, ?>) => boolean} [when] - Optional gate; skipped when it returns false.
|
|
8
|
+
*/
|
|
1
9
|
/**
|
|
2
10
|
* Replays client sync envelopes through project supplied authentication,
|
|
3
11
|
* authorization, application, and persistence hooks.
|
|
@@ -21,6 +29,14 @@ export default class SyncEnvelopeReplayService {
|
|
|
21
29
|
* @param {{debug?: (...args: Array<unknown>) => void, warn?: (...args: Array<unknown>) => void}} [args.logger] - Logger used for normalization warnings.
|
|
22
30
|
* @param {?} [args.syncModel] - Sync/change model enabling model-backed default hooks.
|
|
23
31
|
* @param {string} [args.actorForeignKeyColumn] - Sync model column linking rows to the replay actor.
|
|
32
|
+
* @param {?} [args.authenticationTokenModel] - Token model enabling the default token-lookup authenticateReplay.
|
|
33
|
+
* @param {string} [args.authenticationTokenColumn] - Token model column holding the token. Defaults to "token".
|
|
34
|
+
* @param {string} [args.authenticationTokenParam] - Request param carrying the token. Defaults to "authenticationToken".
|
|
35
|
+
* @param {Record<string, ((args: Record<string, ?>) => Promise<?>) | ConstructorParameters<typeof SyncReplayUpsertApplier>[0]>} [args.applyHandlers] - Per-resourceType apply handlers (functions or declarative upsert-applier specs) enabling the default applyReplayMutation dispatch.
|
|
36
|
+
* @param {(args: Record<string, ?>) => Record<string, ?>} [args.persistExtraAttributes] - Extra attributes merged into the model-backed persisted row (e.g. an event scope column).
|
|
37
|
+
* @param {(args: {mutation: ?, applyResult: ?}) => ?} [args.persistSerializedData] - Overrides the persisted data payload (object results are JSON stringified).
|
|
38
|
+
* @param {(broadcast: {channel: string, params: Record<string, ?>, body: ?}) => Promise<void>} [args.broadcaster] - Delivers declarative broadcasts. Required when broadcasts are configured.
|
|
39
|
+
* @param {SyncReplayBroadcast[]} [args.broadcasts] - Broadcasts fanned out by the default afterReplayMutation.
|
|
24
40
|
*/
|
|
25
41
|
constructor(args?: {
|
|
26
42
|
logger?: {
|
|
@@ -29,6 +45,48 @@ export default class SyncEnvelopeReplayService {
|
|
|
29
45
|
} | undefined;
|
|
30
46
|
syncModel?: unknown;
|
|
31
47
|
actorForeignKeyColumn?: string | undefined;
|
|
48
|
+
authenticationTokenModel?: unknown;
|
|
49
|
+
authenticationTokenColumn?: string | undefined;
|
|
50
|
+
authenticationTokenParam?: string | undefined;
|
|
51
|
+
applyHandlers?: Record<string, {
|
|
52
|
+
modelClass: unknown;
|
|
53
|
+
fields: Record<string, string | {
|
|
54
|
+
type: string;
|
|
55
|
+
column?: string;
|
|
56
|
+
} | ((value: unknown, label: string) => unknown)>;
|
|
57
|
+
findRecord?: ((args: {
|
|
58
|
+
data: Record<string, unknown>;
|
|
59
|
+
mutation: unknown;
|
|
60
|
+
context: Record<string, unknown>;
|
|
61
|
+
}) => Promise<unknown>) | undefined;
|
|
62
|
+
findRecordForDelete?: ((args: {
|
|
63
|
+
mutation: unknown;
|
|
64
|
+
context: Record<string, unknown>;
|
|
65
|
+
}) => Promise<unknown>) | undefined;
|
|
66
|
+
restArgs?: "error" | "ignore" | undefined;
|
|
67
|
+
afterApply?: ((args: {
|
|
68
|
+
mappedAttributes: Record<string, unknown>;
|
|
69
|
+
mutation: unknown;
|
|
70
|
+
context: Record<string, unknown>;
|
|
71
|
+
record: unknown;
|
|
72
|
+
}) => Promise<Record<string, unknown> | void>) | undefined;
|
|
73
|
+
serialize?: ((args: {
|
|
74
|
+
mutation: unknown;
|
|
75
|
+
context: Record<string, unknown>;
|
|
76
|
+
record: unknown;
|
|
77
|
+
}) => Promise<Record<string, unknown>> | Record<string, unknown>) | undefined;
|
|
78
|
+
} | ((args: Record<string, unknown>) => Promise<unknown>)> | undefined;
|
|
79
|
+
persistExtraAttributes?: ((args: Record<string, unknown>) => Record<string, unknown>) | undefined;
|
|
80
|
+
persistSerializedData?: ((args: {
|
|
81
|
+
mutation: unknown;
|
|
82
|
+
applyResult: unknown;
|
|
83
|
+
}) => unknown) | undefined;
|
|
84
|
+
broadcaster?: ((broadcast: {
|
|
85
|
+
channel: string;
|
|
86
|
+
params: Record<string, unknown>;
|
|
87
|
+
body: unknown;
|
|
88
|
+
}) => Promise<void>) | undefined;
|
|
89
|
+
broadcasts?: SyncReplayBroadcast[] | undefined;
|
|
32
90
|
});
|
|
33
91
|
logger: {
|
|
34
92
|
debug?: (...args: Array<unknown>) => void;
|
|
@@ -36,6 +94,27 @@ export default class SyncEnvelopeReplayService {
|
|
|
36
94
|
};
|
|
37
95
|
syncModel: any;
|
|
38
96
|
actorForeignKeyColumn: string;
|
|
97
|
+
authenticationTokenModel: any;
|
|
98
|
+
authenticationTokenColumn: string;
|
|
99
|
+
authenticationTokenParam: string;
|
|
100
|
+
persistExtraAttributes: ((args: Record<string, unknown>) => Record<string, unknown>) | null;
|
|
101
|
+
persistSerializedData: ((args: {
|
|
102
|
+
mutation: unknown;
|
|
103
|
+
applyResult: unknown;
|
|
104
|
+
}) => unknown) | null;
|
|
105
|
+
broadcaster: ((broadcast: {
|
|
106
|
+
channel: string;
|
|
107
|
+
params: Record<string, unknown>;
|
|
108
|
+
body: unknown;
|
|
109
|
+
}) => Promise<void>) | null;
|
|
110
|
+
broadcasts: SyncReplayBroadcast[] | null;
|
|
111
|
+
applyHandlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>> | null;
|
|
112
|
+
/**
|
|
113
|
+
* Wraps declarative apply-handler specs in upsert appliers.
|
|
114
|
+
* @param {Record<string, ?>} applyHandlers - Raw apply handlers.
|
|
115
|
+
* @returns {Record<string, (args: Record<string, ?>) => Promise<?>>} Callable handlers by resource type.
|
|
116
|
+
*/
|
|
117
|
+
builtApplyHandlers(applyHandlers: Record<string, unknown>): Record<string, (args: Record<string, unknown>) => Promise<unknown>>;
|
|
39
118
|
/**
|
|
40
119
|
* Replays a sync batch.
|
|
41
120
|
* @param {Record<string, ?>} params - Request params carrying authentication and syncs.
|
|
@@ -49,10 +128,13 @@ export default class SyncEnvelopeReplayService {
|
|
|
49
128
|
}>;
|
|
50
129
|
/**
|
|
51
130
|
* Authenticates the sync batch actor.
|
|
52
|
-
*
|
|
131
|
+
*
|
|
132
|
+
* Defaults to a token-model lookup when `authenticationTokenModel` is
|
|
133
|
+
* configured; otherwise apps override this hook.
|
|
134
|
+
* @param {Record<string, ?>} params - Request params.
|
|
53
135
|
* @returns {Promise<{authenticated: true, actor: ?} | {authenticated: false, errorCode: string, errorMessage: string}>} Auth result.
|
|
54
136
|
*/
|
|
55
|
-
authenticateReplay(
|
|
137
|
+
authenticateReplay(params: Record<string, unknown>): Promise<{
|
|
56
138
|
authenticated: true;
|
|
57
139
|
actor: unknown;
|
|
58
140
|
} | {
|
|
@@ -155,10 +237,13 @@ export default class SyncEnvelopeReplayService {
|
|
|
155
237
|
existingReplaySyncClientUpdatedAt(existingSync: unknown): Date | null;
|
|
156
238
|
/**
|
|
157
239
|
* Applies one normalized mutation to domain models.
|
|
158
|
-
*
|
|
240
|
+
*
|
|
241
|
+
* Defaults to dispatching through the configured apply-handler registry;
|
|
242
|
+
* mutations without a registered handler fail loudly.
|
|
243
|
+
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
|
|
159
244
|
* @returns {Promise<?>} Project-specific apply result.
|
|
160
245
|
*/
|
|
161
|
-
applyReplayMutation(
|
|
246
|
+
applyReplayMutation(args: {
|
|
162
247
|
actor: unknown;
|
|
163
248
|
context: Record<string, unknown>;
|
|
164
249
|
existingSync: unknown;
|
|
@@ -183,7 +268,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
183
268
|
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay persistence arguments.
|
|
184
269
|
* @returns {Promise<void>}
|
|
185
270
|
*/
|
|
186
|
-
persistReplayMutation({ actor, existingSync, mutation }: {
|
|
271
|
+
persistReplayMutation({ actor, applyResult, context, existingSync, mutation, shouldApply }: {
|
|
187
272
|
actor: unknown;
|
|
188
273
|
context: Record<string, unknown>;
|
|
189
274
|
existingSync: unknown;
|
|
@@ -202,10 +287,13 @@ export default class SyncEnvelopeReplayService {
|
|
|
202
287
|
}): Record<string, unknown>;
|
|
203
288
|
/**
|
|
204
289
|
* Runs side effects after a successful mutation replay and persistence.
|
|
205
|
-
*
|
|
290
|
+
*
|
|
291
|
+
* Defaults to fanning the applied result out through the configured
|
|
292
|
+
* declarative broadcasts.
|
|
293
|
+
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay side-effect arguments.
|
|
206
294
|
* @returns {Promise<void>}
|
|
207
295
|
*/
|
|
208
|
-
afterReplayMutation(
|
|
296
|
+
afterReplayMutation(args: {
|
|
209
297
|
actor: unknown;
|
|
210
298
|
context: Record<string, unknown>;
|
|
211
299
|
existingSync: unknown;
|
|
@@ -214,6 +302,27 @@ export default class SyncEnvelopeReplayService {
|
|
|
214
302
|
shouldApply: boolean;
|
|
215
303
|
}): Promise<void>;
|
|
216
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* One declarative broadcast fanned out after a mutation applies.
|
|
307
|
+
*/
|
|
308
|
+
export type SyncReplayBroadcast = {
|
|
309
|
+
/**
|
|
310
|
+
* - Channel name or resolver.
|
|
311
|
+
*/
|
|
312
|
+
channel: string | ((args: Record<string, unknown>) => string);
|
|
313
|
+
/**
|
|
314
|
+
* - Channel routing params.
|
|
315
|
+
*/
|
|
316
|
+
broadcastParams: (args: Record<string, unknown>) => Record<string, unknown>;
|
|
317
|
+
/**
|
|
318
|
+
* - Broadcast body.
|
|
319
|
+
*/
|
|
320
|
+
body: (args: Record<string, unknown>) => unknown;
|
|
321
|
+
/**
|
|
322
|
+
* - Optional gate; skipped when it returns false.
|
|
323
|
+
*/
|
|
324
|
+
when?: ((args: Record<string, unknown>) => boolean) | undefined;
|
|
325
|
+
};
|
|
217
326
|
export type SyncReplayMutation = {
|
|
218
327
|
/**
|
|
219
328
|
* - Client-side mutation timestamp.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import SyncReplayUpsertApplier from "./sync-replay-upsert-applier.js";
|
|
3
|
+
/**
|
|
4
|
+
* One declarative broadcast fanned out after a mutation applies.
|
|
5
|
+
* @typedef {object} SyncReplayBroadcast
|
|
6
|
+
* @property {string | ((args: Record<string, ?>) => string)} channel - Channel name or resolver.
|
|
7
|
+
* @property {(args: Record<string, ?>) => Record<string, ?>} broadcastParams - Channel routing params.
|
|
8
|
+
* @property {(args: Record<string, ?>) => ?} body - Broadcast body.
|
|
9
|
+
* @property {(args: Record<string, ?>) => boolean} [when] - Optional gate; skipped when it returns false.
|
|
10
|
+
*/
|
|
2
11
|
/**
|
|
3
12
|
* Replays client sync envelopes through project supplied authentication,
|
|
4
13
|
* authorization, application, and persistence hooks.
|
|
@@ -22,14 +31,46 @@ export default class SyncEnvelopeReplayService {
|
|
|
22
31
|
* @param {{debug?: (...args: Array<unknown>) => void, warn?: (...args: Array<unknown>) => void}} [args.logger] - Logger used for normalization warnings.
|
|
23
32
|
* @param {?} [args.syncModel] - Sync/change model enabling model-backed default hooks.
|
|
24
33
|
* @param {string} [args.actorForeignKeyColumn] - Sync model column linking rows to the replay actor.
|
|
34
|
+
* @param {?} [args.authenticationTokenModel] - Token model enabling the default token-lookup authenticateReplay.
|
|
35
|
+
* @param {string} [args.authenticationTokenColumn] - Token model column holding the token. Defaults to "token".
|
|
36
|
+
* @param {string} [args.authenticationTokenParam] - Request param carrying the token. Defaults to "authenticationToken".
|
|
37
|
+
* @param {Record<string, ((args: Record<string, ?>) => Promise<?>) | ConstructorParameters<typeof SyncReplayUpsertApplier>[0]>} [args.applyHandlers] - Per-resourceType apply handlers (functions or declarative upsert-applier specs) enabling the default applyReplayMutation dispatch.
|
|
38
|
+
* @param {(args: Record<string, ?>) => Record<string, ?>} [args.persistExtraAttributes] - Extra attributes merged into the model-backed persisted row (e.g. an event scope column).
|
|
39
|
+
* @param {(args: {mutation: ?, applyResult: ?}) => ?} [args.persistSerializedData] - Overrides the persisted data payload (object results are JSON stringified).
|
|
40
|
+
* @param {(broadcast: {channel: string, params: Record<string, ?>, body: ?}) => Promise<void>} [args.broadcaster] - Delivers declarative broadcasts. Required when broadcasts are configured.
|
|
41
|
+
* @param {SyncReplayBroadcast[]} [args.broadcasts] - Broadcasts fanned out by the default afterReplayMutation.
|
|
25
42
|
*/
|
|
26
43
|
constructor(args = {}) {
|
|
27
44
|
this.logger = args.logger || console;
|
|
28
45
|
this.syncModel = args.syncModel || null;
|
|
29
46
|
this.actorForeignKeyColumn = args.actorForeignKeyColumn || "authentication_token_id";
|
|
47
|
+
this.authenticationTokenModel = args.authenticationTokenModel || null;
|
|
48
|
+
this.authenticationTokenColumn = args.authenticationTokenColumn || "token";
|
|
49
|
+
this.authenticationTokenParam = args.authenticationTokenParam || "authenticationToken";
|
|
50
|
+
this.persistExtraAttributes = args.persistExtraAttributes || null;
|
|
51
|
+
this.persistSerializedData = args.persistSerializedData || null;
|
|
52
|
+
this.broadcaster = args.broadcaster || null;
|
|
53
|
+
this.broadcasts = args.broadcasts || null;
|
|
54
|
+
this.applyHandlers = args.applyHandlers ? this.builtApplyHandlers(args.applyHandlers) : null;
|
|
30
55
|
if (args.actorForeignKeyColumn !== undefined && (typeof args.actorForeignKeyColumn !== "string" || args.actorForeignKeyColumn.length < 1)) {
|
|
31
56
|
throw new Error(`actorForeignKeyColumn must be a non-blank string, got: ${String(args.actorForeignKeyColumn)}`);
|
|
32
57
|
}
|
|
58
|
+
if (this.broadcasts && !this.broadcaster) {
|
|
59
|
+
throw new Error("SyncEnvelopeReplayService broadcasts require a broadcaster option delivering them");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Wraps declarative apply-handler specs in upsert appliers.
|
|
64
|
+
* @param {Record<string, ?>} applyHandlers - Raw apply handlers.
|
|
65
|
+
* @returns {Record<string, (args: Record<string, ?>) => Promise<?>>} Callable handlers by resource type.
|
|
66
|
+
*/
|
|
67
|
+
builtApplyHandlers(applyHandlers) {
|
|
68
|
+
return Object.fromEntries(Object.entries(applyHandlers).map(([resourceType, handler]) => {
|
|
69
|
+
if (typeof handler === "function")
|
|
70
|
+
return [resourceType, handler];
|
|
71
|
+
const applier = new SyncReplayUpsertApplier(handler);
|
|
72
|
+
return [resourceType, (/** @type {Record<string, ?>} */ applyArgs) => applier.apply(/** @type {?} */ (applyArgs))];
|
|
73
|
+
}));
|
|
33
74
|
}
|
|
34
75
|
/**
|
|
35
76
|
* Replays a sync batch.
|
|
@@ -77,11 +118,25 @@ export default class SyncEnvelopeReplayService {
|
|
|
77
118
|
}
|
|
78
119
|
/**
|
|
79
120
|
* Authenticates the sync batch actor.
|
|
80
|
-
*
|
|
121
|
+
*
|
|
122
|
+
* Defaults to a token-model lookup when `authenticationTokenModel` is
|
|
123
|
+
* configured; otherwise apps override this hook.
|
|
124
|
+
* @param {Record<string, ?>} params - Request params.
|
|
81
125
|
* @returns {Promise<{authenticated: true, actor: ?} | {authenticated: false, errorCode: string, errorMessage: string}>} Auth result.
|
|
82
126
|
*/
|
|
83
|
-
async authenticateReplay(
|
|
84
|
-
|
|
127
|
+
async authenticateReplay(params) {
|
|
128
|
+
if (!this.authenticationTokenModel) {
|
|
129
|
+
throw new Error("SyncEnvelopeReplayService.authenticateReplay must be implemented (or configure authenticationTokenModel)");
|
|
130
|
+
}
|
|
131
|
+
const token = params[this.authenticationTokenParam];
|
|
132
|
+
if (!token) {
|
|
133
|
+
return { authenticated: false, errorCode: "missing-authentication-token", errorMessage: "Missing authentication token" };
|
|
134
|
+
}
|
|
135
|
+
const actor = await this.authenticationTokenModel.findBy({ [this.authenticationTokenColumn]: token });
|
|
136
|
+
if (!actor) {
|
|
137
|
+
return { authenticated: false, errorCode: "invalid-authentication-token", errorMessage: "Invalid authentication token" };
|
|
138
|
+
}
|
|
139
|
+
return { actor, authenticated: true };
|
|
85
140
|
}
|
|
86
141
|
/**
|
|
87
142
|
* Builds per-batch mutable context for caches shared across sync items.
|
|
@@ -223,11 +278,19 @@ export default class SyncEnvelopeReplayService {
|
|
|
223
278
|
}
|
|
224
279
|
/**
|
|
225
280
|
* Applies one normalized mutation to domain models.
|
|
226
|
-
*
|
|
281
|
+
*
|
|
282
|
+
* Defaults to dispatching through the configured apply-handler registry;
|
|
283
|
+
* mutations without a registered handler fail loudly.
|
|
284
|
+
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
|
|
227
285
|
* @returns {Promise<?>} Project-specific apply result.
|
|
228
286
|
*/
|
|
229
|
-
async applyReplayMutation(
|
|
230
|
-
|
|
287
|
+
async applyReplayMutation(args) {
|
|
288
|
+
if (!this.applyHandlers)
|
|
289
|
+
return null;
|
|
290
|
+
const applyHandler = this.applyHandlers[args.mutation.resourceType];
|
|
291
|
+
if (!applyHandler)
|
|
292
|
+
throw new Error(`No sync apply handler registered for: ${args.mutation.resourceType}`);
|
|
293
|
+
return await applyHandler(args);
|
|
231
294
|
}
|
|
232
295
|
/**
|
|
233
296
|
* Resolves an apply result for stale mutations that should not touch domain models.
|
|
@@ -245,10 +308,21 @@ export default class SyncEnvelopeReplayService {
|
|
|
245
308
|
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay persistence arguments.
|
|
246
309
|
* @returns {Promise<void>}
|
|
247
310
|
*/
|
|
248
|
-
async persistReplayMutation({ actor, existingSync, mutation }) {
|
|
311
|
+
async persistReplayMutation({ actor, applyResult, context, existingSync, mutation, shouldApply }) {
|
|
249
312
|
if (!this.syncModel)
|
|
250
313
|
return;
|
|
251
314
|
const attributes = this.replayPersistAttributes({ actor, mutation });
|
|
315
|
+
// Stale replays never applied anything, so the applyResult-driven extension
|
|
316
|
+
// hooks must not run against the default null skipped result.
|
|
317
|
+
if (this.persistExtraAttributes && shouldApply) {
|
|
318
|
+
Object.assign(attributes, this.persistExtraAttributes({ actor, applyResult, context, existingSync, mutation, shouldApply }));
|
|
319
|
+
}
|
|
320
|
+
if (this.persistSerializedData && shouldApply) {
|
|
321
|
+
const serializedData = this.persistSerializedData({ applyResult, mutation });
|
|
322
|
+
if (serializedData !== undefined && serializedData !== null) {
|
|
323
|
+
attributes.data = typeof serializedData === "string" ? serializedData : JSON.stringify(serializedData);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
252
326
|
if (existingSync) {
|
|
253
327
|
const existingClientUpdatedAt = this.existingReplaySyncClientUpdatedAt(existingSync);
|
|
254
328
|
if (existingClientUpdatedAt && mutation.clientUpdatedAt <= existingClientUpdatedAt)
|
|
@@ -278,10 +352,29 @@ export default class SyncEnvelopeReplayService {
|
|
|
278
352
|
}
|
|
279
353
|
/**
|
|
280
354
|
* Runs side effects after a successful mutation replay and persistence.
|
|
281
|
-
*
|
|
355
|
+
*
|
|
356
|
+
* Defaults to fanning the applied result out through the configured
|
|
357
|
+
* declarative broadcasts.
|
|
358
|
+
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, applyResult: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, shouldApply: boolean}} args - Replay side-effect arguments.
|
|
282
359
|
* @returns {Promise<void>}
|
|
283
360
|
*/
|
|
284
|
-
async afterReplayMutation(
|
|
361
|
+
async afterReplayMutation(args) {
|
|
362
|
+
if (!this.broadcasts || !this.broadcaster)
|
|
363
|
+
return;
|
|
364
|
+
// Stale replays never applied anything - broadcasting their skipped results
|
|
365
|
+
// would fan out stale side effects (or crash on the default null applyResult).
|
|
366
|
+
if (!args.shouldApply)
|
|
367
|
+
return;
|
|
368
|
+
for (const broadcast of this.broadcasts) {
|
|
369
|
+
if (broadcast.when && !broadcast.when(args))
|
|
370
|
+
continue;
|
|
371
|
+
await this.broadcaster({
|
|
372
|
+
body: broadcast.body(args),
|
|
373
|
+
channel: typeof broadcast.channel === "function" ? broadcast.channel(args) : broadcast.channel,
|
|
374
|
+
params: broadcast.broadcastParams(args)
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
285
378
|
}
|
|
286
379
|
/**
|
|
287
380
|
* @typedef {object} SyncReplayMutation
|
|
@@ -293,4 +386,4 @@ export default class SyncEnvelopeReplayService {
|
|
|
293
386
|
* @property {string} serializedData - JSON serialized mutation payload.
|
|
294
387
|
* @property {string} syncType - Sync operation type.
|
|
295
388
|
*/
|
|
296
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILFlBQVksSUFBSSxHQUFHLEVBQUU7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQTtRQUNwQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFBO1FBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMscUJBQXFCLElBQUkseUJBQXlCLENBQUE7UUFFcEYsSUFBSSxJQUFJLENBQUMscUJBQXFCLEtBQUssU0FBUyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMscUJBQXFCLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMxSSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxNQUFNLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2pILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTTtRQUNqQixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUV6RCxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQy9CLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsU0FBUyxFQUFFLFdBQVcsQ0FB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QUksdUJBQXVCO2dCQUFFLE9BQU07WUFFMUYsWUFBWSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUMvQixNQUFNLFlBQVksQ0FBQyxxQkFBcUIsRUFBRSxDQUFBO1lBQzFDLE1BQU0sWUFBWSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQzNCLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN6QyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCx1QkFBdUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUM7UUFDdkMsT0FBTztZQUNMLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7WUFDdkQsaUJBQWlCLEVBQUUsUUFBUSxDQUFDLGVBQWU7WUFDM0MsSUFBSSxFQUFFLFFBQVEsQ0FBQyxjQUFjO1lBQzdCLFdBQVcsRUFBRSxRQUFRLENBQUMsVUFBVTtZQUNoQyxhQUFhLEVBQUUsUUFBUSxDQUFDLFlBQVk7WUFDcEMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxRQUFRO1NBQzdCLENBQUE7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLElBQUcsQ0FBQztDQUNwQztBQUVEOzs7Ozs7Ozs7R0FTRyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG4vKipcbiAqIFJlcGxheXMgY2xpZW50IHN5bmMgZW52ZWxvcGVzIHRocm91Z2ggcHJvamVjdCBzdXBwbGllZCBhdXRoZW50aWNhdGlvbixcbiAqIGF1dGhvcml6YXRpb24sIGFwcGxpY2F0aW9uLCBhbmQgcGVyc2lzdGVuY2UgaG9va3MuXG4gKlxuICogVGhpcyBpcyBpbnRlbnRpb25hbGx5IHRyYW5zcG9ydC9tb2RlbCBhZ25vc3RpYzogVmVsb2Npb3VzIG93bnMgdGhlIGdlbmVyaWNcbiAqIHJlcGxheSBsb29wLCBub3JtYWxpemF0aW9uLCBzdGFsZS1jbGllbnQgY29tcGFyaXNvbiwgYW5kIHBlci1zeW5jIHJlc3VsdFxuICogc2hhcGUgd2hpbGUgZWFjaCBhcHAgb3ducyBpdHMgdG9rZW4gbG9va3VwLCBtb2RlbCBoYW5kbGVycywgYW5kXG4gKiBkb21haW4gYXV0aG9yaXphdGlvbiBydWxlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc3luYyBlbnZlbG9wZSByZXBsYXkgc2VydmljZS5cbiAgICpcbiAgICogV2hlbiBhIHN5bmMgbW9kZWwgaXMgZ2l2ZW4sIGBmaW5kRXhpc3RpbmdSZXBsYXlTeW5jYCBhbmRcbiAgICogYHBlcnNpc3RSZXBsYXlNdXRhdGlvbmAgZ2V0IG1vZGVsLWJhY2tlZCBkZWZhdWx0IGltcGxlbWVudGF0aW9ucy4gVGhlIHN5bmNcbiAgICogbW9kZWwgbXVzdCBleHBvc2UgYGZpbmRCeWAvYGNyZWF0ZWAgc3RhdGljcyBwbHVzIGluc3RhbmNlXG4gICAqIGBhc3NpZ25gL2BzYXZlYC9gY2xpZW50VXBkYXRlZEF0YCBhbmQgYGFkdmFuY2VTZXJ2ZXJTZXF1ZW5jZWAgKHRoZVxuICAgKiBjaGFuZ2UtZmVlZCBzZXF1ZW5jZSBjb250cmFjdCksIGFuZCB0aGUgYWN0b3IgcmV0dXJuZWQgZnJvbVxuICAgKiBgYXV0aGVudGljYXRlUmVwbGF5YCBtdXN0IGV4cG9zZSBhbiBgaWQoKWAgbWV0aG9kLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge3tkZWJ1Zz86ICguLi5hcmdzOiBBcnJheTx1bmtub3duPikgPT4gdm9pZCwgd2Fybj86ICguLi5hcmdzOiBBcnJheTx1bmtub3duPikgPT4gdm9pZH19IFthcmdzLmxvZ2dlcl0gLSBMb2dnZXIgdXNlZCBmb3Igbm9ybWFsaXphdGlvbiB3YXJuaW5ncy5cbiAgICogQHBhcmFtIHs/fSBbYXJncy5zeW5jTW9kZWxdIC0gU3luYy9jaGFuZ2UgbW9kZWwgZW5hYmxpbmcgbW9kZWwtYmFja2VkIGRlZmF1bHQgaG9va3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dIC0gU3luYyBtb2RlbCBjb2x1bW4gbGlua2luZyByb3dzIHRvIHRoZSByZXBsYXkgYWN0b3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhcmdzID0ge30pIHtcbiAgICB0aGlzLmxvZ2dlciA9IGFyZ3MubG9nZ2VyIHx8IGNvbnNvbGVcbiAgICB0aGlzLnN5bmNNb2RlbCA9IGFyZ3Muc3luY01vZGVsIHx8IG51bGxcbiAgICB0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbiA9IGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uIHx8IFwiYXV0aGVudGljYXRpb25fdG9rZW5faWRcIlxuXG4gICAgaWYgKGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uICE9PSB1bmRlZmluZWQgJiYgKHR5cGVvZiBhcmdzLmFjdG9yRm9yZWlnbktleUNvbHVtbiAhPT0gXCJzdHJpbmdcIiB8fCBhcmdzLmFjdG9yRm9yZWlnbktleUNvbHVtbi5sZW5ndGggPCAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBhY3RvckZvcmVpZ25LZXlDb2x1bW4gbXVzdCBiZSBhIG5vbi1ibGFuayBzdHJpbmcsIGdvdDogJHtTdHJpbmcoYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4pfWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxheXMgYSBzeW5jIGJhdGNoLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcyBjYXJyeWluZyBhdXRoZW50aWNhdGlvbiBhbmQgc3luY3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHtzeW5jczogQXJyYXk8UmVjb3JkPHN0cmluZywgPz4+LCBzdGF0dXM/OiBzdHJpbmcsIGVycm9yQ29kZT86IHN0cmluZywgZXJyb3JNZXNzYWdlPzogc3RyaW5nfT59IFJlcGxheSByZXNwb25zZS5cbiAgICovXG4gIGFzeW5jIHJlcGxheShwYXJhbXMpIHtcbiAgICBjb25zdCBhY3RvclJlc3VsdCA9IGF3YWl0IHRoaXMuYXV0aGVudGljYXRlUmVwbGF5KHBhcmFtcylcblxuICAgIGlmICghYWN0b3JSZXN1bHQuYXV0aGVudGljYXRlZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3luY3M6IFtdLFxuICAgICAgICBzdGF0dXM6IFwiZXJyb3JcIixcbiAgICAgICAgZXJyb3JDb2RlOiBhY3RvclJlc3VsdC5lcnJvckNvZGUsXG4gICAgICAgIGVycm9yTWVzc2FnZTogYWN0b3JSZXN1bHQuZXJyb3JNZXNzYWdlXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3luY1Jlc3BvbnNlcyA9IFtdXG4gICAgY29uc3QgY29udGV4dCA9IGF3YWl0IHRoaXMuYnVpbGRSZXBsYXlDb250ZXh0KHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIHBhcmFtc30pXG5cbiAgICBmb3IgKGNvbnN0IHJhd1N5bmMgb2YgdGhpcy5yZXBsYXlTeW5jcyhwYXJhbXMpKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkUmVzdWx0ID0gdGhpcy5ub3JtYWxpemVSZXBsYXlTeW5jKHJhd1N5bmMpXG5cbiAgICAgIGlmICghbm9ybWFsaXplZFJlc3VsdC5vaykge1xuICAgICAgICBzeW5jUmVzcG9uc2VzLnB1c2gobm9ybWFsaXplZFJlc3VsdC5yZXNwb25zZSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgbXV0YXRpb24gPSBub3JtYWxpemVkUmVzdWx0Lm11dGF0aW9uXG4gICAgICBjb25zdCBhY2Nlc3NSZXN1bHQgPSBhd2FpdCB0aGlzLmF1dGhvcml6ZVJlcGxheU11dGF0aW9uKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIG11dGF0aW9ufSlcblxuICAgICAgaWYgKCFhY2Nlc3NSZXN1bHQuYWxsb3dlZCkge1xuICAgICAgICBzeW5jUmVzcG9uc2VzLnB1c2goe1xuICAgICAgICAgIGlkOiBtdXRhdGlvbi5pZCxcbiAgICAgICAgICBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsXG4gICAgICAgICAgcmVhc29uOiBhY2Nlc3NSZXN1bHQucmVhc29uIHx8IFwiYWNjZXNzLWRlbmllZFwiXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4aXN0aW5nU3luYyA9IGF3YWl0IHRoaXMuZmluZEV4aXN0aW5nUmVwbGF5U3luYyh7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBtdXRhdGlvbn0pXG4gICAgICBjb25zdCBzaG91bGRBcHBseSA9IGF3YWl0IHRoaXMuc2hvdWxkQXBwbHlSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcbiAgICAgIGNvbnN0IGFwcGx5UmVzdWx0ID0gc2hvdWxkQXBwbHlcbiAgICAgICAgPyBhd2FpdCB0aGlzLmFwcGx5UmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pXG4gICAgICAgIDogYXdhaXQgdGhpcy5za2lwcGVkUmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pXG5cbiAgICAgIGF3YWl0IHRoaXMucGVyc2lzdFJlcGxheU11dGF0aW9uKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgYXBwbHlSZXN1bHQsIG11dGF0aW9uLCBzaG91bGRBcHBseX0pXG4gICAgICBhd2FpdCB0aGlzLmFmdGVyUmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBhcHBseVJlc3VsdCwgbXV0YXRpb24sIHNob3VsZEFwcGx5fSlcblxuICAgICAgc3luY1Jlc3BvbnNlcy5wdXNoKHtpZDogbXV0YXRpb24uaWQsIHN5bmNTdGF0ZTogXCJzdWNjZXNzZnVsXCJ9KVxuICAgIH1cblxuICAgIHJldHVybiB7c3luY3M6IHN5bmNSZXNwb25zZXN9XG4gIH1cblxuICAvKipcbiAgICogQXV0aGVudGljYXRlcyB0aGUgc3luYyBiYXRjaCBhY3Rvci5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gX3BhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7YXV0aGVudGljYXRlZDogdHJ1ZSwgYWN0b3I6ID99IHwge2F1dGhlbnRpY2F0ZWQ6IGZhbHNlLCBlcnJvckNvZGU6IHN0cmluZywgZXJyb3JNZXNzYWdlOiBzdHJpbmd9Pn0gQXV0aCByZXN1bHQuXG4gICAqL1xuICBhc3luYyBhdXRoZW50aWNhdGVSZXBsYXkoX3BhcmFtcykge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2UuYXV0aGVudGljYXRlUmVwbGF5IG11c3QgYmUgaW1wbGVtZW50ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgcGVyLWJhdGNoIG11dGFibGUgY29udGV4dCBmb3IgY2FjaGVzIHNoYXJlZCBhY3Jvc3Mgc3luYyBpdGVtcy5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIHBhcmFtczogUmVjb3JkPHN0cmluZywgPz59fSBfYXJncyAtIEFjdG9yIGFuZCByZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBSZXBsYXkgY29udGV4dC5cbiAgICovXG4gIGFzeW5jIGJ1aWxkUmVwbGF5Q29udGV4dChfYXJncykge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcmF3IHN5bmMgZW50cmllcyBmcm9tIHJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge0FycmF5PD8+fSBSYXcgc3luYyBlbnRyaWVzLlxuICAgKi9cbiAgcmVwbGF5U3luY3MocGFyYW1zKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocGFyYW1zLnN5bmNzKSA/IHBhcmFtcy5zeW5jcyA6IFtdXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBvbmUgc3luYyBlbnRyeS5cbiAgICogQHBhcmFtIHs/fSByYXdTeW5jIC0gUmF3IHN5bmMgZW50cnkuXG4gICAqIEByZXR1cm5zIHt7b2s6IHRydWUsIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSB8IHtvazogZmFsc2UsIHJlc3BvbnNlOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IE5vcm1hbGl6ZWQgbXV0YXRpb24gb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luYyhyYXdTeW5jKSB7XG4gICAgaWYgKCFyYXdTeW5jIHx8IHR5cGVvZiByYXdTeW5jICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocmF3U3luYykpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkOiB1bmRlZmluZWQsIHN5bmNTdGF0ZTogXCJmYWlsZWRcIiwgcmVhc29uOiBcImludmFsaWQtc3luY1wifX1cbiAgICB9XG5cbiAgICBjb25zdCBzeW5jID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHJhd1N5bmMpXG4gICAgY29uc3Qge2NsaWVudFVwZGF0ZWRBdCwgZGF0YSwgaWQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZSwgc3luY1R5cGV9ID0gc3luY1xuXG4gICAgaWYgKHR5cGVvZiByZXNvdXJjZVR5cGUgIT09IFwic3RyaW5nXCIgfHwgcmVzb3VyY2VUeXBlLmxlbmd0aCA8IDEgfHwgcmVzb3VyY2VJZCA9PT0gdW5kZWZpbmVkIHx8IHJlc291cmNlSWQgPT09IG51bGwgfHwgdHlwZW9mIHN5bmNUeXBlICE9PSBcInN0cmluZ1wiIHx8IHN5bmNUeXBlLmxlbmd0aCA8IDEpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkLCBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsIHJlYXNvbjogXCJpbnZhbGlkLXJlc291cmNlLWlkXCJ9fVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlSWRTdHJpbmcgPSBTdHJpbmcocmVzb3VyY2VJZClcbiAgICBsZXQgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IHR5cGVvZiBjbGllbnRVcGRhdGVkQXQgPT09IFwic3RyaW5nXCIgfHwgY2xpZW50VXBkYXRlZEF0IGluc3RhbmNlb2YgRGF0ZSA/IG5ldyBEYXRlKGNsaWVudFVwZGF0ZWRBdCkgOiBuZXcgRGF0ZSgpXG5cbiAgICBpZiAoTnVtYmVyLmlzTmFOKGNsaWVudFVwZGF0ZWRBdERhdGUuZ2V0VGltZSgpKSkgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IG5ldyBEYXRlKClcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWREYXRhUmVzdWx0ID0gdGhpcy5ub3JtYWxpemVSZXBsYXlTeW5jRGF0YSh7ZGF0YSwgaWQsIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsIHJlc291cmNlVHlwZX0pXG5cbiAgICBpZiAoIW5vcm1hbGl6ZWREYXRhUmVzdWx0Lm9rKSByZXR1cm4gbm9ybWFsaXplZERhdGFSZXN1bHRcblxuICAgIHJldHVybiB7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIG11dGF0aW9uOiB7XG4gICAgICAgIGNsaWVudFVwZGF0ZWRBdDogY2xpZW50VXBkYXRlZEF0RGF0ZSxcbiAgICAgICAgZGF0YTogbm9ybWFsaXplZERhdGFSZXN1bHQuZGF0YSxcbiAgICAgICAgaWQsXG4gICAgICAgIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsXG4gICAgICAgIHJlc291cmNlVHlwZSxcbiAgICAgICAgc2VyaWFsaXplZERhdGE6IEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWREYXRhUmVzdWx0LmRhdGEpLFxuICAgICAgICBzeW5jVHlwZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIG9uZSBzeW5jIGRhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHt7ZGF0YTogPywgaWQ6ID8sIHJlc291cmNlSWQ6IHN0cmluZywgcmVzb3VyY2VUeXBlOiBzdHJpbmd9fSBhcmdzIC0gU3luYyBwYXlsb2FkIG5vcm1hbGl6YXRpb24gYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7e29rOiB0cnVlLCBkYXRhOiBSZWNvcmQ8c3RyaW5nLCA/Pn0gfCB7b2s6IGZhbHNlLCByZXNwb25zZTogUmVjb3JkPHN0cmluZywgPz59fSBOb3JtYWxpemVkIHBheWxvYWQgb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luY0RhdGEoe2RhdGEsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KSB7XG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCB8fCBkYXRhID09PSBudWxsKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoZGF0YSlcblxuICAgICAgICBpZiAoIXBhcnNlZERhdGEgfHwgdHlwZW9mIHBhcnNlZERhdGEgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShwYXJzZWREYXRhKSkgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YToge319XG5cbiAgICAgICAgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YTogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHBhcnNlZERhdGEpfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2Fybj8uKFwiSW52YWxpZCBzeW5jIGRhdGEgSlNPTlwiLCB7ZXJyb3IsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KVxuICAgICAgICByZXR1cm4ge29rOiBmYWxzZSwgcmVzcG9uc2U6IHtpZCwgc3luY1N0YXRlOiBcImZhaWxlZFwiLCByZWFzb246IFwiaW52YWxpZC1kYXRhXCJ9fVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGRhdGEpKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIHJldHVybiB7b2s6IHRydWUsIGRhdGE6IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpfVxuICB9XG5cbiAgLyoqXG4gICAqIEF1dGhvcml6ZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBfYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthbGxvd2VkOiBib29sZWFuLCByZWFzb24/OiBzdHJpbmd9Pn0gQWNjZXNzIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhvcml6ZVJlcGxheU11dGF0aW9uKF9hcmdzKSB7XG4gICAgcmV0dXJuIHthbGxvd2VkOiB0cnVlfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBwcmV2aW91c2x5IHN0b3JlZCBzeW5jL2NoYW5nZSByb3cgZm9yIHN0YWxlLWNsaWVudCBjb21wYXJpc29uLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHN5bmMtbW9kZWwgbG9va3VwIGJ5IGFjdG9yIGFuZCByZXNvdXJjZSBpZGVudGl0eSB3aGVuIGEgc3luY1xuICAgKiBtb2RlbCBpcyBjb25maWd1cmVkOyBvdGhlcndpc2UgYXBwcyBvdmVycmlkZSB0aGlzIGhvb2suXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKi9cbiAgYXN5bmMgZmluZEV4aXN0aW5nUmVwbGF5U3luYyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIGlmICghdGhpcy5zeW5jTW9kZWwpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zeW5jTW9kZWwuZmluZEJ5KHtcbiAgICAgIFt0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbl06IHRoaXMucmVwbGF5QWN0b3JJZChhY3RvciksXG4gICAgICByZXNvdXJjZV9pZDogbXV0YXRpb24ucmVzb3VyY2VJZCxcbiAgICAgIHJlc291cmNlX3R5cGU6IG11dGF0aW9uLnJlc291cmNlVHlwZVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIHBlcnNpc3RlZCBhY3RvciBpZCB1c2VkIGJ5IG1vZGVsLWJhY2tlZCBkZWZhdWx0IGhvb2tzLlxuICAgKiBAcGFyYW0gez99IGFjdG9yIC0gQWN0b3IgcmV0dXJuZWQgZnJvbSBhdXRoZW50aWNhdGVSZXBsYXkuXG4gICAqIEByZXR1cm5zIHs/fSBBY3RvciBpZC5cbiAgICovXG4gIHJlcGxheUFjdG9ySWQoYWN0b3IpIHtcbiAgICBpZiAoIWFjdG9yIHx8IHR5cGVvZiBhY3RvciAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYWN0b3IuaWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSBtb2RlbC1iYWNrZWQgZGVmYXVsdHMgcmVxdWlyZSBhbiBhY3RvciB3aXRoIGFuIGlkKCkgbWV0aG9kIGZyb20gYXV0aGVudGljYXRlUmVwbGF5XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIGFjdG9yLmlkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgYSBub3JtYWxpemVkIG11dGF0aW9uIHNob3VsZCBiZSBhcHBsaWVkIHRvIGRvbWFpbiBtb2RlbHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IGFyZ3MgLSBBY3RvciwgYmF0Y2ggY29udGV4dCwgZXhpc3Rpbmcgc3luYyByb3csIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdG8gYXBwbHkgdGhlIG11dGF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc2hvdWxkQXBwbHlSZXBsYXlNdXRhdGlvbih7ZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pIHtcbiAgICBjb25zdCBleGlzdGluZ0NsaWVudFVwZGF0ZWRBdCA9IHRoaXMuZXhpc3RpbmdSZXBsYXlTeW5jQ2xpZW50VXBkYXRlZEF0KGV4aXN0aW5nU3luYylcblxuICAgIHJldHVybiAhZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgfHwgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0ID4gZXhpc3RpbmdDbGllbnRVcGRhdGVkQXRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgY2xpZW50IHRpbWVzdGFtcCBmcm9tIGFuIGV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcGFyYW0gez99IGV4aXN0aW5nU3luYyAtIEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcmV0dXJucyB7RGF0ZSB8IG51bGx9IEV4aXN0aW5nIGNsaWVudCB0aW1lc3RhbXAuXG4gICAqL1xuICBleGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKSB7XG4gICAgaWYgKCFleGlzdGluZ1N5bmMgfHwgdHlwZW9mIGV4aXN0aW5nU3luYyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHN5bmNSZWNvcmQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoZXhpc3RpbmdTeW5jKVxuICAgIGNvbnN0IHZhbHVlID0gdHlwZW9mIHN5bmNSZWNvcmQuY2xpZW50VXBkYXRlZEF0ID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gc3luY1JlY29yZC5jbGllbnRVcGRhdGVkQXQoKVxuICAgICAgOiBzeW5jUmVjb3JkLmNsaWVudFVwZGF0ZWRBdFxuXG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIHZhbHVlXG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSlcblxuICAgIHJldHVybiBOdW1iZXIuaXNOYU4ocGFyc2VkVmFsdWUuZ2V0VGltZSgpKSA/IG51bGwgOiBwYXJzZWRWYWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24gdG8gZG9tYWluIG1vZGVscy5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufX0gX2FyZ3MgLSBBY3RvciwgYmF0Y2ggY29udGV4dCwgZXhpc3Rpbmcgc3luYyByb3csIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IFByb2plY3Qtc3BlY2lmaWMgYXBwbHkgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgYXBwbHlSZXBsYXlNdXRhdGlvbihfYXJncykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYW4gYXBwbHkgcmVzdWx0IGZvciBzdGFsZSBtdXRhdGlvbnMgdGhhdCBzaG91bGQgbm90IHRvdWNoIGRvbWFpbiBtb2RlbHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IF9hcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGV4aXN0aW5nIHN5bmMgcm93LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPD8+fSBQcm9qZWN0LXNwZWNpZmljIGFwcGx5IHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHNraXBwZWRSZXBsYXlNdXRhdGlvbihfYXJncykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogUGVyc2lzdHMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24gaW50byB0aGUgYXBwIHN5bmMvY2hhbmdlIHN0b3JlLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHN0YWxlLWd1YXJkZWQgc3luYy1tb2RlbCB1cHNlcnQgKHdpdGggc2VydmVyIHJlLXNlcXVlbmNpbmcgb25cbiAgICogdXBkYXRlcykgd2hlbiBhIHN5bmMgbW9kZWwgaXMgY29uZmlndXJlZDsgb3RoZXJ3aXNlIGFwcHMgb3ZlcnJpZGUgdGhpcyBob29rLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgYXBwbHlSZXN1bHQ6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9uLCBzaG91bGRBcHBseTogYm9vbGVhbn19IGFyZ3MgLSBSZXBsYXkgcGVyc2lzdGVuY2UgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHBlcnNpc3RSZXBsYXlNdXRhdGlvbih7YWN0b3IsIGV4aXN0aW5nU3luYywgbXV0YXRpb259KSB7XG4gICAgaWYgKCF0aGlzLnN5bmNNb2RlbCkgcmV0dXJuXG5cbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gdGhpcy5yZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSlcblxuICAgIGlmIChleGlzdGluZ1N5bmMpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0ID0gdGhpcy5leGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKVxuXG4gICAgICBpZiAoZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgJiYgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0IDw9IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0KSByZXR1cm5cblxuICAgICAgZXhpc3RpbmdTeW5jLmFzc2lnbihhdHRyaWJ1dGVzKVxuICAgICAgYXdhaXQgZXhpc3RpbmdTeW5jLmFkdmFuY2VTZXJ2ZXJTZXF1ZW5jZSgpXG4gICAgICBhd2FpdCBleGlzdGluZ1N5bmMuc2F2ZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY01vZGVsLmNyZWF0ZShhdHRyaWJ1dGVzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHN5bmMtbW9kZWwgYXR0cmlidXRlcyBwZXJzaXN0ZWQgYnkgdGhlIG1vZGVsLWJhY2tlZCBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IFN5bmMgcm93IGF0dHJpYnV0ZXMuXG4gICAqL1xuICByZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIHJldHVybiB7XG4gICAgICBbdGhpcy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dOiB0aGlzLnJlcGxheUFjdG9ySWQoYWN0b3IpLFxuICAgICAgY2xpZW50X3VwZGF0ZWRfYXQ6IG11dGF0aW9uLmNsaWVudFVwZGF0ZWRBdCxcbiAgICAgIGRhdGE6IG11dGF0aW9uLnNlcmlhbGl6ZWREYXRhLFxuICAgICAgcmVzb3VyY2VfaWQ6IG11dGF0aW9uLnJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZV90eXBlOiBtdXRhdGlvbi5yZXNvdXJjZVR5cGUsXG4gICAgICBzeW5jX3R5cGU6IG11dGF0aW9uLnN5bmNUeXBlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2lkZSBlZmZlY3RzIGFmdGVyIGEgc3VjY2Vzc2Z1bCBtdXRhdGlvbiByZXBsYXkgYW5kIHBlcnNpc3RlbmNlLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgYXBwbHlSZXN1bHQ6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9uLCBzaG91bGRBcHBseTogYm9vbGVhbn19IF9hcmdzIC0gUmVwbGF5IHNpZGUtZWZmZWN0IGFyZ3VtZW50cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBhZnRlclJlcGxheU11dGF0aW9uKF9hcmdzKSB7fVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN5bmNSZXBsYXlNdXRhdGlvblxuICogQHByb3BlcnR5IHtEYXRlfSBjbGllbnRVcGRhdGVkQXQgLSBDbGllbnQtc2lkZSBtdXRhdGlvbiB0aW1lc3RhbXAuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsID8+fSBkYXRhIC0gUGFyc2VkIG11dGF0aW9uIHBheWxvYWQuXG4gKiBAcHJvcGVydHkgez99IGlkIC0gQ2xpZW50IHN5bmMgcm93IGlkIGZvciBwZXItc3luYyByZXNwb25zZXMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVzb3VyY2VJZCAtIFJlc291cmNlIGlkIGFzIGEgc3RyaW5nLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJlc291cmNlVHlwZSAtIFJlc291cmNlL21vZGVsIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VyaWFsaXplZERhdGEgLSBKU09OIHNlcmlhbGl6ZWQgbXV0YXRpb24gcGF5bG9hZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzeW5jVHlwZSAtIFN5bmMgb3BlcmF0aW9uIHR5cGUuXG4gKi9cbiJdfQ==
|
|
389
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sdUJBQXVCLE1BQU0saUNBQWlDLENBQUE7QUFFckU7Ozs7Ozs7R0FPRztBQUVIOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNILFlBQVksSUFBSSxHQUFHLEVBQUU7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQTtRQUNwQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFBO1FBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMscUJBQXFCLElBQUkseUJBQXlCLENBQUE7UUFDcEYsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxJQUFJLENBQUE7UUFDckUsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxPQUFPLENBQUE7UUFDMUUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxxQkFBcUIsQ0FBQTtRQUN0RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixJQUFJLElBQUksQ0FBQTtRQUNqRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixJQUFJLElBQUksQ0FBQTtRQUMvRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFBO1FBQzNDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFB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QUFDLENBQUE7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7OztHQVNHIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBTeW5jUmVwbGF5VXBzZXJ0QXBwbGllciBmcm9tIFwiLi9zeW5jLXJlcGxheS11cHNlcnQtYXBwbGllci5qc1wiXG5cbi8qKlxuICogT25lIGRlY2xhcmF0aXZlIGJyb2FkY2FzdCBmYW5uZWQgb3V0IGFmdGVyIGEgbXV0YXRpb24gYXBwbGllcy5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN5bmNSZXBsYXlCcm9hZGNhc3RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgKChhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gc3RyaW5nKX0gY2hhbm5lbCAtIENoYW5uZWwgbmFtZSBvciByZXNvbHZlci5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBSZWNvcmQ8c3RyaW5nLCA/Pn0gYnJvYWRjYXN0UGFyYW1zIC0gQ2hhbm5lbCByb3V0aW5nIHBhcmFtcy5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiA/fSBib2R5IC0gQnJvYWRjYXN0IGJvZHkuXG4gKiBAcHJvcGVydHkgeyhhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gYm9vbGVhbn0gW3doZW5dIC0gT3B0aW9uYWwgZ2F0ZTsgc2tpcHBlZCB3aGVuIGl0IHJldHVybnMgZmFsc2UuXG4gKi9cblxuLyoqXG4gKiBSZXBsYXlzIGNsaWVudCBzeW5jIGVudmVsb3BlcyB0aHJvdWdoIHByb2plY3Qgc3VwcGxpZWQgYXV0aGVudGljYXRpb24sXG4gKiBhdXRob3JpemF0aW9uLCBhcHBsaWNhdGlvbiwgYW5kIHBlcnNpc3RlbmNlIGhvb2tzLlxuICpcbiAqIFRoaXMgaXMgaW50ZW50aW9uYWxseSB0cmFuc3BvcnQvbW9kZWwgYWdub3N0aWM6IFZlbG9jaW91cyBvd25zIHRoZSBnZW5lcmljXG4gKiByZXBsYXkgbG9vcCwgbm9ybWFsaXphdGlvbiwgc3RhbGUtY2xpZW50IGNvbXBhcmlzb24sIGFuZCBwZXItc3luYyByZXN1bHRcbiAqIHNoYXBlIHdoaWxlIGVhY2ggYXBwIG93bnMgaXRzIHRva2VuIGxvb2t1cCwgbW9kZWwgaGFuZGxlcnMsIGFuZFxuICogZG9tYWluIGF1dGhvcml6YXRpb24gcnVsZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2Uge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHN5bmMgZW52ZWxvcGUgcmVwbGF5IHNlcnZpY2UuXG4gICAqXG4gICAqIFdoZW4gYSBzeW5jIG1vZGVsIGlzIGdpdmVuLCBgZmluZEV4aXN0aW5nUmVwbGF5U3luY2AgYW5kXG4gICAqIGBwZXJzaXN0UmVwbGF5TXV0YXRpb25gIGdldCBtb2RlbC1iYWNrZWQgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMuIFRoZSBzeW5jXG4gICAqIG1vZGVsIG11c3QgZXhwb3NlIGBmaW5kQnlgL2BjcmVhdGVgIHN0YXRpY3MgcGx1cyBpbnN0YW5jZVxuICAgKiBgYXNzaWduYC9gc2F2ZWAvYGNsaWVudFVwZGF0ZWRBdGAgYW5kIGBhZHZhbmNlU2VydmVyU2VxdWVuY2VgICh0aGVcbiAgICogY2hhbmdlLWZlZWQgc2VxdWVuY2UgY29udHJhY3QpLCBhbmQgdGhlIGFjdG9yIHJldHVybmVkIGZyb21cbiAgICogYGF1dGhlbnRpY2F0ZVJlcGxheWAgbXVzdCBleHBvc2UgYW4gYGlkKClgIG1ldGhvZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIENvbnN0cnVjdG9yIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHt7ZGVidWc/OiAoLi4uYXJnczogQXJyYXk8dW5rbm93bj4pID0+IHZvaWQsIHdhcm4/OiAoLi4uYXJnczogQXJyYXk8dW5rbm93bj4pID0+IHZvaWR9fSBbYXJncy5sb2dnZXJdIC0gTG9nZ2VyIHVzZWQgZm9yIG5vcm1hbGl6YXRpb24gd2FybmluZ3MuXG4gICAqIEBwYXJhbSB7P30gW2FyZ3Muc3luY01vZGVsXSAtIFN5bmMvY2hhbmdlIG1vZGVsIGVuYWJsaW5nIG1vZGVsLWJhY2tlZCBkZWZhdWx0IGhvb2tzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uXSAtIFN5bmMgbW9kZWwgY29sdW1uIGxpbmtpbmcgcm93cyB0byB0aGUgcmVwbGF5IGFjdG9yLlxuICAgKiBAcGFyYW0gez99IFthcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5Nb2RlbF0gLSBUb2tlbiBtb2RlbCBlbmFibGluZyB0aGUgZGVmYXVsdCB0b2tlbi1sb29rdXAgYXV0aGVudGljYXRlUmVwbGF5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbl0gLSBUb2tlbiBtb2RlbCBjb2x1bW4gaG9sZGluZyB0aGUgdG9rZW4uIERlZmF1bHRzIHRvIFwidG9rZW5cIi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5QYXJhbV0gLSBSZXF1ZXN0IHBhcmFtIGNhcnJ5aW5nIHRoZSB0b2tlbi4gRGVmYXVsdHMgdG8gXCJhdXRoZW50aWNhdGlvblRva2VuXCIuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgKChhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gUHJvbWlzZTw/PikgfCBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFN5bmNSZXBsYXlVcHNlcnRBcHBsaWVyPlswXT59IFthcmdzLmFwcGx5SGFuZGxlcnNdIC0gUGVyLXJlc291cmNlVHlwZSBhcHBseSBoYW5kbGVycyAoZnVuY3Rpb25zIG9yIGRlY2xhcmF0aXZlIHVwc2VydC1hcHBsaWVyIHNwZWNzKSBlbmFibGluZyB0aGUgZGVmYXVsdCBhcHBseVJlcGxheU11dGF0aW9uIGRpc3BhdGNoLlxuICAgKiBAcGFyYW0geyhhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gUmVjb3JkPHN0cmluZywgPz59IFthcmdzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXNdIC0gRXh0cmEgYXR0cmlidXRlcyBtZXJnZWQgaW50byB0aGUgbW9kZWwtYmFja2VkIHBlcnNpc3RlZCByb3cgKGUuZy4gYW4gZXZlbnQgc2NvcGUgY29sdW1uKS5cbiAgICogQHBhcmFtIHsoYXJnczoge211dGF0aW9uOiA/LCBhcHBseVJlc3VsdDogP30pID0+ID99IFthcmdzLnBlcnNpc3RTZXJpYWxpemVkRGF0YV0gLSBPdmVycmlkZXMgdGhlIHBlcnNpc3RlZCBkYXRhIHBheWxvYWQgKG9iamVjdCByZXN1bHRzIGFyZSBKU09OIHN0cmluZ2lmaWVkKS5cbiAgICogQHBhcmFtIHsoYnJvYWRjYXN0OiB7Y2hhbm5lbDogc3RyaW5nLCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsID8+LCBib2R5OiA/fSkgPT4gUHJvbWlzZTx2b2lkPn0gW2FyZ3MuYnJvYWRjYXN0ZXJdIC0gRGVsaXZlcnMgZGVjbGFyYXRpdmUgYnJvYWRjYXN0cy4gUmVxdWlyZWQgd2hlbiBicm9hZGNhc3RzIGFyZSBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0ge1N5bmNSZXBsYXlCcm9hZGNhc3RbXX0gW2FyZ3MuYnJvYWRjYXN0c10gLSBCcm9hZGNhc3RzIGZhbm5lZCBvdXQgYnkgdGhlIGRlZmF1bHQgYWZ0ZXJSZXBsYXlNdXRhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGFyZ3MgPSB7fSkge1xuICAgIHRoaXMubG9nZ2VyID0gYXJncy5sb2dnZXIgfHwgY29uc29sZVxuICAgIHRoaXMuc3luY01vZGVsID0gYXJncy5zeW5jTW9kZWwgfHwgbnVsbFxuICAgIHRoaXMuYWN0b3JGb3JlaWduS2V5Q29sdW1uID0gYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4gfHwgXCJhdXRoZW50aWNhdGlvbl90b2tlbl9pZFwiXG4gICAgdGhpcy5hdXRoZW50aWNhdGlvblRva2VuTW9kZWwgPSBhcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5Nb2RlbCB8fCBudWxsXG4gICAgdGhpcy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uID0gYXJncy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uIHx8IFwidG9rZW5cIlxuICAgIHRoaXMuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtID0gYXJncy5hdXRoZW50aWNhdGlvblRva2VuUGFyYW0gfHwgXCJhdXRoZW50aWNhdGlvblRva2VuXCJcbiAgICB0aGlzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgPSBhcmdzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgfHwgbnVsbFxuICAgIHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhID0gYXJncy5wZXJzaXN0U2VyaWFsaXplZERhdGEgfHwgbnVsbFxuICAgIHRoaXMuYnJvYWRjYXN0ZXIgPSBhcmdzLmJyb2FkY2FzdGVyIHx8IG51bGxcbiAgICB0aGlzLmJyb2FkY2FzdHMgPSBhcmdzLmJyb2FkY2FzdHMgfHwgbnVsbFxuICAgIHRoaXMuYXBwbHlIYW5kbGVycyA9IGFyZ3MuYXBwbHlIYW5kbGVycyA/IHRoaXMuYnVpbHRBcHBseUhhbmRsZXJzKGFyZ3MuYXBwbHlIYW5kbGVycykgOiBudWxsXG5cbiAgICBpZiAoYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4gIT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uICE9PSBcInN0cmluZ1wiIHx8IGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uLmxlbmd0aCA8IDEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGFjdG9yRm9yZWlnbktleUNvbHVtbiBtdXN0IGJlIGEgbm9uLWJsYW5rIHN0cmluZywgZ290OiAke1N0cmluZyhhcmdzLmFjdG9yRm9yZWlnbktleUNvbHVtbil9YClcbiAgICB9XG4gICAgaWYgKHRoaXMuYnJvYWRjYXN0cyAmJiAhdGhpcy5icm9hZGNhc3Rlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSBicm9hZGNhc3RzIHJlcXVpcmUgYSBicm9hZGNhc3RlciBvcHRpb24gZGVsaXZlcmluZyB0aGVtXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBzIGRlY2xhcmF0aXZlIGFwcGx5LWhhbmRsZXIgc3BlY3MgaW4gdXBzZXJ0IGFwcGxpZXJzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhcHBseUhhbmRsZXJzIC0gUmF3IGFwcGx5IGhhbmRsZXJzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgKGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBQcm9taXNlPD8+Pn0gQ2FsbGFibGUgaGFuZGxlcnMgYnkgcmVzb3VyY2UgdHlwZS5cbiAgICovXG4gIGJ1aWx0QXBwbHlIYW5kbGVycyhhcHBseUhhbmRsZXJzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhhcHBseUhhbmRsZXJzKS5tYXAoKFtyZXNvdXJjZVR5cGUsIGhhbmRsZXJdKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFtyZXNvdXJjZVR5cGUsIGhhbmRsZXJdXG5cbiAgICAgIGNvbnN0IGFwcGxpZXIgPSBuZXcgU3luY1JlcGxheVVwc2VydEFwcGxpZXIoaGFuZGxlcilcblxuICAgICAgcmV0dXJuIFtyZXNvdXJjZVR5cGUsICgvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyBhcHBseUFyZ3MpID0+IGFwcGxpZXIuYXBwbHkoLyoqIEB0eXBlIHs/fSAqLyAoYXBwbHlBcmdzKSldXG4gICAgfSkpXG4gIH1cblxuICAvKipcbiAgICogUmVwbGF5cyBhIHN5bmMgYmF0Y2guXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zIGNhcnJ5aW5nIGF1dGhlbnRpY2F0aW9uIGFuZCBzeW5jcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8e3N5bmNzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4sIHN0YXR1cz86IHN0cmluZywgZXJyb3JDb2RlPzogc3RyaW5nLCBlcnJvck1lc3NhZ2U/OiBzdHJpbmd9Pn0gUmVwbGF5IHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgcmVwbGF5KHBhcmFtcykge1xuICAgIGNvbnN0IGFjdG9yUmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRoZW50aWNhdGVSZXBsYXkocGFyYW1zKVxuXG4gICAgaWYgKCFhY3RvclJlc3VsdC5hdXRoZW50aWNhdGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzeW5jczogW10sXG4gICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICBlcnJvckNvZGU6IGFjdG9yUmVzdWx0LmVycm9yQ29kZSxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBhY3RvclJlc3VsdC5lcnJvck1lc3NhZ2VcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzeW5jUmVzcG9uc2VzID0gW11cbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5idWlsZFJlcGxheUNvbnRleHQoe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgcGFyYW1zfSlcblxuICAgIGZvciAoY29uc3QgcmF3U3luYyBvZiB0aGlzLnJlcGxheVN5bmNzKHBhcmFtcykpIHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXN1bHQgPSB0aGlzLm5vcm1hbGl6ZVJlcGxheVN5bmMocmF3U3luYylcblxuICAgICAgaWYgKCFub3JtYWxpemVkUmVzdWx0Lm9rKSB7XG4gICAgICAgIHN5bmNSZXNwb25zZXMucHVzaChub3JtYWxpemVkUmVzdWx0LnJlc3BvbnNlKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtdXRhdGlvbiA9IG5vcm1hbGl6ZWRSZXN1bHQubXV0YXRpb25cbiAgICAgIGNvbnN0IGFjY2Vzc1Jlc3VsdCA9IGF3YWl0IHRoaXMuYXV0aG9yaXplUmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgbXV0YXRpb259KVxuXG4gICAgICBpZiAoIWFjY2Vzc1Jlc3VsdC5hbGxvd2VkKSB7XG4gICAgICAgIHN5bmNSZXNwb25zZXMucHVzaCh7XG4gICAgICAgICAgaWQ6IG11dGF0aW9uLmlkLFxuICAgICAgICAgIHN5bmNTdGF0ZTogXCJmYWlsZWRcIixcbiAgICAgICAgICByZWFzb246IGFjY2Vzc1Jlc3VsdC5yZWFzb24gfHwgXCJhY2Nlc3MtZGVuaWVkXCJcbiAgICAgICAgfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpc3RpbmdTeW5jID0gYXdhaXQgdGhpcy5maW5kRXhpc3RpbmdSZXBsYXlTeW5jKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIG11dGF0aW9ufSlcbiAgICAgIGNvbnN0IHNob3VsZEFwcGx5ID0gYXdhaXQgdGhpcy5zaG91bGRBcHBseVJlcGxheU11dGF0aW9uKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgbXV0YXRpb259KVxuICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBzaG91bGRBcHBseVxuICAgICAgICA/IGF3YWl0IHRoaXMuYXBwbHlSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcbiAgICAgICAgOiBhd2FpdCB0aGlzLnNraXBwZWRSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcblxuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0UmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBhcHBseVJlc3VsdCwgbXV0YXRpb24sIHNob3VsZEFwcGx5fSlcbiAgICAgIGF3YWl0IHRoaXMuYWZ0ZXJSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIGFwcGx5UmVzdWx0LCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KVxuXG4gICAgICBzeW5jUmVzcG9uc2VzLnB1c2goe2lkOiBtdXRhdGlvbi5pZCwgc3luY1N0YXRlOiBcInN1Y2Nlc3NmdWxcIn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHtzeW5jczogc3luY1Jlc3BvbnNlc31cbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRoZW50aWNhdGVzIHRoZSBzeW5jIGJhdGNoIGFjdG9yLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHRva2VuLW1vZGVsIGxvb2t1cCB3aGVuIGBhdXRoZW50aWNhdGlvblRva2VuTW9kZWxgIGlzXG4gICAqIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSBhcHBzIG92ZXJyaWRlIHRoaXMgaG9vay5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gUmVxdWVzdCBwYXJhbXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthdXRoZW50aWNhdGVkOiB0cnVlLCBhY3RvcjogP30gfCB7YXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yQ29kZTogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZ30+fSBBdXRoIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhlbnRpY2F0ZVJlcGxheShwYXJhbXMpIHtcbiAgICBpZiAoIXRoaXMuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jRW52ZWxvcGVSZXBsYXlTZXJ2aWNlLmF1dGhlbnRpY2F0ZVJlcGxheSBtdXN0IGJlIGltcGxlbWVudGVkIChvciBjb25maWd1cmUgYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsKVwiKVxuICAgIH1cblxuICAgIGNvbnN0IHRva2VuID0gcGFyYW1zW3RoaXMuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtXVxuXG4gICAgaWYgKCF0b2tlbikge1xuICAgICAgcmV0dXJuIHthdXRoZW50aWNhdGVkOiBmYWxzZSwgZXJyb3JDb2RlOiBcIm1pc3NpbmctYXV0aGVudGljYXRpb24tdG9rZW5cIiwgZXJyb3JNZXNzYWdlOiBcIk1pc3NpbmcgYXV0aGVudGljYXRpb24gdG9rZW5cIn1cbiAgICB9XG5cbiAgICBjb25zdCBhY3RvciA9IGF3YWl0IHRoaXMuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsLmZpbmRCeSh7W3RoaXMuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbl06IHRva2VufSlcblxuICAgIGlmICghYWN0b3IpIHtcbiAgICAgIHJldHVybiB7YXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yQ29kZTogXCJpbnZhbGlkLWF1dGhlbnRpY2F0aW9uLXRva2VuXCIsIGVycm9yTWVzc2FnZTogXCJJbnZhbGlkIGF1dGhlbnRpY2F0aW9uIHRva2VuXCJ9XG4gICAgfVxuXG4gICAgcmV0dXJuIHthY3RvciwgYXV0aGVudGljYXRlZDogdHJ1ZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgcGVyLWJhdGNoIG11dGFibGUgY29udGV4dCBmb3IgY2FjaGVzIHNoYXJlZCBhY3Jvc3Mgc3luYyBpdGVtcy5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIHBhcmFtczogUmVjb3JkPHN0cmluZywgPz59fSBfYXJncyAtIEFjdG9yIGFuZCByZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBSZXBsYXkgY29udGV4dC5cbiAgICovXG4gIGFzeW5jIGJ1aWxkUmVwbGF5Q29udGV4dChfYXJncykge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcmF3IHN5bmMgZW50cmllcyBmcm9tIHJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge0FycmF5PD8+fSBSYXcgc3luYyBlbnRyaWVzLlxuICAgKi9cbiAgcmVwbGF5U3luY3MocGFyYW1zKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocGFyYW1zLnN5bmNzKSA/IHBhcmFtcy5zeW5jcyA6IFtdXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBvbmUgc3luYyBlbnRyeS5cbiAgICogQHBhcmFtIHs/fSByYXdTeW5jIC0gUmF3IHN5bmMgZW50cnkuXG4gICAqIEByZXR1cm5zIHt7b2s6IHRydWUsIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSB8IHtvazogZmFsc2UsIHJlc3BvbnNlOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IE5vcm1hbGl6ZWQgbXV0YXRpb24gb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luYyhyYXdTeW5jKSB7XG4gICAgaWYgKCFyYXdTeW5jIHx8IHR5cGVvZiByYXdTeW5jICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocmF3U3luYykpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkOiB1bmRlZmluZWQsIHN5bmNTdGF0ZTogXCJmYWlsZWRcIiwgcmVhc29uOiBcImludmFsaWQtc3luY1wifX1cbiAgICB9XG5cbiAgICBjb25zdCBzeW5jID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHJhd1N5bmMpXG4gICAgY29uc3Qge2NsaWVudFVwZGF0ZWRBdCwgZGF0YSwgaWQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZSwgc3luY1R5cGV9ID0gc3luY1xuXG4gICAgaWYgKHR5cGVvZiByZXNvdXJjZVR5cGUgIT09IFwic3RyaW5nXCIgfHwgcmVzb3VyY2VUeXBlLmxlbmd0aCA8IDEgfHwgcmVzb3VyY2VJZCA9PT0gdW5kZWZpbmVkIHx8IHJlc291cmNlSWQgPT09IG51bGwgfHwgdHlwZW9mIHN5bmNUeXBlICE9PSBcInN0cmluZ1wiIHx8IHN5bmNUeXBlLmxlbmd0aCA8IDEpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkLCBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsIHJlYXNvbjogXCJpbnZhbGlkLXJlc291cmNlLWlkXCJ9fVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlSWRTdHJpbmcgPSBTdHJpbmcocmVzb3VyY2VJZClcbiAgICBsZXQgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IHR5cGVvZiBjbGllbnRVcGRhdGVkQXQgPT09IFwic3RyaW5nXCIgfHwgY2xpZW50VXBkYXRlZEF0IGluc3RhbmNlb2YgRGF0ZSA/IG5ldyBEYXRlKGNsaWVudFVwZGF0ZWRBdCkgOiBuZXcgRGF0ZSgpXG5cbiAgICBpZiAoTnVtYmVyLmlzTmFOKGNsaWVudFVwZGF0ZWRBdERhdGUuZ2V0VGltZSgpKSkgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IG5ldyBEYXRlKClcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWREYXRhUmVzdWx0ID0gdGhpcy5ub3JtYWxpemVSZXBsYXlTeW5jRGF0YSh7ZGF0YSwgaWQsIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsIHJlc291cmNlVHlwZX0pXG5cbiAgICBpZiAoIW5vcm1hbGl6ZWREYXRhUmVzdWx0Lm9rKSByZXR1cm4gbm9ybWFsaXplZERhdGFSZXN1bHRcblxuICAgIHJldHVybiB7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIG11dGF0aW9uOiB7XG4gICAgICAgIGNsaWVudFVwZGF0ZWRBdDogY2xpZW50VXBkYXRlZEF0RGF0ZSxcbiAgICAgICAgZGF0YTogbm9ybWFsaXplZERhdGFSZXN1bHQuZGF0YSxcbiAgICAgICAgaWQsXG4gICAgICAgIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsXG4gICAgICAgIHJlc291cmNlVHlwZSxcbiAgICAgICAgc2VyaWFsaXplZERhdGE6IEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWREYXRhUmVzdWx0LmRhdGEpLFxuICAgICAgICBzeW5jVHlwZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIG9uZSBzeW5jIGRhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHt7ZGF0YTogPywgaWQ6ID8sIHJlc291cmNlSWQ6IHN0cmluZywgcmVzb3VyY2VUeXBlOiBzdHJpbmd9fSBhcmdzIC0gU3luYyBwYXlsb2FkIG5vcm1hbGl6YXRpb24gYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7e29rOiB0cnVlLCBkYXRhOiBSZWNvcmQ8c3RyaW5nLCA/Pn0gfCB7b2s6IGZhbHNlLCByZXNwb25zZTogUmVjb3JkPHN0cmluZywgPz59fSBOb3JtYWxpemVkIHBheWxvYWQgb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luY0RhdGEoe2RhdGEsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KSB7XG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCB8fCBkYXRhID09PSBudWxsKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoZGF0YSlcblxuICAgICAgICBpZiAoIXBhcnNlZERhdGEgfHwgdHlwZW9mIHBhcnNlZERhdGEgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShwYXJzZWREYXRhKSkgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YToge319XG5cbiAgICAgICAgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YTogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHBhcnNlZERhdGEpfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2Fybj8uKFwiSW52YWxpZCBzeW5jIGRhdGEgSlNPTlwiLCB7ZXJyb3IsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KVxuICAgICAgICByZXR1cm4ge29rOiBmYWxzZSwgcmVzcG9uc2U6IHtpZCwgc3luY1N0YXRlOiBcImZhaWxlZFwiLCByZWFzb246IFwiaW52YWxpZC1kYXRhXCJ9fVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGRhdGEpKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIHJldHVybiB7b2s6IHRydWUsIGRhdGE6IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpfVxuICB9XG5cbiAgLyoqXG4gICAqIEF1dGhvcml6ZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBfYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthbGxvd2VkOiBib29sZWFuLCByZWFzb24/OiBzdHJpbmd9Pn0gQWNjZXNzIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhvcml6ZVJlcGxheU11dGF0aW9uKF9hcmdzKSB7XG4gICAgcmV0dXJuIHthbGxvd2VkOiB0cnVlfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBwcmV2aW91c2x5IHN0b3JlZCBzeW5jL2NoYW5nZSByb3cgZm9yIHN0YWxlLWNsaWVudCBjb21wYXJpc29uLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHN5bmMtbW9kZWwgbG9va3VwIGJ5IGFjdG9yIGFuZCByZXNvdXJjZSBpZGVudGl0eSB3aGVuIGEgc3luY1xuICAgKiBtb2RlbCBpcyBjb25maWd1cmVkOyBvdGhlcndpc2UgYXBwcyBvdmVycmlkZSB0aGlzIGhvb2suXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKi9cbiAgYXN5bmMgZmluZEV4aXN0aW5nUmVwbGF5U3luYyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIGlmICghdGhpcy5zeW5jTW9kZWwpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zeW5jTW9kZWwuZmluZEJ5KHtcbiAgICAgIFt0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbl06IHRoaXMucmVwbGF5QWN0b3JJZChhY3RvciksXG4gICAgICByZXNvdXJjZV9pZDogbXV0YXRpb24ucmVzb3VyY2VJZCxcbiAgICAgIHJlc291cmNlX3R5cGU6IG11dGF0aW9uLnJlc291cmNlVHlwZVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIHBlcnNpc3RlZCBhY3RvciBpZCB1c2VkIGJ5IG1vZGVsLWJhY2tlZCBkZWZhdWx0IGhvb2tzLlxuICAgKiBAcGFyYW0gez99IGFjdG9yIC0gQWN0b3IgcmV0dXJuZWQgZnJvbSBhdXRoZW50aWNhdGVSZXBsYXkuXG4gICAqIEByZXR1cm5zIHs/fSBBY3RvciBpZC5cbiAgICovXG4gIHJlcGxheUFjdG9ySWQoYWN0b3IpIHtcbiAgICBpZiAoIWFjdG9yIHx8IHR5cGVvZiBhY3RvciAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYWN0b3IuaWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSBtb2RlbC1iYWNrZWQgZGVmYXVsdHMgcmVxdWlyZSBhbiBhY3RvciB3aXRoIGFuIGlkKCkgbWV0aG9kIGZyb20gYXV0aGVudGljYXRlUmVwbGF5XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIGFjdG9yLmlkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgYSBub3JtYWxpemVkIG11dGF0aW9uIHNob3VsZCBiZSBhcHBsaWVkIHRvIGRvbWFpbiBtb2RlbHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IGFyZ3MgLSBBY3RvciwgYmF0Y2ggY29udGV4dCwgZXhpc3Rpbmcgc3luYyByb3csIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdG8gYXBwbHkgdGhlIG11dGF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc2hvdWxkQXBwbHlSZXBsYXlNdXRhdGlvbih7ZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pIHtcbiAgICBjb25zdCBleGlzdGluZ0NsaWVudFVwZGF0ZWRBdCA9IHRoaXMuZXhpc3RpbmdSZXBsYXlTeW5jQ2xpZW50VXBkYXRlZEF0KGV4aXN0aW5nU3luYylcblxuICAgIHJldHVybiAhZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgfHwgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0ID4gZXhpc3RpbmdDbGllbnRVcGRhdGVkQXRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgY2xpZW50IHRpbWVzdGFtcCBmcm9tIGFuIGV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcGFyYW0gez99IGV4aXN0aW5nU3luYyAtIEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcmV0dXJucyB7RGF0ZSB8IG51bGx9IEV4aXN0aW5nIGNsaWVudCB0aW1lc3RhbXAuXG4gICAqL1xuICBleGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKSB7XG4gICAgaWYgKCFleGlzdGluZ1N5bmMgfHwgdHlwZW9mIGV4aXN0aW5nU3luYyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHN5bmNSZWNvcmQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoZXhpc3RpbmdTeW5jKVxuICAgIGNvbnN0IHZhbHVlID0gdHlwZW9mIHN5bmNSZWNvcmQuY2xpZW50VXBkYXRlZEF0ID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gc3luY1JlY29yZC5jbGllbnRVcGRhdGVkQXQoKVxuICAgICAgOiBzeW5jUmVjb3JkLmNsaWVudFVwZGF0ZWRBdFxuXG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIHZhbHVlXG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSlcblxuICAgIHJldHVybiBOdW1iZXIuaXNOYU4ocGFyc2VkVmFsdWUuZ2V0VGltZSgpKSA/IG51bGwgOiBwYXJzZWRWYWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24gdG8gZG9tYWluIG1vZGVscy5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gZGlzcGF0Y2hpbmcgdGhyb3VnaCB0aGUgY29uZmlndXJlZCBhcHBseS1oYW5kbGVyIHJlZ2lzdHJ5O1xuICAgKiBtdXRhdGlvbnMgd2l0aG91dCBhIHJlZ2lzdGVyZWQgaGFuZGxlciBmYWlsIGxvdWRseS5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufX0gYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBleGlzdGluZyBzeW5jIHJvdywgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gUHJvamVjdC1zcGVjaWZpYyBhcHBseSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBhcHBseVJlcGxheU11dGF0aW9uKGFyZ3MpIHtcbiAgICBpZiAoIXRoaXMuYXBwbHlIYW5kbGVycykgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGFwcGx5SGFuZGxlciA9IHRoaXMuYXBwbHlIYW5kbGVyc1thcmdzLm11dGF0aW9uLnJlc291cmNlVHlwZV1cblxuICAgIGlmICghYXBwbHlIYW5kbGVyKSB0aHJvdyBuZXcgRXJyb3IoYE5vIHN5bmMgYXBwbHkgaGFuZGxlciByZWdpc3RlcmVkIGZvcjogJHthcmdzLm11dGF0aW9uLnJlc291cmNlVHlwZX1gKVxuXG4gICAgcmV0dXJuIGF3YWl0IGFwcGx5SGFuZGxlcihhcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIGFuIGFwcGx5IHJlc3VsdCBmb3Igc3RhbGUgbXV0YXRpb25zIHRoYXQgc2hvdWxkIG5vdCB0b3VjaCBkb21haW4gbW9kZWxzLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBfYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBleGlzdGluZyBzeW5jIHJvdywgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gUHJvamVjdC1zcGVjaWZpYyBhcHBseSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBza2lwcGVkUmVwbGF5TXV0YXRpb24oX2FyZ3MpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNpc3RzIG9uZSBub3JtYWxpemVkIG11dGF0aW9uIGludG8gdGhlIGFwcCBzeW5jL2NoYW5nZSBzdG9yZS5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gYSBzdGFsZS1ndWFyZGVkIHN5bmMtbW9kZWwgdXBzZXJ0ICh3aXRoIHNlcnZlciByZS1zZXF1ZW5jaW5nIG9uXG4gICAqIHVwZGF0ZXMpIHdoZW4gYSBzeW5jIG1vZGVsIGlzIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSBhcHBzIG92ZXJyaWRlIHRoaXMgaG9vay5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIGFwcGx5UmVzdWx0OiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbiwgc2hvdWxkQXBwbHk6IGJvb2xlYW59fSBhcmdzIC0gUmVwbGF5IHBlcnNpc3RlbmNlIGFyZ3VtZW50cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBwZXJzaXN0UmVwbGF5TXV0YXRpb24oe2FjdG9yLCBhcHBseVJlc3VsdCwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KSB7XG4gICAgaWYgKCF0aGlzLnN5bmNNb2RlbCkgcmV0dXJuXG5cbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gdGhpcy5yZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSlcblxuICAgIC8vIFN0YWxlIHJlcGxheXMgbmV2ZXIgYXBwbGllZCBhbnl0aGluZywgc28gdGhlIGFwcGx5UmVzdWx0LWRyaXZlbiBleHRlbnNpb25cbiAgICAvLyBob29rcyBtdXN0IG5vdCBydW4gYWdhaW5zdCB0aGUgZGVmYXVsdCBudWxsIHNraXBwZWQgcmVzdWx0LlxuICAgIGlmICh0aGlzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgJiYgc2hvdWxkQXBwbHkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24oYXR0cmlidXRlcywgdGhpcy5wZXJzaXN0RXh0cmFBdHRyaWJ1dGVzKHthY3RvciwgYXBwbHlSZXN1bHQsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgbXV0YXRpb24sIHNob3VsZEFwcGx5fSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhICYmIHNob3VsZEFwcGx5KSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkRGF0YSA9IHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhKHthcHBseVJlc3VsdCwgbXV0YXRpb259KVxuXG4gICAgICBpZiAoc2VyaWFsaXplZERhdGEgIT09IHVuZGVmaW5lZCAmJiBzZXJpYWxpemVkRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICBhdHRyaWJ1dGVzLmRhdGEgPSB0eXBlb2Ygc2VyaWFsaXplZERhdGEgPT09IFwic3RyaW5nXCIgPyBzZXJpYWxpemVkRGF0YSA6IEpTT04uc3RyaW5naWZ5KHNlcmlhbGl6ZWREYXRhKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleGlzdGluZ1N5bmMpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0ID0gdGhpcy5leGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKVxuXG4gICAgICBpZiAoZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgJiYgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0IDw9IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0KSByZXR1cm5cblxuICAgICAgZXhpc3RpbmdTeW5jLmFzc2lnbihhdHRyaWJ1dGVzKVxuICAgICAgYXdhaXQgZXhpc3RpbmdTeW5jLmFkdmFuY2VTZXJ2ZXJTZXF1ZW5jZSgpXG4gICAgICBhd2FpdCBleGlzdGluZ1N5bmMuc2F2ZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY01vZGVsLmNyZWF0ZShhdHRyaWJ1dGVzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHN5bmMtbW9kZWwgYXR0cmlidXRlcyBwZXJzaXN0ZWQgYnkgdGhlIG1vZGVsLWJhY2tlZCBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IFN5bmMgcm93IGF0dHJpYnV0ZXMuXG4gICAqL1xuICByZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIHJldHVybiB7XG4gICAgICBbdGhpcy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dOiB0aGlzLnJlcGxheUFjdG9ySWQoYWN0b3IpLFxuICAgICAgY2xpZW50X3VwZGF0ZWRfYXQ6IG11dGF0aW9uLmNsaWVudFVwZGF0ZWRBdCxcbiAgICAgIGRhdGE6IG11dGF0aW9uLnNlcmlhbGl6ZWREYXRhLFxuICAgICAgcmVzb3VyY2VfaWQ6IG11dGF0aW9uLnJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZV90eXBlOiBtdXRhdGlvbi5yZXNvdXJjZVR5cGUsXG4gICAgICBzeW5jX3R5cGU6IG11dGF0aW9uLnN5bmNUeXBlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2lkZSBlZmZlY3RzIGFmdGVyIGEgc3VjY2Vzc2Z1bCBtdXRhdGlvbiByZXBsYXkgYW5kIHBlcnNpc3RlbmNlLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBmYW5uaW5nIHRoZSBhcHBsaWVkIHJlc3VsdCBvdXQgdGhyb3VnaCB0aGUgY29uZmlndXJlZFxuICAgKiBkZWNsYXJhdGl2ZSBicm9hZGNhc3RzLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgYXBwbHlSZXN1bHQ6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9uLCBzaG91bGRBcHBseTogYm9vbGVhbn19IGFyZ3MgLSBSZXBsYXkgc2lkZS1lZmZlY3QgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGFmdGVyUmVwbGF5TXV0YXRpb24oYXJncykge1xuICAgIGlmICghdGhpcy5icm9hZGNhc3RzIHx8ICF0aGlzLmJyb2FkY2FzdGVyKSByZXR1cm5cbiAgICAvLyBTdGFsZSByZXBsYXlzIG5ldmVyIGFwcGxpZWQgYW55dGhpbmcgLSBicm9hZGNhc3RpbmcgdGhlaXIgc2tpcHBlZCByZXN1bHRzXG4gICAgLy8gd291bGQgZmFuIG91dCBzdGFsZSBzaWRlIGVmZmVjdHMgKG9yIGNyYXNoIG9uIHRoZSBkZWZhdWx0IG51bGwgYXBwbHlSZXN1bHQpLlxuICAgIGlmICghYXJncy5zaG91bGRBcHBseSkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IGJyb2FkY2FzdCBvZiB0aGlzLmJyb2FkY2FzdHMpIHtcbiAgICAgIGlmIChicm9hZGNhc3Qud2hlbiAmJiAhYnJvYWRjYXN0LndoZW4oYXJncykpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuYnJvYWRjYXN0ZXIoe1xuICAgICAgICBib2R5OiBicm9hZGNhc3QuYm9keShhcmdzKSxcbiAgICAgICAgY2hhbm5lbDogdHlwZW9mIGJyb2FkY2FzdC5jaGFubmVsID09PSBcImZ1bmN0aW9uXCIgPyBicm9hZGNhc3QuY2hhbm5lbChhcmdzKSA6IGJyb2FkY2FzdC5jaGFubmVsLFxuICAgICAgICBwYXJhbXM6IGJyb2FkY2FzdC5icm9hZGNhc3RQYXJhbXMoYXJncylcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gU3luY1JlcGxheU11dGF0aW9uXG4gKiBAcHJvcGVydHkge0RhdGV9IGNsaWVudFVwZGF0ZWRBdCAtIENsaWVudC1zaWRlIG11dGF0aW9uIHRpbWVzdGFtcC5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgPz59IGRhdGEgLSBQYXJzZWQgbXV0YXRpb24gcGF5bG9hZC5cbiAqIEBwcm9wZXJ0eSB7P30gaWQgLSBDbGllbnQgc3luYyByb3cgaWQgZm9yIHBlci1zeW5jIHJlc3BvbnNlcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZXNvdXJjZUlkIC0gUmVzb3VyY2UgaWQgYXMgYSBzdHJpbmcuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVzb3VyY2VUeXBlIC0gUmVzb3VyY2UvbW9kZWwgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXJpYWxpemVkRGF0YSAtIEpTT04gc2VyaWFsaXplZCBtdXRhdGlvbiBwYXlsb2FkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHN5bmNUeXBlIC0gU3luYyBvcGVyYXRpb24gdHlwZS5cbiAqL1xuIl19
|