@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.
@@ -0,0 +1,324 @@
1
+ import {
2
+ addListener,
3
+ watch,
4
+ event,
5
+ Observable,
6
+ PENDING_KEYS
7
+ } from "./control";
8
+ const define = Object.defineProperty;
9
+ const ID = /* @__PURE__ */ new WeakMap();
10
+ const STATE = /* @__PURE__ */ new WeakMap();
11
+ const NOTIFY = /* @__PURE__ */ new WeakMap();
12
+ const PARENT = /* @__PURE__ */ new WeakMap();
13
+ const METHODS = /* @__PURE__ */ new WeakMap();
14
+ const METHOD = /* @__PURE__ */ new WeakMap();
15
+ let EXPORT;
16
+ class State {
17
+ constructor(...args) {
18
+ prepare(this);
19
+ define(this, "is", { value: this });
20
+ init(this, args);
21
+ }
22
+ [Observable](callback, required) {
23
+ const watch2 = /* @__PURE__ */ new Set();
24
+ const proxy = Object.create(this);
25
+ addListener(this, (key) => {
26
+ if (watch2.has(key)) callback();
27
+ });
28
+ OBSERVER.set(proxy, (key, value) => {
29
+ if (value === void 0 && required)
30
+ throw new Error(`${this}.${key} is required in this context.`);
31
+ watch2.add(key);
32
+ if (value instanceof Object && Observable in value)
33
+ return value[Observable](callback, required) || value;
34
+ return value;
35
+ });
36
+ return proxy;
37
+ }
38
+ get(arg1, arg2) {
39
+ const self = this.is;
40
+ if (arg1 === void 0) return values(self);
41
+ if (typeof arg1 == "function") return effect(self, arg1);
42
+ if (typeof arg2 == "function") return addListener(self, arg2, arg1);
43
+ if (arg1 === null) return Object.isFrozen(STATE.get(self));
44
+ return access(self, arg1, arg2);
45
+ }
46
+ set(arg1, arg2, arg3) {
47
+ const self = this.is;
48
+ if (typeof arg1 == "function")
49
+ return addListener(self, (key) => {
50
+ if (arg2 === key || arg2 === void 0 && typeof key == "string")
51
+ return arg1.call(self, key, self);
52
+ });
53
+ if (arg1 && typeof arg1 == "object") {
54
+ assign(self, arg1, arg2 === true);
55
+ } else if (!arg2) {
56
+ event(self, arg1);
57
+ } else if (arg3) {
58
+ manage(self, arg1, arg2);
59
+ } else {
60
+ update(self, arg1, arg2);
61
+ }
62
+ const pending = PENDING_KEYS.get(this);
63
+ if (pending)
64
+ return {
65
+ then: (res) => new Promise((res2) => {
66
+ const remove = addListener(this, (key) => {
67
+ if (key !== true) {
68
+ remove();
69
+ return res2.bind(null, Array.from(pending));
70
+ }
71
+ });
72
+ }).then(res)
73
+ };
74
+ }
75
+ /**
76
+ * Iterate over managed properties in this instance of State.
77
+ * Yeilds the key and current value for each property.
78
+ */
79
+ [Symbol.iterator]() {
80
+ return Object.entries(STATE.get(this.is))[Symbol.iterator]();
81
+ }
82
+ /**
83
+ * Create and activate a new instance of this state.
84
+ *
85
+ * **Important** - Unlike `new this(...)` - this method also activates state.
86
+ *
87
+ * @param args - arguments sent to constructor
88
+ */
89
+ static new(...args) {
90
+ const instance = new this(...args, (x) => {
91
+ const cb = x.new && x.new();
92
+ if (cb) x.set(cb, null);
93
+ });
94
+ event(instance);
95
+ return instance;
96
+ }
97
+ /**
98
+ * Static equivalent of `x instanceof this`.
99
+ * Determines if provided class is a subtype of this one.
100
+ * If so, language server will make available all static
101
+ * methods and properties of this class.
102
+ */
103
+ static is(maybe) {
104
+ return maybe === this || typeof maybe == "function" && maybe.prototype instanceof this;
105
+ }
106
+ /**
107
+ * Register a callback to run when any instance of this State is updated.
108
+ */
109
+ static on(listener) {
110
+ let notify = NOTIFY.get(this);
111
+ if (!notify) NOTIFY.set(this, notify = /* @__PURE__ */ new Set());
112
+ notify.add(listener);
113
+ return () => notify.delete(listener);
114
+ }
115
+ }
116
+ define(State.prototype, "toString", {
117
+ value() {
118
+ return ID.get(this.is);
119
+ }
120
+ });
121
+ define(State, "toString", {
122
+ value() {
123
+ return this.name;
124
+ }
125
+ });
126
+ function assign(subject, data, silent) {
127
+ const methods = METHODS.get(subject.constructor);
128
+ for (const key in data) {
129
+ const bind = methods.get(key);
130
+ if (bind) 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
+ }
142
+ function prepare(state) {
143
+ let T = state.constructor;
144
+ if (T === State) throw new Error("Cannot create base State.");
145
+ const chain = [];
146
+ let keys = /* @__PURE__ */ new Map();
147
+ ID.set(state, `${T}-${uid()}`);
148
+ while (T.name) {
149
+ for (const cb of NOTIFY.get(T) || []) {
150
+ addListener(state, cb);
151
+ }
152
+ if (T === State) break;
153
+ else chain.unshift(T);
154
+ T = Object.getPrototypeOf(T);
155
+ }
156
+ for (const type of chain) {
157
+ if (METHODS.has(type)) {
158
+ keys = METHODS.get(type);
159
+ continue;
160
+ }
161
+ METHODS.set(type, keys = new Map(keys));
162
+ for (const [key, { value }] of Object.entries(
163
+ Object.getOwnPropertyDescriptors(type.prototype)
164
+ )) {
165
+ let bind2 = function(original) {
166
+ const { is } = this;
167
+ if (is.hasOwnProperty(key) && !original) 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") continue;
176
+ keys.set(key, bind2);
177
+ define(type.prototype, key, { get: bind2, set: bind2 });
178
+ }
179
+ }
180
+ }
181
+ function init(self, args) {
182
+ const state = {};
183
+ STATE.set(self, state);
184
+ args = args.flat().filter((arg) => {
185
+ if (typeof arg == "string") ID.set(self, arg);
186
+ else return true;
187
+ });
188
+ addListener(self, () => {
189
+ if (!PARENT.has(self)) PARENT.set(self, null);
190
+ for (const key in self) {
191
+ const desc = Object.getOwnPropertyDescriptor(self, key);
192
+ if ("value" in desc) manage(self, key, desc.value, true);
193
+ }
194
+ for (const arg of args) {
195
+ const use = typeof arg == "function" ? arg.call(self, self) : arg;
196
+ if (use instanceof Promise)
197
+ use.catch((err) => {
198
+ console.error(`Async error in constructor for ${self}:`);
199
+ console.error(err);
200
+ });
201
+ else if (Array.isArray(use)) args.push(...use);
202
+ else if (typeof use == "function") addListener(self, use, null);
203
+ else if (typeof use == "object") assign(self, use, true);
204
+ }
205
+ addListener(
206
+ self,
207
+ () => {
208
+ for (const [_, value] of self)
209
+ if (value instanceof State && PARENT.get(value) === self)
210
+ value.set(null);
211
+ Object.freeze(state);
212
+ },
213
+ null
214
+ );
215
+ return null;
216
+ });
217
+ }
218
+ function effect(target, fn) {
219
+ const effect2 = METHOD.get(fn) || fn;
220
+ let pending = /* @__PURE__ */ new Set();
221
+ return watch(target, (proxy) => {
222
+ const cb = effect2.call(proxy, proxy, pending);
223
+ if (cb === null) return cb;
224
+ return (update2) => {
225
+ pending = PENDING_KEYS.get(target);
226
+ if (typeof cb == "function") cb(update2);
227
+ };
228
+ });
229
+ }
230
+ function values(target) {
231
+ const values2 = {};
232
+ let isNotRecursive;
233
+ if (!EXPORT) {
234
+ isNotRecursive = true;
235
+ EXPORT = /* @__PURE__ */ new Map([[target, values2]]);
236
+ }
237
+ for (let [key, value] of target) {
238
+ if (EXPORT.has(value)) value = EXPORT.get(value);
239
+ else if (value && typeof value == "object" && "get" in value && typeof value.get === "function")
240
+ EXPORT.set(value, value = value.get());
241
+ values2[key] = value;
242
+ }
243
+ if (isNotRecursive) EXPORT = void 0;
244
+ return Object.freeze(values2);
245
+ }
246
+ function manage(target, key, value, silent) {
247
+ const state = STATE.get(target);
248
+ function get() {
249
+ return follow(this, key, state[key]);
250
+ }
251
+ function set(value2, silent2) {
252
+ update(target, key, value2, silent2);
253
+ if (value2 instanceof State && !PARENT.has(value2)) {
254
+ PARENT.set(value2, target);
255
+ event(value2);
256
+ }
257
+ }
258
+ define(target, key, { set, get });
259
+ set(value, silent);
260
+ }
261
+ const OBSERVER = /* @__PURE__ */ new WeakMap();
262
+ function follow(from, key, value) {
263
+ const observe = OBSERVER.get(from);
264
+ return observe ? observe(key, value) : value;
265
+ }
266
+ function access(subject, property, required) {
267
+ const state = STATE.get(subject);
268
+ if (property in state || required === false) {
269
+ const value = state[property];
270
+ if (value !== void 0 || !required) return value;
271
+ }
272
+ if (METHODS.get(subject.constructor).has(property))
273
+ return METHOD.get(subject[property]);
274
+ const error = new Error(`${subject}.${property} is not yet available.`);
275
+ const promise = new Promise((resolve, reject) => {
276
+ addListener(subject, (key) => {
277
+ if (key === property) {
278
+ resolve(state[key]);
279
+ return null;
280
+ }
281
+ if (key === null) {
282
+ reject(new Error(`${subject} is destroyed.`));
283
+ }
284
+ });
285
+ });
286
+ throw Object.assign(promise, {
287
+ toString: () => String(error),
288
+ name: "Suspense",
289
+ message: error.message,
290
+ stack: error.stack
291
+ });
292
+ }
293
+ function update(subject, key, value, arg) {
294
+ const state = STATE.get(subject);
295
+ if (Object.isFrozen(state))
296
+ throw new Error(
297
+ `Tried to update ${subject}.${String(key)} but state is destroyed.`
298
+ );
299
+ const previous = state[key];
300
+ if (typeof arg == "function") {
301
+ const out = arg.call(subject, value, previous);
302
+ if (out === false) return false;
303
+ if (typeof out == "function") value = out();
304
+ }
305
+ if (value === previous && key in state) return;
306
+ state[key] = value;
307
+ if (arg !== true) event(subject, key);
308
+ return true;
309
+ }
310
+ function uid() {
311
+ return (0.278 + Math.random() * 0.722).toString(36).substring(2, 8).toUpperCase();
312
+ }
313
+ export {
314
+ METHOD,
315
+ PARENT,
316
+ STATE,
317
+ State,
318
+ access,
319
+ event,
320
+ follow,
321
+ uid,
322
+ update
323
+ };
324
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3N0YXRlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1xuICBhZGRMaXN0ZW5lcixcbiAgd2F0Y2gsXG4gIGV2ZW50LFxuICBPYnNlcnZhYmxlLFxuICBOb3RpZnksXG4gIFBFTkRJTkdfS0VZU1xufSBmcm9tICcuL2NvbnRyb2wnO1xuXG5jb25zdCBkZWZpbmUgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbi8qKiBSZWdpc3RlciBmb3IgYWxsIGFjdGl2ZSBzdGF0ZXMgdmlhIHN0cmluZyBpZGVudGlmaWVycyAodXN1YWxseSB1bmlxdWUpLiAqL1xuY29uc3QgSUQgPSBuZXcgV2Vha01hcDxTdGF0ZSwgc3RyaW5nPigpO1xuXG4vKiogSW50ZXJuYWwgc3RhdGUgYXNzaWduZWQgdG8gc3RhdGVzLiAqL1xuY29uc3QgU1RBVEUgPSBuZXcgV2Vha01hcDxTdGF0ZSwgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgdW5rbm93bj4+KCk7XG5cbi8qKiBFeHRlcm5hbCBsaXN0ZW5lcnMgZm9yIGFueSBnaXZlbiBTdGF0ZS4gKi9cbmNvbnN0IE5PVElGWSA9IG5ldyBXZWFrTWFwPFN0YXRlLkV4dGVuZHMsIFNldDxOb3RpZnk+PigpO1xuXG4vKiogUGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHMuICovXG5jb25zdCBQQVJFTlQgPSBuZXcgV2Vha01hcDxTdGF0ZSwgU3RhdGUgfCBudWxsPigpO1xuXG4vKiogTGlzdCBvZiBtZXRob2RzIGRlZmluZWQgYnkgYSBnaXZlbiB0eXBlLiAqL1xuY29uc3QgTUVUSE9EUyA9IG5ldyBXZWFrTWFwPEZ1bmN0aW9uLCBNYXA8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gdm9pZD4+KCk7XG5cbi8qKiBSZWZlcmVuY2UgYm91bmQgaW5zdGFuY2UgbWV0aG9kcyB0byByZWFsIG9uZXMuICovXG5jb25zdCBNRVRIT0QgPSBuZXcgV2Vha01hcDxhbnksIGFueT4oKTtcblxuLyoqIEN1cnJlbnRseSBhY2N1bXVsYXRpbmcgZXhwb3J0LiBTdG9yZXMgcmVhbCB2YWx1ZXMgb2YgcGxhY2Vob2xkZXIgcHJvcGVydGllcyBzdWNoIGFzIHJlZigpIG9yIGNoaWxkIHN0YXRlcy4gKi9cbmxldCBFWFBPUlQ6IE1hcDxhbnksIGFueT4gfCB1bmRlZmluZWQ7XG5cbmRlY2xhcmUgbmFtZXNwYWNlIFN0YXRlIHtcbiAgLyoqXG4gICAqIFN0YXRlIHdoaWNoIGlzIHZhbGlkIHRvIGNyZWF0ZS5cbiAgICpcbiAgICogVGhpcyBpbnRlcmZhY2UgbWF5IGJlIGF1Z21lbnRlZCB0byBhZGQgZGRpdGlvbmFsXG4gICAqIGNvbnN0cmFpbnRzIG9uIHN0YXRlcywgc3VjaCBhcyBzcGVjaWFsIGhvb2tzIG9yIHByb3BlcnRpZXMsXG4gICAqIHRvIGludGVyYWN0IHdpdGggZW52aXJvbm1lbnQgb3IgaGVscGVyIGZyYW1ld29ya3MuXG4gICAqKi9cbiAgaW50ZXJmYWNlIFZhbGlkIGV4dGVuZHMgU3RhdGUge1xuICAgICduZXcnPygpOiB2b2lkIHwgKCgpID0+IHZvaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgU3RhdGUgY2xhc3Mgd2hpY2ggaXMgdmFsaWQgYW5kIG1heSBiZSBpbnN0YW50aWF0ZWQuXG4gICAqL1xuICB0eXBlIE5ldzxUIGV4dGVuZHMgU3RhdGU+ID0gU3RhdGUuQ2xhc3M8VCAmIFZhbGlkPjtcblxuICAvKiogQW55IHR5cGUgb2YgU3RhdGUsIHVzaW5nIG93biBjbGFzcyBjb25zdHJ1Y3RvciBhcyBpdHMgaWRlbnRpZmllci4gKi9cbiAgdHlwZSBFeHRlbmRzPFQgZXh0ZW5kcyBTdGF0ZSA9IFN0YXRlPiA9IChhYnN0cmFjdCBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBUKSAmXG4gICAgdHlwZW9mIFN0YXRlO1xuXG4gIC8qKiBBIFN0YXRlIGNvbnN0cnVjdG9yIHdoaWNoIGlzIG5vdCBhYnN0cmFjdC4gKi9cbiAgdHlwZSBDbGFzczxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAobmV3ICguLi5hcmdzOiBTdGF0ZS5BcmdzPFQ+KSA9PiBUKSAmXG4gICAgT21pdDx0eXBlb2YgU3RhdGUsIG5ldmVyPjtcblxuICAvKiogU3RhdGUgY29uc3RydWN0b3IgYXJndW1lbnRzICovXG4gIHR5cGUgQXJnczxUIGV4dGVuZHMgU3RhdGUgPSBhbnk+ID0gKFxuICAgIHwgQXJnczxUPlxuICAgIHwgSW5pdDxUPlxuICAgIHwgQXNzaWduPFQ+XG4gICAgfCBzdHJpbmdcbiAgICB8IHZvaWRcbiAgKVtdO1xuXG4gIC8qKlxuICAgKiBTdGF0ZSBjb25zdHJ1Y3RvciBjYWxsYmFjayAtIGlzIGNhbGxlZCB3aGVuIFN0YXRlIGZpbmlzaGVzIGludGlhbGl6aW5nLlxuICAgKiBSZXR1cm5lZCBmdW5jdGlvbiB3aWxsIHJ1biB3aGVuIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgSW5pdDxUIGV4dGVuZHMgU3RhdGUgPSBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICB0aGlzQXJnOiBUXG4gICkgPT4gUHJvbWlzZTx2b2lkPiB8ICgoKSA9PiB2b2lkKSB8IEFyZ3M8VD4gfCBBc3NpZ248VD4gfCB2b2lkO1xuXG4gIC8qKiBPYmplY3Qgb3ZlcmxheSB0byBvdmVycmlkZSB2YWx1ZXMgYW5kIG1ldGhvZHMgb24gYSBzdGF0ZS4gKi9cbiAgdHlwZSBBc3NpZ248VD4gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiAmIHtcbiAgICBbSyBpbiBGaWVsZDxUPl0/OiBUW0tdIGV4dGVuZHMgKC4uLmFyZ3M6IGluZmVyIEEpID0+IGluZmVyIFJcbiAgICAgID8gKHRoaXM6IFQsIC4uLmFyZ3M6IEEpID0+IFJcbiAgICAgIDogVFtLXTtcbiAgfTtcblxuICAvKiogU3Vic2V0IG9mIGBrZXlvZiBUYCB3aGljaCBhcmUgbm90IG1ldGhvZHMgb3IgZGVmaW5lZCBieSBiYXNlIFN0YXRlIFUuICoqL1xuICB0eXBlIEZpZWxkPFQ+ID0gRXhjbHVkZTxrZXlvZiBULCBrZXlvZiBTdGF0ZT47XG5cbiAgLyoqIEFueSB2YWxpZCBrZXkgZm9yIHN0YXRlLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIEZpZWxkPFQ+LiAqL1xuICB0eXBlIEV2ZW50PFQ+ID0gRmllbGQ8VD4gfCBudW1iZXIgfCBzeW1ib2wgfCAoc3RyaW5nICYge30pO1xuXG4gIC8qKiBFeHBvcnQvSW1wb3J0IGNvbXBhdGlibGUgdmFsdWUgZm9yIGEgZ2l2ZW4gcHJvcGVydHkgaW4gYSBTdGF0ZS4gKi9cbiAgdHlwZSBFeHBvcnQ8Uj4gPSBSIGV4dGVuZHMgeyBnZXQoKTogaW5mZXIgVCB9ID8gVCA6IFI7XG5cbiAgLyoqIFZhbHVlIGZvciBhIHByb3BlcnR5IG1hbmFnZWQgYnkgYSBzdGF0ZS4gKi9cbiAgdHlwZSBWYWx1ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBFdmVudDxUPj4gPSBLIGV4dGVuZHMga2V5b2YgVFxuICAgID8gRXhwb3J0PFRbS10+XG4gICAgOiB1bmtub3duO1xuXG4gIHR5cGUgU2V0dGVyPFQ+ID0gKHZhbHVlOiBULCBwcmV2aW91czogVCkgPT4gYm9vbGVhbiB8IHZvaWQgfCAoKCkgPT4gVCk7XG5cbiAgdHlwZSBPbkV2ZW50PFQgZXh0ZW5kcyBTdGF0ZT4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IHVua25vd24sXG4gICAgc291cmNlOiBUXG4gICkgPT4gdm9pZCB8ICgoKSA9PiB2b2lkKSB8IG51bGw7XG5cbiAgdHlwZSBPblVwZGF0ZTxUIGV4dGVuZHMgU3RhdGUsIEsgZXh0ZW5kcyBFdmVudDxUPj4gPSAoXG4gICAgdGhpczogVCxcbiAgICBrZXk6IEssXG4gICAgdGhpc0FyZzogS1xuICApID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFZhbHVlcyBmcm9tIGN1cnJlbnQgc3RhdGUgb2YgZ2l2ZW4gc3RhdGUuXG4gICAqIERpZmZlcnMgZnJvbSBgVmFsdWVzYCBhcyB2YWx1ZXMgaGVyZSB3aWxsIGRyaWxsXG4gICAqIGludG8gXCJyZWFsXCIgdmFsdWVzIGhlbGQgYnkgZXhvdGljcyBsaWtlIHJlZi5PYmplY3QuXG4gICAqL1xuICB0eXBlIFZhbHVlczxUPiA9IHsgW1AgaW4gRmllbGQ8VD5dOiBFeHBvcnQ8VFtQXT4gfTtcblxuICAvKiogT2JqZWN0IGNvbXBlcmFibGUgdG8gZGF0YSBmb3VuZCBpbiBULiAqL1xuICB0eXBlIFBhcnRpYWw8VD4gPSB7IFtQIGluIEZpZWxkPFQ+XT86IEV4cG9ydDxUW1BdPiB9O1xuXG4gIC8qKiBFeG90aWMgdmFsdWUsIHdoZXJlIGFjdHVhbCB2YWx1ZSBpcyBjb250YWluZWQgd2l0aGluLiAqL1xuICB0eXBlIFJlZjxUID0gYW55PiA9IHtcbiAgICAobmV4dDogVCk6IHZvaWQ7XG4gICAgY3VycmVudDogVCB8IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgc3Vic2NyaWJlZCB0byBwYXJlbnQgYW5kIHVwZGF0ZXMgd2hlbiBhY2Nlc3NlZCBwcm9wZXJ0aWVzIGNoYW5nZS5cbiAgICpcbiAgICogQHBhcmFtIGN1cnJlbnQgLSBDdXJyZW50IHN0YXRlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgYSBwcm94eSB3aGljaCBkZXRlY3RzIHByb3BlcnRpZXMgd2hpY2hcbiAgICogd2hlcmUgYWNjZXNzZWQsIGFuZCB0aHVzIGRlcGVuZGVkIHVwb24gdG8gc3RheSBjdXJyZW50LlxuICAgKlxuICAgKiBAcGFyYW0gdXBkYXRlIC0gU2V0IG9mIHByb3BlcnRpZXMgd2hpY2ggaGF2ZSBjaGFuZ2VkLCBhbmQgZXZlbnRzIGZpcmVkLCBzaW5jZSBsYXN0IHVwZGF0ZS5cbiAgICpcbiAgICogQHJldHVybnMgQSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoaXMgZWZmZWN0IGlzIHN0YWxlLlxuICAgKi9cbiAgdHlwZSBFZmZlY3Q8VD4gPSAoXG4gICAgdGhpczogVCxcbiAgICBjdXJyZW50OiBULFxuICAgIHVwZGF0ZTogU2V0PEV2ZW50PFQ+PlxuICApID0+IEVmZmVjdENhbGxiYWNrIHwgUHJvbWlzZTx2b2lkPiB8IG51bGwgfCB2b2lkO1xuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGVmZmVjdC4gV2lsbCBiZSBjYWxsZWQgd2hlbiBlZmZlY3QgaXMgc3RhbGUuXG4gICAqXG4gICAqIEBwYXJhbSB1cGRhdGUgLSBgdHJ1ZWAgaWYgdXBkYXRlIGlzIHBlbmRpbmcsIGBmYWxzZWAgZWZmZWN0IGhhcyBiZWVuIGNhbmNlbGxlZCwgYG51bGxgIGlmIHN0YXRlIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIHR5cGUgRWZmZWN0Q2FsbGJhY2sgPSAodXBkYXRlOiBib29sZWFuIHwgbnVsbCkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIFN0YXRlIHtcbiAgLyoqXG4gICAqIExvb3BiYWNrIHRvIGluc3RhbmNlIG9mIHRoaXMgc3RhdGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gaW4gYSBzdWJzY3JpYmVkIGNvbnRleHQsXG4gICAqIHRvIGtlZXAgd3JpdGUgYWNjZXNzIHRvIGB0aGlzYCBhZnRlciBhIGRlc3RydWN0dXJlLiBZb3UgY2FuIHVzZSBpdCB0byByZWFkIHZhcmlhYmxlcyBzaWxlbnRseSBhcyB3ZWxsLlxuICAgKiovXG4gIGlzOiB0aGlzO1xufVxuXG5hYnN0cmFjdCBjbGFzcyBTdGF0ZSBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBjb25zdHJ1Y3RvciguLi5hcmdzOiBTdGF0ZS5BcmdzKSB7XG4gICAgcHJlcGFyZSh0aGlzKTtcbiAgICBkZWZpbmUodGhpcywgJ2lzJywgeyB2YWx1ZTogdGhpcyB9KTtcbiAgICBpbml0KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgW09ic2VydmFibGVdKGNhbGxiYWNrOiBPYnNlcnZhYmxlLkNhbGxiYWNrLCByZXF1aXJlZD86IGJvb2xlYW4pIHtcbiAgICBjb25zdCB3YXRjaCA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgICBjb25zdCBwcm94eSA9IE9iamVjdC5jcmVhdGUodGhpcyk7XG5cbiAgICBhZGRMaXN0ZW5lcih0aGlzLCAoa2V5KSA9PiB7XG4gICAgICBpZiAod2F0Y2guaGFzKGtleSkpIGNhbGxiYWNrKCk7XG4gICAgfSk7XG5cbiAgICBPQlNFUlZFUi5zZXQocHJveHksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiByZXF1aXJlZClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXN9LiR7a2V5fSBpcyByZXF1aXJlZCBpbiB0aGlzIGNvbnRleHQuYCk7XG5cbiAgICAgIHdhdGNoLmFkZChrZXkpO1xuXG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QgJiYgT2JzZXJ2YWJsZSBpbiB2YWx1ZSlcbiAgICAgICAgcmV0dXJuIHZhbHVlW09ic2VydmFibGVdKGNhbGxiYWNrLCByZXF1aXJlZCkgfHwgdmFsdWU7XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwcm94eSBhcyB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1bGwgY3VycmVudCB2YWx1ZXMgZnJvbSBzdGF0ZS4gRmxhdHRlbnMgYWxsIHN0YXRlcyBhbmQgZXhvdGljIHZhbHVlcyByZWN1cnNpdmVseS5cbiAgICpcbiAgICogQHJldHVybnMgT2JqZWN0IHdpdGggYWxsIHZhbHVlcyBmcm9tIHRoaXMgc3RhdGUuXG4gICAqKi9cbiAgZ2V0KCk6IFN0YXRlLlZhbHVlczx0aGlzPjtcblxuICAvKipcbiAgICogUnVuIGEgZnVuY3Rpb24gd2hpY2ggd2lsbCBydW4gYXV0b21hdGljYWxseSB3aGVuIGFjY2Vzc2VkIHZhbHVlcyBjaGFuZ2UuXG4gICAqXG4gICAqIEBwYXJhbSBlZmZlY3QgRnVuY3Rpb24gdG8gcnVuLCBhbmQgYWdhaW4gd2hlbmV2ZXIgYWNjZXNzZWQgdmFsdWVzIGNoYW5nZS5cbiAgICogICAgICAgICAgICAgICBJZiBlZmZlY3QgcmV0dXJucyBhIGZ1bmN0aW9uLCBpdCB3aWxsIGJlIGNhbGxlZCB3aGVuIGEgY2hhbmdlIG9jY3VycyAoc3luY3Jvbm91c2x5KSxcbiAgICogICAgICAgICAgICAgICBlZmZlY3QgaXMgY2FuY2VsbGVkLCBvciBwYXJlbnQgc3RhdGUgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoZWZmZWN0OiBTdGF0ZS5FZmZlY3Q8dGhpcz4pOiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBHZXQgdmFsdWUgb2YgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFByb3BlcnR5IHRvIGdldCB2YWx1ZSBvZi5cbiAgICogQHBhcmFtIHJlcXVpcmVkIC0gSWYgdHJ1ZSwgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcmV0dXJucyBWYWx1ZSBvZiBwcm9wZXJ0eS5cbiAgICovXG4gIGdldDxUIGV4dGVuZHMgU3RhdGUuRXZlbnQ8dGhpcz4+KFxuICAgIGtleTogVCxcbiAgICByZXF1aXJlZD86IGJvb2xlYW5cbiAgKTogU3RhdGUuVmFsdWU8dGhpcywgVD47XG5cbiAgLyoqXG4gICAqIFJ1biBhIGZ1bmN0aW9uIHdoZW4gYSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUHJvcGVydHkgdG8gd2F0Y2ggZm9yIHVwZGF0ZXMuXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQ8VCBleHRlbmRzIFN0YXRlLkV2ZW50PHRoaXM+PihcbiAgICBrZXk6IFQsXG4gICAgY2FsbGJhY2s6IFN0YXRlLk9uVXBkYXRlPHRoaXMsIFQ+XG4gICk6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHN0YXRlIGlzIGV4cGlyZWQuXG4gICAqXG4gICAqIEBwYXJhbSBzdGF0dXMgLSBgbnVsbGAgdG8gY2hlY2sgaWYgc3RhdGUgaXMgZXhwaXJlZC5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHN0YXRlIGlzIGV4cGlyZWQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0KHN0YXR1czogbnVsbCk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHdoZW4gc3RhdGUgaXMgdG8gYmUgZGVzdHJveWVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gc3RhdGUgaXMgZGVzdHJveWVkLlxuICAgKiBAcmV0dXJucyBGdW5jdGlvbiB0byBjYW5jZWwgbGlzdGVuZXIuXG4gICAqL1xuICBnZXQoc3RhdHVzOiBudWxsLCBjYWxsYmFjazogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQ7XG5cbiAgZ2V0KFxuICAgIGFyZzE/OiBTdGF0ZS5FZmZlY3Q8dGhpcz4gfCBzdHJpbmcgfCBudWxsLFxuICAgIGFyZzI/OiBib29sZWFuIHwgU3RhdGUuT25VcGRhdGU8dGhpcywgYW55PlxuICApIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcy5pcztcblxuICAgIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHJldHVybiB2YWx1ZXMoc2VsZik7XG4gICAgaWYgKHR5cGVvZiBhcmcxID09ICdmdW5jdGlvbicpIHJldHVybiBlZmZlY3Qoc2VsZiwgYXJnMSk7XG4gICAgaWYgKHR5cGVvZiBhcmcyID09ICdmdW5jdGlvbicpIHJldHVybiBhZGRMaXN0ZW5lcihzZWxmLCBhcmcyLCBhcmcxKTtcbiAgICBpZiAoYXJnMSA9PT0gbnVsbCkgcmV0dXJuIE9iamVjdC5pc0Zyb3plbihTVEFURS5nZXQoc2VsZikpO1xuICAgIHJldHVybiBhY2Nlc3Moc2VsZiwgYXJnMSwgYXJnMik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHVwZGF0ZSBpbiBwcm9ncmVzcy5cbiAgICpcbiAgICogQHJldHVybnMgUHJvbWlzZSB3aGljaCByZXNvbHZlcyBvYmplY3Qgd2l0aCB1cGRhdGVkIHZhbHVlcywgYHVuZGVmaW5lZGAgaWYgdGhlcmUgbm8gdXBkYXRlIGlzIHBlbmRpbmcuXG4gICAqKi9cbiAgc2V0KCk6IFByb21pc2VMaWtlPFN0YXRlLkV2ZW50PHRoaXM+W10+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsaXRwbGUgcHJvcGVydGllcyBhdCBvbmNlLiBNZXJnZXMgYXJndW1lbnQgd2l0aCBjdXJyZW50IHN0YXRlLlxuICAgKiBQcm9wZXJ0aWVzIHdoaWNoIGFyZSBub3QgbWFuYWdlZCBieSB0aGlzIHN0YXRlIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtIGFzc2lnbiAtIE9iamVjdCB3aXRoIHByb3BlcnRpZXMgdG8gdXBkYXRlLlxuICAgKiBAcGFyYW0gc2lsZW50IC0gSWYgYW4gdXBkYXRlIGRvZXMgb2NjdXIsIGxpc3RlbmVycyB3aWxsIG5vdCBiZSByZWZyZXNoZWQgYXV0b21hdGljYWxseS5cbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgYW4gYXJyYXkgb2Yga2V5cyB1cGRhdGVkLCBgdW5kZWZpbmVkYCAoaW1tZWRpYXRlbHkpIGlmIGEgbm9vcC5cbiAgICovXG4gIHNldChcbiAgICBhc3NpZ24/OiBTdGF0ZS5Bc3NpZ248dGhpcz4sXG4gICAgc2lsZW50PzogYm9vbGVhblxuICApOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogUHVzaCBhbiB1cGRhdGUuIFRoaXMgd2lsbCBub3QgY2hhbmdlIHRoZSB2YWx1ZSBvZiBhc3NvY2lhdGVkIHByb3BlcnR5LlxuICAgKlxuICAgKiBVc2VmdWwgd2hlcmUgYSBwcm9wZXJ0eSB2YWx1ZSBpbnRlcm5hbGx5IGhhcyBjaGFuZ2VkLCBidXQgdGhlIG9iamVjdCBpcyB0aGUgc2FtZS5cbiAgICogRm9yIGV4YW1wbGU6IEFuIGFycmF5IGhhcyBwdXNoZWQgYSBuZXcgdmFsdWUsIG9yIGEgbmVzdGVkIHByb3BlcnR5IGlzIHVwZGF0ZWQuXG4gICAqXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgdGhpcyB0byBkaXNwYXRjaCBhcmJpdHJhcnkgZXZlbnRzLlxuICAgKiBTeW1ib2xzIGFyZSByZWNvbW1lbmRlZCBhcyBub24tcHJvcGVydHkgZXZlbnRzLCBob3dldmVyIHlvdSBjYW4gdXNlIGFueSBzdHJpbmcuXG4gICAqIElmIGRvaW5nIHNvLCBiZSBzdXJlIHRvIGF2b2lkIGNvbGxpc2lvbnMgd2l0aCBwcm9wZXJ0eSBuYW1lcyEgQW4gZWFzeSB3YXkgdG8gZG8gdGhpcyBpc1xuICAgKiB0byBwcmVmaXggYW4gZXZlbnQgd2l0aCBcIiFcIiBhbmQvb3IgdXNlIGRhc2gtY2FzZS4gZS5nLiBgc2V0KFwiIWV2ZW50XCIpYCBvciBgc2V0KFwibXktZXZlbnRcIilgLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUHJvcGVydHkgb3IgZXZlbnQgdG8gZGlzcGF0Y2guXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2ZXMgYW4gYXJyYXkgb2Yga2V5cyB1cGRhdGVkLlxuICAgKi9cbiAgc2V0KGtleTogU3RhdGUuRXZlbnQ8dGhpcz4pOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgZm9yIGEgcHJvcGVydHkuIFRoaXMgd2lsbCB1cGRhdGUgdGhlIHZhbHVlIGFuZCBub3RpZnkgbGlzdGVuZXJzLlxuICAgKlxuICAgKiAqKlVzZSB3aXRoIGNhdXRpb24hKiogS2V5IG5vciB2YWx1ZSBhcmUgY2hlY2tlZCBmb3IgdmFsaWRpdHkuXG4gICAqXG4gICAqIFRoaXMgaXMgbWVhbnQgZm9yIGFzc2lnbmluZyB2YWx1ZXMgcHJvZ3JhbW1hdGljYWxseSxcbiAgICogd2hlcmUgc2ltcGxlIGFzc2lnbm1lbnQgaXMgbm90IHByYWN0aWNhYmxlLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZTogYCh0aGlzIGFzIGFueSlbbXlQcm9wZXJ0eV0gPSB2YWx1ZTtgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBQcm9wZXJ0eSB0byBzZXQgdmFsdWUgZm9yLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBzZXQgZm9yIHByb3BlcnR5LlxuICAgKiBAcGFyYW0gaW5pdCAtIElmIHRydWUsIHN0YXRlIHdpbGwgYmVnaW4gdG8gbWFuYWdlIHRoZSBwcm9wZXJ0eSBpZiBpdCBpcyBub3QgYWxyZWFkeS5cbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZlcyBhbiBhcnJheSBvZiBrZXlzIHVwZGF0ZWQuXG4gICAqL1xuICBzZXQoXG4gICAga2V5OiBTdGF0ZS5FdmVudDx0aGlzPixcbiAgICB2YWx1ZTogdW5rbm93bixcbiAgICBpbml0PzogYm9vbGVhblxuICApOiBQcm9taXNlTGlrZTxTdGF0ZS5FdmVudDx0aGlzPltdPjtcblxuICAvKipcbiAgICogQ2FsbCBhIGZ1bmN0aW9uIHdoZW4gdXBkYXRlIG9jY3Vycy5cbiAgICpcbiAgICogR2l2ZW4gZnVuY3Rpb24gaXMgY2FsbGVkIGZvciBldmVyeSBhc3NpZ25tZW50ICh3aGljaCBjaGFuZ2VzIHZhbHVlKSBvciBleHBsaWNpdCBgc2V0YC5cbiAgICpcbiAgICogVG8gcnVuIGxvZ2ljIG9uIGZpbmFsIHZhbHVlIG9ubHksIGNhbGxiYWNrIG1heSByZXR1cm4gYSBmdW5jdGlvbi4gVXNpbmcgdGhlIHNhbWVcbiAgICogZnVuY3Rpb24gZm9yIG9uZSBvciBtb3JlIGV2ZW50cyB3aWxsIGVuc3VyZSBpdCBpcyBjYWxsZWQgb25seSB3aGVuIGV2ZW50cyBhcmUgc2V0dGxlZC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIHVwZGF0ZSBvY2N1cnMuXG4gICAqIEByZXR1cm5zIEZ1bmN0aW9uIHRvIHJlbW92ZSBsaXN0ZW5lci4gV2lsbCByZXR1cm4gYHRydWVgIGlmIHJlbW92ZWQsIGBmYWxzZWAgaWYgaW5hY3RpdmUgYWxyZWFkeS5cbiAgICpcbiAgICovXG4gIHNldChjYWxsYmFjazogU3RhdGUuT25FdmVudDx0aGlzPik6ICgpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aGVuIGEgcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogVW5saWtlIGBnZXRgLCB0aGlzIGNhbGxzIHN5bmNocm9ub3VzbHkgYW5kIHdpbGwgZmlyZSBhcyBtYW55IHRpbWVzIGFzIHRoZSBwcm9wZXJ0eSBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gcHJvcGVydHkgaXMgdXBkYXRlZC5cbiAgICogQHBhcmFtIGV2ZW50IC0gUHJvcGVydHkgdG8gd2F0Y2ggZm9yIHVwZGF0ZXMuXG4gICAqL1xuICBzZXQoXG4gICAgY2FsbGJhY2s6IFN0YXRlLk9uRXZlbnQ8dGhpcz4sXG4gICAgZXZlbnQ6IFN0YXRlLkV2ZW50PHRoaXM+IHwgbnVsbFxuICApOiAoKSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBEZWNsYXJlIGFuIGVuZCB0byB1cGRhdGVzLiBUaGlzIGV2ZW50IGlzIGZpbmFsIGFuZCB3aWxsIGZyZWV6ZSBzdGF0ZS5cbiAgICogVGhpcyBldmVudCBjYW4gYmUgd2F0Y2hlZCBmb3IgYXMgd2VsbCwgdG8gcnVuIGNsZWFudXAgbG9naWMgYW5kIGludGVybmFsbHkgd2lsbCByZW1vdmUgYWxsIGxpc3RlbmVycy5cbiAgICpcbiAgICogQHBhcmFtIHN0YXR1cyAtIGBudWxsYCB0byBlbmQgdXBkYXRlcy5cbiAgICovXG4gIHNldChzdGF0dXM6IG51bGwpOiB2b2lkO1xuXG4gIHNldChcbiAgICBhcmcxPzogU3RhdGUuT25FdmVudDx0aGlzPiB8IFN0YXRlLkFzc2lnbjx0aGlzPiB8IFN0YXRlLkV2ZW50PHRoaXM+IHwgbnVsbCxcbiAgICBhcmcyPzogdW5rbm93bixcbiAgICBhcmczPzogYm9vbGVhblxuICApIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcy5pcztcblxuICAgIGlmICh0eXBlb2YgYXJnMSA9PSAnZnVuY3Rpb24nKVxuICAgICAgcmV0dXJuIGFkZExpc3RlbmVyKHNlbGYsIChrZXkpID0+IHtcbiAgICAgICAgaWYgKGFyZzIgPT09IGtleSB8fCAoYXJnMiA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBrZXkgPT0gJ3N0cmluZycpKVxuICAgICAgICAgIHJldHVybiBhcmcxLmNhbGwoc2VsZiwga2V5LCBzZWxmKTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKGFyZzEgJiYgdHlwZW9mIGFyZzEgPT0gJ29iamVjdCcpIHtcbiAgICAgIGFzc2lnbihzZWxmLCBhcmcxLCBhcmcyID09PSB0cnVlKTtcbiAgICB9IGVsc2UgaWYgKCFhcmcyKSB7XG4gICAgICBldmVudChzZWxmLCBhcmcxKTtcbiAgICB9IGVsc2UgaWYgKGFyZzMpIHtcbiAgICAgIG1hbmFnZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZShzZWxmLCBhcmcxIGFzIHN0cmluZyB8IG51bWJlciwgYXJnMik7XG4gICAgfVxuXG4gICAgY29uc3QgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGhpcyk7XG5cbiAgICBpZiAocGVuZGluZylcbiAgICAgIHJldHVybiA8UHJvbWlzZUxpa2U8U3RhdGUuRXZlbnQ8dGhpcz5bXT4+e1xuICAgICAgICB0aGVuOiAocmVzKSA9PlxuICAgICAgICAgIG5ldyBQcm9taXNlPGFueT4oKHJlcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlID0gYWRkTGlzdGVuZXIodGhpcywgKGtleSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoa2V5ICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5iaW5kKG51bGwsIEFycmF5LmZyb20ocGVuZGluZykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KS50aGVuKHJlcylcbiAgICAgIH07XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZSBvdmVyIG1hbmFnZWQgcHJvcGVydGllcyBpbiB0aGlzIGluc3RhbmNlIG9mIFN0YXRlLlxuICAgKiBZZWlsZHMgdGhlIGtleSBhbmQgY3VycmVudCB2YWx1ZSBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAgICovXG4gIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhdG9yPFtzdHJpbmcsIHVua25vd25dPiB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKFNUQVRFLmdldCh0aGlzLmlzKSEpW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW5kIGFjdGl2YXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgc3RhdGUuXG4gICAqXG4gICAqICoqSW1wb3J0YW50KiogLSBVbmxpa2UgYG5ldyB0aGlzKC4uLilgIC0gdGhpcyBtZXRob2QgYWxzbyBhY3RpdmF0ZXMgc3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBhcmdzIC0gYXJndW1lbnRzIHNlbnQgdG8gY29uc3RydWN0b3JcbiAgICovXG4gIHN0YXRpYyBuZXc8VCBleHRlbmRzIFN0YXRlPih0aGlzOiBTdGF0ZS5OZXc8VD4sIC4uLmFyZ3M6IFN0YXRlLkFyZ3M8VD4pOiBUIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyB0aGlzKC4uLmFyZ3MsICh4KSA9PiB7XG4gICAgICBjb25zdCBjYiA9IHgubmV3ICYmIHgubmV3KCk7XG4gICAgICBpZiAoY2IpIHguc2V0KGNiLCBudWxsKTtcbiAgICB9KTtcbiAgICBldmVudChpbnN0YW5jZSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRpYyBlcXVpdmFsZW50IG9mIGB4IGluc3RhbmNlb2YgdGhpc2AuXG4gICAqIERldGVybWluZXMgaWYgcHJvdmlkZWQgY2xhc3MgaXMgYSBzdWJ0eXBlIG9mIHRoaXMgb25lLlxuICAgKiBJZiBzbywgbGFuZ3VhZ2Ugc2VydmVyIHdpbGwgbWFrZSBhdmFpbGFibGUgYWxsIHN0YXRpY1xuICAgKiBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzIG9mIHRoaXMgY2xhc3MuXG4gICAqL1xuICBzdGF0aWMgaXM8VCBleHRlbmRzIFN0YXRlLkV4dGVuZHM+KHRoaXM6IFQsIG1heWJlOiB1bmtub3duKTogbWF5YmUgaXMgVCB7XG4gICAgcmV0dXJuIChcbiAgICAgIG1heWJlID09PSB0aGlzIHx8XG4gICAgICAodHlwZW9mIG1heWJlID09ICdmdW5jdGlvbicgJiYgbWF5YmUucHJvdG90eXBlIGluc3RhbmNlb2YgdGhpcylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcnVuIHdoZW4gYW55IGluc3RhbmNlIG9mIHRoaXMgU3RhdGUgaXMgdXBkYXRlZC5cbiAgICovXG4gIHN0YXRpYyBvbjxUIGV4dGVuZHMgU3RhdGU+KFxuICAgIHRoaXM6IFN0YXRlLkV4dGVuZHM8VD4sXG4gICAgbGlzdGVuZXI6IFN0YXRlLk9uRXZlbnQ8VD5cbiAgKSB7XG4gICAgbGV0IG5vdGlmeSA9IE5PVElGWS5nZXQodGhpcyk7XG5cbiAgICBpZiAoIW5vdGlmeSkgTk9USUZZLnNldCh0aGlzLCAobm90aWZ5ID0gbmV3IFNldCgpKSk7XG5cbiAgICBub3RpZnkuYWRkKGxpc3RlbmVyKTtcblxuICAgIHJldHVybiAoKSA9PiBub3RpZnkuZGVsZXRlKGxpc3RlbmVyKTtcbiAgfVxufVxuXG5kZWZpbmUoU3RhdGUucHJvdG90eXBlLCAndG9TdHJpbmcnLCB7XG4gIHZhbHVlKCkge1xuICAgIHJldHVybiBJRC5nZXQodGhpcy5pcyk7XG4gIH1cbn0pO1xuXG5kZWZpbmUoU3RhdGUsICd0b1N0cmluZycsIHtcbiAgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIGFzc2lnbihzdWJqZWN0OiBTdGF0ZSwgZGF0YTogU3RhdGUuQXNzaWduPFN0YXRlPiwgc2lsZW50PzogYm9vbGVhbikge1xuICBjb25zdCBtZXRob2RzID0gTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvcikhO1xuXG4gIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICBjb25zdCBiaW5kID0gbWV0aG9kcy5nZXQoa2V5KTtcblxuICAgIGlmIChiaW5kKSBiaW5kLmNhbGwoc3ViamVjdCwgZGF0YVtrZXldKTtcbiAgICBlbHNlIGlmIChrZXkgaW4gc3ViamVjdCAmJiBrZXkgIT09ICdpcycpIHtcbiAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHN1YmplY3QsIGtleSkhO1xuICAgICAgY29uc3Qgc2V0ID0gZGVzYyAmJiAoZGVzYy5zZXQgYXMgKHZhbHVlOiBhbnksIHNpbGVudD86IGJvb2xlYW4pID0+IHZvaWQpO1xuXG4gICAgICBpZiAoc2V0KSB7XG4gICAgICAgIHNldC5jYWxsKHN1YmplY3QsIGRhdGFba2V5XSwgc2lsZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIChzdWJqZWN0IGFzIGFueSlba2V5XSA9IGRhdGFba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqIEFwcGx5IGluc3RydWN0aW9ucyBhbmQgaW5oZXJpdGVkIGV2ZW50IGxpc3RlbmVycy4gRW5zdXJlIGNsYXNzIG1ldGFkYXRhIGlzIHJlYWR5LiAqL1xuZnVuY3Rpb24gcHJlcGFyZShzdGF0ZTogU3RhdGUpIHtcbiAgbGV0IFQgPSBzdGF0ZS5jb25zdHJ1Y3RvciBhcyBTdGF0ZS5FeHRlbmRzO1xuXG4gIGlmIChUID09PSBTdGF0ZSkgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY3JlYXRlIGJhc2UgU3RhdGUuJyk7XG5cbiAgY29uc3QgY2hhaW4gPSBbXSBhcyBTdGF0ZS5FeHRlbmRzW107XG4gIGxldCBrZXlzID0gbmV3IE1hcDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiB2b2lkPigpO1xuXG4gIElELnNldChzdGF0ZSwgYCR7VH0tJHt1aWQoKX1gKTtcblxuICB3aGlsZSAoVC5uYW1lKSB7XG4gICAgZm9yIChjb25zdCBjYiBvZiBOT1RJRlkuZ2V0KFQpIHx8IFtdKSB7XG4gICAgICBhZGRMaXN0ZW5lcihzdGF0ZSwgY2IpO1xuICAgIH1cblxuICAgIGlmIChUID09PSBTdGF0ZSkgYnJlYWs7XG4gICAgZWxzZSBjaGFpbi51bnNoaWZ0KFQpO1xuXG4gICAgVCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihUKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdHlwZSBvZiBjaGFpbikge1xuICAgIGlmIChNRVRIT0RTLmhhcyh0eXBlKSkge1xuICAgICAga2V5cyA9IE1FVEhPRFMuZ2V0KHR5cGUpITtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIE1FVEhPRFMuc2V0KHR5cGUsIChrZXlzID0gbmV3IE1hcChrZXlzKSkpO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCB7IHZhbHVlIH1dIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnModHlwZS5wcm90b3R5cGUpXG4gICAgKSkge1xuICAgICAgaWYgKCF2YWx1ZSB8fCBrZXkgPT0gJ2NvbnN0cnVjdG9yJykgY29udGludWU7XG5cbiAgICAgIGZ1bmN0aW9uIGJpbmQodGhpczogU3RhdGUsIG9yaWdpbmFsPzogRnVuY3Rpb24pIHtcbiAgICAgICAgY29uc3QgeyBpcyB9ID0gdGhpcztcblxuICAgICAgICBpZiAoaXMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAhb3JpZ2luYWwpIHJldHVybiB2YWx1ZSBhcyBGdW5jdGlvbjtcblxuICAgICAgICBjb25zdCBmbiA9IG9yaWdpbmFsIHx8IHZhbHVlO1xuICAgICAgICBjb25zdCBib3VuZCA9IGZuLmJpbmQoaXMpO1xuXG4gICAgICAgIE1FVEhPRC5zZXQoYm91bmQsIGZuKTtcbiAgICAgICAgZGVmaW5lKGlzLCBrZXksIHsgdmFsdWU6IGJvdW5kLCB3cml0YWJsZTogdHJ1ZSB9KTtcblxuICAgICAgICByZXR1cm4gYm91bmQ7XG4gICAgICB9XG5cbiAgICAgIGtleXMuc2V0KGtleSwgYmluZCk7XG4gICAgICBkZWZpbmUodHlwZS5wcm90b3R5cGUsIGtleSwgeyBnZXQ6IGJpbmQsIHNldDogYmluZCB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBseSBzdGF0ZSBhcmd1ZW1udHMsIHJ1biBjYWxsYmFja3MgYW5kIG9ic2VydmUgcHJvcGVydGllcy5cbiAqIEFjY3VtdWxhdGUgYW5kIGhhbmRsZSBjbGVhbnVwIGV2ZW50cy5cbiAqKi9cbmZ1bmN0aW9uIGluaXQoc2VsZjogU3RhdGUsIGFyZ3M6IFN0YXRlLkFyZ3MpIHtcbiAgY29uc3Qgc3RhdGUgPSB7fSBhcyBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyIHwgc3ltYm9sLCB1bmtub3duPjtcblxuICBTVEFURS5zZXQoc2VsZiwgc3RhdGUpO1xuXG4gIGFyZ3MgPSBhcmdzLmZsYXQoKS5maWx0ZXIoKGFyZykgPT4ge1xuICAgIGlmICh0eXBlb2YgYXJnID09ICdzdHJpbmcnKSBJRC5zZXQoc2VsZiwgYXJnKTtcbiAgICBlbHNlIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBhZGRMaXN0ZW5lcihzZWxmLCAoKSA9PiB7XG4gICAgaWYgKCFQQVJFTlQuaGFzKHNlbGYpKSBQQVJFTlQuc2V0KHNlbGYsIG51bGwpO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gc2VsZikge1xuICAgICAgY29uc3QgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc2VsZiwga2V5KSE7XG5cbiAgICAgIGlmICgndmFsdWUnIGluIGRlc2MpIG1hbmFnZShzZWxmLCBrZXksIGRlc2MudmFsdWUsIHRydWUpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgYXJnIG9mIGFyZ3MpIHtcbiAgICAgIGNvbnN0IHVzZSA9XG4gICAgICAgIHR5cGVvZiBhcmcgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgID8gYXJnLmNhbGwoc2VsZiwgc2VsZilcbiAgICAgICAgICA6IChhcmcgYXMgU3RhdGUuQXNzaWduPFN0YXRlPik7XG5cbiAgICAgIGlmICh1c2UgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICB1c2UuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFzeW5jIGVycm9yIGluIGNvbnN0cnVjdG9yIGZvciAke3NlbGZ9OmApO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgfSk7XG4gICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KHVzZSkpIGFyZ3MucHVzaCguLi51c2UpO1xuICAgICAgZWxzZSBpZiAodHlwZW9mIHVzZSA9PSAnZnVuY3Rpb24nKSBhZGRMaXN0ZW5lcihzZWxmLCB1c2UsIG51bGwpO1xuICAgICAgZWxzZSBpZiAodHlwZW9mIHVzZSA9PSAnb2JqZWN0JykgYXNzaWduKHNlbGYsIHVzZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIoXG4gICAgICBzZWxmLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IFtfLCB2YWx1ZV0gb2Ygc2VsZilcbiAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdGF0ZSAmJiBQQVJFTlQuZ2V0KHZhbHVlKSA9PT0gc2VsZilcbiAgICAgICAgICAgIHZhbHVlLnNldChudWxsKTtcblxuICAgICAgICBPYmplY3QuZnJlZXplKHN0YXRlKTtcbiAgICAgIH0sXG4gICAgICBudWxsXG4gICAgKTtcblxuICAgIHJldHVybiBudWxsO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0PFQgZXh0ZW5kcyBTdGF0ZT4odGFyZ2V0OiBULCBmbjogU3RhdGUuRWZmZWN0PFQ+KSB7XG4gIGNvbnN0IGVmZmVjdCA9IE1FVEhPRC5nZXQoZm4pIHx8IGZuO1xuICBsZXQgcGVuZGluZyA9IG5ldyBTZXQ8U3RhdGUuRXZlbnQ8VD4+KCk7XG5cbiAgcmV0dXJuIHdhdGNoKHRhcmdldCwgKHByb3h5KSA9PiB7XG4gICAgY29uc3QgY2IgPSBlZmZlY3QuY2FsbChwcm94eSwgcHJveHksIHBlbmRpbmcpO1xuXG4gICAgaWYgKGNiID09PSBudWxsKSByZXR1cm4gY2I7XG5cbiAgICByZXR1cm4gKHVwZGF0ZSkgPT4ge1xuICAgICAgcGVuZGluZyA9IFBFTkRJTkdfS0VZUy5nZXQodGFyZ2V0KSE7XG4gICAgICBpZiAodHlwZW9mIGNiID09ICdmdW5jdGlvbicpIGNiKHVwZGF0ZSk7XG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbHVlczxUIGV4dGVuZHMgU3RhdGU+KHRhcmdldDogVCk6IFN0YXRlLlZhbHVlczxUPiB7XG4gIGNvbnN0IHZhbHVlcyA9IHt9IGFzIGFueTtcbiAgbGV0IGlzTm90UmVjdXJzaXZlO1xuXG4gIGlmICghRVhQT1JUKSB7XG4gICAgaXNOb3RSZWN1cnNpdmUgPSB0cnVlO1xuICAgIEVYUE9SVCA9IG5ldyBNYXAoW1t0YXJnZXQsIHZhbHVlc11dKTtcbiAgfVxuXG4gIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiB0YXJnZXQpIHtcbiAgICBpZiAoRVhQT1JULmhhcyh2YWx1ZSkpIHZhbHVlID0gRVhQT1JULmdldCh2YWx1ZSk7XG4gICAgZWxzZSBpZiAoXG4gICAgICB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnICYmXG4gICAgICAnZ2V0JyBpbiB2YWx1ZSAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmdldCA9PT0gJ2Z1bmN0aW9uJ1xuICAgIClcbiAgICAgIEVYUE9SVC5zZXQodmFsdWUsICh2YWx1ZSA9IHZhbHVlLmdldCgpKSk7XG5cbiAgICB2YWx1ZXNba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzTm90UmVjdXJzaXZlKSBFWFBPUlQgPSB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUodmFsdWVzKTtcbn1cblxuZnVuY3Rpb24gbWFuYWdlKFxuICB0YXJnZXQ6IFN0YXRlLFxuICBrZXk6IHN0cmluZyB8IG51bWJlcixcbiAgdmFsdWU6IGFueSxcbiAgc2lsZW50PzogYm9vbGVhblxuKSB7XG4gIGNvbnN0IHN0YXRlID0gU1RBVEUuZ2V0KHRhcmdldCkhO1xuXG4gIGZ1bmN0aW9uIGdldCh0aGlzOiBTdGF0ZSkge1xuICAgIHJldHVybiBmb2xsb3codGhpcywga2V5LCBzdGF0ZVtrZXldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCh2YWx1ZTogdW5rbm93biwgc2lsZW50PzogYm9vbGVhbikge1xuICAgIHVwZGF0ZSh0YXJnZXQsIGtleSwgdmFsdWUsIHNpbGVudCk7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RhdGUgJiYgIVBBUkVOVC5oYXModmFsdWUpKSB7XG4gICAgICBQQVJFTlQuc2V0KHZhbHVlLCB0YXJnZXQpO1xuICAgICAgZXZlbnQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGRlZmluZSh0YXJnZXQsIGtleSwgeyBzZXQsIGdldCB9KTtcbiAgc2V0KHZhbHVlLCBzaWxlbnQpO1xufVxuXG50eXBlIFByb3h5PFQgPSBhbnk+ID0gKGtleTogc3RyaW5nIHwgbnVtYmVyLCB2YWx1ZTogVCkgPT4gVDtcblxuY29uc3QgT0JTRVJWRVIgPSBuZXcgV2Vha01hcDxTdGF0ZSwgUHJveHk+KCk7XG5cbmZ1bmN0aW9uIGZvbGxvdyhmcm9tOiBTdGF0ZSwga2V5OiBzdHJpbmcgfCBudW1iZXIsIHZhbHVlPzogYW55KSB7XG4gIGNvbnN0IG9ic2VydmUgPSBPQlNFUlZFUi5nZXQoZnJvbSk7XG4gIHJldHVybiBvYnNlcnZlID8gb2JzZXJ2ZShrZXksIHZhbHVlKSA6IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBhY2Nlc3Moc3ViamVjdDogU3RhdGUsIHByb3BlcnR5OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbikge1xuICBjb25zdCBzdGF0ZSA9IFNUQVRFLmdldChzdWJqZWN0KSE7XG5cbiAgaWYgKHByb3BlcnR5IGluIHN0YXRlIHx8IHJlcXVpcmVkID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHZhbHVlID0gc3RhdGVbcHJvcGVydHldO1xuXG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgfHwgIXJlcXVpcmVkKSByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBpZiAoTUVUSE9EUy5nZXQoc3ViamVjdC5jb25zdHJ1Y3RvcikhLmhhcyhwcm9wZXJ0eSkpXG4gICAgcmV0dXJuIE1FVEhPRC5nZXQoKHN1YmplY3QgYXMgYW55KVtwcm9wZXJ0eV0pO1xuXG4gIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGAke3N1YmplY3R9LiR7cHJvcGVydHl9IGlzIG5vdCB5ZXQgYXZhaWxhYmxlLmApO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgYWRkTGlzdGVuZXIoc3ViamVjdCwgKGtleSkgPT4ge1xuICAgICAgaWYgKGtleSA9PT0gcHJvcGVydHkpIHtcbiAgICAgICAgcmVzb2x2ZShzdGF0ZVtrZXldKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChrZXkgPT09IG51bGwpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgJHtzdWJqZWN0fSBpcyBkZXN0cm95ZWQuYCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICB0aHJvdyBPYmplY3QuYXNzaWduKHByb21pc2UsIHtcbiAgICB0b1N0cmluZzogKCkgPT4gU3RyaW5nKGVycm9yKSxcbiAgICBuYW1lOiAnU3VzcGVuc2UnLFxuICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgc3RhY2s6IGVycm9yLnN0YWNrXG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGU8VD4oXG4gIHN1YmplY3Q6IFN0YXRlLFxuICBrZXk6IHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCxcbiAgdmFsdWU6IFQsXG4gIGFyZz86IGJvb2xlYW4gfCBTdGF0ZS5TZXR0ZXI8VD5cbikge1xuICBjb25zdCBzdGF0ZSA9IFNUQVRFLmdldChzdWJqZWN0KSE7XG5cbiAgaWYgKE9iamVjdC5pc0Zyb3plbihzdGF0ZSkpXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFRyaWVkIHRvIHVwZGF0ZSAke3N1YmplY3R9LiR7U3RyaW5nKGtleSl9IGJ1dCBzdGF0ZSBpcyBkZXN0cm95ZWQuYFxuICAgICk7XG5cbiAgY29uc3QgcHJldmlvdXMgPSBzdGF0ZVtrZXldIGFzIFQ7XG5cbiAgaWYgKHR5cGVvZiBhcmcgPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IG91dCA9IGFyZy5jYWxsKHN1YmplY3QsIHZhbHVlLCBwcmV2aW91cyk7XG5cbiAgICBpZiAob3V0ID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJykgdmFsdWUgPSBvdXQoKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gcHJldmlvdXMgJiYga2V5IGluIHN0YXRlKSByZXR1cm47XG5cbiAgc3RhdGVba2V5XSA9IHZhbHVlO1xuXG4gIGlmIChhcmcgIT09IHRydWUpIGV2ZW50KHN1YmplY3QsIGtleSk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKiBSYW5kb20gYWxwaGFudW1iZXJpYyBvZiBsZW5ndGggNjsgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgbGV0dGVyLiAqL1xuZnVuY3Rpb24gdWlkKCkge1xuICByZXR1cm4gKDAuMjc4ICsgTWF0aC5yYW5kb20oKSAqIDAuNzIyKVxuICAgIC50b1N0cmluZygzNilcbiAgICAuc3Vic3RyaW5nKDIsIDgpXG4gICAgLnRvVXBwZXJDYXNlKCk7XG59XG5cbmV4cG9ydCB7IGV2ZW50LCBNRVRIT0QsIFN0YXRlLCBQQVJFTlQsIFNUQVRFLCB1aWQsIGFjY2VzcywgdXBkYXRlLCBmb2xsb3cgfTtcbiJdLAogICJtYXBwaW5ncyI6ICJBQUFBO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBRUE7QUFBQSxPQUNLO0FBRVAsTUFBTSxTQUFT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LE1BQUksUUFBUSxJQUFJLFFBQVEsV0FBVyxFQUFHLElBQUksUUFBUTtBQUNoRCxXQUFPLE9BQU8sSUFBSyxRQUFnQixRQUFRLENBQUM7QUFFOUMsUUFBTSxRQUFRLElBQUksTUFBTSxHQUFHLE9BQU8sSUFBSSxRQUFRLHdCQUF3QjtBQUN0RSxRQUFNLFVBQVUsSUFBSSxRQUFhLENBQUMsU0FBUyxXQUFXO0FBQ3BELGdCQUFZLFNBQVMsQ0FBQyxRQUFRO0FBQzVCLFVBQUksUUFBUSxVQUFVO0FBQ3BCLGdCQUFRLE1BQU0sR0FBRyxDQUFDO0FBQ2xCLGVBQU87QUFBQSxNQUNUO0FBRUEsVUFBSSxRQUFRLE1BQU07QUFDaEIsZUFBTyxJQUFJLE1BQU0sR0FBRyxPQUFPLGdCQUFnQixDQUFDO0FBQUEsTUFDOUM7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNILENBQUM7QUFFRCxRQUFNLE9BQU8sT0FBTyxTQUFTO0FBQUEsSUFDM0IsVUFBVSxNQUFNLE9BQU8sS0FBSztBQUFBLElBQzVCLE1BQU07QUFBQSxJQUNOLFNBQVMsTUFBTTtBQUFBLElBQ2YsT0FBTyxNQUFNO0FBQUEsRUFDZixDQUFDO0FBQ0g7QUFFQSxTQUFTLE9BQ1AsU0FDQSxLQUNBLE9BQ0EsS0FDQTtBQUNBLFFBQU0sUUFBUSxNQUFNLElBQUksT0FBTztBQUUvQixNQUFJLE9BQU8sU0FBUyxLQUFLO0FBQ3ZCLFVBQU0sSUFBSTtBQUFBLE1BQ1IsbUJBQW1CLE9BQU8sSUFBSSxPQUFPLEdBQUcsQ0FBQztBQUFBLElBQzNDO0FBRUYsUUFBTSxXQUFXLE1BQU0sR0FBRztBQUUxQixNQUFJLE9BQU8sT0FBTyxZQUFZO0FBQzVCLFVBQU0sTUFBTSxJQUFJLEtBQUssU0FBUyxPQUFPLFFBQVE7QUFFN0MsUUFBSSxRQUFRLE1BQU8sUUFBTztBQUUxQixRQUFJLE9BQU8sT0FBTyxXQUFZLFNBQVEsSUFBSTtBQUFBLEVBQzVDO0FBRUEsTUFBSSxVQUFVLFlBQVksT0FBTyxNQUFPO0FBRXhDLFFBQU0sR0FBRyxJQUFJO0FBRWIsTUFBSSxRQUFRLEtBQU0sT0FBTSxTQUFTLEdBQUc7QUFFcEMsU0FBTztBQUNUO0FBR0EsU0FBUyxNQUFNO0FBQ2IsVUFBUSxRQUFRLEtBQUssT0FBTyxJQUFJLE9BQzdCLFNBQVMsRUFBRSxFQUNYLFVBQVUsR0FBRyxDQUFDLEVBQ2QsWUFBWTtBQUNqQjsiLAogICJuYW1lcyI6IFsid2F0Y2giLCAicmVzIiwgImJpbmQiLCAiZWZmZWN0IiwgInVwZGF0ZSIsICJ2YWx1ZXMiLCAidmFsdWUiLCAic2lsZW50Il0KfQo=