appium 2.0.0-beta.23 → 2.0.0-beta.26

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.
Files changed (125) hide show
  1. package/README.md +1 -2
  2. package/build/lib/appium-config.schema.json +278 -0
  3. package/build/lib/appium.js +62 -71
  4. package/build/lib/cli/args.js +31 -53
  5. package/build/lib/cli/driver-command.js +5 -9
  6. package/build/lib/cli/extension-command.js +73 -64
  7. package/build/lib/cli/extension.js +10 -23
  8. package/build/lib/cli/parser.js +10 -20
  9. package/build/lib/cli/plugin-command.js +5 -9
  10. package/build/lib/cli/utils.js +2 -4
  11. package/build/lib/config-file.js +5 -10
  12. package/build/lib/config.js +67 -30
  13. package/build/lib/constants.js +60 -0
  14. package/build/lib/extension/driver-config.js +190 -0
  15. package/build/lib/extension/extension-config.js +297 -0
  16. package/build/lib/extension/index.js +77 -0
  17. package/build/lib/extension/manifest.js +246 -0
  18. package/build/lib/extension/package-changed.js +68 -0
  19. package/build/lib/extension/plugin-config.js +87 -0
  20. package/build/lib/grid-register.js +2 -4
  21. package/build/lib/logger.js +2 -4
  22. package/build/lib/logsink.js +2 -4
  23. package/build/lib/main.js +64 -92
  24. package/build/lib/schema/appium-config-schema.js +2 -4
  25. package/build/lib/schema/arg-spec.js +14 -15
  26. package/build/lib/schema/cli-args.js +8 -16
  27. package/build/lib/schema/cli-transformers.js +2 -4
  28. package/build/lib/schema/index.js +2 -4
  29. package/build/lib/schema/keywords.js +2 -4
  30. package/build/lib/schema/schema.js +136 -41
  31. package/build/lib/utils.js +13 -64
  32. package/lib/appium.js +74 -55
  33. package/lib/cli/args.js +36 -37
  34. package/lib/cli/driver-command.js +10 -2
  35. package/lib/cli/extension-command.js +216 -135
  36. package/lib/cli/extension.js +7 -15
  37. package/lib/cli/parser.js +7 -15
  38. package/lib/cli/plugin-command.js +1 -2
  39. package/lib/config-file.js +12 -15
  40. package/lib/config.js +111 -36
  41. package/lib/constants.js +79 -0
  42. package/lib/extension/driver-config.js +230 -0
  43. package/lib/extension/extension-config.js +459 -0
  44. package/lib/extension/index.js +103 -0
  45. package/lib/extension/manifest.js +590 -0
  46. package/lib/extension/package-changed.js +64 -0
  47. package/lib/extension/plugin-config.js +111 -0
  48. package/lib/grid-register.js +4 -4
  49. package/lib/main.js +110 -96
  50. package/lib/schema/arg-spec.js +11 -5
  51. package/lib/schema/cli-args.js +7 -30
  52. package/lib/schema/keywords.js +1 -1
  53. package/lib/schema/schema.js +206 -48
  54. package/lib/utils.js +27 -58
  55. package/package.json +29 -21
  56. package/{postinstall.js → scripts/postinstall.js} +1 -1
  57. package/types/types.d.ts +72 -28
  58. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  59. package/build/check-npm-pack-files.js +0 -23
  60. package/build/commands-yml/parse.js +0 -319
  61. package/build/commands-yml/validator.js +0 -130
  62. package/build/index.js +0 -19
  63. package/build/lib/cli/npm.js +0 -220
  64. package/build/lib/driver-config.js +0 -100
  65. package/build/lib/drivers.js +0 -100
  66. package/build/lib/ext-config-io.js +0 -165
  67. package/build/lib/extension-config.js +0 -320
  68. package/build/lib/plugin-config.js +0 -69
  69. package/build/lib/plugins.js +0 -16
  70. package/build/postinstall.js +0 -90
  71. package/build/test/cli/cli-e2e-specs.js +0 -221
  72. package/build/test/cli/cli-helpers.js +0 -86
  73. package/build/test/cli/cli-specs.js +0 -71
  74. package/build/test/cli/fixtures/test-driver/package.json +0 -27
  75. package/build/test/cli/schema-args-specs.js +0 -48
  76. package/build/test/cli/schema-e2e-specs.js +0 -47
  77. package/build/test/config-e2e-specs.js +0 -112
  78. package/build/test/config-file-e2e-specs.js +0 -209
  79. package/build/test/config-file-specs.js +0 -281
  80. package/build/test/config-specs.js +0 -159
  81. package/build/test/driver-e2e-specs.js +0 -435
  82. package/build/test/driver-specs.js +0 -321
  83. package/build/test/ext-config-io-specs.js +0 -181
  84. package/build/test/extension-config-specs.js +0 -365
  85. package/build/test/fixtures/allow-feat.txt +0 -5
  86. package/build/test/fixtures/caps.json +0 -3
  87. package/build/test/fixtures/config/allow-insecure.txt +0 -3
  88. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
  89. package/build/test/fixtures/config/appium.config.bad.json +0 -32
  90. package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
  91. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
  92. package/build/test/fixtures/config/appium.config.good.js +0 -40
  93. package/build/test/fixtures/config/appium.config.good.json +0 -33
  94. package/build/test/fixtures/config/appium.config.good.yaml +0 -30
  95. package/build/test/fixtures/config/appium.config.invalid.json +0 -31
  96. package/build/test/fixtures/config/appium.config.security-array.json +0 -5
  97. package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
  98. package/build/test/fixtures/config/appium.config.security-path.json +0 -5
  99. package/build/test/fixtures/config/driver-fake.config.json +0 -8
  100. package/build/test/fixtures/config/nodeconfig.json +0 -3
  101. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  102. package/build/test/fixtures/default-args.js +0 -35
  103. package/build/test/fixtures/deny-feat.txt +0 -5
  104. package/build/test/fixtures/driver.schema.js +0 -20
  105. package/build/test/fixtures/extensions.yaml +0 -27
  106. package/build/test/fixtures/flattened-schema.js +0 -504
  107. package/build/test/fixtures/plugin.schema.js +0 -20
  108. package/build/test/fixtures/schema-with-extensions.js +0 -28
  109. package/build/test/grid-register-specs.js +0 -74
  110. package/build/test/helpers.js +0 -75
  111. package/build/test/logger-specs.js +0 -76
  112. package/build/test/npm-specs.js +0 -20
  113. package/build/test/parser-specs.js +0 -314
  114. package/build/test/plugin-e2e-specs.js +0 -316
  115. package/build/test/schema/arg-spec-specs.js +0 -70
  116. package/build/test/schema/cli-args-specs.js +0 -431
  117. package/build/test/schema/schema-specs.js +0 -389
  118. package/build/test/utils-specs.js +0 -266
  119. package/lib/cli/npm.js +0 -251
  120. package/lib/driver-config.js +0 -101
  121. package/lib/drivers.js +0 -84
  122. package/lib/ext-config-io.js +0 -287
  123. package/lib/extension-config.js +0 -366
  124. package/lib/plugin-config.js +0 -63
  125. package/lib/plugins.js +0 -11
