@expressive/mvc 0.71.0 → 0.72.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/dist/esm/model.js DELETED
@@ -1,318 +0,0 @@
1
- import { addListener, createEffect, event, Observable, PENDING_KEYS } from "./control";
2
- const define = Object.defineProperty;
3
- const ID = /* @__PURE__ */ new WeakMap();
4
- const STATE = /* @__PURE__ */ new WeakMap();
5
- const NOTIFY = /* @__PURE__ */ new WeakMap();
6
- const PARENT = /* @__PURE__ */ new WeakMap();
7
- const METHODS = /* @__PURE__ */ new WeakMap();
8
- const METHOD = /* @__PURE__ */ new WeakMap();
9
- class Model {
10
- constructor(...args) {
11
- prepare(this);
12
- define(this, "is", { value: this });
13
- init(this, args);
14
- }
15
- [Observable](callback, required) {
16
- const watch2 = /* @__PURE__ */ new Set();
17
- const proxy = Object.create(this);
18
- addListener(this, (key) => {
19
- if (watch2.has(key))
20
- callback();
21
- });
22
- OBSERVER.set(proxy, (key, value) => {
23
- if (value === void 0 && required)
24
- throw new Error(`${this}.${key} is required in this context.`);
25
- watch2.add(key);
26
- if (value instanceof Object && Observable in value)
27
- return value[Observable](callback, required) || value;
28
- return value;
29
- });
30
- return proxy;
31
- }
32
- get(arg1, arg2) {
33
- const self = this.is;
34
- if (typeof arg1 == "function") {
35
- const effect = METHOD.get(arg1) || arg1;
36
- let pending = /* @__PURE__ */ new Set();
37
- return createEffect(self, (proxy) => {
38
- const cb = effect.call(proxy, proxy, pending);
39
- return cb === null ? null : (update2) => {
40
- pending = PENDING_KEYS.get(self);
41
- if (typeof cb == "function")
42
- cb(update2);
43
- };
44
- });
45
- }
46
- return arg1 === void 0 ? snapshot(self) : typeof arg2 == "function" ? addListener(self, arg2, arg1) : arg1 === null ? Object.isFrozen(STATE.get(self)) : fetch(self, arg1, arg2);
47
- }
48
- set(arg1, arg2, arg3) {
49
- const self = this.is;
50
- if (typeof arg1 == "function")
51
- return addListener(self, (key) => {
52
- if (arg2 === key || arg2 === void 0 && typeof key == "string")
53
- return arg1.call(self, key, self);
54
- });
55
- if (arg1 && typeof arg1 == "object")
56
- assign(self, arg1, arg2 === true);
57
- else if (!arg2)
58
- event(self, arg1);
59
- else if (arg3)
60
- manage(self, arg1, arg2);
61
- else
62
- update(self, arg1, arg2);
63
- const pending = PENDING_KEYS.get(this);
64
- if (pending)
65
- return {
66
- then: (res) => new Promise((res2) => {
67
- const remove = addListener(this, (key) => {
68
- if (key !== true) {
69
- remove();
70
- return res2.bind(null, Array.from(pending));
71
- }
72
- });
73
- }).then(res)
74
- };
75
- }
76
- /**
77
- * Iterate over managed properties in this instance of Model.
78
- * Yeilds the key and current value for each property.
79
- */
80
- [Symbol.iterator]() {
81
- return Object.entries(STATE.get(this.is))[Symbol.iterator]();
82
- }
83
- /**
84
- * Create and activate a new instance of this model.
85
- *
86
- * **Important** - Unlike `new this(...)` - this method also activates state.
87
- *
88
- * @param args - arguments sent to constructor
89
- */
90
- static new(...args) {
91
- const instance = new this(...args);
92
- event(instance);
93
- return instance;
94
- }
95
- /**
96
- * Static equivalent of `x instanceof this`.
97
- * Determines if provided class is a subtype of this one.
98
- * If so, language server will make available all static
99
- * methods and properties of this class.
100
- */
101
- static is(maybe) {
102
- return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
103
- }
104
- /**
105
- * Register a callback to run when any instance of this Model is updated.
106
- */
107
- static on(listener) {
108
- let notify = NOTIFY.get(this);
109
- if (!notify)
110
- NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
111
- notify.add(listener);
112
- return () => notify.delete(listener);
113
- }
114
- }
115
- define(Model.prototype, "toString", {
116
- value() {
117
- return ID.get(this.is);
118
- }
119
- });
120
- define(Model, "toString", {
121
- value() {
122
- return this.name;
123
- }
124
- });
125
- function assign(subject, data, silent) {
126
- const methods = METHODS.get(subject.constructor);
127
- for (const key in data) {
128
- const bind = methods.get(key);
129
- if (bind)
130
- bind.call(subject, data[key]);
131
- else if (key in subject && key !== "is") {
132
- const desc = Object.getOwnPropertyDescriptor(subject, key);
133
- const set = desc && desc.set;
134
- if (set)
135
- set.call(subject, data[key], silent);
136
- else
137
- subject[key] = data[key];
138
- }
139
- }
140
- }
141
- function prepare(model) {
142
- let T = model.constructor;
143
- if (T === Model)
144
- throw new Error("Cannot create base Model.");
145
- const chain = [];
146
- let keys = /* @__PURE__ */ new Map();
147
- ID.set(model, `${T}-${uid()}`);
148
- while (T.name) {
149
- for (const cb of NOTIFY.get(T) || [])
150
- addListener(model, cb);
151
- if (T === Model) break;
152
- else chain.unshift(T);
153
- T = Object.getPrototypeOf(T);
154
- }
155
- for (const type of chain) {
156
- if (METHODS.has(type)) {
157
- keys = METHODS.get(type);
158
- continue;
159
- }
160
- METHODS.set(type, keys = new Map(keys));
161
- for (const [key, { value }] of Object.entries(
162
- Object.getOwnPropertyDescriptors(type.prototype)
163
- )) {
164
- let bind2 = function(original) {
165
- const { is } = this;
166
- if (is.hasOwnProperty(key) && !original)
167
- return value;
168
- const fn = original || value;
169
- const bound = fn.bind(is);
170
- METHOD.set(bound, fn);
171
- define(is, key, { value: bound, writable: true });
172
- return bound;
173
- };
174
- var bind = bind2;
175
- if (!value || key == "constructor")
176
- continue;
177
- keys.set(key, bind2);
178
- define(type.prototype, key, { get: bind2, set: bind2 });
179
- }
180
- }
181
- }
182
- function init(model, args) {
183
- const state = {};
184
- STATE.set(model, state);
185
- args = args.flat().filter((arg) => {
186
- if (typeof arg != "string")
187
- return true;
188
- ID.set(model, arg);
189
- });
190
- addListener(model, () => {
191
- if (!PARENT.has(model))
192
- PARENT.set(model, null);
193
- for (const key in model) {
194
- const desc = Object.getOwnPropertyDescriptor(model, key);
195
- if ("value" in desc)
196
- manage(model, key, desc.value, true);
197
- }
198
- for (const arg of args) {
199
- const use = typeof arg == "function" ? arg.call(model, model) : arg;
200
- if (use instanceof Promise)
201
- use.catch((err) => {
202
- console.error(`Async error in constructor for ${model}:`);
203
- console.error(err);
204
- });
205
- else if (typeof use == "function")
206
- addListener(model, use, null);
207
- else if (typeof use == "object")
208
- assign(model, use, true);
209
- }
210
- addListener(model, () => {
211
- for (const [_, value] of model)
212
- if (value instanceof Model && PARENT.get(value) === model)
213
- value.set(null);
214
- Object.freeze(state);
215
- }, null);
216
- return null;
217
- });
218
- }
219
- function manage(target, key, value, silent) {
220
- const state = STATE.get(target);
221
- function get() {
222
- return watch(this, key, state[key]);
223
- }
224
- function set(value2, silent2) {
225
- update(target, key, value2, silent2);
226
- if (value2 instanceof Model && !PARENT.has(value2)) {
227
- PARENT.set(value2, target);
228
- event(value2);
229
- }
230
- }
231
- define(target, key, { set, get });
232
- set(value, silent);
233
- }
234
- const OBSERVER = /* @__PURE__ */ new WeakMap();
235
- function watch(from, key, value) {
236
- const access = OBSERVER.get(from);
237
- return access ? access(key, value) : value;
238
- }
239
- function fetch(subject, property, required) {
240
- const state = STATE.get(subject);
241
- if (property in state || required === false) {
242
- const value = state[property];
243
- if (value !== void 0 || !required)
244
- return value;
245
- }
246
- if (METHODS.get(subject.constructor).has(property))
247
- return METHOD.get(subject[property]);
248
- const error = new Error(`${subject}.${property} is not yet available.`);
249
- const promise = new Promise((resolve, reject) => {
250
- addListener(subject, (key) => {
251
- if (key === property) {
252
- resolve(state[key]);
253
- return null;
254
- }
255
- if (key === null)
256
- reject(new Error(`${subject} is destroyed.`));
257
- });
258
- });
259
- throw Object.assign(promise, {
260
- toString: () => String(error),
261
- name: "Suspense",
262
- message: error.message,
263
- stack: error.stack
264
- });
265
- }
266
- let EXPORT;
267
- function snapshot(model) {
268
- const values = {};
269
- let isNotRecursive;
270
- if (!EXPORT) {
271
- isNotRecursive = true;
272
- EXPORT = /* @__PURE__ */ new Map([[model, values]]);
273
- }
274
- for (let [key, value] of model) {
275
- if (EXPORT.has(value))
276
- value = EXPORT.get(value);
277
- else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
278
- EXPORT.set(value, value = value.get());
279
- values[key] = value;
280
- }
281
- if (isNotRecursive)
282
- EXPORT = void 0;
283
- return Object.freeze(values);
284
- }
285
- function update(subject, key, value, arg) {
286
- const state = STATE.get(subject);
287
- if (Object.isFrozen(state))
288
- throw new Error(`Tried to update ${subject}.${String(key)} but model is destroyed.`);
289
- const previous = state[key];
290
- if (typeof arg == "function") {
291
- const out = arg.call(subject, value, previous);
292
- if (out === false)
293
- return false;
294
- if (typeof out == "function")
295
- value = out();
296
- }
297
- if (value === previous && key in state)
298
- return;
299
- state[key] = value;
300
- if (arg !== true)
301
- event(subject, key);
302
- return true;
303
- }
304
- function uid() {
305
- return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
306
- }
307
- export {
308
- METHOD,
309
- Model,
310
- PARENT,
311
- STATE,
312
- event,
313
- fetch,
314
- uid,
315
- update,
316
- watch
317
- };
318
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL21vZGVsLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBhZGRMaXN0ZW5lciwgY3JlYXRlRWZmZWN0LCBldmVudCwgT2JzZXJ2YWJsZSwgT25VcGRhdGUsIFBFTkRJTkdfS0VZUyB9IGZyb20gJy4vY29udHJvbCc7XG5cbmNvbnN0IGRlZmluZSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuLyoqIFJlZ2lzdGVyIGZvciBhbGwgYWN0aXZlIG1vZGVscyB2aWEgc3RyaW5nIGlkZW50aWZpZXJzICh1c3VhbGx5IHVuaXF1ZSkuICovXG5jb25zdCBJRCA9IG5ldyBXZWFrTWFwPE1vZGVsLCBzdHJpbmc+KCk7XG5cbi8qKiBJbnRlcm5hbCBzdGF0ZSBhc3NpZ25lZCB0byBtb2RlbHMuICovXG5jb25zdCBTVEFURSA9IG5ldyBXZWFrTWFwPE1vZGVsLCBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sLCB1bmtub3duPj4oKTtcblxuLyoqIEV4dGVybmFsIGxpc3RlbmVycyBmb3IgYW55IGdpdmVuIE1vZGVsLiAqL1xuY29uc3QgTk9USUZZID0gbmV3IFdlYWtNYXA8TW9kZWwuVHlwZSwgU2V0PE9uVXBkYXRlPj4oKTtcblxuLyoqIFBhcmVudC1jaGlsZCByZWxhdGlvbnNoaXBzLiAqL1xuY29uc3QgUEFSRU5UID0gbmV3IFdlYWtNYXA8TW9kZWwsIE1vZGVsIHwgbnVsbD4oKTtcblxuLyoqIExpc3Qgb2YgbWV0aG9kcyBkZWZpbmVkIGJ5IGEgZ2l2ZW4gdHlwZS4gKi9cbmNvbnN0IE1FVEhPRFMgPSBuZXcgV2Vha01hcDxNb2RlbC5UeXBlLCBNYXA8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gdm9pZD4+KCk7XG5cbi8qKiBSZWZlcmVuY2UgYm91bmQgaW5zdGFuY2UgbWV0aG9kcyB0byByZWFsIG9uZXMuICovXG5jb25zdCBNRVRIT0QgPSBuZXcgV2Vha01hcDxhbnksIGFueT4oKTtcblxuZGVjbGFyZSBuYW1lc3BhY2UgTW9kZWwge1xuICAvKiogQW55IHR5cGUgb2YgTW9kZWwsIHVzaW5nIG93biBjbGFzcyBjb25zdHJ1Y3RvciBhcyBpdHMgaWRlbnRpZmllci4gKi9cbiAgdHlwZSBUeXBlPFQgZXh0ZW5kcyBNb2RlbCA9IE1vZGVsPiA9XG4gICAgKGFic3RyYWN0IG5ldyAoLi4uYXJnczogYW55W10pID0+IFQpICYgdHlwZW9mIE1vZGVsO1xuXG4gIC8qKiBBIE1vZGVsIGNvbnN0cnVjdG9yLCBidXQgd2hpY2ggaXMgbm90IGFic3RyYWN0LiAqL1xuICB0eXBlIEluaXQ8VCBleHRlbmRzIE1vZGVsID0gTW9kZWw+ID1cbiAgICAobmV3ICguLi5hcmdzOiBNb2RlbC5BcmdzPFQ+KSA9PiBUKSAmIE9taXQ8dHlwZW9mIE1vZGVsLCBuZXZlcj47XG5cbiAgLyoqXG4gICAqIE1vZGVsIGNvbnN0cnVjdG9yIGNhbGxiYWNrIC0gaXMgY2FsbGVkIHdoZW4gTW9kZWwgZmluaXNoZXMgaW50aWFsaXppbmcuXG4gICAqIFJldHVybmVkIGZ1bmN0aW9uIHdpbGwgcnVuIHdoZW4gbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgdHlwZSBDYWxsYmFjazxUIGV4dGVuZHMgTW9kZWwgPSBNb2RlbD4gPVxuICAgICh0aGlzOiBULCB0aGlzQXJnOiBUKSA9PiBQcm9taXNlPHZvaWQ+IHwgKCgpID0+IHZvaWQpIHwgQXNzaWduPFQ+IHwgdm9pZDtcblxuICAvKiogTW9kZWwgY29uc3RydWN0b3IgYXJndW1lbnQgKi9cbiAgdHlwZSBBcmd1bWVudDxUIGV4dGVuZHMgTW9kZWwgPSBNb2RlbD4gPSBBc3NpZ248VD4gfCBDYWxsYmFjazxUPiB8IHN0cmluZyB8IHZvaWQ7XG5cbiAgLyoqIE1vZGVsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyAqL1xuICB0eXBlIEFyZ3M8VCBleHRlbmRzIE1vZGVsID0gYW55PiA9IChBcmd1bWVudDxUPiB8IEFyZ3M8VD4pW107XG5cbiAgLyoqIFN1YnNldCBvZiBga2V5b2YgVGAgd2hpY2ggYXJlIG5vdCBtZXRob2RzIG9yIGRlZmluZWQgYnkgYmFzZSBNb2RlbCBVLiAqKi9cbiAgdHlwZSBGaWVsZDxUPiA9IEV4Y2x1ZGU8a2V5b2YgVCwga2V5b2YgTW9kZWw+O1xuXG4gIC8qKiBBbnkgdmFsaWQga2V5IGZvciBtb2RlbCwgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBGaWVsZDxUPi4gKi9cbiAgdHlwZSBFdmVudDxUPiA9IEZpZWxkPFQ+IHwgKHN0cmluZyAmIHt9KSB8IG51bWJlciB8IHN5bWJvbDtcblxuICAvKiogT2JqZWN0IG92ZXJsYXkgdG8gb3ZlcnJpZGUgdmFsdWVzIGFuZCBtZXRob2RzIG9uIGEgbW9kZWwuICovXG4gIHR5cGUgQXNzaWduPFQ+ID0ge1xuICAgIFtLIGluIEZpZWxkPFQ+XT86XG4gICAgICBUW0tdIGV4dGVuZHMgKC4uLmFyZ3M6IGluZmVyIEEpID0+IGluZmVyIFIgXG4gICAgICAgID8gKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbiAgICAgICAgOiBUW0tdO1xuICB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgLyoqIEV4cG9ydC9JbXBvcnQgY29tcGF0aWJsZSB2YWx1ZSBmb3IgYSBnaXZlbiBwcm9wZXJ0eSBpbiBhIE1vZGVsLiAqL1xuICB0eXBlIEV4cG9ydDxSPiA9IFIgZXh0ZW5kcyB7IGdldCgpOiBpbmZlciBUIH0gPyBUIDogUjtcblxuICAvKiogVmFsdWUgZm9yIGEgcHJvcGVydHkgbWFuYWdlZCBieSBhIG1vZGVsLiAqL1xuICB0eXBlIFZhbHVlPFQgZXh0ZW5kcyBNb2RlbCwgSyBleHRlbmRzIEV2ZW50PFQ+PiA9XG4gICAgSyBleHRlbmRzIGtleW9mIFQgPyBFeHBvcnQ8VFtLXT4gOiB1bmtub3duO1xuXG4gIHR5cGUgT25FdmVudDxUIGV4dGVuZHMgTW9kZWw+ID1cbiAgICAodGhpczogVCwga2V5OiB1bmtub3duLCBzb3VyY2U6IFQpID0+ICgoKSA9PiB2b2lkKSB8IHZvaWQgfCBudWxsO1xuXG4gIHR5cGUgT25VcGRhdGU8VCBleHRlbmRzIE1vZGVsLCBLIGV4dGVuZHMgRXZlbnQ8VD4+ID1cbiAgICAodGhpczogVCwga2V5OiBLLCB0aGlzQXJnOiBLKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBWYWx1ZXMgZnJvbSBjdXJyZW50IHN0YXRlIG9mIGdpdmVuIG1vZGVsLlxuICAgKiBEaWZmZXJzIGZyb20gYFZhbHVlc2AgYXMgdmFsdWVzIGhlcmUgd2lsbCBkcmlsbFxuICAgKiBpbnRvIFwicmVhbFwiIHZhbHVlcyBoZWxkIGJ5IGV4b3RpY3MgbGlrZSByZWYuT2JqZWN0LlxuICAgKi9cbiAgdHlwZSBTdGF0ZTxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dOiBFeHBvcnQ8VFtQXT4gfTtcblxuICAvKiogT2JqZWN0IGNvbXBlcmFibGUgdG8gZGF0YSBmb3VuZCBpbiBULiAqL1xuICB0eXBlIFZhbHVlczxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dPzogRXhwb3J0PFRbUF0+IH07XG5cbiAgLyoqIEV4b3RpYyB2YWx1ZSwgd2hlcmUgYWN0dWFsIHZhbHVlIGlzIGNvbnRhaW5lZCB3aXRoaW4uICovXG4gIHR5cGUgUmVmPFQgPSBhbnk+ID0ge1xuICAgIChuZXh0OiBUKTogdm9pZDtcbiAgICBjdXJyZW50OiBUIHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIHN1YnNjcmliZWQgdG8gcGFyZW50IGFuZCB1cGRhdGVzIHdoZW4gYWNjZXNzZWQgcHJvcGVydGllcyBjaGFuZ2UuXG4gICAqIFxuICAgKiBAcGFyYW0gY3VycmVudCAtIEN1cnJlbnQgc3RhdGUgb2YgdGhpcyBtb2RlbC4gVGhpcyBpcyBhIHByb3h5IHdoaWNoIGRldGVjdHMgcHJvcGVydGllcyB3aGljaFxuICAgKiB3aGVyZSBhY2Nlc3NlZCwgYW5kIHRodXMgZGVwZW5kZWQgdXBvbiB0byBzdGF5IGN1cnJlbnQuXG4gICAqIFxuICAgKiBAcGFyYW0gdXBkYXRlIC0gU2V0IG9mIHByb3BlcnRpZXMgd2hpY2ggaGF2ZSBjaGFuZ2VkLCBhbmQgZXZlbnRzIGZpcmVkLCBzaW5jZSBsYXN0IHVwZGF0ZS5cbiAgICogXG4gICAqIEByZXR1cm5zIEEgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGlzIGVmZmVjdCBpcyBzdGFsZS5cbiAgICovXG4gIHR5cGUgRWZmZWN0PFQ+ID0gKHRoaXM6IFQsIGN1cnJlbnQ6IFQsIHVwZGF0ZTogU2V0PEV2ZW50PFQ+PikgPT5cbiAgICBFZmZlY3RDYWxsYmFjayB8IFByb21pc2U8dm9pZD4gfCBudWxsIHwgdm9pZDtcblxuICAvKipcbiAgICogQSBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5lZCBieSBlZmZlY3QuIFdpbGwgYmUgY2FsbGVkIHdoZW4gZWZmZWN0IGlzIHN0YWxlLlxuICAgKiBcbiAgICogQHBhcmFtIHVwZGF0ZSAtIGB0cnVlYCBpZiB1cGRhdGUgaXMgcGVuZGluZywgYGZhbHNlYCBlZmZlY3QgaGFzIGJlZW4gY2FuY2VsbGVkLCBgbnVsbGAgaWYgbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgdHlwZSBFZmZlY3RDYWxsYmFjayA9ICgodXBkYXRlOiBib29sZWFuIHwgbnVsbCkgPT4gdm9pZCk7XG5cbiAgLyoqXG4gICAqIFByb3BlcnR5IGluaXRpYWxpemVyLCB3aWxsIHJ1biB1cG9uIGluc3RhbmNlIGNyZWF0aW9uLlxuICAgKiBPcHRpb25hbCByZXR1cm5lZCBjYWxsYmFjayB3aWxsIHJ1biB3aGVuIG9uY2UgdXBvbiBmaXJzdCBhY2Nlc3MuXG4gICAqL1xuICB0eXBlIEluc3RydWN0aW9uPFQgPSBhbnksIE0gZXh0ZW5kcyBNb2RlbCA9IGFueT4gPVxuICAgIC8vIFRPRE86IFNob3VsZCB0aGlzIGFsbG93IGZvciBudW1iZXJzL3N5bWJvbCBwcm9wZXJ0aWVzP1xuICAgICh0aGlzOiBNLCBrZXk6IEV4dHJhY3Q8RmllbGQ8TT4sIHN0cmluZz4sIHRoaXNBcmc6IE0sIHN0YXRlOiBTdGF0ZTxNPikgPT5cbiAgICAgIERlc2NyaXB0b3I8VD4gfCAoKHNvdXJjZTogTSkgPT4gVCkgfCB2b2lkO1xuXG4gIHR5cGUgR2V0dGVyPFQ+ID0gKHNvdXJjZTogTW9kZWwpID0+IFQ7XG4gIHR5cGUgU2V0dGVyPFQ+ID0gKHZhbHVlOiBULCBwcmV2aW91czogVCkgPT4gYm9vbGVhbiB8IHZvaWQgfCAoKCkgPT4gVCk7XG5cbiAgdHlwZSBEZXNjcmlwdG9yPFQgPSBhbnk+ID0ge1xuICAgIGdldD86IEdldHRlcjxUPiB8IGJvb2xlYW47XG4gICAgc2V0PzogU2V0dGVyPFQ+IHwgYm9vbGVhbjtcbiAgICBlbnVtZXJhYmxlPzogYm9vbGVhbjtcbiAgICB2YWx1ZT86IFQ7XG4gIH1cbn1cblxuaW50ZXJmYWNlIE1vZGVsIHtcbiAgLyoqXG4gICAqIExvb3BiYWNrIHRvIGluc3RhbmNlIG9mIHRoaXMgbW9kZWwuIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW4gYSBzdWJzY3JpYmVkIGNvbnRleHQsXG4gICAqIHRvIGtlZXAgd3JpdGUgYWNjZXNzIHRvIGB0aGlzYCBhZnRlciBhIGRlc3RydWN0dXJlLiBZb3UgY2FuIHVzZSBpdCB0byByZWFkIHZhcmlhYmxlcyBzaWxlbnRseSBhcyB3ZWxsLlxuICAgKiovXG4gIGlzOiB0aGlzO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBNb2RlbCBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBjb25zdHJ1Y3RvciguLi5hcmdzOiBNb2RlbC5BcmdzKXtcbiAgICBwcmVwYXJlKHRoaXMpO1xuICAgIGRlZmluZSh0aGlzLCBcImlzXCIsIHsgdmFsdWU6IHRoaXMgfSk7XG4gICAgaW5pdCh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIFtPYnNlcnZhYmxlXShjYWxsYmFjazogT2JzZXJ2YWJsZS5DYWxsYmFjaywgcmVxdWlyZWQ/OiBib29sZWFuKXtcbiAgICBjb25zdCB3YXRjaCA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgICBjb25zdCBwcm94eSA9IE9iamVjdC5jcmVhdGUodGhpcyk7XG4gICAgXG4gICAgYWRkTGlzdGVuZXIodGhpcywgKGtleSkgPT4ge1xuICAgICAgaWYod2F0Y2guaGFzKGtleSkpXG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG5cbiAgICBPQlNFUlZFUi5zZXQocHJveHksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZih2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIHJlcXVpcmVkKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpc30uJHtrZXl9IGlzIHJlcXVpcmVkIGluIHRoaXMgY29udGV4dC5gKTtcblxuICAgICAgd2F0Y2guYWRkKGtleSk7XG5cbiAgICAgIGlmKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIE9ic2VydmFibGUgaW4gdmFsdWUpXG4gICAgICAgIHJldHVybiB2YWx1ZVtPYnNlcnZhYmxlXShjYWxsYmFjaywgcmVxdWlyZWQpIHx8IHZhbHVlO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcHJveHkgYXMgdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxsIGN1cnJlbnQgdmFsdWVzIGZyb20gc3RhdGUuIEZsYXR0ZW5zIGFsbCBtb2RlbHMgYW5kIGV4b3RpYyB2YWx1ZXMgcmVjdXJzaXZlbHkuXG4gICAqIFxuICAgKiBAcmV0dXJucyBPYmplY3Qgd2l0aCBhbGwgdmFsdWVzIGZyb20gdGhpcyBtb2RlbC5cbiAgICoqL1xuICBnZXQoKTogTW9kZWwuU3RhdGU8dGhpcz47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoaWNoIHdpbGwgcnVuIGF1dG9tYXRpY2FsbHkgd2hlbiBhY2Nlc3NlZCB2YWx1ZXMgY2hhbmdlLlxuICAgKiBcbiAgICogQHBhcmFtIGVmZmVjdCBGdW5jdGlvbiB0byBydW4sIGFuZCBhZ2FpbiB3aGVuZXZlciBhY2Nlc3NlZCB2YWx1ZXMgY2hhbmdlLlxuICAgKiAgICAgICAgICAgICAgIElmIGVmZmVjdCByZXR1cm5zIGEgZnVuY3Rpb24sIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBjaGFuZ2Ugb2NjdXJzIChzeW5jcm9ub3VzbHkpLFxuICAgKiAgICAgICAgICAgICAgIGVmZmVjdCBpcyBjYW5jZWxsZWQsIG9yIHBhcmVudCBtb2RlbCBpcyBkZXN0cm95ZWQuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIGNhbmNlbCBsaXN0ZW5lci5cbiAgICovXG4gIGdldChlZmZlY3Q6IE1vZGVsLkVmZmVjdDx0aGlzPik6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEdldCB2YWx1ZSBvZiBhIHByb3BlcnR5LlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIGdldCB2YWx1ZSBvZi5cbiAgICogQHBhcmFtIHJlcXVpcmVkIC0gSWYgdHJ1ZSwgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcmV0dXJucyBWYWx1ZSBvZiBwcm9wZXJ0eS5cbiAgICovXG4gIGdldDxUIGV4dGVuZHMgTW9kZWwuRXZlbnQ8dGhpcz4+KGtleTogVCwgcmVxdWlyZWQ/OiBib29sZWFuKTogTW9kZWwuVmFsdWU8dGhpcywgVD47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoZW4gYSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogQHJldHVybnMgRnVuY3Rpb24gdG8gY2FuY2VsIGxpc3RlbmVyLlxuICAgKi9cbiAgZ2V0PFQgZXh0ZW5kcyBNb2RlbC5FdmVudDx0aGlzPj4oa2V5OiBULCBjYWxsYmFjazogTW9kZWwuT25VcGRhdGU8dGhpcywgVD4pOiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBtb2RlbCBpcyBleHBpcmVkLlxuICAgKiBcbiAgICogQHBhcmFtIHN0YXR1cyAtIGBudWxsYCB0byBjaGVjayBpZiBtb2RlbCBpcyBleHBpcmVkLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgbW9kZWwgaXMgZXhwaXJlZCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsKTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgd2hlbiBtb2RlbCBpcyB0byBiZSBkZXN0cm95ZWQuXG4gICAqIFxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gbW9kZWwgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsLCBjYWxsYmFjazogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQ7XG5cbiAgZ2V0KGFyZzE/OiBNb2RlbC5FZmZlY3Q8dGhpcz4gfCBzdHJpbmcgfCBudWxsLCBhcmcyPzogYm9vbGVhbiB8IE1vZGVsLk9uVXBkYXRlPHRoaXMsIGFueT4pe1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzLmlzO1xuXG4gICAgaWYodHlwZW9mIGFyZzEgPT0gXCJmdW5jdGlvblwiKXtcbiAgICAgIGNvbnN0IGVmZmVjdCA9IE1FVEhPRC5nZXQoYXJnMSkgfHwgYXJnMTtcbiAgICAgIGxldCBwZW5kaW5nID0gbmV3IFNldDxNb2RlbC5FdmVudDx0aGlzPj4oKTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZUVmZmVjdChzZWxmLCAocHJveHkpID0+IHtcbiAgICAgICAgY29uc3QgY2IgPSBlZmZlY3QuY2FsbChwcm94eSwgcHJveHksIHBlbmRpbmcpO1xuXG4gICAgICAgIHJldHVybiBjYiA9PT0gbnVsbCA/IG51bGwgOiAoKHVwZGF0ZSkgPT4ge1xuICAgICAgICAgIHBlbmRpbmcgPSBQRU5ESU5HX0tFWVMuZ2V0KHNlbGYpITtcbiAgICAgICAgICBpZih0eXBlb2YgY2IgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgY2IodXBkYXRlKTtcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICBhcmcxID09PSB1bmRlZmluZWQgPyBzbmFwc2hvdChzZWxmKSA6XG4gICAgICB0eXBlb2YgYXJnMiA9PSBcImZ1bmN0aW9uXCIgPyBhZGRMaXN0ZW5lcihzZWxmLCBhcmcyLCBhcmcxKSA6XG4gICAgICBhcmcxID09PSBudWxsID8gT2JqZWN0LmlzRnJvemVuKFNUQVRFLmdldChzZWxmKSkgOlxuICAgICAgZmV0Y2goc2VsZiwgYXJnMSwgYXJnMilcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogR2V0IHVwZGF0ZSBpbiBwcm9ncmVzcy5cbiAgICpcbiAgICogQHJldHVybnMgUHJvbWlzZSB3aGljaCByZXNvbHZlcyBvYmplY3Qgd2l0aCB1cGRhdGVkIHZhbHVlcywgYHVuZGVmaW5lZGAgaWYgdGhlcmUgbm8gdXBkYXRlIGlzIHBlbmRpbmcuXG4gICAqKi9cbiAgc2V0KCk6IFByb21pc2VMaWtlPE1vZGVsLkV2ZW50PHRoaXM+W10+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsaXRwbGUgcHJvcGVydGllcyBhdCBvbmNlLiBNZXJnZXMgYXJndW1lbnQgd2l0aCBjdXJyZW50IHN0YXRlLlxuICAgKiBQcm9wZXJ0aWVzIHdoaWNoIGFyZSBub3QgbWFuYWdlZCBieSB0aGlzIG1vZGVsIHdpbGwgYmUgaWdub3JlZC5cbiAgICogXG4gICAqIEBwYXJhbSBhc3NpZ24gLSBPYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIHNpbGVudCAtIElmIGFuIHVwZGF0ZSBkb2VzIG9jY3VyLCBsaXN0ZW5lcnMgd2lsbCBub3QgYmUgcmVmcmVzaGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZCwgYHVuZGVmaW5lZGAgKGltbWVkaWF0ZWx5KSBpZiBhIG5vb3AuXG4gICAqL1xuICBzZXQoYXNzaWduPzogTW9kZWwuQXNzaWduPHRoaXM+LCBzaWxlbnQ/OiBib29sZWFuKTogUHJvbWlzZUxpa2U8TW9kZWwuRXZlbnQ8dGhpcz5bXT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFB1c2ggYW4gdXBkYXRlLiBUaGlzIHdpbGwgbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgYXNzb2NpYXRlZCBwcm9wZXJ0eS5cbiAgICogXG4gICAqIFVzZWZ1bCB3aGVyZSBhIHByb3BlcnR5IHZhbHVlIGludGVybmFsbHkgaGFzIGNoYW5nZWQsIGJ1dCB0aGUgb2JqZWN0IGlzIHRoZSBzYW1lLlxuICAgKiBGb3IgZXhhbXBsZTogQW4gYXJyYXkgaGFzIHB1c2hlZCBhIG5ldyB2YWx1ZSwgb3IgYSBuZXN0ZWQgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgdGhpcyB0byBkaXNwYXRjaCBhcmJpdHJhcnkgZXZlbnRzLlxuICAgKiBTeW1ib2xzIGFyZSByZWNvbW1lbmRlZCBhcyBub24tcHJvcGVydHkgZXZlbnRzLCBob3dldmVyIHlvdSBjYW4gdXNlIGFueSBzdHJpbmcuXG4gICAqIElmIGRvaW5nIHNvLCBiZSBzdXJlIHRvIGF2b2lkIGNvbGxpc2lvbnMgd2l0aCBwcm9wZXJ0eSBuYW1lcyEgQW4gZWFzeSB3YXkgdG8gZG8gdGhpcyBpc1xuICAgKiB0byBwcmVmaXggYW4gZXZlbnQgd2l0aCBcIiFcIiBhbmQvb3IgdXNlIGRhc2gtY2FzZS4gZS5nLiBgc2V0KFwiIWV2ZW50XCIpYCBvciBgc2V0KFwibXktZXZlbnRcIilgLlxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IG9yIGV2ZW50IHRvIGRpc3BhdGNoLlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmVzIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZC5cbiAgICovXG4gIHNldChrZXk6IE1vZGVsLkV2ZW50PHRoaXM+KTogUHJvbWlzZUxpa2U8TW9kZWwuRXZlbnQ8dGhpcz5bXT47XG5cbiAgLyoqXG4gICAqIFNldCBhIHZhbHVlIGZvciBhIHByb3BlcnR5LiBUaGlzIHdpbGwgdXBkYXRlIHRoZSB2YWx1ZSBhbmQgbm90aWZ5IGxpc3RlbmVycy5cbiAgICogXG4gICAqICoqVXNlIHdpdGggY2F1dGlvbiEqKiBLZXkgbm9yIHZhbHVlIGFyZSBjaGVja2VkIGZvciB2YWxpZGl0eS5cbiAgICogXG4gICAqIFRoaXMgaXMgbWVhbnQgZm9yIGFzc2lnbmluZyB2YWx1ZXMgcHJvZ3JhbW1hdGljYWxseSxcbiAgICogd2hlcmUgc2ltcGxlIGFzc2lnbm1lbnQgaXMgbm90IHByYWN0aWNhYmxlLlxuICAgKiBcbiAgICogRm9yIGV4YW1wbGU6IGAodGhpcyBhcyBhbnkpW215UHJvcGVydHldID0gdmFsdWU7YFxuICAgKiBcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIHNldCB2YWx1ZSBmb3IuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIHNldCBmb3IgcHJvcGVydHkuXG4gICAqIEBwYXJhbSBpbml0IC0gSWYgdHJ1ZSwgbW9kZWwgd2lsbCBiZWdpbiB0byBtYW5hZ2UgdGhlIHByb3BlcnR5IGlmIGl0IGlzIG5vdCBhbHJlYWR5LlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmVzIGFuIGFycmF5IG9mIGtleXMgdXBkYXRlZC5cbiAgICovXG4gIHNldChrZXk6IE1vZGVsLkV2ZW50PHRoaXM+LCB2YWx1ZTogdW5rbm93biwgaW5pdD86IGJvb2xlYW4pOiBQcm9taXNlTGlrZTxNb2RlbC5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdXBkYXRlIG9jY3Vycy5cbiAgICogXG4gICAqIEdpdmVuIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgZXZlcnkgYXNzaWdubWVudCAod2hpY2ggY2hhbmdlcyB2YWx1ZSkgb3IgZXhwbGljaXQgYHNldGAuXG4gICAqIFxuICAgKiBUbyBydW4gbG9naWMgb24gZmluYWwgdmFsdWUgb25seSwgY2FsbGJhY2sgbWF5IHJldHVybiBhIGZ1bmN0aW9uLiBVc2luZyB0aGUgc2FtZVxuICAgKiBmdW5jdGlvbiBmb3Igb25lIG9yIG1vcmUgZXZlbnRzIHdpbGwgZW5zdXJlIGl0IGlzIGNhbGxlZCBvbmx5IHdoZW4gZXZlbnRzIGFyZSBzZXR0bGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHVwZGF0ZSBvY2N1cnMuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIHJlbW92ZSBsaXN0ZW5lci4gV2lsbCByZXR1cm4gYHRydWVgIGlmIHJlbW92ZWQsIGBmYWxzZWAgaWYgaW5hY3RpdmUgYWxyZWFkeS5cbiAgICogXG4gICovXG4gIHNldChjYWxsYmFjazogTW9kZWwuT25FdmVudDx0aGlzPik6ICgpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aGVuIGEgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogVW5saWtlIGBnZXRgLCB0aGlzIGNhbHNsIHN5bmNocm9ub3VzbHkgYW5kIHdpbGwgZmlyZSBhcyBtYW55IHRpbWVzIGFzIHRoZSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqIEBwYXJhbSBldmVudCAtIFByb3BlcnR5IHRvIHdhdGNoIGZvciB1cGRhdGVzLlxuICAgKi9cbiAgc2V0KGNhbGxiYWNrOiBNb2RlbC5PbkV2ZW50PHRoaXM+LCBldmVudDogTW9kZWwuRXZlbnQ8dGhpcz4gfCBudWxsKTogKCkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgICogRGVjbGFyZSBhbiBlbmQgdG8gdXBkYXRlcy4gVGhpcyBldmVudCBpcyBmaW5hbCBhbmQgd2lsbCBmcmVlemUgc3RhdGUuXG4gICAqIFRoaXMgZXZlbnQgY2FuIGJlIHdhdGNoZWQgZm9yIGFzIHdlbGwsIHRvIHJ1biBjbGVhbnVwIGxvZ2ljIGFuZCBpbnRlcm5hbGx5IHdpbGwgcmVtb3ZlIGFsbCBsaXN0ZW5lcnMuXG4gICAqIFxuICAgKiBAcGFyYW0gc3RhdHVzIC0gYG51bGxgIHRvIGVuZCB1cGRhdGVzLlxuICAgKi9cbiAgc2V0KHN0YXR1czogbnVsbCk6IHZvaWQ7XG5cbiAgc2V0KFxuICAgIGFyZzE/OiBNb2RlbC5PbkV2ZW50PHRoaXM+IHwgTW9kZWwuQXNzaWduPHRoaXM+IHwgTW9kZWwuRXZlbnQ8dGhpcz4gfCBudWxsLFxuICAgIGFyZzI/OiB1bmtub3duLFxuICAgIGFyZzM/OiBib29sZWFuKXtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzLmlzO1xuXG4gICAgaWYodHlwZW9mIGFyZzEgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgcmV0dXJuIGFkZExpc3RlbmVyKHNlbGYsIGtleSA9PiB7XG4gICAgICAgIGlmKGFyZzIgPT09IGtleSB8fCBhcmcyID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIGtleSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgIHJldHVybiBhcmcxLmNhbGwoc2VsZiwga2V5LCBzZWxmKTtcbiAgICAgIH0pXG4gICAgICBcbiAgICBpZihhcmcxICYmIHR5cGVvZiBhcmcxID09IFwib2JqZWN0XCIpXG4gICAgICBhc3NpZ24oc2VsZiwgYXJnMSwgYXJnMiA9PT0gdHJ1ZSk7XG4gICAgZWxzZSBpZighYXJnMilcbiAgICAgIGV2ZW50KHNlbGYsIGFyZzEpO1xuICAgIGVsc2UgaWYoYXJnMylcbiAgICAgIG1hbmFnZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgZWxzZVxuICAgICAgdXBkYXRlKHNlbGYsIGFyZzEgYXMgc3RyaW5nIHwgbnVtYmVyLCBhcmcyKVxuXG4gICAgY29uc3QgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGhpcyk7XG5cbiAgICBpZihwZW5kaW5nKVxuICAgICAgcmV0dXJuIDxQcm9taXNlTGlrZTxNb2RlbC5FdmVudDx0aGlzPltdPj4ge1xuICAgICAgICB0aGVuOiAocmVzKSA9PiBuZXcgUHJvbWlzZTxhbnk+KHJlcyA9PiB7XG4gICAgICAgICAgY29uc3QgcmVtb3ZlID0gYWRkTGlzdGVuZXIodGhpcywga2V5ID0+IHtcbiAgICAgICAgICAgIGlmKGtleSAhPT0gdHJ1ZSl7XG4gICAgICAgICAgICAgIHJlbW92ZSgpO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzLmJpbmQobnVsbCwgQXJyYXkuZnJvbShwZW5kaW5nKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLnRoZW4ocmVzKVxuICAgICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBtYW5hZ2VkIHByb3BlcnRpZXMgaW4gdGhpcyBpbnN0YW5jZSBvZiBNb2RlbC5cbiAgICogWWVpbGRzIHRoZSBrZXkgYW5kIGN1cnJlbnQgdmFsdWUgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAqL1xuICBbU3ltYm9sLml0ZXJhdG9yXSgpOiBJdGVyYXRvcjxbc3RyaW5nLCB1bmtub3duXT4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhTVEFURS5nZXQodGhpcy5pcykhKVtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuZCBhY3RpdmF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIG1vZGVsLlxuICAgKiBcbiAgICogKipJbXBvcnRhbnQqKiAtIFVubGlrZSBgbmV3IHRoaXMoLi4uKWAgLSB0aGlzIG1ldGhvZCBhbHNvIGFjdGl2YXRlcyBzdGF0ZS5cbiAgICogXG4gICAqIEBwYXJhbSBhcmdzIC0gYXJndW1lbnRzIHNlbnQgdG8gY29uc3RydWN0b3JcbiAgICovXG4gIHN0YXRpYyBuZXc8VCBleHRlbmRzIE1vZGVsPih0aGlzOiBNb2RlbC5Jbml0PFQ+LCAuLi5hcmdzOiBNb2RlbC5BcmdzPFQ+KXtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyB0aGlzKC4uLmFyZ3MpO1xuICAgIGV2ZW50KGluc3RhbmNlKTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIGVxdWl2YWxlbnQgb2YgYHggaW5zdGFuY2VvZiB0aGlzYC5cbiAgICogRGV0ZXJtaW5lcyBpZiBwcm92aWRlZCBjbGFzcyBpcyBhIHN1YnR5cGUgb2YgdGhpcyBvbmUuXG4gICAqIElmIHNvLCBsYW5ndWFnZSBzZXJ2ZXIgd2lsbCBtYWtlIGF2YWlsYWJsZSBhbGwgc3RhdGljXG4gICAqIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMgb2YgdGhpcyBjbGFzcy5cbiAgICovXG4gIHN0YXRpYyBpczxUIGV4dGVuZHMgTW9kZWwuVHlwZT4odGhpczogVCwgbWF5YmU6IHVua25vd24pOiBtYXliZSBpcyBUIHtcbiAgICByZXR1cm4gbWF5YmUgPT09IHRoaXMgfHwgdHlwZW9mIG1heWJlID09IFwiZnVuY3Rpb25cIiAmJiBtYXliZS5wcm90b3R5cGUgaW5zdGFuY2VvZiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcnVuIHdoZW4gYW55IGluc3RhbmNlIG9mIHRoaXMgTW9kZWwgaXMgdXBkYXRlZC4gXG4gICAqL1xuICBzdGF0aWMgb248VCBleHRlbmRzIE1vZGVsPih0aGlzOiBNb2RlbC5UeXBlPFQ+LCBsaXN0ZW5lcjogTW9kZWwuT25FdmVudDxUPil7XG4gICAgbGV0IG5vdGlmeSA9IE5PVElGWS5nZXQodGhpcyk7XG5cbiAgICBpZighbm90aWZ5KVxuICAgICAgTk9USUZZLnNldCh0aGlzLCBub3RpZnkgPSBuZXcgU2V0KTtcblxuICAgIG5vdGlmeS5hZGQobGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuICgpID0+IG5vdGlmeS5kZWxldGUobGlzdGVuZXIpO1xuICB9XG59XG5cbmRlZmluZShNb2RlbC5wcm90b3R5cGUsIFwidG9TdHJpbmdcIiwge1xuICB2YWx1ZSgpe1xuICAgIHJldHVybiBJRC5nZXQodGhpcy5pcyk7XG4gIH1cbn0pO1xuXG5kZWZpbmUoTW9kZWwsIFwidG9TdHJpbmdcIiwge1xuICB2YWx1ZSgpe1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBhc3NpZ24oc3ViamVjdDogTW9kZWwsIGRhdGE6IE1vZGVsLkFzc2lnbjxNb2RlbD4sIHNpbGVudD86IGJvb2xlYW4pe1xuICBjb25zdCBtZXRob2RzID0gTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvciBhcyBNb2RlbC5UeXBlKSE7XG4gICAgXG4gIGZvcihjb25zdCBrZXkgaW4gZGF0YSl7XG4gICAgY29uc3QgYmluZCA9IG1ldGhvZHMuZ2V0KGtleSk7XG5cbiAgICBpZihiaW5kKVxuICAgICAgYmluZC5jYWxsKHN1YmplY3QsIGRhdGFba2V5XSk7XG4gICAgZWxzZSBpZihrZXkgaW4gc3ViamVjdCAmJiBrZXkgIT09IFwiaXNcIil7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzdWJqZWN0LCBrZXkpITtcbiAgICAgIGNvbnN0IHNldCA9IGRlc2MgJiYgZGVzYy5zZXQgYXMgKHZhbHVlOiBhbnksIHNpbGVudD86IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgICAgIGlmKHNldClcbiAgICAgICAgc2V0LmNhbGwoc3ViamVjdCwgZGF0YVtrZXldLCBzaWxlbnQpO1xuICAgICAgZWxzZVxuICAgICAgICAoc3ViamVjdCBhcyBhbnkpW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9XG59XG5cbi8qKiBBcHBseSBpbnN0cnVjdGlvbnMgYW5kIGluaGVyaXRlZCBldmVudCBsaXN0ZW5lcnMuIEVuc3VyZSBjbGFzcyBtZXRhZGF0YSBpcyByZWFkeS4gKi9cbmZ1bmN0aW9uIHByZXBhcmUobW9kZWw6IE1vZGVsKXtcbiAgbGV0IFQgPSBtb2RlbC5jb25zdHJ1Y3RvciBhcyBNb2RlbC5UeXBlO1xuXG4gIGlmKFQgPT09IE1vZGVsKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjcmVhdGUgYmFzZSBNb2RlbC5cIik7XG5cbiAgY29uc3QgY2hhaW4gPSBbXSBhcyBNb2RlbC5UeXBlW107XG4gIGxldCBrZXlzID0gbmV3IE1hcDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiB2b2lkPigpO1xuXG4gIElELnNldChtb2RlbCwgYCR7VH0tJHt1aWQoKX1gKTtcblxuICB3aGlsZShULm5hbWUpe1xuICAgIGZvcihjb25zdCBjYiBvZiBOT1RJRlkuZ2V0KFQpIHx8IFtdKVxuICAgICAgYWRkTGlzdGVuZXIobW9kZWwsIGNiKTtcblxuICAgIGlmKFQgPT09IE1vZGVsKSBicmVhaztcbiAgICBlbHNlIGNoYWluLnVuc2hpZnQoVCk7XG5cbiAgICBUID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKFQpXG4gIH1cblxuICBmb3IoY29uc3QgdHlwZSBvZiBjaGFpbil7XG4gICAgaWYoTUVUSE9EUy5oYXModHlwZSkpe1xuICAgICAga2V5cyA9IE1FVEhPRFMuZ2V0KHR5cGUpITtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIE1FVEhPRFMuc2V0KHR5cGUsIGtleXMgPSBuZXcgTWFwKGtleXMpKTtcblxuICAgIGZvcihjb25zdCBba2V5LCB7IHZhbHVlIH1dIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnModHlwZS5wcm90b3R5cGUpXG4gICAgKSl7XG4gICAgICBpZighdmFsdWUgfHwga2V5ID09IFwiY29uc3RydWN0b3JcIilcbiAgICAgICAgY29udGludWU7XG4gICAgICBcbiAgICAgIGZ1bmN0aW9uIGJpbmQodGhpczogTW9kZWwsIG9yaWdpbmFsPzogRnVuY3Rpb24pe1xuICAgICAgICBjb25zdCB7IGlzIH0gPSB0aGlzO1xuXG4gICAgICAgIGlmKGlzLmhhc093blByb3BlcnR5KGtleSkgJiYgIW9yaWdpbmFsKVxuICAgICAgICAgIHJldHVybiB2YWx1ZSBhcyBGdW5jdGlvbjtcblxuICAgICAgICBjb25zdCBmbiA9IG9yaWdpbmFsIHx8IHZhbHVlO1xuICAgICAgICBjb25zdCBib3VuZCA9IGZuLmJpbmQoaXMpO1xuICAgICAgICBcbiAgICAgICAgTUVUSE9ELnNldChib3VuZCwgZm4pO1xuICAgICAgICBkZWZpbmUoaXMsIGtleSwgeyB2YWx1ZTogYm91bmQsIHdyaXRhYmxlOiB0cnVlIH0pO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgICAgfVxuXG4gICAgICBrZXlzLnNldChrZXksIGJpbmQpO1xuICAgICAgZGVmaW5lKHR5cGUucHJvdG90eXBlLCBrZXksIHsgZ2V0OiBiaW5kLCBzZXQ6IGJpbmQgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQXBwbHkgbW9kZWwgYXJndWVtbnRzLCBydW4gY2FsbGJhY2tzIGFuZCBvYnNlcnZlIHByb3BlcnRpZXMuXG4gKiBBY2N1bXVsYXRlIGFuZCBoYW5kbGUgY2xlYW51cCBldmVudHMuXG4gKiovXG5mdW5jdGlvbiBpbml0KG1vZGVsOiBNb2RlbCwgYXJnczogTW9kZWwuQXJncyl7XG4gIGNvbnN0IHN0YXRlID0ge30gYXMgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgdW5rbm93bj47XG5cbiAgU1RBVEUuc2V0KG1vZGVsLCBzdGF0ZSk7XG5cbiAgYXJncyA9IGFyZ3MuZmxhdCgpLmZpbHRlcihhcmcgPT4ge1xuICAgIGlmKHR5cGVvZiBhcmcgIT0gXCJzdHJpbmdcIilcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgSUQuc2V0KG1vZGVsLCBhcmcpO1xuICB9KTtcblxuICBhZGRMaXN0ZW5lcihtb2RlbCwgKCkgPT4ge1xuICAgIGlmKCFQQVJFTlQuaGFzKG1vZGVsKSlcbiAgICAgIFBBUkVOVC5zZXQobW9kZWwsIG51bGwpO1xuXG4gICAgZm9yKGNvbnN0IGtleSBpbiBtb2RlbCl7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtb2RlbCwga2V5KSE7XG5cbiAgICAgIGlmKFwidmFsdWVcIiBpbiBkZXNjKVxuICAgICAgICBtYW5hZ2UobW9kZWwsIGtleSwgZGVzYy52YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZm9yKGNvbnN0IGFyZyBvZiBhcmdzKXtcbiAgICAgIGNvbnN0IHVzZSA9IHR5cGVvZiBhcmcgPT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gYXJnLmNhbGwobW9kZWwsIG1vZGVsKVxuICAgICAgICA6IGFyZyBhcyBNb2RlbC5Bc3NpZ248TW9kZWw+O1xuXG4gICAgICBpZih1c2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICB1c2UuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBBc3luYyBlcnJvciBpbiBjb25zdHJ1Y3RvciBmb3IgJHttb2RlbH06YCk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICB9KTtcbiAgICAgIGVsc2UgaWYodHlwZW9mIHVzZSA9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgIGFkZExpc3RlbmVyKG1vZGVsLCB1c2UsIG51bGwpXG4gICAgICBlbHNlIGlmKHR5cGVvZiB1c2UgPT0gXCJvYmplY3RcIilcbiAgICAgICAgYXNzaWduKG1vZGVsLCB1c2UsIHRydWUpO1xuICAgIH1cblxuICAgIGFkZExpc3RlbmVyKG1vZGVsLCAoKSA9PiB7XG4gICAgICBmb3IoY29uc3QgW18sIHZhbHVlXSBvZiBtb2RlbClcbiAgICAgICAgaWYodmFsdWUgaW5zdGFuY2VvZiBNb2RlbCAmJiBQQVJFTlQuZ2V0KHZhbHVlKSA9PT0gbW9kZWwpXG4gICAgICAgICAgdmFsdWUuc2V0KG51bGwpO1xuICBcbiAgICAgIE9iamVjdC5mcmVlemUoc3RhdGUpO1xuICAgIH0sIG51bGwpO1xuICBcbiAgICByZXR1cm4gbnVsbDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG1hbmFnZSh0YXJnZXQ6IE1vZGVsLCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU6IGFueSwgc2lsZW50PzogYm9vbGVhbil7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHRhcmdldCkhO1xuICBcbiAgZnVuY3Rpb24gZ2V0KHRoaXM6IE1vZGVsKXtcbiAgICByZXR1cm4gd2F0Y2godGhpcywga2V5LCBzdGF0ZVtrZXldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCh2YWx1ZTogdW5rbm93biwgc2lsZW50PzogYm9vbGVhbil7XG4gICAgdXBkYXRlKHRhcmdldCwga2V5LCB2YWx1ZSwgc2lsZW50KTtcbiAgICBpZih2YWx1ZSBpbnN0YW5jZW9mIE1vZGVsICYmICFQQVJFTlQuaGFzKHZhbHVlKSl7XG4gICAgICBQQVJFTlQuc2V0KHZhbHVlLCB0YXJnZXQpO1xuICAgICAgZXZlbnQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGRlZmluZSh0YXJnZXQsIGtleSwgeyBzZXQsIGdldCB9KTtcbiAgc2V0KHZhbHVlLCBzaWxlbnQpO1xufVxuXG50eXBlIFByb3h5PFQgPSBhbnk+ID0gKGtleTogc3RyaW5nIHwgbnVtYmVyLCB2YWx1ZTogVCkgPT4gVDtcblxuY29uc3QgT0JTRVJWRVIgPSBuZXcgV2Vha01hcDxNb2RlbCwgUHJveHk+KCk7XG5cbmZ1bmN0aW9uIHdhdGNoKGZyb206IE1vZGVsLCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU/OiBhbnkpe1xuICBjb25zdCBhY2Nlc3MgPSBPQlNFUlZFUi5nZXQoZnJvbSk7XG4gIHJldHVybiBhY2Nlc3MgPyBhY2Nlc3Moa2V5LCB2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gZmV0Y2goc3ViamVjdDogTW9kZWwsIHByb3BlcnR5OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbil7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHN1YmplY3QpITtcbiAgXG4gIGlmKHByb3BlcnR5IGluIHN0YXRlIHx8IHJlcXVpcmVkID09PSBmYWxzZSl7XG4gICAgY29uc3QgdmFsdWUgPSBzdGF0ZVtwcm9wZXJ0eV07XG5cbiAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8ICFyZXF1aXJlZClcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGlmKE1FVEhPRFMuZ2V0KHN1YmplY3QuY29uc3RydWN0b3IgYXMgTW9kZWwuSW5pdCkhLmhhcyhwcm9wZXJ0eSkpXG4gICAgcmV0dXJuIE1FVEhPRC5nZXQoKHN1YmplY3QgYXMgYW55KVtwcm9wZXJ0eV0pO1xuXG4gIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGAke3N1YmplY3R9LiR7cHJvcGVydHl9IGlzIG5vdCB5ZXQgYXZhaWxhYmxlLmApO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgYWRkTGlzdGVuZXIoc3ViamVjdCwga2V5ID0+IHtcbiAgICAgIGlmKGtleSA9PT0gcHJvcGVydHkpe1xuICAgICAgICByZXNvbHZlKHN0YXRlW2tleV0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYoa2V5ID09PSBudWxsKVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAke3N1YmplY3R9IGlzIGRlc3Ryb3llZC5gKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRocm93IE9iamVjdC5hc3NpZ24ocHJvbWlzZSwge1xuICAgIHRvU3RyaW5nOiAoKSA9PiBTdHJpbmcoZXJyb3IpLFxuICAgIG5hbWU6IFwiU3VzcGVuc2VcIixcbiAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgIHN0YWNrOiBlcnJvci5zdGFja1xuICB9KTtcbn1cblxuLyoqIEN1cnJlbnRseSBhY2N1bXVsYXRpbmcgZXhwb3J0LiBTdG9yZXMgcmVhbCB2YWx1ZXMgb2YgcGxhY2Vob2xkZXIgcHJvcGVydGllcyBzdWNoIGFzIHJlZigpIG9yIGNoaWxkIG1vZGVscy4gKi9cbmxldCBFWFBPUlQ6IE1hcDxhbnksIGFueT4gfCB1bmRlZmluZWQ7XG5cbmZ1bmN0aW9uIHNuYXBzaG90PFQgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFQpOiBNb2RlbC5TdGF0ZTxUPiB7XG4gIGNvbnN0IHZhbHVlcyA9IHt9IGFzIGFueTtcbiAgbGV0IGlzTm90UmVjdXJzaXZlO1xuXG4gIGlmKCFFWFBPUlQpe1xuICAgIGlzTm90UmVjdXJzaXZlID0gdHJ1ZTtcbiAgICBFWFBPUlQgPSBuZXcgTWFwKFtbbW9kZWwsIHZhbHVlc11dKTtcbiAgfVxuXG4gIGZvcihsZXQgW2tleSwgdmFsdWVdIG9mIG1vZGVsKXtcbiAgICBpZihFWFBPUlQuaGFzKHZhbHVlKSlcbiAgICAgIHZhbHVlID0gRVhQT1JULmdldCh2YWx1ZSk7XG4gICAgZWxzZSBpZih2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiBcImdldFwiIGluIHZhbHVlICYmIHR5cGVvZiB2YWx1ZS5nZXQgPT09IFwiZnVuY3Rpb25cIilcbiAgICAgIEVYUE9SVC5zZXQodmFsdWUsIHZhbHVlID0gdmFsdWUuZ2V0KCkpO1xuXG4gICAgdmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIGlmKGlzTm90UmVjdXJzaXZlKVxuICAgIEVYUE9SVCA9IHVuZGVmaW5lZDtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh2YWx1ZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGU8VD4oXG4gIHN1YmplY3Q6IE1vZGVsLFxuICBrZXk6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCxcbiAgdmFsdWU6IFQsXG4gIGFyZz86IGJvb2xlYW4gfCBNb2RlbC5TZXR0ZXI8VD4pe1xuXG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHN1YmplY3QpITtcblxuICBpZihPYmplY3QuaXNGcm96ZW4oc3RhdGUpKVxuICAgIHRocm93IG5ldyBFcnJvcihgVHJpZWQgdG8gdXBkYXRlICR7c3ViamVjdH0uJHtTdHJpbmcoa2V5KX0gYnV0IG1vZGVsIGlzIGRlc3Ryb3llZC5gKTtcblxuICBjb25zdCBwcmV2aW91cyA9IHN0YXRlW2tleV0gYXMgVDtcblxuICBpZih0eXBlb2YgYXJnID09IFwiZnVuY3Rpb25cIil7XG4gICAgY29uc3Qgb3V0ID0gYXJnLmNhbGwoc3ViamVjdCwgdmFsdWUsIHByZXZpb3VzKTtcblxuICAgIGlmKG91dCA9PT0gZmFsc2UpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBpZih0eXBlb2Ygb3V0ID09IFwiZnVuY3Rpb25cIilcbiAgICAgIHZhbHVlID0gb3V0KCk7XG4gIH1cblxuICBpZih2YWx1ZSA9PT0gcHJldmlvdXMgJiYga2V5IGluIHN0YXRlKVxuICAgIHJldHVybjtcblxuICBzdGF0ZVtrZXldID0gdmFsdWU7XG5cbiAgaWYoYXJnICE9PSB0cnVlKVxuICAgIGV2ZW50KHN1YmplY3QsIGtleSk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBSYW5kb20gYWxwaGFudW1iZXJpYyBvZiBsZW5ndGggNjsgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgbGV0dGVyLiAqL1xuZnVuY3Rpb24gdWlkKCl7XG4gIHJldHVybiAoMC4yNzggKyBNYXRoLnJhbmRvbSgpICogMC43MjIpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgOCkudG9VcHBlckNhc2UoKTtcbn1cblxuZXhwb3J0IHtcbiAgZXZlbnQsXG4gIGZldGNoLFxuICBNRVRIT0QsXG4gIE1vZGVsLFxuICBQQVJFTlQsXG4gIFNUQVRFLFxuICB1aWQsXG4gIHVwZGF0ZSxcbiAgd2F0Y2hcbn0iXSwKICAibWFwcGluZ3MiOiAiQUFBQSxTQUFTLGFBQWEsY0FBYyxPQUFPLFlBQXNCLG9CQUFvQjtBQUVyRixNQUFNLFNBQVMsT0FBTztBQUd0QixNQUFNLEtBQUssb0JBQUksUUFBdUI7QUFHdEMsTUFBTSxRQUFRLG9CQUFJLFFBQTBEO0FBRzVFLE1BQU0sU0FBUyxvQkFBSSxRQUFtQztBQUd0RCxNQUFNLFNBQVMsb0JBQUksUUFBNkI7QUFHaEQsTUFBTSxVQUFVLG9CQUFJLFFBQXVEO0FBRzNFLE1BQU0sU0FBUyxvQkFBSSxRQUFrQjtBQW1IckMsTUFBZSxNQUE0QjtBQUFBLEVBQ3pDLGVBQWUsTUFBaUI7QUFDOUIsWUFBUSxJQUFJO0FBQ1osV0FBTyxNQUFNLE1BQU0s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QU8sR0FBRyxDQUFDLDBCQUEwQjtBQUVyRixRQUFNLFdBQVcsTUFBTSxHQUFHO0FBRTFCLE1BQUcsT0FBTyxPQUFPLFlBQVc7QUFDMUIsVUFBTSxNQUFNLElBQUksS0FBSyxTQUFTLE9BQU8sUUFBUTtBQUU3QyxRQUFHLFFBQVE7QUFDVCxhQUFPO0FBRVQsUUFBRyxPQUFPLE9BQU87QUFDZixjQUFRLElBQUk7QUFBQSxFQUNoQjtBQUVBLE1BQUcsVUFBVSxZQUFZLE9BQU87QUFDOUI7QUFFRixRQUFNLEdBQUcsSUFBSTtBQUViLE1BQUcsUUFBUTtBQUNULFVBQU0sU0FBUyxHQUFHO0FBRXBCLFNBQU87QUFDVDtBQUdBLFNBQVMsTUFBSztBQUNaLFVBQVEsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLFNBQVMsRUFBRSxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUUsWUFBWTtBQUNsRjsiLAogICJuYW1lcyI6IFsid2F0Y2giLCAidXBkYXRlIiwgInJlcyIsICJiaW5kIiwgInZhbHVlIiwgInNpbGVudCJdCn0K