appium-adb 9.10.2 → 9.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,397 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.default = void 0;
9
-
10
- require("source-map-support/register");
11
-
12
- var _logger = _interopRequireDefault(require("../logger.js"));
13
-
14
- var _helpers = require("../helpers");
15
-
16
- var _lodash = _interopRequireDefault(require("lodash"));
17
-
18
- var _net = _interopRequireDefault(require("net"));
19
-
20
- var _support = require("@appium/support");
21
-
22
- var _bluebird = _interopRequireDefault(require("bluebird"));
23
-
24
- var _path = _interopRequireDefault(require("path"));
25
-
26
- var _ini = _interopRequireDefault(require("ini"));
27
-
28
- const PHONE_NUMBER_PATTERN = /^[+]?[(]?[0-9]*[)]?[-\s.]?[0-9]*[-\s.]?[0-9]{2,}$/im;
29
- const emuMethods = {};
30
- emuMethods.POWER_AC_STATES = Object.freeze({
31
- POWER_AC_ON: 'on',
32
- POWER_AC_OFF: 'off'
33
- });
34
- emuMethods.GSM_CALL_ACTIONS = Object.freeze({
35
- GSM_CALL: 'call',
36
- GSM_ACCEPT: 'accept',
37
- GSM_CANCEL: 'cancel',
38
- GSM_HOLD: 'hold'
39
- });
40
- emuMethods.GSM_VOICE_STATES = Object.freeze({
41
- GSM_VOICE_UNREGISTERED: 'unregistered',
42
- GSM_VOICE_HOME: 'home',
43
- GSM_VOICE_ROAMING: 'roaming',
44
- GSM_VOICE_SEARCHING: 'searching',
45
- GSM_VOICE_DENIED: 'denied',
46
- GSM_VOICE_OFF: 'off',
47
- GSM_VOICE_ON: 'on'
48
- });
49
- emuMethods.GSM_SIGNAL_STRENGTHS = [0, 1, 2, 3, 4];
50
- emuMethods.NETWORK_SPEED = Object.freeze({
51
- GSM: 'gsm',
52
- SCSD: 'scsd',
53
- GPRS: 'gprs',
54
- EDGE: 'edge',
55
- UMTS: 'umts',
56
- HSDPA: 'hsdpa',
57
- LTE: 'lte',
58
- EVDO: 'evdo',
59
- FULL: 'full'
60
- });
61
- emuMethods.SENSORS = Object.freeze({
62
- ACCELERATION: 'acceleration',
63
- GYROSCOPE: 'gyroscope',
64
- MAGNETIC_FIELD: 'magnetic-field',
65
- ORIENTATION: 'orientation',
66
- TEMPERATURE: 'temperature',
67
- PROXIMITY: 'proximity',
68
- LIGHT: 'light',
69
- PRESSURE: 'pressure',
70
- HUMIDITY: 'humidity',
71
- MAGNETIC_FIELD_UNCALIBRATED: 'magnetic-field-uncalibrated',
72
- GYROSCOPE_UNCALIBRATED: 'gyroscope-uncalibrated',
73
- HINGE_ANGLE0: 'hinge-angle0',
74
- HINGE_ANGLE1: 'hinge-angle1',
75
- HINGE_ANGLE2: 'hinge-angle2',
76
- HEART_RATE: 'heart-rate',
77
- RGBC_LIGHT: 'rgbc-light'
78
- });
79
-
80
- async function listEmulators() {
81
- let avdsRoot = process.env.ANDROID_AVD_HOME;
82
-
83
- if (await (0, _helpers.dirExists)(avdsRoot)) {
84
- return await getAvdConfigPaths(avdsRoot);
85
- }
86
-
87
- if (avdsRoot) {
88
- _logger.default.warn(`The value of the ANDROID_AVD_HOME environment variable '${avdsRoot}' is not an existing directory`);
89
- }
90
-
91
- const prefsRoot = await (0, _helpers.getAndroidPrefsRoot)();
92
-
93
- if (!prefsRoot) {
94
- return [];
95
- }
96
-
97
- avdsRoot = _path.default.resolve(prefsRoot, 'avd');
98
-
99
- if (!(await (0, _helpers.dirExists)(avdsRoot))) {
100
- _logger.default.debug(`Virtual devices config root '${avdsRoot}' is not an existing directory`);
101
-
102
- return [];
103
- }
104
-
105
- return await getAvdConfigPaths(avdsRoot);
106
- }
107
-
108
- async function getAvdConfigPaths(avdsRoot) {
109
- const configs = await _support.fs.glob('*.ini', {
110
- cwd: avdsRoot,
111
- absolute: true
112
- });
113
- return configs.map(confPath => {
114
- const avdName = _path.default.basename(confPath).split('.').slice(0, -1).join('.');
115
-
116
- return {
117
- name: avdName,
118
- config: confPath
119
- };
120
- }).filter(({
121
- name
122
- }) => _lodash.default.trim(name));
123
- }
124
-
125
- emuMethods.isEmulatorConnected = async function isEmulatorConnected() {
126
- let emulators = await this.getConnectedEmulators();
127
- return !!_lodash.default.find(emulators, x => x && x.udid === this.curDeviceId);
128
- };
129
-
130
- emuMethods.verifyEmulatorConnected = async function verifyEmulatorConnected() {
131
- if (!(await this.isEmulatorConnected())) {
132
- throw new Error(`The emulator "${this.curDeviceId}" was unexpectedly disconnected`);
133
- }
134
- };
135
-
136
- emuMethods.fingerprint = async function fingerprint(fingerprintId) {
137
- if (!fingerprintId) {
138
- throw new Error('Fingerprint id parameter must be defined');
139
- }
140
-
141
- let level = await this.getApiLevel();
142
-
143
- if (level < 23) {
144
- throw new Error(`Device API Level must be >= 23. Current Api level '${level}'`);
145
- }
146
-
147
- await this.adbExecEmu(['finger', 'touch', fingerprintId]);
148
- };
149
-
150
- emuMethods.rotate = async function rotate() {
151
- await this.adbExecEmu(['rotate']);
152
- };
153
-
154
- emuMethods.powerAC = async function powerAC(state = 'on') {
155
- if (_lodash.default.values(emuMethods.POWER_AC_STATES).indexOf(state) === -1) {
156
- throw new TypeError(`Wrong power AC state sent '${state}'. ` + `Supported values: ${_lodash.default.values(emuMethods.POWER_AC_STATES)}]`);
157
- }
158
-
159
- await this.adbExecEmu(['power', 'ac', state]);
160
- };
161
-
162
- emuMethods.sensorSet = async function sensorSet(sensor, value) {
163
- if (!_lodash.default.includes(emuMethods.SENSORS, sensor)) {
164
- throw new TypeError(`Unsupported sensor sent '${sensor}'. ` + `Supported values: ${_lodash.default.values(emuMethods.SENSORS)}]`);
165
- }
166
-
167
- if (_lodash.default.isNil(value) || value === '') {
168
- throw new TypeError(`Missing/invalid sensor value argument. ` + `You need to provide a valid value to set to the sensor in ` + `format <value-a>[:<value-b>[:<value-c>[...]]].`);
169
- }
170
-
171
- await this.adbExecEmu(['sensor', 'set', sensor, value]);
172
- };
173
-
174
- emuMethods.powerCapacity = async function powerCapacity(percent = 100) {
175
- percent = parseInt(percent, 10);
176
-
177
- if (isNaN(percent) || percent < 0 || percent > 100) {
178
- throw new Error(`The percentage value should be valid integer between 0 and 100`);
179
- }
180
-
181
- await this.adbExecEmu(['power', 'capacity', percent]);
182
- };
183
-
184
- emuMethods.powerOFF = async function powerOFF() {
185
- await this.powerAC(emuMethods.POWER_AC_STATES.POWER_AC_OFF);
186
- await this.powerCapacity(0);
187
- };
188
-
189
- emuMethods.sendSMS = async function sendSMS(phoneNumber, message = '') {
190
- message = message.trim();
191
-
192
- if (message === '') {
193
- throw new Error('Sending an SMS requires a message');
194
- }
195
-
196
- phoneNumber = `${phoneNumber}`.replace(/\s*/, '');
197
-
198
- if (!PHONE_NUMBER_PATTERN.test(phoneNumber)) {
199
- throw new Error(`Invalid sendSMS phoneNumber param ${phoneNumber}`);
200
- }
201
-
202
- await this.adbExecEmu(['sms', 'send', phoneNumber, message]);
203
- };
204
-
205
- emuMethods.gsmCall = async function gsmCall(phoneNumber, action = '') {
206
- if (_lodash.default.values(emuMethods.GSM_CALL_ACTIONS).indexOf(action) === -1) {
207
- throw new Error(`Invalid gsm action param ${action}. Supported values: ${_lodash.default.values(emuMethods.GSM_CALL_ACTIONS)}`);
208
- }
209
-
210
- phoneNumber = `${phoneNumber}`.replace(/\s*/, '');
211
-
212
- if (!PHONE_NUMBER_PATTERN.test(phoneNumber)) {
213
- throw new Error(`Invalid gsmCall phoneNumber param ${phoneNumber}`);
214
- }
215
-
216
- await this.adbExecEmu(['gsm', action, phoneNumber]);
217
- };
218
-
219
- emuMethods.gsmSignal = async function gsmSignal(strength = 4) {
220
- strength = parseInt(strength, 10);
221
-
222
- if (emuMethods.GSM_SIGNAL_STRENGTHS.indexOf(strength) === -1) {
223
- throw new Error(`Invalid signal strength param ${strength}. Supported values: ${_lodash.default.values(emuMethods.GSM_SIGNAL_STRENGTHS)}`);
224
- }
225
-
226
- _logger.default.info('gsm signal-profile <strength> changes the reported strength on next (15s) update.');
227
-
228
- await this.adbExecEmu(['gsm', 'signal-profile', strength]);
229
- };
230
-
231
- emuMethods.gsmVoice = async function gsmVoice(state = 'on') {
232
- if (_lodash.default.values(emuMethods.GSM_VOICE_STATES).indexOf(state) === -1) {
233
- throw new Error(`Invalid gsm voice state param ${state}. Supported values: ${_lodash.default.values(emuMethods.GSM_VOICE_STATES)}`);
234
- }
235
-
236
- await this.adbExecEmu(['gsm', 'voice', state]);
237
- };
238
-
239
- emuMethods.networkSpeed = async function networkSpeed(speed = 'full') {
240
- if (_lodash.default.values(emuMethods.NETWORK_SPEED).indexOf(speed) === -1) {
241
- throw new Error(`Invalid network speed param ${speed}. Supported values: ${_lodash.default.values(emuMethods.NETWORK_SPEED)}`);
242
- }
243
-
244
- await this.adbExecEmu(['network', 'speed', speed]);
245
- };
246
-
247
- emuMethods.execEmuConsoleCommand = async function execTelnet(cmd, opts = {}) {
248
- let port = parseInt(opts.port, 10);
249
-
250
- if (!port) {
251
- const portMatch = /emulator-(\d+)/i.exec(this.curDeviceId);
252
-
253
- if (!portMatch) {
254
- throw new Error(`Cannot parse the console port number from the device identifier '${this.curDeviceId}'. ` + `Is it an emulator?`);
255
- }
256
-
257
- port = parseInt(portMatch[1], 10);
258
- }
259
-
260
- const host = '127.0.0.1';
261
- const {
262
- execTimeout = 60000,
263
- connTimeout = 5000,
264
- initTimeout = 5000
265
- } = opts;
266
- await this.resetTelnetAuthToken();
267
- const okFlag = /^OK$/m;
268
- const nokFlag = /^KO\b/m;
269
- const eol = '\r\n';
270
-
271
- const client = _net.default.connect({
272
- host,
273
- port
274
- });
275
-
276
- return await new _bluebird.default((resolve, reject) => {
277
- const connTimeoutObj = setTimeout(() => reject(new Error(`Cannot connect to the Emulator console at ${host}:${port} ` + `after ${connTimeout}ms`)), connTimeout);
278
- let execTimeoutObj;
279
- let initTimeoutObj;
280
- let isCommandSent = false;
281
- let serverResponse = [];
282
- client.once('error', e => {
283
- clearTimeout(connTimeoutObj);
284
- reject(new Error(`Cannot connect to the Emulator console at ${host}:${port}. ` + `Original error: ${e.message}`));
285
- });
286
- client.once('connect', () => {
287
- clearTimeout(connTimeoutObj);
288
- initTimeoutObj = setTimeout(() => reject(new Error(`Did not get the initial response from the Emulator console at ${host}:${port} ` + `after ${initTimeout}ms`)), initTimeout);
289
- });
290
- client.on('data', chunk => {
291
- serverResponse.push(chunk);
292
- const output = Buffer.concat(serverResponse).toString('utf8').trim();
293
-
294
- if (okFlag.test(output)) {
295
- if (!isCommandSent) {
296
- clearTimeout(initTimeoutObj);
297
- serverResponse = [];
298
- const cmdStr = _lodash.default.isArray(cmd) ? _support.util.quote(cmd) : `${cmd}`;
299
-
300
- _logger.default.debug(`Executing Emulator console command: ${cmdStr}`);
301
-
302
- client.write(cmdStr);
303
- client.write(eol);
304
- isCommandSent = true;
305
- execTimeoutObj = setTimeout(() => reject(new Error(`Did not get any response from the Emulator console at ${host}:${port} ` + `to '${cmd}' command after ${execTimeout}ms`)), execTimeout);
306
- return;
307
- }
308
-
309
- clearTimeout(execTimeoutObj);
310
- client.end();
311
- const outputArr = output.split(eol);
312
- return resolve(outputArr.slice(0, outputArr.length - 1).join('\n').trim());
313
- } else if (nokFlag.test(output)) {
314
- clearTimeout(initTimeoutObj);
315
- clearTimeout(execTimeoutObj);
316
- client.end();
317
- const outputArr = output.split(eol);
318
- return reject(_lodash.default.trim(_lodash.default.last(outputArr)));
319
- }
320
- });
321
- });
322
- };
323
-
324
- emuMethods.getEmuVersionInfo = async function getEmuVersionInfo() {
325
- const propsPath = _path.default.join(this.sdkRoot, 'emulator', 'source.properties');
326
-
327
- if (!(await _support.fs.exists(propsPath))) {
328
- return {};
329
- }
330
-
331
- const content = await _support.fs.readFile(propsPath, 'utf8');
332
- const revisionMatch = /^Pkg\.Revision=([\d.]+)$/m.exec(content);
333
- const result = {};
334
-
335
- if (revisionMatch) {
336
- result.revision = revisionMatch[1];
337
- }
338
-
339
- const buildIdMatch = /^Pkg\.BuildId=(\d+)$/m.exec(content);
340
-
341
- if (buildIdMatch) {
342
- result.buildId = parseInt(buildIdMatch[1], 10);
343
- }
344
-
345
- return result;
346
- };
347
-
348
- emuMethods.getEmuImageProperties = async function getEmuImageProperties(avdName) {
349
- const avds = await listEmulators();
350
- const avd = avds.find(({
351
- name
352
- }) => name === avdName);
353
-
354
- if (!avd) {
355
- let msg = `Cannot find '${avdName}' emulator. `;
356
-
357
- if (_lodash.default.isEmpty(avds)) {
358
- msg += `No emulators have been detected on your system`;
359
- } else {
360
- msg += `Available avd names are: ${avds.map(({
361
- name
362
- }) => name)}`;
363
- }
364
-
365
- throw new Error(msg);
366
- }
367
-
368
- return _ini.default.parse(await _support.fs.readFile(avd.config, 'utf8'));
369
- };
370
-
371
- emuMethods.checkAvdExist = async function checkAvdExist(avdName) {
372
- const avds = await listEmulators();
373
-
374
- if (!avds.some(({
375
- name
376
- }) => name === avdName)) {
377
- let msg = `Avd '${avdName}' is not available. `;
378
-
379
- if (_lodash.default.isEmpty(avds)) {
380
- msg += `No emulators have been detected on your system`;
381
- } else {
382
- msg += `Please select your avd name from one of these: '${avds.map(({
383
- name
384
- }) => name)}'`;
385
- }
386
-
387
- throw new Error(msg);
388
- }
389
-
390
- return true;
391
- };
392
-
393
- var _default = emuMethods;
394
- exports.default = _default;require('source-map-support').install();
395
-
396
-
397
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliL3Rvb2xzL2FkYi1lbXUtY29tbWFuZHMuanMiLCJuYW1lcyI6WyJQSE9ORV9OVU1CRVJfUEFUVEVSTiIsImVtdU1ldGhvZHMiLCJQT1dFUl9BQ19TVEFURVMiLCJPYmplY3QiLCJmcmVlemUiLCJQT1dFUl9BQ19PTiIsIlBPV0VSX0FDX09GRiIsIkdTTV9DQUxMX0FDVElPTlMiLCJHU01fQ0FMTCIsIkdTTV9BQ0NFUFQiLCJHU01fQ0FOQ0VMIiwiR1NNX0hPTEQiLCJHU01fVk9JQ0VfU1RBVEVTIiwiR1NNX1ZPSUNFX1VOUkVHSVNURVJFRCIsIkdTTV9WT0lDRV9IT01FIiwiR1NNX1ZPSUNFX1JPQU1JTkciLCJHU01fVk9JQ0VfU0VBUkNISU5HIiwiR1NNX1ZPSUNFX0RFTklFRCIsIkdTTV9WT0lDRV9PRkYiLCJHU01fVk9JQ0VfT04iLCJHU01fU0lHTkFMX1NUUkVOR1RIUyIsIk5FVFdPUktfU1BFRUQiLCJHU00iLCJTQ1NEIiwiR1BSUyIsIkVER0UiLCJVTVRTIiwiSFNEUEEiLCJMVEUiLCJFVkRPIiwiRlVMTCIsIlNFTlNPUlMiLCJBQ0NFTEVSQVRJT04iLCJHWVJPU0NPUEUiLCJNQUdORVRJQ19GSUVMRCIsIk9SSUVOVEFUSU9OIiwiVEVNUEVSQVRVUkUiLCJQUk9YSU1JVFkiLCJMSUdIVCIsIlBSRVNTVVJFIiwiSFVNSURJVFkiLCJNQUdORVRJQ19GSUVMRF9VTkNBTElCUkFURUQiLCJHWVJPU0NPUEVfVU5DQUxJQlJBVEVEIiwiSElOR0VfQU5HTEUwIiwiSElOR0VfQU5HTEUxIiwiSElOR0VfQU5HTEUyIiwiSEVBUlRfUkFURSIsIlJHQkNfTElHSFQiLCJsaXN0RW11bGF0b3JzIiwiYXZkc1Jvb3QiLCJwcm9jZXNzIiwiZW52IiwiQU5EUk9JRF9BVkRfSE9NRSIsImRpckV4aXN0cyIsImdldEF2ZENvbmZpZ1BhdGhzIiwibG9nIiwid2FybiIsInByZWZzUm9vdCIsImdldEFuZHJvaWRQcmVmc1Jvb3QiLCJwYXRoIiwicmVzb2x2ZSIsImRlYnVnIiwiY29uZmlncyIsImZzIiwiZ2xvYiIsImN3ZCIsImFic29sdXRlIiwibWFwIiwiY29uZlBhdGgiLCJhdmROYW1lIiwiYmFzZW5hbWUiLCJzcGxpdCIsInNsaWNlIiwiam9pbiIsIm5hbWUiLCJjb25maWciLCJmaWx0ZXIiLCJfIiwidHJpbSIsImlzRW11bGF0b3JDb25uZWN0ZWQiLCJlbXVsYXRvcnMiLCJnZXRDb25uZWN0ZWRFbXVsYXRvcnMiLCJmaW5kIiwieCIsInVkaWQiLCJjdXJEZXZpY2VJZCIsInZlcmlmeUVtdWxhdG9yQ29ubmVjdGVkIiwiRXJyb3IiLCJmaW5nZXJwcmludCIsImZpbmdlcnByaW50SWQiLCJsZXZlbCIsImdldEFwaUxldmVsIiwiYWRiRXhlY0VtdSIsInJvdGF0ZSIsInBvd2VyQUMiLCJzdGF0ZSIsInZhbHVlcyIsImluZGV4T2YiLCJUeXBlRXJyb3IiLCJzZW5zb3JTZXQiLCJzZW5zb3IiLCJ2YWx1ZSIsImluY2x1ZGVzIiwiaXNOaWwiLCJwb3dlckNhcGFjaXR5IiwicGVyY2VudCIsInBhcnNlSW50IiwiaXNOYU4iLCJwb3dlck9GRiIsInNlbmRTTVMiLCJwaG9uZU51bWJlciIsIm1lc3NhZ2UiLCJyZXBsYWNlIiwidGVzdCIsImdzbUNhbGwiLCJhY3Rpb24iLCJnc21TaWduYWwiLCJzdHJlbmd0aCIsImluZm8iLCJnc21Wb2ljZSIsIm5ldHdvcmtTcGVlZCIsInNwZWVkIiwiZXhlY0VtdUNvbnNvbGVDb21tYW5kIiwiZXhlY1RlbG5ldCIsImNtZCIsIm9wdHMiLCJwb3J0IiwicG9ydE1hdGNoIiwiZXhlYyIsImhvc3QiLCJleGVjVGltZW91dCIsImNvbm5UaW1lb3V0IiwiaW5pdFRpbWVvdXQiLCJyZXNldFRlbG5ldEF1dGhUb2tlbiIsIm9rRmxhZyIsIm5va0ZsYWciLCJlb2wiLCJjbGllbnQiLCJuZXQiLCJjb25uZWN0IiwiQiIsInJlamVjdCIsImNvbm5UaW1lb3V0T2JqIiwic2V0VGltZW91dCIsImV4ZWNUaW1lb3V0T2JqIiwiaW5pdFRpbWVvdXRPYmoiLCJpc0NvbW1hbmRTZW50Iiwic2VydmVyUmVzcG9uc2UiLCJvbmNlIiwiZSIsImNsZWFyVGltZW91dCIsIm9uIiwiY2h1bmsiLCJwdXNoIiwib3V0cHV0IiwiQnVmZmVyIiwiY29uY2F0IiwidG9TdHJpbmciLCJjbWRTdHIiLCJpc0FycmF5IiwidXRpbCIsInF1b3RlIiwid3JpdGUiLCJlbmQiLCJvdXRwdXRBcnIiLCJsZW5ndGgiLCJsYXN0IiwiZ2V0RW11VmVyc2lvbkluZm8iLCJwcm9wc1BhdGgiLCJzZGtSb290IiwiZXhpc3RzIiwiY29udGVudCIsInJlYWRGaWxlIiwicmV2aXNpb25NYXRjaCIsInJlc3VsdCIsInJldmlzaW9uIiwiYnVpbGRJZE1hdGNoIiwiYnVpbGRJZCIsImdldEVtdUltYWdlUHJvcGVydGllcyIsImF2ZHMiLCJhdmQiLCJtc2ciLCJpc0VtcHR5IiwiaW5pIiwicGFyc2UiLCJjaGVja0F2ZEV4aXN0Iiwic29tZSJdLCJzb3VyY2VSb290IjoiLi4vLi4vLi4iLCJzb3VyY2VzIjpbImxpYi90b29scy9hZGItZW11LWNvbW1hbmRzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2cgZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGdldEFuZHJvaWRQcmVmc1Jvb3QsIGRpckV4aXN0cyB9IGZyb20gJy4uL2hlbHBlcnMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IHV0aWwsIGZzIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGluaSBmcm9tICdpbmknO1xuXG5jb25zdCBQSE9ORV9OVU1CRVJfUEFUVEVSTiA9IC9eWytdP1soXT9bMC05XSpbKV0/Wy1cXHMuXT9bMC05XSpbLVxccy5dP1swLTldezIsfSQvaW07XG5cbmNvbnN0IGVtdU1ldGhvZHMgPSB7fTtcbmVtdU1ldGhvZHMuUE9XRVJfQUNfU1RBVEVTID0gT2JqZWN0LmZyZWV6ZSh7XG4gIFBPV0VSX0FDX09OOiAnb24nLFxuICBQT1dFUl9BQ19PRkY6ICdvZmYnXG59KTtcbmVtdU1ldGhvZHMuR1NNX0NBTExfQUNUSU9OUyA9IE9iamVjdC5mcmVlemUoe1xuICBHU01fQ0FMTDogJ2NhbGwnLFxuICBHU01fQUNDRVBUOiAnYWNjZXB0JyxcbiAgR1NNX0NBTkNFTDogJ2NhbmNlbCcsXG4gIEdTTV9IT0xEOiAnaG9sZCdcbn0pO1xuZW11TWV0aG9kcy5HU01fVk9JQ0VfU1RBVEVTID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEdTTV9WT0lDRV9VTlJFR0lTVEVSRUQ6ICd1bnJlZ2lzdGVyZWQnLFxuICBHU01fVk9JQ0VfSE9NRTogJ2hvbWUnLFxuICBHU01fVk9JQ0VfUk9BTUlORzogJ3JvYW1pbmcnLFxuICBHU01fVk9JQ0VfU0VBUkNISU5HOiAnc2VhcmNoaW5nJyxcbiAgR1NNX1ZPSUNFX0RFTklFRDogJ2RlbmllZCcsXG4gIEdTTV9WT0lDRV9PRkY6ICdvZmYnLFxuICBHU01fVk9JQ0VfT046ICdvbidcbn0pO1xuZW11TWV0aG9kcy5HU01fU0lHTkFMX1NUUkVOR1RIUyA9IFswLCAxLCAyLCAzLCA0XTtcblxuZW11TWV0aG9kcy5ORVRXT1JLX1NQRUVEID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEdTTTogJ2dzbScsIC8vIEdTTS9DU0QgKHVwOiAxNC40LCBkb3duOiAxNC40KS5cbiAgU0NTRDogJ3Njc2QnLCAvLyBIU0NTRCAodXA6IDE0LjQsIGRvd246IDU3LjYpLlxuICBHUFJTOiAnZ3BycycsIC8vIEdQUlMgKHVwOiAyOC44LCBkb3duOiA1Ny42KS5cbiAgRURHRTogJ2VkZ2UnLCAvLyBFREdFL0VHUFJTICh1cDogNDczLjYsIGRvd246IDQ3My42KS5cbiAgVU1UUzogJ3VtdHMnLCAvLyBVTVRTLzNHICh1cDogMzg0LjAsIGRvd246IDM4NC4wKS5cbiAgSFNEUEE6ICdoc2RwYScsIC8vIEhTRFBBICh1cDogNTc2MC4wLCBkb3duOiAxMyw5ODAuMCkuXG4gIExURTogJ2x0ZScsIC8vIExURSAodXA6IDU4LDAwMCwgZG93bjogMTczLDAwMCkuXG4gIEVWRE86ICdldmRvJywgLy8gRVZETyAodXA6IDc1LDAwMCwgZG93bjogMjgwLDAwMCkuXG4gIEZVTEw6ICdmdWxsJyAvLyBObyBsaW1pdCwgdGhlIGRlZmF1bHQgKHVwOiAwLjAsIGRvd246IDAuMCkuXG59KTtcblxuZW11TWV0aG9kcy5TRU5TT1JTID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEFDQ0VMRVJBVElPTjogJ2FjY2VsZXJhdGlvbicsXG4gIEdZUk9TQ09QRTogJ2d5cm9zY29wZScsXG4gIE1BR05FVElDX0ZJRUxEOiAnbWFnbmV0aWMtZmllbGQnLFxuICBPUklFTlRBVElPTjogJ29yaWVudGF0aW9uJyxcbiAgVEVNUEVSQVRVUkU6ICd0ZW1wZXJhdHVyZScsXG4gIFBST1hJTUlUWTogJ3Byb3hpbWl0eScsXG4gIExJR0hUOiAnbGlnaHQnLFxuICBQUkVTU1VSRTogJ3ByZXNzdXJlJyxcbiAgSFVNSURJVFk6ICdodW1pZGl0eScsXG4gIE1BR05FVElDX0ZJRUxEX1VOQ0FMSUJSQVRFRDogJ21hZ25ldGljLWZpZWxkLXVuY2FsaWJyYXRlZCcsXG4gIEdZUk9TQ09QRV9VTkNBTElCUkFURUQ6ICdneXJvc2NvcGUtdW5jYWxpYnJhdGVkJyxcbiAgSElOR0VfQU5HTEUwOiAnaGluZ2UtYW5nbGUwJyxcbiAgSElOR0VfQU5HTEUxOiAnaGluZ2UtYW5nbGUxJyxcbiAgSElOR0VfQU5HTEUyOiAnaGluZ2UtYW5nbGUyJyxcbiAgSEVBUlRfUkFURTogJ2hlYXJ0LXJhdGUnLFxuICBSR0JDX0xJR0hUOiAncmdiYy1saWdodCcsXG59KTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbXVJbmZvXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbmFtZSBFbXVsYXRvciBuYW1lLCBmb3IgZXhhbXBsZSBgUGl4ZWxfWExfQVBJXzMwYFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGNvbmZpZyBGdWxsIHBhdGggdG8gdGhlIGVtdWxhdG9yIGNvbmZpZyAuaW5pIGZpbGUsXG4gKiBmb3IgZXhhbXBsZSBgL1VzZXJzL3VzZXIvLmFuZHJvaWQvYXZkL1BpeGVsX1hMX0FQSV8zMC5pbmlgXG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIEFuZHJvaWQgZW11bGF0b3JzXG4gKlxuICogQHJldHVybnMge0FycmF5PEVtdUluZm8+fVxuICovXG5hc3luYyBmdW5jdGlvbiBsaXN0RW11bGF0b3JzICgpIHtcbiAgbGV0IGF2ZHNSb290ID0gcHJvY2Vzcy5lbnYuQU5EUk9JRF9BVkRfSE9NRTtcbiAgaWYgKGF3YWl0IGRpckV4aXN0cyhhdmRzUm9vdCkpIHtcbiAgICByZXR1cm4gYXdhaXQgZ2V0QXZkQ29uZmlnUGF0aHMoYXZkc1Jvb3QpO1xuICB9XG5cbiAgaWYgKGF2ZHNSb290KSB7XG4gICAgbG9nLndhcm4oYFRoZSB2YWx1ZSBvZiB0aGUgQU5EUk9JRF9BVkRfSE9NRSBlbnZpcm9ubWVudCB2YXJpYWJsZSAnJHthdmRzUm9vdH0nIGlzIG5vdCBhbiBleGlzdGluZyBkaXJlY3RvcnlgKTtcbiAgfVxuXG4gIGNvbnN0IHByZWZzUm9vdCA9IGF3YWl0IGdldEFuZHJvaWRQcmVmc1Jvb3QoKTtcbiAgaWYgKCFwcmVmc1Jvb3QpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBhdmRzUm9vdCA9IHBhdGgucmVzb2x2ZShwcmVmc1Jvb3QsICdhdmQnKTtcbiAgaWYgKCFhd2FpdCBkaXJFeGlzdHMoYXZkc1Jvb3QpKSB7XG4gICAgbG9nLmRlYnVnKGBWaXJ0dWFsIGRldmljZXMgY29uZmlnIHJvb3QgJyR7YXZkc1Jvb3R9JyBpcyBub3QgYW4gZXhpc3RpbmcgZGlyZWN0b3J5YCk7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIGF3YWl0IGdldEF2ZENvbmZpZ1BhdGhzKGF2ZHNSb290KTtcbn1cblxuLyoqXG4gKiBHZXQgY29uZmlndXJhdGlvbiBwYXRocyBvZiBhbGwgdmlydHVhbCBkZXZpY2VzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGF2ZHNSb290IFBhdGggdG8gdGhlIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIHRoZSBBVkQgLmluaSBmaWxlc1xuICogQHJldHVybnMge0FycmF5PEVtdUluZm8+fVxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRBdmRDb25maWdQYXRocyAoYXZkc1Jvb3QpIHtcbiAgY29uc3QgY29uZmlncyA9IGF3YWl0IGZzLmdsb2IoJyouaW5pJywge1xuICAgIGN3ZDogYXZkc1Jvb3QsXG4gICAgYWJzb2x1dGU6IHRydWUsXG4gIH0pO1xuICByZXR1cm4gY29uZmlncy5tYXAoKGNvbmZQYXRoKSA9PiB7XG4gICAgY29uc3QgYXZkTmFtZSA9IHBhdGguYmFzZW5hbWUoY29uZlBhdGgpLnNwbGl0KCcuJykuc2xpY2UoMCwgLTEpLmpvaW4oJy4nKTtcbiAgICByZXR1cm4ge25hbWU6IGF2ZE5hbWUsIGNvbmZpZzogY29uZlBhdGh9O1xuICB9KS5maWx0ZXIoKHtuYW1lfSkgPT4gXy50cmltKG5hbWUpKTtcbn1cblxuLyoqXG4gKiBDaGVjayB0aGUgZW11bGF0b3Igc3RhdGUuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBFbXVsYXRvciBpcyB2aXNpYmxlIHRvIGFkYi5cbiAqL1xuZW11TWV0aG9kcy5pc0VtdWxhdG9yQ29ubmVjdGVkID0gYXN5bmMgZnVuY3Rpb24gaXNFbXVsYXRvckNvbm5lY3RlZCAoKSB7XG4gIGxldCBlbXVsYXRvcnMgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZEVtdWxhdG9ycygpO1xuICByZXR1cm4gISFfLmZpbmQoZW11bGF0b3JzLCAoeCkgPT4geCAmJiB4LnVkaWQgPT09IHRoaXMuY3VyRGV2aWNlSWQpO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgdGhlIGVtdWxhdG9yIGlzIGNvbm5lY3RlZC5cbiAqXG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgRW11bGF0b3IgaXMgbm90IHZpc2libGUgdG8gYWRiLlxuICovXG5lbXVNZXRob2RzLnZlcmlmeUVtdWxhdG9yQ29ubmVjdGVkID0gYXN5bmMgZnVuY3Rpb24gdmVyaWZ5RW11bGF0b3JDb25uZWN0ZWQgKCkge1xuICBpZiAoIShhd2FpdCB0aGlzLmlzRW11bGF0b3JDb25uZWN0ZWQoKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBlbXVsYXRvciBcIiR7dGhpcy5jdXJEZXZpY2VJZH1cIiB3YXMgdW5leHBlY3RlZGx5IGRpc2Nvbm5lY3RlZGApO1xuICB9XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgZmluZ2VycHJpbnQgdG91Y2ggZXZlbnQgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmluZ2VycHJpbnRJZCAtIFRoZSBJRCBvZiB0aGUgZmluZ2VycHJpbnQuXG4gKi9cbmVtdU1ldGhvZHMuZmluZ2VycHJpbnQgPSBhc3luYyBmdW5jdGlvbiBmaW5nZXJwcmludCAoZmluZ2VycHJpbnRJZCkge1xuICBpZiAoIWZpbmdlcnByaW50SWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbmdlcnByaW50IGlkIHBhcmFtZXRlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgfVxuICAvLyB0aGUgbWV0aG9kIHVzZWQgb25seSB3b3JrcyBmb3IgQVBJIGxldmVsIDIzIGFuZCBhYm92ZVxuICBsZXQgbGV2ZWwgPSBhd2FpdCB0aGlzLmdldEFwaUxldmVsKCk7XG4gIGlmIChsZXZlbCA8IDIzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBEZXZpY2UgQVBJIExldmVsIG11c3QgYmUgPj0gMjMuIEN1cnJlbnQgQXBpIGxldmVsICcke2xldmVsfSdgKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydmaW5nZXInLCAndG91Y2gnLCBmaW5nZXJwcmludElkXSk7XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgZGlzcGxheSBvcmllbnRhdGlvbiBvbiB0aGUgY29ubmVjdGVkIGVtdWxhdG9yLlxuICogVGhlIG9yaWVudGF0aW9uIGlzIGNoYW5nZWQgKFBJLzIgaXMgYWRkZWQpIGV2ZXJ5IHRpbWVcbiAqIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC5cbiAqL1xuZW11TWV0aG9kcy5yb3RhdGUgPSBhc3luYyBmdW5jdGlvbiByb3RhdGUgKCkge1xuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydyb3RhdGUnXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgcG93ZXIgc3RhdGUgY2hhbmdlIG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlIFsnb24nXSAtIEVpdGhlciAnb24nIG9yICdvZmYnLlxuICovXG5lbXVNZXRob2RzLnBvd2VyQUMgPSBhc3luYyBmdW5jdGlvbiBwb3dlckFDIChzdGF0ZSA9ICdvbicpIHtcbiAgaWYgKF8udmFsdWVzKGVtdU1ldGhvZHMuUE9XRVJfQUNfU1RBVEVTKS5pbmRleE9mKHN0YXRlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBXcm9uZyBwb3dlciBBQyBzdGF0ZSBzZW50ICcke3N0YXRlfScuIGBcbiAgICAgICsgYFN1cHBvcnRlZCB2YWx1ZXM6ICR7Xy52YWx1ZXMoZW11TWV0aG9kcy5QT1dFUl9BQ19TVEFURVMpfV1gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydwb3dlcicsICdhYycsIHN0YXRlXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgc2Vuc29ycyB2YWx1ZXMgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc2Vuc29yIC0gU2Vuc29yIHR5cGUgZGVjbGFyZWQgaW4gU0VOU09SUyBpdGVtcy5cbiAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdmFsdWUgIC0gTnVtYmVyIHRvIHNldCBhcyB0aGUgc2Vuc29yIHZhbHVlLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgc2Vuc29yIHR5cGUgb3Igc2Vuc29yIHZhbHVlIGlzIG5vdCBkZWZpbmVkXG4gKi9cbmVtdU1ldGhvZHMuc2Vuc29yU2V0ID0gYXN5bmMgZnVuY3Rpb24gc2Vuc29yU2V0IChzZW5zb3IsIHZhbHVlKSB7XG4gIGlmICghXy5pbmNsdWRlcyhlbXVNZXRob2RzLlNFTlNPUlMsIHNlbnNvcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCBzZW5zb3Igc2VudCAnJHtzZW5zb3J9Jy4gYFxuICAgICAgKyBgU3VwcG9ydGVkIHZhbHVlczogJHtfLnZhbHVlcyhlbXVNZXRob2RzLlNFTlNPUlMpfV1gKTtcbiAgfVxuICBpZiAoXy5pc05pbCh2YWx1ZSkgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTWlzc2luZy9pbnZhbGlkIHNlbnNvciB2YWx1ZSBhcmd1bWVudC4gYFxuICAgICAgKyBgWW91IG5lZWQgdG8gcHJvdmlkZSBhIHZhbGlkIHZhbHVlIHRvIHNldCB0byB0aGUgc2Vuc29yIGluIGBcbiAgICAgICsgYGZvcm1hdCA8dmFsdWUtYT5bOjx2YWx1ZS1iPls6PHZhbHVlLWM+Wy4uLl1dXS5gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydzZW5zb3InLCAnc2V0Jywgc2Vuc29yLCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIHBvd2VyIGNhcGFjaXR5IGNoYW5nZSBvbiB0aGUgY29ubmVjdGVkIGVtdWxhdG9yLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gcGVyY2VudCBbMTAwXSAtIFBlcmNlbnRhZ2UgdmFsdWUgaW4gcmFuZ2UgWzAsIDEwMF0uXG4gKi9cbmVtdU1ldGhvZHMucG93ZXJDYXBhY2l0eSA9IGFzeW5jIGZ1bmN0aW9uIHBvd2VyQ2FwYWNpdHkgKHBlcmNlbnQgPSAxMDApIHtcbiAgcGVyY2VudCA9IHBhcnNlSW50KHBlcmNlbnQsIDEwKTtcbiAgaWYgKGlzTmFOKHBlcmNlbnQpIHx8IHBlcmNlbnQgPCAwIHx8IHBlcmNlbnQgPiAxMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBwZXJjZW50YWdlIHZhbHVlIHNob3VsZCBiZSB2YWxpZCBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwYCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsncG93ZXInLCAnY2FwYWNpdHknLCBwZXJjZW50XSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgcG93ZXIgb2ZmIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKi9cbmVtdU1ldGhvZHMucG93ZXJPRkYgPSBhc3luYyBmdW5jdGlvbiBwb3dlck9GRiAoKSB7XG4gIGF3YWl0IHRoaXMucG93ZXJBQyhlbXVNZXRob2RzLlBPV0VSX0FDX1NUQVRFUy5QT1dFUl9BQ19PRkYpO1xuICBhd2FpdCB0aGlzLnBvd2VyQ2FwYWNpdHkoMCk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgc2VuZCBTTVMgZXZlbnQgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHBob25lTnVtYmVyIC0gVGhlIHBob25lIG51bWJlciBvZiBtZXNzYWdlIHNlbmRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFsnJ10gLSBUaGUgbWVzc2FnZSBjb250ZW50LlxuICogQHRocm93cyB7ZXJyb3J9IElmIHBob25lIG51bWJlciBoYXMgaW52YWxpZCBmb3JtYXQuXG4gKi9cbmVtdU1ldGhvZHMuc2VuZFNNUyA9IGFzeW5jIGZ1bmN0aW9uIHNlbmRTTVMgKHBob25lTnVtYmVyLCBtZXNzYWdlID0gJycpIHtcbiAgbWVzc2FnZSA9IG1lc3NhZ2UudHJpbSgpO1xuICBpZiAobWVzc2FnZSA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlbmRpbmcgYW4gU01TIHJlcXVpcmVzIGEgbWVzc2FnZScpO1xuICB9XG4gIHBob25lTnVtYmVyID0gYCR7cGhvbmVOdW1iZXJ9YC5yZXBsYWNlKC9cXHMqLywgJycpO1xuICBpZiAoIVBIT05FX05VTUJFUl9QQVRURVJOLnRlc3QocGhvbmVOdW1iZXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNlbmRTTVMgcGhvbmVOdW1iZXIgcGFyYW0gJHtwaG9uZU51bWJlcn1gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydzbXMnLCAnc2VuZCcsIHBob25lTnVtYmVyLCBtZXNzYWdlXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgR1NNIGNhbGwgZXZlbnQgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHBob25lTnVtYmVyIC0gVGhlIHBob25lIG51bWJlciBvZiB0aGUgY2FsbGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiBbJyddIC0gT25lIG9mIGF2YWlsYWJsZSBHU00gY2FsbCBhY3Rpb25zLlxuICogQHRocm93cyB7ZXJyb3J9IElmIHBob25lIG51bWJlciBoYXMgaW52YWxpZCBmb3JtYXQuXG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgX2FjdGlvbl8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5nc21DYWxsID0gYXN5bmMgZnVuY3Rpb24gZ3NtQ2FsbCAocGhvbmVOdW1iZXIsIGFjdGlvbiA9ICcnKSB7XG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9DQUxMX0FDVElPTlMpLmluZGV4T2YoYWN0aW9uKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZ3NtIGFjdGlvbiBwYXJhbSAke2FjdGlvbn0uIFN1cHBvcnRlZCB2YWx1ZXM6ICR7Xy52YWx1ZXMoZW11TWV0aG9kcy5HU01fQ0FMTF9BQ1RJT05TKX1gKTtcbiAgfVxuICBwaG9uZU51bWJlciA9IGAke3Bob25lTnVtYmVyfWAucmVwbGFjZSgvXFxzKi8sICcnKTtcbiAgaWYgKCFQSE9ORV9OVU1CRVJfUEFUVEVSTi50ZXN0KHBob25lTnVtYmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBnc21DYWxsIHBob25lTnVtYmVyIHBhcmFtICR7cGhvbmVOdW1iZXJ9YCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsnZ3NtJywgYWN0aW9uLCBwaG9uZU51bWJlcl0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIEdTTSBzaWduYWwgc3RyZW5ndGggY2hhbmdlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHJlbmd0aCBbNF0gLSBBIG51bWJlciBpbiByYW5nZSBbMCwgNF07XG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgX3N0cmVuZ3RoXyB2YWx1ZSBpcyBpbnZhbGlkLlxuICovXG5lbXVNZXRob2RzLmdzbVNpZ25hbCA9IGFzeW5jIGZ1bmN0aW9uIGdzbVNpZ25hbCAoc3RyZW5ndGggPSA0KSB7XG4gIHN0cmVuZ3RoID0gcGFyc2VJbnQoc3RyZW5ndGgsIDEwKTtcbiAgaWYgKGVtdU1ldGhvZHMuR1NNX1NJR05BTF9TVFJFTkdUSFMuaW5kZXhPZihzdHJlbmd0aCkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNpZ25hbCBzdHJlbmd0aCBwYXJhbSAke3N0cmVuZ3RofS4gU3VwcG9ydGVkIHZhbHVlczogJHtfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9TSUdOQUxfU1RSRU5HVEhTKX1gKTtcbiAgfVxuICBsb2cuaW5mbygnZ3NtIHNpZ25hbC1wcm9maWxlIDxzdHJlbmd0aD4gY2hhbmdlcyB0aGUgcmVwb3J0ZWQgc3RyZW5ndGggb24gbmV4dCAoMTVzKSB1cGRhdGUuJyk7XG4gIGF3YWl0IHRoaXMuYWRiRXhlY0VtdShbJ2dzbScsICdzaWduYWwtcHJvZmlsZScsIHN0cmVuZ3RoXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgR1NNIHZvaWNlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlIFsnb24nXSAtIEVpdGhlciAnb24nIG9yICdvZmYnLlxuICogQHRocm93cyB7ZXJyb3J9IElmIF9zdGF0ZV8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5nc21Wb2ljZSA9IGFzeW5jIGZ1bmN0aW9uIGdzbVZvaWNlIChzdGF0ZSA9ICdvbicpIHtcbiAgLy8gZ3NtIHZvaWNlIDxzdGF0ZT4gYWxsb3dzIHlvdSB0byBjaGFuZ2UgdGhlIHN0YXRlIG9mIHlvdXIgR1BSUyBjb25uZWN0aW9uXG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9WT0lDRV9TVEFURVMpLmluZGV4T2Yoc3RhdGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBnc20gdm9pY2Ugc3RhdGUgcGFyYW0gJHtzdGF0ZX0uIFN1cHBvcnRlZCB2YWx1ZXM6ICR7Xy52YWx1ZXMoZW11TWV0aG9kcy5HU01fVk9JQ0VfU1RBVEVTKX1gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydnc20nLCAndm9pY2UnLCBzdGF0ZV0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIG5ldHdvcmsgc3BlZWQgY2hhbmdlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNwZWVkIFsnZnVsbCddIC0gT25lIG9mIHBvc3NpYmxlIE5FVFdPUktfU1BFRUQgdmFsdWVzLlxuICogQHRocm93cyB7ZXJyb3J9IElmIF9zcGVlZF8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5uZXR3b3JrU3BlZWQgPSBhc3luYyBmdW5jdGlvbiBuZXR3b3JrU3BlZWQgKHNwZWVkID0gJ2Z1bGwnKSB7XG4gIC8vIG5ldHdvcmsgc3BlZWQgPHNwZWVkPiBhbGxvd3MgeW91IHRvIHNldCB0aGUgbmV0d29yayBzcGVlZCBlbXVsYXRpb24uXG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLk5FVFdPUktfU1BFRUQpLmluZGV4T2Yoc3BlZWQpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBuZXR3b3JrIHNwZWVkIHBhcmFtICR7c3BlZWR9LiBTdXBwb3J0ZWQgdmFsdWVzOiAke18udmFsdWVzKGVtdU1ldGhvZHMuTkVUV09SS19TUEVFRCl9YCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsnbmV0d29yaycsICdzcGVlZCcsIHNwZWVkXSk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEV4ZWNUZWxuZXRPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXhlY1RpbWVvdXQgWzYwMDAwXSBBIHRpbWVvdXQgdXNlZCB0byB3YWl0IGZvciBhIHNlcnZlclxuICogcmVwbHkgdG8gdGhlIGdpdmVuIGNvbW1hbmRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb25uVGltZW91dCBbNTAwMF0gQ29uc29sZSBjb25uZWN0aW9uIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5pdFRpbWVvdXQgWzUwMDBdIFRlbG5ldCBjb25zb2xlIGluaXRpYWxpemF0aW9uIHRpbWVvdXRcbiAqIGluIG1pbGxpc2Vjb25kcyAodGhlIHRpbWUgYmV0d2VlbiBjb25uZWN0aW9uIGhhcHBlbnMgYW5kIHRoZSBjb21tYW5kIHByb21wdFxuICogaXMgYXZhaWxhYmxlKVxuICogQHByb3BlcnR5IHs/bnVtYmVyfHN0cmluZ30gcG9ydCBUaGUgZW11bGF0b3IgcG9ydCBudW1iZXIuIFRoZSBtZXRob2Qgd2lsbCB0cnkgdG8gcGFyc2UgaXRcbiAqIGZyb20gdGhlIGN1cnJlbnQgZGV2aWNlIGlkZW50aWZpZXIgaWYgdW5zZXRcbiAqL1xuXG4vKipcbiAqIEV4ZWN1dGVzIGEgY29tbWFuZCB0aHJvdWdoIGVtdWxhdG9yIHRlbG5ldCBjb25zb2xlIGludGVyZmFjZSBhbmQgcmV0dXJucyBpdHMgb3V0cHV0XG4gKlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fHN0cmluZ30gY21kIC0gVGhlIGFjdHVhbCBjb21tYW5kIHRvIGV4ZWN1dGUuIFNlZVxuICogaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vc3R1ZGlvL3J1bi9lbXVsYXRvci1jb25zb2xlIGZvciBtb3JlIGRldGFpbHNcbiAqIG9uIGF2YWlsYWJsZSBjb21tYW5kc1xuICogQHBhcmFtIHtFeGVjVGVsbmV0T3B0aW9uc30gb3B0c1xuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbW1hbmQgb3V0cHV0XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGFuIGVycm9yIHdoaWxlIGNvbm5lY3RpbmcgdG8gdGhlIFRlbG5ldCBjb25zb2xlXG4gKiBvciBpZiB0aGUgZ2l2ZW4gY29tbWFuZCByZXR1cm5lZCBub24tT0sgcmVzcG9uc2VcbiAqL1xuZW11TWV0aG9kcy5leGVjRW11Q29uc29sZUNvbW1hbmQgPSBhc3luYyBmdW5jdGlvbiBleGVjVGVsbmV0IChjbWQsIG9wdHMgPSB7fSkge1xuICBsZXQgcG9ydCA9IHBhcnNlSW50KG9wdHMucG9ydCwgMTApO1xuICBpZiAoIXBvcnQpIHtcbiAgICBjb25zdCBwb3J0TWF0Y2ggPSAvZW11bGF0b3ItKFxcZCspL2kuZXhlYyh0aGlzLmN1ckRldmljZUlkKTtcbiAgICBpZiAoIXBvcnRNYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcGFyc2UgdGhlIGNvbnNvbGUgcG9ydCBudW1iZXIgZnJvbSB0aGUgZGV2aWNlIGlkZW50aWZpZXIgJyR7dGhpcy5jdXJEZXZpY2VJZH0nLiBgICtcbiAgICAgICAgYElzIGl0IGFuIGVtdWxhdG9yP2ApO1xuICAgIH1cbiAgICBwb3J0ID0gcGFyc2VJbnQocG9ydE1hdGNoWzFdLCAxMCk7XG4gIH1cbiAgY29uc3QgaG9zdCA9ICcxMjcuMC4wLjEnO1xuICBjb25zdCB7XG4gICAgZXhlY1RpbWVvdXQgPSA2MDAwMCxcbiAgICBjb25uVGltZW91dCA9IDUwMDAsXG4gICAgaW5pdFRpbWVvdXQgPSA1MDAwLFxuICB9ID0gb3B0cztcbiAgYXdhaXQgdGhpcy5yZXNldFRlbG5ldEF1dGhUb2tlbigpO1xuXG4gIGNvbnN0IG9rRmxhZyA9IC9eT0skL207XG4gIGNvbnN0IG5va0ZsYWcgPSAvXktPXFxiL207XG4gIGNvbnN0IGVvbCA9ICdcXHJcXG4nO1xuICBjb25zdCBjbGllbnQgPSBuZXQuY29ubmVjdCh7XG4gICAgaG9zdCxcbiAgICBwb3J0LFxuICB9KTtcblxuICByZXR1cm4gYXdhaXQgbmV3IEIoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNvbm5UaW1lb3V0T2JqID0gc2V0VGltZW91dChcbiAgICAgICgpID0+IHJlamVjdChuZXcgRXJyb3IoYENhbm5vdCBjb25uZWN0IHRvIHRoZSBFbXVsYXRvciBjb25zb2xlIGF0ICR7aG9zdH06JHtwb3J0fSBgICtcbiAgICAgICAgYGFmdGVyICR7Y29ublRpbWVvdXR9bXNgKSksIGNvbm5UaW1lb3V0KTtcbiAgICBsZXQgZXhlY1RpbWVvdXRPYmo7XG4gICAgbGV0IGluaXRUaW1lb3V0T2JqO1xuICAgIGxldCBpc0NvbW1hbmRTZW50ID0gZmFsc2U7XG4gICAgbGV0IHNlcnZlclJlc3BvbnNlID0gW107XG5cbiAgICBjbGllbnQub25jZSgnZXJyb3InLCAoZSkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KGNvbm5UaW1lb3V0T2JqKTtcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoYENhbm5vdCBjb25uZWN0IHRvIHRoZSBFbXVsYXRvciBjb25zb2xlIGF0ICR7aG9zdH06JHtwb3J0fS4gYCArXG4gICAgICAgIGBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCkpO1xuICAgIH0pO1xuXG4gICAgY2xpZW50Lm9uY2UoJ2Nvbm5lY3QnLCAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoY29ublRpbWVvdXRPYmopO1xuICAgICAgaW5pdFRpbWVvdXRPYmogPSBzZXRUaW1lb3V0KFxuICAgICAgICAoKSA9PiByZWplY3QobmV3IEVycm9yKGBEaWQgbm90IGdldCB0aGUgaW5pdGlhbCByZXNwb25zZSBmcm9tIHRoZSBFbXVsYXRvciBjb25zb2xlIGF0ICR7aG9zdH06JHtwb3J0fSBgICtcbiAgICAgICAgICBgYWZ0ZXIgJHtpbml0VGltZW91dH1tc2ApKSwgaW5pdFRpbWVvdXQpO1xuICAgIH0pO1xuXG4gICAgY2xpZW50Lm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICBzZXJ2ZXJSZXNwb25zZS5wdXNoKGNodW5rKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IEJ1ZmZlci5jb25jYXQoc2VydmVyUmVzcG9uc2UpLnRvU3RyaW5nKCd1dGY4JykudHJpbSgpO1xuICAgICAgaWYgKG9rRmxhZy50ZXN0KG91dHB1dCkpIHtcbiAgICAgICAgLy8gVGhlIGluaXRpYWwgaW5jb21pbmcgZGF0YSBjaHVuayBjb25maXJtcyB0aGUgaW50ZXJmYWNlIGlzIHJlYWR5IGZvciBpbnB1dFxuICAgICAgICBpZiAoIWlzQ29tbWFuZFNlbnQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaW5pdFRpbWVvdXRPYmopO1xuICAgICAgICAgIHNlcnZlclJlc3BvbnNlID0gW107XG4gICAgICAgICAgY29uc3QgY21kU3RyID0gXy5pc0FycmF5KGNtZCkgPyB1dGlsLnF1b3RlKGNtZCkgOiBgJHtjbWR9YDtcbiAgICAgICAgICBsb2cuZGVidWcoYEV4ZWN1dGluZyBFbXVsYXRvciBjb25zb2xlIGNvbW1hbmQ6ICR7Y21kU3RyfWApO1xuICAgICAgICAgIGNsaWVudC53cml0ZShjbWRTdHIpO1xuICAgICAgICAgIGNsaWVudC53cml0ZShlb2wpO1xuICAgICAgICAgIGlzQ29tbWFuZFNlbnQgPSB0cnVlO1xuICAgICAgICAgIGV4ZWNUaW1lb3V0T2JqID0gc2V0VGltZW91dChcbiAgICAgICAgICAgICgpID0+IHJlamVjdChuZXcgRXJyb3IoYERpZCBub3QgZ2V0IGFueSByZXNwb25zZSBmcm9tIHRoZSBFbXVsYXRvciBjb25zb2xlIGF0ICR7aG9zdH06JHtwb3J0fSBgICtcbiAgICAgICAgICAgICAgYHRvICcke2NtZH0nIGNvbW1hbmQgYWZ0ZXIgJHtleGVjVGltZW91dH1tc2ApKSwgZXhlY1RpbWVvdXQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjbGVhclRpbWVvdXQoZXhlY1RpbWVvdXRPYmopO1xuICAgICAgICBjbGllbnQuZW5kKCk7XG4gICAgICAgIGNvbnN0IG91dHB1dEFyciA9IG91dHB1dC5zcGxpdChlb2wpO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHJlZHVuZGFudCBPSyBmbGFnIGZyb20gdGhlIHJlc3VsdGluZyBjb21tYW5kIG91dHB1dFxuICAgICAgICByZXR1cm4gcmVzb2x2ZShvdXRwdXRBcnIuc2xpY2UoMCwgb3V0cHV0QXJyLmxlbmd0aCAtIDEpLmpvaW4oJ1xcbicpLnRyaW0oKSk7XG4gICAgICB9IGVsc2UgaWYgKG5va0ZsYWcudGVzdChvdXRwdXQpKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChpbml0VGltZW91dE9iaik7XG4gICAgICAgIGNsZWFyVGltZW91dChleGVjVGltZW91dE9iaik7XG4gICAgICAgIGNsaWVudC5lbmQoKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0QXJyID0gb3V0cHV0LnNwbGl0KGVvbCk7XG4gICAgICAgIHJldHVybiByZWplY3QoXy50cmltKF8ubGFzdChvdXRwdXRBcnIpKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbXVWZXJzaW9uSW5mb1xuICogQHByb3BlcnR5IHs/c3RyaW5nfSByZXZpc2lvbiBUaGUgYWN0dWFsIHJldmlzaW9uIG51bWJlciwgZm9yIGV4YW1wbGUgJzMwLjAuNSdcbiAqIEBwcm9wZXJ0eSB7P251bWJlcn0gYnVpbGRJZCBUaGUgYnVpbGQgaWRlbnRpZmllciwgZm9yIGV4YW1wbGUgNjMwNjA0N1xuICovXG5cbi8qKlxuICogUmV0cmlldmVzIGVtdWxhdG9yIHZlcnNpb24gZnJvbSB0aGUgZmlsZSBzeXN0ZW1cbiAqXG4gKiBAcmV0dXJucyB7RW11VmVyc2lvbkluZm99IElmIG5vIHZlcnNpb24gaW5mbyBjb3VsZCBiZSBwYXJzZWQgdGhlbiBhbiBlbXB0eVxuICogb2JqZWN0IGlzIHJldHVybmVkXG4gKi9cbmVtdU1ldGhvZHMuZ2V0RW11VmVyc2lvbkluZm8gPSBhc3luYyBmdW5jdGlvbiBnZXRFbXVWZXJzaW9uSW5mbyAoKSB7XG4gIGNvbnN0IHByb3BzUGF0aCA9IHBhdGguam9pbih0aGlzLnNka1Jvb3QsICdlbXVsYXRvcicsICdzb3VyY2UucHJvcGVydGllcycpO1xuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhwcm9wc1BhdGgpKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHByb3BzUGF0aCwgJ3V0ZjgnKTtcbiAgY29uc3QgcmV2aXNpb25NYXRjaCA9IC9eUGtnXFwuUmV2aXNpb249KFtcXGQuXSspJC9tLmV4ZWMoY29udGVudCk7XG4gIGNvbnN0IHJlc3VsdCA9IHt9O1xuICBpZiAocmV2aXNpb25NYXRjaCkge1xuICAgIHJlc3VsdC5yZXZpc2lvbiA9IHJldmlzaW9uTWF0Y2hbMV07XG4gIH1cbiAgY29uc3QgYnVpbGRJZE1hdGNoID0gL15Qa2dcXC5CdWlsZElkPShcXGQrKSQvbS5leGVjKGNvbnRlbnQpO1xuICBpZiAoYnVpbGRJZE1hdGNoKSB7XG4gICAgcmVzdWx0LmJ1aWxkSWQgPSBwYXJzZUludChidWlsZElkTWF0Y2hbMV0sIDEwKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgZW11bGF0b3IgaW1hZ2UgcHJvcGVydGllcyBmcm9tIHRoZSBsb2NhbCBmaWxlIHN5c3RlbVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhdmROYW1lIEVtdWxhdG9yIG5hbWUuIFNob3VsZCBOT1Qgc3RhcnQgd2l0aCAnQCcgY2hhcmFjdGVyXG4gKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlcmUgd2FzIGEgZmFpbHVyZSB3aGlsZSBleHRyYWN0aW5nIHRoZSBwcm9wZXJ0aWVzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgY29udGVudCBvZiBlbXVsYXRvciBpbWFnZSBwcm9wZXJ0aWVzIGZpbGUuXG4gKiBVc3VhbGx5IHRoaXMgY29uZmlndXJhdGlvbiAuaW5pIGZpbGUgaGFzIHRoZSBmb2xsb3dpbmcgY29udGVudDpcbiAqICAgYXZkLmluaS5lbmNvZGluZz1VVEYtOFxuICogICBwYXRoPS9Vc2Vycy91c2VybmFtZS8uYW5kcm9pZC9hdmQvUGl4ZWxfWExfQVBJXzMwLmF2ZFxuICogICBwYXRoLnJlbD1hdmQvUGl4ZWxfWExfQVBJXzMwLmF2ZFxuICogICB0YXJnZXQ9YW5kcm9pZC0zMFxuICovXG5lbXVNZXRob2RzLmdldEVtdUltYWdlUHJvcGVydGllcyA9IGFzeW5jIGZ1bmN0aW9uIGdldEVtdUltYWdlUHJvcGVydGllcyAoYXZkTmFtZSkge1xuICBjb25zdCBhdmRzID0gYXdhaXQgbGlzdEVtdWxhdG9ycygpO1xuICBjb25zdCBhdmQgPSBhdmRzLmZpbmQoKHtuYW1lfSkgPT4gbmFtZSA9PT0gYXZkTmFtZSk7XG4gIGlmICghYXZkKSB7XG4gICAgbGV0IG1zZyA9IGBDYW5ub3QgZmluZCAnJHthdmROYW1lfScgZW11bGF0b3IuIGA7XG4gICAgaWYgKF8uaXNFbXB0eShhdmRzKSkge1xuICAgICAgbXNnICs9IGBObyBlbXVsYXRvcnMgaGF2ZSBiZWVuIGRldGVjdGVkIG9uIHlvdXIgc3lzdGVtYDtcbiAgICB9IGVsc2Uge1xuICAgICAgbXNnICs9IGBBdmFpbGFibGUgYXZkIG5hbWVzIGFyZTogJHthdmRzLm1hcCgoe25hbWV9KSA9PiBuYW1lKX1gO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgfVxuICByZXR1cm4gaW5pLnBhcnNlKGF3YWl0IGZzLnJlYWRGaWxlKGF2ZC5jb25maWcsICd1dGY4JykpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBnaXZlbiBlbXVsYXRvciBleGlzdHMgaW4gdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIGF2ZHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGF2ZE5hbWUgLSBUaGUgbmFtZSBvZiBlbXVsYXRvciB0byB2ZXJpZnkgZm9yIGV4aXN0ZW5jZS5cbiAqIFNob3VsZCBOT1Qgc3RhcnQgd2l0aCAnQCcgY2hhcmFjdGVyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGVtdWxhdG9yIHdpdGggZ2l2ZW4gbmFtZSBkb2VzIG5vdCBleGlzdC5cbiAqL1xuZW11TWV0aG9kcy5jaGVja0F2ZEV4aXN0ID0gYXN5bmMgZnVuY3Rpb24gY2hlY2tBdmRFeGlzdCAoYXZkTmFtZSkge1xuICBjb25zdCBhdmRzID0gYXdhaXQgbGlzdEVtdWxhdG9ycygpO1xuICBpZiAoIWF2ZHMuc29tZSgoe25hbWV9KSA9PiBuYW1lID09PSBhdmROYW1lKSkge1xuICAgIGxldCBtc2cgPSBgQXZkICcke2F2ZE5hbWV9JyBpcyBub3QgYXZhaWxhYmxlLiBgO1xuICAgIGlmIChfLmlzRW1wdHkoYXZkcykpIHtcbiAgICAgIG1zZyArPSBgTm8gZW11bGF0b3JzIGhhdmUgYmVlbiBkZXRlY3RlZCBvbiB5b3VyIHN5c3RlbWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1zZyArPSBgUGxlYXNlIHNlbGVjdCB5b3VyIGF2ZCBuYW1lIGZyb20gb25lIG9mIHRoZXNlOiAnJHthdmRzLm1hcCgoe25hbWV9KSA9PiBuYW1lKX0nYDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBlbXVNZXRob2RzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLG9CQUFvQixHQUFHLHFEQUE3QjtBQUVBLE1BQU1DLFVBQVUsR0FBRyxFQUFuQjtBQUNBQSxVQUFVLENBQUNDLGVBQVgsR0FBNkJDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0VBQ3pDQyxXQUFXLEVB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