@@ -1,321 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- require("source-map-support/register");
6
-
7
- var _appium = require("../lib/appium");
8
-
9
- var _baseDriver = require("@appium/base-driver");
10
-
11
- var _fakeDriver = require("@appium/fake-driver");
12
-
13
- var _helpers = require("./helpers");
14
-
15
- var _schema = require("../lib/schema/schema");
16
-
17
- var _lodash = _interopRequireDefault(require("lodash"));
18
-
19
- var _sinon = _interopRequireDefault(require("sinon"));
20
-
21
- var _asyncbox = require("asyncbox");
22
-
23
- var _utils = require("../lib/utils");
24
-
25
- const SESSION_ID = 1;
26
- describe('AppiumDriver', function () {
27
- beforeEach(function () {
28
- (0, _schema.resetSchema)();
29
- });
30
- describe('AppiumDriver', function () {
31
- function getDriverAndFakeDriver(appiumArgs = {}, DriverClass = _fakeDriver.FakeDriver) {
32
- const appium = new _appium.AppiumDriver(appiumArgs);
33
- const fakeDriver = new DriverClass();
34
-
35
- const mockFakeDriver = _sinon.default.mock(fakeDriver);
36
-
37
- mockFakeDriver._fakeDriver = fakeDriver;
38
-
39
- const mockedDriverReturnerClass = function Driver() {
40
- return fakeDriver;
41
- };
42
-
43
- appium._findMatchingDriver = function () {
44
- return {
45
- driver: mockedDriverReturnerClass,
46
- version: '1.2.3',
47
- driverName: 'fake'
48
- };
49
- };
50
-
51
- return [appium, mockFakeDriver];
52
- }
53
-
54
- describe('createSession', function () {
55
- let appium;
56
- let mockFakeDriver;
57
- beforeEach(function () {
58
- [appium, mockFakeDriver] = getDriverAndFakeDriver();
59
- });
60
- afterEach(async function () {
61
- mockFakeDriver.restore();
62
- await appium.deleteSession(SESSION_ID);
63
- });
64
- it(`should call inner driver's createSession with desired capabilities`, async function () {
65
- mockFakeDriver.expects('createSession').once().withExactArgs(null, null, _helpers.W3C_CAPS, []).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
66
- await appium.createSession(null, null, _helpers.W3C_CAPS);
67
- mockFakeDriver.verify();
68
- });
69
- it(`should call inner driver's createSession with desired and default capabilities`, async function () {
70
- let defaultCaps = {
71
- 'appium:someCap': 'hello'
72
- };
73
- let allCaps = { ..._helpers.W3C_CAPS,
74
- alwaysMatch: { ..._helpers.W3C_CAPS.alwaysMatch,
75
- ...defaultCaps
76
- }
77
- };
78
- appium.args.defaultCapabilities = defaultCaps;
79
- mockFakeDriver.expects('createSession').once().withArgs(null, null, allCaps).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(allCaps.alwaysMatch)]);
80
- await appium.createSession(null, null, _helpers.W3C_CAPS);
81
- mockFakeDriver.verify();
82
- });
83
- it(`should call inner driver's createSession with desired and default capabilities without overriding caps`, async function () {
84
- let defaultCaps = {
85
- platformName: 'Ersatz'
86
- };
87
- appium.args.defaultCapabilities = defaultCaps;
88
- mockFakeDriver.expects('createSession').once().withArgs(null, null, _helpers.W3C_CAPS).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
89
- await appium.createSession(null, null, _helpers.W3C_CAPS);
90
- mockFakeDriver.verify();
91
- });
92
- it('should kill all other sessions if sessionOverride is on', async function () {
93
- appium.args.sessionOverride = true;
94
- let fakeDrivers = [new _fakeDriver.FakeDriver(), new _fakeDriver.FakeDriver(), new _fakeDriver.FakeDriver()];
95
-
96
- let mockFakeDrivers = _lodash.default.map(fakeDrivers, fd => _sinon.default.mock(fd));
97
-
98
- mockFakeDrivers[0].expects('deleteSession').once();
99
- mockFakeDrivers[1].expects('deleteSession').once().throws('Cannot shut down Android driver; it has already shut down');
100
- mockFakeDrivers[2].expects('deleteSession').once();
101
- appium.sessions['abc-123-xyz'] = fakeDrivers[0];
102
- appium.sessions['xyz-321-abc'] = fakeDrivers[1];
103
- appium.sessions['123-abc-xyz'] = fakeDrivers[2];
104
- let sessions = await appium.getSessions();
105
- sessions.should.have.length(3);
106
- mockFakeDriver.expects('createSession').once().withExactArgs(null, null, _helpers.W3C_CAPS, []).returns([SESSION_ID, (0, _utils.removeAppiumPrefixes)(_helpers.W3C_PREFIXED_CAPS)]);
107
- await appium.createSession(null, null, _helpers.W3C_CAPS);
108
- sessions = await appium.getSessions();
109
- sessions.should.have.length(1);
110
-
111
- for (let mfd of mockFakeDrivers) {
112
- mfd.verify();
113
- }
114
-
115
- mockFakeDriver.verify();
116
- });
117
- it('should call "createSession" with W3C capabilities argument, if provided', async function () {
118
- mockFakeDriver.expects('createSession').once().withArgs(null, undefined, _helpers.W3C_CAPS).returns([SESSION_ID, _helpers.BASE_CAPS]);
119
- await appium.createSession(undefined, undefined, _helpers.W3C_CAPS);
120
- mockFakeDriver.verify();
121
- });
122
- it('should call "createSession" with W3C capabilities argument with additional provided parameters', async function () {
123
- let w3cCaps = { ..._helpers.W3C_CAPS,
124
- alwaysMatch: { ..._helpers.W3C_CAPS.alwaysMatch,
125
- 'appium:someOtherParm': 'someOtherParm'
126
- }
127
- };
128
- mockFakeDriver.expects('createSession').once().withArgs(null, undefined, {
129
- alwaysMatch: { ...w3cCaps.alwaysMatch,
130
- 'appium:someOtherParm': 'someOtherParm'
131
- },
132
- firstMatch: [{}]
133
- }).returns([SESSION_ID, (0, _utils.insertAppiumPrefixes)(_helpers.BASE_CAPS)]);
134
- await appium.createSession(undefined, undefined, w3cCaps);
135
- mockFakeDriver.verify();
136
- });
137
- it('should not call "createSession" with JSONWP capabilities if W3C has incomplete capabilities', async function () {
138
- const w3cCaps = { ..._helpers.W3C_CAPS,
139
- alwaysMatch: {
140
- 'appium:someOtherParm': 'someOtherParm'
141
- }
142
- };
143
- const jsonwpCaps = { ..._helpers.BASE_CAPS,
144
- automationName: 'Fake',
145
- someOtherParam: 'someOtherParam'
146
- };
147
- mockFakeDriver.expects('createSession').never();
148
- await appium.createSession(jsonwpCaps, undefined, w3cCaps);
149
- mockFakeDriver.verify();
150
- });
151
- it('should assign args to property `cliArgs`', async function () {
152
- class ArgsDriver extends _baseDriver.BaseDriver {}
153
-
154
- const args = {
155
- driver: {
156
- fake: {
157
- randomArg: 1234
158
- }
159
- }
160
- };
161
- [appium, mockFakeDriver] = getDriverAndFakeDriver(args, ArgsDriver);
162
- const {
163
- value
164
- } = await appium.createSession(undefined, undefined, _helpers.W3C_CAPS);
165
-
166
- try {
167
- mockFakeDriver._fakeDriver.cliArgs.should.eql({
168
- randomArg: 1234
169
- });
170
- } finally {
171
- await appium.deleteSession(value[0]);
172
- }
173
- });
174
- });
175
- describe('deleteSession', function () {
176
- let appium;
177
- let mockFakeDriver;
178
- beforeEach(function () {
179
- [appium, mockFakeDriver] = getDriverAndFakeDriver();
180
- });
181
- afterEach(function () {
182
- mockFakeDriver.restore();
183
- });
184
- it('should remove the session if it is found', async function () {
185
- let [sessionId] = (await appium.createSession(null, null, _helpers.W3C_CAPS)).value;
186
- let sessions = await appium.getSessions();
187
- sessions.should.have.length(1);
188
- await appium.deleteSession(sessionId);
189
- sessions = await appium.getSessions();
190
- sessions.should.have.length(0);
191
- });
192
- it('should call inner driver\'s deleteSession method', async function () {
193
- const [sessionId] = (await appium.createSession(null, null, _helpers.W3C_CAPS)).value;
194
- mockFakeDriver.expects('deleteSession').once().withExactArgs(sessionId, []).returns();
195
- await appium.deleteSession(sessionId);
196
- mockFakeDriver.verify();
197
- await mockFakeDriver.object.deleteSession();
198
- });
199
- });
200
- describe('getSessions', function () {
201
- let appium, mockFakeDriver;
202
- let sessions;
203
- before(function () {
204
- [appium, mockFakeDriver] = getDriverAndFakeDriver();
205
- });
206
- afterEach(async function () {
207
- for (let session of sessions) {
208
- await appium.deleteSession(session.id);
209
- }
210
-
211
- mockFakeDriver.restore();
212
- });
213
- it('should return an empty array of sessions', async function () {
214
- sessions = await appium.getSessions();
215
- sessions.should.be.an('array');
216
- sessions.should.be.empty;
217
- });
218
- it('should return sessions created', async function () {
219
- let caps1 = {
220
- alwaysMatch: { ..._helpers.W3C_PREFIXED_CAPS,
221
- 'appium:cap': 'value'
222
- }
223
- };
224
- let caps2 = {
225
- alwaysMatch: { ..._helpers.W3C_PREFIXED_CAPS,
226
- 'appium:cap': 'other value'
227
- }
228
- };
229
- mockFakeDriver.expects('createSession').once().returns(['fake-session-id-1', (0, _utils.removeAppiumPrefixes)(caps1.alwaysMatch)]);
230
- let [session1Id, session1Caps] = (await appium.createSession(null, null, caps1)).value;
231
- mockFakeDriver.expects('createSession').once().returns(['fake-session-id-2', (0, _utils.removeAppiumPrefixes)(caps2.alwaysMatch)]);
232
- let [session2Id, session2Caps] = (await appium.createSession(null, null, caps2)).value;
233
- sessions = await appium.getSessions();
234
- sessions.should.be.an('array');
235
- sessions.should.have.length(2);
236
- sessions[0].id.should.equal(session1Id);
237
- (0, _utils.removeAppiumPrefixes)(caps1.alwaysMatch).should.eql(session1Caps);
238
- sessions[1].id.should.equal(session2Id);
239
- (0, _utils.removeAppiumPrefixes)(caps2.alwaysMatch).should.eql(session2Caps);
240
- });
241
- });
242
- describe('getStatus', function () {
243
- let appium;
244
- before(function () {
245
- appium = new _appium.AppiumDriver({});
246
- });
247
- it('should return a status', async function () {
248
- let status = await appium.getStatus();
249
- status.build.should.exist;
250
- status.build.version.should.exist;
251
- });
252
- });
253
- describe('sessionExists', function () {});
254
- describe('attachUnexpectedShutdownHandler', function () {
255
- let appium;
256
- let mockFakeDriver;
257
- beforeEach(function () {
258
- [appium, mockFakeDriver] = getDriverAndFakeDriver();
259
- });
260
- afterEach(async function () {
261
- await mockFakeDriver.object.deleteSession();
262
- mockFakeDriver.restore();
263
- appium.args.defaultCapabilities = {};
264
- });
265
- it('should remove session if inner driver unexpectedly exits with an error', async function () {
266
- let [sessionId] = (await appium.createSession(null, null, _lodash.default.clone(_helpers.W3C_CAPS))).value;
267
-
268
- _lodash.default.keys(appium.sessions).should.contain(sessionId);
269
-
270
- appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown', new Error('Oops'));
271
- await (0, _asyncbox.sleep)(1);
272
-
273
- _lodash.default.keys(appium.sessions).should.not.contain(sessionId);
274
- });
275
- it('should remove session if inner driver unexpectedly exits with no error', async function () {
276
- let [sessionId] = (await appium.createSession(null, null, _lodash.default.clone(_helpers.W3C_CAPS))).value;
277
-
278
- _lodash.default.keys(appium.sessions).should.contain(sessionId);
279
-
280
- appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown');
281
- await (0, _asyncbox.sleep)(1);
282
-
283
- _lodash.default.keys(appium.sessions).should.not.contain(sessionId);
284
- });
285
- });
286
- });
287
- describe('#createPluginInstances', function () {
288
- class NoArgsPlugin {}
289
-
290
- NoArgsPlugin.pluginName = 'noargs';
291
-
292
- class ArgsPlugin {}
293
-
294
- ArgsPlugin.pluginName = 'args';
295
- it('should not set CLI args if none are sent', function () {
296
- const appium = new _appium.AppiumDriver({});
297
- appium.pluginClasses = [NoArgsPlugin, ArgsPlugin];
298
-
299
- for (const plugin of appium.createPluginInstances()) {
300
- should.not.exist(plugin.cliArgs);
301
- }
302
- });
303
- it('should add cliArgs to the plugin once validated', function () {
304
- const appium = new _appium.AppiumDriver({
305
- plugin: {
306
- args: {
307
- randomArg: 1234
308
- }
309
- }
310
- });
311
- appium.pluginClasses = [ArgsPlugin];
312
- const plugin = appium.createPluginInstances()[0];
313
- plugin.cliArgs.should.eql({
314
- randomArg: 1234
315
- });
316
- });
317
- });
318
- });require('source-map-support').install();
319
-
320
-
321
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZHJpdmVyLXNwZWNzLmpzIl0sIm5hbWVzIjpbIlNFU1NJT05fSUQiLCJkZXNjcmliZSIsImJlZm9yZUVhY2giLCJnZXREcml2ZXJBbmRGYWtlRHJpdmVyIiwiYXBwaXVtQXJncyIsIkRyaXZlckNsYXNzIiwiRmFrZURyaXZlciIsImFwcGl1bSIsIkFwcGl1bURyaXZlciIsImZha2VEcml2ZXIiLCJtb2NrRmFrZURyaXZlciIsInNpbm9uIiwibW9jayIsIl9mYWtlRHJpdmVyIiwibW9ja2VkRHJpdmVyUmV0dXJuZXJDbGFzcyIsIkRyaXZlciIsIl9maW5kTWF0Y2hpbmdEcml2ZXIiLCJkcml2ZXIiLCJ2ZXJzaW9uIiwiZHJpdmVyTmFtZSIsImFmdGVyRWFjaCIsInJlc3RvcmUiLCJkZWxldGVTZXNzaW9uIiwiaXQiLCJleHBlY3RzIiwib25jZSIsIndpdGhFeGFjdEFyZ3MiLCJXM0NfQ0FQUyIsInJldHVybnMiLCJXM0NfUFJFRklYRURfQ0FQUyIsImNyZWF0ZVNlc3Npb24iLCJ2ZXJpZnkiLCJkZWZhdWx0Q2FwcyIsImFsbENhcHMiLCJhbHdheXNNYXRjaCIsImFyZ3MiLCJkZWZhdWx0Q2FwYWJpbGl0aWVzIiwid2l0aEFyZ3MiLCJwbGF0Zm9ybU5hbWUiLCJzZXNzaW9uT3ZlcnJpZGUiLCJmYWtlRHJpdmVycyIsIm1vY2tGYWtlRHJpdmVycyIsIl8iLCJtYXAiLCJmZCIsInRocm93cyIsInNlc3Npb25zIiwiZ2V0U2Vzc2lvbnMiLCJzaG91bGQiLCJoYXZlIiwibGVuZ3RoIiwibWZkIiwidW5kZWZpbmVkIiwiQkFTRV9DQVBTIiwidzNjQ2FwcyIsImZpcnN0TWF0Y2giLCJqc29ud3BDYXBzIiwiYXV0b21hdGlvbk5hbWUiLCJzb21lT3RoZXJQYXJhbSIsIm5ldmVyIiwiQXJnc0RyaXZlciIsIkJhc2VEcml2ZXIiLCJmYWtlIiwicmFuZG9tQXJnIiwidmFsdWUiLCJjbGlBcmdzIiwiZXFsIiwic2Vzc2lvbklkIiwib2JqZWN0IiwiYmVmb3JlIiwic2Vzc2lvbiIsImlkIiwiYmUiLCJhbiIsImVtcHR5IiwiY2FwczEiLCJjYXBzMiIsInNlc3Npb24xSWQiLCJzZXNzaW9uMUNhcHMiLCJzZXNzaW9uMklkIiwic2Vzc2lvbjJDYXBzIiwiZXF1YWwiLCJzdGF0dXMiLCJnZXRTdGF0dXMiLCJidWlsZCIsImV4aXN0IiwiY2xvbmUiLCJrZXlzIiwiY29udGFpbiIsImV2ZW50RW1pdHRlciIsImVtaXQiLCJFcnJvciIsIm5vdCIsIk5vQXJnc1BsdWdpbiIsInBsdWdpbk5hbWUiLCJBcmdzUGx1Z2luIiwicGx1Z2luQ2xhc3NlcyIsInBsdWdpbiIsImNyZWF0ZVBsdWdpbkluc3RhbmNlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsTUFBTUEsVUFBVSxHQUFHLENBQW5CO0FBRUFDLFFBQVEsQ0FBQyxjQUFELEVBQWlCLFlBQVk7QUFDbkNDLEVBQUFBLFVBQVUsQ0FBQyxZQUFZO0FBQ3JCO0FBQ0QsR0FGUyxDQUFWO0FBR0FELEVBQUFBLFFBQVEsQ0FBQyxjQUFELEVBQWlCLFlBQVk7QUFDbkMsYUFBU0Usc0JBQVQsQ0FBaUNDLFVBQVUsR0FBRyxFQUE5QyxFQUFrREMsV0FBVyxHQUFHQyxzQkFBaEUsRUFBNEU7QUFDMUUsWUFBTUMsTUFBTSxHQUFHLElBQUlDLG9CQUFKLENBQWlCSixVQUFqQixDQUFmO0FBQ0EsWUFBTUssVUFBVSxHQUFHLElBQUlKLFdBQUosRUFBbkI7O0FBQ0EsWUFBTUssY0FBYyxHQUFHQyxlQUFNQyxJQUFOLENBQVdILFVBQVgsQ0FBdkI7O0FBQ0FDLE1BQUFBLGNBQWMsQ0FBQ0csV0FBZixHQUE2QkosVUFBN0I7O0FBQ0EsWUFBTUsseUJBQXlCLEdBQUcsU0FBU0MsTUFBVCxHQUFtQjtBQUNuRCxlQUFPTixVQUFQO0FBQ0QsT0FGRDs7QUFJQUYsTUFBQUEsTUFBTSxDQUFDUyxtQkFBUCxHQUE2QixZQUFZO0FBQ3ZDLGVBQU87QUFDTEMs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RUFBRSxDQUFDLDBDQUFELEVBQTZDLFlBQVk7QUFDekQsWUFBTWhCLE1BQU0sR0FBRyxJQUFJQyxvQkFBSixDQUFpQixFQUFqQixDQUFmO0FBQ0FELE1BQUFBLE1BQU0sQ0FBQ3lGLGFBQVAsR0FBdUIsQ0FBQ0gsWUFBRCxFQUFlRSxVQUFmLENBQXZCOztBQUNBLFdBQUssTUFBTUUsTUFBWCxJQUFxQjFGLE1BQU0sQ0FBQzJGLHFCQUFQLEVBQXJCLEVBQXFEO0FBQ25EbEQsUUFBQUEsTUFBTSxDQUFDNEMsR0FBUCxDQUFXUCxLQUFYLENBQWlCWSxNQUFNLENBQUNoQyxPQUF4QjtBQUNEO0FBQ0YsS0FOQyxDQUFGO0FBT0ExQyxJQUFBQSxFQUFFLENBQUMsaURBQUQsRUFBb0QsWUFBWTtBQUNoRSxZQUFNaEIsTUFBTSxHQUFHLElBQUlDLG9CQUFKLENBQWlCO0FBQUN5RixRQUFBQSxNQUFNLEVBQUU7QUFBQzlELFVBQUFBLElBQUksRUFBRTtBQUFDNEIsWUFBQUEsU0FBUyxFQUFFO0FBQVo7QUFBUDtBQUFULE9BQWpCLENBQWY7QUFDQXhELE1BQUFBLE1BQU0sQ0FBQ3lGLGFBQVAsR0FBdUIsQ0FBQ0QsVUFBRCxDQUF2QjtBQUNBLFlBQU1FLE1BQU0sR0FBRzFGLE1BQU0sQ0FBQzJGLHFCQUFQLEdBQStCLENBQS9CLENBQWY7QUFDQUQsTUFBQUEsTUFBTSxDQUFDaEMsT0FBUCxDQUFlakIsTUFBZixDQUFzQmtCLEdBQXRCLENBQTBCO0FBQUNILFFBQUFBLFNBQVMsRUFBRTtBQUFaLE9BQTFCO0FBQ0QsS0FMQyxDQUFGO0FBTUQsR0FwQk8sQ0FBUjtBQXFCRCxDQWhTTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1vY2hhXG5cbmltcG9ydCB7IEFwcGl1bURyaXZlciB9IGZyb20gJy4uL2xpYi9hcHBpdW0nO1xuaW1wb3J0IHsgQmFzZURyaXZlciB9IGZyb20gJ0BhcHBpdW0vYmFzZS1kcml2ZXInO1xuaW1wb3J0IHsgRmFrZURyaXZlciB9IGZyb20gJ0BhcHBpdW0vZmFrZS1kcml2ZXInO1xuaW1wb3J0IHsgQkFTRV9DQVBTLCBXM0NfQ0FQUywgVzNDX1BSRUZJWEVEX0NBUFMgfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHtyZXNldFNjaGVtYX0gZnJvbSAnLi4vbGliL3NjaGVtYS9zY2hlbWEnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IGluc2VydEFwcGl1bVByZWZpeGVzLCByZW1vdmVBcHBpdW1QcmVmaXhlcyB9IGZyb20gJy4uL2xpYi91dGlscyc7XG5cblxuY29uc3QgU0VTU0lPTl9JRCA9IDE7XG5cbmRlc2NyaWJlKCdBcHBpdW1Ecml2ZXInLCBmdW5jdGlvbiAoKSB7XG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHJlc2V0U2NoZW1hKCk7XG4gIH0pO1xuICBkZXNjcmliZSgnQXBwaXVtRHJpdmVyJywgZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIGdldERyaXZlckFuZEZha2VEcml2ZXIgKGFwcGl1bUFyZ3MgPSB7fSwgRHJpdmVyQ2xhc3MgPSBGYWtlRHJpdmVyKSB7XG4gICAgICBjb25zdCBhcHBpdW0gPSBuZXcgQXBwaXVtRHJpdmVyKGFwcGl1bUFyZ3MpO1xuICAgICAgY29uc3QgZmFrZURyaXZlciA9IG5ldyBEcml2ZXJDbGFzcygpO1xuICAgICAgY29uc3QgbW9ja0Zha2VEcml2ZXIgPSBzaW5vbi5tb2NrKGZha2VEcml2ZXIpO1xuICAgICAgbW9ja0Zha2VEcml2ZXIuX2Zha2VEcml2ZXIgPSBmYWtlRHJpdmVyO1xuICAgICAgY29uc3QgbW9ja2VkRHJpdmVyUmV0dXJuZXJDbGFzcyA9IGZ1bmN0aW9uIERyaXZlciAoKSB7XG4gICAgICAgIHJldHVybiBmYWtlRHJpdmVyO1xuICAgICAgfTtcblxuICAgICAgYXBwaXVtLl9maW5kTWF0Y2hpbmdEcml2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZHJpdmVyOiBtb2NrZWREcml2ZXJSZXR1cm5lckNsYXNzLFxuICAgICAgICAgIHZlcnNpb246ICcxLjIuMycsXG4gICAgICAgICAgZHJpdmVyTmFtZTogJ2Zha2UnLFxuICAgICAgICB9O1xuICAgICAgfTtcbiAgICAgIHJldHVybiBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl07XG4gICAgfVxuICAgIGRlc2NyaWJlKCdjcmVhdGVTZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGFwcGl1bTtcbiAgICAgIGxldCBtb2NrRmFrZURyaXZlcjtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl0gPSBnZXREcml2ZXJBbmRGYWtlRHJpdmVyKCk7XG4gICAgICB9KTtcbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnJlc3RvcmUoKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmRlbGV0ZVNlc3Npb24oU0VTU0lPTl9JRCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjYWxsIGlubmVyIGRyaXZlcidzIGNyZWF0ZVNlc3Npb24gd2l0aCBkZXNpcmVkIGNhcGFiaWxpdGllc2AsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoRXhhY3RBcmdzKG51bGwsIG51bGwsIFczQ19DQVBTLCBbXSlcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoVzNDX1BSRUZJWEVEX0NBUFMpXSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KGBzaG91bGQgY2FsbCBpbm5lciBkcml2ZXIncyBjcmVhdGVTZXNzaW9uIHdpdGggZGVzaXJlZCBhbmQgZGVmYXVsdCBjYXBhYmlsaXRpZXNgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBkZWZhdWx0Q2FwcyA9IHsnYXBwaXVtOnNvbWVDYXAnOiAnaGVsbG8nfTtcbiAgICAgICAgbGV0IGFsbENhcHMgPSB7Li4uVzNDX0NBUFMsIGFsd2F5c01hdGNoOiB7Li4uVzNDX0NBUFMuYWx3YXlzTWF0Y2gsIC4uLmRlZmF1bHRDYXBzfX07XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSBkZWZhdWx0Q2FwcztcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCBudWxsLCBhbGxDYXBzKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCByZW1vdmVBcHBpdW1QcmVmaXhlcyhhbGxDYXBzLmFsd2F5c01hdGNoKV0pO1xuICAgICAgICBhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBXM0NfQ0FQUyk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG4gICAgICBpdChgc2hvdWxkIGNhbGwgaW5uZXIgZHJpdmVyJ3MgY3JlYXRlU2Vzc2lvbiB3aXRoIGRlc2lyZWQgYW5kIGRlZmF1bHQgY2FwYWJpbGl0aWVzIHdpdGhvdXQgb3ZlcnJpZGluZyBjYXBzYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBhIGRlZmF1bHQgY2FwYWJpbGl0eSB3aXRoIHRoZSBzYW1lIGtleSBhcyBhIGRlc2lyZWQgY2FwYWJpbGl0eVxuICAgICAgICAvLyBzaG91bGQgZG8gbm90aGluZ1xuICAgICAgICBsZXQgZGVmYXVsdENhcHMgPSB7cGxhdGZvcm1OYW1lOiAnRXJzYXR6J307XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSBkZWZhdWx0Q2FwcztcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCBudWxsLCBXM0NfQ0FQUylcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoVzNDX1BSRUZJWEVEX0NBUFMpXSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQga2lsbCBhbGwgb3RoZXIgc2Vzc2lvbnMgaWYgc2Vzc2lvbk92ZXJyaWRlIGlzIG9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhcHBpdW0uYXJncy5zZXNzaW9uT3ZlcnJpZGUgPSB0cnVlO1xuXG4gICAgICAgIC8vIG1vY2sgdGhyZWUgc2Vzc2lvbnMgdGhhdCBzaG91bGQgYmUgcmVtb3ZlZCB3aGVuIHRoZSBuZXcgb25lIGlzIGNyZWF0ZWRcbiAgICAgICAgbGV0IGZha2VEcml2ZXJzID0gW1xuICAgICAgICAgIG5ldyBGYWtlRHJpdmVyKCksXG4gICAgICAgICAgbmV3IEZha2VEcml2ZXIoKSxcbiAgICAgICAgICBuZXcgRmFrZURyaXZlcigpLFxuICAgICAgICBdO1xuICAgICAgICBsZXQgbW9ja0Zha2VEcml2ZXJzID0gXy5tYXAoZmFrZURyaXZlcnMsIChmZCkgPT4gc2lub24ubW9jayhmZCkpO1xuICAgICAgICBtb2NrRmFrZURyaXZlcnNbMF0uZXhwZWN0cygnZGVsZXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXJzWzFdLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKClcbiAgICAgICAgICAudGhyb3dzKCdDYW5ub3Qgc2h1dCBkb3duIEFuZHJvaWQgZHJpdmVyOyBpdCBoYXMgYWxyZWFkeSBzaHV0IGRvd24nKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXJzWzJdLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKCk7XG4gICAgICAgIGFwcGl1bS5zZXNzaW9uc1snYWJjLTEyMy14eXonXSA9IGZha2VEcml2ZXJzWzBdO1xuICAgICAgICBhcHBpdW0uc2Vzc2lvbnNbJ3h5ei0zMjEtYWJjJ10gPSBmYWtlRHJpdmVyc1sxXTtcbiAgICAgICAgYXBwaXVtLnNlc3Npb25zWycxMjMtYWJjLXh5eiddID0gZmFrZURyaXZlcnNbMl07XG5cbiAgICAgICAgbGV0IHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgzKTtcblxuICAgICAgICBtb2NrRmFrZURyaXZlci5leHBlY3RzKCdjcmVhdGVTZXNzaW9uJylcbiAgICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MobnVsbCwgbnVsbCwgVzNDX0NBUFMsIFtdKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCByZW1vdmVBcHBpdW1QcmVmaXhlcyhXM0NfUFJFRklYRURfQ0FQUyldKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24obnVsbCwgbnVsbCwgVzNDX0NBUFMpO1xuXG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcblxuICAgICAgICBmb3IgKGxldCBtZmQgb2YgbW9ja0Zha2VEcml2ZXJzKSB7XG4gICAgICAgICAgbWZkLnZlcmlmeSgpO1xuICAgICAgICB9XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGNhbGwgXCJjcmVhdGVTZXNzaW9uXCIgd2l0aCBXM0MgY2FwYWJpbGl0aWVzIGFyZ3VtZW50LCBpZiBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpXG4gICAgICAgICAgLm9uY2UoKS53aXRoQXJncyhudWxsLCB1bmRlZmluZWQsIFczQ19DQVBTKVxuICAgICAgICAgIC5yZXR1cm5zKFtTRVNTSU9OX0lELCBCQVNFX0NBUFNdKTtcbiAgICAgICAgYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24odW5kZWZpbmVkLCB1bmRlZmluZWQsIFczQ19DQVBTKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgY2FsbCBcImNyZWF0ZVNlc3Npb25cIiB3aXRoIFczQyBjYXBhYmlsaXRpZXMgYXJndW1lbnQgd2l0aCBhZGRpdGlvbmFsIHByb3ZpZGVkIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCB3M2NDYXBzID0ge1xuICAgICAgICAgIC4uLlczQ19DQVBTLFxuICAgICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgICAuLi5XM0NfQ0FQUy5hbHdheXNNYXRjaCxcbiAgICAgICAgICAgICdhcHBpdW06c29tZU90aGVyUGFybSc6ICdzb21lT3RoZXJQYXJtJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBtb2NrRmFrZURyaXZlci5leHBlY3RzKCdjcmVhdGVTZXNzaW9uJylcbiAgICAgICAgICAub25jZSgpLndpdGhBcmdzKG51bGwsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAgICAgLi4udzNjQ2Fwcy5hbHdheXNNYXRjaCxcbiAgICAgICAgICAgICAgJ2FwcGl1bTpzb21lT3RoZXJQYXJtJzogJ3NvbWVPdGhlclBhcm0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmV0dXJucyhbU0VTU0lPTl9JRCwgaW5zZXJ0QXBwaXVtUHJlZml4ZXMoQkFTRV9DQVBTKV0pO1xuXG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB3M2NDYXBzKTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIudmVyaWZ5KCk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgbm90IGNhbGwgXCJjcmVhdGVTZXNzaW9uXCIgd2l0aCBKU09OV1AgY2FwYWJpbGl0aWVzIGlmIFczQyBoYXMgaW5jb21wbGV0ZSBjYXBhYmlsaXRpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHczY0NhcHMgPSB7XG4gICAgICAgICAgLi4uVzNDX0NBUFMsXG4gICAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAgICdhcHBpdW06c29tZU90aGVyUGFybSc6ICdzb21lT3RoZXJQYXJtJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGpzb253cENhcHMgPSB7XG4gICAgICAgICAgLi4uQkFTRV9DQVBTLFxuICAgICAgICAgIGF1dG9tYXRpb25OYW1lOiAnRmFrZScsXG4gICAgICAgICAgc29tZU90aGVyUGFyYW06ICdzb21lT3RoZXJQYXJhbScsXG4gICAgICAgIH07XG5cbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpLm5ldmVyKCk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKGpzb253cENhcHMsIHVuZGVmaW5lZCwgdzNjQ2Fwcyk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYXNzaWduIGFyZ3MgdG8gcHJvcGVydHkgYGNsaUFyZ3NgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGFzcyBBcmdzRHJpdmVyIGV4dGVuZHMgQmFzZURyaXZlciB7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXJncyA9IHtkcml2ZXI6IHtmYWtlOiB7cmFuZG9tQXJnOiAxMjM0fX19O1xuICAgICAgICBbYXBwaXVtLCBtb2NrRmFrZURyaXZlcl0gPSBnZXREcml2ZXJBbmRGYWtlRHJpdmVyKGFyZ3MsIEFyZ3NEcml2ZXIpO1xuICAgICAgICBjb25zdCB7dmFsdWV9ID0gYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24odW5kZWZpbmVkLCB1bmRlZmluZWQsIFczQ19DQVBTKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtb2NrRmFrZURyaXZlci5fZmFrZURyaXZlci5jbGlBcmdzLnNob3VsZC5lcWwoe3JhbmRvbUFyZzogMTIzNH0pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHZhbHVlWzBdKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJ2RlbGV0ZVNlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtO1xuICAgICAgbGV0IG1vY2tGYWtlRHJpdmVyO1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIFthcHBpdW0sIG1vY2tGYWtlRHJpdmVyXSA9IGdldERyaXZlckFuZEZha2VEcml2ZXIoKTtcbiAgICAgIH0pO1xuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIucmVzdG9yZSgpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSB0aGUgc2Vzc2lvbiBpZiBpdCBpcyBmb3VuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IFtzZXNzaW9uSWRdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKSkudmFsdWU7XG4gICAgICAgIGxldCBzZXNzaW9ucyA9IGF3YWl0IGFwcGl1bS5nZXRTZXNzaW9ucygpO1xuICAgICAgICBzZXNzaW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5oYXZlLmxlbmd0aCgwKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBjYWxsIGlubmVyIGRyaXZlclxcJ3MgZGVsZXRlU2Vzc2lvbiBtZXRob2QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IFtzZXNzaW9uSWRdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIFczQ19DQVBTKSkudmFsdWU7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLmV4cGVjdHMoJ2RlbGV0ZVNlc3Npb24nKVxuICAgICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhzZXNzaW9uSWQsIFtdKVxuICAgICAgICAgIC5yZXR1cm5zKCk7XG4gICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnZlcmlmeSgpO1xuXG4gICAgICAgIC8vIGNsZWFudXAsIHNpbmNlIHdlIGZha2VkIHRoZSBkZWxldGUgc2Vzc2lvbiBjYWxsXG4gICAgICAgIGF3YWl0IG1vY2tGYWtlRHJpdmVyLm9iamVjdC5kZWxldGVTZXNzaW9uKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnZ2V0U2Vzc2lvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtLCBtb2NrRmFrZURyaXZlcjtcbiAgICAgIGxldCBzZXNzaW9ucztcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIFthcHBpdW0sIG1vY2tGYWtlRHJpdmVyXSA9IGdldERyaXZlckFuZEZha2VEcml2ZXIoKTtcbiAgICAgIH0pO1xuICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yIChsZXQgc2Vzc2lvbiBvZiBzZXNzaW9ucykge1xuICAgICAgICAgIGF3YWl0IGFwcGl1bS5kZWxldGVTZXNzaW9uKHNlc3Npb24uaWQpO1xuICAgICAgICB9XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgYXJyYXkgb2Ygc2Vzc2lvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5iZS5hbignYXJyYXknKTtcbiAgICAgICAgc2Vzc2lvbnMuc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBzZXNzaW9ucyBjcmVhdGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgY2FwczEgPSB7YWx3YXlzTWF0Y2g6IHsuLi5XM0NfUFJFRklYRURfQ0FQUywgJ2FwcGl1bTpjYXAnOiAndmFsdWUnfX07XG4gICAgICAgIGxldCBjYXBzMiA9IHthbHdheXNNYXRjaDogey4uLlczQ19QUkVGSVhFRF9DQVBTLCAnYXBwaXVtOmNhcCc6ICdvdGhlciB2YWx1ZSd9fTtcbiAgICAgICAgbW9ja0Zha2VEcml2ZXIuZXhwZWN0cygnY3JlYXRlU2Vzc2lvbicpLm9uY2UoKVxuICAgICAgICAgIC5yZXR1cm5zKFsnZmFrZS1zZXNzaW9uLWlkLTEnLCByZW1vdmVBcHBpdW1QcmVmaXhlcyhjYXBzMS5hbHdheXNNYXRjaCldKTtcbiAgICAgICAgbGV0IFtzZXNzaW9uMUlkLCBzZXNzaW9uMUNhcHNdID0gKGF3YWl0IGFwcGl1bS5jcmVhdGVTZXNzaW9uKG51bGwsIG51bGwsIGNhcHMxKSkudmFsdWU7XG4gICAgICAgIG1vY2tGYWtlRHJpdmVyLmV4cGVjdHMoJ2NyZWF0ZVNlc3Npb24nKS5vbmNlKClcbiAgICAgICAgICAucmV0dXJucyhbJ2Zha2Utc2Vzc2lvbi1pZC0yJywgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoY2FwczIuYWx3YXlzTWF0Y2gpXSk7XG4gICAgICAgIGxldCBbc2Vzc2lvbjJJZCwgc2Vzc2lvbjJDYXBzXSA9IChhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBjYXBzMikpLnZhbHVlO1xuXG4gICAgICAgIHNlc3Npb25zID0gYXdhaXQgYXBwaXVtLmdldFNlc3Npb25zKCk7XG4gICAgICAgIHNlc3Npb25zLnNob3VsZC5iZS5hbignYXJyYXknKTtcbiAgICAgICAgc2Vzc2lvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgICBzZXNzaW9uc1swXS5pZC5zaG91bGQuZXF1YWwoc2Vzc2lvbjFJZCk7XG4gICAgICAgIHJlbW92ZUFwcGl1bVByZWZpeGVzKGNhcHMxLmFsd2F5c01hdGNoKS5zaG91bGQuZXFsKHNlc3Npb24xQ2Fwcyk7XG4gICAgICAgIHNlc3Npb25zWzFdLmlkLnNob3VsZC5lcXVhbChzZXNzaW9uMklkKTtcbiAgICAgICAgcmVtb3ZlQXBwaXVtUHJlZml4ZXMoY2FwczIuYWx3YXlzTWF0Y2gpLnNob3VsZC5lcWwoc2Vzc2lvbjJDYXBzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdnZXRTdGF0dXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgYXBwaXVtO1xuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXBwaXVtID0gbmV3IEFwcGl1bURyaXZlcih7fSk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RhdHVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgc3RhdHVzID0gYXdhaXQgYXBwaXVtLmdldFN0YXR1cygpO1xuICAgICAgICBzdGF0dXMuYnVpbGQuc2hvdWxkLmV4aXN0O1xuICAgICAgICBzdGF0dXMuYnVpbGQudmVyc2lvbi5zaG91bGQuZXhpc3Q7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnc2Vzc2lvbkV4aXN0cycsIGZ1bmN0aW9uICgpIHtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBhcHBpdW07XG4gICAgICBsZXQgbW9ja0Zha2VEcml2ZXI7XG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgW2FwcGl1bSwgbW9ja0Zha2VEcml2ZXJdID0gZ2V0RHJpdmVyQW5kRmFrZURyaXZlcigpO1xuICAgICAgfSk7XG4gICAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBtb2NrRmFrZURyaXZlci5vYmplY3QuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgICBtb2NrRmFrZURyaXZlci5yZXN0b3JlKCk7XG4gICAgICAgIGFwcGl1bS5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMgPSB7fTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSBzZXNzaW9uIGlmIGlubmVyIGRyaXZlciB1bmV4cGVjdGVkbHkgZXhpdHMgd2l0aCBhbiBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IFtzZXNzaW9uSWQsXSA9IChhd2FpdCBhcHBpdW0uY3JlYXRlU2Vzc2lvbihudWxsLCBudWxsLCBfLmNsb25lKFczQ19DQVBTKSkpLnZhbHVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNvbW1hLXNwYWNpbmdcbiAgICAgICAgXy5rZXlzKGFwcGl1bS5zZXNzaW9ucykuc2hvdWxkLmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgICAgYXBwaXVtLnNlc3Npb25zW3Nlc3Npb25JZF0uZXZlbnRFbWl0dGVyLmVtaXQoJ29uVW5leHBlY3RlZFNodXRkb3duJywgbmV3IEVycm9yKCdPb3BzJykpO1xuICAgICAgICAvLyBsZXQgZXZlbnQgbG9vcCBzcGluIHNvIHJlamVjdGlvbiBpcyBoYW5kbGVkXG4gICAgICAgIGF3YWl0IHNsZWVwKDEpO1xuICAgICAgICBfLmtleXMoYXBwaXVtLnNlc3Npb25zKS5zaG91bGQubm90LmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZW1vdmUgc2Vzc2lvbiBpZiBpbm5lciBkcml2ZXIgdW5leHBlY3RlZGx5IGV4aXRzIHdpdGggbm8gZXJyb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBbc2Vzc2lvbklkLF0gPSAoYXdhaXQgYXBwaXVtLmNyZWF0ZVNlc3Npb24obnVsbCwgbnVsbCwgXy5jbG9uZShXM0NfQ0FQUykpKS52YWx1ZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb21tYS1zcGFjaW5nXG4gICAgICAgIF8ua2V5cyhhcHBpdW0uc2Vzc2lvbnMpLnNob3VsZC5jb250YWluKHNlc3Npb25JZCk7XG4gICAgICAgIGFwcGl1bS5zZXNzaW9uc1tzZXNzaW9uSWRdLmV2ZW50RW1pdHRlci5lbWl0KCdvblVuZXhwZWN0ZWRTaHV0ZG93bicpO1xuICAgICAgICAvLyBsZXQgZXZlbnQgbG9vcCBzcGluIHNvIHJlamVjdGlvbiBpcyBoYW5kbGVkXG4gICAgICAgIGF3YWl0IHNsZWVwKDEpO1xuICAgICAgICBfLmtleXMoYXBwaXVtLnNlc3Npb25zKS5zaG91bGQubm90LmNvbnRhaW4oc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJyNjcmVhdGVQbHVnaW5JbnN0YW5jZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY2xhc3MgTm9BcmdzUGx1Z2luIHt9XG4gICAgTm9BcmdzUGx1Z2luLnBsdWdpbk5hbWUgPSAnbm9hcmdzJztcblxuICAgIGNsYXNzIEFyZ3NQbHVnaW4ge31cbiAgICBBcmdzUGx1Z2luLnBsdWdpbk5hbWUgPSAnYXJncyc7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBzZXQgQ0xJIGFyZ3MgaWYgbm9uZSBhcmUgc2VudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFwcGl1bSA9IG5ldyBBcHBpdW1Ecml2ZXIoe30pO1xuICAgICAgYXBwaXVtLnBsdWdpbkNsYXNzZXMgPSBbTm9BcmdzUGx1Z2luLCBBcmdzUGx1Z2luXTtcbiAgICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIGFwcGl1bS5jcmVhdGVQbHVnaW5JbnN0YW5jZXMoKSkge1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KHBsdWdpbi5jbGlBcmdzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGFkZCBjbGlBcmdzIHRvIHRoZSBwbHVnaW4gb25jZSB2YWxpZGF0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhcHBpdW0gPSBuZXcgQXBwaXVtRHJpdmVyKHtwbHVnaW46IHthcmdzOiB7cmFuZG9tQXJnOiAxMjM0fX19KTtcbiAgICAgIGFwcGl1bS5wbHVnaW5DbGFzc2VzID0gW0FyZ3NQbHVnaW5dO1xuICAgICAgY29uc3QgcGx1Z2luID0gYXBwaXVtLmNyZWF0ZVBsdWdpbkluc3RhbmNlcygpWzBdO1xuICAgICAgcGx1Z2luLmNsaUFyZ3Muc2hvdWxkLmVxbCh7cmFuZG9tQXJnOiAxMjM0fSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvZHJpdmVyLXNwZWNzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uIn0=
@@ -1,181 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- require("source-map-support/register");
6
-
7
- var _fs = require("fs");
8
-
9
- var _path = _interopRequireDefault(require("path"));
10
-
11
- var _sinon = _interopRequireDefault(require("sinon"));
12
-
13
- var _yaml = _interopRequireDefault(require("yaml"));
14
-
15
- var _helpers = require("./helpers");
16
-
17
- const expect = chai.expect;
18
- describe('ExtensionConfigIO', function () {
19
- let sandbox;
20
- let yamlFixture;
21
- before(async function () {
22
- yamlFixture = await _fs.promises.readFile(_path.default.join(__dirname, 'fixtures', 'extensions.yaml'), 'utf8');
23
- });
24
- let getExtConfigIOInstance;
25
- let mocks;
26
- beforeEach(function () {
27
- sandbox = _sinon.default.createSandbox();
28
- mocks = {
29
- '@appium/support': {
30
- fs: {
31
- readFile: sandbox.stub().resolves(yamlFixture),
32
- writeFile: sandbox.stub().resolves(true)
33
- },
34
- mkdirp: sandbox.stub().resolves()
35
- }
36
- };
37
- getExtConfigIOInstance = _helpers.rewiremock.proxy('../lib/ext-config-io', mocks).getExtConfigIOInstance;
38
- });
39
- afterEach(function () {
40
- sandbox.restore();
41
- getExtConfigIOInstance.cache = new Map();
42
- });
43
- describe('instantiation', function () {
44
- describe('when called twice with the same `appiumHome` value', function () {
45
- it('should return the same object both times', function () {
46
- const firstInstance = getExtConfigIOInstance('/some/path');
47
- const secondInstance = getExtConfigIOInstance('/some/path');
48
- expect(firstInstance).to.equal(secondInstance);
49
- });
50
- });
51
- describe('when called twice with different `appiumHome` values', function () {
52
- it('should return different objects', function () {
53
- const firstInstance = getExtConfigIOInstance('/some/path');
54
- const secondInstance = getExtConfigIOInstance('/some/other/path');
55
- expect(firstInstance).to.not.equal(secondInstance);
56
- });
57
- });
58
- });
59
- describe('property', function () {
60
- describe('filepath', function () {
61
- it('should not be writable', function () {
62
- const instance = getExtConfigIOInstance('/some/path');
63
- expect(() => {
64
- instance.filepath = '/some/other/path';
65
- }).to.throw(TypeError);
66
- });
67
- });
68
- });
69
- describe('read()', function () {
70
- let io;
71
- beforeEach(function () {
72
- io = getExtConfigIOInstance('/some/path');
73
- });
74
- describe('when called with a valid extension type', function () {
75
- describe('when the file does not yet exist', function () {
76
- beforeEach(async function () {
77
- const err = new Error();
78
- err.code = 'ENOENT';
79
- mocks['@appium/support'].fs.readFile.rejects(err);
80
- await io.read('driver');
81
- });
82
- it('should create a new file', function () {
83
- expect(mocks['@appium/support'].fs.writeFile).to.be.calledOnceWith(io.filepath, _yaml.default.stringify({
84
- drivers: {},
85
- plugins: {},
86
- schemaRev: 2
87
- }), 'utf8');
88
- });
89
- });
90
- describe('when the file already exists', function () {
91
- beforeEach(async function () {
92
- await io.read('driver');
93
- });
94
- it('should attempt to create the `appiumHome` directory', function () {
95
- expect(mocks['@appium/support'].mkdirp).to.have.been.calledOnceWith('/some/path');
96
- });
97
- it('should attempt to read the file at `filepath`', function () {
98
- expect(mocks['@appium/support'].fs.readFile).to.have.been.calledOnceWith(io.filepath, 'utf8');
99
- });
100
- });
101
- });
102
- describe('when called with an unknown extension type`', function () {
103
- it('should reject', async function () {
104
- const promise = io.read('unknown');
105
- return await expect(promise).to.be.rejectedWith(TypeError, /invalid extension type/i);
106
- });
107
- });
108
- describe('when called twice with the same `extensionType`', function () {
109
- it('should return the same object both times', async function () {
110
- const firstInstance = await io.read('driver');
111
- const secondInstance = await io.read('driver');
112
- expect(firstInstance).to.equal(secondInstance);
113
- });
114
- });
115
- });
116
- describe('write()', function () {
117
- let io;
118
- let driverData;
119
- beforeEach(function () {
120
- io = getExtConfigIOInstance('/some/path');
121
- });
122
- describe('when called after `read()`', function () {
123
- beforeEach(async function () {
124
- driverData = await io.read('driver');
125
- });
126
- describe('when called without modifying the data', function () {
127
- it('should not write the file', async function () {
128
- expect(await io.write()).to.be.false;
129
- });
130
- });
131
- describe('when called after adding a property', function () {
132
- beforeEach(function () {
133
- driverData.foo = {
134
- name: 'foo',
135
- version: '1.0.0',
136
- path: '/foo/path'
137
- };
138
- });
139
- it('should write the file', async function () {
140
- expect(await io.write()).to.be.true;
141
- });
142
- });
143
- describe('when called after deleting a property', function () {
144
- beforeEach(function () {
145
- driverData.foo = {
146
- name: 'foo',
147
- version: '1.0.0',
148
- path: '/foo/path'
149
- };
150
- io._dirty = false;
151
- delete driverData.foo;
152
- });
153
- it('should write the file', async function () {
154
- expect(await io.write()).to.be.true;
155
- });
156
- });
157
- describe('when the config file could not be written', function () {
158
- beforeEach(function () {
159
- mocks['@appium/support'].fs.writeFile = sandbox.stub().rejects(new Error());
160
- io._dirty = true;
161
- });
162
- it('should reject', async function () {
163
- await expect(io.write()).to.be.rejectedWith(Error, /Appium could not parse or write/i);
164
- });
165
- });
166
- });
167
- describe('when called before `read()`', function () {
168
- it('should return `false`', async function () {
169
- expect(await io.write()).to.be.false;
170
- });
171
- describe('when called with `force: true`', function () {
172
- it('should reject', async function () {
173
- await expect(io.write(true)).to.be.rejectedWith(ReferenceError, 'No data to write. Call `read()` first');
174
- });
175
- });
176
- });
177
- });
178
- });require('source-map-support').install();
179
-
180
-
181
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZXh0LWNvbmZpZy1pby1zcGVjcy5qcyJdLCJuYW1lcyI6WyJleHBlY3QiLCJjaGFpIiwiZGVzY3JpYmUiLCJzYW5kYm94IiwieWFtbEZpeHR1cmUiLCJiZWZvcmUiLCJmcyIsInJlYWRGaWxlIiwicGF0aCIsImpvaW4iLCJfX2Rpcm5hbWUiLCJnZXRFeHRDb25maWdJT0luc3RhbmNlIiwibW9ja3MiLCJiZWZvcmVFYWNoIiwic2lub24iLCJjcmVhdGVTYW5kYm94Iiwic3R1YiIsInJlc29sdmVzIiwid3JpdGVGaWxlIiwibWtkaXJwIiwicmV3aXJlbW9jayIsInByb3h5IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsImNhY2hlIiwiTWFwIiwiaXQiLCJmaXJzdEluc3RhbmNlIiwic2Vjb25kSW5zdGFuY2UiLCJ0byIsImVxdWFsIiwibm90IiwiaW5zdGFuY2UiLCJmaWxlcGF0aCIsInRocm93IiwiVHlwZUVycm9yIiwiaW8iLCJlcnIiLCJFcnJvciIsImNvZGUiLCJyZWplY3RzIiwicmVhZCIsImJlIiwiY2FsbGVkT25jZVdpdGgiLCJZQU1MIiwic3RyaW5naWZ5IiwiZHJpdmVycyIsInBsdWdpbnMiLCJzY2hlbWFSZXYiLCJoYXZlIiwiYmVlbiIsInByb21pc2UiLCJyZWplY3RlZFdpdGgiLCJkcml2ZXJEYXRhIiwid3JpdGUiLCJmYWxzZSIsImZvbyIsIm5hbWUiLCJ2ZXJzaW9uIiwidHJ1ZSIsIl9kaXJ0eSIsIlJlZmVyZW5jZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQSxNQUFNQSxNQUFNLEdBQUdDLElBQUksQ0FBQ0QsTUFBcEI7QUFFQUUsUUFBUSxDQUFDLG1CQUFELEVBQXNCLFlBQVk7QUFJeEMsTUFBSUMsT0FBSjtBQUdBLE1BQUlDLFdBQUo7QUFFQUMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkQsSUFBQUEsV0FBVyxHQUFHLE1BQU1FLGFBQUdDLFFBQUgsQ0FDbEJD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QUFzREFwQyxJQUFBQSxRQUFRLENBQUMsNkJBQUQsRUFBZ0MsWUFBWTtBQUNsRHdCLE1BQUFBLEVBQUUsQ0FBQyx1QkFBRCxFQUEwQixrQkFBa0I7QUFDNUMxQixRQUFBQSxNQUFNLENBQUMsTUFBTW9DLEVBQUUsQ0FBQ2tCLEtBQUgsRUFBUCxDQUFOLENBQXlCekIsRUFBekIsQ0FBNEJhLEVBQTVCLENBQStCYSxLQUEvQjtBQUNELE9BRkMsQ0FBRjtBQUlBckQsTUFBQUEsUUFBUSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFDckR3QixRQUFBQSxFQUFFLENBQUMsZUFBRCxFQUFrQixrQkFBa0I7QUFDcEMsZ0JBQU0xQixNQUFNLENBQUNvQyxFQUFFLENBQUNrQixLQUFILENBQVMsSUFBVCxDQUFELENBQU4sQ0FBdUJ6QixFQUF2QixDQUEwQmEsRUFBMUIsQ0FBNkJVLFlBQTdCLENBQTBDUyxjQUExQyxFQUEwRCx1Q0FBMUQsQ0FBTjtBQUNELFNBRkMsQ0FBRjtBQUdELE9BSk8sQ0FBUjtBQUtELEtBVk8sQ0FBUjtBQVdELEdBekVPLENBQVI7QUEwRUQsQ0F2Tk8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmcyB9IGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBZQU1MIGZyb20gJ3lhbWwnO1xuaW1wb3J0IHsgcmV3aXJlbW9jayB9IGZyb20gJy4vaGVscGVycyc7XG5jb25zdCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuZGVzY3JpYmUoJ0V4dGVuc2lvbkNvbmZpZ0lPJywgZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9XG4gICAqL1xuICBsZXQgc2FuZGJveDtcblxuICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgbGV0IHlhbWxGaXh0dXJlO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgeWFtbEZpeHR1cmUgPSBhd2FpdCBmcy5yZWFkRmlsZShcbiAgICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICdmaXh0dXJlcycsICdleHRlbnNpb25zLnlhbWwnKSxcbiAgICAgICd1dGY4JyxcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4uL2xpYi9leHQtY29uZmlnLWlvJykuZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZX1cbiAgICovXG4gIGxldCBnZXRFeHRDb25maWdJT0luc3RhbmNlO1xuXG4gIGxldCBtb2NrcztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIG1vY2tzID0ge1xuICAgICAgJ0BhcHBpdW0vc3VwcG9ydCc6IHtcbiAgICAgICAgZnM6IHtcbiAgICAgICAgICByZWFkRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoeWFtbEZpeHR1cmUpLFxuICAgICAgICAgIHdyaXRlRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXModHJ1ZSksXG4gICAgICAgIH0sXG4gICAgICAgIG1rZGlycDogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBnZXRFeHRDb25maWdJT0luc3RhbmNlID0gcmV3aXJlbW9jay5wcm94eShcbiAgICAgICcuLi9saWIvZXh0LWNvbmZpZy1pbycsXG4gICAgICBtb2NrcyxcbiAgICApLmdldEV4dENvbmZpZ0lPSW5zdGFuY2U7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZS5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luc3RhbnRpYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHR3aWNlIHdpdGggdGhlIHNhbWUgYGFwcGl1bUhvbWVgIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IGJvdGggdGltZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SW5zdGFuY2UgPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgICAgIGNvbnN0IHNlY29uZEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCBkaWZmZXJlbnQgYGFwcGl1bUhvbWVgIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRpZmZlcmVudCBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmaXJzdEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL290aGVyL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KGZpcnN0SW5zdGFuY2UpLnRvLm5vdC5lcXVhbChzZWNvbmRJbnN0YW5jZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Byb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgIGRlc2NyaWJlKCdmaWxlcGF0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgbm90IGJlIHdyaXRhYmxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgaW5zdGFuY2UuZmlsZXBhdGggPSAnL3NvbWUvb3RoZXIvcGF0aCc7XG4gICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlYWQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydCgnLi4vbGliL2V4dC1jb25maWctaW8nKS5FeHRlbnNpb25Db25maWdJT30gKi9cbiAgICBsZXQgaW87XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlvID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHdpdGggYSB2YWxpZCBleHRlbnNpb24gdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBmaWxlIGRvZXMgbm90IHlldCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLyoqIEB0eXBlIHtOb2RlSlMuRXJybm9FeGNlcHRpb259ICovXG4gICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgZXJyLmNvZGUgPSAnRU5PRU5UJztcbiAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUucmVqZWN0cyhlcnIpO1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBmaWxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMud3JpdGVGaWxlKS50by5iZS5jYWxsZWRPbmNlV2l0aChcbiAgICAgICAgICAgIGlvLmZpbGVwYXRoLFxuICAgICAgICAgICAgWUFNTC5zdHJpbmdpZnkoe2RyaXZlcnM6IHt9LCBwbHVnaW5zOiB7fSwgc2NoZW1hUmV2OiAyfSksXG4gICAgICAgICAgICAndXRmOCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGZpbGUgYWxyZWFkeSBleGlzdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGF0dGVtcHQgdG8gY3JlYXRlIHRoZSBgYXBwaXVtSG9tZWAgZGlyZWN0b3J5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10ubWtkaXJwKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoXG4gICAgICAgICAgICAnL3NvbWUvcGF0aCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBhdHRlbXB0IHRvIHJlYWQgdGhlIGZpbGUgYXQgYGZpbGVwYXRoYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUsXG4gICAgICAgICAgKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoaW8uZmlsZXBhdGgsICd1dGY4Jyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgd2l0aCBhbiB1bmtub3duIGV4dGVuc2lvbiB0eXBlYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBpby5yZWFkKCd1bmtub3duJyk7XG4gICAgICAgIHJldHVybiBhd2FpdCBleHBlY3QocHJvbWlzZSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAvaW52YWxpZCBleHRlbnNpb24gdHlwZS9pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCB0aGUgc2FtZSBgZXh0ZW5zaW9uVHlwZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgc2FtZSBvYmplY3QgYm90aCB0aW1lcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZmlyc3RJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3cml0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBpbztcbiAgICBsZXQgZHJpdmVyRGF0YTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgaW8gPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYHJlYWQoKWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZHJpdmVyRGF0YSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRob3V0IG1vZGlmeWluZyB0aGUgZGF0YScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBub3Qgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYWRkaW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB3cml0ZSB0aGUgZmlsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoYXdhaXQgaW8ud3JpdGUoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIGFmdGVyIGRlbGV0aW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpby5fZGlydHkgPSBmYWxzZTtcbiAgICAgICAgICBkZWxldGUgZHJpdmVyRGF0YS5mb287XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBjb3VsZCBub3QgYmUgd3JpdHRlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbW9ja3NbJ0BhcHBpdW0vc3VwcG9ydCddLmZzLndyaXRlRmlsZSA9IHNhbmRib3guc3R1YigpLnJlamVjdHMobmV3IEVycm9yKCkpO1xuICAgICAgICAgIGlvLl9kaXJ0eSA9IHRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSgpKS50by5iZS5yZWplY3RlZFdpdGgoRXJyb3IsIC9BcHBpdW0gY291bGQgbm90IHBhcnNlIG9yIHdyaXRlL2kpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYmVmb3JlIGByZWFkKClgJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYGZhbHNlYCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRoIGBmb3JjZTogdHJ1ZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSh0cnVlKSkudG8uYmUucmVqZWN0ZWRXaXRoKFJlZmVyZW5jZUVycm9yLCAnTm8gZGF0YSB0byB3cml0ZS4gQ2FsbCBgcmVhZCgpYCBmaXJzdCcpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L2V4dC1jb25maWctaW8tc3BlY3MuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==