@archont561/qgis-sdk 0.0.0 → 0.4.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/LICENSE +21 -0
- package/README.md +40 -30
- package/dist/bridge.d.ts +2 -0
- package/dist/bridge.js +31 -0
- package/dist/host.d.ts +2 -0
- package/dist/host.js +51 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +732 -0
- package/dist/react.d.ts +137 -0
- package/dist/react.js +214 -0
- package/dist/shared/chunk-2hwva3a3.js +14 -0
- package/dist/shared/chunk-8gawbn19.js +433 -0
- package/dist/shared/chunk-jjx14tgd.d.ts +55 -0
- package/dist/shared/chunk-khemhx86.d.ts +158 -0
- package/dist/shared/chunk-pdj2fxjb.d.ts +17 -0
- package/dist/shared/chunk-tmca1ynt.d.ts +87 -0
- package/dist/shared/chunk-vqyymknv.js +414 -0
- package/dist/shared/chunk-wtv4vt4q.d.ts +280 -0
- package/dist/testing.d.ts +131 -0
- package/dist/testing.js +366 -0
- package/package.json +62 -8
package/dist/testing.js
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HOST_SCHEMA_VERSION2,
|
|
3
|
+
HOST_OPERATIONS2
|
|
4
|
+
} from "./shared/chunk-vqyymknv.js";
|
|
5
|
+
import {
|
|
6
|
+
QgisSdkError2
|
|
7
|
+
} from "./shared/chunk-2hwva3a3.js";
|
|
8
|
+
|
|
9
|
+
// src/testing.ts
|
|
10
|
+
var PROTOCOL = 1;
|
|
11
|
+
var SUBSCRIPTION_CAPACITY = 64;
|
|
12
|
+
function fault(code, message) {
|
|
13
|
+
return Object.freeze({ fault: Object.freeze({ code, message }) });
|
|
14
|
+
}
|
|
15
|
+
function isFault(value) {
|
|
16
|
+
return typeof value === "object" && value !== null && "fault" in value && typeof value.fault === "object";
|
|
17
|
+
}
|
|
18
|
+
var SILENCE = Symbol("qgis-sdk-harness-silence");
|
|
19
|
+
|
|
20
|
+
class QgisSdkBridgeHarnessError extends QgisSdkError2 {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message, "harness_error");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class Harness {
|
|
27
|
+
granted;
|
|
28
|
+
plugin;
|
|
29
|
+
listenerSet = new Set;
|
|
30
|
+
expectations = [];
|
|
31
|
+
recorded = [];
|
|
32
|
+
unexpectedCalls = [];
|
|
33
|
+
streams = new Map;
|
|
34
|
+
problems = [];
|
|
35
|
+
outbox = [];
|
|
36
|
+
draining = null;
|
|
37
|
+
streamCounter = 0;
|
|
38
|
+
constructor(options, plugin) {
|
|
39
|
+
this.granted = Object.freeze([...options.granted ?? HOST_OPERATIONS2]);
|
|
40
|
+
this.plugin = plugin;
|
|
41
|
+
}
|
|
42
|
+
get calls() {
|
|
43
|
+
return [...this.recorded];
|
|
44
|
+
}
|
|
45
|
+
get unexpected() {
|
|
46
|
+
return [...this.unexpectedCalls];
|
|
47
|
+
}
|
|
48
|
+
get openSubscriptions() {
|
|
49
|
+
return [...this.streams.values()].filter((stream) => stream.open).map((stream) => stream.id);
|
|
50
|
+
}
|
|
51
|
+
get listeners() {
|
|
52
|
+
return this.listenerSet.size;
|
|
53
|
+
}
|
|
54
|
+
subscribe(listener) {
|
|
55
|
+
this.listenerSet.add(listener);
|
|
56
|
+
return () => {
|
|
57
|
+
this.listenerSet.delete(listener);
|
|
58
|
+
if (this.listenerSet.size === 0) {
|
|
59
|
+
for (const stream of this.streams.values()) {
|
|
60
|
+
stream.open = false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
send(message) {
|
|
66
|
+
const envelope = this.parseEnvelope(message);
|
|
67
|
+
if (envelope.kind === "unsubscribe") {
|
|
68
|
+
this.closeFromPage(envelope);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (envelope.kind === "handshake") {
|
|
72
|
+
this.answerHandshake(envelope);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const expectation = this.take(envelope.kind, envelope.operation);
|
|
76
|
+
if (expectation === undefined) {
|
|
77
|
+
this.unexpectedCalls.push(envelope);
|
|
78
|
+
this.deliverFailure(envelope.callId, "unexpected_call", `no expectation covers ${envelope.kind} ${JSON.stringify(envelope.operation)}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (expectation.kind === "invoke") {
|
|
82
|
+
this.answerInvoke(envelope, expectation);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.answerSubscribe(envelope, expectation);
|
|
86
|
+
}
|
|
87
|
+
expectInvoke(operation, handler) {
|
|
88
|
+
this.expectations.push({
|
|
89
|
+
kind: "invoke",
|
|
90
|
+
operation,
|
|
91
|
+
handler
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
expectSubscribe(operation, script, options = {}) {
|
|
95
|
+
this.expectations.push({
|
|
96
|
+
kind: "subscribe",
|
|
97
|
+
operation,
|
|
98
|
+
script,
|
|
99
|
+
options
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
deliver(raw) {
|
|
103
|
+
this.outbox.push(raw);
|
|
104
|
+
this.drain();
|
|
105
|
+
}
|
|
106
|
+
settled() {
|
|
107
|
+
return this.draining ?? Promise.resolve();
|
|
108
|
+
}
|
|
109
|
+
assertSatisfied() {
|
|
110
|
+
const problems = [...this.problems];
|
|
111
|
+
if (this.expectations.length > 0) {
|
|
112
|
+
const unmet = this.expectations.map((expectation) => `${expectation.kind} ${expectation.operation}`);
|
|
113
|
+
problems.push(`unmet expectations: ${unmet.join(", ")}`);
|
|
114
|
+
}
|
|
115
|
+
if (this.unexpectedCalls.length > 0) {
|
|
116
|
+
const unexpected = this.unexpectedCalls.map((call) => `${call.kind} ${call.operation}`);
|
|
117
|
+
problems.push(`unexpected calls: ${unexpected.join(", ")}`);
|
|
118
|
+
}
|
|
119
|
+
const open = this.openSubscriptions;
|
|
120
|
+
if (open.length > 0) {
|
|
121
|
+
problems.push(`open subscriptions: ${open.join(", ")}`);
|
|
122
|
+
}
|
|
123
|
+
if (problems.length > 0) {
|
|
124
|
+
throw new QgisSdkBridgeHarnessError(problems.join("; "));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
answerHandshake(call) {
|
|
128
|
+
const declared = [
|
|
129
|
+
...(this.plugin?.actions ?? []).map((action) => action.id),
|
|
130
|
+
...(this.plugin?.streams ?? []).map((stream) => stream.id)
|
|
131
|
+
];
|
|
132
|
+
this.deliver({
|
|
133
|
+
protocol: PROTOCOL,
|
|
134
|
+
call_id: call.callId,
|
|
135
|
+
ok: true,
|
|
136
|
+
value: {
|
|
137
|
+
protocol: PROTOCOL,
|
|
138
|
+
generation: 0,
|
|
139
|
+
plugin: this.plugin,
|
|
140
|
+
host_schema_version: HOST_SCHEMA_VERSION2,
|
|
141
|
+
operations: [...declared, ...this.granted].map((id) => ({
|
|
142
|
+
id,
|
|
143
|
+
title: id
|
|
144
|
+
}))
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
answerInvoke(call, expectation) {
|
|
149
|
+
this.resolveHandler(call, () => expectation.handler(call.payload ?? {})).then((reply) => {
|
|
150
|
+
if (reply === SILENCE) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (isFault(reply)) {
|
|
154
|
+
this.deliverFailure(call.callId, reply.fault.code, reply.fault.message);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.deliver({
|
|
158
|
+
protocol: PROTOCOL,
|
|
159
|
+
call_id: call.callId,
|
|
160
|
+
ok: true,
|
|
161
|
+
value: reply
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
answerSubscribe(call, expectation) {
|
|
166
|
+
this.streamCounter += 1;
|
|
167
|
+
const open = {
|
|
168
|
+
id: `s${this.streamCounter}`,
|
|
169
|
+
operation: call.operation,
|
|
170
|
+
seq: 0,
|
|
171
|
+
open: false
|
|
172
|
+
};
|
|
173
|
+
const held = [];
|
|
174
|
+
let sink = (frame) => {
|
|
175
|
+
held.push(frame);
|
|
176
|
+
};
|
|
177
|
+
const stream = this.scripted(open, (frame) => sink(frame));
|
|
178
|
+
const ack = expectation.options.ack ?? (() => Promise.resolve());
|
|
179
|
+
ack().then(() => this.resolveHandler(call, () => {
|
|
180
|
+
open.open = true;
|
|
181
|
+
return expectation.script(call.payload ?? {}, stream);
|
|
182
|
+
})).then((outcome) => {
|
|
183
|
+
if (outcome === SILENCE || isFault(outcome)) {
|
|
184
|
+
open.open = false;
|
|
185
|
+
held.length = 0;
|
|
186
|
+
if (isFault(outcome)) {
|
|
187
|
+
this.deliverFailure(call.callId, outcome.fault.code, outcome.fault.message);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (this.listenerSet.size === 0) {
|
|
192
|
+
open.open = false;
|
|
193
|
+
held.length = 0;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.streams.set(open.id, open);
|
|
197
|
+
this.deliver({
|
|
198
|
+
protocol: PROTOCOL,
|
|
199
|
+
call_id: call.callId,
|
|
200
|
+
ok: true,
|
|
201
|
+
value: {
|
|
202
|
+
subscription_id: open.id,
|
|
203
|
+
capacity: SUBSCRIPTION_CAPACITY
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
sink = (frame) => this.deliver(frame);
|
|
207
|
+
for (const frame of held) {
|
|
208
|
+
sink(frame);
|
|
209
|
+
}
|
|
210
|
+
held.length = 0;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
resolveHandler(call, run) {
|
|
214
|
+
return new Promise((resolve) => {
|
|
215
|
+
resolve(run());
|
|
216
|
+
}).catch((error) => {
|
|
217
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
218
|
+
this.problems.push(`handler for ${call.kind} ${call.operation} threw: ${message}`);
|
|
219
|
+
return fault("harness_error", message);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
scripted(open, sink) {
|
|
223
|
+
const requireOpen = (verb) => {
|
|
224
|
+
if (!open.open) {
|
|
225
|
+
throw new QgisSdkBridgeHarnessError(`cannot ${verb} on subscription ${open.id}: it is not open`);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
id: open.id,
|
|
230
|
+
operation: open.operation,
|
|
231
|
+
get open() {
|
|
232
|
+
return open.open;
|
|
233
|
+
},
|
|
234
|
+
emit: (kind, payload) => {
|
|
235
|
+
requireOpen("emit");
|
|
236
|
+
sink({
|
|
237
|
+
protocol: PROTOCOL,
|
|
238
|
+
subscription_id: open.id,
|
|
239
|
+
seq: open.seq,
|
|
240
|
+
event: { kind, payload }
|
|
241
|
+
});
|
|
242
|
+
open.seq += 1;
|
|
243
|
+
},
|
|
244
|
+
end: (terminal) => {
|
|
245
|
+
requireOpen("end");
|
|
246
|
+
open.open = false;
|
|
247
|
+
sink({
|
|
248
|
+
protocol: PROTOCOL,
|
|
249
|
+
subscription_id: open.id,
|
|
250
|
+
seq: open.seq,
|
|
251
|
+
terminal
|
|
252
|
+
});
|
|
253
|
+
open.seq += 1;
|
|
254
|
+
},
|
|
255
|
+
skip: (frames) => {
|
|
256
|
+
requireOpen("skip");
|
|
257
|
+
open.seq += frames;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
closeFromPage(call) {
|
|
262
|
+
const open = call.subscriptionId === undefined ? undefined : this.streams.get(call.subscriptionId);
|
|
263
|
+
const disposed = open?.open === true;
|
|
264
|
+
if (open !== undefined) {
|
|
265
|
+
open.open = false;
|
|
266
|
+
}
|
|
267
|
+
this.deliver({
|
|
268
|
+
protocol: PROTOCOL,
|
|
269
|
+
call_id: call.callId,
|
|
270
|
+
ok: true,
|
|
271
|
+
value: { disposed }
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
deliverFailure(callId, code, message) {
|
|
275
|
+
this.deliver({
|
|
276
|
+
protocol: PROTOCOL,
|
|
277
|
+
call_id: callId,
|
|
278
|
+
ok: false,
|
|
279
|
+
error: { code, message }
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
drain() {
|
|
283
|
+
if (this.draining !== null) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this.draining = (async () => {
|
|
287
|
+
while (this.outbox.length > 0) {
|
|
288
|
+
await Promise.resolve();
|
|
289
|
+
const message = this.outbox.shift();
|
|
290
|
+
for (const listener of [...this.listenerSet]) {
|
|
291
|
+
listener(message);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
this.draining = null;
|
|
295
|
+
})();
|
|
296
|
+
}
|
|
297
|
+
take(kind, operation) {
|
|
298
|
+
const index = this.expectations.findIndex((expectation) => expectation.kind === kind && expectation.operation === operation);
|
|
299
|
+
if (index === -1) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
return this.expectations.splice(index, 1)[0];
|
|
303
|
+
}
|
|
304
|
+
parseEnvelope(message) {
|
|
305
|
+
if (typeof message !== "object" || message === null) {
|
|
306
|
+
throw new QgisSdkBridgeHarnessError("the client sent a non-object");
|
|
307
|
+
}
|
|
308
|
+
const raw = message;
|
|
309
|
+
if (raw.protocol !== PROTOCOL) {
|
|
310
|
+
throw new QgisSdkBridgeHarnessError(`the client speaks protocol ${String(raw.protocol)}; the harness fakes ${PROTOCOL}`);
|
|
311
|
+
}
|
|
312
|
+
if (typeof raw.call_id !== "string" || raw.call_id.length === 0) {
|
|
313
|
+
throw new QgisSdkBridgeHarnessError("the client sent no call_id");
|
|
314
|
+
}
|
|
315
|
+
const callId = raw.call_id;
|
|
316
|
+
if (raw.kind === "unsubscribe") {
|
|
317
|
+
const subscriptionId = raw.subscription_id;
|
|
318
|
+
if (typeof subscriptionId !== "string") {
|
|
319
|
+
throw new QgisSdkBridgeHarnessError(`${callId}: unsubscribe names no subscription_id`);
|
|
320
|
+
}
|
|
321
|
+
const call = {
|
|
322
|
+
callId,
|
|
323
|
+
kind: "unsubscribe",
|
|
324
|
+
operation: this.streams.get(subscriptionId)?.operation ?? "",
|
|
325
|
+
subscriptionId
|
|
326
|
+
};
|
|
327
|
+
this.recorded.push(call);
|
|
328
|
+
return call;
|
|
329
|
+
}
|
|
330
|
+
if (raw.kind === "handshake") {
|
|
331
|
+
const call = { callId, kind: "handshake", operation: "" };
|
|
332
|
+
this.recorded.push(call);
|
|
333
|
+
return call;
|
|
334
|
+
}
|
|
335
|
+
if (raw.kind !== "invoke" && raw.kind !== "subscribe") {
|
|
336
|
+
throw new QgisSdkBridgeHarnessError(`${callId}: ${String(raw.kind)} is not a bridge envelope kind`);
|
|
337
|
+
}
|
|
338
|
+
if (typeof raw.operation !== "string") {
|
|
339
|
+
throw new QgisSdkBridgeHarnessError(`${callId}: operation must be a string`);
|
|
340
|
+
}
|
|
341
|
+
const payload = typeof raw.payload === "object" && raw.payload !== null ? raw.payload : {};
|
|
342
|
+
const call = {
|
|
343
|
+
callId,
|
|
344
|
+
kind: raw.kind,
|
|
345
|
+
operation: raw.operation,
|
|
346
|
+
payload
|
|
347
|
+
};
|
|
348
|
+
this.recorded.push(call);
|
|
349
|
+
return call;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function createBridgeHarness(first = {}, second = {}) {
|
|
353
|
+
if ("schema_version" in first) {
|
|
354
|
+
return new Harness(second, first);
|
|
355
|
+
}
|
|
356
|
+
return new Harness(first, null);
|
|
357
|
+
}
|
|
358
|
+
export {
|
|
359
|
+
QgisSdkBridgeHarnessError,
|
|
360
|
+
SILENCE,
|
|
361
|
+
createBridgeHarness,
|
|
362
|
+
fault
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
//# debugId=A423121C49C80BCD64756E2164756E21
|
|
366
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3Rlc3RpbmcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBBbiBpbmplY3RlZCBwZXItY2xpZW50IGhhcm5lc3MgZm9yIHRoZSBicmlkZ2UgKFRBU0stMTgsIGRlY2lzaW9uLTIzKS5cbiAqXG4gKiBUaGUgaGFybmVzcyBpcyBhIHtAbGluayBXaXJlVHJhbnNwb3J0fTogYSBwYWdlJ3Mgb3duIGBCcmlkZ2VDbGllbnRgIHNwZWFrcyB0b1xuICogaXQgZXhhY3RseSBhcyBpdCB3b3VsZCB0byBhIFFXZWJDaGFubmVsLCBhbmQgYSB0ZXN0IHNjcmlwdHMgd2hhdCB0aGUgaG9zdFxuICogYW5zd2VycyAtIHR5cGVkIHJlcGxpZXMsIGZhdWx0cywgc2lsZW5jZSwgc3RyZWFtIGV2ZW50cywgdGVybWluYWxzLCBnYXBzIC1cbiAqIHdpdGhvdXQgdG91Y2hpbmcgYSBicm93c2VyIGdsb2JhbCBvciBhIHJ1bm5pbmcgUUdJUy4gVHdvIGhhcm5lc3NlcyBhcmUgdHdvXG4gKiBob3N0cywgc28gaXNvbGF0aW9uIGJldHdlZW4gY2xpZW50cyBpcyBhIGZhY3QgYSB0ZXN0IGNhbiBwcm92ZS5cbiAqXG4gKiBXaGF0IGl0IHByb3ZlcyBpcyBib3VuZGVkLiBBIGdyZWVuIHRlc3QgaGVyZSBzYXlzIHRoZSBwYWdlIGhhbmRsZXMgdGhlXG4gKiBmcmFtZXMgYSBob3N0ICpjb3VsZCogc2VuZDsgaXQgc2F5cyBub3RoaW5nIGFib3V0IHdoYXQgYSBRV2ViRW5naW5lVmlldyBvclxuICogYSByZWFsIGhvc3QgZG9lcy4gVGhhdCBldmlkZW5jZSBsaXZlcyBpbiB0aGUgUHl0aG9uIHN1aXRlIGFuZCBpbiB0aGVcbiAqIHF1YWxpZmljYXRpb24gaGFybmVzc2VzIHJlY29yZGVkIGluIGRvYy0xNC4gS2VlcCB0aGUgdHdvIGFwYXJ0IGluIHJlcG9ydHMuXG4gKlxuICogRXZlcnl0aGluZyB0aGUgaGFybmVzcyBzZW5kcyBpcyBkZWxpdmVyZWQgYXN5bmNocm9ub3VzbHksIG9uZSBtZXNzYWdlIHBlclxuICogbWljcm90YXNrLCBzbyBhIHJlcGx5IG5ldmVyIHJlLWVudGVycyB0aGUgY2xpZW50IGluc2lkZSBpdHMgb3duIGBzZW5kYC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG5cdEJyaWRnZVN0cmVhbVRlcm1pbmFsLFxuXHRTdHJlYW1FdmVudEtpbmQsXG5cdFdpcmVUcmFuc3BvcnQsXG59IGZyb20gXCIuL2JyaWRnZVwiO1xuaW1wb3J0IHsgUWdpc1Nka0Vycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQge1xuXHRIT1NUX09QRVJBVElPTlMsXG5cdEhPU1RfU0NIRU1BX1ZFUlNJT04sXG5cdHR5cGUgSG9zdE9wZXJhdGlvbklkLFxufSBmcm9tIFwiLi9nZW5lcmF0ZWQvaG9zdFwiO1xuaW1wb3J0IHR5cGUgeyBCcmlkZ2VTY2hlbWEsIE9wZXJhdGlvblNoYXBlLCBTdHJlYW1TaGFwZSB9IGZyb20gXCIuL3NjaGVtYVwiO1xuXG5jb25zdCBQUk9UT0NPTCA9IDE7XG5jb25zdCBTVUJTQ1JJUFRJT05fQ0FQQUNJVFkgPSA2NDtcblxuLyoqIEEgc2NyaXB0ZWQgaG9zdCBmYWlsdXJlLCByZXR1cm5lZCBmcm9tIGFuIGV4cGVjdGF0aW9uJ3MgaGFuZGxlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NyaXB0ZWRGYXVsdCB7XG5cdHJlYWRvbmx5IGZhdWx0OiB7IHJlYWRvbmx5IGNvZGU6IHN0cmluZzsgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nIH07XG59XG5cbi8qKiBTY3JpcHQgYSBmYWlsdXJlIHJlcGx5IHdpdGggdGhpcyBjb2RlIGFuZCBtZXNzYWdlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhdWx0KGNvZGU6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogU2NyaXB0ZWRGYXVsdCB7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHsgZmF1bHQ6IE9iamVjdC5mcmVlemUoeyBjb2RlLCBtZXNzYWdlIH0pIH0pO1xufVxuXG5mdW5jdGlvbiBpc0ZhdWx0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU2NyaXB0ZWRGYXVsdCB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG5cdFx0dmFsdWUgIT09IG51bGwgJiZcblx0XHRcImZhdWx0XCIgaW4gdmFsdWUgJiZcblx0XHR0eXBlb2YgKHZhbHVlIGFzIFNjcmlwdGVkRmF1bHQpLmZhdWx0ID09PSBcIm9iamVjdFwiXG5cdCk7XG59XG5cbi8qKiBSZXR1cm4gdGhpcyBmcm9tIGEgaGFuZGxlciB0byBuZXZlciBhbnN3ZXIsIHNvIHRoZSBjbGllbnQncyB0aW1lb3V0IHNwZWFrcy4gKi9cbmV4cG9ydCBjb25zdCBTSUxFTkNFOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sKFwicWdpcy1zZGstaGFybmVzcy1zaWxlbmNlXCIpO1xuXG4vKiogQSBzdWJzY3JpcHRpb24gdGhlIHNjcmlwdCB0dXJucyBkb3duOiBhIGZhdWx0IHJlcGx5LCBvciBubyByZXBseSBhdCBhbGwuICovXG5leHBvcnQgdHlwZSBTY3JpcHRlZFJlZnVzYWwgPSBTY3JpcHRlZEZhdWx0IHwgdHlwZW9mIFNJTEVOQ0U7XG5cbi8qKlxuICogQSBzdWJzY3JpYmUgZXhwZWN0YXRpb24ncyBzY3JpcHQ6IGVtaXQgb24gYHN0cmVhbWAgbm93IG9yIGxhdGVyLCBvciByZXR1cm5cbiAqIGEgcmVmdXNhbCBpbnN0ZWFkIG9mIGFja25vd2xlZGdpbmcuXG4gKi9cbmV4cG9ydCB0eXBlIFN1YnNjcmliZVNjcmlwdDxSZXEgZXh0ZW5kcyBvYmplY3Q+ID0gKFxuXHRwYXlsb2FkOiBSZXEsXG5cdHN0cmVhbTogU2NyaXB0ZWRTdHJlYW0sXG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9Db25mdXNpbmdWb2lkVHlwZTogYSBzY3JpcHQgdGhhdCBvbmx5IGVtaXRzIHJldHVybnMgbm90aGluZ1xuKSA9PiBTY3JpcHRlZFJlZnVzYWwgfCB2b2lkO1xuXG4vKiogV2hhdCBhbiBpbnZva2UgZXhwZWN0YXRpb24gbWF5IGFuc3dlciB3aXRoLiAqL1xuZXhwb3J0IHR5cGUgU2NyaXB0ZWRSZXBseTxSZXM+ID1cblx0fCBSZXNcblx0fCBTY3JpcHRlZEZhdWx0XG5cdHwgdHlwZW9mIFNJTEVOQ0Vcblx0fCBQcm9taXNlPFJlcyB8IFNjcmlwdGVkRmF1bHQgfCB0eXBlb2YgU0lMRU5DRT47XG5cbi8qKiBBIG1lc3NhZ2UgdGhlIGNsaWVudCBzZW50LCBhcyB0aGUgaGFybmVzcyByZWNvcmRlZCBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkZWRDYWxsIHtcblx0cmVhZG9ubHkgY2FsbElkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGtpbmQ6IFwiaW52b2tlXCIgfCBcInN1YnNjcmliZVwiIHwgXCJ1bnN1YnNjcmliZVwiIHwgXCJoYW5kc2hha2VcIjtcblx0LyoqIEVtcHR5IGZvciBhIGhhbmRzaGFrZSwgd2hpY2ggbmFtZXMgbm8gb3BlcmF0aW9uLiAqL1xuXHRyZWFkb25seSBvcGVyYXRpb246IHN0cmluZztcblx0cmVhZG9ubHkgcGF5bG9hZD86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgc3Vic2NyaXB0aW9uSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT25lIHNjcmlwdGVkIHN1YnNjcmlwdGlvbi4gRnJhbWVzIGNhcnJ5IHRoZSBzZXF1ZW5jZSB0aGUga2VybmVsIGNoZWNrcywgc29cbiAqIGBza2lwYCBpcyB0aGUgb25lIHdheSB0byBzY3JpcHQgYSBnYXAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NyaXB0ZWRTdHJlYW0ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSBvcGVyYXRpb246IHN0cmluZztcblx0LyoqIGBmYWxzZWAgb25jZSB0aGUgaG9zdCBlbmRlZCBpdCBvciB0aGUgcGFnZSBjbG9zZWQgaXQuICovXG5cdHJlYWRvbmx5IG9wZW46IGJvb2xlYW47XG5cdGVtaXQoa2luZDogU3RyZWFtRXZlbnRLaW5kLCBwYXlsb2FkOiB1bmtub3duKTogdm9pZDtcblx0ZW5kKHRlcm1pbmFsOiBCcmlkZ2VTdHJlYW1UZXJtaW5hbCk6IHZvaWQ7XG5cdC8qKiBBZHZhbmNlIHRoZSBzZXF1ZW5jZSB3aXRob3V0IHNlbmRpbmcsIHNvIHRoZSBuZXh0IGZyYW1lIGlzIGEgZ2FwLiAqL1xuXHRza2lwKGZyYW1lczogbnVtYmVyKTogdm9pZDtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIGEgc3Vic2NyaWJlIGV4cGVjdGF0aW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdWJzY3JpYmVPcHRpb25zIHtcblx0LyoqIERlbGF5IHRoZSBhY2tub3dsZWRnZW1lbnQgdW50aWwgdGhpcyBwcm9taXNlIHNldHRsZXMuICovXG5cdHJlYWRvbmx5IGFjaz86ICgpID0+IFByb21pc2U8dm9pZD47XG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlQnJpZGdlSGFybmVzc30uICovXG5leHBvcnQgaW50ZXJmYWNlIEhhcm5lc3NPcHRpb25zIHtcblx0LyoqXG5cdCAqIFRoZSBob3N0IG9wZXJhdGlvbiBpZHMgdGhlIHNjcmlwdGVkIGhhbmRzaGFrZSBhZHZlcnRpc2VzOyBldmVyeSBjdXJhdGVkXG5cdCAqIGlkIGJ5IGRlZmF1bHQuIEEgbmFycm93ZWQgbGlzdCBpcyBob3cgYSB0ZXN0IHByb3ZlcyBhIHBhZ2UgcmVzcGVjdHNcblx0ICogYHFnaXMuaG9zdC5ncmFudGVkYCAoVEFTSy02NiBBQyAjNSkuIEEgY2FsbCBvdXRzaWRlIGl0IGlzIHN0aWxsIGFuc3dlcmVkXG5cdCAqIGJ5IHdoYXRldmVyIHRoZSB0ZXN0IHNjcmlwdGVkIC0gdHlwaWNhbGx5IGBmYXVsdChcIm5vdF9hdXRob3JpemVkXCIsIC4uLilgIC1cblx0ICogYmVjYXVzZSB0aGF0IHJlZnVzYWwgaXMgdGhlIGhvc3Qncywgbm90IHRoZSBoYXJuZXNzJ3MuXG5cdCAqL1xuXHRyZWFkb25seSBncmFudGVkPzogcmVhZG9ubHkgSG9zdE9wZXJhdGlvbklkW107XG59XG5cbi8qKlxuICogQSB0ZXN0J3Mgc2NyaXB0IHdlbnQgd3Jvbmc6IGFuIHVubWV0IG9yIHVuZXhwZWN0ZWQgY2FsbCwgYSBsZWFrZWRcbiAqIHN1YnNjcmlwdGlvbiwgYSBoYW5kbGVyIHRoYXQgdGhyZXcsIG9yIGFuIGVudmVsb3BlIHRoYXQgaXMgbm90IHByb3RvY29sIDEuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrQnJpZGdlSGFybmVzc0Vycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuXHRcdHN1cGVyKG1lc3NhZ2UsIFwiaGFybmVzc19lcnJvclwiKTtcblx0fVxufVxuXG5pbnRlcmZhY2UgSW52b2tlRXhwZWN0YXRpb24ge1xuXHRyZWFkb25seSBraW5kOiBcImludm9rZVwiO1xuXHRyZWFkb25seSBvcGVyYXRpb246IHN0cmluZztcblx0cmVhZG9ubHkgaGFuZGxlcjogKHBheWxvYWQ6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikgPT4gdW5rbm93bjtcbn1cblxuaW50ZXJmYWNlIFN1YnNjcmliZUV4cGVjdGF0aW9uIHtcblx0cmVhZG9ubHkga2luZDogXCJzdWJzY3JpYmVcIjtcblx0cmVhZG9ubHkgb3BlcmF0aW9uOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHNjcmlwdDogU3Vic2NyaWJlU2NyaXB0PFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pj47XG5cdHJlYWRvbmx5IG9wdGlvbnM6IFN1YnNjcmliZU9wdGlvbnM7XG59XG5cbnR5cGUgRXhwZWN0YXRpb24gPSBJbnZva2VFeHBlY3RhdGlvbiB8IFN1YnNjcmliZUV4cGVjdGF0aW9uO1xuXG5pbnRlcmZhY2UgT3BlblN0cmVhbSB7XG5cdHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IG9wZXJhdGlvbjogc3RyaW5nO1xuXHRzZXE6IG51bWJlcjtcblx0b3BlbjogYm9vbGVhbjtcbn1cblxuLyoqIFRoZSBoYXJuZXNzIGEgdGVzdCBob2xkczsgYWxzbyB0aGUgdHJhbnNwb3J0IGl0cyBjbGllbnQgaXMgYnVpbHQgb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEJyaWRnZUhhcm5lc3M8T3AgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+XG5cdGV4dGVuZHMgV2lyZVRyYW5zcG9ydCB7XG5cdC8qKiBFdmVyeSBtZXNzYWdlIHRoZSBjbGllbnQgc2VudCwgaW4gb3JkZXIuICovXG5cdHJlYWRvbmx5IGNhbGxzOiByZWFkb25seSBSZWNvcmRlZENhbGxbXTtcblx0LyoqIENhbGxzIG5vIGV4cGVjdGF0aW9uIGNvdmVyZWQ7IGVhY2ggd2FzIGFuc3dlcmVkIGB1bmV4cGVjdGVkX2NhbGxgLiAqL1xuXHRyZWFkb25seSB1bmV4cGVjdGVkOiByZWFkb25seSBSZWNvcmRlZENhbGxbXTtcblx0LyoqIFN1YnNjcmlwdGlvbnMgbmVpdGhlciBlbmRlZCBieSBhIHNjcmlwdCBub3IgY2xvc2VkIGJ5IHRoZSBwYWdlLiAqL1xuXHRyZWFkb25seSBvcGVuU3Vic2NyaXB0aW9uczogcmVhZG9ubHkgc3RyaW5nW107XG5cdC8qKiBDbGllbnRzIGN1cnJlbnRseSBhdHRhY2hlZC4gKi9cblx0cmVhZG9ubHkgbGlzdGVuZXJzOiBudW1iZXI7XG5cdC8qKiBBbnN3ZXIgdGhlIG5leHQgYG9wZXJhdGlvbmAgY2FsbCB3aXRoIHdoYXQgYGhhbmRsZXJgIHJldHVybnMuICovXG5cdGV4cGVjdEludm9rZTxcblx0XHRSZXEgZXh0ZW5kcyBvYmplY3QgPSBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG5cdFx0UmVzID0gdW5rbm93bixcblx0PihvcGVyYXRpb246IE9wLCBoYW5kbGVyOiAocGF5bG9hZDogUmVxKSA9PiBTY3JpcHRlZFJlcGx5PFJlcz4pOiB2b2lkO1xuXHQvKipcblx0ICogQWNrbm93bGVkZ2UgdGhlIG5leHQgYG9wZXJhdGlvbmAgc3Vic2NyaXB0aW9uIGFuZCBoYW5kIGBzY3JpcHRgIHRoZVxuXHQgKiBzdHJlYW07IHJldHVybiBhIGZhdWx0IG9yIHtAbGluayBTSUxFTkNFfSBmcm9tIGl0IHRvIHJlZnVzZSBpbnN0ZWFkLlxuXHQgKi9cblx0ZXhwZWN0U3Vic2NyaWJlPFJlcSBleHRlbmRzIG9iamVjdCA9IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pj4oXG5cdFx0b3BlcmF0aW9uOiBPcCxcblx0XHRzY3JpcHQ6IFN1YnNjcmliZVNjcmlwdDxSZXE+LFxuXHRcdG9wdGlvbnM/OiBTdWJzY3JpYmVPcHRpb25zLFxuXHQpOiB2b2lkO1xuXHQvKiogUHVzaCBhbnkgcmF3IG1lc3NhZ2UsIGZvciB3aGF0IG5vIGV4cGVjdGF0aW9uIGNhbiBzY3JpcHQuICovXG5cdGRlbGl2ZXIocmF3OiB1bmtub3duKTogdm9pZDtcblx0LyoqIFJlc29sdmUgb25jZSBldmVyeXRoaW5nIHF1ZXVlZCBzbyBmYXIgaGFzIGJlZW4gZGVsaXZlcmVkLiAqL1xuXHRzZXR0bGVkKCk6IFByb21pc2U8dm9pZD47XG5cdC8qKiBUaHJvdyB1bmxlc3MgZXZlcnkgZXhwZWN0YXRpb24gd2FzIG1ldCBhbmQgbm90aGluZyBsZWFrZWQuICovXG5cdGFzc2VydFNhdGlzZmllZCgpOiB2b2lkO1xufVxuXG4vKipcbiAqIFRoZSBoYXJuZXNzIHtAbGluayBjcmVhdGVCcmlkZ2VIYXJuZXNzfSByZXR1cm5zIGZvciBhIHNjaGVtYTogdGhlIHNhbWVcbiAqIGhhcm5lc3MsIHdpdGggYGV4cGVjdEludm9rZWAgYW5kIGBleHBlY3RTdWJzY3JpYmVgIHR5cGVkIGJ5IHRoZSBzY2hlbWEnc1xuICogYE9wZXJhdGlvbnNgIGFuZCBgU3RyZWFtc2AgLSBhIHBheWxvYWQgaXMgdGhlIGRlY2xhcmVkIHJlcXVlc3QsIGEgcmVwbHkgdGhlXG4gKiBkZWNsYXJlZCByZXN1bHQgLSBhbmQgYnkgdGhlIGN1cmF0ZWQgaG9zdCBpZHMsIHdob3NlIHNoYXBlcyB0aGUgaG9zdCBtb2R1bGVcbiAqIG93bnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZW1hQnJpZGdlSGFybmVzczxPLCBTPlxuXHRleHRlbmRzIE9taXQ8XG5cdFx0QnJpZGdlSGFybmVzczxFeHRyYWN0PGtleW9mIE8gfCBrZXlvZiBTLCBzdHJpbmc+IHwgSG9zdE9wZXJhdGlvbklkPixcblx0XHRcImV4cGVjdEludm9rZVwiIHwgXCJleHBlY3RTdWJzY3JpYmVcIlxuXHQ+IHtcblx0ZXhwZWN0SW52b2tlPEsgZXh0ZW5kcyBFeHRyYWN0PGtleW9mIE8sIHN0cmluZz4+KFxuXHRcdG9wZXJhdGlvbjogSyxcblx0XHRoYW5kbGVyOiAoXG5cdFx0XHRwYXlsb2FkOiBPW0tdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGUgPyBPW0tdW1wicmVxdWVzdFwiXSA6IG5ldmVyLFxuXHRcdCkgPT4gU2NyaXB0ZWRSZXBseTxPW0tdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGUgPyBPW0tdW1wicmVzdWx0XCJdIDogbmV2ZXI+LFxuXHQpOiB2b2lkO1xuXHRleHBlY3RJbnZva2U8XG5cdFx0UmVxIGV4dGVuZHMgb2JqZWN0ID0gUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuXHRcdFJlcyA9IHVua25vd24sXG5cdD4oXG5cdFx0b3BlcmF0aW9uOiBIb3N0T3BlcmF0aW9uSWQsXG5cdFx0aGFuZGxlcjogKHBheWxvYWQ6IFJlcSkgPT4gU2NyaXB0ZWRSZXBseTxSZXM+LFxuXHQpOiB2b2lkO1xuXHRleHBlY3RTdWJzY3JpYmU8SyBleHRlbmRzIEV4dHJhY3Q8a2V5b2YgUywgc3RyaW5nPj4oXG5cdFx0b3BlcmF0aW9uOiBLLFxuXHRcdHNjcmlwdDogU3Vic2NyaWJlU2NyaXB0PFNbS10gZXh0ZW5kcyBTdHJlYW1TaGFwZSA/IFNbS11bXCJyZXF1ZXN0XCJdIDogbmV2ZXI+LFxuXHRcdG9wdGlvbnM/OiBTdWJzY3JpYmVPcHRpb25zLFxuXHQpOiB2b2lkO1xuXHRleHBlY3RTdWJzY3JpYmU8UmVxIGV4dGVuZHMgb2JqZWN0ID0gUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+Pihcblx0XHRvcGVyYXRpb246IEhvc3RPcGVyYXRpb25JZCxcblx0XHRzY3JpcHQ6IFN1YnNjcmliZVNjcmlwdDxSZXE+LFxuXHRcdG9wdGlvbnM/OiBTdWJzY3JpYmVPcHRpb25zLFxuXHQpOiB2b2lkO1xufVxuXG5jbGFzcyBIYXJuZXNzPE9wIGV4dGVuZHMgc3RyaW5nPiBpbXBsZW1lbnRzIEJyaWRnZUhhcm5lc3M8T3A+IHtcblx0cHJpdmF0ZSByZWFkb25seSBncmFudGVkOiByZWFkb25seSBIb3N0T3BlcmF0aW9uSWRbXTtcblx0cHJpdmF0ZSByZWFkb25seSBwbHVnaW46IEJyaWRnZVNjaGVtYSB8IG51bGw7XG5cdHByaXZhdGUgcmVhZG9ubHkgbGlzdGVuZXJTZXQgPSBuZXcgU2V0PChtZXNzYWdlOiB1bmtub3duKSA9PiB2b2lkPigpO1xuXHRwcml2YXRlIHJlYWRvbmx5IGV4cGVjdGF0aW9uczogRXhwZWN0YXRpb25bXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IHJlY29yZGVkOiBSZWNvcmRlZENhbGxbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IHVuZXhwZWN0ZWRDYWxsczogUmVjb3JkZWRDYWxsW10gPSBbXTtcblx0cHJpdmF0ZSByZWFkb25seSBzdHJlYW1zID0gbmV3IE1hcDxzdHJpbmcsIE9wZW5TdHJlYW0+KCk7XG5cdHByaXZhdGUgcmVhZG9ubHkgcHJvYmxlbXM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgb3V0Ym94OiB1bmtub3duW10gPSBbXTtcblx0cHJpdmF0ZSBkcmFpbmluZzogUHJvbWlzZTx2b2lkPiB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIHN0cmVhbUNvdW50ZXIgPSAwO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBIYXJuZXNzT3B0aW9ucywgcGx1Z2luOiBCcmlkZ2VTY2hlbWEgfCBudWxsKSB7XG5cdFx0dGhpcy5ncmFudGVkID0gT2JqZWN0LmZyZWV6ZShbLi4uKG9wdGlvbnMuZ3JhbnRlZCA/PyBIT1NUX09QRVJBVElPTlMpXSk7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRwdWJsaWMgZ2V0IGNhbGxzKCk6IHJlYWRvbmx5IFJlY29yZGVkQ2FsbFtdIHtcblx0XHRyZXR1cm4gWy4uLnRoaXMucmVjb3JkZWRdO1xuXHR9XG5cblx0cHVibGljIGdldCB1bmV4cGVjdGVkKCk6IHJlYWRvbmx5IFJlY29yZGVkQ2FsbFtdIHtcblx0XHRyZXR1cm4gWy4uLnRoaXMudW5leHBlY3RlZENhbGxzXTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgb3BlblN1YnNjcmlwdGlvbnMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuXHRcdHJldHVybiBbLi4udGhpcy5zdHJlYW1zLnZhbHVlcygpXVxuXHRcdFx0LmZpbHRlcigoc3RyZWFtKSA9PiBzdHJlYW0ub3Blbilcblx0XHRcdC5tYXAoKHN0cmVhbSkgPT4gc3RyZWFtLmlkKTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgbGlzdGVuZXJzKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMubGlzdGVuZXJTZXQuc2l6ZTtcblx0fVxuXG5cdHB1YmxpYyBzdWJzY3JpYmUobGlzdGVuZXI6IChtZXNzYWdlOiB1bmtub3duKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG5cdFx0dGhpcy5saXN0ZW5lclNldC5hZGQobGlzdGVuZXIpO1xuXHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHR0aGlzLmxpc3RlbmVyU2V0LmRlbGV0ZShsaXN0ZW5lcik7XG5cdFx0XHRpZiAodGhpcy5saXN0ZW5lclNldC5zaXplID09PSAwKSB7XG5cdFx0XHRcdC8vIFRoZSBsYXN0IGNsaWVudCBkZXRhY2hlZDogdGhlIHZpZXcgaXMgZ29uZSwgYW5kIGEgaG9zdCBkaXNwb3Nlc1xuXHRcdFx0XHQvLyB0aGUgc3Vic2NyaXB0aW9ucyBvZiBhIHZpZXcgaXQgbG9zdCAoZGVjaXNpb24tMjMpLCBzbyB0aGV5IGFyZVxuXHRcdFx0XHQvLyBubyBsb25nZXIgbGVha3MuXG5cdFx0XHRcdGZvciAoY29uc3Qgc3RyZWFtIG9mIHRoaXMuc3RyZWFtcy52YWx1ZXMoKSkge1xuXHRcdFx0XHRcdHN0cmVhbS5vcGVuID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG5cblx0cHVibGljIHNlbmQobWVzc2FnZTogdW5rbm93bik6IHZvaWQge1xuXHRcdGNvbnN0IGVudmVsb3BlID0gdGhpcy5wYXJzZUVudmVsb3BlKG1lc3NhZ2UpO1xuXHRcdGlmIChlbnZlbG9wZS5raW5kID09PSBcInVuc3Vic2NyaWJlXCIpIHtcblx0XHRcdHRoaXMuY2xvc2VGcm9tUGFnZShlbnZlbG9wZSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmIChlbnZlbG9wZS5raW5kID09PSBcImhhbmRzaGFrZVwiKSB7XG5cdFx0XHR0aGlzLmFuc3dlckhhbmRzaGFrZShlbnZlbG9wZSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGNvbnN0IGV4cGVjdGF0aW9uID0gdGhpcy50YWtlKGVudmVsb3BlLmtpbmQsIGVudmVsb3BlLm9wZXJhdGlvbik7XG5cdFx0aWYgKGV4cGVjdGF0aW9uID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHRoaXMudW5leHBlY3RlZENhbGxzLnB1c2goZW52ZWxvcGUpO1xuXHRcdFx0dGhpcy5kZWxpdmVyRmFpbHVyZShcblx0XHRcdFx0ZW52ZWxvcGUuY2FsbElkLFxuXHRcdFx0XHRcInVuZXhwZWN0ZWRfY2FsbFwiLFxuXHRcdFx0XHRgbm8gZXhwZWN0YXRpb24gY292ZXJzICR7ZW52ZWxvcGUua2luZH0gJHtKU09OLnN0cmluZ2lmeShlbnZlbG9wZS5vcGVyYXRpb24pfWAsXG5cdFx0XHQpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAoZXhwZWN0YXRpb24ua2luZCA9PT0gXCJpbnZva2VcIikge1xuXHRcdFx0dGhpcy5hbnN3ZXJJbnZva2UoZW52ZWxvcGUsIGV4cGVjdGF0aW9uKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5hbnN3ZXJTdWJzY3JpYmUoZW52ZWxvcGUsIGV4cGVjdGF0aW9uKTtcblx0fVxuXG5cdHB1YmxpYyBleHBlY3RJbnZva2U8UmVxIGV4dGVuZHMgb2JqZWN0LCBSZXM+KFxuXHRcdG9wZXJhdGlvbjogT3AsXG5cdFx0aGFuZGxlcjogKHBheWxvYWQ6IFJlcSkgPT4gU2NyaXB0ZWRSZXBseTxSZXM+LFxuXHQpOiB2b2lkIHtcblx0XHR0aGlzLmV4cGVjdGF0aW9ucy5wdXNoKHtcblx0XHRcdGtpbmQ6IFwiaW52b2tlXCIsXG5cdFx0XHRvcGVyYXRpb24sXG5cdFx0XHRoYW5kbGVyOiBoYW5kbGVyIGFzIEludm9rZUV4cGVjdGF0aW9uW1wiaGFuZGxlclwiXSxcblx0XHR9KTtcblx0fVxuXG5cdHB1YmxpYyBleHBlY3RTdWJzY3JpYmU8UmVxIGV4dGVuZHMgb2JqZWN0Pihcblx0XHRvcGVyYXRpb246IE9wLFxuXHRcdHNjcmlwdDogU3Vic2NyaWJlU2NyaXB0PFJlcT4sXG5cdFx0b3B0aW9uczogU3Vic2NyaWJlT3B0aW9ucyA9IHt9LFxuXHQpOiB2b2lkIHtcblx0XHR0aGlzLmV4cGVjdGF0aW9ucy5wdXNoKHtcblx0XHRcdGtpbmQ6IFwic3Vic2NyaWJlXCIsXG5cdFx0XHRvcGVyYXRpb24sXG5cdFx0XHRzY3JpcHQ6IHNjcmlwdCBhcyBTdWJzY3JpYmVFeHBlY3RhdGlvbltcInNjcmlwdFwiXSxcblx0XHRcdG9wdGlvbnMsXG5cdFx0fSk7XG5cdH1cblxuXHRwdWJsaWMgZGVsaXZlcihyYXc6IHVua25vd24pOiB2b2lkIHtcblx0XHR0aGlzLm91dGJveC5wdXNoKHJhdyk7XG5cdFx0dGhpcy5kcmFpbigpO1xuXHR9XG5cblx0cHVibGljIHNldHRsZWQoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0cmV0dXJuIHRoaXMuZHJhaW5pbmcgPz8gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHRwdWJsaWMgYXNzZXJ0U2F0aXNmaWVkKCk6IHZvaWQge1xuXHRcdGNvbnN0IHByb2JsZW1zID0gWy4uLnRoaXMucHJvYmxlbXNdO1xuXHRcdGlmICh0aGlzLmV4cGVjdGF0aW9ucy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25zdCB1bm1ldCA9IHRoaXMuZXhwZWN0YXRpb25zLm1hcChcblx0XHRcdFx0KGV4cGVjdGF0aW9uKSA9PiBgJHtleHBlY3RhdGlvbi5raW5kfSAke2V4cGVjdGF0aW9uLm9wZXJhdGlvbn1gLFxuXHRcdFx0KTtcblx0XHRcdHByb2JsZW1zLnB1c2goYHVubWV0IGV4cGVjdGF0aW9uczogJHt1bm1ldC5qb2luKFwiLCBcIil9YCk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnVuZXhwZWN0ZWRDYWxscy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25zdCB1bmV4cGVjdGVkID0gdGhpcy51bmV4cGVjdGVkQ2FsbHMubWFwKFxuXHRcdFx0XHQoY2FsbCkgPT4gYCR7Y2FsbC5raW5kfSAke2NhbGwub3BlcmF0aW9ufWAsXG5cdFx0XHQpO1xuXHRcdFx0cHJvYmxlbXMucHVzaChgdW5leHBlY3RlZCBjYWxsczogJHt1bmV4cGVjdGVkLmpvaW4oXCIsIFwiKX1gKTtcblx0XHR9XG5cdFx0Y29uc3Qgb3BlbiA9IHRoaXMub3BlblN1YnNjcmlwdGlvbnM7XG5cdFx0aWYgKG9wZW4ubGVuZ3RoID4gMCkge1xuXHRcdFx0cHJvYmxlbXMucHVzaChgb3BlbiBzdWJzY3JpcHRpb25zOiAke29wZW4uam9pbihcIiwgXCIpfWApO1xuXHRcdH1cblx0XHRpZiAocHJvYmxlbXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VIYXJuZXNzRXJyb3IocHJvYmxlbXMuam9pbihcIjsgXCIpKTtcblx0XHR9XG5cdH1cblxuXHQvLyAtLSBhbnN3ZXJpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0LyoqXG5cdCAqIEFuc3dlciB0aGUgaGFuZHNoYWtlIHRoZSB3YXkgYERpc3BhdGNoZXJgIGRvZXM6IHRoZSBwbHVnaW4gZGVzY3JpcHRpb25cblx0ICogdGhlIGhhcm5lc3Mgd2FzIGJ1aWx0IGZyb20gKG9yIG5vbmUpIGFuZCB0aGUgYWR2ZXJ0aXNlZCBvcGVyYXRpb24gaWRzIC1cblx0ICogdGhlIHBsdWdpbidzLCB0aGVuIHRoZSBncmFudGVkIGhvc3QgaWRzLiBObyBleHBlY3RhdGlvbiBpcyBjb25zdW1lZDogYVxuXHQgKiBoYW5kc2hha2UgaXMgdGhlIFNESydzIGZpcnN0IG1lc3NhZ2UsIG5vdCBzb21ldGhpbmcgYSB0ZXN0IHNjcmlwdHMuXG5cdCAqL1xuXHRwcml2YXRlIGFuc3dlckhhbmRzaGFrZShjYWxsOiBSZWNvcmRlZENhbGwpOiB2b2lkIHtcblx0XHRjb25zdCBkZWNsYXJlZCA9IFtcblx0XHRcdC4uLih0aGlzLnBsdWdpbj8uYWN0aW9ucyA/PyBbXSkubWFwKChhY3Rpb24pID0+IGFjdGlvbi5pZCksXG5cdFx0XHQuLi4odGhpcy5wbHVnaW4/LnN0cmVhbXMgPz8gW10pLm1hcCgoc3RyZWFtKSA9PiBzdHJlYW0uaWQpLFxuXHRcdF07XG5cdFx0dGhpcy5kZWxpdmVyKHtcblx0XHRcdHByb3RvY29sOiBQUk9UT0NPTCxcblx0XHRcdGNhbGxfaWQ6IGNhbGwuY2FsbElkLFxuXHRcdFx0b2s6IHRydWUsXG5cdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRwcm90b2NvbDogUFJPVE9DT0wsXG5cdFx0XHRcdGdlbmVyYXRpb246IDAsXG5cdFx0XHRcdHBsdWdpbjogdGhpcy5wbHVnaW4sXG5cdFx0XHRcdGhvc3Rfc2NoZW1hX3ZlcnNpb246IEhPU1RfU0NIRU1BX1ZFUlNJT04sXG5cdFx0XHRcdG9wZXJhdGlvbnM6IFsuLi5kZWNsYXJlZCwgLi4udGhpcy5ncmFudGVkXS5tYXAoKGlkKSA9PiAoe1xuXHRcdFx0XHRcdGlkLFxuXHRcdFx0XHRcdHRpdGxlOiBpZCxcblx0XHRcdFx0fSkpLFxuXHRcdFx0fSxcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgYW5zd2VySW52b2tlKFxuXHRcdGNhbGw6IFJlY29yZGVkQ2FsbCxcblx0XHRleHBlY3RhdGlvbjogSW52b2tlRXhwZWN0YXRpb24sXG5cdCk6IHZvaWQge1xuXHRcdHRoaXMucmVzb2x2ZUhhbmRsZXIoY2FsbCwgKCkgPT5cblx0XHRcdGV4cGVjdGF0aW9uLmhhbmRsZXIoY2FsbC5wYXlsb2FkID8/IHt9KSxcblx0XHQpLnRoZW4oKHJlcGx5KSA9PiB7XG5cdFx0XHRpZiAocmVwbHkgPT09IFNJTEVOQ0UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGlzRmF1bHQocmVwbHkpKSB7XG5cdFx0XHRcdHRoaXMuZGVsaXZlckZhaWx1cmUoY2FsbC5jYWxsSWQsIHJlcGx5LmZhdWx0LmNvZGUsIHJlcGx5LmZhdWx0Lm1lc3NhZ2UpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRlbGl2ZXIoe1xuXHRcdFx0XHRwcm90b2NvbDogUFJPVE9DT0wsXG5cdFx0XHRcdGNhbGxfaWQ6IGNhbGwuY2FsbElkLFxuXHRcdFx0XHRvazogdHJ1ZSxcblx0XHRcdFx0dmFsdWU6IHJlcGx5LFxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIGFuc3dlclN1YnNjcmliZShcblx0XHRjYWxsOiBSZWNvcmRlZENhbGwsXG5cdFx0ZXhwZWN0YXRpb246IFN1YnNjcmliZUV4cGVjdGF0aW9uLFxuXHQpOiB2b2lkIHtcblx0XHR0aGlzLnN0cmVhbUNvdW50ZXIgKz0gMTtcblx0XHRjb25zdCBvcGVuOiBPcGVuU3RyZWFtID0ge1xuXHRcdFx0aWQ6IGBzJHt0aGlzLnN0cmVhbUNvdW50ZXJ9YCxcblx0XHRcdG9wZXJhdGlvbjogY2FsbC5vcGVyYXRpb24sXG5cdFx0XHRzZXE6IDAsXG5cdFx0XHRvcGVuOiBmYWxzZSxcblx0XHR9O1xuXHRcdC8vIEZyYW1lcyB0aGUgc2NyaXB0IGVtaXRzIGJlZm9yZSB0aGUgYWNrbm93bGVkZ2VtZW50IGlzIGRlY2lkZWQgYXJlIGhlbGRcblx0XHQvLyBiYWNrOiBhIHJlZnVzZWQgc3Vic2NyaXB0aW9uIHNlbmRzIG5vbmUsIGFuIGFjY2VwdGVkIG9uZSBzZW5kcyB0aGVtXG5cdFx0Ly8gYWZ0ZXIgdGhlIGFja25vd2xlZGdlbWVudCwgc28gdGhlIGtlcm5lbCBoYXMgcmVnaXN0ZXJlZCB0aGVcblx0XHQvLyBzdWJzY3JpcHRpb24gYnkgdGhlIHRpbWUgdGhlIGZpcnN0IGZyYW1lIHJlYWNoZXMgaXQuXG5cdFx0Y29uc3QgaGVsZDogdW5rbm93bltdID0gW107XG5cdFx0bGV0IHNpbmsgPSAoZnJhbWU6IHVua25vd24pOiB2b2lkID0+IHtcblx0XHRcdGhlbGQucHVzaChmcmFtZSk7XG5cdFx0fTtcblx0XHRjb25zdCBzdHJlYW0gPSB0aGlzLnNjcmlwdGVkKG9wZW4sIChmcmFtZSkgPT4gc2luayhmcmFtZSkpO1xuXHRcdGNvbnN0IGFjayA9IGV4cGVjdGF0aW9uLm9wdGlvbnMuYWNrID8/ICgoKSA9PiBQcm9taXNlLnJlc29sdmUoKSk7XG5cdFx0YWNrKClcblx0XHRcdC50aGVuKCgpID0+XG5cdFx0XHRcdHRoaXMucmVzb2x2ZUhhbmRsZXIoY2FsbCwgKCkgPT4ge1xuXHRcdFx0XHRcdG9wZW4ub3BlbiA9IHRydWU7XG5cdFx0XHRcdFx0cmV0dXJuIGV4cGVjdGF0aW9uLnNjcmlwdChjYWxsLnBheWxvYWQgPz8ge30sIHN0cmVhbSk7XG5cdFx0XHRcdH0pLFxuXHRcdFx0KVxuXHRcdFx0LnRoZW4oKG91dGNvbWUpID0+IHtcblx0XHRcdFx0aWYgKG91dGNvbWUgPT09IFNJTEVOQ0UgfHwgaXNGYXVsdChvdXRjb21lKSkge1xuXHRcdFx0XHRcdG9wZW4ub3BlbiA9IGZhbHNlO1xuXHRcdFx0XHRcdGhlbGQubGVuZ3RoID0gMDtcblx0XHRcdFx0XHRpZiAoaXNGYXVsdChvdXRjb21lKSkge1xuXHRcdFx0XHRcdFx0dGhpcy5kZWxpdmVyRmFpbHVyZShcblx0XHRcdFx0XHRcdFx0Y2FsbC5jYWxsSWQsXG5cdFx0XHRcdFx0XHRcdG91dGNvbWUuZmF1bHQuY29kZSxcblx0XHRcdFx0XHRcdFx0b3V0Y29tZS5mYXVsdC5tZXNzYWdlLFxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh0aGlzLmxpc3RlbmVyU2V0LnNpemUgPT09IDApIHtcblx0XHRcdFx0XHQvLyBUaGUgdmlldyBkZXRhY2hlZCB3aGlsZSB0aGUgaG9zdCB3YXMgZGVjaWRpbmc6IG5vdGhpbmcgdG9cblx0XHRcdFx0XHQvLyBhY2tub3dsZWRnZSB0bywgbm90aGluZyB0byBrZWVwIG9wZW4uXG5cdFx0XHRcdFx0b3Blbi5vcGVuID0gZmFsc2U7XG5cdFx0XHRcdFx0aGVsZC5sZW5ndGggPSAwO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnN0cmVhbXMuc2V0KG9wZW4uaWQsIG9wZW4pO1xuXHRcdFx0XHR0aGlzLmRlbGl2ZXIoe1xuXHRcdFx0XHRcdHByb3RvY29sOiBQUk9UT0NPTCxcblx0XHRcdFx0XHRjYWxsX2lkOiBjYWxsLmNhbGxJZCxcblx0XHRcdFx0XHRvazogdHJ1ZSxcblx0XHRcdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRcdFx0c3Vic2NyaXB0aW9uX2lkOiBvcGVuLmlkLFxuXHRcdFx0XHRcdFx0Y2FwYWNpdHk6IFNVQlNDUklQVElPTl9DQVBBQ0lUWSxcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c2luayA9IChmcmFtZSkgPT4gdGhpcy5kZWxpdmVyKGZyYW1lKTtcblx0XHRcdFx0Zm9yIChjb25zdCBmcmFtZSBvZiBoZWxkKSB7XG5cdFx0XHRcdFx0c2luayhmcmFtZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aGVsZC5sZW5ndGggPSAwO1xuXHRcdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIHJlc29sdmVIYW5kbGVyKFxuXHRcdGNhbGw6IFJlY29yZGVkQ2FsbCxcblx0XHRydW46ICgpID0+IHVua25vd24sXG5cdCk6IFByb21pc2U8dW5rbm93bj4ge1xuXHRcdHJldHVybiBuZXcgUHJvbWlzZTx1bmtub3duPigocmVzb2x2ZSkgPT4ge1xuXHRcdFx0cmVzb2x2ZShydW4oKSk7XG5cdFx0fSkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG5cdFx0XHRjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuXHRcdFx0dGhpcy5wcm9ibGVtcy5wdXNoKFxuXHRcdFx0XHRgaGFuZGxlciBmb3IgJHtjYWxsLmtpbmR9ICR7Y2FsbC5vcGVyYXRpb259IHRocmV3OiAke21lc3NhZ2V9YCxcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gZmF1bHQoXCJoYXJuZXNzX2Vycm9yXCIsIG1lc3NhZ2UpO1xuXHRcdH0pO1xuXHR9XG5cblx0cHJpdmF0ZSBzY3JpcHRlZChcblx0XHRvcGVuOiBPcGVuU3RyZWFtLFxuXHRcdHNpbms6IChmcmFtZTogdW5rbm93bikgPT4gdm9pZCxcblx0KTogU2NyaXB0ZWRTdHJlYW0ge1xuXHRcdGNvbnN0IHJlcXVpcmVPcGVuID0gKHZlcmI6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdFx0aWYgKCFvcGVuLm9wZW4pIHtcblx0XHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VIYXJuZXNzRXJyb3IoXG5cdFx0XHRcdFx0YGNhbm5vdCAke3ZlcmJ9IG9uIHN1YnNjcmlwdGlvbiAke29wZW4uaWR9OiBpdCBpcyBub3Qgb3BlbmAsXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aWQ6IG9wZW4uaWQsXG5cdFx0XHRvcGVyYXRpb246IG9wZW4ub3BlcmF0aW9uLFxuXHRcdFx0Z2V0IG9wZW4oKTogYm9vbGVhbiB7XG5cdFx0XHRcdHJldHVybiBvcGVuLm9wZW47XG5cdFx0XHR9LFxuXHRcdFx0ZW1pdDogKGtpbmQsIHBheWxvYWQpID0+IHtcblx0XHRcdFx0cmVxdWlyZU9wZW4oXCJlbWl0XCIpO1xuXHRcdFx0XHRzaW5rKHtcblx0XHRcdFx0XHRwcm90b2NvbDogUFJPVE9DT0wsXG5cdFx0XHRcdFx0c3Vic2NyaXB0aW9uX2lkOiBvcGVuLmlkLFxuXHRcdFx0XHRcdHNlcTogb3Blbi5zZXEsXG5cdFx0XHRcdFx0ZXZlbnQ6IHsga2luZCwgcGF5bG9hZCB9LFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0b3Blbi5zZXEgKz0gMTtcblx0XHRcdH0sXG5cdFx0XHRlbmQ6ICh0ZXJtaW5hbCkgPT4ge1xuXHRcdFx0XHRyZXF1aXJlT3BlbihcImVuZFwiKTtcblx0XHRcdFx0b3Blbi5vcGVuID0gZmFsc2U7XG5cdFx0XHRcdHNpbmsoe1xuXHRcdFx0XHRcdHByb3RvY29sOiBQUk9UT0NPTCxcblx0XHRcdFx0XHRzdWJzY3JpcHRpb25faWQ6IG9wZW4uaWQsXG5cdFx0XHRcdFx0c2VxOiBvcGVuLnNlcSxcblx0XHRcdFx0XHR0ZXJtaW5hbCxcblx0XHRcdFx0fSk7XG5cdFx0XHRcdG9wZW4uc2VxICs9IDE7XG5cdFx0XHR9LFxuXHRcdFx0c2tpcDogKGZyYW1lcykgPT4ge1xuXHRcdFx0XHRyZXF1aXJlT3BlbihcInNraXBcIik7XG5cdFx0XHRcdG9wZW4uc2VxICs9IGZyYW1lcztcblx0XHRcdH0sXG5cdFx0fTtcblx0fVxuXG5cdHByaXZhdGUgY2xvc2VGcm9tUGFnZShjYWxsOiBSZWNvcmRlZENhbGwpOiB2b2lkIHtcblx0XHRjb25zdCBvcGVuID1cblx0XHRcdGNhbGwuc3Vic2NyaXB0aW9uSWQgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQ/IHVuZGVmaW5lZFxuXHRcdFx0XHQ6IHRoaXMuc3RyZWFtcy5nZXQoY2FsbC5zdWJzY3JpcHRpb25JZCk7XG5cdFx0Y29uc3QgZGlzcG9zZWQgPSBvcGVuPy5vcGVuID09PSB0cnVlO1xuXHRcdGlmIChvcGVuICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdG9wZW4ub3BlbiA9IGZhbHNlO1xuXHRcdH1cblx0XHR0aGlzLmRlbGl2ZXIoe1xuXHRcdFx0cHJvdG9jb2w6IFBST1RPQ09MLFxuXHRcdFx0Y2FsbF9pZDogY2FsbC5jYWxsSWQsXG5cdFx0XHRvazogdHJ1ZSxcblx0XHRcdHZhbHVlOiB7IGRpc3Bvc2VkIH0sXG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIGRlbGl2ZXJGYWlsdXJlKGNhbGxJZDogc3RyaW5nLCBjb2RlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuXHRcdHRoaXMuZGVsaXZlcih7XG5cdFx0XHRwcm90b2NvbDogUFJPVE9DT0wsXG5cdFx0XHRjYWxsX2lkOiBjYWxsSWQsXG5cdFx0XHRvazogZmFsc2UsXG5cdFx0XHRlcnJvcjogeyBjb2RlLCBtZXNzYWdlIH0sXG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIGRyYWluKCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmRyYWluaW5nICE9PSBudWxsKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuZHJhaW5pbmcgPSAoYXN5bmMgKCkgPT4ge1xuXHRcdFx0d2hpbGUgKHRoaXMub3V0Ym94Lmxlbmd0aCA+IDApIHtcblx0XHRcdFx0YXdhaXQgUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0XHRcdGNvbnN0IG1lc3NhZ2UgPSB0aGlzLm91dGJveC5zaGlmdCgpO1xuXHRcdFx0XHRmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIFsuLi50aGlzLmxpc3RlbmVyU2V0XSkge1xuXHRcdFx0XHRcdGxpc3RlbmVyKG1lc3NhZ2UpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRyYWluaW5nID0gbnVsbDtcblx0XHR9KSgpO1xuXHR9XG5cblx0Ly8gLS0gcGFyc2luZyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSB0YWtlKFxuXHRcdGtpbmQ6IFwiaW52b2tlXCIgfCBcInN1YnNjcmliZVwiLFxuXHRcdG9wZXJhdGlvbjogc3RyaW5nLFxuXHQpOiBFeHBlY3RhdGlvbiB8IHVuZGVmaW5lZCB7XG5cdFx0Y29uc3QgaW5kZXggPSB0aGlzLmV4cGVjdGF0aW9ucy5maW5kSW5kZXgoXG5cdFx0XHQoZXhwZWN0YXRpb24pID0+XG5cdFx0XHRcdGV4cGVjdGF0aW9uLmtpbmQgPT09IGtpbmQgJiYgZXhwZWN0YXRpb24ub3BlcmF0aW9uID09PSBvcGVyYXRpb24sXG5cdFx0KTtcblx0XHRpZiAoaW5kZXggPT09IC0xKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5leHBlY3RhdGlvbnMuc3BsaWNlKGluZGV4LCAxKVswXTtcblx0fVxuXG5cdHByaXZhdGUgcGFyc2VFbnZlbG9wZShtZXNzYWdlOiB1bmtub3duKTogUmVjb3JkZWRDYWxsIHtcblx0XHRpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VIYXJuZXNzRXJyb3IoXCJ0aGUgY2xpZW50IHNlbnQgYSBub24tb2JqZWN0XCIpO1xuXHRcdH1cblx0XHRjb25zdCByYXcgPSBtZXNzYWdlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRcdGlmIChyYXcucHJvdG9jb2wgIT09IFBST1RPQ09MKSB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0JyaWRnZUhhcm5lc3NFcnJvcihcblx0XHRcdFx0YHRoZSBjbGllbnQgc3BlYWtzIHByb3RvY29sICR7U3RyaW5nKHJhdy5wcm90b2NvbCl9OyB0aGUgaGFybmVzcyBmYWtlcyAke1BST1RPQ09MfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHJhdy5jYWxsX2lkICE9PSBcInN0cmluZ1wiIHx8IHJhdy5jYWxsX2lkLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VIYXJuZXNzRXJyb3IoXCJ0aGUgY2xpZW50IHNlbnQgbm8gY2FsbF9pZFwiKTtcblx0XHR9XG5cdFx0Y29uc3QgY2FsbElkID0gcmF3LmNhbGxfaWQ7XG5cdFx0aWYgKHJhdy5raW5kID09PSBcInVuc3Vic2NyaWJlXCIpIHtcblx0XHRcdGNvbnN0IHN1YnNjcmlwdGlvbklkID0gcmF3LnN1YnNjcmlwdGlvbl9pZDtcblx0XHRcdGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSWQgIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtCcmlkZ2VIYXJuZXNzRXJyb3IoXG5cdFx0XHRcdFx0YCR7Y2FsbElkfTogdW5zdWJzY3JpYmUgbmFtZXMgbm8gc3Vic2NyaXB0aW9uX2lkYCxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGNhbGw6IFJlY29yZGVkQ2FsbCA9IHtcblx0XHRcdFx0Y2FsbElkLFxuXHRcdFx0XHRraW5kOiBcInVuc3Vic2NyaWJlXCIsXG5cdFx0XHRcdG9wZXJhdGlvbjogdGhpcy5zdHJlYW1zLmdldChzdWJzY3JpcHRpb25JZCk/Lm9wZXJhdGlvbiA/PyBcIlwiLFxuXHRcdFx0XHRzdWJzY3JpcHRpb25JZCxcblx0XHRcdH07XG5cdFx0XHR0aGlzLnJlY29yZGVkLnB1c2goY2FsbCk7XG5cdFx0XHRyZXR1cm4gY2FsbDtcblx0XHR9XG5cdFx0aWYgKHJhdy5raW5kID09PSBcImhhbmRzaGFrZVwiKSB7XG5cdFx0XHRjb25zdCBjYWxsOiBSZWNvcmRlZENhbGwgPSB7IGNhbGxJZCwga2luZDogXCJoYW5kc2hha2VcIiwgb3BlcmF0aW9uOiBcIlwiIH07XG5cdFx0XHR0aGlzLnJlY29yZGVkLnB1c2goY2FsbCk7XG5cdFx0XHRyZXR1cm4gY2FsbDtcblx0XHR9XG5cdFx0aWYgKHJhdy5raW5kICE9PSBcImludm9rZVwiICYmIHJhdy5raW5kICE9PSBcInN1YnNjcmliZVwiKSB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0JyaWRnZUhhcm5lc3NFcnJvcihcblx0XHRcdFx0YCR7Y2FsbElkfTogJHtTdHJpbmcocmF3LmtpbmQpfSBpcyBub3QgYSBicmlkZ2UgZW52ZWxvcGUga2luZGAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHJhdy5vcGVyYXRpb24gIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrQnJpZGdlSGFybmVzc0Vycm9yKFxuXHRcdFx0XHRgJHtjYWxsSWR9OiBvcGVyYXRpb24gbXVzdCBiZSBhIHN0cmluZ2AsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRjb25zdCBwYXlsb2FkID1cblx0XHRcdHR5cGVvZiByYXcucGF5bG9hZCA9PT0gXCJvYmplY3RcIiAmJiByYXcucGF5bG9hZCAhPT0gbnVsbFxuXHRcdFx0XHQ/IChyYXcucGF5bG9hZCBhcyBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pXG5cdFx0XHRcdDoge307XG5cdFx0Y29uc3QgY2FsbDogUmVjb3JkZWRDYWxsID0ge1xuXHRcdFx0Y2FsbElkLFxuXHRcdFx0a2luZDogcmF3LmtpbmQsXG5cdFx0XHRvcGVyYXRpb246IHJhdy5vcGVyYXRpb24sXG5cdFx0XHRwYXlsb2FkLFxuXHRcdH07XG5cdFx0dGhpcy5yZWNvcmRlZC5wdXNoKGNhbGwpO1xuXHRcdHJldHVybiBjYWxsO1xuXHR9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgaGFybmVzcy5cbiAqXG4gKiBHaXZlbiB0aGUgZ2VuZXJhdGVkIGBicmlkZ2Uuc2NoZW1hLnRzYCBkZWZhdWx0IGV4cG9ydCwgdGhlIGhhcm5lc3MgaXMgdHlwZWRcbiAqIGJ5IGl0OiBgZXhwZWN0SW52b2tlKFwic2l0ZXMuc3VtbWFyeVwiLCAocGF5bG9hZCkgPT4gLi4uKWAgc2VlcyB0aGUgZGVjbGFyZWRcbiAqIHJlcXVlc3QgYW5kIG11c3QgYW5zd2VyIHdpdGggdGhlIGRlY2xhcmVkIHJlc3VsdCwgYW5kIHRoZSBoYW5kc2hha2UgaXRcbiAqIGFuc3dlcnMgYWR2ZXJ0aXNlcyB0aGUgc2NoZW1hJ3Mgb3BlcmF0aW9ucy4gV2l0aG91dCBvbmUsIGBPcGAgbmFycm93cyB0aGVcbiAqIG9wZXJhdGlvbnMgYSB0ZXN0IG1heSBleHBlY3QsIHR5cGljYWxseSBhIGdlbmVyYXRlZCBgT3BlcmF0aW9uSWRgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQnJpZGdlSGFybmVzczxPcCBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG5cdG9wdGlvbnM/OiBIYXJuZXNzT3B0aW9ucyxcbik6IEJyaWRnZUhhcm5lc3M8T3A+O1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUJyaWRnZUhhcm5lc3M8TywgUz4oXG5cdHNjaGVtYTogQnJpZGdlU2NoZW1hPE8sIFM+LFxuXHRvcHRpb25zPzogSGFybmVzc09wdGlvbnMsXG4pOiBTY2hlbWFCcmlkZ2VIYXJuZXNzPE8sIFM+O1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUJyaWRnZUhhcm5lc3MoXG5cdGZpcnN0OiBIYXJuZXNzT3B0aW9ucyB8IEJyaWRnZVNjaGVtYSA9IHt9LFxuXHRzZWNvbmQ6IEhhcm5lc3NPcHRpb25zID0ge30sXG4pOiBCcmlkZ2VIYXJuZXNzIHwgU2NoZW1hQnJpZGdlSGFybmVzczx1bmtub3duLCB1bmtub3duPiB7XG5cdGlmIChcInNjaGVtYV92ZXJzaW9uXCIgaW4gZmlyc3QpIHtcblx0XHRyZXR1cm4gbmV3IEhhcm5lc3M8c3RyaW5nPihzZWNvbmQsIGZpcnN0KSBhcyBTY2hlbWFCcmlkZ2VIYXJuZXNzPFxuXHRcdFx0dW5rbm93bixcblx0XHRcdHVua25vd25cblx0XHQ+O1xuXHR9XG5cdHJldHVybiBuZXcgSGFybmVzczxzdHJpbmc+KGZpcnN0LCBudWxsKTtcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7OztBQStCQSxJQUFNLFdBQVc7QUFDakIsSUFBTSx3QkFBd0I7QUFRdkIsU0FBUyxLQUFLLENBQUMsTUFBYyxTQUFnQztBQUFBLEVBQ25FLE9BQU8sT0FBTyxPQUFPLEVBQUUsT0FBTyxPQUFPLE9BQU8sRUFBRSxNQUFNLFFBQVEsQ0FBQyxFQUFFLENBQUM7QUFBQTtBQUdqRSxTQUFTLE9BQU8sQ0FBQyxPQUF3QztBQUFBLEVBQ3hELE9BQ0Ms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
|
package/package.json
CHANGED
|
@@ -1,10 +1,64 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
"name": "@archont561/qgis-sdk",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "TypeScript bridge contracts and error primitives for QGIS SDK WebEngine plugin interfaces.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./bridge": {
|
|
16
|
+
"types": "./dist/bridge.d.ts",
|
|
17
|
+
"import": "./dist/bridge.js",
|
|
18
|
+
"default": "./dist/bridge.js"
|
|
19
|
+
},
|
|
20
|
+
"./host": {
|
|
21
|
+
"types": "./dist/host.d.ts",
|
|
22
|
+
"import": "./dist/host.js",
|
|
23
|
+
"default": "./dist/host.js"
|
|
24
|
+
},
|
|
25
|
+
"./react": {
|
|
26
|
+
"types": "./dist/react.d.ts",
|
|
27
|
+
"import": "./dist/react.js",
|
|
28
|
+
"default": "./dist/react.js"
|
|
29
|
+
},
|
|
30
|
+
"./testing": {
|
|
31
|
+
"types": "./dist/testing.d.ts",
|
|
32
|
+
"import": "./dist/testing.js",
|
|
33
|
+
"default": "./dist/testing.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/Archont561/qgis-sdk.git",
|
|
44
|
+
"directory": "packages/qgis-sdk-typescript"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "bunup && tsc -p tsconfig.dist.json",
|
|
51
|
+
"test": "bun test",
|
|
52
|
+
"coverage": "bun --cwd=../.. --config=bunfig.toml test --coverage packages/qgis-sdk-typescript/tests",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"generate:contract-types": "json2ts -i 'tests/contracts/generated/schemas/*.json' -o tests/contracts/generated/types/ && json2ts -i 'tests/contracts/pydantic/generated/schemas/*.json' -o tests/contracts/pydantic/generated/types/"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"react": ">=18"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"react": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
}
|
|
10
64
|
}
|