@archont561/qgis-sdk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -33
- package/dist/bridge.d.ts +2 -205
- package/dist/bridge.js +3 -4
- package/dist/host.d.ts +2 -157
- package/dist/host.js +72 -430
- package/dist/index.d.ts +62 -95
- package/dist/index.js +399 -12
- package/dist/react.d.ts +61 -161
- package/dist/react.js +70 -139
- package/dist/shared/chunk-2hwva3a3.js +14 -0
- package/dist/shared/chunk-3zscfm3y.d.ts +342 -0
- package/dist/shared/chunk-7tgzmz0m.d.ts +252 -0
- package/dist/shared/chunk-8gawbn19.js +433 -0
- package/dist/shared/chunk-a33y575v.d.ts +155 -0
- package/dist/shared/chunk-pdj2fxjb.d.ts +17 -0
- package/dist/shared/chunk-stre69mw.js +777 -0
- package/dist/shared/chunk-t1vpt5yq.js +895 -0
- package/dist/shared/chunk-wtv4vt4q.d.ts +280 -0
- package/dist/svelte.d.ts +75 -0
- package/dist/svelte.js +70 -0
- package/dist/testing.d.ts +58 -30
- package/dist/testing.js +51 -5
- package/dist/vue.d.ts +106 -0
- package/dist/vue.js +91 -0
- package/package.json +21 -3
- package/dist/shared/chunk-0fknax6w.js +0 -207
- package/dist/shared/chunk-a7bjgeve.js +0 -422
package/dist/index.js
CHANGED
|
@@ -1,31 +1,418 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPlainRecord,
|
|
3
|
+
BRIDGE_PROTOCOL_VERSION2,
|
|
4
|
+
MAX_CALL_ID_LENGTH2,
|
|
5
|
+
QgisSdkBridgeProtocolError2,
|
|
6
|
+
QgisSdkBridgeTimeoutError2,
|
|
7
|
+
QgisSdkBridgeAbortedError2,
|
|
8
|
+
QgisSdkBridgeClosedError2,
|
|
9
|
+
QgisSdkBridgeSequenceError2,
|
|
10
|
+
QgisSdkBridgeStreamEndedError2,
|
|
11
|
+
QgisSdkBridgeRemoteError2,
|
|
12
|
+
parseInvokeReply2,
|
|
13
|
+
parseStreamFrame2,
|
|
14
|
+
BridgeClient2
|
|
15
|
+
} from "./shared/chunk-8gawbn19.js";
|
|
1
16
|
import {
|
|
2
17
|
MAX_SAFE_INTEGER2,
|
|
3
18
|
MIN_SAFE_INTEGER2,
|
|
4
19
|
PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
|
|
5
20
|
isSafeJsonInteger2,
|
|
6
|
-
QgisSdkError2,
|
|
7
|
-
QgisSdkScopeClosedError2,
|
|
8
|
-
QgisSdkUnsupportedCapabilityError2,
|
|
9
21
|
QgisSdkDeclarationError2,
|
|
10
22
|
QgisSdkValidationIssue2,
|
|
11
23
|
QgisSdkContractValidationError2,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
parsePluginDescription2,
|
|
25
|
+
QgisSdkContractError2,
|
|
26
|
+
validateAgainstSchema2,
|
|
27
|
+
QgisSdkStoreError2,
|
|
28
|
+
OperationStore2,
|
|
29
|
+
stableKey2,
|
|
30
|
+
StreamStore2,
|
|
31
|
+
labelFor2,
|
|
32
|
+
schemaFields2,
|
|
33
|
+
FormStore2,
|
|
34
|
+
formStore2,
|
|
35
|
+
HostQueryStore2,
|
|
36
|
+
layersQuery2,
|
|
37
|
+
layerFieldsQuery2
|
|
38
|
+
} from "./shared/chunk-t1vpt5yq.js";
|
|
39
|
+
import {
|
|
40
|
+
HOST_OPERATIONS2,
|
|
41
|
+
createHost2
|
|
42
|
+
} from "./shared/chunk-stre69mw.js";
|
|
43
|
+
import {
|
|
44
|
+
QgisSdkError2
|
|
45
|
+
} from "./shared/chunk-2hwva3a3.js";
|
|
46
|
+
// src/processing.ts
|
|
47
|
+
async function runAlgorithm(qgis, id, params, options) {
|
|
48
|
+
const raw = await qgis.host.algorithms.run({ algorithm_id: id, params }, options);
|
|
49
|
+
return {
|
|
50
|
+
algorithm: raw.algorithm,
|
|
51
|
+
outputs: outputsByName(raw.outputs),
|
|
52
|
+
raw
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function outputsByName(outputs) {
|
|
56
|
+
const result = {};
|
|
57
|
+
for (const output of outputs) {
|
|
58
|
+
if (output.kind === "vector")
|
|
59
|
+
result[output.name] = output.layer;
|
|
60
|
+
else if (output.kind === "file")
|
|
61
|
+
result[output.name] = output.file;
|
|
62
|
+
else
|
|
63
|
+
result[output.name] = output.value;
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
// src/webchannel.ts
|
|
68
|
+
class QgisSdkWebChannelError extends QgisSdkError2 {
|
|
69
|
+
constructor(message) {
|
|
70
|
+
super(message, "no_web_channel");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function scope() {
|
|
74
|
+
return globalThis;
|
|
75
|
+
}
|
|
76
|
+
function insideQgis() {
|
|
77
|
+
const page = scope();
|
|
78
|
+
return page.qt !== undefined && typeof page.QWebChannel === "function";
|
|
79
|
+
}
|
|
80
|
+
function createWebChannelTransport(objectName = "bridge") {
|
|
81
|
+
const page = scope();
|
|
82
|
+
const qt = page.qt;
|
|
83
|
+
const QWebChannel = page.QWebChannel;
|
|
84
|
+
if (qt === undefined || typeof QWebChannel !== "function") {
|
|
85
|
+
throw new QgisSdkWebChannelError("not inside a QGIS web view: window.qt is missing");
|
|
86
|
+
}
|
|
87
|
+
const listeners = new Set;
|
|
88
|
+
const queue = [];
|
|
89
|
+
let object = null;
|
|
90
|
+
let failure = null;
|
|
91
|
+
let closed = false;
|
|
92
|
+
const forward = (text) => {
|
|
93
|
+
if (closed) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let parsed;
|
|
97
|
+
try {
|
|
98
|
+
parsed = JSON.parse(text);
|
|
99
|
+
} catch {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
for (const listener of [...listeners]) {
|
|
103
|
+
listener(parsed);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const ready = new Promise((resolve, reject) => {
|
|
107
|
+
new QWebChannel(qt.webChannelTransport, (channel) => {
|
|
108
|
+
const found = channel.objects[objectName];
|
|
109
|
+
if (found === undefined) {
|
|
110
|
+
failure = new QgisSdkWebChannelError(`the host registered no ${JSON.stringify(objectName)} channel object`);
|
|
111
|
+
queue.length = 0;
|
|
112
|
+
reject(failure);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (closed) {
|
|
116
|
+
resolve();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
object = found;
|
|
120
|
+
found.message.connect(forward);
|
|
121
|
+
for (const text of queue.splice(0)) {
|
|
122
|
+
found.receive(text);
|
|
123
|
+
}
|
|
124
|
+
resolve();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
ready,
|
|
129
|
+
send(message) {
|
|
130
|
+
if (closed) {
|
|
131
|
+
throw new QgisSdkWebChannelError("the web channel transport is closed");
|
|
132
|
+
}
|
|
133
|
+
if (failure !== null) {
|
|
134
|
+
throw failure;
|
|
135
|
+
}
|
|
136
|
+
const text = JSON.stringify(message);
|
|
137
|
+
if (object === null) {
|
|
138
|
+
queue.push(text);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
object.receive(text);
|
|
142
|
+
},
|
|
143
|
+
subscribe(listener) {
|
|
144
|
+
listeners.add(listener);
|
|
145
|
+
return () => {
|
|
146
|
+
listeners.delete(listener);
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
close() {
|
|
150
|
+
if (closed) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
closed = true;
|
|
154
|
+
queue.length = 0;
|
|
155
|
+
listeners.clear();
|
|
156
|
+
object?.message.disconnect(forward);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/qgis-sdk.ts
|
|
162
|
+
var QGIS_SDK_MEMBERS = Object.freeze([
|
|
163
|
+
"client",
|
|
164
|
+
"host",
|
|
165
|
+
"schema",
|
|
166
|
+
"ready",
|
|
167
|
+
"close"
|
|
168
|
+
]);
|
|
169
|
+
var HOST_IDS = new Set(HOST_OPERATIONS2);
|
|
170
|
+
function parseHandshake(value) {
|
|
171
|
+
if (!isPlainRecord(value) || !Array.isArray(value.operations)) {
|
|
172
|
+
throw new QgisSdkBridgeProtocolError2("The handshake reply carries no operations list");
|
|
173
|
+
}
|
|
174
|
+
const operations = [];
|
|
175
|
+
for (const operation of value.operations) {
|
|
176
|
+
if (isPlainRecord(operation) && typeof operation.id === "string") {
|
|
177
|
+
operations.push(operation.id);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
operations,
|
|
182
|
+
granted: Object.freeze(operations.filter((id) => HOST_IDS.has(id))),
|
|
183
|
+
theme: parseTheme(value.theme)
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function parseTheme(value) {
|
|
187
|
+
if (!isPlainRecord(value) || !isPlainRecord(value.palette)) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
const palette = {};
|
|
191
|
+
for (const [role, colour] of Object.entries(value.palette)) {
|
|
192
|
+
if (typeof colour === "string") {
|
|
193
|
+
palette[role] = colour;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
palette: Object.freeze(palette),
|
|
198
|
+
dark: value.dark === true
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function unwrapRequest(operation, request) {
|
|
202
|
+
if (request === undefined) {
|
|
203
|
+
return {};
|
|
204
|
+
}
|
|
205
|
+
if (!isPlainRecord(request)) {
|
|
206
|
+
throw new QgisSdkContractError2(operation, "request", [
|
|
207
|
+
...validateAgainstSchema2(request, { type: "object" })
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
return request;
|
|
211
|
+
}
|
|
212
|
+
function checkedRequest(description, request) {
|
|
213
|
+
const payload = unwrapRequest(description.id, request);
|
|
214
|
+
const issues = validateAgainstSchema2(payload, description.request);
|
|
215
|
+
if (issues.length > 0) {
|
|
216
|
+
throw new QgisSdkContractError2(description.id, "request", issues);
|
|
217
|
+
}
|
|
218
|
+
return payload;
|
|
219
|
+
}
|
|
220
|
+
function operationMethod(client, action) {
|
|
221
|
+
return async (request, options) => {
|
|
222
|
+
const payload = checkedRequest(action, request);
|
|
223
|
+
const value = await client.invoke(action.id, payload, options);
|
|
224
|
+
const issues = validateAgainstSchema2(value, action.result, {
|
|
225
|
+
allowUnknown: true
|
|
226
|
+
});
|
|
227
|
+
if (issues.length > 0) {
|
|
228
|
+
throw new QgisSdkContractError2(action.id, "result", issues);
|
|
229
|
+
}
|
|
230
|
+
return value;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function streamMethod(client, stream) {
|
|
234
|
+
return async (request, handlers, options) => {
|
|
235
|
+
const payload = checkedRequest(stream, request);
|
|
236
|
+
let ended = false;
|
|
237
|
+
let violated = false;
|
|
238
|
+
let handle = null;
|
|
239
|
+
const end = (terminal) => {
|
|
240
|
+
if (ended) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
ended = true;
|
|
244
|
+
handlers.onTerminal?.(terminal);
|
|
245
|
+
};
|
|
246
|
+
handle = await client.subscribe(stream.id, payload, {
|
|
247
|
+
onEvent: (event) => {
|
|
248
|
+
if (ended) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const declared = stream.events[event.kind];
|
|
252
|
+
const issues = declared === undefined ? undefined : validateAgainstSchema2(event.payload, declared, {
|
|
253
|
+
allowUnknown: true,
|
|
254
|
+
path: ["payload"]
|
|
255
|
+
});
|
|
256
|
+
if (issues !== undefined && issues.length === 0) {
|
|
257
|
+
handlers.onEvent?.(event);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const error = new QgisSdkContractError2(stream.id, "event", issues ?? []);
|
|
261
|
+
end({ kind: "error", message: error.message });
|
|
262
|
+
if (handle === null) {
|
|
263
|
+
violated = true;
|
|
264
|
+
} else {
|
|
265
|
+
handle.close();
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
onTerminal: end
|
|
269
|
+
}, options);
|
|
270
|
+
if (violated) {
|
|
271
|
+
handle.close();
|
|
272
|
+
}
|
|
273
|
+
return handle;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function buildHost(client, handshake) {
|
|
277
|
+
const host = createHost2(client);
|
|
278
|
+
return Object.freeze({
|
|
279
|
+
...host,
|
|
280
|
+
get granted() {
|
|
281
|
+
return granted(handshake());
|
|
282
|
+
},
|
|
283
|
+
get theme() {
|
|
284
|
+
return handshake()?.theme ?? null;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
var NO_GRANTS = Object.freeze([]);
|
|
289
|
+
function granted(handshake) {
|
|
290
|
+
return handshake === null ? NO_GRANTS : handshake.granted;
|
|
291
|
+
}
|
|
292
|
+
function build(schema, options) {
|
|
293
|
+
if (options.client !== undefined && options.transport !== undefined) {
|
|
294
|
+
throw new QgisSdkDeclarationError2("QgisSdk.fromBridgeSchema takes a client or a transport, not both");
|
|
295
|
+
}
|
|
296
|
+
const owned = options.client === undefined;
|
|
297
|
+
const transport = options.transport ?? (options.client === undefined ? createWebChannelTransport(options.channelObject ?? "bridge") : undefined);
|
|
298
|
+
const client = options.client ?? new BridgeClient2(transport, options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs });
|
|
299
|
+
let handshake = null;
|
|
300
|
+
const ready = client.handshake().then((value) => {
|
|
301
|
+
handshake = parseHandshake(value);
|
|
302
|
+
});
|
|
303
|
+
ready.catch(() => {
|
|
304
|
+
return;
|
|
305
|
+
});
|
|
306
|
+
const members = {
|
|
307
|
+
schema,
|
|
308
|
+
client,
|
|
309
|
+
host: buildHost(client, () => handshake),
|
|
310
|
+
ready,
|
|
311
|
+
close: () => {
|
|
312
|
+
if (owned) {
|
|
313
|
+
client.close();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const namespaces = [];
|
|
318
|
+
for (const action of schema.actions) {
|
|
319
|
+
place(members, namespaces, action.id, operationMethod(client, action));
|
|
320
|
+
}
|
|
321
|
+
for (const stream of schema.streams) {
|
|
322
|
+
place(members, namespaces, stream.id, streamMethod(client, stream));
|
|
323
|
+
}
|
|
324
|
+
for (const namespace of namespaces) {
|
|
325
|
+
Object.freeze(namespace);
|
|
326
|
+
}
|
|
327
|
+
return Object.freeze(members);
|
|
328
|
+
}
|
|
329
|
+
function place(members, namespaces, id, method) {
|
|
330
|
+
const segments = id.split(".");
|
|
331
|
+
if (segments.some((segment) => segment === "")) {
|
|
332
|
+
throw new QgisSdkDeclarationError2(`${id}: an operation id may not have an empty segment`);
|
|
333
|
+
}
|
|
334
|
+
const head = segments[0];
|
|
335
|
+
if (QGIS_SDK_MEMBERS.includes(head)) {
|
|
336
|
+
throw new QgisSdkDeclarationError2(`${id}: an operation id may not start with a QgisSdk member (${QGIS_SDK_MEMBERS.join(", ")})`);
|
|
337
|
+
}
|
|
338
|
+
let node = members;
|
|
339
|
+
for (const [index, segment] of segments.entries()) {
|
|
340
|
+
const prefix = segments.slice(0, index + 1).join(".");
|
|
341
|
+
const existing = node[segment];
|
|
342
|
+
if (index === segments.length - 1) {
|
|
343
|
+
if (existing !== undefined) {
|
|
344
|
+
throw new QgisSdkDeclarationError2(typeof existing === "function" ? `${id}: duplicate operation id` : `${id}: an operation id may not be a prefix of another declared id`);
|
|
345
|
+
}
|
|
346
|
+
node[segment] = method;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (existing === undefined) {
|
|
350
|
+
const namespace = {};
|
|
351
|
+
namespaces.push(namespace);
|
|
352
|
+
node[segment] = namespace;
|
|
353
|
+
node = namespace;
|
|
354
|
+
} else if (typeof existing === "function") {
|
|
355
|
+
throw new QgisSdkDeclarationError2(`${id}: ${prefix} is already an operation id; an id may not extend another`);
|
|
356
|
+
} else {
|
|
357
|
+
node = existing;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
var QgisSdk;
|
|
362
|
+
((QgisSdk) => {
|
|
363
|
+
function fromBridgeSchema(schema, options = {}) {
|
|
364
|
+
return build(schema, options);
|
|
365
|
+
}
|
|
366
|
+
QgisSdk.fromBridgeSchema = fromBridgeSchema;
|
|
367
|
+
})(QgisSdk ||= {});
|
|
368
|
+
// src/schema.ts
|
|
369
|
+
function defineBridgeSchema(input) {
|
|
370
|
+
return parsePluginDescription2(input);
|
|
371
|
+
}
|
|
15
372
|
export {
|
|
373
|
+
BRIDGE_PROTOCOL_VERSION2 as BRIDGE_PROTOCOL_VERSION,
|
|
374
|
+
BridgeClient2 as BridgeClient,
|
|
375
|
+
FormStore2 as FormStore,
|
|
376
|
+
HostQueryStore2 as HostQueryStore,
|
|
377
|
+
MAX_CALL_ID_LENGTH2 as MAX_CALL_ID_LENGTH,
|
|
16
378
|
MAX_SAFE_INTEGER2 as MAX_SAFE_INTEGER,
|
|
17
379
|
MIN_SAFE_INTEGER2 as MIN_SAFE_INTEGER,
|
|
380
|
+
OperationStore2 as OperationStore,
|
|
18
381
|
PLUGIN_DESCRIPTION_SCHEMA_VERSION2 as PLUGIN_DESCRIPTION_SCHEMA_VERSION,
|
|
382
|
+
QGIS_SDK_MEMBERS,
|
|
383
|
+
QgisSdk,
|
|
384
|
+
QgisSdkBridgeAbortedError2 as QgisSdkBridgeAbortedError,
|
|
385
|
+
QgisSdkBridgeClosedError2 as QgisSdkBridgeClosedError,
|
|
386
|
+
QgisSdkBridgeProtocolError2 as QgisSdkBridgeProtocolError,
|
|
387
|
+
QgisSdkBridgeRemoteError2 as QgisSdkBridgeRemoteError,
|
|
388
|
+
QgisSdkBridgeSequenceError2 as QgisSdkBridgeSequenceError,
|
|
389
|
+
QgisSdkBridgeStreamEndedError2 as QgisSdkBridgeStreamEndedError,
|
|
390
|
+
QgisSdkBridgeTimeoutError2 as QgisSdkBridgeTimeoutError,
|
|
391
|
+
QgisSdkContractError2 as QgisSdkContractError,
|
|
19
392
|
QgisSdkContractValidationError2 as QgisSdkContractValidationError,
|
|
20
393
|
QgisSdkDeclarationError2 as QgisSdkDeclarationError,
|
|
21
394
|
QgisSdkError2 as QgisSdkError,
|
|
22
|
-
|
|
23
|
-
QgisSdkUnsupportedCapabilityError2 as QgisSdkUnsupportedCapabilityError,
|
|
395
|
+
QgisSdkStoreError2 as QgisSdkStoreError,
|
|
24
396
|
QgisSdkValidationIssue2 as QgisSdkValidationIssue,
|
|
25
|
-
|
|
397
|
+
QgisSdkWebChannelError,
|
|
398
|
+
StreamStore2 as StreamStore,
|
|
399
|
+
createWebChannelTransport,
|
|
400
|
+
defineBridgeSchema,
|
|
401
|
+
formStore2 as formStore,
|
|
402
|
+
insideQgis,
|
|
26
403
|
isSafeJsonInteger2 as isSafeJsonInteger,
|
|
27
|
-
|
|
404
|
+
labelFor2 as labelFor,
|
|
405
|
+
layerFieldsQuery2 as layerFieldsQuery,
|
|
406
|
+
layersQuery2 as layersQuery,
|
|
407
|
+
outputsByName,
|
|
408
|
+
parseInvokeReply2 as parseInvokeReply,
|
|
409
|
+
parsePluginDescription2 as parsePluginDescription,
|
|
410
|
+
parseStreamFrame2 as parseStreamFrame,
|
|
411
|
+
runAlgorithm,
|
|
412
|
+
schemaFields2 as schemaFields,
|
|
413
|
+
stableKey2 as stableKey,
|
|
414
|
+
validateAgainstSchema2 as validateAgainstSchema
|
|
28
415
|
};
|
|
29
416
|
|
|
30
|
-
//# debugId=
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFtdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICBdLAogICJtYXBwaW5ncyI6ICIiLAogICJkZWJ1Z0lkIjogIkI4RTY0RTJEODc2NEQ0ODA2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
|
|
417
|
+
//# debugId=507C47A54A87BD1B64756E2164756E21
|
|
418
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3Byb2Nlc3NpbmcudHMiLCAic3JjL3dlYmNoYW5uZWwudHMiLCAic3JjL3FnaXMtc2RrLnRzIiwgInNyYy9zY2hlbWEudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBQcm9jZXNzaW5nIGZyb20gYSBwYWdlIChkZWNpc2lvbi02NCk6IHRoZSB2YWx1ZSBhbGlhc2VzIGEgZ2VuZXJhdGVkXG4gKiBgcHJvY2Vzc2luZy5zY2hlbWEudHNgIGFubm90YXRlcyB3aXRoLCBhbmQgYHJ1bkFsZ29yaXRobWAsIHdoaWNoIHNlbmRzIG9uZVxuICogYGFsZ29yaXRobXMucnVuYCBhbmQgcmVzaGFwZXMgdGhlIHRhZ2dlZCBvdXRwdXRzIGludG8gdGhlIHJlc3VsdCBvYmplY3QgdGhlXG4gKiBnZW5lcmF0ZWQgYDxQcm92aWRlcj48QWxnb3JpdGhtPlJlc3VsdGAgdHlwZSBzcGVsbHMuXG4gKlxuICogVGhlIHR5cGluZyBsaXZlcyBpbiB0aGUgZ2VuZXJhdGVkIG1vZHVsZSwgbm90IGhlcmU6IGBxZ2lzLXNkayBwcm9jZXNzaW5nXG4gKiBnZW5lcmF0ZWAgZW1pdHMgYW4gYEFsZ29yaXRobVJlZ2lzdHJ5YCBmb3IgdGhlIHByb3ZpZGVycyB0aGUgcHJvamVjdCBhc2tlZFxuICogZm9yIGFuZCBhIGBydW5BbGdvcml0aG1gIGJvdW5kIHRvIGl0LiBUaGlzIG1vZHVsZSBpcyBnZW5lcmljIG92ZXIgYW55IHN1Y2hcbiAqIHJlZ2lzdHJ5IHNvIHRoZSBicmlkZ2UgaXRzZWxmIHNoaXBzIG5vIGNhdGFsb2d1ZSAoZGVjaXNpb24tNDc6IHplcm8gcnVudGltZVxuICogZGF0YSB0aGF0IGdvZXMgc3RhbGUgd2l0aCBhIFFHSVMgcmVsZWFzZSkuXG4gKlxuICogVGhlIGhvc3QgdmFsaWRhdGVzIHRoZSBwYXJhbWV0ZXJzIGFnYWluc3QgdGhlIGFsZ29yaXRobSdzIG93biBkZXNjcmlwdGlvblxuICogYmVmb3JlIGFueXRoaW5nIHJ1bnM7IGEgbGF5ZXIgaW5wdXQgaXMgYW4gb3duZWQgbGF5ZXIgaWQsIGEgZmlsZSBpbnB1dCBpcyBhXG4gKiByZWYgdGhlIGhvc3QgbWludGVkIGZvciB0aGlzIHZpZXcsIGFuZCBhbiBvbWl0dGVkIGRlc3RpbmF0aW9uIGNvbWVzIGJhY2sgYXNcbiAqIGFuIG93bmVkIGxheWVyIG9yIGEgcmVhZGFibGUgcmVmLlxuICovXG5cbmltcG9ydCB0eXBlIHtcblx0RmlsZVJlZixcblx0SG9zdEludm9rZU9wdGlvbnMsXG5cdEhvc3RPcGVyYXRpb25zLFxuXHRSdW5PdXRwdXQsXG5cdFJ1blJlc3VsdCxcblx0VmVjdG9yTGF5ZXJJbmZvLFxufSBmcm9tIFwiLi9nZW5lcmF0ZWQvaG9zdFwiO1xuXG5leHBvcnQgdHlwZSB7XG5cdEFsZ29yaXRobUluZm8sXG5cdEFsZ29yaXRobVN1bW1hcnksXG5cdEZpbGVSZWYsXG5cdEhvc3RJbnZva2VPcHRpb25zLFxuXHRPdXRwdXRJbmZvLFxuXHRQYXJhbWV0ZXJJbmZvLFxuXHRQcm92aWRlckluZm8sXG5cdFJ1bk91dHB1dCxcblx0UnVuUmVzdWx0LFxuXHRWZWN0b3JMYXllckluZm8sXG59IGZyb20gXCIuL2dlbmVyYXRlZC9ob3N0XCI7XG5cbi8qKiBBIGxheWVyIGlucHV0OiB0aGUgaWQgb2YgYSBsYXllciB0aGUgaG9zdCBvd25zLCBvciBhIHJlZiB0aGUgdmlldyBob2xkcy4gKi9cbmV4cG9ydCB0eXBlIExheWVyUmVmID0gc3RyaW5nIHwgRmlsZVJlZjtcbi8qKiBXaGVyZSBhbiBvdXRwdXQgZ29lczogYSB3cml0YWJsZSByZWYsIG9yIGBudWxsYCB0byBsZXQgdGhlIGhvc3QgYWxsb2NhdGUgb25lLiAqL1xuZXhwb3J0IHR5cGUgRGVzdGluYXRpb24gPSBGaWxlUmVmIHwgbnVsbDtcbi8qKiBgXCJ4bWluLHhtYXgseW1pbix5bWF4IFtjcnNdXCJgIGFzIFFHSVMgd3JpdGVzIGl0LCBvciB0aGUgZm91ciBudW1iZXJzLiAqL1xuZXhwb3J0IHR5cGUgRXh0ZW50ID0gc3RyaW5nIHwgcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4vKiogYFwieCx5IFtjcnNdXCJgIG9yIHRoZSB0d28gbnVtYmVycy4gKi9cbmV4cG9ydCB0eXBlIFBvaW50VmFsdWUgPSBzdHJpbmcgfCByZWFkb25seSBbbnVtYmVyLCBudW1iZXJdO1xuLyoqIGBbbG93ZXIsIHVwcGVyXWAuICovXG5leHBvcnQgdHlwZSBSYW5nZVZhbHVlID0gcmVhZG9ubHkgW251bWJlciwgbnVtYmVyXTtcblxuLyoqXG4gKiBXaGF0IGEgZ2VuZXJhdGVkIGBBbGdvcml0aG1SZWdpc3RyeWAgaXM6IHBhcmFtcyBhbmQgcmVzdWx0IHBlciBhbGdvcml0aG0gaWQuXG4gKiBTcGVsbGVkIGFzIGEgbWFwcGVkIGNvbnN0cmFpbnQgb3ZlciB0aGUgcmVnaXN0cnkgaXRzZWxmIHNvIGFuIGBpbnRlcmZhY2VgXG4gKiAod2hpY2ggaGFzIG5vIGltcGxpY2l0IGluZGV4IHNpZ25hdHVyZSkgc2F0aXNmaWVzIGl0LlxuICovXG5leHBvcnQgdHlwZSBBbGdvcml0aG1SZWdpc3RyeUxpa2U8Uj4gPSB7XG5cdHJlYWRvbmx5IFtLIGluIGtleW9mIFJdOiB7IHJlYWRvbmx5IHBhcmFtczogb2JqZWN0OyByZWFkb25seSByZXN1bHQ6IG9iamVjdCB9O1xufTtcblxuLyoqIFRoZSBwYXJ0IG9mIGEgYFFnaXNTZGtgIChvciBhbnl0aGluZyBlbHNlKSBgcnVuQWxnb3JpdGhtYCBuZWVkcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxnb3JpdGhtSG9zdCB7XG5cdHJlYWRvbmx5IGhvc3Q6IFBpY2s8SG9zdE9wZXJhdGlvbnMsIFwiYWxnb3JpdGhtc1wiPjtcbn1cblxuLyoqIE9uZSBydW4gYXMgdGhlIHBhZ2Ugc2VlcyBpdDogdGhlIG91dHB1dHMgYnkgbmFtZSwgcGx1cyB0aGUgcmVwbHkgYXMgaXQgY3Jvc3NlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxnb3JpdGhtUnVuPFJlc3VsdCBleHRlbmRzIG9iamVjdD4ge1xuXHRyZWFkb25seSBhbGdvcml0aG06IHN0cmluZztcblx0cmVhZG9ubHkgb3V0cHV0czogUmVzdWx0O1xuXHRyZWFkb25seSByYXc6IFJ1blJlc3VsdDtcbn1cblxuLyoqXG4gKiBSdW4gYGlkYCB3aXRoIGBwYXJhbXNgIHRocm91Z2ggYHFnaXMuaG9zdC5hbGdvcml0aG1zLnJ1bmAgYW5kIHJlc2hhcGUgdGhlXG4gKiByZXBseTogYSBgdmVjdG9yYCBvdXRwdXQgYmVjb21lcyBpdHMgYFZlY3RvckxheWVySW5mb2AsIGEgYGZpbGVgIG91dHB1dCBpdHNcbiAqIGBGaWxlUmVmYCwgYSBgdmFsdWVgIG91dHB1dCB0aGUgc2NhbGFyIC0ga2V5ZWQgYnkgb3V0cHV0IG5hbWUsIHdoaWNoIGlzIHdoYXRcbiAqIHRoZSBnZW5lcmF0ZWQgYC4uLlJlc3VsdGAgaW50ZXJmYWNlcyBkZWNsYXJlLlxuICpcbiAqIEJvdGggdHlwZSBwYXJhbWV0ZXJzIGFyZSBtZWFudCB0byBiZSBib3VuZCBieSB0aGUgZ2VuZXJhdGVkIG1vZHVsZSdzIG93blxuICogYHJ1bkFsZ29yaXRobWA7IGNhbGxpbmcgdGhpcyBvbmUgZGlyZWN0bHkgbmVlZHMgdGhlbSBzcGVsbGVkIG91dC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkFsZ29yaXRobTxcblx0UiBleHRlbmRzIEFsZ29yaXRobVJlZ2lzdHJ5TGlrZTxSPixcblx0SyBleHRlbmRzIGtleW9mIFIgJiBzdHJpbmcsXG4+KFxuXHRxZ2lzOiBBbGdvcml0aG1Ib3N0LFxuXHRpZDogSyxcblx0cGFyYW1zOiBSW0tdW1wicGFyYW1zXCJdLFxuXHRvcHRpb25zPzogSG9zdEludm9rZU9wdGlvbnMsXG4pOiBQcm9taXNlPEFsZ29yaXRobVJ1bjxSW0tdW1wicmVzdWx0XCJdPj4ge1xuXHRjb25zdCByYXcgPSBhd2FpdCBxZ2lzLmhvc3QuYWxnb3JpdGhtcy5ydW4oXG5cdFx0eyBhbGdvcml0aG1faWQ6IGlkLCBwYXJhbXM6IHBhcmFtcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9LFxuXHRcdG9wdGlvbnMsXG5cdCk7XG5cdHJldHVybiB7XG5cdFx0YWxnb3JpdGhtOiByYXcuYWxnb3JpdGhtLFxuXHRcdG91dHB1dHM6IG91dHB1dHNCeU5hbWUocmF3Lm91dHB1dHMpIGFzIFJbS11bXCJyZXN1bHRcIl0sXG5cdFx0cmF3LFxuXHR9O1xufVxuXG4vKiogVW53cmFwIGEgdGFnZ2VkIG91dHB1dCBsaXN0IGludG8gYHsgW25hbWVdOiBsYXllciB8IHJlZiB8IHZhbHVlIH1gLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG91dHB1dHNCeU5hbWUoXG5cdG91dHB1dHM6IHJlYWRvbmx5IFJ1bk91dHB1dFtdLFxuKTogUmVjb3JkPFxuXHRzdHJpbmcsXG5cdFZlY3RvckxheWVySW5mbyB8IEZpbGVSZWYgfCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZFxuPiB7XG5cdGNvbnN0IHJlc3VsdDogUmVjb3JkPFxuXHRcdHN0cmluZyxcblx0XHRWZWN0b3JMYXllckluZm8gfCBGaWxlUmVmIHwgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWRcblx0PiA9IHt9O1xuXHRmb3IgKGNvbnN0IG91dHB1dCBvZiBvdXRwdXRzKSB7XG5cdFx0aWYgKG91dHB1dC5raW5kID09PSBcInZlY3RvclwiKSByZXN1bHRbb3V0cHV0Lm5hbWVdID0gb3V0cHV0LmxheWVyO1xuXHRcdGVsc2UgaWYgKG91dHB1dC5raW5kID09PSBcImZpbGVcIikgcmVzdWx0W291dHB1dC5uYW1lXSA9IG91dHB1dC5maWxlO1xuXHRcdGVsc2UgcmVzdWx0W291dHB1dC5uYW1lXSA9IG91dHB1dC52YWx1ZTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0O1xufVxuIiwKICAgICIvKipcbiAqIFRoZSBkZWZhdWx0IHRyYW5zcG9ydDogUXQncyBXZWJDaGFubmVsLCBhcyBhIFFHSVMgd2ViIHZpZXcgaW5qZWN0cyBpdC5cbiAqXG4gKiBRR0lTIHJlZ2lzdGVycyBvbmUgb2JqZWN0IG9uIHRoZSBjaGFubmVsICh0aGUgZXhhbXBsZSBuYW1lcyBpdCBcImJyaWRnZVwiO1xuICogc2VlIGBjcmVhdGVfY2hhbm5lbF9vYmplY3RgIGluIHRoZSBQeXRob24gcnVudGltZSkuIEl0cyBgcmVjZWl2ZWAgc2xvdCB0YWtlc1xuICogYSBKU09OIGVudmVsb3BlIGFuZCBpdHMgYG1lc3NhZ2VgIHNpZ25hbCBjYXJyaWVzIGV2ZXJ5IHJlcGx5IGFuZCBzdHJlYW1cbiAqIGZyYW1lIGJhY2suIFRoZSBjaGFubmVsIGJlY29tZXMgcmVhZHkgb24gYSBsYXRlciB0dXJuLCBzbyB0aGlzIHRyYW5zcG9ydFxuICogaXMgbGF6eTogYSBgUWdpc1Nka2AgYnVpbHQgaW4gdGhlIGZpcnN0IHN0YXRlbWVudCBvZiBhIHBhZ2UgY2FuIHNlbmQgYXRcbiAqIG9uY2UsIGFuZCB3aGF0IGl0IHNlbnQgaXMgZGVsaXZlcmVkIHdoZW4gdGhlIGNoYW5uZWwgcmVwb3J0cyByZWFkeS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBvbmUgbW9kdWxlIG9mIHRoZSByb290IGVudHJ5IHBvaW50IHRoYXQgcmVhZHMgYSBicm93c2VyIGdsb2JhbCxcbiAqIGFuZCBpdCBvbmx5IGRvZXMgc28gd2hlbiBjYWxsZWQ6IGltcG9ydGluZyBpdCB0b3VjaGVzIG5vdGhpbmcsIGFuZCBhIHBhZ2VcbiAqIHRoYXQgaXMgbm90IGluc2lkZSBRR0lTIGdldHMgYSBzeW5jaHJvbm91cywgbmFtZWQgcmVmdXNhbCBpbnN0ZWFkIG9mIGEgaGFuZy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdpcmVUcmFuc3BvcnQgfSBmcm9tIFwiLi9icmlkZ2VcIjtcbmltcG9ydCB7IFFnaXNTZGtFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG5pbnRlcmZhY2UgQ2hhbm5lbE9iamVjdCB7XG5cdHJlY2VpdmUodGV4dDogc3RyaW5nKTogdm9pZDtcblx0cmVhZG9ubHkgbWVzc2FnZToge1xuXHRcdGNvbm5lY3QobGlzdGVuZXI6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkO1xuXHRcdGRpc2Nvbm5lY3QobGlzdGVuZXI6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkO1xuXHR9O1xufVxuXG5pbnRlcmZhY2UgQ2hhbm5lbCB7XG5cdHJlYWRvbmx5IG9iamVjdHM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIENoYW5uZWxPYmplY3QgfCB1bmRlZmluZWQ+Pjtcbn1cblxuaW50ZXJmYWNlIFF0U2NvcGUge1xuXHRyZWFkb25seSBxdD86IHsgcmVhZG9ubHkgd2ViQ2hhbm5lbFRyYW5zcG9ydDogdW5rbm93biB9O1xuXHRyZWFkb25seSBRV2ViQ2hhbm5lbD86IG5ldyAoXG5cdFx0dHJhbnNwb3J0OiB1bmtub3duLFxuXHRcdHJlYWR5OiAoY2hhbm5lbDogQ2hhbm5lbCkgPT4gdm9pZCxcblx0KSA9PiB1bmtub3duO1xufVxuXG4vKiogVGhlIHdlYiB2aWV3IGRpZCBub3QgcHJvdmlkZSBhIHVzYWJsZSBjaGFubmVsLiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtXZWJDaGFubmVsRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJub193ZWJfY2hhbm5lbFwiKTtcblx0fVxufVxuXG4vKiogVGhlIHRyYW5zcG9ydCB7QGxpbmsgY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydH0gcmV0dXJucy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2ViQ2hhbm5lbFRyYW5zcG9ydCBleHRlbmRzIFdpcmVUcmFuc3BvcnQge1xuXHQvKiogUmVzb2x2ZXMgb25jZSB0aGUgY2hhbm5lbCBvYmplY3QgYW5zd2VyZWQ7IHJlamVjdHMgd2hlbiBpdCBuZXZlciB3aWxsLiAqL1xuXHRyZWFkb25seSByZWFkeTogUHJvbWlzZTx2b2lkPjtcblx0LyoqIFN0b3AgZm9yd2FyZGluZyBtZXNzYWdlczsgc2VuZHMgYWZ0ZXIgdGhpcyB0aHJvdy4gKi9cblx0Y2xvc2UoKTogdm9pZDtcbn1cblxuZnVuY3Rpb24gc2NvcGUoKTogUXRTY29wZSB7XG5cdHJldHVybiBnbG9iYWxUaGlzIGFzIHVua25vd24gYXMgUXRTY29wZTtcbn1cblxuLyoqIFRydWUgaW5zaWRlIGEgUUdJUyB3ZWIgdmlldywgd2hlcmUgUXQgaW5qZWN0ZWQgaXRzIHRyYW5zcG9ydCBhbmQgc2NyaXB0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluc2lkZVFnaXMoKTogYm9vbGVhbiB7XG5cdGNvbnN0IHBhZ2UgPSBzY29wZSgpO1xuXHRyZXR1cm4gcGFnZS5xdCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwYWdlLlFXZWJDaGFubmVsID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8qKlxuICogQ29ubmVjdCB0byB0aGUgY2hhbm5lbCBvYmplY3QgYG9iamVjdE5hbWVgIGFuZCByZXR1cm4gYSB0cmFuc3BvcnQgb24gaXQuXG4gKlxuICogVGhyb3dzIHtAbGluayBRZ2lzU2RrV2ViQ2hhbm5lbEVycm9yfSBzeW5jaHJvbm91c2x5IG91dHNpZGUgYSBRR0lTIHdlYiB2aWV3LFxuICogc28gYSBwYWdlIGxlYXJucyBpbiBpdHMgZmlyc3Qgc3RhdGVtZW50IHRoYXQgaXQgaGFzIG5vIGhvc3QgdG8gdGFsayB0by5cbiAqIEluc2lkZSBvbmUsIG1lc3NhZ2VzIHNlbnQgYmVmb3JlIHRoZSBjaGFubmVsIGlzIHJlYWR5IGFyZSBxdWV1ZWQgYW5kXG4gKiBkZWxpdmVyZWQgaW4gb3JkZXIgb25jZSBpdCBpczsgYHJlYWR5YCByZWplY3RzIChhbmQgcXVldWVkIHNlbmRzIGFyZVxuICogZHJvcHBlZCkgd2hlbiB0aGUgaG9zdCByZWdpc3RlcmVkIG5vIG9iamVjdCB1bmRlciB0aGF0IG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJDaGFubmVsVHJhbnNwb3J0KFxuXHRvYmplY3ROYW1lID0gXCJicmlkZ2VcIixcbik6IFdlYkNoYW5uZWxUcmFuc3BvcnQge1xuXHRjb25zdCBwYWdlID0gc2NvcGUoKTtcblx0Y29uc3QgcXQgPSBwYWdlLnF0O1xuXHRjb25zdCBRV2ViQ2hhbm5lbCA9IHBhZ2UuUVdlYkNoYW5uZWw7XG5cdGlmIChxdCA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBRV2ViQ2hhbm5lbCAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IoXG5cdFx0XHRcIm5vdCBpbnNpZGUgYSBRR0lTIHdlYiB2aWV3OiB3aW5kb3cucXQgaXMgbWlzc2luZ1wiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgbGlzdGVuZXJzID0gbmV3IFNldDwobWVzc2FnZTogdW5rbm93bikgPT4gdm9pZD4oKTtcblx0Y29uc3QgcXVldWU6IHN0cmluZ1tdID0gW107XG5cdGxldCBvYmplY3Q6IENoYW5uZWxPYmplY3QgfCBudWxsID0gbnVsbDtcblx0bGV0IGZhaWx1cmU6IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IgfCBudWxsID0gbnVsbDtcblx0bGV0IGNsb3NlZCA9IGZhbHNlO1xuXHRjb25zdCBmb3J3YXJkID0gKHRleHQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdGlmIChjbG9zZWQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0bGV0IHBhcnNlZDogdW5rbm93bjtcblx0XHR0cnkge1xuXHRcdFx0cGFyc2VkID0gSlNPTi5wYXJzZSh0ZXh0KTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Zm9yIChjb25zdCBsaXN0ZW5lciBvZiBbLi4ubGlzdGVuZXJzXSkge1xuXHRcdFx0bGlzdGVuZXIocGFyc2VkKTtcblx0XHR9XG5cdH07XG5cdGNvbnN0IHJlYWR5ID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdG5ldyBRV2ViQ2hhbm5lbChxdC53ZWJDaGFubmVsVHJhbnNwb3J0LCAoY2hhbm5lbCkgPT4ge1xuXHRcdFx0Y29uc3QgZm91bmQgPSBjaGFubmVsLm9iamVjdHNbb2JqZWN0TmFtZV07XG5cdFx0XHRpZiAoZm91bmQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRmYWlsdXJlID0gbmV3IFFnaXNTZGtXZWJDaGFubmVsRXJyb3IoXG5cdFx0XHRcdFx0YHRoZSBob3N0IHJlZ2lzdGVyZWQgbm8gJHtKU09OLnN0cmluZ2lmeShvYmplY3ROYW1lKX0gY2hhbm5lbCBvYmplY3RgLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRxdWV1ZS5sZW5ndGggPSAwO1xuXHRcdFx0XHRyZWplY3QoZmFpbHVyZSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGlmIChjbG9zZWQpIHtcblx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRvYmplY3QgPSBmb3VuZDtcblx0XHRcdGZvdW5kLm1lc3NhZ2UuY29ubmVjdChmb3J3YXJkKTtcblx0XHRcdGZvciAoY29uc3QgdGV4dCBvZiBxdWV1ZS5zcGxpY2UoMCkpIHtcblx0XHRcdFx0Zm91bmQucmVjZWl2ZSh0ZXh0KTtcblx0XHRcdH1cblx0XHRcdHJlc29sdmUoKTtcblx0XHR9KTtcblx0fSk7XG5cdHJldHVybiB7XG5cdFx0cmVhZHksXG5cdFx0c2VuZChtZXNzYWdlOiB1bmtub3duKTogdm9pZCB7XG5cdFx0XHRpZiAoY2xvc2VkKSB7XG5cdFx0XHRcdHRocm93IG5ldyBRZ2lzU2RrV2ViQ2hhbm5lbEVycm9yKFwidGhlIHdlYiBjaGFubmVsIHRyYW5zcG9ydCBpcyBjbG9zZWRcIik7XG5cdFx0XHR9XG5cdFx0XHRpZiAoZmFpbHVyZSAhPT0gbnVsbCkge1xuXHRcdFx0XHR0aHJvdyBmYWlsdXJlO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdGV4dCA9IEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpO1xuXHRcdFx0aWYgKG9iamVjdCA9PT0gbnVsbCkge1xuXHRcdFx0XHRxdWV1ZS5wdXNoKHRleHQpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRvYmplY3QucmVjZWl2ZSh0ZXh0KTtcblx0XHR9LFxuXHRcdHN1YnNjcmliZShsaXN0ZW5lcjogKG1lc3NhZ2U6IHVua25vd24pID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcblx0XHRcdGxpc3RlbmVycy5hZGQobGlzdGVuZXIpO1xuXHRcdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdFx0bGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcik7XG5cdFx0XHR9O1xuXHRcdH0sXG5cdFx0Y2xvc2UoKTogdm9pZCB7XG5cdFx0XHRpZiAoY2xvc2VkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNsb3NlZCA9IHRydWU7XG5cdFx0XHRxdWV1ZS5sZW5ndGggPSAwO1xuXHRcdFx0bGlzdGVuZXJzLmNsZWFyKCk7XG5cdFx0XHRvYmplY3Q/Lm1lc3NhZ2UuZGlzY29ubmVjdChmb3J3YXJkKTtcblx0XHR9LFxuXHR9O1xufVxuIiwKICAgICIvKipcbiAqIGBRZ2lzU2RrYDogdGhlIHBhZ2Utc2lkZSBvYmplY3QgYSBwbHVnaW4ncyB3ZWIgdmlldyB0YWxrcyB0byBRR0lTIHRocm91Z2guXG4gKlxuICogVGhyZWUgc3RhdGVtZW50cyBjb25uZWN0IGEgcGFnZSAoZGVjaXNpb24tNDQpOlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgc2NoZW1hIGZyb20gXCIuL2JyaWRnZS5zY2hlbWFcIjtcbiAqIGNvbnN0IHFnaXMgPSBRZ2lzU2RrLmZyb21CcmlkZ2VTY2hlbWEoc2NoZW1hKTtcbiAqIGF3YWl0IHFnaXMuc2l0ZXMuc3VtbWFyeSh7IGxheWVyX2lkIH0pO1xuICogYGBgXG4gKlxuICogVGhlIHNjaGVtYSBpcyB0aGUgZ2VuZXJhdGVkIGBicmlkZ2Uuc2NoZW1hLnRzYDogdGhlIHBsdWdpbiBkZXNjcmlwdGlvbiBwbHVzXG4gKiBpdHMgYE9wZXJhdGlvbnNgIGFuZCBgU3RyZWFtc2AgdHlwZXMuIEZyb20gdGhlIGRlc2NyaXB0aW9uIHRoZSBTREsgYnVpbGRzXG4gKiBvbmUgbWV0aG9kIHBlciBkZWNsYXJlZCBhY3Rpb24gYW5kIHN0cmVhbSwgbmVzdGVkIHVuZGVyIHRoZSBzZWdtZW50cyBvZiBpdHNcbiAqIGlkIChgc2l0ZXMuc3VtbWFyeWAgaXMgYHFnaXMuc2l0ZXMuc3VtbWFyeWAsIGBidWZmZXJgIGlzIGBxZ2lzLmJ1ZmZlcmApLFxuICogYW5kIGNoZWNrcyBldmVyeSBhcmd1bWVudCwgcmVwbHkgYW5kIGV2ZW50IGFnYWluc3QgdGhlIGRlY2xhcmVkIHNjaGVtYXNcbiAqIHdpdGggdGhlIHNhbWUgcnVsZXMgdGhlIGhvc3QgYXBwbGllcyAoYHZhbGlkYXRlLnRzYCkuIEZyb20gdGhlIHR5cGVzIGl0IGdpdmVzIHRob3NlXG4gKiBtZXRob2RzIHRoZWlyIHNpZ25hdHVyZXMsIHNvIGEgd3JvbmcgYXJndW1lbnQgc2hhcGUgb3IgYW4gdW5rbm93biBvcGVyYXRpb25cbiAqIGlzIGEgY29tcGlsZSBlcnJvciBhbmQgYSB2YWx1ZSBvdXRzaWRlIHRoZSBzY2hlbWEgYXQgcnVuIHRpbWUgaXMgYVxuICoge0BsaW5rIFFnaXNTZGtDb250cmFjdEVycm9yfS5cbiAqXG4gKiBgaG9zdGAgaXMgdGhlIGN1cmF0ZWQgaG9zdCBzdXJmYWNlIG9mIGRlY2lzaW9uLTI3LCBidWlsdCBvbiB0aGUgc2FtZSBjbGllbnQsXG4gKiBwbHVzIGBncmFudGVkYDogdGhlIGhvc3Qgb3BlcmF0aW9uIGlkcyB0aGUgaGFuZHNoYWtlIGFkdmVydGlzZWQgZm9yIHRoaXNcbiAqIHZpZXcuIEEgY2FsbCBvdXRzaWRlIHRoZSBncmFudHMgaXMgbm90IHJlZnVzZWQgaGVyZSAtIHRoZSBob3N0IHJlZnVzZXMgaXQsXG4gKiBhbmQgdGhlIHBhZ2Ugc2VlcyB0aGUgaG9zdCdzIGBub3RfYXV0aG9yaXplZGAgLSBidXQgYSBwYWdlIGNhbiByZWFkIGBncmFudGVkYFxuICogYWZ0ZXIgYHJlYWR5YCB0byBoaWRlIHdoYXQgaXQgbWF5IG5vdCB1c2UuXG4gKi9cblxuaW1wb3J0IHtcblx0QnJpZGdlQ2xpZW50LFxuXHR0eXBlIEJyaWRnZVN0cmVhbVRlcm1pbmFsLFxuXHR0eXBlIEJyaWRnZVN1YnNjcmlwdGlvbixcblx0dHlwZSBJbnZva2VPcHRpb25zLFxuXHRRZ2lzU2RrQnJpZGdlUHJvdG9jb2xFcnJvcixcblx0dHlwZSBXaXJlVHJhbnNwb3J0LFxufSBmcm9tIFwiLi9icmlkZ2VcIjtcbmltcG9ydCB7XG5cdHR5cGUgQWN0aW9uRGVzY3JpcHRpb24sXG5cdFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yLFxuXHR0eXBlIFN0cmVhbURlc2NyaXB0aW9uLFxufSBmcm9tIFwiLi9kZWNsYXJhdGlvbnNcIjtcbmltcG9ydCB7XG5cdGNyZWF0ZUhvc3QsXG5cdEhPU1RfT1BFUkFUSU9OUyxcblx0dHlwZSBIb3N0T3BlcmF0aW9uSWQsXG5cdHR5cGUgSG9zdE9wZXJhdGlvbnMsXG59IGZyb20gXCIuL2dlbmVyYXRlZC9ob3N0XCI7XG5pbXBvcnQgeyBpc1BsYWluUmVjb3JkIH0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcbmltcG9ydCB0eXBlIHtcblx0QnJpZGdlU2NoZW1hLFxuXHRPcGVyYXRpb25NYXAsXG5cdE9wZXJhdGlvblNoYXBlLFxuXHRTdHJlYW1NYXAsXG5cdFN0cmVhbVNoYXBlLFxufSBmcm9tIFwiLi9zY2hlbWFcIjtcbmltcG9ydCB7IFFnaXNTZGtDb250cmFjdEVycm9yLCB2YWxpZGF0ZUFnYWluc3RTY2hlbWEgfSBmcm9tIFwiLi92YWxpZGF0ZVwiO1xuaW1wb3J0IHsgY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydCB9IGZyb20gXCIuL3dlYmNoYW5uZWxcIjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBRZ2lzU2RrLmZyb21CcmlkZ2VTY2hlbWF9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBRZ2lzU2RrT3B0aW9ucyB7XG5cdC8qKiBBIHRyYW5zcG9ydCB0byBzcGVhayB0aHJvdWdoOyBkZWZhdWx0cyB0byB0aGUgcGFnZSdzIFFXZWJDaGFubmVsLiAqL1xuXHRyZWFkb25seSB0cmFuc3BvcnQ/OiBXaXJlVHJhbnNwb3J0O1xuXHQvKiogQSBjbGllbnQgdGhlIGNhbGxlciBvd25zOyBgY2xvc2UoKWAgbGVhdmVzIGl0IG9wZW4uIEV4Y2x1ZGVzIGB0cmFuc3BvcnRgLiAqL1xuXHRyZWFkb25seSBjbGllbnQ/OiBCcmlkZ2VDbGllbnQ7XG5cdC8qKiBQZXItY2FsbCB0aW1lb3V0IGZvciBhbiBvd25lZCBjbGllbnQuICovXG5cdHJlYWRvbmx5IHRpbWVvdXRNcz86IG51bWJlcjtcblx0LyoqIFRoZSBjaGFubmVsIG9iamVjdCdzIG5hbWUgd2hlbiB0aGUgZGVmYXVsdCB0cmFuc3BvcnQgaXMgdXNlZC4gKi9cblx0cmVhZG9ubHkgY2hhbm5lbE9iamVjdD86IHN0cmluZztcbn1cblxuLyoqIEhhbmRsZXJzIGZvciBhIHR5cGVkIHN0cmVhbTogZXZlbnRzIGFzIGRlY2xhcmVkLCB0aGVuIGV4YWN0bHkgb25lIGVuZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtSGFuZGxlcnM8RT4ge1xuXHRyZWFkb25seSBvbkV2ZW50PzogKGV2ZW50OiBFKSA9PiB2b2lkO1xuXHRyZWFkb25seSBvblRlcm1pbmFsPzogKHRlcm1pbmFsOiBCcmlkZ2VTdHJlYW1UZXJtaW5hbCkgPT4gdm9pZDtcbn1cblxuLyoqIEEgbGl2ZSBzdHJlYW0sIGFzIHRoZSBjYWxsZXIgaG9sZHMgaXQuICovXG5leHBvcnQgdHlwZSBTdHJlYW1IYW5kbGUgPSBCcmlkZ2VTdWJzY3JpcHRpb247XG5cbi8qKiBUaGUgbWV0aG9kIG9uZSBkZWNsYXJlZCBhY3Rpb24gYmVjb21lczsgYW4gZW1wdHkgcmVxdWVzdCBtYXkgYmUgb21pdHRlZC4gKi9cbmV4cG9ydCB0eXBlIE9wZXJhdGlvbk1ldGhvZDxPcCBleHRlbmRzIE9wZXJhdGlvblNoYXBlPiA9XG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9CYW5uZWRUeXBlczogYHt9YCBpcyB0aGUgdGVzdCBmb3IgXCJub3RoaW5nIHJlcXVpcmVkXCJcblx0e30gZXh0ZW5kcyBPcFtcInJlcXVlc3RcIl1cblx0XHQ/IChcblx0XHRcdFx0cmVxdWVzdD86IE9wW1wicmVxdWVzdFwiXSxcblx0XHRcdFx0b3B0aW9ucz86IEludm9rZU9wdGlvbnMsXG5cdFx0XHQpID0+IFByb21pc2U8T3BbXCJyZXN1bHRcIl0+XG5cdFx0OiAoXG5cdFx0XHRcdHJlcXVlc3Q6IE9wW1wicmVxdWVzdFwiXSxcblx0XHRcdFx0b3B0aW9ucz86IEludm9rZU9wdGlvbnMsXG5cdFx0XHQpID0+IFByb21pc2U8T3BbXCJyZXN1bHRcIl0+O1xuXG4vKiogVGhlIG1ldGhvZCBvbmUgZGVjbGFyZWQgc3RyZWFtIGJlY29tZXMuICovXG5leHBvcnQgdHlwZSBTdHJlYW1NZXRob2Q8U3QgZXh0ZW5kcyBTdHJlYW1TaGFwZT4gPSAoXG5cdHJlcXVlc3Q6IFN0W1wicmVxdWVzdFwiXSxcblx0aGFuZGxlcnM6IFN0cmVhbUhhbmRsZXJzPFN0W1wiZXZlbnRcIl0+LFxuXHRvcHRpb25zPzogSW52b2tlT3B0aW9ucyxcbikgPT4gUHJvbWlzZTxTdHJlYW1IYW5kbGU+O1xuXG4vKipcbiAqIFRoZSBydW5uaW5nIHBhbGV0dGUsIHdoZW4gdGhlIGhhbmRzaGFrZSBjYXJyaWVkIG9uZSAoZGVjaXNpb24tMTYpOiB0aGVcbiAqIGBRUGFsZXR0ZWAgY29sb3VyIHJvbGVzIHRoZSBob3N0IHJlYWQsIGFzIENTUyBoZXggKGAjcnJnZ2JiYCBvclxuICogYCNycmdnYmJhYWApIGJ5IHRoZWlyIGNhbWVsLWNhc2VkIHJvbGUgbmFtZSwgYW5kIHdoZXRoZXIgdGhlIHdpbmRvdyBjb2xvdXJcbiAqIGlzIGRhcmsuIGBxZ2lzLXNkay11aWAgdHVybnMgaXQgaW50byB0aGUgYC0tcWdpcy1zZGstKmAgY3VzdG9tIHByb3BlcnRpZXM7XG4gKiBhIHBhZ2Ugb3V0c2lkZSBRR0lTIHNlZXMgYG51bGxgIGFuZCBrZWVwcyB0aGUgZG9jdW1lbnRlZCBkZWZhdWx0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRZ2lzU2RrSG9zdFRoZW1lIHtcblx0cmVhZG9ubHkgcGFsZXR0ZTogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG5cdHJlYWRvbmx5IGRhcms6IGJvb2xlYW47XG59XG5cbi8qKiBXaGF0IHRoZSBoYW5kc2hha2UgdG9sZCB0aGlzIHBhZ2UgYWJvdXQgdGhlIGhvc3QgKGRlY2lzaW9uLTI3KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUWdpc1Nka0hvc3QgZXh0ZW5kcyBIb3N0T3BlcmF0aW9ucyB7XG5cdC8qKlxuXHQgKiBUaGUgaG9zdCBvcGVyYXRpb24gaWRzIHRoZSBoYW5kc2hha2UgYWR2ZXJ0aXNlZCBmb3IgdGhpcyB2aWV3OyBlbXB0eVxuXHQgKiB1bnRpbCB7QGxpbmsgUWdpc1Nka0NvcmUucmVhZHl9IGhhcyByZXNvbHZlZC5cblx0ICovXG5cdHJlYWRvbmx5IGdyYW50ZWQ6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdO1xuXHQvKipcblx0ICogVGhlIGhvc3QncyBwYWxldHRlLCBgbnVsbGAgdW50aWwge0BsaW5rIFFnaXNTZGtDb3JlLnJlYWR5fSBoYXMgcmVzb2x2ZWRcblx0ICogYW5kIHdoZW4gdGhlIGhvc3Qgc2VudCBub25lLlxuXHQgKi9cblx0cmVhZG9ubHkgdGhlbWU6IFFnaXNTZGtIb3N0VGhlbWUgfCBudWxsO1xufVxuXG4vKiogVGhlIG1lbWJlcnMgZXZlcnkgYFFnaXNTZGtgIGhhcywgd2hhdGV2ZXIgaXRzIHNjaGVtYSBkZWNsYXJlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUWdpc1Nka0NvcmU8TyA9IE9wZXJhdGlvbk1hcCwgUyA9IFN0cmVhbU1hcD4ge1xuXHQvKiogVGhlIHNjaGVtYSB0aGlzIGluc3RhbmNlIHdhcyBidWlsdCBmcm9tLiAqL1xuXHRyZWFkb25seSBzY2hlbWE6IEJyaWRnZVNjaGVtYTxPLCBTPjtcblx0LyoqIFRoZSBjbGllbnQgdW5kZXIgdGhlIG1ldGhvZHMsIGZvciB3aGF0IGEgbWV0aG9kIGRvZXMgbm90IGNvdmVyLiAqL1xuXHRyZWFkb25seSBjbGllbnQ6IEJyaWRnZUNsaWVudDtcblx0LyoqIFRoZSBjdXJhdGVkIGhvc3Qgc3VyZmFjZSwgYW5kIHdoYXQgdGhpcyB2aWV3IHdhcyBncmFudGVkIG9mIGl0LiAqL1xuXHRyZWFkb25seSBob3N0OiBRZ2lzU2RrSG9zdDtcblx0LyoqIFJlc29sdmVzIG9uY2UgdGhlIGhhbmRzaGFrZSBhbnN3ZXJlZDsgcmVqZWN0cyB3aGVuIHRoZSBob3N0IHJlZnVzZWQgaXQuICovXG5cdHJlYWRvbmx5IHJlYWR5OiBQcm9taXNlPHZvaWQ+O1xuXHQvKiogQ2xvc2UgYW4gb3duZWQgY2xpZW50OyBhIGNsaWVudCB0aGUgY2FsbGVyIHBhc3NlZCBpbiBpcyBsZWZ0IGFsb25lLiAqL1xuXHRjbG9zZSgpOiB2b2lkO1xufVxuXG4vKiogVGhlIGZpcnN0IHNlZ21lbnQgb2YgYSBkb3R0ZWQgaWQsIG9yIHRoZSB3aG9sZSBpZCB3aGVuIGl0IGhhcyBub25lLiAqL1xudHlwZSBIZWFkPEsgZXh0ZW5kcyBzdHJpbmc+ID0gSyBleHRlbmRzIGAke2luZmVyIEh9LiR7c3RyaW5nfWAgPyBIIDogSztcblxuLyoqIFRoZSBtZW1iZXJzIG9mIGBNYCB1bmRlciBvbmUgaGVhZCwga2V5ZWQgYnkgdGhlIHJlc3Qgb2YgdGhlaXIgaWRzLiAqL1xudHlwZSBVbmRlcjxNLCBIIGV4dGVuZHMgc3RyaW5nPiA9IHtcblx0W0sgaW4ga2V5b2YgTSAmIHN0cmluZyBhcyBLIGV4dGVuZHMgYCR7SH0uJHtpbmZlciBSZXN0fWBcblx0XHQ/IFJlc3Rcblx0XHQ6IG5ldmVyXTogTVtLXTtcbn07XG5cbi8qKlxuICogVGhlIGRlY2xhcmVkIGFjdGlvbnMgYXMgYSB0cmVlOiBhIHBsYWluIGlkIGlzIGEgbWV0aG9kLCBhIGRvdHRlZCBpZCBuZXN0c1xuICogb25lIG9iamVjdCBwZXIgc2VnbWVudC4gQW4gaWQgdGhhdCBpcyBib3RoIGEgbGVhZiBhbmQgYSBwcmVmaXggb2YgYW5vdGhlclxuICogaXMgcmVmdXNlZCBhdCBydW4gdGltZSwgc28gdGhlIHR5cGUgbmVlZCBub3Qgc2F5IHdoYXQgaXQgd291bGQgbWVhbi5cbiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uVHJlZTxPPiA9IHtcblx0cmVhZG9ubHkgW0ggaW4gSGVhZDxrZXlvZiBPICYgc3RyaW5nPl06IEggZXh0ZW5kcyBrZXlvZiBPXG5cdFx0PyBPW0hdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGVcblx0XHRcdD8gT3BlcmF0aW9uTWV0aG9kPE9bSF0+XG5cdFx0XHQ6IG5ldmVyXG5cdFx0OiBPcGVyYXRpb25UcmVlPFVuZGVyPE8sIEg+Pjtcbn07XG5cbi8qKiBUaGUgZGVjbGFyZWQgc3RyZWFtcyBhcyB0aGUgc2FtZSB0cmVlLCB3aXRoIGEgc3RyZWFtIG1ldGhvZCBhdCBlYWNoIGxlYWYuICovXG5leHBvcnQgdHlwZSBTdHJlYW1UcmVlPFM+ID0ge1xuXHRyZWFkb25seSBbSCBpbiBIZWFkPGtleW9mIFMgJiBzdHJpbmc+XTogSCBleHRlbmRzIGtleW9mIFNcblx0XHQ/IFNbSF0gZXh0ZW5kcyBTdHJlYW1TaGFwZVxuXHRcdFx0PyBTdHJlYW1NZXRob2Q8U1tIXT5cblx0XHRcdDogbmV2ZXJcblx0XHQ6IFN0cmVhbVRyZWU8VW5kZXI8UywgSD4+O1xufTtcblxuLyoqXG4gKiBBIHBhZ2UncyBoYW5kbGUgb24gUUdJUzogdGhlIGNvcmUsIHBsdXMgb25lIG1ldGhvZCBwZXIgZGVjbGFyZWQgb3BlcmF0aW9uXG4gKiBuZXN0ZWQgdW5kZXIgdGhlIHNlZ21lbnRzIG9mIGl0cyBpZC5cbiAqL1xuZXhwb3J0IHR5cGUgUWdpc1NkazxPID0gT3BlcmF0aW9uTWFwLCBTID0gU3RyZWFtTWFwPiA9IFFnaXNTZGtDb3JlPE8sIFM+ICZcblx0T3BlcmF0aW9uVHJlZTxPPiAmXG5cdFN0cmVhbVRyZWU8Uz47XG5cbi8qKiBOYW1lcyB7QGxpbmsgUWdpc1Nka0NvcmV9IGtlZXBzOyBhIGRlY2xhcmVkIGlkIG1heSBub3Qgc3RhcnQgd2l0aCBvbmUuICovXG5leHBvcnQgY29uc3QgUUdJU19TREtfTUVNQkVSUzogcmVhZG9ubHkgc3RyaW5nW10gPSBPYmplY3QuZnJlZXplKFtcblx0XCJjbGllbnRcIixcblx0XCJob3N0XCIsXG5cdFwic2NoZW1hXCIsXG5cdFwicmVhZHlcIixcblx0XCJjbG9zZVwiLFxuXSk7XG5cbmNvbnN0IEhPU1RfSURTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldDxzdHJpbmc+KEhPU1RfT1BFUkFUSU9OUyk7XG5cbi8qKiBUaGUgaGFuZHNoYWtlLCBhcyBmYXIgYXMgdGhpcyBtb2R1bGUgcmVhZHMgaXQuICovXG5pbnRlcmZhY2UgSGFuZHNoYWtlIHtcblx0cmVhZG9ubHkgb3BlcmF0aW9uczogcmVhZG9ubHkgc3RyaW5nW107XG5cdHJlYWRvbmx5IGdyYW50ZWQ6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdO1xuXHRyZWFkb25seSB0aGVtZTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGw7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSGFuZHNoYWtlKHZhbHVlOiB1bmtub3duKTogSGFuZHNoYWtlIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHZhbHVlKSB8fCAhQXJyYXkuaXNBcnJheSh2YWx1ZS5vcGVyYXRpb25zKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrQnJpZGdlUHJvdG9jb2xFcnJvcihcblx0XHRcdFwiVGhlIGhhbmRzaGFrZSByZXBseSBjYXJyaWVzIG5vIG9wZXJhdGlvbnMgbGlzdFwiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3Qgb3BlcmF0aW9uczogc3RyaW5nW10gPSBbXTtcblx0Zm9yIChjb25zdCBvcGVyYXRpb24gb2YgdmFsdWUub3BlcmF0aW9ucykge1xuXHRcdGlmIChpc1BsYWluUmVjb3JkKG9wZXJhdGlvbikgJiYgdHlwZW9mIG9wZXJhdGlvbi5pZCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0b3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbi5pZCk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiB7XG5cdFx0b3BlcmF0aW9ucyxcblx0XHRncmFudGVkOiBPYmplY3QuZnJlZXplKFxuXHRcdFx0b3BlcmF0aW9ucy5maWx0ZXIoKGlkKTogaWQgaXMgSG9zdE9wZXJhdGlvbklkID0+IEhPU1RfSURTLmhhcyhpZCkpLFxuXHRcdCksXG5cdFx0dGhlbWU6IHBhcnNlVGhlbWUodmFsdWUudGhlbWUpLFxuXHR9O1xufVxuXG4vKipcbiAqIFRoZSBgdGhlbWVgIG9mIGEgaGFuZHNoYWtlLCBvciBgbnVsbGAgd2hlbiBhYnNlbnQgb3IgbWFsZm9ybWVkOiBhIHBhbGV0dGVcbiAqIHRoYXQgY2Fubm90IGJlIHJlYWQgaXMgbm8gcmVhc29uIHRvIHJlZnVzZSB0aGUgaG9zdCwgdGhlIHBhZ2UganVzdCBrZWVwc1xuICogaXRzIGRlZmF1bHRzLiBPbmx5IHN0cmluZyBjb2xvdXJzIGFyZSBrZXB0LlxuICovXG5mdW5jdGlvbiBwYXJzZVRoZW1lKHZhbHVlOiB1bmtub3duKTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGwge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQodmFsdWUpIHx8ICFpc1BsYWluUmVjb3JkKHZhbHVlLnBhbGV0dGUpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0Y29uc3QgcGFsZXR0ZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXHRmb3IgKGNvbnN0IFtyb2xlLCBjb2xvdXJdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlLnBhbGV0dGUpKSB7XG5cdFx0aWYgKHR5cGVvZiBjb2xvdXIgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHBhbGV0dGVbcm9sZV0gPSBjb2xvdXI7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRwYWxldHRlOiBPYmplY3QuZnJlZXplKHBhbGV0dGUpLFxuXHRcdGRhcms6IHZhbHVlLmRhcmsgPT09IHRydWUsXG5cdH0pO1xufVxuXG5mdW5jdGlvbiB1bndyYXBSZXF1ZXN0KFxuXHRvcGVyYXRpb246IHN0cmluZyxcblx0cmVxdWVzdDogdW5rbm93bixcbik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcblx0aWYgKHJlcXVlc3QgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB7fTtcblx0fVxuXHRpZiAoIWlzUGxhaW5SZWNvcmQocmVxdWVzdCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0NvbnRyYWN0RXJyb3Iob3BlcmF0aW9uLCBcInJlcXVlc3RcIiwgW1xuXHRcdFx0Li4udmFsaWRhdGVBZ2FpbnN0U2NoZW1hKHJlcXVlc3QsIHsgdHlwZTogXCJvYmplY3RcIiB9KSxcblx0XHRdKTtcblx0fVxuXHRyZXR1cm4gcmVxdWVzdDtcbn1cblxuZnVuY3Rpb24gY2hlY2tlZFJlcXVlc3QoXG5cdGRlc2NyaXB0aW9uOiBBY3Rpb25EZXNjcmlwdGlvbiB8IFN0cmVhbURlc2NyaXB0aW9uLFxuXHRyZXF1ZXN0OiB1bmtub3duLFxuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuXHRjb25zdCBwYXlsb2FkID0gdW53cmFwUmVxdWVzdChkZXNjcmlwdGlvbi5pZCwgcmVxdWVzdCk7XG5cdGNvbnN0IGlzc3VlcyA9IHZhbGlkYXRlQWdhaW5zdFNjaGVtYShwYXlsb2FkLCBkZXNjcmlwdGlvbi5yZXF1ZXN0KTtcblx0aWYgKGlzc3Vlcy5sZW5ndGggPiAwKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtDb250cmFjdEVycm9yKGRlc2NyaXB0aW9uLmlkLCBcInJlcXVlc3RcIiwgaXNzdWVzKTtcblx0fVxuXHRyZXR1cm4gcGF5bG9hZDtcbn1cblxuZnVuY3Rpb24gb3BlcmF0aW9uTWV0aG9kKFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0YWN0aW9uOiBBY3Rpb25EZXNjcmlwdGlvbixcbik6IChyZXF1ZXN0PzogdW5rbm93biwgb3B0aW9ucz86IEludm9rZU9wdGlvbnMpID0+IFByb21pc2U8dW5rbm93bj4ge1xuXHRyZXR1cm4gYXN5bmMgKHJlcXVlc3QsIG9wdGlvbnMpID0+IHtcblx0XHRjb25zdCBwYXlsb2FkID0gY2hlY2tlZFJlcXVlc3QoYWN0aW9uLCByZXF1ZXN0KTtcblx0XHRjb25zdCB2YWx1ZSA9IGF3YWl0IGNsaWVudC5pbnZva2UoYWN0aW9uLmlkLCBwYXlsb2FkLCBvcHRpb25zKTtcblx0XHRjb25zdCBpc3N1ZXMgPSB2YWxpZGF0ZUFnYWluc3RTY2hlbWEodmFsdWUsIGFjdGlvbi5yZXN1bHQsIHtcblx0XHRcdGFsbG93VW5rbm93bjogdHJ1ZSxcblx0XHR9KTtcblx0XHRpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrQ29udHJhY3RFcnJvcihhY3Rpb24uaWQsIFwicmVzdWx0XCIsIGlzc3Vlcyk7XG5cdFx0fVxuXHRcdHJldHVybiB2YWx1ZTtcblx0fTtcbn1cblxuZnVuY3Rpb24gc3RyZWFtTWV0aG9kKFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0c3RyZWFtOiBTdHJlYW1EZXNjcmlwdGlvbixcbik6IChcblx0cmVxdWVzdDogdW5rbm93bixcblx0aGFuZGxlcnM6IFN0cmVhbUhhbmRsZXJzPHVua25vd24+LFxuXHRvcHRpb25zPzogSW52b2tlT3B0aW9ucyxcbikgPT4gUHJvbWlzZTxTdHJlYW1IYW5kbGU+IHtcblx0cmV0dXJuIGFzeW5jIChyZXF1ZXN0LCBoYW5kbGVycywgb3B0aW9ucykgPT4ge1xuXHRcdGNvbnN0IHBheWxvYWQgPSBjaGVja2VkUmVxdWVzdChzdHJlYW0sIHJlcXVlc3QpO1xuXHRcdC8vIFRoZSB0eXBlZCBzdHJlYW0gZW5kcyBleGFjdGx5IG9uY2UsIGxpa2UgdGhlIHN1YnNjcmlwdGlvbiB1bmRlciBpdDogYVxuXHRcdC8vIGNvbnRyYWN0IHZpb2xhdGlvbiBlbmRzIGl0IGhlcmUsIGNsb3NlcyB0aGUgc3Vic2NyaXB0aW9uLCBhbmQgdGhlXG5cdFx0Ly8gYGRpc3Bvc2VkYCB0aGUgY2xpZW50IHRoZW4gcmVwb3J0cyBpcyBub3QgZGVsaXZlcmVkIGEgc2Vjb25kIHRpbWUuXG5cdFx0bGV0IGVuZGVkID0gZmFsc2U7XG5cdFx0bGV0IHZpb2xhdGVkID0gZmFsc2U7XG5cdFx0bGV0IGhhbmRsZTogU3RyZWFtSGFuZGxlIHwgbnVsbCA9IG51bGw7XG5cdFx0Y29uc3QgZW5kID0gKHRlcm1pbmFsOiBCcmlkZ2VTdHJlYW1UZXJtaW5hbCk6IHZvaWQgPT4ge1xuXHRcdFx0aWYgKGVuZGVkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGVuZGVkID0gdHJ1ZTtcblx0XHRcdGhhbmRsZXJzLm9uVGVybWluYWw/Lih0ZXJtaW5hbCk7XG5cdFx0fTtcblx0XHRoYW5kbGUgPSBhd2FpdCBjbGllbnQuc3Vic2NyaWJlKFxuXHRcdFx0c3RyZWFtLmlkLFxuXHRcdFx0cGF5bG9hZCxcblx0XHRcdHtcblx0XHRcdFx0b25FdmVudDogKGV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0aWYgKGVuZGVkKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IGRlY2xhcmVkID0gc3RyZWFtLmV2ZW50c1tldmVudC5raW5kXTtcblx0XHRcdFx0XHRjb25zdCBpc3N1ZXMgPVxuXHRcdFx0XHRcdFx0ZGVjbGFyZWQgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHQ/IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHQ6IHZhbGlkYXRlQWdhaW5zdFNjaGVtYShldmVudC5wYXlsb2FkLCBkZWNsYXJlZCwge1xuXHRcdFx0XHRcdFx0XHRcdFx0YWxsb3dVbmtub3duOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aDogW1wicGF5bG9hZFwiXSxcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRpZiAoaXNzdWVzICE9PSB1bmRlZmluZWQgJiYgaXNzdWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMub25FdmVudD8uKGV2ZW50KTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3IgPSBuZXcgUWdpc1Nka0NvbnRyYWN0RXJyb3IoXG5cdFx0XHRcdFx0XHRzdHJlYW0uaWQsXG5cdFx0XHRcdFx0XHRcImV2ZW50XCIsXG5cdFx0XHRcdFx0XHRpc3N1ZXMgPz8gW10sXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRlbmQoeyBraW5kOiBcImVycm9yXCIsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfSk7XG5cdFx0XHRcdFx0aWYgKGhhbmRsZSA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0dmlvbGF0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRoYW5kbGUuY2xvc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdG9uVGVybWluYWw6IGVuZCxcblx0XHRcdH0sXG5cdFx0XHRvcHRpb25zLFxuXHRcdCk7XG5cdFx0aWYgKHZpb2xhdGVkKSB7XG5cdFx0XHRoYW5kbGUuY2xvc2UoKTtcblx0XHR9XG5cdFx0cmV0dXJuIGhhbmRsZTtcblx0fTtcbn1cblxuZnVuY3Rpb24gYnVpbGRIb3N0KFxuXHRjbGllbnQ6IEJyaWRnZUNsaWVudCxcblx0aGFuZHNoYWtlOiAoKSA9PiBIYW5kc2hha2UgfCBudWxsLFxuKTogUWdpc1Nka0hvc3Qge1xuXHRjb25zdCBob3N0ID0gY3JlYXRlSG9zdChjbGllbnQpO1xuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0Li4uaG9zdCxcblx0XHRnZXQgZ3JhbnRlZCgpOiByZWFkb25seSBIb3N0T3BlcmF0aW9uSWRbXSB7XG5cdFx0XHRyZXR1cm4gZ3JhbnRlZChoYW5kc2hha2UoKSk7XG5cdFx0fSxcblx0XHRnZXQgdGhlbWUoKTogUWdpc1Nka0hvc3RUaGVtZSB8IG51bGwge1xuXHRcdFx0cmV0dXJuIGhhbmRzaGFrZSgpPy50aGVtZSA/PyBudWxsO1xuXHRcdH0sXG5cdH0pO1xufVxuXG5jb25zdCBOT19HUkFOVFM6IHJlYWRvbmx5IEhvc3RPcGVyYXRpb25JZFtdID0gT2JqZWN0LmZyZWV6ZShbXSk7XG5cbmZ1bmN0aW9uIGdyYW50ZWQoaGFuZHNoYWtlOiBIYW5kc2hha2UgfCBudWxsKTogcmVhZG9ubHkgSG9zdE9wZXJhdGlvbklkW10ge1xuXHRyZXR1cm4gaGFuZHNoYWtlID09PSBudWxsID8gTk9fR1JBTlRTIDogaGFuZHNoYWtlLmdyYW50ZWQ7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkPE8sIFM+KFxuXHRzY2hlbWE6IEJyaWRnZVNjaGVtYTxPLCBTPixcblx0b3B0aW9uczogUWdpc1Nka09wdGlvbnMsXG4pOiBRZ2lzU2RrPE8sIFM+IHtcblx0aWYgKG9wdGlvbnMuY2xpZW50ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50cmFuc3BvcnQgIT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFwiUWdpc1Nkay5mcm9tQnJpZGdlU2NoZW1hIHRha2VzIGEgY2xpZW50IG9yIGEgdHJhbnNwb3J0LCBub3QgYm90aFwiLFxuXHRcdCk7XG5cdH1cblx0Y29uc3Qgb3duZWQgPSBvcHRpb25zLmNsaWVudCA9PT0gdW5kZWZpbmVkO1xuXHRjb25zdCB0cmFuc3BvcnQgPVxuXHRcdG9wdGlvbnMudHJhbnNwb3J0ID8/XG5cdFx0KG9wdGlvbnMuY2xpZW50ID09PSB1bmRlZmluZWRcblx0XHRcdD8gY3JlYXRlV2ViQ2hhbm5lbFRyYW5zcG9ydChvcHRpb25zLmNoYW5uZWxPYmplY3QgPz8gXCJicmlkZ2VcIilcblx0XHRcdDogdW5kZWZpbmVkKTtcblx0Y29uc3QgY2xpZW50ID1cblx0XHRvcHRpb25zLmNsaWVudCA/P1xuXHRcdG5ldyBCcmlkZ2VDbGllbnQoXG5cdFx0XHR0cmFuc3BvcnQgYXMgV2lyZVRyYW5zcG9ydCxcblx0XHRcdG9wdGlvbnMudGltZW91dE1zID09PSB1bmRlZmluZWQgPyB7fSA6IHsgdGltZW91dE1zOiBvcHRpb25zLnRpbWVvdXRNcyB9LFxuXHRcdCk7XG5cdGxldCBoYW5kc2hha2U6IEhhbmRzaGFrZSB8IG51bGwgPSBudWxsO1xuXHRjb25zdCByZWFkeSA9IGNsaWVudC5oYW5kc2hha2UoKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdGhhbmRzaGFrZSA9IHBhcnNlSGFuZHNoYWtlKHZhbHVlKTtcblx0fSk7XG5cdC8vIEEgcGFnZSB0aGF0IG5ldmVyIGF3YWl0cyBgcmVhZHlgIHN0aWxsIHNlZXMgZXZlcnkgY2FsbCBmYWlsIG9uIGl0cyBvd247XG5cdC8vIHRoZSByZWplY3Rpb24gaXMgbm90IGxlZnQgdW5vYnNlcnZlZCBvbiB0b3Agb2YgdGhhdC5cblx0cmVhZHkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblx0Y29uc3QgbWVtYmVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG5cdFx0c2NoZW1hLFxuXHRcdGNsaWVudCxcblx0XHRob3N0OiBidWlsZEhvc3QoY2xpZW50LCAoKSA9PiBoYW5kc2hha2UpLFxuXHRcdHJlYWR5LFxuXHRcdGNsb3NlOiAoKTogdm9pZCA9PiB7XG5cdFx0XHRpZiAob3duZWQpIHtcblx0XHRcdFx0Y2xpZW50LmNsb3NlKCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0fTtcblx0Y29uc3QgbmFtZXNwYWNlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSA9IFtdO1xuXHRmb3IgKGNvbnN0IGFjdGlvbiBvZiBzY2hlbWEuYWN0aW9ucykge1xuXHRcdHBsYWNlKG1lbWJlcnMsIG5hbWVzcGFjZXMsIGFjdGlvbi5pZCwgb3BlcmF0aW9uTWV0aG9kKGNsaWVudCwgYWN0aW9uKSk7XG5cdH1cblx0Zm9yIChjb25zdCBzdHJlYW0gb2Ygc2NoZW1hLnN0cmVhbXMpIHtcblx0XHRwbGFjZShtZW1iZXJzLCBuYW1lc3BhY2VzLCBzdHJlYW0uaWQsIHN0cmVhbU1ldGhvZChjbGllbnQsIHN0cmVhbSkpO1xuXHR9XG5cdGZvciAoY29uc3QgbmFtZXNwYWNlIG9mIG5hbWVzcGFjZXMpIHtcblx0XHRPYmplY3QuZnJlZXplKG5hbWVzcGFjZSk7XG5cdH1cblx0cmV0dXJuIE9iamVjdC5mcmVlemUobWVtYmVycykgYXMgdW5rbm93biBhcyBRZ2lzU2RrPE8sIFM+O1xufVxuXG4vKipcbiAqIFB1dCBvbmUgbWV0aG9kIHdoZXJlIGl0cyBpZCBzYXlzOiBgYS5iLmNgIGJlY29tZXMgYG1lbWJlcnMuYS5iLmNgLCBidWlsZGluZ1xuICogdGhlIG9iamVjdHMgb24gdGhlIHdheS4gVHdvIGlkcyBjYW5ub3QgYm90aCBiZSBob25lc3Qgd2hlbiBvbmUgaXMgYSBwcmVmaXhcbiAqIG9mIHRoZSBvdGhlciAtIGBzaXRlc2AgY2Fubm90IGJlIGEgbWV0aG9kIGFuZCBob2xkIGBzaXRlcy5zdW1tYXJ5YCAtIGFuZCBhXG4gKiBmaXJzdCBzZWdtZW50IHRoYXQgaXMgYSBjb3JlIG1lbWJlciB3b3VsZCBoaWRlIGl0LCBzbyBib3RoIGFyZSByZWZ1c2VkLlxuICovXG5mdW5jdGlvbiBwbGFjZShcblx0bWVtYmVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG5cdG5hbWVzcGFjZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG5cdGlkOiBzdHJpbmcsXG5cdG1ldGhvZDogdW5rbm93bixcbik6IHZvaWQge1xuXHRjb25zdCBzZWdtZW50cyA9IGlkLnNwbGl0KFwiLlwiKTtcblx0aWYgKHNlZ21lbnRzLnNvbWUoKHNlZ21lbnQpID0+IHNlZ21lbnQgPT09IFwiXCIpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7aWR9OiBhbiBvcGVyYXRpb24gaWQgbWF5IG5vdCBoYXZlIGFuIGVtcHR5IHNlZ21lbnRgLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgaGVhZCA9IHNlZ21lbnRzWzBdIGFzIHN0cmluZztcblx0aWYgKFFHSVNfU0RLX01FTUJFUlMuaW5jbHVkZXMoaGVhZCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IGFuIG9wZXJhdGlvbiBpZCBtYXkgbm90IHN0YXJ0IHdpdGggYSBRZ2lzU2RrIG1lbWJlciAoJHtRR0lTX1NES19NRU1CRVJTLmpvaW4oXCIsIFwiKX0pYCxcblx0XHQpO1xuXHR9XG5cdGxldCBub2RlID0gbWVtYmVycztcblx0Zm9yIChjb25zdCBbaW5kZXgsIHNlZ21lbnRdIG9mIHNlZ21lbnRzLmVudHJpZXMoKSkge1xuXHRcdGNvbnN0IHByZWZpeCA9IHNlZ21lbnRzLnNsaWNlKDAsIGluZGV4ICsgMSkuam9pbihcIi5cIik7XG5cdFx0Y29uc3QgZXhpc3RpbmcgPSBub2RlW3NlZ21lbnRdO1xuXHRcdGlmIChpbmRleCA9PT0gc2VnbWVudHMubGVuZ3RoIC0gMSkge1xuXHRcdFx0aWYgKGV4aXN0aW5nICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0XHRcdHR5cGVvZiBleGlzdGluZyA9PT0gXCJmdW5jdGlvblwiXG5cdFx0XHRcdFx0XHQ/IGAke2lkfTogZHVwbGljYXRlIG9wZXJhdGlvbiBpZGBcblx0XHRcdFx0XHRcdDogYCR7aWR9OiBhbiBvcGVyYXRpb24gaWQgbWF5IG5vdCBiZSBhIHByZWZpeCBvZiBhbm90aGVyIGRlY2xhcmVkIGlkYCxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG5vZGVbc2VnbWVudF0gPSBtZXRob2Q7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRjb25zdCBuYW1lc3BhY2U6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cdFx0XHRuYW1lc3BhY2VzLnB1c2gobmFtZXNwYWNlKTtcblx0XHRcdG5vZGVbc2VnbWVudF0gPSBuYW1lc3BhY2U7XG5cdFx0XHRub2RlID0gbmFtZXNwYWNlO1xuXHRcdH0gZWxzZSBpZiAodHlwZW9mIGV4aXN0aW5nID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aWR9OiAke3ByZWZpeH0gaXMgYWxyZWFkeSBhbiBvcGVyYXRpb24gaWQ7IGFuIGlkIG1heSBub3QgZXh0ZW5kIGFub3RoZXJgLFxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bm9kZSA9IGV4aXN0aW5nIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIFRoZSBlbnRyeSBwb2ludDogYFFnaXNTZGsuZnJvbUJyaWRnZVNjaGVtYShzY2hlbWEpYC5cbiAqXG4gKiBBIG5hbWVzcGFjZSByYXRoZXIgdGhhbiBhIGNvbnN0YW50IHNvIHRoZSB2YWx1ZSBhbmQgdGhlIGluc3RhbmNlIHR5cGUgc2hhcmVcbiAqIG9uZSBuYW1lIHRocm91Z2ggZXZlcnkgZGVjbGFyYXRpb24gYnVuZGxlci5cbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBRZ2lzU2RrIHtcblx0LyoqXG5cdCAqIEJ1aWxkIGEgYFFnaXNTZGtgIG9uIGEgZ2VuZXJhdGVkIHNjaGVtYS5cblx0ICpcblx0ICogV2l0aG91dCBvcHRpb25zIGl0IGNvbm5lY3RzIHRvIHRoZSBwYWdlJ3MgUVdlYkNoYW5uZWwgb2JqZWN0IG5hbWVkXG5cdCAqIFwiYnJpZGdlXCIsIHdoaWNoIGlzIHdoYXQgdGhlIFB5dGhvbiBydW50aW1lIHJlZ2lzdGVyczsgYSB0ZXN0IHBhc3NlcyB0aGVcblx0ICogaGFybmVzcyBmcm9tIGBAYXJjaG9udDU2MS9xZ2lzLXNkay90ZXN0aW5nYCBhcyBgdHJhbnNwb3J0YCBpbnN0ZWFkLlxuXHQgKi9cblx0ZXhwb3J0IGZ1bmN0aW9uIGZyb21CcmlkZ2VTY2hlbWE8XG5cdFx0TyBleHRlbmRzIFJlY29yZDxrZXlvZiBPLCBPcGVyYXRpb25TaGFwZT4sXG5cdFx0UyBleHRlbmRzIFJlY29yZDxrZXlvZiBTLCBTdHJlYW1TaGFwZT4sXG5cdD4oc2NoZW1hOiBCcmlkZ2VTY2hlbWE8TywgUz4sIG9wdGlvbnM6IFFnaXNTZGtPcHRpb25zID0ge30pOiBRZ2lzU2RrPE8sIFM+IHtcblx0XHRyZXR1cm4gYnVpbGQoc2NoZW1hLCBvcHRpb25zKTtcblx0fVxufVxuIiwKICAgICIvKipcbiAqIFRoZSBicmlkZ2Ugc2NoZW1hOiBhIHBsdWdpbiBkZXNjcmlwdGlvbiB0aGF0IGFsc28gY2FycmllcyBpdHMgdHlwZXMuXG4gKlxuICogYHFnaXMtc2RrIGJyaWRnZSBnZW5lcmF0ZWAgd3JpdGVzIG9uZSBgYnJpZGdlLnNjaGVtYS50c2AgcGVyIHBsdWdpblxuICogKGRlY2lzaW9uLTQ0KS4gVGhhdCBtb2R1bGUgaGFzIG5vIGNvZGUgb2YgaXRzIG93bjogaXQgZGVjbGFyZXMgdGhlIHZhbHVlXG4gKiBpbnRlcmZhY2VzLCB0d28gbWFwcyAtIGBPcGVyYXRpb25zYCBhbmQgYFN0cmVhbXNgLCBrZXllZCBieSBvcGVyYXRpb24gaWQgLVxuICogYW5kIGVuZHMgaW4gYGRlZmluZUJyaWRnZVNjaGVtYTxPcGVyYXRpb25zLCBTdHJlYW1zPih7IC4uLmRlc2NyaXB0aW9uIH0pYC5cbiAqIFRoZSB0d28gdHlwZSBwYXJhbWV0ZXJzIG5ldmVyIGV4aXN0IGF0IHJ1biB0aW1lOyB0aGV5IHJpZGUgb24gdGhlIHJldHVybmVkXG4gKiBvYmplY3Qgc28gYFFnaXNTZGsuZnJvbUJyaWRnZVNjaGVtYShzY2hlbWEpYCBjYW4gaW5mZXIgdGhlbSwgYW5kIHRoZVxuICogZGVzY3JpcHRpb24gaXRzZWxmIGlzIHdoYXQgdGhlIFNESyB2YWxpZGF0ZXMgYWdhaW5zdC5cbiAqL1xuXG5pbXBvcnQgeyB0eXBlIFBsdWdpbkRlc2NyaXB0aW9uLCBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uIH0gZnJvbSBcIi4vZGVjbGFyYXRpb25zXCI7XG5cbi8qKiBXaGF0IG9uZSBkZWNsYXJlZCBhY3Rpb24gcHJvbWlzZXM6IGFuIG9iamVjdCBpbiwgYSB2YWx1ZSBvdXQuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvblNoYXBlIHtcblx0cmVhZG9ubHkgcmVxdWVzdDogb2JqZWN0O1xuXHRyZWFkb25seSByZXN1bHQ6IHVua25vd247XG59XG5cbi8qKiBXaGF0IG9uZSBkZWNsYXJlZCBzdHJlYW0gcHJvbWlzZXM6IGFuIG9iamVjdCBpbiwgZGlzY3JpbWluYXRlZCBldmVudHMgb3V0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1TaGFwZSB7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IG9iamVjdDtcblx0cmVhZG9ubHkgZXZlbnQ6IHsgcmVhZG9ubHkga2luZDogc3RyaW5nOyByZWFkb25seSBwYXlsb2FkOiB1bmtub3duIH07XG59XG5cbi8qKiBUaGUgZGVmYXVsdCwgdW50eXBlZCBtYXA6IGFueSBpZCwgYW55IHNoYXBlLiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uTWFwID0geyByZWFkb25seSBbaWQ6IHN0cmluZ106IE9wZXJhdGlvblNoYXBlIH07XG5cbi8qKiBUaGUgZGVmYXVsdCwgdW50eXBlZCBtYXA6IGFueSBpZCwgYW55IHNoYXBlLiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtTWFwID0geyByZWFkb25seSBbaWQ6IHN0cmluZ106IFN0cmVhbVNoYXBlIH07XG5cbi8qKlxuICogQSBwYXJzZWQgcGx1Z2luIGRlc2NyaXB0aW9uIGNhcnJ5aW5nIGl0cyBgT3BlcmF0aW9uc2AgYW5kIGBTdHJlYW1zYCB0eXBlcy5cbiAqXG4gKiBUaGUgYFwifnR5cGVzXCJgIG1lbWJlciBpcyBjb21waWxlLXRpbWUgb25seTogaXQgaXMgbmV2ZXIgc2V0LCBhbmQgYSBzY2hlbWEgaXNcbiAqIGEgZnJvemVuIHtAbGluayBQbHVnaW5EZXNjcmlwdGlvbn0gYW5kIG5vdGhpbmcgbW9yZSBhdCBydW4gdGltZS4gSXQgaXMgYVxuICogc3RyaW5nIGtleSwgbm90IGEgdW5pcXVlIHN5bWJvbCwgc28gdGhlIHR5cGUgc3RheXMgc3RydWN0dXJhbGx5IHRoZSBzYW1lXG4gKiBhY3Jvc3MgdGhlIHBhY2thZ2UncyBlbnRyeSBwb2ludHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnJpZGdlU2NoZW1hPE8gPSBPcGVyYXRpb25NYXAsIFMgPSBTdHJlYW1NYXA+XG5cdGV4dGVuZHMgUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBcIn50eXBlc1wiPzoge1xuXHRcdHJlYWRvbmx5IG9wZXJhdGlvbnM6IE87XG5cdFx0cmVhZG9ubHkgc3RyZWFtczogUztcblx0fTtcbn1cblxuLyoqIFRoZSBgT3BlcmF0aW9uc2AgbWFwIGEgc2NoZW1hIGNhcnJpZXMuICovXG5leHBvcnQgdHlwZSBPcGVyYXRpb25zT2Y8U2NoZW1hPiA9XG5cdFNjaGVtYSBleHRlbmRzIEJyaWRnZVNjaGVtYTxpbmZlciBPLCB1bmtub3duPiA/IE8gOiBuZXZlcjtcblxuLyoqIFRoZSBgU3RyZWFtc2AgbWFwIGEgc2NoZW1hIGNhcnJpZXMuICovXG5leHBvcnQgdHlwZSBTdHJlYW1zT2Y8U2NoZW1hPiA9XG5cdFNjaGVtYSBleHRlbmRzIEJyaWRnZVNjaGVtYTx1bmtub3duLCBpbmZlciBTPiA/IFMgOiBuZXZlcjtcblxuLyoqXG4gKiBQYXJzZSBhIGRlc2NyaXB0aW9uIGFuZCB0eXBlIGl0OyB0aGUgZ2VuZXJhdGVkIG1vZHVsZSBpcyB0aGUgb25seSBjYWxsZXIuXG4gKlxuICogVGhlIGRlc2NyaXB0aW9uIGlzIGNoZWNrZWQgdGhlIHdheSBhbnkgZGVzY3JpcHRpb24gaXMgKGBzY2hlbWFfdmVyc2lvbmAsXG4gKiBpZHMsIGhhbmRsZXJzLCBkZWNsYXJlZCBzdHJlYW1zKSwgc28gYSBoYW5kLWVkaXRlZCBvciBzdGFsZSBtb2R1bGUgZmFpbHNcbiAqIGhlcmUsIGF0IGltcG9ydCwgcmF0aGVyIHRoYW4gb24gdGhlIGZpcnN0IGNhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVCcmlkZ2VTY2hlbWE8XG5cdE8gZXh0ZW5kcyBSZWNvcmQ8a2V5b2YgTywgT3BlcmF0aW9uU2hhcGU+LFxuXHRTIGV4dGVuZHMgUmVjb3JkPGtleW9mIFMsIFN0cmVhbVNoYXBlPixcbj4oaW5wdXQ6IHN0cmluZyB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pik6IEJyaWRnZVNjaGVtYTxPLCBTPiB7XG5cdHJldHVybiBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uKGlucHV0KSBhcyBCcmlkZ2VT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RUFDbkU7QUFBQSxFQUNBLFdBQVcsYUFBYSxZQUFZO0FBQUEsSUFDbkMsT0FBTyxPQUFPLFNBQVM7QUFBQSxFQUN4QjtBQUFBLEVBQ0EsT0FBTyxPQUFPLE9BQU8sT0FBTztBQUFBO0FBUzdCLFNBQVMsS0FBSyxDQUNiLFNBQ0EsWUFDQSxJQUNBLFFBQ087QUFBQSxFQUNQLE1BQU0sV0FBVyxHQUFHLE1BQU0sR0FBRztBQUFBLEVBQzdCLElBQUksU0FBUyxLQUFLLENBQUMsWUFBWSxZQUFZLEVBQUUsR0FBRztBQUFBLElBQy9DLE1BQU0sSUFBSSx5QkFDVCxHQUFHLG1EQUNKO0FBQUEsRUFDRDtBQUFBLEVBQ0EsTUFBTSxPQUFPLFNBQVM7QUFBQSxFQUN0QixJQUFJLGlCQUFpQixTQUFTLElBQUksR0FBRztBQUFBLElBQ3BDLE1BQU0sSUFBSSx5QkFDVCxHQUFHLDREQUE0RCxpQkFBaUIsS0FBSyxJQUFJLElBQzFGO0FBQUEsRUFDRDtBQUFBLEVBQ0EsSUFBSSxPQUFPO0FBQUEsRUFDWCxZQUFZLE9BQU8sWUFBWSxTQUFTLFFBQVEsR0FBRztBQUFBLElBQ2xELE1BQU0sU0FBUyxTQUFTLE1BQU0sR0FBRyxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUc7QUFBQSxJQUNwRCxNQUFNLFdBQVcsS0FBSztBQUFBLElBQ3RCLElBQUksVUFBVSxTQUFTLFNBQVMsR0FBRztBQUFBLE1BQ2xDLElBQUksYUFBYSxXQUFXO0FBQUEsUUFDM0IsTUFBTSxJQUFJLHlCQUNULE9BQU8sYUFBYSxhQUNqQixHQUFHLCtCQUNILEdBQUcsZ0VBQ1A7QUFBQSxNQUNEO0FBQUEsTUFDQSxLQUFLLFdBQVc7QUFBQSxNQUNoQjtBQUFBLElBQ0Q7QUFBQSxJQUNBLElBQUksYUFBYSxXQUFXO0FBQUEsTUFDM0IsTUFBTSxZQUFxQyxDQUFDO0FBQUEsTUFDNUMsV0FBVyxLQUFLLFNBQVM7QUFBQSxNQUN6QixLQUFLLFdBQVc7QUFBQSxNQUNoQixPQUFPO0FBQUEsSUFDUixFQUFPLFNBQUksT0FBTyxhQUFhLFlBQVk7QUFBQSxNQUMxQyxNQUFNLElBQUkseUJBQ1QsR0FBRyxPQUFPLGlFQUNYO0FBQUEsSUFDRCxFQUFPO0FBQUEsTUFDTixPQUFPO0FBQUE7QUFBQSxFQUVUO0FBQUE7QUFTTSxJQUFVO0FBQUEsQ0FBVixDQUFVLFlBQVY7QUFBQSxFQVFDLFNBQVMsZ0JBR2YsQ0FBQyxRQUE0QixVQUEwQixDQUFDLEdBQWtCO0FBQUEsSUFDMUUsT0FBTyxNQUFNLFFBQVEsT0FBTztBQUFBO0FBQUEsRUFKdEIsUUFBUztBQUFBLEdBUkE7O0FDcGFWLFNBQVMsa0JBR2YsQ0FBQyxPQUF1RTtBQUFBLEVBQ3hFLE9BQU8sd0JBQXVCLEtBQUs7QUFBQTsiLAogICJkZWJ1Z0lkIjogIjUwN0M0N0E1NEE4N0JEMUI2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
|