| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 |
3
48
2
3
64
1
1
1
1
1
1
1
1
1
1
1
1
16
16
16
1
1
9
1
1
1
32
32
32
32
32
1
1
18
1
1
1
16
16
16
16
16
1
1
1
22
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
2
2
2
2
1
1
1
1
1
1
1
1
2
3
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
| "use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); Iif (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else Eif ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _prototypeProperties = function (child, staticProps, instanceProps) { Iif (staticProps) Object.defineProperties(child, staticProps); Eif (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
var _inherits = function (subClass, superClass) { Iif (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); Eif (superClass) subClass.__proto__ = superClass; };
var _classCallCheck = function (instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var fluxMixin = _interopRequire(require("../fluxMixin"));
var _Flux = require("../../Flux");
var Flummox = _Flux.Flummox;
var Store = _Flux.Store;
var Actions = _Flux.Actions;
var sinon = _interopRequire(require("sinon"));
var React = _interopRequire(require("react/addons"));
var PropTypes = React.PropTypes;
var TestUtils = React.addons.TestUtils;
describe("fluxMixin", function () {
var TestActions = (function (Actions) {
function TestActions() {
_classCallCheck(this, TestActions);
Eif (Actions != null) {
Actions.apply(this, arguments);
}
}
_inherits(TestActions, Actions);
_prototypeProperties(TestActions, null, {
getSomething: {
value: function getSomething(something) {
return something;
},
writable: true,
configurable: true
}
});
return TestActions;
})(Actions);
var TestStore = (function (Store) {
function TestStore(flux) {
_classCallCheck(this, TestStore);
_get(Object.getPrototypeOf(TestStore.prototype), "constructor", this).call(this);
var testActions = flux.getActions("test");
this.register(testActions.getSomething, this.handleGetSomething);
this.state = {
something: null
};
}
_inherits(TestStore, Store);
_prototypeProperties(TestStore, null, {
handleGetSomething: {
value: function handleGetSomething(something) {
this.setState({ something: something });
},
writable: true,
configurable: true
}
});
return TestStore;
})(Store);
var Flux = (function (Flummox) {
function Flux() {
_classCallCheck(this, Flux);
_get(Object.getPrototypeOf(Flux.prototype), "constructor", this).call(this);
this.createActions("test", TestActions);
this.createStore("test", TestStore, this);
this.createStore("test2", TestStore, this);
}
_inherits(Flux, Flummox);
return Flux;
})(Flummox);
var ComponentWithFluxMixin = React.createClass({
displayName: "ComponentWithFluxMixin",
mixins: [fluxMixin()],
render: function render() {
return null;
}
});
it("gets flux from either props or context", function () {
var flux = new Flux();
var contextComponent = undefined,
propsComponent = undefined;
var ContextComponent = addContext(ComponentWithFluxMixin, { flux: flux }, { flux: React.PropTypes.instanceOf(Flummox) });
var tree = TestUtils.renderIntoDocument(React.createElement(ContextComponent, { keys: "test" }));
contextComponent = TestUtils.findRenderedComponentWithType(tree, ComponentWithFluxMixin);
propsComponent = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
expect(contextComponent.flux).to.be.an["instanceof"](Flummox);
expect(propsComponent.flux).to.be.an["instanceof"](Flummox);
});
it("exposes flux as context", function () {
var flux = new Flux();
var ChildComponent = React.createClass({
displayName: "ChildComponent",
contextTypes: {
flux: PropTypes.instanceOf(Flummox) },
render: function render() {
return React.createElement("div", null);
}
});
var Component = React.createClass({
displayName: "Component",
mixins: [fluxMixin()],
render: function render() {
return React.createElement(
"div",
null,
React.createElement(ChildComponent, { key: "test" })
);
}
});
var tree = TestUtils.renderIntoDocument(React.createElement(Component, { flux: flux }));
var childComponent = TestUtils.findRenderedComponentWithType(tree, ChildComponent);
expect(childComponent.context.flux).to.equal(flux);
});
it("throws error if neither props or context is set", function () {
var flux = new Flux();
expect(TestUtils.renderIntoDocument.bind(null, React.createElement(ComponentWithFluxMixin, null))).to["throw"]("fluxMixin: Could not find Flux instance. Ensure that your component " + "has either `this.context.flux` or `this.props.flux`.");
});
it("ignores change event after unmounted", function () {
var flux = new Flux();
flux.getActions("test").getSomething("foo");
var getterMap = {
test: function (store) {
return { something: store.state.something };
}
};
var Component = React.createClass({
displayName: "Component",
mixins: [fluxMixin(getterMap)],
render: function render() {
return null;
}
});
var container = document.createElement("div");
var component = React.render(React.createElement(Component, { flux: flux }), container);
var listener = flux.getStore("test").listeners("change")[0];
React.unmountComponentAtNode(container);
flux.getActions("test").getSomething("bar");
listener();
expect(component.state.something).to.equal("foo");
});
it("uses #connectToStores() to get initial state", function () {
var flux = new Flux();
flux.getActions("test").getSomething("foobar");
var getterMap = {
test: function (store) {
return {
something: store.state.something,
custom: true };
} };
var mixin = fluxMixin(getterMap);
var connectToStores = sinon.spy(mixin, "connectToStores");
var Component = React.createClass({
displayName: "Component",
mixins: [mixin],
getInitialState: function getInitialState() {
return {
foobar: "baz" };
},
render: function render() {
return null;
}
});
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: "test", flux: flux }));
expect(connectToStores.calledOnce).to.be["true"];
expect(connectToStores.firstCall.args[0]).to.equal(getterMap);
expect(flux.getStore("test").listeners("change")).to.have.length(1);
expect(component.state).to.deep.equal({
something: "foobar",
custom: true,
foobar: "baz" });
});
describe("#connectToStores", function () {
it("returns initial state", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
var initialState = component.connectToStores("test");
expect(initialState).to.deep.equal({
something: null });
});
it("merges store state with component state on change", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.setState({ otherThing: "barbaz" });
component.connectToStores("test");
flux.getActions("test").getSomething("foobar");
expect(component.state).to.deep.equal({
something: "foobar",
otherThing: "barbaz" });
});
it("uses custom state getter, if given", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.setState({ otherThing: "barbaz" });
component.connectToStores("test", function (store) {
return {
something: store.state.something,
custom: true };
});
flux.getActions("test").getSomething("foobar");
expect(component.state).to.deep.equal({
something: "foobar",
otherThing: "barbaz",
custom: true });
});
it("binds state getter to component", function () {
var flux = new Flux();
var Component = React.createClass({
displayName: "Component",
mixins: [fluxMixin({
test: function (store) {
this.someComponentMethod("some arg");
return {
something: store.state.something,
custom: true };
} })],
render: function render() {
return null;
},
someComponentMethod: function someComponentMethod(string) {
return string;
}
});
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: "test", flux: flux }));
var someComponentMethod = sinon.spy(component, "someComponentMethod");
flux.getActions("test").getSomething("foobar");
expect(someComponentMethod.calledOnce).to.be["true"];
expect(someComponentMethod.firstCall.args[0]).to.equal("some arg");
});
it("syncs with store after prop change", function () {
var flux = new Flux();
var Component = React.createClass({
displayName: "Component",
mixins: [fluxMixin({
test: function (store) {
return {
foo: "foo is " + this.props.foo };
} })],
render: function render() {
return null;
}
});
var component = TestUtils.renderIntoDocument(React.createElement(Component, { key: "test", flux: flux, foo: "bar" }));
expect(component.state.foo).to.equal("foo is bar");
component.setProps({ foo: "baz" });
expect(component.state.foo).to.equal("foo is baz");
});
it("accepts object of keys to state getters", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.setState({ otherThing: "barbaz" });
component.connectToStores({
test: function (store) {
return {
something: store.state.something,
custom: true };
} });
flux.getActions("test").getSomething("foobar");
expect(component.state).to.deep.equal({
something: "foobar",
otherThing: "barbaz",
custom: true });
});
it("calls default state getter once with array of stores", function () {
var flux = new Flux();
flux.getStore("test2").setState({ otherThing: "barbaz" });
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.connectToStores(["test", "test2"]);
flux.getActions("test").getSomething("foobar");
expect(component.state).to.deep.equal({
something: "foobar",
otherThing: "barbaz"
});
});
it("calls custom state getter once with array of stores", function () {
var flux = new Flux();
var testStore = flux.getStore("test");
var test2Store = flux.getStore("test2");
testStore._testId = "test";
test2Store._testId = "test2";
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
var stateGetter = sinon.stub().returns({ foo: "bar" });
var state = component.connectToStores(["test", "test2"], stateGetter);
expect(stateGetter.calledOnce).to.be["true"];
// Use _testId as unique identifier on store.
expect(stateGetter.firstCall.args[0][0]._testId).to.equal("test");
expect(stateGetter.firstCall.args[0][1]._testId).to.equal("test2");
expect(state).to.deep.equal({
foo: "bar"
});
});
it("uses default getter if null is passed as getter", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.setState({ otherThing: "barbaz" });
component.connectToStores("test", null);
flux.getActions("test").getSomething("foobar");
expect(component.state).to.deep.equal({
something: "foobar",
otherThing: "barbaz" });
});
it("removes listener before unmounting", function () {
var flux = new Flux();
var div = document.createElement("div");
var component = React.render(React.createElement(ComponentWithFluxMixin, { flux: flux }), div);
var store = flux.getStore("test");
component.connectToStores("test");
expect(store.listeners("change").length).to.equal(1);
React.unmountComponentAtNode(div);
expect(store.listeners("change").length).to.equal(0);
});
});
describe("#getStoreState", function () {
it("gets combined state of connected stores", function () {
var flux = new Flux();
var component = TestUtils.renderIntoDocument(React.createElement(ComponentWithFluxMixin, { key: "test", flux: flux }));
component.connectToStores({
test: function (store) {
return {
foo: "bar" };
},
test2: function (store) {
return {
bar: "baz"
};
}
});
component.setState({ baz: "foo" });
expect(component.getStoreState()).to.deep.equal({
foo: "bar",
bar: "baz"
});
});
});
});
function addContext(Component, context, contextTypes) {
return React.createClass({
childContextTypes: contextTypes,
getChildContext: function getChildContext() {
return context;
},
render: function render() {
return React.createElement(Component, this.props);
}
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9hZGRvbnMvX190ZXN0c19fL2ZsdXhNaXhpbi10ZXN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztJQUFPLFNBQVMsMkJBQU0sY0FBYzs7b0JBQ0ksWUFBWTs7SUFBM0MsT0FBTyxTQUFQLE9BQU87SUFBRSxLQUFLLFNBQUwsS0FBSztJQUFFLE9BQU8sU0FBUCxPQUFPO0lBQ3pCLEtBQUssMkJBQU0sT0FBTzs7SUFFbEIsS0FBSywyQkFBTSxjQUFjOztJQUMxQixTQUFTLEdBQUssS0FBSyxDQUFuQixTQUFTO0lBQ1QsU0FBUyxHQUFLLEtBQUssQ0FBQyxNQUFNLENBQTFCLFNBQVM7OztBQUVmLFFBQVEsQ0FBQyxXQUFXLEVBQUUsWUFBTTtNQUVwQixXQUFXLGNBQVMsT0FBTzthQUEzQixXQUFXOzRCQUFYLFdBQVc7O1VBQVMsT0FBTztBQUFQLGVBQU87Ozs7Y0FBM0IsV0FBVyxFQUFTLE9BQU87O3lCQUEzQixXQUFXO0FBQ2Ysa0JBQVk7ZUFBQSxzQkFBQyxTQUFTLEVBQUU7QUFDdEIsaUJBQU8sU0FBUyxDQUFDO1NBQ2xCOzs7Ozs7V0FIRyxXQUFXO0tBQVMsT0FBTzs7TUFNM0IsU0FBUyxjQUFTLEtBQUs7QUFDaEIsYUFEUCxTQUFTLENBQ0QsSUFBSTs0QkFEWixTQUFTOztBQUVYLGlDQUZFLFNBQVMsNkNBRUg7O0FBRVIsVUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxQyxVQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7O0FBRWpFLFVBQUksQ0FBQyxLQUFLLEdBQUc7QUFDWCxpQkFBUyxFQUFFLElBQUk7T0FDaEIsQ0FBQztLQUNIOztjQVZHLFNBQVMsRUFBUyxLQUFLOzt5QkFBdkIsU0FBUztBQVliLHdCQUFrQjtlQUFBLDRCQUFDLFNBQVMsRUFBRTtBQUM1QixjQUFJLENBQUMsUUFBUSxDQUFD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SSxFQUFFLENBQUM7O0FBRXRCLFVBQUksU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FDMUMsb0JBQUMsc0JBQXNCLElBQUMsR0FBRyxFQUFDLE1BQU0sRUFBQyxJQUFJLEVBQUUsSUFBSSxBQUFDLEdBQUcsQ0FDbEQsQ0FBQzs7QUFFRixlQUFTLENBQUMsZUFBZSxDQUFDO0FBQ3hCLFlBQUksRUFBRSxVQUFBLEtBQUs7aUJBQUs7QUFDZCxlQUFHLEVBQUUsS0FBSyxFQUNYO1NBQUM7QUFDRixhQUFLLEVBQUUsVUFBQSxLQUFLO2lCQUFLO0FBQ2YsZUFBRyxFQUFFLEtBQUs7V0FDWDtTQUFDO09BQ0gsQ0FBQyxDQUFDOztBQUVILGVBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzs7QUFFbkMsWUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQzlDLFdBQUcsRUFBRSxLQUFLO0FBQ1YsV0FBRyxFQUFFLEtBQUs7T0FDWCxDQUFDLENBQUM7S0FDSixDQUFDLENBQUM7R0FDSixDQUFDLENBQUM7Q0FFSixDQUFDLENBQUM7O0FBRUgsU0FBUyxVQUFVLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUU7QUFDcEQsU0FBTyxLQUFLLENBQUMsV0FBVyxDQUFDO0FBQ3ZCLHFCQUFpQixFQUFFLFlBQVk7O0FBRS9CLG1CQUFlLEVBQUEsMkJBQUc7QUFDaEIsYUFBTyxPQUFPLENBQUM7S0FDaEI7O0FBRUQsVUFBTSxFQUFBLGtCQUFHO0FBQ1AsYUFBTyxvQkFBQyxTQUFTLEVBQUssSUFBSSxDQUFDLEtBQUssQ0FBSSxDQUFDO0tBQ3RDO0dBQ0YsQ0FBQyxDQUFDO0NBQ0oiLCJmaWxlIjoibGliL2FkZG9ucy9fX3Rlc3RzX18vZmx1eE1peGluLXRlc3QuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZmx1eE1peGluIGZyb20gJy4uL2ZsdXhNaXhpbic7XG5pbXBvcnQgeyBGbHVtbW94LCBTdG9yZSwgQWN0aW9ucyB9IGZyb20gJy4uLy4uL0ZsdXgnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0L2FkZG9ucyc7XG5sZXQgeyBQcm9wVHlwZXMgfSA9IFJlYWN0O1xubGV0IHsgVGVzdFV0aWxzIH0gPSBSZWFjdC5hZGRvbnM7XG5cbmRlc2NyaWJlKCdmbHV4TWl4aW4nLCAoKSA9PiB7XG5cbiAgY2xhc3MgVGVzdEFjdGlvbnMgZXh0ZW5kcyBBY3Rpb25zIHtcbiAgICBnZXRTb21ldGhpbmcoc29tZXRoaW5nKSB7XG4gICAgICByZXR1cm4gc29tZXRoaW5nO1xuICAgIH1cbiAgfVxuXG4gIGNsYXNzIFRlc3RTdG9yZSBleHRlbmRzIFN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcihmbHV4KSB7XG4gICAgICBzdXBlcigpO1xuXG4gICAgICBsZXQgdGVzdEFjdGlvbnMgPSBmbHV4LmdldEFjdGlvbnMoJ3Rlc3QnKTtcbiAgICAgIHRoaXMucmVnaXN0ZXIodGVzdEFjdGlvbnMuZ2V0U29tZXRoaW5nLCB0aGlzLmhhbmRsZUdldFNvbWV0aGluZyk7XG5cbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIHNvbWV0aGluZzogbnVsbFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBoYW5kbGVHZXRTb21ldGhpbmcoc29tZXRoaW5nKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgc29tZXRoaW5nIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNsYXNzIEZsdXggZXh0ZW5kcyBGbHVtbW94IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHN1cGVyKCk7XG5cbiAgICAgIHRoaXMuY3JlYXRlQWN0aW9ucygndGVzdCcsIFRlc3RBY3Rpb25zKTtcbiAgICAgIHRoaXMuY3JlYXRlU3RvcmUoJ3Rlc3QnLCBUZXN0U3RvcmUsIHRoaXMpO1xuICAgICAgdGhpcy5jcmVhdGVTdG9yZSgndGVzdDInLCBUZXN0U3RvcmUsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIGxldCBDb21wb25lbnRXaXRoRmx1eE1peGluID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIG1peGluczogW2ZsdXhNaXhpbigpXSxcblxuICAgIHJlbmRlcigpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2dldHMgZmx1eCBmcm9tIGVpdGhlciBwcm9wcyBvciBjb250ZXh0JywgKCkgPT4ge1xuICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcbiAgICBsZXQgY29udGV4dENvbXBvbmVudCwgcHJvcHNDb21wb25lbnQ7XG5cbiAgICBsZXQgQ29udGV4dENvbXBvbmVudCA9IGFkZENvbnRleHQoXG4gICAgICBDb21wb25lbnRXaXRoRmx1eE1peGluLFxuICAgICAgeyBmbHV4IH0sXG4gICAgICB7IGZsdXg6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEZsdW1tb3gpIH1cbiAgICApO1xuXG4gICAgbGV0IHRyZWUgPSBUZXN0VXRpbHMucmVuZGVySW50b0RvY3VtZW50KFxuICAgICAgPENvbnRleHRDb21wb25lbnQga2V5cz1cInRlc3RcIiAvPlxuICAgICk7XG5cbiAgICBjb250ZXh0Q29tcG9uZW50ID0gVGVzdFV0aWxzLmZpbmRSZW5kZXJlZENvbXBvbmVudFdpdGhUeXBlKFxuICAgICAgdHJlZSwgQ29tcG9uZW50V2l0aEZsdXhNaXhpblxuICAgICk7XG5cbiAgICBwcm9wc0NvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICA8Q29tcG9uZW50V2l0aEZsdXhNaXhpbiBrZXk9XCJ0ZXN0XCIgZmx1eD17Zmx1eH0gLz5cbiAgICApO1xuXG4gICAgZXhwZWN0KGNvbnRleHRDb21wb25lbnQuZmx1eCkudG8uYmUuYW4uaW5zdGFuY2VvZihGbHVtbW94KTtcbiAgICBleHBlY3QocHJvcHNDb21wb25lbnQuZmx1eCkudG8uYmUuYW4uaW5zdGFuY2VvZihGbHVtbW94KTtcbiAgfSk7XG5cbiAgaXQoJ2V4cG9zZXMgZmx1eCBhcyBjb250ZXh0JywgKCkgPT4ge1xuICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgIGxldCBDaGlsZENvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICAgIGNvbnRleHRUeXBlczoge1xuICAgICAgICBmbHV4OiBQcm9wVHlwZXMuaW5zdGFuY2VPZihGbHVtbW94KSxcbiAgICAgIH0sXG5cbiAgICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIDxkaXYgLz47XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgICAgbWl4aW5zOiBbZmx1eE1peGluKCldLFxuXG4gICAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxDaGlsZENvbXBvbmVudCBrZXk9XCJ0ZXN0XCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCB0cmVlID0gVGVzdFV0aWxzLnJlbmRlckludG9Eb2N1bWVudCg8Q29tcG9uZW50IGZsdXg9e2ZsdXh9IC8+KTtcblxuICAgIGxldCBjaGlsZENvbXBvbmVudCA9IFRlc3RVdGlscy5maW5kUmVuZGVyZWRDb21wb25lbnRXaXRoVHlwZShcbiAgICAgIHRyZWUsXG4gICAgICBDaGlsZENvbXBvbmVudFxuICAgICk7XG5cbiAgICBleHBlY3QoY2hpbGRDb21wb25lbnQuY29udGV4dC5mbHV4KS50by5lcXVhbChmbHV4KTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBlcnJvciBpZiBuZWl0aGVyIHByb3BzIG9yIGNvbnRleHQgaXMgc2V0JywgKCkgPT4ge1xuICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgIGV4cGVjdChUZXN0VXRpbHMucmVuZGVySW50b0RvY3VtZW50LmJpbmQobnVsbCwgPENvbXBvbmVudFdpdGhGbHV4TWl4aW4gLz4pKVxuICAgICAgLnRvLnRocm93KFxuICAgICAgICAnZmx1eE1peGluOiBDb3VsZCBub3QgZmluZCBGbHV4IGluc3RhbmNlLiBFbnN1cmUgdGhhdCB5b3VyIGNvbXBvbmVudCAnXG4gICAgICArICdoYXMgZWl0aGVyIGB0aGlzLmNvbnRleHQuZmx1eGAgb3IgYHRoaXMucHJvcHMuZmx1eGAuJ1xuICAgICAgKTtcbiAgfSk7XG5cbiAgaXQoJ2lnbm9yZXMgY2hhbmdlIGV2ZW50IGFmdGVyIHVubW91bnRlZCcsICgpID0+IHtcbiAgICBsZXQgZmx1eCA9IG5ldyBGbHV4KCk7XG4gICAgZmx1eC5nZXRBY3Rpb25zKCd0ZXN0JykuZ2V0U29tZXRoaW5nKCdmb28nKTtcblxuICAgIGxldCBnZXR0ZXJNYXAgPSB7XG4gICAgICB0ZXN0OiBzdG9yZSA9PiAoeyBzb21ldGhpbmc6IHN0b3JlLnN0YXRlLnNvbWV0aGluZyB9KVxuICAgIH07XG4gICAgbGV0IENvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICAgIG1peGluczogW2ZsdXhNaXhpbihnZXR0ZXJNYXApXSxcblxuICAgICAgcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBsZXQgY29tcG9uZW50ID0gUmVhY3QucmVuZGVyKDxDb21wb25lbnQgZmx1eD17Zmx1eH0gLz4sIGNvbnRhaW5lcik7XG4gICAgbGV0IGxpc3RlbmVyID0gZmx1eC5nZXRTdG9yZSgndGVzdCcpLmxpc3RlbmVycygnY2hhbmdlJylbMF07XG5cbiAgICBSZWFjdC51bm1vdW50Q29tcG9uZW50QXROb2RlKGNvbnRhaW5lcik7XG5cbiAgICBmbHV4LmdldEFjdGlvbnMoJ3Rlc3QnKS5nZXRTb21ldGhpbmcoJ2JhcicpO1xuICAgIGxpc3RlbmVyKCk7XG5cbiAgICBleHBlY3QoY29tcG9uZW50LnN0YXRlLnNvbWV0aGluZykudG8uZXF1YWwoJ2ZvbycpO1xuICB9KTtcblxuICBpdCgndXNlcyAjY29ubmVjdFRvU3RvcmVzKCkgdG8gZ2V0IGluaXRpYWwgc3RhdGUnLCAoKSA9PiB7XG4gICAgbGV0IGZsdXggPSBuZXcgRmx1eCgpO1xuXG4gICAgZmx1eC5nZXRBY3Rpb25zKCd0ZXN0JykuZ2V0U29tZXRoaW5nKCdmb29iYXInKTtcblxuICAgIGxldCBnZXR0ZXJNYXAgPSB7XG4gICAgICB0ZXN0OiBzdG9yZSA9PiAoe1xuICAgICAgICBzb21ldGhpbmc6IHN0b3JlLnN0YXRlLnNvbWV0aGluZyxcbiAgICAgICAgY3VzdG9tOiB0cnVlLFxuICAgICAgfSksXG4gICAgfTtcblxuICAgIGxldCBtaXhpbiA9IGZsdXhNaXhpbihnZXR0ZXJNYXApO1xuXG4gICAgbGV0IGNvbm5lY3RUb1N0b3JlcyA9IHNpbm9uLnNweShtaXhpbiwgJ2Nvbm5lY3RUb1N0b3JlcycpO1xuXG4gICAgbGV0IENvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICAgIG1peGluczogW21peGluXSxcblxuICAgICAgZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGZvb2JhcjogJ2JheicsXG4gICAgICAgIH07XG4gICAgICB9LFxuXG4gICAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgbGV0IGNvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICA8Q29tcG9uZW50IGtleT1cInRlc3RcIiBmbHV4PXtmbHV4fSAvPlxuICAgICk7XG5cbiAgICBleHBlY3QoY29ubmVjdFRvU3RvcmVzLmNhbGxlZE9uY2UpLnRvLmJlLnRydWU7XG4gICAgZXhwZWN0KGNvbm5lY3RUb1N0b3Jlcy5maXJzdENhbGwuYXJnc1swXSkudG8uZXF1YWwoZ2V0dGVyTWFwKTtcblxuICAgIGV4cGVjdChmbHV4LmdldFN0b3JlKCd0ZXN0JykubGlzdGVuZXJzKCdjaGFuZ2UnKSkudG8uaGF2ZS5sZW5ndGgoMSk7XG5cbiAgICBleHBlY3QoY29tcG9uZW50LnN0YXRlKS50by5kZWVwLmVxdWFsKHtcbiAgICAgIHNvbWV0aGluZzogJ2Zvb2JhcicsXG4gICAgICBjdXN0b206IHRydWUsXG4gICAgICBmb29iYXI6ICdiYXonLFxuICAgIH0pO1xuXG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjY29ubmVjdFRvU3RvcmVzJywgKCkgPT4ge1xuXG4gICAgaXQoJ3JldHVybnMgaW5pdGlhbCBzdGF0ZScsICgpID0+IHtcbiAgICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgICAgbGV0IGNvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICAgIDxDb21wb25lbnRXaXRoRmx1eE1peGluIGtleT1cInRlc3RcIiBmbHV4PXtmbHV4fSAvPlxuICAgICAgKTtcblxuICAgICAgbGV0IGluaXRpYWxTdGF0ZSA9IGNvbXBvbmVudC5jb25uZWN0VG9TdG9yZXMoJ3Rlc3QnKTtcblxuICAgICAgZXhwZWN0KGluaXRpYWxTdGF0ZSkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgIHNvbWV0aGluZzogbnVsbCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ21lcmdlcyBzdG9yZSBzdGF0ZSB3aXRoIGNvbXBvbmVudCBzdGF0ZSBvbiBjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICBsZXQgZmx1eCA9IG5ldyBGbHV4KCk7XG5cbiAgICAgIGxldCBjb21wb25lbnQgPSBUZXN0VXRpbHMucmVuZGVySW50b0RvY3VtZW50KFxuICAgICAgICA8Q29tcG9uZW50V2l0aEZsdXhNaXhpbiBrZXk9XCJ0ZXN0XCIgZmx1eD17Zmx1eH0gLz5cbiAgICAgICk7XG5cbiAgICAgIGNvbXBvbmVudC5zZXRTdGF0ZSh7IG90aGVyVGhpbmc6ICdiYXJiYXonIH0pO1xuXG4gICAgICBjb21wb25lbnQuY29ubmVjdFRvU3RvcmVzKCd0ZXN0Jyk7XG4gICAgICBmbHV4LmdldEFjdGlvbnMoJ3Rlc3QnKS5nZXRTb21ldGhpbmcoJ2Zvb2JhcicpO1xuXG4gICAgICBleHBlY3QoY29tcG9uZW50LnN0YXRlKS50by5kZWVwLmVxdWFsKHtcbiAgICAgICAgc29tZXRoaW5nOiAnZm9vYmFyJyxcbiAgICAgICAgb3RoZXJUaGluZzogJ2JhcmJheicsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCd1c2VzIGN1c3RvbSBzdGF0ZSBnZXR0ZXIsIGlmIGdpdmVuJywgKCkgPT4ge1xuICAgICAgbGV0IGZsdXggPSBuZXcgRmx1eCgpO1xuXG4gICAgICBsZXQgY29tcG9uZW50ID0gVGVzdFV0aWxzLnJlbmRlckludG9Eb2N1bWVudChcbiAgICAgICAgPENvbXBvbmVudFdpdGhGbHV4TWl4aW4ga2V5PVwidGVzdFwiIGZsdXg9e2ZsdXh9IC8+XG4gICAgICApO1xuXG4gICAgICBjb21wb25lbnQuc2V0U3RhdGUoeyBvdGhlclRoaW5nOiAnYmFyYmF6JyB9KTtcblxuICAgICAgY29tcG9uZW50LmNvbm5lY3RUb1N0b3JlcygndGVzdCcsIHN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzb21ldGhpbmc6IHN0b3JlLnN0YXRlLnNvbWV0aGluZyxcbiAgICAgICAgICBjdXN0b206IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgZmx1eC5nZXRBY3Rpb25zKCd0ZXN0JykuZ2V0U29tZXRoaW5nKCdmb29iYXInKTtcblxuICAgICAgZXhwZWN0KGNvbXBvbmVudC5zdGF0ZSkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgIHNvbWV0aGluZzogJ2Zvb2JhcicsXG4gICAgICAgIG90aGVyVGhpbmc6ICdiYXJiYXonLFxuICAgICAgICBjdXN0b206IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdiaW5kcyBzdGF0ZSBnZXR0ZXIgdG8gY29tcG9uZW50JywgKCkgPT4ge1xuICAgICAgbGV0IGZsdXggPSBuZXcgRmx1eCgpO1xuXG4gICAgICBsZXQgQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgICAgICBtaXhpbnM6IFtmbHV4TWl4aW4oe1xuICAgICAgICAgIHRlc3Q6IGZ1bmN0aW9uKHN0b3JlKSB7XG4gICAgICAgICAgICB0aGlzLnNvbWVDb21wb25lbnRNZXRob2QoJ3NvbWUgYXJnJyk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHNvbWV0aGluZzogc3RvcmUuc3RhdGUuc29tZXRoaW5nLFxuICAgICAgICAgICAgICBjdXN0b206IHRydWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pXSxcblxuICAgICAgICByZW5kZXIoKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc29tZUNvbXBvbmVudE1ldGhvZChzdHJpbmcpIHtcbiAgICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgbGV0IGNvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICAgIDxDb21wb25lbnQga2V5PVwidGVzdFwiIGZsdXg9e2ZsdXh9IC8+XG4gICAgICApO1xuXG4gICAgICBsZXQgc29tZUNvbXBvbmVudE1ldGhvZCA9IHNpbm9uLnNweShjb21wb25lbnQsICdzb21lQ29tcG9uZW50TWV0aG9kJyk7XG4gICAgICBmbHV4LmdldEFjdGlvbnMoJ3Rlc3QnKS5nZXRTb21ldGhpbmcoJ2Zvb2JhcicpO1xuXG4gICAgICBleHBlY3Qoc29tZUNvbXBvbmVudE1ldGhvZC5jYWxsZWRPbmNlKS50by5iZS50cnVlO1xuICAgICAgZXhwZWN0KHNvbWVDb21wb25lbnRNZXRob2QuZmlyc3RDYWxsLmFyZ3NbMF0pLnRvLmVxdWFsKCdzb21lIGFyZycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N5bmNzIHdpdGggc3RvcmUgYWZ0ZXIgcHJvcCBjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICBsZXQgZmx1eCA9IG5ldyBGbHV4KCk7XG5cbiAgICAgIGxldCBDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgICAgIG1peGluczogW2ZsdXhNaXhpbih7XG4gICAgICAgICAgdGVzdDogZnVuY3Rpb24oc3RvcmUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGZvbzogJ2ZvbyBpcyAnICsgdGhpcy5wcm9wcy5mb28sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pXSxcblxuICAgICAgICByZW5kZXIoKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBsZXQgY29tcG9uZW50ID0gVGVzdFV0aWxzLnJlbmRlckludG9Eb2N1bWVudChcbiAgICAgICAgPENvbXBvbmVudCBrZXk9XCJ0ZXN0XCIgZmx1eD17Zmx1eH0gZm9vPVwiYmFyXCIgLz5cbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb21wb25lbnQuc3RhdGUuZm9vKS50by5lcXVhbCgnZm9vIGlzIGJhcicpO1xuXG4gICAgICBjb21wb25lbnQuc2V0UHJvcHMoeyBmb286ICdiYXonIH0pO1xuXG4gICAgICBleHBlY3QoY29tcG9uZW50LnN0YXRlLmZvbykudG8uZXF1YWwoJ2ZvbyBpcyBiYXonKTtcbiAgICB9KTtcblxuICAgIGl0KCdhY2NlcHRzIG9iamVjdCBvZiBrZXlzIHRvIHN0YXRlIGdldHRlcnMnLCAoKSA9PiB7XG4gICAgICBsZXQgZmx1eCA9IG5ldyBGbHV4KCk7XG5cbiAgICAgIGxldCBjb21wb25lbnQgPSBUZXN0VXRpbHMucmVuZGVySW50b0RvY3VtZW50KFxuICAgICAgICA8Q29tcG9uZW50V2l0aEZsdXhNaXhpbiBrZXk9XCJ0ZXN0XCIgZmx1eD17Zmx1eH0gLz5cbiAgICAgICk7XG5cbiAgICAgIGNvbXBvbmVudC5zZXRTdGF0ZSh7IG90aGVyVGhpbmc6ICdiYXJiYXonIH0pO1xuXG4gICAgICBjb21wb25lbnQuY29ubmVjdFRvU3RvcmVzKHtcbiAgICAgICAgdGVzdDogc3RvcmUgPT4gKHtcbiAgICAgICAgICBzb21ldGhpbmc6IHN0b3JlLnN0YXRlLnNvbWV0aGluZyxcbiAgICAgICAgICBjdXN0b206IHRydWUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGZsdXguZ2V0QWN0aW9ucygndGVzdCcpLmdldFNvbWV0aGluZygnZm9vYmFyJyk7XG5cbiAgICAgIGV4cGVjdChjb21wb25lbnQuc3RhdGUpLnRvLmRlZXAuZXF1YWwoe1xuICAgICAgICBzb21ldGhpbmc6ICdmb29iYXInLFxuICAgICAgICBvdGhlclRoaW5nOiAnYmFyYmF6JyxcbiAgICAgICAgY3VzdG9tOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY2FsbHMgZGVmYXVsdCBzdGF0ZSBnZXR0ZXIgb25jZSB3aXRoIGFycmF5IG9mIHN0b3JlcycsICgpID0+IHtcbiAgICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgICAgZmx1eC5nZXRTdG9yZSgndGVzdDInKS5zZXRTdGF0ZSh7IG90aGVyVGhpbmc6ICdiYXJiYXonIH0pO1xuXG4gICAgICBsZXQgY29tcG9uZW50ID0gVGVzdFV0aWxzLnJlbmRlckludG9Eb2N1bWVudChcbiAgICAgICAgPENvbXBvbmVudFdpdGhGbHV4TWl4aW4ga2V5PVwidGVzdFwiIGZsdXg9e2ZsdXh9IC8+XG4gICAgICApO1xuXG4gICAgICBjb21wb25lbnQuY29ubmVjdFRvU3RvcmVzKFsndGVzdCcsICd0ZXN0MiddKTtcblxuICAgICAgZmx1eC5nZXRBY3Rpb25zKCd0ZXN0JykuZ2V0U29tZXRoaW5nKCdmb29iYXInKTtcblxuICAgICAgZXhwZWN0KGNvbXBvbmVudC5zdGF0ZSkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgIHNvbWV0aGluZzogJ2Zvb2JhcicsXG4gICAgICAgIG90aGVyVGhpbmc6ICdiYXJiYXonXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjYWxscyBjdXN0b20gc3RhdGUgZ2V0dGVyIG9uY2Ugd2l0aCBhcnJheSBvZiBzdG9yZXMnLCAoKSA9PiB7XG4gICAgICBsZXQgZmx1eCA9IG5ldyBGbHV4KCk7XG4gICAgICBsZXQgdGVzdFN0b3JlID0gZmx1eC5nZXRTdG9yZSgndGVzdCcpO1xuICAgICAgbGV0IHRlc3QyU3RvcmUgPSBmbHV4LmdldFN0b3JlKCd0ZXN0MicpO1xuXG4gICAgICB0ZXN0U3RvcmUuX3Rlc3RJZCA9ICd0ZXN0JztcbiAgICAgIHRlc3QyU3RvcmUuX3Rlc3RJZCA9ICd0ZXN0Mic7XG5cbiAgICAgIGxldCBjb21wb25lbnQgPSBUZXN0VXRpbHMucmVuZGVySW50b0RvY3VtZW50KFxuICAgICAgICA8Q29tcG9uZW50V2l0aEZsdXhNaXhpbiBrZXk9XCJ0ZXN0XCIgZmx1eD17Zmx1eH0gLz5cbiAgICAgICk7XG5cbiAgICAgIGxldCBzdGF0ZUdldHRlciA9IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHsgZm9vOiAnYmFyJyB9KTtcbiAgICAgIGxldCBzdGF0ZSA9IGNvbXBvbmVudC5jb25uZWN0VG9TdG9yZXMoWyd0ZXN0JywgJ3Rlc3QyJ10sIHN0YXRlR2V0dGVyKTtcblxuICAgICAgZXhwZWN0KHN0YXRlR2V0dGVyLmNhbGxlZE9uY2UpLnRvLmJlLnRydWU7XG4gICAgICAvLyBVc2UgX3Rlc3RJZCBhcyB1bmlxdWUgaWRlbnRpZmllciBvbiBzdG9yZS5cbiAgICAgIGV4cGVjdChzdGF0ZUdldHRlci5maXJzdENhbGwuYXJnc1swXVswXS5fdGVzdElkKS50by5lcXVhbCgndGVzdCcpO1xuICAgICAgZXhwZWN0KHN0YXRlR2V0dGVyLmZpcnN0Q2FsbC5hcmdzWzBdWzFdLl90ZXN0SWQpLnRvLmVxdWFsKCd0ZXN0MicpO1xuXG4gICAgICBleHBlY3Qoc3RhdGUpLnRvLmRlZXAuZXF1YWwoe1xuICAgICAgICBmb286ICdiYXInXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCd1c2VzIGRlZmF1bHQgZ2V0dGVyIGlmIG51bGwgaXMgcGFzc2VkIGFzIGdldHRlcicsICgpID0+IHtcbiAgICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgICAgbGV0IGNvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICAgIDxDb21wb25lbnRXaXRoRmx1eE1peGluIGtleT1cInRlc3RcIiBmbHV4PXtmbHV4fSAvPlxuICAgICAgKTtcblxuICAgICAgY29tcG9uZW50LnNldFN0YXRlKHsgb3RoZXJUaGluZzogJ2JhcmJheicgfSk7XG5cbiAgICAgIGNvbXBvbmVudC5jb25uZWN0VG9TdG9yZXMoJ3Rlc3QnLCBudWxsKTtcblxuICAgICAgZmx1eC5nZXRBY3Rpb25zKCd0ZXN0JykuZ2V0U29tZXRoaW5nKCdmb29iYXInKTtcblxuICAgICAgZXhwZWN0KGNvbXBvbmVudC5zdGF0ZSkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgIHNvbWV0aGluZzogJ2Zvb2JhcicsXG4gICAgICAgIG90aGVyVGhpbmc6ICdiYXJiYXonLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVtb3ZlcyBsaXN0ZW5lciBiZWZvcmUgdW5tb3VudGluZycsICgpID0+IHtcbiAgICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcbiAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAgICAgbGV0IGNvbXBvbmVudCA9IFJlYWN0LnJlbmRlcig8Q29tcG9uZW50V2l0aEZsdXhNaXhpbiBmbHV4PXtmbHV4fSAvPiwgZGl2KTtcblxuICAgICAgbGV0IHN0b3JlID0gZmx1eC5nZXRTdG9yZSgndGVzdCcpO1xuICAgICAgY29tcG9uZW50LmNvbm5lY3RUb1N0b3JlcygndGVzdCcpO1xuXG4gICAgICBleHBlY3Qoc3RvcmUubGlzdGVuZXJzKCdjaGFuZ2UnKS5sZW5ndGgpLnRvLmVxdWFsKDEpO1xuICAgICAgUmVhY3QudW5tb3VudENvbXBvbmVudEF0Tm9kZShkaXYpO1xuICAgICAgZXhwZWN0KHN0b3JlLmxpc3RlbmVycygnY2hhbmdlJykubGVuZ3RoKS50by5lcXVhbCgwKTtcbiAgICB9KTtcblxuICB9KTtcblxuICBkZXNjcmliZSgnI2dldFN0b3JlU3RhdGUnLCAoKSA9PiB7XG4gICAgaXQoJ2dldHMgY29tYmluZWQgc3RhdGUgb2YgY29ubmVjdGVkIHN0b3JlcycsICgpID0+IHtcbiAgICAgIGxldCBmbHV4ID0gbmV3IEZsdXgoKTtcblxuICAgICAgbGV0IGNvbXBvbmVudCA9IFRlc3RVdGlscy5yZW5kZXJJbnRvRG9jdW1lbnQoXG4gICAgICAgIDxDb21wb25lbnRXaXRoRmx1eE1peGluIGtleT1cInRlc3RcIiBmbHV4PXtmbHV4fSAvPlxuICAgICAgKTtcblxuICAgICAgY29tcG9uZW50LmNvbm5lY3RUb1N0b3Jlcyh7XG4gICAgICAgIHRlc3Q6IHN0b3JlID0+ICh7XG4gICAgICAgICAgZm9vOiAnYmFyJyxcbiAgICAgICAgfSksXG4gICAgICAgIHRlc3QyOiBzdG9yZSA9PiAoe1xuICAgICAgICAgIGJhcjogJ2JheidcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuXG4gICAgICBjb21wb25lbnQuc2V0U3RhdGUoeyBiYXo6ICdmb28nIH0pO1xuXG4gICAgICBleHBlY3QoY29tcG9uZW50LmdldFN0b3JlU3RhdGUoKSkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgIGZvbzogJ2JhcicsXG4gICAgICAgIGJhcjogJ2JheidcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxufSk7XG5cbmZ1bmN0aW9uIGFkZENvbnRleHQoQ29tcG9uZW50LCBjb250ZXh0LCBjb250ZXh0VHlwZXMpIHtcbiAgcmV0dXJuIFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBjaGlsZENvbnRleHRUeXBlczogY29udGV4dFR5cGVzLFxuXG4gICAgZ2V0Q2hpbGRDb250ZXh0KCkge1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfSxcblxuICAgIHJlbmRlcigpIHtcbiAgICAgIHJldHVybiA8Q29tcG9uZW50IHsuLi50aGlzLnByb3BzfSAvPjtcbiAgICB9XG4gIH0pO1xufVxuIl19 |