@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.
@@ -1,207 +0,0 @@
1
- // src/index.ts
2
- var MAX_SAFE_INTEGER2 = 9007199254740991;
3
- var MIN_SAFE_INTEGER2 = -9007199254740991;
4
- var PLUGIN_DESCRIPTION_SCHEMA_VERSION2 = 1;
5
- var STREAM_EVENT_KINDS = [
6
- "data",
7
- "progress",
8
- "state"
9
- ];
10
- function isSafeJsonInteger2(value) {
11
- return typeof value === "number" && Number.isSafeInteger(value);
12
- }
13
-
14
- class QgisSdkError2 extends Error {
15
- code;
16
- constructor(message, code = "sdk_error") {
17
- super(message);
18
- this.name = new.target.name;
19
- this.code = code;
20
- }
21
- }
22
-
23
- class QgisSdkScopeClosedError2 extends QgisSdkError2 {
24
- constructor() {
25
- super("This resource scope has been disposed", "scope_closed");
26
- }
27
- }
28
-
29
- class QgisSdkUnsupportedCapabilityError2 extends QgisSdkError2 {
30
- capability;
31
- constructor(capability) {
32
- super(`Capability ${JSON.stringify(capability)} is unavailable in this runtime`, "unsupported_capability");
33
- this.capability = capability;
34
- }
35
- }
36
-
37
- class QgisSdkDeclarationError2 extends QgisSdkError2 {
38
- constructor(message) {
39
- super(message, "invalid_declaration");
40
- }
41
- }
42
-
43
- class QgisSdkValidationIssue2 {
44
- path;
45
- code;
46
- constructor(path, code) {
47
- this.path = Object.freeze([...path]);
48
- this.code = code;
49
- }
50
- toJSON() {
51
- return {
52
- path: [...this.path],
53
- code: this.code
54
- };
55
- }
56
- }
57
-
58
- class QgisSdkContractValidationError2 extends QgisSdkError2 {
59
- direction;
60
- issues;
61
- constructor(direction, issues) {
62
- const prefix = direction === "request" ? "Request" : "Result";
63
- super(`${prefix} contract validation failed`, "contract_validation_failed");
64
- this.direction = direction;
65
- this.issues = Object.freeze([...issues]);
66
- }
67
- toJSON() {
68
- return {
69
- code: this.code,
70
- direction: this.direction,
71
- issues: this.issues.map((issue) => issue.toJSON())
72
- };
73
- }
74
- }
75
- var DECLARATION_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
76
- var PYTHON_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
77
- function isPlainRecord2(value) {
78
- return typeof value === "object" && value !== null && !Array.isArray(value);
79
- }
80
- function validateDeclarationId(value, label) {
81
- if (typeof value !== "string" || !DECLARATION_ID_PATTERN.test(value)) {
82
- throw new QgisSdkDeclarationError2(`Invalid ${label} id: expected [a-zA-Z][a-zA-Z0-9_.-]*`);
83
- }
84
- return value;
85
- }
86
- function validateNonBlankTitle(value, id) {
87
- if (typeof value !== "string" || value.trim().length === 0) {
88
- throw new QgisSdkDeclarationError2(`${id}: title must be a nonempty string`);
89
- }
90
- return value;
91
- }
92
- function parseOperationHead(raw, label) {
93
- if (!isPlainRecord2(raw)) {
94
- throw new QgisSdkDeclarationError2(`${label[0]?.toUpperCase()}${label.slice(1)} description must be an object`);
95
- }
96
- const id = validateDeclarationId(raw.id, label);
97
- const title = validateNonBlankTitle(raw.title, id);
98
- if (typeof raw.handler !== "string" || !PYTHON_IDENTIFIER_PATTERN.test(raw.handler)) {
99
- throw new QgisSdkDeclarationError2(`${id}: handler must be a valid Python identifier`);
100
- }
101
- if (!isPlainRecord2(raw.request)) {
102
- throw new QgisSdkDeclarationError2(`${id}: request schema must be an object`);
103
- }
104
- return {
105
- raw,
106
- id,
107
- title,
108
- handler: raw.handler,
109
- request: Object.freeze({ ...raw.request })
110
- };
111
- }
112
- function parseActionDescription(raw) {
113
- const head = parseOperationHead(raw, "action");
114
- if (!isPlainRecord2(head.raw.result)) {
115
- throw new QgisSdkDeclarationError2(`${head.id}: result schema must be an object`);
116
- }
117
- return Object.freeze({
118
- id: head.id,
119
- title: head.title,
120
- handler: head.handler,
121
- request: head.request,
122
- result: Object.freeze({ ...head.raw.result })
123
- });
124
- }
125
- function parseStreamDescription(raw) {
126
- const head = parseOperationHead(raw, "stream");
127
- const declared = head.raw.events;
128
- if (!isPlainRecord2(declared) || Object.keys(declared).length === 0) {
129
- throw new QgisSdkDeclarationError2(`${head.id}: events must map at least one event kind to a schema`);
130
- }
131
- const events = {};
132
- for (const [kind, schema] of Object.entries(declared)) {
133
- if (!STREAM_EVENT_KINDS.includes(kind)) {
134
- throw new QgisSdkDeclarationError2(`${head.id}: ${kind} is not a stream event kind`);
135
- }
136
- if (!isPlainRecord2(schema)) {
137
- throw new QgisSdkDeclarationError2(`${head.id}: events.${kind} schema must be an object`);
138
- }
139
- events[kind] = Object.freeze({ ...schema });
140
- }
141
- return Object.freeze({
142
- id: head.id,
143
- title: head.title,
144
- handler: head.handler,
145
- request: head.request,
146
- events: Object.freeze(events)
147
- });
148
- }
149
- function parsePluginDescription2(input) {
150
- let parsed = input;
151
- if (typeof input === "string") {
152
- try {
153
- parsed = JSON.parse(input);
154
- } catch {
155
- throw new QgisSdkDeclarationError2("Plugin description is not valid JSON");
156
- }
157
- }
158
- if (!isPlainRecord2(parsed)) {
159
- throw new QgisSdkDeclarationError2("Plugin description must be an object");
160
- }
161
- if (parsed.schema_version !== PLUGIN_DESCRIPTION_SCHEMA_VERSION2) {
162
- throw new QgisSdkDeclarationError2(`Unsupported plugin description schema_version: ${String(parsed.schema_version)}`);
163
- }
164
- const id = validateDeclarationId(parsed.id, "plugin");
165
- const title = validateNonBlankTitle(parsed.title, id);
166
- if (!Array.isArray(parsed.actions)) {
167
- throw new QgisSdkDeclarationError2(`${id}: actions must be an array`);
168
- }
169
- const declaredStreams = parsed.streams ?? [];
170
- if (!Array.isArray(declaredStreams)) {
171
- throw new QgisSdkDeclarationError2(`${id}: streams must be an array`);
172
- }
173
- const seenIds = new Set;
174
- const claim = (operationId, label) => {
175
- if (seenIds.has(operationId)) {
176
- throw new QgisSdkDeclarationError2(`${id}: duplicate ${label} id ${operationId}`);
177
- }
178
- seenIds.add(operationId);
179
- };
180
- const actions = [];
181
- for (const item of parsed.actions) {
182
- const action = parseActionDescription(item);
183
- claim(action.id, "action");
184
- actions.push(action);
185
- }
186
- const streams = [];
187
- for (const item of declaredStreams) {
188
- const stream = parseStreamDescription(item);
189
- claim(stream.id, "stream");
190
- streams.push(stream);
191
- }
192
- const byId = (left, right) => left.id < right.id ? -1 : 1;
193
- actions.sort(byId);
194
- streams.sort(byId);
195
- return Object.freeze({
196
- schema_version: PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
197
- id,
198
- title,
199
- actions: Object.freeze(actions),
200
- streams: Object.freeze(streams)
201
- });
202
- }
203
-
204
- export { MAX_SAFE_INTEGER2, MIN_SAFE_INTEGER2, PLUGIN_DESCRIPTION_SCHEMA_VERSION2, isSafeJsonInteger2, QgisSdkError2, QgisSdkScopeClosedError2, QgisSdkUnsupportedCapabilityError2, QgisSdkDeclarationError2, QgisSdkValidationIssue2, QgisSdkContractValidationError2, isPlainRecord2, parsePluginDescription2 };
205
-
206
- //# debugId=BF5795AE7CCB0B5464756E2164756E21
207
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogUHVibGljIDAuMS4wIGNvbnRyYWN0LCB3aXJlLWxpbWl0LCBhbmQgZXJyb3IgcHJpbWl0aXZlcyBmb3IgdGhlIFFHSVMgU0RLIGJyaWRnZS5cbiAqXG4gKiBNaXJyb3JzIHRoZSBRR0lTLWZyZWUgYHFnaXNfc2RrLm1vZGVsc2AgYW5kIGBxZ2lzX3Nkay5kZWNsYXJhdGlvbnNgXG4gKiAoYHNjaGVtYV92ZXJzaW9uID0gMWApIGNvbnRyYWN0cyB3aXRob3V0IGltcG9ydGluZyBicm93c2VyIG9yIFF0IGdsb2JhbHMuXG4gKi9cblxuZXhwb3J0IGNvbnN0IE1BWF9TQUZFX0lOVEVHRVI6IG51bWJlciA9IDlfMDA3XzE5OV8yNTRfNzQwXzk5MTtcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSOiBudW1iZXIgPSAtOV8wMDdfMTk5XzI1NF83NDBfOTkxO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTjogMSA9IDE7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25EaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdHJlYWRvbmx5IHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHJlYWRvbmx5IGNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJpYWxpemVkQ29udHJhY3RWYWxpZGF0aW9uRXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgcmVzdWx0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbi8qKiBUaGUgZXZlbnQga2luZHMgYSBzdHJlYW0gbWF5IGRlY2xhcmU7IHRoZSBmcmFtZSBjYXJyaWVzIHRoZSBzYW1lIHRocmVlLiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtRXZlbnRLaW5kID0gXCJkYXRhXCIgfCBcInByb2dyZXNzXCIgfCBcInN0YXRlXCI7XG5cbi8qKlxuICogQSBkZWNsYXJlZCBzdHJlYW0gKGRlY2lzaW9uLTI4KTogYSByZXF1ZXN0IGluLCBvbmUgcGF5bG9hZCBzY2hlbWEgcGVyXG4gKiBkZWNsYXJlZCBldmVudCBraW5kIG91dC4gVGhlcmUgaXMgbm8gYHJlc3VsdGA6IHRoZSByZXBseSB0byBhIHN1YnNjcmlwdGlvbiBpc1xuICogdGhlIHByb3RvY29sJ3MgYWNrbm93bGVkZ2VtZW50LCBub3Qgc29tZXRoaW5nIGFuIGF1dGhvciBkZWNsYXJlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGhhbmRsZXI6IHN0cmluZztcblx0cmVhZG9ubHkgcmVxdWVzdDogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuXHRyZWFkb25seSBldmVudHM6IFJlYWRvbmx5PFxuXHRcdFBhcnRpYWw8UmVjb3JkPFN0cmVhbUV2ZW50S2luZCwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+Pj5cblx0Pjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IHNjaGVtYV92ZXJzaW9uOiAxO1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBhY3Rpb25zOiByZWFkb25seSBBY3Rpb25EZXNjcmlwdGlvbltdO1xuXHQvKiogRGVjbGFyZWQgc3RyZWFtczsgYSBkZXNjcmlwdGlvbiBmcm9tIGEgaG9zdCB0aGF0IHByZWRhdGVzIHRoZW0gaXMgZW1wdHkuICovXG5cdHJlYWRvbmx5IHN0cmVhbXM6IHJlYWRvbmx5IFN0cmVhbURlc2NyaXB0aW9uW107XG59XG5cbmNvbnN0IFNUUkVBTV9FVkVOVF9LSU5EUzogcmVhZG9ubHkgU3RyZWFtRXZlbnRLaW5kW10gPSBbXG5cdFwiZGF0YVwiLFxuXHRcInByb2dyZXNzXCIsXG5cdFwic3RhdGVcIixcbl07XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYHZhbHVlYCBpcyBhIGZpbml0ZSBpbnRlZ2VyIHdpdGhpbiB0aGUgSmF2YVNjcmlwdC1zYWZlIHdpcmUgcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NhZmVKc29uSW50ZWdlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG5cdHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpO1xufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGV4cGVjdGVkIFNESyBlcnJvcnMgYWNyb3NzIHRoZSBicmlkZ2UgYm91bmRhcnkuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdHB1YmxpYyByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgY29kZTogc3RyaW5nID0gXCJzZGtfZXJyb3JcIikge1xuXHRcdHN1cGVyKG1lc3NhZ2UpO1xuXHRcdHRoaXMubmFtZSA9IG5ldy50YXJnZXQubmFtZTtcblx0XHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR9XG59XG5cbi8qKlxuICogQW4gb3BlcmF0aW9uIGF0dGVtcHRlZCB0byB1c2UgYW4gYWxyZWFkeSBkaXNwb3NlZCBvd25lciBzY29wZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtTY29wZUNsb3NlZEVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKFwiVGhpcyByZXNvdXJjZSBzY29wZSBoYXMgYmVlbiBkaXNwb3NlZFwiLCBcInNjb3BlX2Nsb3NlZFwiKTtcblx0fVxufVxuXG4vKipcbiAqIFRoZSBzZWxlY3RlZCBydW50aW1lIGRvZXMgbm90IG9mZmVyIGFuIGV4cGxpY2l0bHkgcmVxdWVzdGVkIGNhcGFiaWxpdHkuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrVW5zdXBwb3J0ZWRDYXBhYmlsaXR5RXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgcmVhZG9ubHkgY2FwYWJpbGl0eTogc3RyaW5nO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihjYXBhYmlsaXR5OiBzdHJpbmcpIHtcblx0XHRzdXBlcihcblx0XHRcdGBDYXBhYmlsaXR5ICR7SlNPTi5zdHJpbmdpZnkoY2FwYWJpbGl0eSl9IGlzIHVuYXZhaWxhYmxlIGluIHRoaXMgcnVudGltZWAsXG5cdFx0XHRcInVuc3VwcG9ydGVkX2NhcGFiaWxpdHlcIixcblx0XHQpO1xuXHRcdHRoaXMuY2FwYWJpbGl0eSA9IGNhcGFiaWxpdHk7XG5cdH1cbn1cblxuLyoqXG4gKiBBIGRlY2xhcmF0aW9uIGNhbm5vdCBiZSByZXByZXNlbnRlZCBvciBwYXJzZWQgaW4gdGhlIHZlcnNpb25lZCBjb250cmFjdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuXHRcdHN1cGVyKG1lc3NhZ2UsIFwiaW52YWxpZF9kZWNsYXJhdGlvblwiKTtcblx0fVxufVxuXG4vKipcbiAqIFNhZmUsIHN0cnVjdHVyZWQgbG9jYXRpb24gYW5kIGNhdGVnb3J5IGZvciBhIHJlamVjdGVkIGNvbnRyYWN0IHZhbHVlLlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZSB7XG5cdHB1YmxpYyByZWFkb25seSBwYXRoOiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdO1xuXHRwdWJsaWMgcmVhZG9ubHkgY29kZTogc3RyaW5nO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihwYXRoOiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdLCBjb2RlOiBzdHJpbmcpIHtcblx0XHR0aGlzLnBhdGggPSBPYmplY3QuZnJlZXplKFsuLi5wYXRoXSk7XG5cdFx0dGhpcy5jb2RlID0gY29kZTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHBhdGg6IFsuLi50aGlzLnBhdGhdLFxuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBBIHJlcXVlc3Qgb3IgcmVzdWx0IGRpZCBub3Qgc2F0aXNmeSBpdHMgZGVjbGFyZWQgd2lyZSBjb250cmFjdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtDb250cmFjdFZhbGlkYXRpb25FcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyByZWFkb25seSBkaXJlY3Rpb246IFZhbGlkYXRpb25EaXJlY3Rpb247XG5cdHB1YmxpYyByZWFkb25seSBpc3N1ZXM6IHJlYWRvbmx5IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXTtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IoXG5cdFx0ZGlyZWN0aW9uOiBWYWxpZGF0aW9uRGlyZWN0aW9uLFxuXHRcdGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdLFxuXHQpIHtcblx0XHRjb25zdCBwcmVmaXggPSBkaXJlY3Rpb24gPT09IFwicmVxdWVzdFwiID8gXCJSZXF1ZXN0XCIgOiBcIlJlc3VsdFwiO1xuXHRcdHN1cGVyKGAke3ByZWZpeH0gY29udHJhY3QgdmFsaWRhdGlvbiBmYWlsZWRgLCBcImNvbnRyYWN0X3ZhbGlkYXRpb25fZmFpbGVkXCIpO1xuXHRcdHRoaXMuZGlyZWN0aW9uID0gZGlyZWN0aW9uO1xuXHRcdHRoaXMuaXNzdWVzID0gT2JqZWN0LmZyZWV6ZShbLi4uaXNzdWVzXSk7XG5cdH1cblxuXHRwdWJsaWMgdG9KU09OKCk6IFNlcmlhbGl6ZWRDb250cmFjdFZhbGlkYXRpb25FcnJvciB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGNvZGU6IHRoaXMuY29kZSxcblx0XHRcdGRpcmVjdGlvbjogdGhpcy5kaXJlY3Rpb24sXG5cdFx0XHRpc3N1ZXM6IHRoaXMuaXNzdWVzLm1hcCgoaXNzdWUpID0+IGlzc3VlLnRvSlNPTigpKSxcblx0XHR9O1xuXHR9XG59XG5cbmNvbnN0IERFQ0xBUkFUSU9OX0lEX1BBVFRFUk4gPSAvXlthLXpBLVpdW2EtekEtWjAtOV8uLV0qJC87XG5jb25zdCBQWVRIT05fSURFTlRJRklFUl9QQVRURVJOID0gL15bYS16QS1aX11bYS16QS1aMC05X10qJC87XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYHZhbHVlYCBpcyBhIG5vbi1udWxsLCBub24tYXJyYXkgb2JqZWN0OiB0aGUgc2hhcGUgZXZlcnkgd2lyZVxuICogZW52ZWxvcGUsIGRlc2NyaXB0aW9uIGFuZCBldmVudCBwYXlsb2FkIG11c3QgaGF2ZSBiZWZvcmUgaXRzIGZpZWxkcyBhcmUgcmVhZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUGxhaW5SZWNvcmQoXG5cdHZhbHVlOiB1bmtub3duLFxuKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuXHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHZhbHVlOiB1bmtub3duLCBsYWJlbDogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIiB8fCAhREVDTEFSQVRJT05fSURfUEFUVEVSTi50ZXN0KHZhbHVlKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBJbnZhbGlkICR7bGFiZWx9IGlkOiBleHBlY3RlZCBbYS16QS1aXVthLXpBLVowLTlfLi1dKmAsXG5cdFx0KTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTm9uQmxhbmtUaXRsZSh2YWx1ZTogdW5rbm93biwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgdmFsdWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHtpZH06IHRpdGxlIG11c3QgYmUgYSBub25lbXB0eSBzdHJpbmdgKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uSGVhZChcblx0cmF3OiB1bmtub3duLFxuXHRsYWJlbDogc3RyaW5nLFxuKToge1xuXHRyZWFkb25seSByYXc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcbn0ge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQocmF3KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2xhYmVsWzBdPy50b1VwcGVyQ2FzZSgpfSR7bGFiZWwuc2xpY2UoMSl9IGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHJhdy5pZCwgbGFiZWwpO1xuXHRjb25zdCB0aXRsZSA9IHZhbGlkYXRlTm9uQmxhbmtUaXRsZShyYXcudGl0bGUsIGlkKTtcblx0aWYgKFxuXHRcdHR5cGVvZiByYXcuaGFuZGxlciAhPT0gXCJzdHJpbmdcIiB8fFxuXHRcdCFQWVRIT05fSURFTlRJRklFUl9QQVRURVJOLnRlc3QocmF3LmhhbmRsZXIpXG5cdCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogaGFuZGxlciBtdXN0IGJlIGEgdmFsaWQgUHl0aG9uIGlkZW50aWZpZXJgLFxuXHRcdCk7XG5cdH1cblx0aWYgKCFpc1BsYWluUmVjb3JkKHJhdy5yZXF1ZXN0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogcmVxdWVzdCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRyYXcsXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0aGFuZGxlcjogcmF3LmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXF1ZXN0IH0pLFxuXHR9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUFjdGlvbkRlc2NyaXB0aW9uKHJhdzogdW5rbm93bik6IEFjdGlvbkRlc2NyaXB0aW9uIHtcblx0Y29uc3QgaGVhZCA9IHBhcnNlT3BlcmF0aW9uSGVhZChyYXcsIFwiYWN0aW9uXCIpO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoaGVhZC5yYXcucmVzdWx0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2hlYWQuaWR9OiByZXN1bHQgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRpZDogaGVhZC5pZCxcblx0XHR0aXRsZTogaGVhZC50aXRsZSxcblx0XHRoYW5kbGVyOiBoZWFkLmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogaGVhZC5yZXF1ZXN0LFxuXHRcdHJlc3VsdDogT2JqZWN0LmZyZWV6ZSh7IC4uLmhlYWQucmF3LnJlc3VsdCB9KSxcblx0fSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RyZWFtRGVzY3JpcHRpb24ocmF3OiB1bmtub3duKTogU3RyZWFtRGVzY3JpcHRpb24ge1xuXHRjb25zdCBoZWFkID0gcGFyc2VPcGVyYXRpb25IZWFkKHJhdywgXCJzdHJlYW1cIik7XG5cdGNvbnN0IGRlY2xhcmVkID0gaGVhZC5yYXcuZXZlbnRzO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoZGVjbGFyZWQpIHx8IE9iamVjdC5rZXlzKGRlY2xhcmVkKS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtoZWFkLmlkfTogZXZlbnRzIG11c3QgbWFwIGF0IGxlYXN0IG9uZSBldmVudCBraW5kIHRvIGEgc2NoZW1hYCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGV2ZW50czogUGFydGlhbDxcblx0XHRSZWNvcmQ8U3RyZWFtRXZlbnRLaW5kLCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+XG5cdD4gPSB7fTtcblx0Zm9yIChjb25zdCBba2luZCwgc2NoZW1hXSBvZiBPYmplY3QuZW50cmllcyhkZWNsYXJlZCkpIHtcblx0XHRpZiAoIVNUUkVBTV9FVkVOVF9LSU5EUy5pbmNsdWRlcyhraW5kIGFzIFN0cmVhbUV2ZW50S2luZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06ICR7a2luZH0gaXMgbm90IGEgc3RyZWFtIGV2ZW50IGtpbmRgLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKCFpc1BsYWluUmVjb3JkKHNjaGVtYSkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06IGV2ZW50cy4ke2tpbmR9IHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdGAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRldmVudHNba2luZCBhcyBTdHJlYW1FdmVudEtpbmRdID0gT2JqZWN0LmZyZWV6ZSh7IC4uLnNjaGVtYSB9KTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0aWQ6IGhlYWQuaWQsXG5cdFx0dGl0bGU6IGhlYWQudGl0bGUsXG5cdFx0aGFuZGxlcjogaGVhZC5oYW5kbGVyLFxuXHRcdHJlcXVlc3Q6IGhlYWQucmVxdWVzdCxcblx0XHRldmVudHM6IE9iamVjdC5mcmVlemUoZXZlbnRzKSxcblx0fSk7XG59XG5cbi8qKlxuICogUGFyc2UgYW5kIHZhbGlkYXRlIGEgdmVyc2lvbiAxIGBQbHVnaW5EZXNjcmlwdGlvbmAgZW1pdHRlZCBieSBgZGVzY3JpYmVfcGx1Z2luYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGx1Z2luRGVzY3JpcHRpb24oXG5cdGlucHV0OiBzdHJpbmcgfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4pOiBQbHVnaW5EZXNjcmlwdGlvbiB7XG5cdGxldCBwYXJzZWQ6IHVua25vd24gPSBpbnB1dDtcblx0aWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdHRyeSB7XG5cdFx0XHRwYXJzZWQgPSBKU09OLnBhcnNlKGlucHV0KTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcIlBsdWdpbiBkZXNjcmlwdGlvbiBpcyBub3QgdmFsaWQgSlNPTlwiKTtcblx0XHR9XG5cdH1cblx0aWYgKCFpc1BsYWluUmVjb3JkKHBhcnNlZCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJQbHVnaW4gZGVzY3JpcHRpb24gbXVzdCBiZSBhbiBvYmplY3RcIik7XG5cdH1cblx0aWYgKHBhcnNlZC5zY2hlbWFfdmVyc2lvbiAhPT0gUExVR0lOX0RFU0NSSVBUSU9OX1NDSEVNQV9WRVJTSU9OKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YFVuc3VwcG9ydGVkIHBsdWdpbiBkZXNjcmlwdGlvbiBzY2hlbWFfdmVyc2lvbjogJHtTdHJpbmcocGFyc2VkLnNjaGVtYV92ZXJzaW9uKX1gLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgaWQgPSB2YWxpZGF0ZURlY2xhcmF0aW9uSWQocGFyc2VkLmlkLCBcInBsdWdpblwiKTtcblx0Y29uc3QgdGl0bGUgPSB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUocGFyc2VkLnRpdGxlLCBpZCk7XG5cdGlmICghQXJyYXkuaXNBcnJheShwYXJzZWQuYWN0aW9ucykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiBhY3Rpb25zIG11c3QgYmUgYW4gYXJyYXlgKTtcblx0fVxuXHRjb25zdCBkZWNsYXJlZFN0cmVhbXMgPSBwYXJzZWQuc3RyZWFtcyA/PyBbXTtcblx0aWYgKCFBcnJheS5pc0FycmF5KGRlY2xhcmVkU3RyZWFtcykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiBzdHJlYW1zIG11c3QgYmUgYW4gYXJyYXlgKTtcblx0fVxuXHQvLyBBY3Rpb25zIGFuZCBzdHJlYW1zIHNoYXJlIG9uZSBpZCBuYW1lc3BhY2UgKGRlY2lzaW9uLTI4KS5cblx0Y29uc3Qgc2VlbklkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRjb25zdCBjbGFpbSA9IChvcGVyYXRpb25JZDogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0aWYgKHNlZW5JZHMuaGFzKG9wZXJhdGlvbklkKSkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0XHRgJHtpZH06IGR1cGxpY2F0ZSAke2xhYmVsfSBpZCAke29wZXJhdGlvbklkfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRzZWVuSWRzLmFkZChvcGVyYXRpb25JZCk7XG5cdH07XG5cdGNvbnN0IGFjdGlvbnM6IEFjdGlvbkRlc2NyaXB0aW9uW10gPSBbXTtcblx0Zm9yIChjb25zdCBpdGVtIG9mIHBhcnNlZC5hY3Rpb25zKSB7XG5cdFx0Y29uc3QgYWN0aW9uID0gcGFyc2VBY3Rpb25EZXNjcmlwdGlvbihpdGVtKTtcblx0XHRjbGFpbShhY3Rpb24uaWQsIFwiYWN0aW9uXCIpO1xuXHRcdGFjdGlvbnMucHVzaChhY3Rpb24pO1xuXHR9XG5cdGNvbnN0IHN0cmVhbXM6IFN0cmVhbURlc2NyaXB0aW9uW10gPSBbXTtcblx0Zm9yIChjb25zdCBpdGVtIG9mIGRlY2xhcmVkU3RyZWFtcykge1xuXHRcdGNvbnN0IHN0cmVhbSA9IHBhcnNlU3RyZWFtRGVzY3JpcHRpb24oaXRlbSk7XG5cdFx0Y2xhaW0oc3RyZWFtLmlkLCBcInN0cmVhbVwiKTtcblx0XHRzdHJlYW1zLnB1c2goc3RyZWFtKTtcblx0fVxuXHRjb25zdCBieUlkID0gKFxuXHRcdGxlZnQ6IHsgcmVhZG9ubHkgaWQ6IHN0cmluZyB9LFxuXHRcdHJpZ2h0OiB7IHJlYWRvbmx5IGlkOiBzdHJpbmcgfSxcblx0KTogbnVtYmVyID0+IChsZWZ0LmlkIDwgcmlnaHQuaWQgPyAtMSA6IDEpO1xuXHRhY3Rpb25zLnNvcnQoYnlJZCk7XG5cdHN0cmVhbXMuc29ydChieUlkKTtcblx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdHNjaGVtYV92ZXJzaW9uOiBQTFVHSU5fREVTQ1JJUFRJT05fU0NIRU1BX1ZFUlNJT04sXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0YWN0aW9uczogT2JqZWN0LmZyZWV6ZShhY3Rpb25zKSxcblx0XHRzdHJlYW1zOiBPYmplY3QuZnJlZXplKHN0cmVhbXMpLFxuXHR9KTtcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7QUFPTyxJQUFNLG9CQUEyQjtBQUNqQyxJQUFNLG9CQUEyQjtBQUNqQyxJQUFNLHFDQUF1QztBQWtEcEQsSUFBTSxxQkFBaUQ7QUFBQSxFQUN0RDtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFLTyxTQUFTLGtCQUFpQixDQUFDLE9BQWlDO0FBQUEsRUFDbEUsT0FBTyxPQUFPLFVBQVUsWUFBWSxPQUFPLGNBQWMsS0FBSztBQUFBO0FBQUE7QUFNeEQsTUFBTSxzQkFBcUIsTUFBTTtBQUFBLEVBQ3ZCO0FBQUEsRUFFVCxXQUFXLENBQUMsU0FBaUIsT0FBZSxhQUFhO0FBQUEsSUFDL0QsTUFBTSxPQUFPO0FBQUEsSUFDYixLQUFLLE9BQU8sV0FBVztBQUFBLElBQ3ZCLEtBQUssT0FBTztBQUFBO0FBRWQ7QUFBQTtBQUtPLE1BQU0saUNBQWdDLGNBQWE7QUFBQSxFQUNsRCxXQUFXLEdBQUc7QUFBQSxJQUNwQixNQUFNLHlDQUF5QyxjQUFjO0FBQUE7QUFFL0Q7QUFBQTtBQUtPLE1BQU0sMkNBQTBDLGNBQWE7QUFBQSxFQUNuRDtBQUFBLEVBRVQsV0FBVyxDQUFDLFlBQW9CO0FBQUEsSUFDdEMsTUFDQyxjQUFjLEtBQUssVUFBVSxVQUFVLG9DQUN2Qyx3QkFDRDtBQUFBLElBQ0EsS0FBSyxhQUFhO0FBQUE7QUFFcEI7QUFBQTtBQUtPLE1BQU0saUNBQWdDLGNBQWE7QUFBQSxFQUNsRCxXQUFXLENBQUMsU0FBaUI7QUFBQSxJQUNuQyxNQUFNLFNBQVMscUJBQXFCO0FBQUE7QUFFdEM7QUFBQTtBQUtPLE1BQU0sd0JBQXVCO0FBQUEsRUFDbkI7QUFBQSxFQUNBO0FBQUEsRUFFVCxXQUFXLENBQUMsTUFBb0MsTUFBYztBQUFBLElBQ3BFLEtBQUssT0FBTyxPQUFPLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQztBQUFBLElBQ25DLEtBQUssT0FBTztBQUFBO0FBQUEsRUFHTixNQUFNLEdBQThCO0FBQUEsSUFDMUMsT0FBTztBQUFBLE1BQ04sTUFBTSxDQUFDLEdBQUcsS0FBSyxJQUFJO0FBQUEsTUFDbkIsTUFBTSxLQUFLO0FBQUEsSUFDWjtBQUFBO0FBRUY7QUFBQTtBQUtPLE1BQU0sd0NBQXVDLGNBQWE7QUFBQSxFQUNoRDtBQUFBLEVBQ0E7QUFBQSxFQUVULFdBQVcsQ0FDakIsV0FDQSxRQUNDO0FBQUEsSUFDRCxNQUFNLFNBQVMsY0FBYyxZQUFZLFlBQVk7QUFBQSxJQUNyRCxNQUFNLEdBQUcscUNBQXFDLDRCQUE0QjtBQUFBLElBQzFFLEtBQUssWUFBWTtBQUFBLElBQ2pCLEtBQUssU0FBUyxPQUFPLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQztBQUFBO0FBQUEsRUFHakMsTUFBTSxHQUFzQztBQUFBLElBQ2xELE9BQU87QUFBQSxNQUNOLE1BQU0sS0FBSztBQUFBLE1BQ1gsV0FBVyxLQUFLO0FBQUEsTUFDaEIsUUFBUSxLQUFLLE9BQU8sSUFBSSxDQUFDLFVBQVUsTUFBTSxPQUFPLENBQUM7QUFBQSxJQUNsRDtBQUFBO0FBRUY7QUFFQSxJQUFNLHlCQUF5QjtBQUMvQixJQUFNLDRCQUE0QjtBQU0zQixTQUFTLGNBQWEsQ0FDNUIsT0FDbUM7QUFBQSxFQUNuQyxPQUFPLE9BQU8sVUFBVSxZQUFZLFVBQVUsUUFBUSxDQUFDLE1BQU0sUUFBUSxLQUFLO0FBQUE7QUFHM0UsU0FBUyxxQkFBcUIsQ0FBQyxPQUFnQixPQUF1QjtBQUFBLEVBQ3JFLElBQUksT0FBTyxVQUFVLFlBQVksQ0FBQyx1QkFBdUIsS0FBSyxLQUFLLEdBQUc7QUFBQSxJQUNyRSxNQUFNLElBQUkseUJBQ1QsV0FBVyw0Q0FDWjtBQUFBLEVBQ0Q7QUFBQSxFQUNBLE9BQU87QUFBQTtBQUdSLFNBQVMscUJBQXFCLENBQUMsT0FBZ0IsSUFBb0I7QUFBQSxFQUNsRSxJQUFJLE9BQU8sVUFBVSxZQUFZLE1BQU0sS0FBSyxFQUFFLFdBQVcsR0FBRztBQUFBLElBQzNELE1BQU0sSUFBSSx5QkFBd0IsR0FBRyxxQ0FBcUM7QUFBQSxFQUMzRTtBQUFBLEVBQ0EsT0FBTztBQUFBO0FBR1IsU0FBUyxrQkFBa0IsQ0FDMUIsS0FDQSxPQU9DO0FBQUEsRUFDRCxJQUFJLENBQUMsZUFBYyxHQUFHLEdBQUc7QUFBQSxJQUN4QixNQUFNLElBQUkseUJBQ1QsR0FBRyxNQUFNLElBQUksWUFBWSxJQUFJLE1BQU0sTUFBTSxDQUFDLGlDQUMzQztBQUFBLEVBQ0Q7QUFBQSxFQUNBLE1BQU0sS0FBSyxzQkFBc0IsSUFBSSxJQUFJLEtBQUs7QUFBQSxFQUM5QyxNQUFNLFFBQVEsc0JBQXNCLElBQUksT0FBTyxFQUFFO0FBQUEsRUFDakQsSUFDQyxPQUFPLElBQUksWUFBWSxZQUN2QixDQUFDLDBCQUEwQixLQUFLLElBQUksT0FBTyxHQUMxQztBQUFBLElBQ0QsTUFBTSxJQUFJLHlCQUNULEdBQUcsK0NBQ0o7QUFBQSxFQUNEO0FBQUEsRUFDQSxJQUFJLENBQUMsZUFBYyxJQUFJLE9BQU8sR0FBRztBQUFBLElBQ2hDLE1BQU0sSUFBSSx5QkFDVCxHQUFHLHNDQUNKO0FBQUEsRUFDRDtBQUFBLEVBQ0EsT0FBTztBQUFBLElBQ047QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0EsU0FBUyxJQUFJO0FBQUEsSUFDYixTQUFTLE9BQU8sT0FBTyxLQUFLLElBQUksUUFBUSxDQUFDO0FBQUEsRUFDMUM7QUFBQTtBQUdELFNBQVMsc0JBQXNCLENBQUMsS0FBaUM7QUFBQSxFQUNoRSxNQUFNLE9BQU8sbUJBQW1CLEtBQUssUUFBUTtBQUFBLEVBQzdDLElBQUksQ0FBQyxlQUFjLEtBQUssSUFBSSxNQUFNLEdBQUc7QUFBQSxJQUNwQyxNQUFNLElBQUkseUJBQ1QsR0FBRyxLQUFLLHFDQUNUO0FBQUEsRUFDRDtBQUFBLEVBQ0EsT0FBTyxPQUFPLE9BQU87QUFBQSxJQUNwQixJQUFJLEtBQUs7QUFBQSxJQUNULE9BQU8sS0FBSztBQUFBLElBQ1osU0FBUyxLQUFLO0FBQUEsSUFDZCxTQUFTLEtBQUs7QUFBQSxJQUNkLFFBQVEsT0FBTyxPQUFPLEtBQUssS0FBSyxJQUFJLE9BQU8sQ0FBQztBQUFBLEVBQzdDLENBQUM7QUFBQTtBQUdGLFNBQVMsc0JBQXNCLENBQUMsS0FBaUM7QUFBQSxFQUNoRSxNQUFNLE9BQU8sbUJBQW1CLEtBQUssUUFBUTtBQUFBLEVBQzdDLE1BQU0sV0FBVyxLQUFLLElBQUk7QUFBQSxFQUMxQixJQUFJLENBQUMsZUFBYyxRQUFRLEtBQUssT0FBTyxLQUFLLFFBQVEsRUFBRSxXQUFXLEdBQUc7QUFBQSxJQUNuRSxNQUFNLElBQUkseUJBQ1QsR0FBRyxLQUFLLHlEQUNUO0FBQUEsRUFDRDtBQUFBLEVBQ0EsTUFBTSxTQUVGLENBQUM7QUFBQSxFQUNMLFlBQVksTUFBTSxXQUFXLE9BQU8sUUFBUSxRQUFRLEdBQUc7QUFBQSxJQUN0RCxJQUFJLENBQUMsbUJBQW1CLFNBQVMsSUFBdUIsR0FBRztBQUFBLE1BQzFELE1BQU0sSUFBSSx5QkFDVCxHQUFHLEtBQUssT0FBTyxpQ0FDaEI7QUFBQSxJQUNEO0FBQUEsSUFDQSxJQUFJLENBQUMsZUFBYyxNQUFNLEdBQUc7QUFBQSxNQUMzQixNQUFNLElBQUkseUJBQ1QsR0FBRyxLQUFLLGNBQWMsK0JBQ3ZCO0FBQUEsSUFDRDtBQUFBLElBQ0EsT0FBTyxRQUEyQixPQUFPLE9BQU8sS0FBSyxPQUFPLENBQUM7QUFBQSxFQUM5RDtBQUFBLEVBQ0EsT0FBTyxPQUFPLE9BQU87QUFBQSxJQUNwQixJQUFJLEtBQUs7QUFBQSxJQUNULE9BQU8sS0FBSztBQUFBLElBQ1osU0FBUyxLQUFLO0FBQUEsSUFDZCxTQUFTLEtBQUs7QUFBQSxJQUNkLFFBQVEsT0FBTyxPQUFPLE1BQU07QUFBQSxFQUM3QixDQUFDO0FBQUE7QUFNSyxTQUFTLHVCQUFzQixDQUNyQyxPQUNvQjtBQUFBLEVBQ3BCLElBQUksU0FBa0I7QUFBQSxFQUN0QixJQUFJLE9BQU8sVUFBVSxVQUFVO0FBQUEsSUFDOUIsSUFBSTtBQUFBLE1BQ0gsU0FBUyxLQUFLLE1BQU0sS0FBSztBQUFBLE1BQ3hCLE1BQU07QUFBQSxNQUNQLE1BQU0sSUFBSSx5QkFBd0Isc0NBQXNDO0FBQUE7QUFBQSxFQUUxRTtBQUFBLEVBQ0EsSUFBSSxDQUFDLGVBQWMsTUFBTSxHQUFHO0FBQUEsSUFDM0IsTUFBTSxJQUFJLHlCQUF3QixzQ0FBc0M7QUFBQSxFQUN6RTtBQUFBLEVBQ0EsSUFBSSxPQUFPLG1CQUFtQixvQ0FBbUM7QUFBQSxJQUNoRSxNQUFNLElBQUkseUJBQ1Qsa0RBQWtELE9BQU8sT0FBTyxjQUFjLEdBQy9FO0FBQUEsRUFDRDtBQUFBLEVBQ0EsTUFBTSxLQUFLLHNCQUFzQixPQUFPLElBQUksUUFBUTtBQUFBLEVBQ3BELE1BQU0sUUFBUSxzQkFBc0IsT0FBTyxPQUFPLEVBQUU7QUFBQSxFQUNwRCxJQUFJLENBQUMsTUFBTSxRQUFRLE9BQU8sT0FBTyxHQUFHO0FBQUEsSUFDbkMsTUFBTSxJQUFJLHlCQUF3QixHQUFHLDhCQUE4QjtBQUFBLEVBQ3BFO0FBQUEsRUFDQSxNQUFNLGtCQUFrQixPQUFPLFdBQVcsQ0FBQztBQUFBLEVBQzNDLElBQUksQ0FBQyxNQUFNLFFBQVEsZUFBZSxHQUFHO0FBQUEsSUFDcEMsTUFBTSxJQUFJLHlCQUF3QixHQUFHLDhCQUE4QjtBQUFBLEVBQ3BFO0FBQUEsRUFFQSxNQUFNLFVBQVUsSUFBSTtBQUFBLEVBQ3BCLE1BQU0sUUFBUSxDQUFDLGFBQXFCLFVBQXdCO0FBQUEsSUFDM0QsSUFBSSxRQUFRLElBQUksV0FBVyxHQUFHO0FBQUEsTUFDN0IsTUFBTSxJQUFJLHlCQUNULEdBQUcsaUJBQWlCLFlBQVksYUFDakM7QUFBQSxJQUNEO0FBQUEsSUFDQSxRQUFRLElBQUksV0FBVztBQUFBO0FBQUEsRUFFeEIsTUFBTSxVQUErQixDQUFDO0FBQUEsRUFDdEMsV0FBVyxRQUFRLE9BQU8sU0FBUztBQUFBLElBQ2xDLE1BQU0sU0FBUyx1QkFBdUIsSUFBSTtBQUFBLElBQzFDLE1BQU0sT0FBTyxJQUFJLFFBQVE7QUFBQSxJQUN6QixRQUFRLEtBQUssTUFBTTtBQUFBLEVBQ3BCO0FBQUEsRUFDQSxNQUFNLFVBQStCLENBQUM7QUFBQSxFQUN0QyxXQUFXLFFBQVEsaUJBQWlCO0FBQUEsSUFDbkMsTUFBTSxTQUFTLHVCQUF1QixJQUFJO0FBQUEsSUFDMUMsTUFBTSxPQUFPLElBQUksUUFBUTtBQUFBLElBQ3pCLFFBQVEsS0FBSyxNQUFNO0FBQUEsRUFDcEI7QUFBQSxFQUNBLE1BQU0sT0FBTyxDQUNaLE1BQ0EsVUFDYSxLQUFLLEtBQUssTUFBTSxLQUFLLEtBQUs7QUFBQSxFQUN4QyxRQUFRLEtBQUssSUFBSTtBQUFBLEVBQ2pCLFFBQVEsS0FBSyxJQUFJO0FBQUEsRUFDakIsT0FBTyxPQUFPLE9BQU87QUFBQSxJQUNwQixnQkFBZ0I7QUFBQSxJQUNoQjtBQUFBLElBQ0E7QUFBQSxJQUNBLFNBQVMsT0FBTyxPQUFPLE9BQU87QUFBQSxJQUM5QixTQUFTLE9BQU8sT0FBTyxPQUFPO0FBQUEsRUFDL0IsQ0FBQztBQUFBOyIsCiAgImRlYnVnSWQiOiAiQkY1Nzk1QUU3Q0NCMEI1NDY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=