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.
- package/README.md +1 -1
- package/lib/helpers.js +26 -3
- package/lib/tools/apk-signing.js +3 -4
- package/package.json +39 -26
- package/build/index.js +0 -30
- package/build/lib/adb.js +0 -132
- package/build/lib/helpers.js +0 -957
- package/build/lib/logcat.js +0 -221
- package/build/lib/logger.js +0 -18
- package/build/lib/tools/aab-utils.js +0 -157
- package/build/lib/tools/adb-commands.js +0 -1150
- package/build/lib/tools/adb-emu-commands.js +0 -397
- package/build/lib/tools/android-manifest.js +0 -231
- package/build/lib/tools/apk-signing.js +0 -333
- package/build/lib/tools/apk-utils.js +0 -992
- package/build/lib/tools/apks-utils.js +0 -219
- package/build/lib/tools/index.js +0 -49
- package/build/lib/tools/keyboard-commands.js +0 -71
- package/build/lib/tools/lockmgmt.js +0 -224
- package/build/lib/tools/settings-client-commands.js +0 -362
- package/build/lib/tools/system-calls.js +0 -1064
package/build/lib/helpers.js
DELETED
|
@@ -1,957 +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_ADB_EXEC_TIMEOUT = exports.APK_INSTALL_TIMEOUT = exports.APK_EXTENSION = exports.APKS_INSTALL_TIMEOUT = exports.APKS_EXTENSION = void 0;
|
|
9
|
-
exports.buildInstallArgs = buildInstallArgs;
|
|
10
|
-
exports.buildStartCmd = buildStartCmd;
|
|
11
|
-
exports.dirExists = dirExists;
|
|
12
|
-
exports.escapeShellArg = escapeShellArg;
|
|
13
|
-
exports.extractMatchingPermissions = void 0;
|
|
14
|
-
exports.formatConfigMarker = formatConfigMarker;
|
|
15
|
-
exports.getAndroidPlatformAndPath = getAndroidPlatformAndPath;
|
|
16
|
-
exports.getAndroidPrefsRoot = getAndroidPrefsRoot;
|
|
17
|
-
exports.getApkanalyzerForOs = getApkanalyzerForOs;
|
|
18
|
-
exports.getApksignerForOs = getApksignerForOs;
|
|
19
|
-
exports.getBuildToolsDirs = void 0;
|
|
20
|
-
exports.getIMEListFromOutput = getIMEListFromOutput;
|
|
21
|
-
exports.getOpenSslForOs = exports.getJavaHome = exports.getJavaForOs = void 0;
|
|
22
|
-
exports.getSdkRootFromEnv = getSdkRootFromEnv;
|
|
23
|
-
exports.getSdkToolsVersion = void 0;
|
|
24
|
-
exports.getSurfaceOrientation = getSurfaceOrientation;
|
|
25
|
-
exports.isCurrentFocusOnKeyguard = isCurrentFocusOnKeyguard;
|
|
26
|
-
exports.isScreenOnFully = isScreenOnFully;
|
|
27
|
-
exports.isShowingLockscreen = isShowingLockscreen;
|
|
28
|
-
exports.matchComponentName = matchComponentName;
|
|
29
|
-
exports.parseAapt2Strings = parseAapt2Strings;
|
|
30
|
-
exports.parseAaptStrings = parseAaptStrings;
|
|
31
|
-
exports.parseJsonData = parseJsonData;
|
|
32
|
-
exports.parseLaunchableActivityNames = parseLaunchableActivityNames;
|
|
33
|
-
exports.parseManifest = parseManifest;
|
|
34
|
-
exports.requireSdkRoot = requireSdkRoot;
|
|
35
|
-
exports.rootDir = void 0;
|
|
36
|
-
exports.toAvdLocaleArgs = toAvdLocaleArgs;
|
|
37
|
-
exports.unsignApk = unsignApk;
|
|
38
|
-
exports.unzipFile = unzipFile;
|
|
39
|
-
|
|
40
|
-
require("source-map-support/register");
|
|
41
|
-
|
|
42
|
-
var _path = _interopRequireDefault(require("path"));
|
|
43
|
-
|
|
44
|
-
var _support = require("@appium/support");
|
|
45
|
-
|
|
46
|
-
var _logger = _interopRequireDefault(require("./logger.js"));
|
|
47
|
-
|
|
48
|
-
var _lodash = _interopRequireDefault(require("lodash"));
|
|
49
|
-
|
|
50
|
-
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
51
|
-
|
|
52
|
-
var _semver = _interopRequireDefault(require("semver"));
|
|
53
|
-
|
|
54
|
-
var _os = _interopRequireDefault(require("os"));
|
|
55
|
-
|
|
56
|
-
const rootDir = _path.default.resolve(__dirname, process.env.NO_PRECOMPILE ? '..' : '../..');
|
|
57
|
-
|
|
58
|
-
exports.rootDir = rootDir;
|
|
59
|
-
const APKS_EXTENSION = '.apks';
|
|
60
|
-
exports.APKS_EXTENSION = APKS_EXTENSION;
|
|
61
|
-
const APK_EXTENSION = '.apk';
|
|
62
|
-
exports.APK_EXTENSION = APK_EXTENSION;
|
|
63
|
-
const APK_INSTALL_TIMEOUT = 60000;
|
|
64
|
-
exports.APK_INSTALL_TIMEOUT = APK_INSTALL_TIMEOUT;
|
|
65
|
-
const APKS_INSTALL_TIMEOUT = APK_INSTALL_TIMEOUT * 2;
|
|
66
|
-
exports.APKS_INSTALL_TIMEOUT = APKS_INSTALL_TIMEOUT;
|
|
67
|
-
const DEFAULT_ADB_EXEC_TIMEOUT = 20000;
|
|
68
|
-
exports.DEFAULT_ADB_EXEC_TIMEOUT = DEFAULT_ADB_EXEC_TIMEOUT;
|
|
69
|
-
const MAIN_ACTION = 'android.intent.action.MAIN';
|
|
70
|
-
const LAUNCHER_CATEGORY = 'android.intent.category.LAUNCHER';
|
|
71
|
-
|
|
72
|
-
function getSdkRootFromEnv() {
|
|
73
|
-
return process.env.ANDROID_HOME || process.env.ANDROID_SDK_ROOT;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function requireSdkRoot(customRoot = null) {
|
|
77
|
-
const sdkRoot = customRoot || getSdkRootFromEnv();
|
|
78
|
-
const docMsg = 'Read https://developer.android.com/studio/command-line/variables for more details';
|
|
79
|
-
|
|
80
|
-
if (_lodash.default.isEmpty(sdkRoot)) {
|
|
81
|
-
throw new Error(`Neither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable was exported. ${docMsg}`);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!(await _support.fs.exists(sdkRoot))) {
|
|
85
|
-
throw new Error(`The Android SDK root folder '${sdkRoot}' does not exist on the local file system. ${docMsg}`);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const stats = await _support.fs.stat(sdkRoot);
|
|
89
|
-
|
|
90
|
-
if (!stats.isDirectory()) {
|
|
91
|
-
throw new Error(`The Android SDK root '${sdkRoot}' must be a folder. ${docMsg}`);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return sdkRoot;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function getAndroidPlatformAndPath(sdkRoot) {
|
|
98
|
-
const propsPaths = await _support.fs.glob('*/build.prop', {
|
|
99
|
-
cwd: _path.default.resolve(sdkRoot, 'platforms'),
|
|
100
|
-
absolute: true
|
|
101
|
-
});
|
|
102
|
-
const platformsMapping = {};
|
|
103
|
-
|
|
104
|
-
for (const propsPath of propsPaths) {
|
|
105
|
-
const propsContent = await _support.fs.readFile(propsPath, 'utf-8');
|
|
106
|
-
|
|
107
|
-
const platformPath = _path.default.dirname(propsPath);
|
|
108
|
-
|
|
109
|
-
const platform = _path.default.basename(platformPath);
|
|
110
|
-
|
|
111
|
-
const match = /ro\.build\.version\.sdk=(\d+)/.exec(propsContent);
|
|
112
|
-
|
|
113
|
-
if (!match) {
|
|
114
|
-
_logger.default.warn(`Cannot read the SDK version from '${propsPath}'. Skipping '${platform}'`);
|
|
115
|
-
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
platformsMapping[parseInt(match[1], 10)] = {
|
|
120
|
-
platform,
|
|
121
|
-
platformPath
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (_lodash.default.isEmpty(platformsMapping)) {
|
|
126
|
-
_logger.default.warn(`Found zero platform folders at '${_path.default.resolve(sdkRoot, 'platforms')}'. ` + `Do you have any Android SDKs installed?`);
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
platform: null,
|
|
130
|
-
platformPath: null
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const recentSdkVersion = _lodash.default.keys(platformsMapping).sort().reverse()[0];
|
|
135
|
-
|
|
136
|
-
const result = platformsMapping[recentSdkVersion];
|
|
137
|
-
|
|
138
|
-
_logger.default.debug(`Found the most recent Android platform: ${JSON.stringify(result)}`);
|
|
139
|
-
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function unzipFile(zipPath, dstRoot = _path.default.dirname(zipPath)) {
|
|
144
|
-
_logger.default.debug(`Unzipping '${zipPath}' to '${dstRoot}'`);
|
|
145
|
-
|
|
146
|
-
await _support.zip.assertValidZip(zipPath);
|
|
147
|
-
await _support.zip.extractAllTo(zipPath, dstRoot);
|
|
148
|
-
|
|
149
|
-
_logger.default.debug('Unzip successful');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function unsignApk(apkPath) {
|
|
153
|
-
const tmpRoot = await _support.tempDir.openDir();
|
|
154
|
-
const metaInfFolderName = 'META-INF';
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
let hasMetaInf = false;
|
|
158
|
-
await _support.zip.readEntries(apkPath, ({
|
|
159
|
-
entry
|
|
160
|
-
}) => {
|
|
161
|
-
hasMetaInf = entry.fileName.startsWith(`${metaInfFolderName}/`);
|
|
162
|
-
return !hasMetaInf;
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
if (!hasMetaInf) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const tmpZipRoot = _path.default.resolve(tmpRoot, 'apk');
|
|
170
|
-
|
|
171
|
-
await _support.zip.extractAllTo(apkPath, tmpZipRoot);
|
|
172
|
-
await _support.fs.rimraf(_path.default.resolve(tmpZipRoot, metaInfFolderName));
|
|
173
|
-
|
|
174
|
-
const tmpResultPath = _path.default.resolve(tmpRoot, _path.default.basename(apkPath));
|
|
175
|
-
|
|
176
|
-
await _support.zip.toArchive(tmpResultPath, {
|
|
177
|
-
cwd: tmpZipRoot
|
|
178
|
-
});
|
|
179
|
-
await _support.fs.unlink(apkPath);
|
|
180
|
-
await _support.fs.mv(tmpResultPath, apkPath);
|
|
181
|
-
return true;
|
|
182
|
-
} finally {
|
|
183
|
-
await _support.fs.rimraf(tmpRoot);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function getIMEListFromOutput(stdout) {
|
|
188
|
-
let engines = [];
|
|
189
|
-
|
|
190
|
-
for (let line of stdout.split('\n')) {
|
|
191
|
-
if (line.length > 0 && line[0] !== ' ') {
|
|
192
|
-
engines.push(line.trim().replace(/:$/, ''));
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return engines;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const getJavaHome = _lodash.default.memoize(async function getJavaHome() {
|
|
200
|
-
const result = process.env.JAVA_HOME;
|
|
201
|
-
|
|
202
|
-
if (!result) {
|
|
203
|
-
throw new Error('The JAVA_HOME environment variable is not set for the current process');
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (!(await _support.fs.exists(result))) {
|
|
207
|
-
throw new Error(`The JAVA_HOME location '${result}' must exist`);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const stats = await _support.fs.stat(result);
|
|
211
|
-
|
|
212
|
-
if (!stats.isDirectory()) {
|
|
213
|
-
throw new Error(`The JAVA_HOME location '${result}' must be a valid folder`);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return result;
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
exports.getJavaHome = getJavaHome;
|
|
220
|
-
|
|
221
|
-
const getJavaForOs = _lodash.default.memoize(async function getJavaForOs() {
|
|
222
|
-
let javaHome;
|
|
223
|
-
let errMsg;
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
javaHome = await getJavaHome();
|
|
227
|
-
} catch (err) {
|
|
228
|
-
errMsg = err.message;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const executableName = `java${_support.system.isWindows() ? '.exe' : ''}`;
|
|
232
|
-
|
|
233
|
-
if (javaHome) {
|
|
234
|
-
const resultPath = _path.default.resolve(javaHome, 'bin', executableName);
|
|
235
|
-
|
|
236
|
-
if (await _support.fs.exists(resultPath)) {
|
|
237
|
-
return resultPath;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
return await _support.fs.which(executableName);
|
|
243
|
-
} catch (ign) {}
|
|
244
|
-
|
|
245
|
-
throw new Error(`The '${executableName}' binary could not be found ` + `neither in PATH nor under JAVA_HOME (${errMsg || _path.default.resolve(javaHome, 'bin')})`);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
exports.getJavaForOs = getJavaForOs;
|
|
249
|
-
|
|
250
|
-
const getOpenSslForOs = async function () {
|
|
251
|
-
const binaryName = `openssl${_support.system.isWindows() ? '.exe' : ''}`;
|
|
252
|
-
|
|
253
|
-
try {
|
|
254
|
-
return await _support.fs.which(binaryName);
|
|
255
|
-
} catch (err) {
|
|
256
|
-
throw new Error('The openssl tool must be installed on the system and available on the path');
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
exports.getOpenSslForOs = getOpenSslForOs;
|
|
261
|
-
|
|
262
|
-
async function getApksignerForOs(sysHelpers) {
|
|
263
|
-
return await sysHelpers.getBinaryFromSdkRoot('apksigner.jar');
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
async function getApkanalyzerForOs(sysHelpers) {
|
|
267
|
-
return await sysHelpers.getBinaryFromSdkRoot('apkanalyzer');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function isShowingLockscreen(dumpsys) {
|
|
271
|
-
return _lodash.default.some(['mShowingLockscreen=true', 'mDreamingLockscreen=true'], x => dumpsys.includes(x)) || _lodash.default.every([/KeyguardStateMonitor[\n\s]+mIsShowing=true/, /\s+mInputRestricted=true/], x => x.test(dumpsys));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function isCurrentFocusOnKeyguard(dumpsys) {
|
|
275
|
-
let m = /mCurrentFocus.+Keyguard/gi.exec(dumpsys);
|
|
276
|
-
return m && m.length && m[0] ? true : false;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function getSurfaceOrientation(dumpsys) {
|
|
280
|
-
let m = /SurfaceOrientation: \d/gi.exec(dumpsys);
|
|
281
|
-
return m && parseInt(m[0].split(':')[1], 10);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function isScreenOnFully(dumpsys) {
|
|
285
|
-
let m = /mScreenOnFully=\w+/gi.exec(dumpsys);
|
|
286
|
-
return !m || m && m.length > 0 && m[0].split('=')[1] === 'true' || false;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function buildStartCmd(startAppOptions, apiLevel) {
|
|
290
|
-
const {
|
|
291
|
-
user,
|
|
292
|
-
waitForLaunch,
|
|
293
|
-
pkg,
|
|
294
|
-
activity,
|
|
295
|
-
action,
|
|
296
|
-
category,
|
|
297
|
-
stopApp,
|
|
298
|
-
flags
|
|
299
|
-
} = startAppOptions;
|
|
300
|
-
const cmd = ['am', 'start'];
|
|
301
|
-
|
|
302
|
-
if (_support.util.hasValue(user)) {
|
|
303
|
-
cmd.push('--user', user);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (waitForLaunch) {
|
|
307
|
-
cmd.push('-W');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (activity && pkg) {
|
|
311
|
-
cmd.push('-n', `${pkg}/${activity}`);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (stopApp && apiLevel >= 15) {
|
|
315
|
-
cmd.push('-S');
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (action) {
|
|
319
|
-
cmd.push('-a', action);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (category) {
|
|
323
|
-
cmd.push('-c', category);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (flags) {
|
|
327
|
-
cmd.push('-f', flags);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (startAppOptions.optionalIntentArguments) {
|
|
331
|
-
let parseKeyValue = function (str) {
|
|
332
|
-
str = str.trim();
|
|
333
|
-
let space = str.indexOf(' ');
|
|
334
|
-
|
|
335
|
-
if (space === -1) {
|
|
336
|
-
return str.length ? [str] : [];
|
|
337
|
-
} else {
|
|
338
|
-
return [str.substring(0, space).trim(), str.substring(space + 1).trim()];
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
let optionalIntentArguments = ` ${startAppOptions.optionalIntentArguments}`;
|
|
343
|
-
let re = / (-[^\s]+) (.+)/;
|
|
344
|
-
|
|
345
|
-
while (true) {
|
|
346
|
-
let args = re.exec(optionalIntentArguments);
|
|
347
|
-
|
|
348
|
-
if (!args) {
|
|
349
|
-
if (optionalIntentArguments.length) {
|
|
350
|
-
cmd.push.apply(cmd, parseKeyValue(optionalIntentArguments));
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
break;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
let flag = args[1];
|
|
357
|
-
let flagPos = optionalIntentArguments.indexOf(flag);
|
|
358
|
-
|
|
359
|
-
if (flagPos !== 0) {
|
|
360
|
-
let prevArgs = optionalIntentArguments.substring(0, flagPos);
|
|
361
|
-
cmd.push.apply(cmd, parseKeyValue(prevArgs));
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
cmd.push(flag);
|
|
365
|
-
optionalIntentArguments = args[2];
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
return cmd;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const getSdkToolsVersion = _lodash.default.memoize(async function getSdkToolsVersion() {
|
|
373
|
-
const androidHome = process.env.ANDROID_HOME;
|
|
374
|
-
|
|
375
|
-
if (!androidHome) {
|
|
376
|
-
throw new Error('ANDROID_HOME environment variable is expected to be set');
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const propertiesPath = _path.default.resolve(androidHome, 'tools', 'source.properties');
|
|
380
|
-
|
|
381
|
-
if (!(await _support.fs.exists(propertiesPath))) {
|
|
382
|
-
_logger.default.warn(`Cannot find ${propertiesPath} file to read SDK version from`);
|
|
383
|
-
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
const propertiesContent = await _support.fs.readFile(propertiesPath, 'utf8');
|
|
388
|
-
const versionMatcher = new RegExp(/Pkg\.Revision=(\d+)\.?(\d+)?\.?(\d+)?/);
|
|
389
|
-
const match = versionMatcher.exec(propertiesContent);
|
|
390
|
-
|
|
391
|
-
if (match) {
|
|
392
|
-
return {
|
|
393
|
-
major: parseInt(match[1], 10),
|
|
394
|
-
minor: match[2] ? parseInt(match[2], 10) : 0,
|
|
395
|
-
build: match[3] ? parseInt(match[3], 10) : 0
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
_logger.default.warn(`Cannot parse "Pkg.Revision" value from ${propertiesPath}`);
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
exports.getSdkToolsVersion = getSdkToolsVersion;
|
|
403
|
-
|
|
404
|
-
const getBuildToolsDirs = _lodash.default.memoize(async function getBuildToolsDirs(sdkRoot) {
|
|
405
|
-
let buildToolsDirs = await _support.fs.glob('*/', {
|
|
406
|
-
cwd: _path.default.resolve(sdkRoot, 'build-tools'),
|
|
407
|
-
absolute: true
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
try {
|
|
411
|
-
buildToolsDirs = buildToolsDirs.map(dir => [_path.default.basename(dir), dir]).sort((a, b) => _semver.default.rcompare(a[0], b[0])).map(pair => pair[1]);
|
|
412
|
-
} catch (err) {
|
|
413
|
-
_logger.default.warn(`Cannot sort build-tools folders ${JSON.stringify(buildToolsDirs.map(dir => _path.default.basename(dir)))} ` + `by semantic version names.`);
|
|
414
|
-
|
|
415
|
-
_logger.default.warn(`Falling back to sorting by modification date. Original error: ${err.message}`);
|
|
416
|
-
|
|
417
|
-
const pairs = await _bluebird.default.map(buildToolsDirs, async dir => [(await _support.fs.stat(dir)).mtime.valueOf(), dir]);
|
|
418
|
-
buildToolsDirs = pairs.sort((a, b) => a[0] < b[0]).map(pair => pair[1]);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
_logger.default.info(`Found ${buildToolsDirs.length} 'build-tools' folders under '${sdkRoot}' (newest first):`);
|
|
422
|
-
|
|
423
|
-
for (let dir of buildToolsDirs) {
|
|
424
|
-
_logger.default.info(` ${dir}`);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return buildToolsDirs;
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
exports.getBuildToolsDirs = getBuildToolsDirs;
|
|
431
|
-
|
|
432
|
-
const extractMatchingPermissions = function (dumpsysOutput, groupNames, grantedState = null) {
|
|
433
|
-
const groupPatternByName = groupName => new RegExp(`^(\\s*${_lodash.default.escapeRegExp(groupName)} permissions:[\\s\\S]+)`, 'm');
|
|
434
|
-
|
|
435
|
-
const indentPattern = /\S|$/;
|
|
436
|
-
const permissionNamePattern = /android\.\w*\.?permission\.\w+/;
|
|
437
|
-
const grantedStatePattern = /\bgranted=(\w+)/;
|
|
438
|
-
const result = [];
|
|
439
|
-
|
|
440
|
-
for (const groupName of groupNames) {
|
|
441
|
-
const groupMatch = groupPatternByName(groupName).exec(dumpsysOutput);
|
|
442
|
-
|
|
443
|
-
if (!groupMatch) {
|
|
444
|
-
continue;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const lines = groupMatch[1].split('\n');
|
|
448
|
-
|
|
449
|
-
if (lines.length < 2) {
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const titleIndent = lines[0].search(indentPattern);
|
|
454
|
-
|
|
455
|
-
for (const line of lines.slice(1)) {
|
|
456
|
-
const currentIndent = line.search(indentPattern);
|
|
457
|
-
|
|
458
|
-
if (currentIndent <= titleIndent) {
|
|
459
|
-
break;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
const permissionNameMatch = permissionNamePattern.exec(line);
|
|
463
|
-
|
|
464
|
-
if (!permissionNameMatch) {
|
|
465
|
-
continue;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const item = {
|
|
469
|
-
permission: permissionNameMatch[0]
|
|
470
|
-
};
|
|
471
|
-
const grantedStateMatch = grantedStatePattern.exec(line);
|
|
472
|
-
|
|
473
|
-
if (grantedStateMatch) {
|
|
474
|
-
item.granted = grantedStateMatch[1] === 'true';
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
result.push(item);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
const filteredResult = result.filter(item => !_lodash.default.isBoolean(grantedState) || item.granted === grantedState).map(item => item.permission);
|
|
482
|
-
|
|
483
|
-
_logger.default.debug(`Retrieved ${_support.util.pluralize('permission', filteredResult.length, true)} ` + `from ${groupNames} ${_support.util.pluralize('group', groupNames.length, false)}`);
|
|
484
|
-
|
|
485
|
-
return filteredResult;
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
exports.extractMatchingPermissions = extractMatchingPermissions;
|
|
489
|
-
|
|
490
|
-
function buildInstallArgs(apiLevel, options = {}) {
|
|
491
|
-
const result = [];
|
|
492
|
-
|
|
493
|
-
if (!_support.util.hasValue(options.replace) || options.replace) {
|
|
494
|
-
result.push('-r');
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
if (options.allowTestPackages) {
|
|
498
|
-
result.push('-t');
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
if (options.useSdcard) {
|
|
502
|
-
result.push('-s');
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
if (options.grantPermissions) {
|
|
506
|
-
if (apiLevel < 23) {
|
|
507
|
-
_logger.default.debug(`Skipping permissions grant option, since ` + `the current API level ${apiLevel} does not support applications ` + `permissions customization`);
|
|
508
|
-
} else {
|
|
509
|
-
result.push('-g');
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (options.partialInstall) {
|
|
514
|
-
result.push('-p');
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
return result;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function parseManifest(manifest) {
|
|
521
|
-
const result = {
|
|
522
|
-
pkg: manifest.package,
|
|
523
|
-
versionCode: parseInt(manifest.versionCode, 10),
|
|
524
|
-
versionName: manifest.versionName || null
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
if (!manifest.application) {
|
|
528
|
-
return result;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
for (const activity of [...manifest.application.activities, ...manifest.application.activityAliases]) {
|
|
532
|
-
if (activity.enabled === false || _lodash.default.isEmpty(activity.intentFilters)) {
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
for (const {
|
|
537
|
-
actions,
|
|
538
|
-
categories
|
|
539
|
-
} of activity.intentFilters) {
|
|
540
|
-
if (_lodash.default.isEmpty(actions) || _lodash.default.isEmpty(categories)) {
|
|
541
|
-
continue;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const isMainAction = actions.some(({
|
|
545
|
-
name
|
|
546
|
-
}) => name === MAIN_ACTION);
|
|
547
|
-
const isLauncherCategory = categories.some(({
|
|
548
|
-
name
|
|
549
|
-
}) => name === LAUNCHER_CATEGORY);
|
|
550
|
-
|
|
551
|
-
if (isMainAction && isLauncherCategory) {
|
|
552
|
-
result.activity = activity.name;
|
|
553
|
-
return result;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
return result;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
function parseAaptStrings(rawOutput, configMarker) {
|
|
562
|
-
const normalizeStringMatch = function (s) {
|
|
563
|
-
return s.replace(/"$/, '').replace(/^"/, '').replace(/\\"/g, '"');
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
const apkStrings = {};
|
|
567
|
-
let isInConfig = false;
|
|
568
|
-
let currentResourceId = null;
|
|
569
|
-
let isInPluralGroup = false;
|
|
570
|
-
const quotedStringPattern = /"[^"\\]*(?:\\.[^"\\]*)*"/;
|
|
571
|
-
|
|
572
|
-
for (const line of rawOutput.split(_os.default.EOL)) {
|
|
573
|
-
const trimmedLine = line.trim();
|
|
574
|
-
|
|
575
|
-
if (_lodash.default.isEmpty(trimmedLine)) {
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
if (['config', 'type', 'spec', 'Package'].some(x => trimmedLine.startsWith(x))) {
|
|
580
|
-
isInConfig = trimmedLine.startsWith(`config ${configMarker}:`);
|
|
581
|
-
currentResourceId = null;
|
|
582
|
-
isInPluralGroup = false;
|
|
583
|
-
continue;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
if (!isInConfig) {
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
if (trimmedLine.startsWith('resource')) {
|
|
591
|
-
isInPluralGroup = false;
|
|
592
|
-
currentResourceId = null;
|
|
593
|
-
|
|
594
|
-
if (trimmedLine.includes(':string/')) {
|
|
595
|
-
const match = /:string\/(\S+):/.exec(trimmedLine);
|
|
596
|
-
|
|
597
|
-
if (match) {
|
|
598
|
-
currentResourceId = match[1];
|
|
599
|
-
}
|
|
600
|
-
} else if (trimmedLine.includes(':plurals/')) {
|
|
601
|
-
const match = /:plurals\/(\S+):/.exec(trimmedLine);
|
|
602
|
-
|
|
603
|
-
if (match) {
|
|
604
|
-
currentResourceId = match[1];
|
|
605
|
-
isInPluralGroup = true;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
continue;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
if (currentResourceId && trimmedLine.startsWith('(string')) {
|
|
613
|
-
const match = quotedStringPattern.exec(trimmedLine);
|
|
614
|
-
|
|
615
|
-
if (match) {
|
|
616
|
-
apkStrings[currentResourceId] = normalizeStringMatch(match[0]);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
currentResourceId = null;
|
|
620
|
-
continue;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
if (currentResourceId && isInPluralGroup && trimmedLine.includes(': (string')) {
|
|
624
|
-
const match = quotedStringPattern.exec(trimmedLine);
|
|
625
|
-
|
|
626
|
-
if (match) {
|
|
627
|
-
apkStrings[currentResourceId] = [...(apkStrings[currentResourceId] || []), normalizeStringMatch(match[0])];
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
continue;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
return apkStrings;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function parseAapt2Strings(rawOutput, configMarker) {
|
|
638
|
-
const allLines = rawOutput.split(_os.default.EOL);
|
|
639
|
-
|
|
640
|
-
function extractContent(startIdx) {
|
|
641
|
-
let idx = startIdx;
|
|
642
|
-
const startCharPos = allLines[startIdx].indexOf('"');
|
|
643
|
-
|
|
644
|
-
if (startCharPos < 0) {
|
|
645
|
-
return [null, idx];
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
let result = '';
|
|
649
|
-
|
|
650
|
-
while (idx < allLines.length) {
|
|
651
|
-
const terminationCharMatch = /"$/.exec(allLines[idx]);
|
|
652
|
-
|
|
653
|
-
if (terminationCharMatch) {
|
|
654
|
-
const terminationCharPos = terminationCharMatch.index;
|
|
655
|
-
|
|
656
|
-
if (startIdx === idx) {
|
|
657
|
-
return [allLines[idx].substring(startCharPos + 1, terminationCharPos), idx];
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
return [`${result}\\n${_lodash.default.trimStart(allLines[idx].substring(0, terminationCharPos))}`, idx];
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
if (idx > startIdx) {
|
|
664
|
-
result += `\\n${_lodash.default.trimStart(allLines[idx])}`;
|
|
665
|
-
} else {
|
|
666
|
-
result += allLines[idx].substring(startCharPos + 1);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
++idx;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
return [result, idx];
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
const apkStrings = {};
|
|
676
|
-
let currentResourceId = null;
|
|
677
|
-
let isInPluralGroup = false;
|
|
678
|
-
let isInCurrentConfig = false;
|
|
679
|
-
let lineIndex = 0;
|
|
680
|
-
|
|
681
|
-
while (lineIndex < allLines.length) {
|
|
682
|
-
const trimmedLine = allLines[lineIndex].trim();
|
|
683
|
-
|
|
684
|
-
if (_lodash.default.isEmpty(trimmedLine)) {
|
|
685
|
-
++lineIndex;
|
|
686
|
-
continue;
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
if (['type', 'Package'].some(x => trimmedLine.startsWith(x))) {
|
|
690
|
-
currentResourceId = null;
|
|
691
|
-
isInPluralGroup = false;
|
|
692
|
-
isInCurrentConfig = false;
|
|
693
|
-
++lineIndex;
|
|
694
|
-
continue;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
if (trimmedLine.startsWith('resource')) {
|
|
698
|
-
isInPluralGroup = false;
|
|
699
|
-
currentResourceId = null;
|
|
700
|
-
isInCurrentConfig = false;
|
|
701
|
-
|
|
702
|
-
if (trimmedLine.includes('string/')) {
|
|
703
|
-
const match = /string\/(\S+)/.exec(trimmedLine);
|
|
704
|
-
|
|
705
|
-
if (match) {
|
|
706
|
-
currentResourceId = match[1];
|
|
707
|
-
}
|
|
708
|
-
} else if (trimmedLine.includes('plurals/')) {
|
|
709
|
-
const match = /plurals\/(\S+)/.exec(trimmedLine);
|
|
710
|
-
|
|
711
|
-
if (match) {
|
|
712
|
-
currentResourceId = match[1];
|
|
713
|
-
isInPluralGroup = true;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
++lineIndex;
|
|
718
|
-
continue;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
if (currentResourceId) {
|
|
722
|
-
if (isInPluralGroup) {
|
|
723
|
-
if (trimmedLine.startsWith('(')) {
|
|
724
|
-
isInCurrentConfig = trimmedLine.startsWith(`(${configMarker})`);
|
|
725
|
-
++lineIndex;
|
|
726
|
-
continue;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
if (isInCurrentConfig) {
|
|
730
|
-
const [content, idx] = extractContent(lineIndex);
|
|
731
|
-
lineIndex = idx;
|
|
732
|
-
|
|
733
|
-
if (_lodash.default.isString(content)) {
|
|
734
|
-
apkStrings[currentResourceId] = [...(apkStrings[currentResourceId] || []), content];
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
} else if (trimmedLine.startsWith(`(${configMarker})`)) {
|
|
738
|
-
const [content, idx] = extractContent(lineIndex);
|
|
739
|
-
lineIndex = idx;
|
|
740
|
-
|
|
741
|
-
if (_lodash.default.isString(content)) {
|
|
742
|
-
apkStrings[currentResourceId] = content;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
currentResourceId = null;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
++lineIndex;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
return apkStrings;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
async function formatConfigMarker(configsGetter, desiredMarker, defaultMarker) {
|
|
756
|
-
let configMarker = desiredMarker || defaultMarker;
|
|
757
|
-
|
|
758
|
-
if (configMarker.includes('-') && !configMarker.includes('-r')) {
|
|
759
|
-
configMarker = configMarker.replace('-', '-r');
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
const configs = await configsGetter();
|
|
763
|
-
|
|
764
|
-
_logger.default.debug(`Resource configurations: ${JSON.stringify(configs)}`);
|
|
765
|
-
|
|
766
|
-
if (configMarker.toLowerCase().startsWith('en') && !configs.some(x => x.trim() === configMarker)) {
|
|
767
|
-
_logger.default.debug(`Resource configuration name '${configMarker}' is unknown. ` + `Replacing it with '${defaultMarker}'`);
|
|
768
|
-
|
|
769
|
-
configMarker = defaultMarker;
|
|
770
|
-
} else {
|
|
771
|
-
_logger.default.debug(`Selected configuration: '${configMarker}'`);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
return configMarker;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
function parseJsonData(output, entityName) {
|
|
778
|
-
if (!/\bresult=-1\b/.test(output) || !/\bdata="/.test(output)) {
|
|
779
|
-
_logger.default.debug(output);
|
|
780
|
-
|
|
781
|
-
throw new Error(`Cannot retrieve ${entityName} from the device. ` + 'Check the server log for more details');
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
const match = /\bdata=(".+)/.exec(output);
|
|
785
|
-
|
|
786
|
-
if (!match) {
|
|
787
|
-
_logger.default.debug(output);
|
|
788
|
-
|
|
789
|
-
throw new Error(`Cannot parse ${entityName} from the command output. ` + 'Check the server log for more details');
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const jsonStr = _lodash.default.trim(match[1]).replace(/(^")|("$)/g, '');
|
|
793
|
-
|
|
794
|
-
try {
|
|
795
|
-
return JSON.parse(jsonStr);
|
|
796
|
-
} catch (e) {
|
|
797
|
-
_logger.default.debug(jsonStr);
|
|
798
|
-
|
|
799
|
-
throw new Error(`Cannot parse ${entityName} from the resulting data string. ` + 'Check the server log for more details');
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
function toAvdLocaleArgs(language, country) {
|
|
804
|
-
const result = [];
|
|
805
|
-
|
|
806
|
-
if (language && _lodash.default.isString(language)) {
|
|
807
|
-
result.push('-prop', `persist.sys.language=${language.toLowerCase()}`);
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
if (country && _lodash.default.isString(country)) {
|
|
811
|
-
result.push('-prop', `persist.sys.country=${country.toUpperCase()}`);
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
let locale;
|
|
815
|
-
|
|
816
|
-
if (_lodash.default.isString(language) && _lodash.default.isString(country) && language && country) {
|
|
817
|
-
locale = language.toLowerCase() + '-' + country.toUpperCase();
|
|
818
|
-
} else if (language && _lodash.default.isString(language)) {
|
|
819
|
-
locale = language.toLowerCase();
|
|
820
|
-
} else if (country && _lodash.default.isString(country)) {
|
|
821
|
-
locale = country;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
if (locale) {
|
|
825
|
-
result.push('-prop', `persist.sys.locale=${locale}`);
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
return result;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
async function getAndroidPrefsRoot() {
|
|
832
|
-
let location = process.env.ANDROID_EMULATOR_HOME;
|
|
833
|
-
|
|
834
|
-
if (await dirExists(location)) {
|
|
835
|
-
return location;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
if (location) {
|
|
839
|
-
_logger.default.warn(`The value of the ANDROID_EMULATOR_HOME environment variable '${location}' is not an existing directory`);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
const home = process.env.HOME || process.env.USERPROFILE;
|
|
843
|
-
|
|
844
|
-
if (home) {
|
|
845
|
-
location = _path.default.resolve(home, '.android');
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
if (!(await dirExists(location))) {
|
|
849
|
-
_logger.default.debug(`Android config root '${location}' is not an existing directory`);
|
|
850
|
-
|
|
851
|
-
return null;
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
return location;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
async function dirExists(location) {
|
|
858
|
-
return location && (await _support.fs.exists(location)) && (await _support.fs.stat(location)).isDirectory();
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
function escapeShellArg(arg) {
|
|
862
|
-
arg = `${arg}`;
|
|
863
|
-
|
|
864
|
-
if (_support.system.isWindows()) {
|
|
865
|
-
return /[&|^\s]/.test(arg) ? `"${arg.replace(/"/g, '""')}"` : arg;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
return arg.replace(/&/g, '\\&');
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
function parseLaunchableActivityNames(dumpsys) {
|
|
872
|
-
const mainActivityNameRe = new RegExp(`^\\s*${_lodash.default.escapeRegExp(MAIN_ACTION)}:$`);
|
|
873
|
-
const categoryNameRe = /^\s*Category:\s+"([a-zA-Z0-9._/-]+)"$/;
|
|
874
|
-
const blocks = [];
|
|
875
|
-
let blockStartIndent;
|
|
876
|
-
let block = [];
|
|
877
|
-
|
|
878
|
-
for (const line of dumpsys.split('\n').map(_lodash.default.trimEnd)) {
|
|
879
|
-
const currentIndent = line.length - _lodash.default.trimStart(line).length;
|
|
880
|
-
|
|
881
|
-
if (mainActivityNameRe.test(line)) {
|
|
882
|
-
blockStartIndent = currentIndent;
|
|
883
|
-
|
|
884
|
-
if (!_lodash.default.isEmpty(block)) {
|
|
885
|
-
blocks.push(block);
|
|
886
|
-
block = [];
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
continue;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (_lodash.default.isNil(blockStartIndent)) {
|
|
893
|
-
continue;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
if (currentIndent > blockStartIndent) {
|
|
897
|
-
block.push(line);
|
|
898
|
-
} else {
|
|
899
|
-
if (!_lodash.default.isEmpty(block)) {
|
|
900
|
-
blocks.push(block);
|
|
901
|
-
block = [];
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
blockStartIndent = null;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
if (!_lodash.default.isEmpty(block)) {
|
|
909
|
-
blocks.push(block);
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
const result = [];
|
|
913
|
-
|
|
914
|
-
for (const item of blocks) {
|
|
915
|
-
let hasCategory = false;
|
|
916
|
-
let isLauncherCategory = false;
|
|
917
|
-
|
|
918
|
-
for (const line of item) {
|
|
919
|
-
const match = categoryNameRe.exec(line);
|
|
920
|
-
|
|
921
|
-
if (!match) {
|
|
922
|
-
continue;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
hasCategory = true;
|
|
926
|
-
isLauncherCategory = match[1] === LAUNCHER_CATEGORY;
|
|
927
|
-
break;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
if (hasCategory && !isLauncherCategory) {
|
|
931
|
-
continue;
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
for (const activityNameStr of item.map(_lodash.default.trim).filter(Boolean)) {
|
|
935
|
-
const fqActivityName = activityNameStr.split(/\s+/)[1];
|
|
936
|
-
|
|
937
|
-
if (!matchComponentName(fqActivityName)) {
|
|
938
|
-
continue;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
if (isLauncherCategory) {
|
|
942
|
-
return [fqActivityName];
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
result.push(fqActivityName);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
return result;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
function matchComponentName(classString) {
|
|
953
|
-
return /^[a-z0-9./_]+$/i.exec(classString);
|
|
954
|
-
}require('source-map-support').install();
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliL2hlbHBlcnMuanMiLCJuYW1lcyI6WyJyb290RGlyIiwicGF0aCIsInJlc29sdmUiLCJfX2Rpcm5hbWUiLCJwcm9jZXNzIiwiZW52IiwiTk9fUFJFQ09NUElMRSIsIkFQS1NfRVhURU5TSU9OIiwiQVBLX0VYVEVOU0lPTiIsIkFQS19JTlNUQUxMX1RJTUVPVVQiLCJBUEtTX0lOU1RBTExfVElNRU9VVCIsIkRFRkFVTFRfQURCX0VYRUNfVElNRU9VVCIsIk1BSU5fQUNUSU9OIiwiTEFVTkNIRVJfQ0FURUdPUlkiLCJnZXRTZGtSb290RnJvbUVudiIsIkFORFJPSURfSE9NRSIsIkFORFJPSURfU0RLX1JPT1QiLCJyZXF1aXJlU2RrUm9vdCIsImN1c3RvbVJvb3QiLCJzZGtSb290IiwiZG9jTXNnIiwiXyIsImlzRW1wdHkiLCJFcnJvciIsImZzIiwiZXhpc3RzIiwic3RhdHMiLCJzdGF0IiwiaXNEaXJlY3RvcnkiLCJnZXRBbmRyb2lkUGxhdGZvcm1BbmRQYXRoIiwicHJvcHNQYXRocyIsImdsb2IiLCJjd2QiLCJhYnNvbHV0ZSIsInBsYXRmb3Jtc01hcHBpbmciLCJwcm9wc1BhdGgiLCJwcm9wc0NvbnRlbnQiLCJyZWFkRmlsZSIsInBsYXRmb3JtUGF0aCIsImRpcm5hbWUiLCJwbGF0Zm9ybSIsImJhc2VuYW1lIiwibWF0Y2giLCJleGVjIiwibG9nIiwid2FybiIsInBhcnNlSW50IiwicmVjZW50U2RrVmVyc2lvbiIsImtleXMiLCJzb3J0IiwicmV2ZXJzZSIsInJlc3VsdCIsImRlYnVnIiwiSlNPTiIsInN0cmluZ2lmeSIsInVuemlwRmlsZSIsInppcFBhdGgiLCJkc3RSb290IiwiemlwIiwiYXNzZXJ0VmFsaWRaaXAiLCJleHRyYWN0QWxsVG8iLCJ1bnNpZ25BcGsiLCJhcGtQYXRoIiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwibWV0YUluZkZvbGRlck5hbWUiLCJoYXNNZXRhSW5mIiwicmVhZEVudHJpZXMiLCJlbnRyeSIsImZpbGVOYW1lIiwic3RhcnRzV2l0aCIsInRtcFppcFJvb3QiLCJyaW1yYWYiLCJ0bXBSZXN1bHRQYXRoIiwidG9BcmNoaXZlIiwidW5saW5rIiwibXYiLCJnZXRJTUVMaXN0RnJvbU91dHB1dCIsInN0ZG91dCIsImVuZ2luZXMiLCJsaW5lIiwic3BsaXQiLCJsZW5ndGgiLCJwdXNoIiwidHJpbSIsInJlcGxhY2UiLCJnZXRKYXZhSG9tZSIsIm1lbW9pemUiLCJKQVZBX0hPTUUiLCJnZXRKYXZhRm9yT3MiLCJqYXZhSG9tZSIsImVyck1zZyIsImVyciIsIm1lc3NhZ2UiLCJleGVjdXRhYmxlTmFtZSIsInN5c3RlbSIsImlzV2luZG93cyIsInJlc3VsdFBhdGgiLCJ3aGljaCIsImlnbiIsImdldE9wZW5Tc2xGb3JPcyIsImJpbmFyeU5hbWUiLCJnZXRBcGtzaWduZXJGb3JPcyIsInN5c0hlbHBlcnMiLCJnZXRCaW5hcnlGcm9tU2RrUm9vdCIsImdldEFwa2FuYWx5emVyRm9yT3MiLCJpc1Nob3dpbmdMb2Nrc2NyZWVuIiwiZHVtcHN5cyIsInNvbWUiLCJ4IiwiaW5jbHVkZXMiLCJldmVyeSIsInRlc3QiLCJpc0N1cnJlbnRGb2N1c09uS2V5Z3VhcmQiLCJtIiwiZ2V0U3VyZmFjZU9yaWVudGF0aW9uIiwiaXNTY3JlZW5PbkZ1bGx5IiwiYnVpbGRTdGFydENtZCIsInN0YXJ0QXBwT3B0aW9ucyIsImFwaUxldmVsIiwidXNlciIsIndhaXRGb3JMYXVuY2giLCJwa2ciLCJhY3Rpdml0eSIsImFjdGlvbiIsImNhdGVnb3J5Iiwic3RvcEFwcCIsImZsYWdzIiwiY21kIiwidXRpbCIsImhhc1ZhbHVlIiwib3B0aW9uYWxJbnRlbnRBcmd1bWVudHMiLCJwYXJzZUtleVZhbHVlIiwic3RyIiwic3BhY2UiLCJpbmRleE9mIiwic3Vic3RyaW5nIiwicmUiLCJhcmdzIiwiYXBwbHkiLCJmbGFnIiwiZmxhZ1BvcyIsInByZXZBcmdzIiwiZ2V0U2RrVG9vbHNWZXJzaW9uIiwiYW5kcm9pZEhvbWUiLCJwcm9wZXJ0aWVzUGF0aCIsInByb3BlcnRpZXNDb250ZW50IiwidmVyc2lvbk1hdGNoZXIiLCJSZWdFeHAiLCJtYWpvciIsIm1pbm9yIiwiYnVpbGQiLCJnZXRCdWlsZFRvb2xzRGlycyIsImJ1aWxkVG9vbHNEaXJzIiwibWFwIiwiZGlyIiwiYSIsImIiLCJzZW12ZXIiLCJyY29tcGFyZSIsInBhaXIiLCJwYWlycyIsIkIiLCJtdGltZSIsInZhbHVlT2YiLCJpbmZvIiwiZXh0cmFjdE1hdGNoaW5nUGVybWlzc2lvbnMiLCJkdW1wc3lzT3V0cHV0IiwiZ3JvdXBOYW1lcyIsImdyYW50ZWRTdGF0ZSIsImdyb3VwUGF0dGVybkJ5TmFtZSIsImdyb3VwTmFtZSIsImVzY2FwZVJlZ0V4cCIsImluZGVudFBhdHRlcm4iLCJwZXJtaXNzaW9uTmFtZVBhdHRlcm4iLCJncmFudGVkU3RhdGVQYXR0ZXJuIiwiZ3JvdXBNYXRjaCIsImxpbmVzIiwidGl0bGVJbmRlbnQiLCJzZWFyY2giLCJzbGljZSIsImN1cnJlbnRJbmRlbnQiLCJwZXJtaXNzaW9uTmFtZU1hdGNoIiwiaXRlbSIsInBlcm1pc3Npb24iLCJncmFudGVkU3RhdGVNYXRjaCIsImdyYW50ZWQiLCJmaWx0ZXJlZFJlc3VsdCIsImZpbHRlciIsImlzQm9vbGVhbiIsInBsdXJhbGl6ZSIsImJ1aWxkSW5zdGFsbEFyZ3MiLCJvcHRpb25zIiwiYWxsb3dUZXN0UGFja2FnZXMiLCJ1c2VTZGNhcmQiLCJncmFudFBlcm1pc3Npb25zIiwicGFydGlhbEluc3RhbGwiLCJwYXJzZU1hbmlmZXN0IiwibWFuaWZlc3QiLCJwYWNrYWdlIiwidmVyc2lvbkNvZGUiLCJ2ZXJzaW9uTmFtZSIsImFwcGxpY2F0aW9uIiwiYWN0aXZpdGllcyIsImFjdGl2aXR5QWxpYXNlcyIsImVuYWJsZWQiLCJpbnRlbnRGaWx0ZXJzIiwiYWN0aW9ucyIsImNhdGVnb3JpZXMiLCJpc01haW5BY3Rpb24iLCJuYW1lIiwiaXNMYXVuY2hlckNhdGVnb3J5IiwicGFyc2VBYXB0U3RyaW5ncyIsInJhd091dHB1dCIsImNvbmZpZ01hcmtlciIsIm5vcm1hbGl6ZVN0cmluZ01hdGNoIiwicyIsImFwa1N0cmluZ3MiLCJpc0luQ29uZmlnIiwiY3VycmVudFJlc291cmNlSWQiLCJpc0luUGx1cmFsR3JvdXAiLCJxdW90ZWRTdHJpbmdQYXR0ZXJuIiwib3MiLCJFT0wiLCJ0cmltbWVkTGluZSIsInBhcnNlQWFwdDJTdHJpbmdzIiwiYWxsTGluZXMiLCJleHRyYWN0Q29udGVudCIsInN0YXJ0SWR4IiwiaWR4Iiwic3RhcnRDaGFyUG9zIiwidGVybWluYXRpb25DaGFyTWF0Y2giLCJ0ZXJtaW5hdGlvbkNoYXJQb3MiLCJpbmRleCIsInRyaW1TdGFydCIsImlzSW5DdXJyZW50Q29uZmlnIiwibGluZUluZGV4IiwiY29udGVudCIsImlzU3RyaW5nIiwiZm9ybWF0Q29uZmlnTWFya2VyIiwiY29uZmlnc0dldHRlciIsImRlc2lyZWRNYXJrZXIiLCJkZWZhdWx0TWFya2VyIiwiY29uZmlncyIsInRvTG93ZXJDYXNlIiwicGFyc2VKc29uRGF0YSIsIm91dHB1dCIsImVudGl0eU5hbWUiLCJqc29uU3RyIiwicGFyc2UiLCJlIiwidG9BdmRMb2NhbGVBcmdzIiwibGFuZ3VhZ2UiLCJjb3VudHJ5IiwidG9VcHBlckNhc2UiLCJsb2NhbGUiLCJnZXRBbmRyb2lkUHJlZnNSb290IiwibG9jYXRpb24iLCJBTkRST0lEX0VNVUxBVE9SX0hPTUUiLCJkaXJFeGlzdHMiLCJob21lIiwiSE9NRSIsIlVTRVJQUk9GSUxFIiwiZXNjYXBlU2hlbGxBcmciLCJhcmciLCJwYXJzZUxhdW5jaGFibGVBY3Rpdml0eU5hbWVzIiwibWFpbkFjdGl2aXR5TmFtZVJlIiwiY2F0ZWdvcnlOYW1lUmUiLCJibG9ja3MiLCJibG9ja1N0YXJ0SW5kZW50IiwiYmxvY2siLCJ0cmltRW5kIiwiaXNOaWwiLCJoYXNDYXRlZ29yeSIsImFjdGl2aXR5TmFtZVN0ciIsIkJvb2xlYW4iLCJmcUFjdGl2aXR5TmFtZSIsIm1hdGNoQ29tcG9uZW50TmFtZSIsImNsYXNzU3RyaW5nIl0sInNvdXJjZVJvb3QiOiIuLi8uLiIsInNvdXJjZXMiOlsibGliL2hlbHBlcnMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBzeXN0ZW0sIGZzLCB6aXAsIHV0aWwsIHRlbXBEaXIgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IG9zIGZyb20gJ29zJztcblxuY29uc3Qgcm9vdERpciA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIHByb2Nlc3MuZW52Lk5PX1BSRUNPTVBJTEUgPyAnLi4nIDogJy4uLy4uJyk7XG5jb25zdCBBUEtTX0VYVEVOU0lPTiA9ICcuYXBrcyc7XG5jb25zdCBBUEtfRVhURU5TSU9OID0gJy5hcGsnO1xuY29uc3QgQVBLX0lOU1RBTExfVElNRU9VVCA9IDYwMDAwO1xuY29uc3QgQVBLU19JTlNUQUxMX1RJTUVPVVQgPSBBUEtfSU5TVEFMTF9USU1FT1VUICogMjtcbmNvbnN0IERFRkFVTFRfQURCX0VYRUNfVElNRU9VVCA9IDIwMDAwOyAvLyBpbiBtaWxsaXNlY29uZHNcbmNvbnN0IE1BSU5fQUNUSU9OID0gJ2FuZHJvaWQuaW50ZW50LmFjdGlvbi5NQUlOJztcbmNvbnN0IExBVU5DSEVSX0NBVEVHT1JZID0gJ2FuZHJvaWQuaW50ZW50LmNhdGVnb3J5LkxBVU5DSEVSJztcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGFjdHVhbCBwYXRoIHRvIFNESyByb290IGZvbGRlciBmcm9tIHRoZSBzeXN0ZW0gZW52aXJvbm1lbnRcbiAqXG4gKiBAcmV0dXJuIHs/c3RyaW5nfSBUaGUgZnVsbCBwYXRoIHRvIHRoZSBTREsgcm9vdCBmb2xkZXJcbiAqL1xuZnVuY3Rpb24gZ2V0U2RrUm9vdEZyb21FbnYgKCkge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuQU5EUk9JRF9IT01FIHx8IHByb2Nlc3MuZW52LkFORFJPSURfU0RLX1JPT1Q7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBhY3R1YWwgcGF0aCB0byBTREsgcm9vdCBmb2xkZXJcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBmdWxsIHBhdGggdG8gdGhlIFNESyByb290IGZvbGRlclxuICogQHRocm93cyB7RXJyb3J9IElmIGVpdGhlciB0aGUgY29ycmVzcG9uZGluZyBlbnYgdmFyaWFibGUgaXMgdW5zZXQgb3IgaXNcbiAqIHBvaW50aW5nIHRvIGFuIGludmFsaWQgZmlsZSBzeXN0ZW0gZW50cnlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVxdWlyZVNka1Jvb3QgKGN1c3RvbVJvb3QgPSBudWxsKSB7XG4gIGNvbnN0IHNka1Jvb3QgPSBjdXN0b21Sb290IHx8IGdldFNka1Jvb3RGcm9tRW52KCk7XG4gIGNvbnN0IGRvY01zZyA9ICdSZWFkIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3N0dWRpby9jb21tYW5kLWxpbmUvdmFyaWFibGVzIGZvciBtb3JlIGRldGFpbHMnO1xuICBpZiAoXy5pc0VtcHR5KHNka1Jvb3QpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBOZWl0aGVyIEFORFJPSURfSE9NRSBub3IgQU5EUk9JRF9TREtfUk9PVCBlbnZpcm9ubWVudCB2YXJpYWJsZSB3YXMgZXhwb3J0ZWQuICR7ZG9jTXNnfWApO1xuICB9XG5cbiAgaWYgKCFhd2FpdCBmcy5leGlzdHMoc2RrUm9vdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBBbmRyb2lkIFNESyByb290IGZvbGRlciAnJHtzZGtSb290fScgZG9lcyBub3QgZXhpc3Qgb24gdGhlIGxvY2FsIGZpbGUgc3lzdGVtLiAke2RvY01zZ31gKTtcbiAgfVxuICBjb25zdCBzdGF0cyA9IGF3YWl0IGZzLnN0YXQoc2RrUm9vdCk7XG4gIGlmICghc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIEFuZHJvaWQgU0RLIHJvb3QgJyR7c2RrUm9vdH0nIG11c3QgYmUgYSBmb2xkZXIuICR7ZG9jTXNnfWApO1xuICB9XG4gIHJldHVybiBzZGtSb290O1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBsYXRmb3JtSW5mb1xuICogQHByb3BlcnR5IHs/c3RyaW5nfSBwbGF0Zm9ybSAtIFRoZSBwbGF0Zm9ybSBuYW1lLCBmb3IgZXhhbXBsZSBgYW5kcm9pZC0yNGBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBgbnVsbGAgaWYgaXQgY2Fubm90IGJlIGZvdW5kXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHBsYXRmb3JtUGF0aCAtIEZ1bGwgcGF0aCB0byB0aGUgcGxhdGZvcm0gU0RLIGZvbGRlclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBgbnVsbGAgaWYgaXQgY2Fubm90IGJlIGZvdW5kXG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZSB0aGUgcGF0aCB0byB0aGUgcmVjZW50IGluc3RhbGxlZCBBbmRyb2lkIHBsYXRmb3JtLlxuICpcbiAqIEByZXR1cm4ge1BsYXRmb3JtSW5mb30gVGhlIHJlc3VsdGluZyBwYXRoIHRvIHRoZSBuZXdlc3QgaW5zdGFsbGVkIHBsYXRmb3JtLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRBbmRyb2lkUGxhdGZvcm1BbmRQYXRoIChzZGtSb290KSB7XG4gIGNvbnN0IHByb3BzUGF0aHMgPSBhd2FpdCBmcy5nbG9iKCcqL2J1aWxkLnByb3AnLCB7XG4gICAgY3dkOiBwYXRoLnJlc29sdmUoc2RrUm9vdCwgJ3BsYXRmb3JtcycpLFxuICAgIGFic29sdXRlOiB0cnVlLFxuICB9KTtcbiAgY29uc3QgcGxhdGZvcm1zTWFwcGluZyA9IHt9O1xuICBmb3IgKGNvbnN0IHByb3BzUGF0aCBvZiBwcm9wc1BhdGhzKSB7XG4gICAgY29uc3QgcHJvcHNDb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUocHJvcHNQYXRoLCAndXRmLTgnKTtcbiAgICBjb25zdCBwbGF0Zm9ybVBhdGggPSBwYXRoLmRpcm5hbWUocHJvcHNQYXRoKTtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IHBhdGguYmFzZW5hbWUocGxhdGZvcm1QYXRoKTtcbiAgICBjb25zdCBtYXRjaCA9IC9yb1xcLmJ1aWxkXFwudmVyc2lvblxcLnNkaz0oXFxkKykvLmV4ZWMocHJvcHNDb250ZW50KTtcbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICBsb2cud2FybihgQ2Fubm90IHJlYWQgdGhlIFNESyB2ZXJzaW9uIGZyb20gJyR7cHJvcHNQYXRofScuIFNraXBwaW5nICcke3BsYXRmb3JtfSdgKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBwbGF0Zm9ybXNNYXBwaW5nW3BhcnNlSW50KG1hdGNoWzFdLCAxMCldID0ge1xuICAgICAgcGxhdGZvcm0sXG4gICAgICBwbGF0Zm9ybVBhdGgsXG4gICAgfTtcbiAgfVxuICBpZiAoXy5pc0VtcHR5KHBsYXRmb3Jtc01hcHBpbmcpKSB7XG4gICAgbG9nLndhcm4oYEZvdW5kIHplcm8gcGxhdGZvcm0gZm9sZGVycyBhdCAnJHtwYXRoLnJlc29sdmUoc2RrUm9vdCwgJ3BsYXRmb3JtcycpfScuIGAgK1xuICAgICAgYERvIHlvdSBoYXZlIGFueSBBbmRyb2lkIFNES3MgaW5zdGFsbGVkP2ApO1xuICAgIHJldHVybiB7XG4gICAgICBwbGF0Zm9ybTogbnVsbCxcbiAgICAgIHBsYXRmb3JtUGF0aDogbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcmVjZW50U2RrVmVyc2lvbiA9IF8ua2V5cyhwbGF0Zm9ybXNNYXBwaW5nKS5zb3J0KCkucmV2ZXJzZSgpWzBdO1xuICBjb25zdCByZXN1bHQgPSBwbGF0Zm9ybXNNYXBwaW5nW3JlY2VudFNka1ZlcnNpb25dO1xuICBsb2cuZGVidWcoYEZvdW5kIHRoZSBtb3N0IHJlY2VudCBBbmRyb2lkIHBsYXRmb3JtOiAke0pTT04uc3RyaW5naWZ5KHJlc3VsdCl9YCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVuemlwRmlsZSAoemlwUGF0aCwgZHN0Um9vdCA9IHBhdGguZGlybmFtZSh6aXBQYXRoKSkge1xuICBsb2cuZGVidWcoYFVuemlwcGluZyAnJHt6aXBQYXRofScgdG8gJyR7ZHN0Um9vdH0nYCk7XG4gIGF3YWl0IHppcC5hc3NlcnRWYWxpZFppcCh6aXBQYXRoKTtcbiAgYXdhaXQgemlwLmV4dHJhY3RBbGxUbyh6aXBQYXRoLCBkc3RSb290KTtcbiAgbG9nLmRlYnVnKCdVbnppcCBzdWNjZXNzZnVsJyk7XG59XG5cbi8qKlxuICogVW5zaWducyB0aGUgZ2l2ZW4gYXBrIGJ5IHJlbW92aW5nIHRoZVxuICogTUVUQS1JTkYgZm9sZGVyIHJlY3Vyc2l2ZWx5IGZyb20gdGhlIGFyY2hpdmUuXG4gKiAhISEgVGhlIGZ1bmN0aW9uIG92ZXJ3cml0ZXMgdGhlIGdpdmVuIGFwayBhZnRlciBzdWNjZXNzZnVsIHVuc2lnbmluZyAhISFcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYXBrUGF0aCBUaGUgcGF0aCB0byB0aGUgYXBrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBhcGsgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5XG4gKiB1bnNpZ25lZCBhbmQgb3ZlcndyaXR0ZW5cbiAqIEB0aHJvd3Mge0Vycm9yfSBpZiB0aGVyZSB3YXMgYW4gZXJyb3IgZHVyaW5nIHRoZSB1bnNpZ24gb3BlcmF0aW9uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVuc2lnbkFwayAoYXBrUGF0aCkge1xuICBjb25zdCB0bXBSb290ID0gYXdhaXQgdGVtcERpci5vcGVuRGlyKCk7XG4gIGNvbnN0IG1ldGFJbmZGb2xkZXJOYW1lID0gJ01FVEEtSU5GJztcbiAgdHJ5IHtcbiAgICBsZXQgaGFzTWV0YUluZiA9IGZhbHNlO1xuICAgIGF3YWl0IHppcC5yZWFkRW50cmllcyhhcGtQYXRoLCAoe2VudHJ5fSkgPT4ge1xuICAgICAgaGFzTWV0YUluZiA9IGVudHJ5LmZpbGVOYW1lLnN0YXJ0c1dpdGgoYCR7bWV0YUluZkZvbGRlck5hbWV9L2ApO1xuICAgICAgLy8gZW50cmllcyBpdGVyYXRpb24gc3RvcHMgYWZ0ZXIgYGZhbHNlYCBpcyByZXR1cm5lZFxuICAgICAgcmV0dXJuICFoYXNNZXRhSW5mO1xuICAgIH0pO1xuICAgIGlmICghaGFzTWV0YUluZikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB0bXBaaXBSb290ID0gcGF0aC5yZXNvbHZlKHRtcFJvb3QsICdhcGsnKTtcbiAgICBhd2FpdCB6aXAuZXh0cmFjdEFsbFRvKGFwa1BhdGgsIHRtcFppcFJvb3QpO1xuICAgIGF3YWl0IGZzLnJpbXJhZihwYXRoLnJlc29sdmUodG1wWmlwUm9vdCwgbWV0YUluZkZvbGRlck5hbWUpKTtcbiAgICBjb25zdCB0bXBSZXN1bHRQYXRoID0gcGF0aC5yZXNvbHZlKHRtcFJvb3QsIHBhdGguYmFzZW5hbWUoYXBrUGF0aCkpO1xuICAgIGF3YWl0IHppcC50b0FyY2hpdmUodG1wUmVzdWx0UGF0aCwge1xuICAgICAgY3dkOiB0bXBaaXBSb290LFxuICAgIH0pO1xuICAgIGF3YWl0IGZzLnVubGluayhhcGtQYXRoKTtcbiAgICBhd2FpdCBmcy5tdih0bXBSZXN1bHRQYXRoLCBhcGtQYXRoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0SU1FTGlzdEZyb21PdXRwdXQgKHN0ZG91dCkge1xuICBsZXQgZW5naW5lcyA9IFtdO1xuICBmb3IgKGxldCBsaW5lIG9mIHN0ZG91dC5zcGxpdCgnXFxuJykpIHtcbiAgICBpZiAobGluZS5sZW5ndGggPiAwICYmIGxpbmVbMF0gIT09ICcgJykge1xuICAgICAgLy8gcmVtb3ZlIG5ld2xpbmUgYW5kIHRyYWlsaW5nIGNvbG9uLCBhbmQgYWRkIHRvIHRoZSBsaXN0XG4gICAgICBlbmdpbmVzLnB1c2gobGluZS50cmltKCkucmVwbGFjZSgvOiQvLCAnJykpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZW5naW5lcztcbn1cblxuY29uc3QgZ2V0SmF2YUhvbWUgPSBfLm1lbW9pemUoYXN5bmMgZnVuY3Rpb24gZ2V0SmF2YUhvbWUgKCkge1xuICBjb25zdCByZXN1bHQgPSBwcm9jZXNzLmVudi5KQVZBX0hPTUU7XG4gIGlmICghcmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgSkFWQV9IT01FIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQgZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MnKTtcbiAgfVxuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhyZXN1bHQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgSkFWQV9IT01FIGxvY2F0aW9uICcke3Jlc3VsdH0nIG11c3QgZXhpc3RgKTtcbiAgfVxuICBjb25zdCBzdGF0cyA9IGF3YWl0IGZzLnN0YXQocmVzdWx0KTtcbiAgaWYgKCFzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgSkFWQV9IT01FIGxvY2F0aW9uICcke3Jlc3VsdH0nIG11c3QgYmUgYSB2YWxpZCBmb2xkZXJgKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG5cbmNvbnN0IGdldEphdmFGb3JPcyA9IF8ubWVtb2l6ZShhc3luYyBmdW5jdGlvbiBnZXRKYXZhRm9yT3MgKCkge1xuICBsZXQgamF2YUhvbWU7XG4gIGxldCBlcnJNc2c7XG4gIHRyeSB7XG4gICAgamF2YUhvbWUgPSBhd2FpdCBnZXRKYXZhSG9tZSgpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJNc2cgPSBlcnIubWVzc2FnZTtcbiAgfVxuICBjb25zdCBleGVjdXRhYmxlTmFtZSA9IGBqYXZhJHtzeXN0ZW0uaXNXaW5kb3dzKCkgPyAnLmV4ZScgOiAnJ31gO1xuICBpZiAoamF2YUhvbWUpIHtcbiAgICBjb25zdCByZXN1bHRQYXRoID0gcGF0aC5yZXNvbHZlKGphdmFIb21lLCAnYmluJywgZXhlY3V0YWJsZU5hbWUpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMocmVzdWx0UGF0aCkpIHtcbiAgICAgIHJldHVybiByZXN1bHRQYXRoO1xuICAgIH1cbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBmcy53aGljaChleGVjdXRhYmxlTmFtZSk7XG4gIH0gY2F0Y2ggKGlnbikge31cbiAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJyR7ZXhlY3V0YWJsZU5hbWV9JyBiaW5hcnkgY291bGQgbm90IGJlIGZvdW5kIGAgK1xuICAgIGBuZWl0aGVyIGluIFBBVEggbm9yIHVuZGVyIEpBVkFfSE9NRSAoJHtlcnJNc2cgfHwgcGF0aC5yZXNvbHZlKGphdmFIb21lLCAnYmluJyl9KWApO1xufSk7XG5cbmNvbnN0IGdldE9wZW5Tc2xGb3JPcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgYmluYXJ5TmFtZSA9IGBvcGVuc3NsJHtzeXN0ZW0uaXNXaW5kb3dzKCkgPyAnLmV4ZScgOiAnJ31gO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBmcy53aGljaChiaW5hcnlOYW1lKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgb3BlbnNzbCB0b29sIG11c3QgYmUgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0gYW5kIGF2YWlsYWJsZSBvbiB0aGUgcGF0aCcpO1xuICB9XG59O1xuXG4vKipcbiAqIEdldCB0aGUgYWJzb2x1dGUgcGF0aCB0byBhcGtzaWduZXIgdG9vbFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzeXNIZWxwZXJzIC0gQW4gaW5zdGFuY2UgY29udGFpbmluZyBzeXN0ZW1DYWxsTWV0aG9kcyBoZWxwZXIgbWV0aG9kc1xuICogQHJldHVybnMge3N0cmluZ30gQW4gYWJzb2x1dGUgcGF0aCB0byBhcGtzaWduZXIgdG9vbC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgdG9vbCBpcyBub3QgcHJlc2VudCBvbiB0aGUgbG9jYWwgZmlsZSBzeXN0ZW0uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldEFwa3NpZ25lckZvck9zIChzeXNIZWxwZXJzKSB7XG4gIHJldHVybiBhd2FpdCBzeXNIZWxwZXJzLmdldEJpbmFyeUZyb21TZGtSb290KCdhcGtzaWduZXIuamFyJyk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBhYnNvbHV0ZSBwYXRoIHRvIGFwa2FuYWx5emVyIHRvb2wuXG4gKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9zdHVkaW8vY29tbWFuZC1saW5lL2Fwa2FuYWx5emVyLmh0bWxcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc3lzSGVscGVycyAtIEFuIGluc3RhbmNlIGNvbnRhaW5pbmcgc3lzdGVtQ2FsbE1ldGhvZHMgaGVscGVyIG1ldGhvZHNcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEFuIGFic29sdXRlIHBhdGggdG8gYXBrYW5hbHl6ZXIgdG9vbC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgdG9vbCBpcyBub3QgcHJlc2VudCBvbiB0aGUgbG9jYWwgZmlsZSBzeXN0ZW0uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldEFwa2FuYWx5emVyRm9yT3MgKHN5c0hlbHBlcnMpIHtcbiAgcmV0dXJuIGF3YWl0IHN5c0hlbHBlcnMuZ2V0QmluYXJ5RnJvbVNka1Jvb3QoJ2Fwa2FuYWx5emVyJyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIG1TaG93aW5nTG9ja3NjcmVlbiBvciBtRHJlYW1pbmdMb2Nrc2NyZWVuIGluIGR1bXBzeXMgb3V0cHV0IHRvIGRldGVybWluZVxuICogaWYgbG9jayBzY3JlZW4gaXMgc2hvd2luZ1xuICpcbiAqIEEgbm90ZTogYGFkYiBzaGVsbCBkdW1wc3lzIHRydXN0YCBwZXJmb3JtcyBiZXR0ZXIgd2hpbGUgZGV0ZWN0aW5nIHRoZSBsb2NrZWQgc2NyZWVuIHN0YXRlXG4gKiBpbiBjb21wYXJpc29uIHRvIGBhZGIgZHVtcHN5cyB3aW5kb3dgIG91dHB1dCBwYXJzaW5nLlxuICogQnV0IHRoZSB0cnVzdCBjb21tYW5kIGRvZXMgbm90IHdvcmsgZm9yIGBTd2lwZWAgdW5sb2NrIHBhdHRlcm4uXG4gKlxuICogSW4gc29tZSBBbmRyb2lkIGRldmljZXMgKFByb2JhYmx5IGFyb3VuZCBBbmRyb2lkIDEwKyksIGBtU2hvd2luZ0xvY2tzY3JlZW5gIGFuZCBgbURyZWFtaW5nTG9ja3NjcmVlbmBcbiAqIGRvIG5vdCB3b3JrIHRvIGRldGVjdCBsb2NrIHN0YXR1cy4gSW5zdGVhZCwga2V5Z3VhcmQgcHJlZmVyZW5jZXMgaGVscHMgdG8gZGV0ZWN0IHRoZSBsb2NrIGNvbmRpdGlvbi5cbiAqIFNvbWUgZGV2aWNlcyBzdWNoIGFzIEFuZHJvaWQgVFYgZG8gbm90IGhhdmUga2V5Z3VhcmQsIHNvIHdlIHNob3VsZCBrZWVwXG4gKiBzY3JlZW4gY29uZGl0aW9uIGFzIHRoaXMgcHJpbWFyeSBtZXRob2QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGR1bXBzeXMgLSBUaGUgb3V0cHV0IG9mIGR1bXBzeXMgd2luZG93IGNvbW1hbmQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGxvY2sgc2NyZWVuIGlzIHNob3dpbmcuXG4gKi9cbmZ1bmN0aW9uIGlzU2hvd2luZ0xvY2tzY3JlZW4gKGR1bXBzeXMpIHtcbiAgcmV0dXJuIF8uc29tZShbJ21TaG93aW5nTG9ja3NjcmVlbj10cnVlJywgJ21EcmVhbWluZ0xvY2tzY3JlZW49dHJ1ZSddLCAoeCkgPT4gZHVtcHN5cy5pbmNsdWRlcyh4KSlcbiAgICAvLyBgbUlzU2hvd2luZ2AgYW5kIGBtSW5wdXRSZXN0cmljdGVkYCBhcmUgYHRydWVgIGluIGxvY2sgY29uZGl0aW9uLiBgZmFsc2VgIGlzIHVubG9jayBjb25kaXRpb24uXG4gICAgfHwgXy5ldmVyeShbL0tleWd1YXJkU3RhdGVNb25pdG9yW1xcblxcc10rbUlzU2hvd2luZz10cnVlLywgL1xccyttSW5wdXRSZXN0cmljdGVkPXRydWUvXSwgKHgpID0+IHgudGVzdChkdW1wc3lzKSk7XG59XG5cbi8qXG4gKiBDaGVja3MgbUN1cnJlbnRGb2N1cyBpbiBkdW1wc3lzIG91dHB1dCB0byBkZXRlcm1pbmUgaWYgS2V5Z3VhcmQgaXMgYWN0aXZhdGVkXG4gKi9cbmZ1bmN0aW9uIGlzQ3VycmVudEZvY3VzT25LZXlndWFyZCAoZHVtcHN5cykge1xuICBsZXQgbSA9IC9tQ3VycmVudEZvY3VzLitLZXlndWFyZC9naS5leGVjKGR1bXBzeXMpO1xuICByZXR1cm4gKG0gJiYgbS5sZW5ndGggJiYgbVswXSkgPyB0cnVlIDogZmFsc2U7XG59XG5cbi8qXG4gKiBSZWFkcyBTdXJmYWNlT3JpZW50YXRpb24gaW4gZHVtcHN5cyBvdXRwdXRcbiAqL1xuZnVuY3Rpb24gZ2V0U3VyZmFjZU9yaWVudGF0aW9uIChkdW1wc3lzKSB7XG4gIGxldCBtID0gL1N1cmZhY2VPcmllbnRhdGlvbjogXFxkL2dpLmV4ZWMoZHVtcHN5cyk7XG4gIHJldHVybiBtICYmIHBhcnNlSW50KG1bMF0uc3BsaXQoJzonKVsxXSwgMTApO1xufVxuXG4vKlxuICogQ2hlY2tzIG1TY3JlZW5PbkZ1bGx5IGluIGR1bXBzeXMgb3V0cHV0IHRvIGRldGVybWluZSBpZiBzY3JlZW4gaXMgc2hvd2luZ1xuICogRGVmYXVsdCBpcyB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2NyZWVuT25GdWxseSAoZHVtcHN5cykge1xuICBsZXQgbSA9IC9tU2NyZWVuT25GdWxseT1cXHcrL2dpLmV4ZWMoZHVtcHN5cyk7XG4gIHJldHVybiAhbSB8fCAvLyBpZiBpbmZvcm1hdGlvbiBpcyBtaXNzaW5nIHdlIGFzc3VtZSBzY3JlZW4gaXMgZnVsbHkgb25cbiAgICAgICAgIChtICYmIG0ubGVuZ3RoID4gMCAmJiBtWzBdLnNwbGl0KCc9JylbMV0gPT09ICd0cnVlJykgfHwgZmFsc2U7XG59XG5cbi8qKlxuICogQnVpbGRzIGNvbW1hbmQgbGluZSByZXByZXNlbnRhdGlvbiBmb3IgdGhlIGdpdmVuXG4gKiBhcHBsaWNhdGlvbiBzdGFydHVwIG9wdGlvbnNcbiAqXG4gKiBAcGFyYW0ge1N0YXJ0QXBwT3B0aW9uc30gc3RhcnRBcHBPcHRpb25zIC0gQXBwbGljYXRpb24gb3B0aW9ucyBtYXBwaW5nXG4gKiBAcGFyYW0ge251bWJlcn0gYXBpTGV2ZWwgLSBUaGUgYWN0dWFsIE9TIEFQSSBsZXZlbFxuICogQHJldHVybnMge0FycmF5PFN0cmluZz59IFRoZSBhY3R1YWwgY29tbWFuZCBsaW5lIGFycmF5XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkU3RhcnRDbWQgKHN0YXJ0QXBwT3B0aW9ucywgYXBpTGV2ZWwpIHtcbiAgY29uc3Qge1xuICAgIHVzZXIsXG4gICAgd2FpdEZvckxhdW5jaCxcbiAgICBwa2csXG4gICAgYWN0aXZpdHksXG4gICAgYWN0aW9uLFxuICAgIGNhdGVnb3J5LFxuICAgIHN0b3BBcHAsXG4gICAgZmxhZ3MsXG4gIH0gPSBzdGFydEFwcE9wdGlvbnM7XG4gIGNvbnN0IGNtZCA9IFsnYW0nLCAnc3RhcnQnXTtcbiAgaWYgKHV0aWwuaGFzVmFsdWUodXNlcikpIHtcbiAgICBjbWQucHVzaCgnLS11c2VyJywgdXNlcik7XG4gIH1cbiAgaWYgKHdhaXRGb3JMYXVuY2gpIHtcbiAgICBjbWQucHVzaCgnLVcnKTtcbiAgfVxuICBpZiAoYWN0aXZpdHkgJiYgcGtnKSB7XG4gICAgY21kLnB1c2goJy1uJywgYCR7cGtnfS8ke2FjdGl2aXR5fWApO1xuICB9XG4gIGlmIChzdG9wQXBwICYmIGFwaUxldmVsID49IDE1KSB7XG4gICAgY21kLnB1c2goJy1TJyk7XG4gIH1cbiAgaWYgKGFjdGlvbikge1xuICAgIGNtZC5wdXNoKCctYScsIGFjdGlvbik7XG4gIH1cbiAgaWYgKGNhdGVnb3J5KSB7XG4gICAgY21kLnB1c2goJy1jJywgY2F0ZWdvcnkpO1xuICB9XG4gIGlmIChmbGFncykge1xuICAgIGNtZC5wdXNoKCctZicsIGZsYWdzKTtcbiAgfVxuICBpZiAoc3RhcnRBcHBPcHRpb25zLm9wdGlvbmFsSW50ZW50QXJndW1lbnRzKSB7XG4gICAgLy8gZXhwZWN0IG9wdGlvbmFsSW50ZW50QXJndW1lbnRzIHRvIGJlIGEgc2luZ2xlIHN0cmluZyBvZiB0aGUgZm9ybTpcbiAgICAvLyAgICAgXCItZmxhZyBrZXlcIlxuICAgIC8vICAgICBcIi1mbGFnIGtleSB2YWx1ZVwiXG4gICAgLy8gb3IgYSBjb21iaW5hdGlvbiBvZiB0aGVzZSAoZS5nLiwgXCItZmxhZzEga2V5MSAtZmxhZzIga2V5MiB2YWx1ZTJcIilcblxuICAgIC8vIHRha2UgYSBzdHJpbmcgYW5kIHBhcnNlIG91dCB0aGUgcGFydCBiZWZvcmUgYW55IHNwYWNlcywgYW5kIGFueXRoaW5nIGFmdGVyXG4gICAgLy8gdGhlIGZpcnN0IHNwYWNlXG4gICAgbGV0IHBhcnNlS2V5VmFsdWUgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgICBzdHIgPSBzdHIudHJpbSgpO1xuICAgICAgbGV0IHNwYWNlID0gc3RyLmluZGV4T2YoJyAnKTtcbiAgICAgIGlmIChzcGFjZSA9PT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5sZW5ndGggPyBbc3RyXSA6IFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtzdHIuc3Vic3RyaW5nKDAsIHNwYWNlKS50cmltKCksIHN0ci5zdWJzdHJpbmcoc3BhY2UgKyAxKS50cmltKCldO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBjeWNsZSB0aHJvdWdoIHRoZSBvcHRpb25hbEludGVudEFyZ3VtZW50cyBhbmQgcHVsbCBvdXQgdGhlIGFyZ3VtZW50c1xuICAgIC8vIGFkZCBhIHNwYWNlIGluaXRpYWxseSBzbyBmbGFncyBjYW4gYmUgZGlzdGluZ3Vpc2hlZCBmcm9tIGFyZ3VtZW50cyB0aGF0XG4gICAgLy8gaGF2ZSBpbnRlcm5hbCBoeXBoZW5zXG4gICAgbGV0IG9wdGlvbmFsSW50ZW50QXJndW1lbnRzID0gYCAke3N0YXJ0QXBwT3B0aW9ucy5vcHRpb25hbEludGVudEFyZ3VtZW50c31gO1xuICAgIGxldCByZSA9IC8gKC1bXlxcc10rKSAoLispLztcbiAgICB3aGlsZSAodHJ1ZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgbGV0IGFyZ3MgPSByZS5leGVjKG9wdGlvbmFsSW50ZW50QXJndW1lbnRzKTtcbiAgICAgIGlmICghYXJncykge1xuICAgICAgICBpZiAob3B0aW9uYWxJbnRlbnRBcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gbm8gbW9yZSBmbGFncywgc28gdGhlIHJlbWFpbmRlciBjYW4gYmUgdHJlYXRlZCBhcyAna2V5JyBvciAna2V5IHZhbHVlJ1xuICAgICAgICAgIGNtZC5wdXNoLmFwcGx5KGNtZCwgcGFyc2VLZXlWYWx1ZShvcHRpb25hbEludGVudEFyZ3VtZW50cykpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHdlIGFyZSBkb25lXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyB0YWtlIHRoZSBmbGFnIGFuZCBzZWUgaWYgaXQgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nXG4gICAgICAvLyBpZiBpdCBpcyBub3QsIHRoZW4gaXQgbWVhbnMgd2UgaGF2ZSBiZWVuIHRocm91Z2ggYWxyZWFkeSwgYW5kXG4gICAgICAvLyB3aGF0IGlzIGJlZm9yZSB0aGUgZmxhZyBpcyB0aGUgYXJndW1lbnQgZm9yIHRoZSBwcmV2aW91cyBmbGFnXG4gICAgICBsZXQgZmxhZyA9IGFyZ3NbMV07XG4gICAgICBsZXQgZmxhZ1BvcyA9IG9wdGlvbmFsSW50ZW50QXJndW1lbnRzLmluZGV4T2YoZmxhZyk7XG4gICAgICBpZiAoZmxhZ1BvcyAhPT0gMCkge1xuICAgICAgICBsZXQgcHJldkFyZ3MgPSBvcHRpb25hbEludGVudEFyZ3VtZW50cy5zdWJzdHJpbmcoMCwgZmxhZ1Bvcyk7XG4gICAgICAgIGNtZC5wdXNoLmFwcGx5KGNtZCwgcGFyc2VLZXlWYWx1ZShwcmV2QXJncykpO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgdGhlIGZsYWcsIGFzIHRoZXJlIGFyZSBubyBtb3JlIGVhcmxpZXIgYXJndW1lbnRzXG4gICAgICBjbWQucHVzaChmbGFnKTtcblxuICAgICAgLy8gbWFrZSBvcHRpb25hbEludGVudEFyZ3VtZW50cyBob2xkIHRoZSByZW1haW5kZXJcbiAgICAgIG9wdGlvbmFsSW50ZW50QXJndW1lbnRzID0gYXJnc1syXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNtZDtcbn1cblxuY29uc3QgZ2V0U2RrVG9vbHNWZXJzaW9uID0gXy5tZW1vaXplKGFzeW5jIGZ1bmN0aW9uIGdldFNka1Rvb2xzVmVyc2lvbiAoKSB7XG4gIGNvbnN0IGFuZHJvaWRIb21lID0gcHJvY2Vzcy5lbnYuQU5EUk9JRF9IT01FO1xuICBpZiAoIWFuZHJvaWRIb21lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBTkRST0lEX0hPTUUgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgZXhwZWN0ZWQgdG8gYmUgc2V0Jyk7XG4gIH1cbiAgY29uc3QgcHJvcGVydGllc1BhdGggPSBwYXRoLnJlc29sdmUoYW5kcm9pZEhvbWUsICd0b29scycsICdzb3VyY2UucHJvcGVydGllcycpO1xuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhwcm9wZXJ0aWVzUGF0aCkpIHtcbiAgICBsb2cud2FybihgQ2Fubm90IGZpbmQgJHtwcm9wZXJ0aWVzUGF0aH0gZmlsZSB0byByZWFkIFNESyB2ZXJzaW9uIGZyb21gKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgcHJvcGVydGllc0NvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShwcm9wZXJ0aWVzUGF0aCwgJ3V0ZjgnKTtcbiAgY29uc3QgdmVyc2lvbk1hdGNoZXIgPSBuZXcgUmVnRXhwKC9Qa2dcXC5SZXZpc2lvbj0oXFxkKylcXC4/KFxcZCspP1xcLj8oXFxkKyk/Lyk7XG4gIGNvbnN0IG1hdGNoID0gdmVyc2lvbk1hdGNoZXIuZXhlYyhwcm9wZXJ0aWVzQ29udGVudCk7XG4gIGlmIChtYXRjaCkge1xuICAgIHJldHVybiB7XG4gICAgICBtYWpvcjogcGFyc2VJbnQobWF0Y2hbMV0sIDEwKSxcbiAgICAgIG1pbm9yOiBtYXRjaFsyXSA/IHBhcnNlSW50KG1hdGNoWzJdLCAxMCkgOiAwLFxuICAgICAgYnVpbGQ6IG1hdGNoWzNdID8gcGFyc2VJbnQobWF0Y2hbM10sIDEwKSA6IDBcbiAgICB9O1xuICB9XG4gIGxvZy53YXJuKGBDYW5ub3QgcGFyc2UgXCJQa2cuUmV2aXNpb25cIiB2YWx1ZSBmcm9tICR7cHJvcGVydGllc1BhdGh9YCk7XG59KTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgZnVsbCBwYXRocyB0byBhbGwgJ2J1aWxkLXRvb2xzJyBzdWJmb2xkZXJzIHVuZGVyIHRoZSBwYXJ0aWN1bGFyXG4gKiBTREsgcm9vdCBmb2xkZXJcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc2RrUm9vdCAtIFRoZSBmdWxsIHBhdGggdG8gdGhlIEFuZHJvaWQgU0RLIHJvb3QgZm9sZGVyXG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gVGhlIGZ1bGwgcGF0aHMgdG8gdGhlIHJlc3VsdGluZyBmb2xkZXJzIHNvcnRlZCBieVxuICogbW9kaWZpY2F0aW9uIGRhdGUgKHRoZSBuZXdlc3QgY29tZXMgZmlyc3QpIG9yIGFuIGVtcHR5IGxpc3QgaWYgbm8gbWFjdGhlcyB3ZXJlIGZvdW5kXG4gKi9cbmNvbnN0IGdldEJ1aWxkVG9vbHNEaXJzID0gXy5tZW1vaXplKGFzeW5jIGZ1bmN0aW9uIGdldEJ1aWxkVG9vbHNEaXJzIChzZGtSb290KSB7XG4gIGxldCBidWlsZFRvb2xzRGlycyA9IGF3YWl0IGZzLmdsb2IoJyovJywge1xuICAgIGN3ZDogcGF0aC5yZXNvbHZlKHNka1Jvb3QsICdidWlsZC10b29scycpLFxuICAgIGFic29sdXRlOiB0cnVlLFxuICB9KTtcbiAgdHJ5IHtcbiAgICBidWlsZFRvb2xzRGlycyA9IGJ1aWxkVG9vbHNEaXJzXG4gICAgICAubWFwKChkaXIpID0+IFtwYXRoLmJhc2VuYW1lKGRpciksIGRpcl0pXG4gICAgICAuc29ydCgoYSwgYikgPT4gc2VtdmVyLnJjb21wYXJlKGFbMF0sIGJbMF0pKVxuICAgICAgLm1hcCgocGFpcikgPT4gcGFpclsxXSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy53YXJuKGBDYW5ub3Qgc29ydCBidWlsZC10b29scyBmb2xkZXJzICR7SlNPTi5zdHJpbmdpZnkoYnVpbGRUb29sc0RpcnMubWFwKChkaXIpID0+IHBhdGguYmFzZW5hbWUoZGlyKSkpfSBgICtcbiAgICAgIGBieSBzZW1hbnRpYyB2ZXJzaW9uIG5hbWVzLmApO1xuICAgIGxvZy53YXJuKGBGYWxsaW5nIGJhY2sgdG8gc29ydGluZyBieSBtb2RpZmljYXRpb24gZGF0ZS4gT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgY29uc3QgcGFpcnMgPSBhd2FpdCBCLm1hcChidWlsZFRvb2xzRGlycywgYXN5bmMgKGRpcikgPT4gWyhhd2FpdCBmcy5zdGF0KGRpcikpLm10aW1lLnZhbHVlT2YoKSwgZGlyXSk7XG4gICAgYnVpbGRUb29sc0RpcnMgPSBwYWlyc1xuICAgICAgLnNvcnQoKGEsIGIpID0+IGFbMF0gPCBiWzBdKVxuICAgICAgLm1hcCgocGFpcikgPT4gcGFpclsxXSk7XG4gIH1cbiAgbG9nLmluZm8oYEZvdW5kICR7YnVpbGRUb29sc0RpcnMubGVuZ3RofSAnYnVpbGQtdG9vbHMnIGZvbGRlcnMgdW5kZXIgJyR7c2RrUm9vdH0nIChuZXdlc3QgZmlyc3QpOmApO1xuICBmb3IgKGxldCBkaXIgb2YgYnVpbGRUb29sc0RpcnMpIHtcbiAgICBsb2cuaW5mbyhgICAgICR7ZGlyfWApO1xuICB9XG4gIHJldHVybiBidWlsZFRvb2xzRGlycztcbn0pO1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBwZXJtaXNzaW9uIG5hbWVzIGVuY29kZWQgaW4gYGR1bXBzeXMgcGFja2FnZWAgY29tbWFuZCBvdXRwdXQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGR1bXBzeXNPdXRwdXQgLSBUaGUgYWN0dWFsIGNvbW1hbmQgb3V0cHV0LlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBncm91cE5hbWVzIC0gVGhlIGxpc3Qgb2YgZ3JvdXAgbmFtZXMgdG8gbGlzdCBwZXJtaXNzaW9ucyBmb3IuXG4gKiBAcGFyYW0gez9ib29sZWFufSBncmFudGVkU3RhdGUgLSBUaGUgZXhwZWN0ZWQgc3RhdGUgb2YgYGdyYW50ZWRgIGF0dHJpYnV0ZSB0byBmaWx0ZXIgd2l0aC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vIGZpbHRlcmluZyBpcyBkb25lIGlmIHRoZSBwYXJhbWV0ZXIgaXMgbm90IHNldC5cbiAqIEByZXR1cm5zIHtBcnJheTxzdHJpbmc+fSBUaGUgbGlzdCBvZiBtYXRjaGVkIHBlcm1pc3Npb24gbmFtZXMgb3IgYW4gZW1wdHkgbGlzdCBpZiBubyBtYXRjaGVzIHdlcmUgZm91bmQuXG4gKi9cbmNvbnN0IGV4dHJhY3RNYXRjaGluZ1Blcm1pc3Npb25zID0gZnVuY3Rpb24gKGR1bXBzeXNPdXRwdXQsIGdyb3VwTmFtZXMsIGdyYW50ZWRTdGF0ZSA9IG51bGwpIHtcbiAgY29uc3QgZ3JvdXBQYXR0ZXJuQnlOYW1lID0gKGdyb3VwTmFtZSkgPT4gbmV3IFJlZ0V4cChgXihcXFxccyoke18uZXNjYXBlUmVnRXhwKGdyb3VwTmFtZSl9IHBlcm1pc3Npb25zOltcXFxcc1xcXFxTXSspYCwgJ20nKTtcbiAgY29uc3QgaW5kZW50UGF0dGVybiA9IC9cXFN8JC87XG4gIGNvbnN0IHBlcm1pc3Npb25OYW1lUGF0dGVybiA9IC9hbmRyb2lkXFwuXFx3KlxcLj9wZXJtaXNzaW9uXFwuXFx3Ky87XG4gIGNvbnN0IGdyYW50ZWRTdGF0ZVBhdHRlcm4gPSAvXFxiZ3JhbnRlZD0oXFx3KykvO1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgZm9yIChjb25zdCBncm91cE5hbWUgb2YgZ3JvdXBOYW1lcykge1xuICAgIGNvbnN0IGdyb3VwTWF0Y2ggPSBncm91cFBhdHRlcm5CeU5hbWUoZ3JvdXBOYW1lKS5leGVjKGR1bXBzeXNPdXRwdXQpO1xuICAgIGlmICghZ3JvdXBNYXRjaCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgbGluZXMgPSBncm91cE1hdGNoWzFdLnNwbGl0KCdcXG4nKTtcbiAgICBpZiAobGluZXMubGVuZ3RoIDwgMikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGVJbmRlbnQgPSBsaW5lc1swXS5zZWFyY2goaW5kZW50UGF0dGVybik7XG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzLnNsaWNlKDEpKSB7XG4gICAgICBjb25zdCBjdXJyZW50SW5kZW50ID0gbGluZS5zZWFyY2goaW5kZW50UGF0dGVybik7XG4gICAgICBpZiAoY3VycmVudEluZGVudCA8PSB0aXRsZUluZGVudCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGVybWlzc2lvbk5hbWVNYXRjaCA9IHBlcm1pc3Npb25OYW1lUGF0dGVybi5leGVjKGxpbmUpO1xuICAgICAgaWYgKCFwZXJtaXNzaW9uTmFtZU1hdGNoKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbSA9IHtcbiAgICAgICAgcGVybWlzc2lvbjogcGVybWlzc2lvbk5hbWVNYXRjaFswXSxcbiAgICAgIH07XG4gICAgICBjb25zdCBncmFudGVkU3RhdGVNYXRjaCA9IGdyYW50ZWRTdGF0ZVBhdHRlcm4uZXhlYyhsaW5lKTtcbiAgICAgIGlmIChncmFudGVkU3RhdGVNYXRjaCkge1xuICAgICAgICBpdGVtLmdyYW50ZWQgPSBncmFudGVkU3RhdGVNYXRjaFsxXSA9PT0gJ3RydWUnO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2goaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZmlsdGVyZWRSZXN1bHQgPSByZXN1bHRcbiAgICAuZmlsdGVyKChpdGVtKSA9PiAhXy5pc0Jvb2xlYW4oZ3JhbnRlZFN0YXRlKSB8fCBpdGVtLmdyYW50ZWQgPT09IGdyYW50ZWRTdGF0ZSlcbiAgICAubWFwKChpdGVtKSA9PiBpdGVtLnBlcm1pc3Npb24pO1xuICBsb2cuZGVidWcoYFJldHJpZXZlZCAke3V0aWwucGx1cmFsaXplKCdwZXJtaXNzaW9uJywgZmlsdGVyZWRSZXN1bHQubGVuZ3RoLCB0cnVlKX0gYCArXG4gICAgYGZyb20gJHtncm91cE5hbWVzfSAke3V0aWwucGx1cmFsaXplKCdncm91cCcsIGdyb3VwTmFtZXMubGVuZ3RoLCBmYWxzZSl9YCk7XG4gIHJldHVybiBmaWx0ZXJlZFJlc3VsdDtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gSW5zdGFsbE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gYWxsb3dUZXN0UGFja2FnZXMgW2ZhbHNlXSAtIFNldCB0byB0cnVlIGluIG9yZGVyIHRvIGFsbG93IHRlc3RcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzIGluc3RhbGxhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gdXNlU2RjYXJkIFtmYWxzZV0gLSBTZXQgdG8gdHJ1ZSB0byBpbnN0YWxsIHRoZSBhcHAgb24gc2RjYXJkXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGVhZCBvZiB0aGUgZGV2aWNlIG1lbW9yeS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZ3JhbnRQZXJtaXNzaW9ucyBbZmFsc2VdIC0gU2V0IHRvIHRydWUgaW4gb3JkZXIgdG8gZ3JhbnQgYWxsIHRoZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyByZXF1ZXN0ZWQgaW4gdGhlIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3RcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGljYWxseSBhZnRlciB0aGUgaW5zdGFsbGF0aW9uIGlzIGNvbXBsZXRlZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlciBBbmRyb2lkIDYrLlxuICogQHByb3BlcnR5IHtib29sZWFufSByZXBsYWNlIFt0cnVlXSAtIFNldCBpdCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBhcHBsaWNhdGlvbiB0byBiZSB1cGdyYWRlZC9yZWluc3RhbGxlZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGl0IGlzIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgZGV2aWNlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBwYXJ0aWFsSW5zdGFsbCBbZmFsc2VdIC0gSW5zdGFsbCBhcGtzIHBhcnRpYWxseS4gSXQgaXMgdXNlZCBmb3IgJ2luc3RhbGwtbXVsdGlwbGUnLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwczovL2FuZHJvaWQuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzExMTA2NC93aGF0LWlzLWEtcGFydGlhbC1hcHBsaWNhdGlvbi1pbnN0YWxsLXZpYS1hZGJcbiAqL1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgZ2l2ZW4gb3B0aW9ucyBpbnRvIHRoZSBsaXN0IG9mIGBhZGIgaW5zdGFsbC5pbnN0YWxsLW11bHRpcGxlYCBjb21tYW5kIGFyZ3VtZW50c1xuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhcGlMZXZlbCAtIFRoZSBjdXJyZW50IEFQSSBsZXZlbFxuICogQHBhcmFtIHs/SW5zdGFsbE9wdGlvbnN9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBtYXBwaW5nIHRvIHRyYW5zZm9ybVxuICogQHJldHVybnMge0FycmF5PFN0cmluZz59IFRoZSBhcnJheSBvZiBhcmd1bWVudHNcbiAqL1xuZnVuY3Rpb24gYnVpbGRJbnN0YWxsQXJncyAoYXBpTGV2ZWwsIG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCByZXN1bHQgPSBbXTtcblxuICBpZiAoIXV0aWwuaGFzVmFsdWUob3B0aW9ucy5yZXBsYWNlKSB8fCBvcHRpb25zLnJlcGxhY2UpIHtcbiAgICByZXN1bHQucHVzaCgnLXInKTtcbiAgfVxuICBpZiAob3B0aW9ucy5hbGxvd1Rlc3RQYWNrYWdlcykge1xuICAgIHJlc3VsdC5wdXNoKCctdCcpO1xuICB9XG4gIGlmIChvcHRpb25zLnVzZVNkY2FyZCkge1xuICAgIHJlc3VsdC5wdXNoKCctcycpO1xuICB9XG4gIGlmIChvcHRpb25zLmdyYW50UGVybWlzc2lvbnMpIHtcbiAgICBpZiAoYXBpTGV2ZWwgPCAyMykge1xuICAgICAgbG9nLmRlYnVnKGBTa2lwcGluZyBwZXJtaXNzaW9ucyBncmFudCBvcHRpb24sIHNpbmNlIGAgK1xuICAgICAgICAgICAgICAgIGB0aGUgY3VycmVudCBBUEkgbGV2ZWwgJHthcGlMZXZlbH0gZG9lcyBub3Qgc3VwcG9ydCBhcHBsaWNhdGlvbnMgYCArXG4gICAgICAgICAgICAgICAgYHBlcm1pc3Npb25zIGN1c3RvbWl6YXRpb25gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnB1c2goJy1nJyk7XG4gICAgfVxuICB9XG4gIC8vIEZvciBtdWx0aXBsZS1pbnN0YWxsXG4gIGlmIChvcHRpb25zLnBhcnRpYWxJbnN0YWxsKSB7XG4gICAgcmVzdWx0LnB1c2goJy1wJyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1hbmlmZXN0SW5mb1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHBrZyAtIFRoZSBhcHBsaWNhdGlvbiBpZGVudGlmaWVyXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYWN0aXZpdHkgLSBUaGUgbmFtZSBvZiB0aGUgbWFpbiBwYWNrYWdlIGFjdGl2aXR5XG4gKiBAcHJvcGVydHkgez9udW1iZXJ9IHZlcnNpb25Db2RlIC0gVGhlIHZlcnNpb24gY29kZSBudW1iZXIgKG1pZ2h0IGJlIGBOYU5gKVxuICogQHByb3BlcnR5IHs/c3RyaW5nfSB2ZXJzaW9uTmFtZSAtIFRoZSB2ZXJzaW9uIG5hbWUgKG1pZ2h0IGJlIGBudWxsYClcbiAqL1xuXG4vKipcbiAqIFBlcmZvcm0gcGFyc2luZyBvZiB0aGUgbWFuaWZlc3Qgb2JqZWN0IGluIG9yZGVyXG4gKiB0byBleHRyYWN0IHNvbWUgdml0YWwgdmFsdWVzIGZyb20gaXRcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbWFuaWZlc3QgVGhlIG1hbmlmZXN0IGNvbnRlbnQgZm9ybWF0dGVkIGFzIEpTT05cbiAqIFNlZSBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hZGJraXQtYXBrcmVhZGVyIGZvciBkZXRhaWxlZCBmb3JtYXQgZGVzY3JpcHRpb25cbiAqIEByZXR1cm5zIHtNYW5pZmVzdEluZm99XG4gKi9cbmZ1bmN0aW9uIHBhcnNlTWFuaWZlc3QgKG1hbmlmZXN0KSB7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBwa2c6IG1hbmlmZXN0LnBhY2thZ2UsXG4gICAgdmVyc2lvbkNvZGU6IHBhcnNlSW50KG1hbmlmZXN0LnZlcnNpb25Db2RlLCAxMCksXG4gICAgdmVyc2lvbk5hbWU6IG1hbmlmZXN0LnZlcnNpb25OYW1lIHx8IG51bGwsXG4gIH07XG4gIGlmICghbWFuaWZlc3QuYXBwbGljYXRpb24pIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gTG9vayBmb3IgZW5hYmxlZCBhY3Rpdml0eSBvciBhY3Rpdml0eS1hbGlhcyB3aXRoXG4gIC8vIGFjdGlvbiA9PSBhbmRyb2lkLmludGVudC5hY3Rpb24uTUFJTiBhbmRcbiAgLy8gY2F0ZWdvcnkgPT0gYW5kcm9pZC5pbnRlbnQuY2F0ZWdvcnkuTEFVTkNIRVJcbiAgZm9yIChjb25zdCBhY3Rpdml0eSBvZiBbXG4gICAgLi4ubWFuaWZlc3QuYXBwbGljYXRpb24uYWN0aXZpdGllcyxcbiAgICAuLi5tYW5pZmVzdC5hcHBsaWNhdGlvbi5hY3Rpdml0eUFsaWFzZXMsXG4gIF0pIHtcbiAgICBpZiAoYWN0aXZpdHkuZW5hYmxlZCA9PT0gZmFsc2UgfHwgXy5pc0VtcHR5KGFjdGl2aXR5LmludGVudEZpbHRlcnMpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHthY3Rpb25zLCBjYXRlZ29yaWVzfSBvZiBhY3Rpdml0eS5pbnRlbnRGaWx0ZXJzKSB7XG4gICAgICBpZiAoXy5pc0VtcHR5KGFjdGlvbnMpIHx8IF8uaXNFbXB0eShjYXRlZ29yaWVzKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNNYWluQWN0aW9uID0gYWN0aW9ucy5zb21lKCh7bmFtZX0pID0+IG5hbWUgPT09IE1BSU5fQUNUSU9OKTtcbiAgICAgIGNvbnN0IGlzTGF1bmNoZXJDYXRlZ29yeSA9IGNhdGVnb3JpZXMuc29tZSgoe25hbWV9KSA9PiBuYW1lID09PSBMQVVOQ0hFUl9DQVRFR09SWSk7XG4gICAgICBpZiAoaXNNYWluQWN0aW9uICYmIGlzTGF1bmNoZXJDYXRlZ29yeSkge1xuICAgICAgICByZXN1bHQuYWN0aXZpdHkgPSBhY3Rpdml0eS5uYW1lO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFBhcnNlcyBhcGsgc3RyaW5ncyBmcm9tIGFhcHQgdG9vbCBvdXRwdXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmF3T3V0cHV0IFRoZSBhY3R1YWwgdG9vbCBvdXRwdXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWdNYXJrZXIgVGhlIGNvbmZpZyBtYXJrZXIuIFVzdWFsbHlcbiAqIGEgbGFuZ3VhZ2UgYWJicmV2aWF0aW9uIG9yIGAoZGVmYXVsdClgXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBTdHJpbmdzIGlkcyB0byB2YWx1ZXMgbWFwcGluZy4gUGx1cmFsXG4gKiB2YWx1ZXMgYXJlIHJlcHJlc2VudGVkIGFzIGFycmF5cy4gSWYgbm8gY29uZmlnIGZvdW5kIGZvciB0aGVcbiAqIGdpdmVuIG1hcmtlciB0aGVuIGFuIGVtcHR5IG1hcHBpbmcgaXMgcmV0dXJuZWQuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQWFwdFN0cmluZ3MgKHJhd091dHB1dCwgY29uZmlnTWFya2VyKSB7XG4gIGNvbnN0IG5vcm1hbGl6ZVN0cmluZ01hdGNoID0gZnVuY3Rpb24gKHMpIHtcbiAgICByZXR1cm4gcy5yZXBsYWNlKC9cIiQvLCAnJykucmVwbGFjZSgvXlwiLywgJycpLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKTtcbiAgfTtcblxuICBjb25zdCBhcGtTdHJpbmdzID0ge307XG4gIGxldCBpc0luQ29uZmlnID0gZmFsc2U7XG4gIGxldCBjdXJyZW50UmVzb3VyY2VJZCA9IG51bGw7XG4gIGxldCBpc0luUGx1cmFsR3JvdXAgPSBmYWxzZTtcbiAgLy8gVGhlIHBhdHRlcm4gbWF0Y2hlcyBhbnkgcXVvdGVkIGNvbnRlbnQgaW5jbHVkaW5nIGVzY2FwZWQgcXVvdGVzXG4gIGNvbnN0IHF1b3RlZFN0cmluZ1BhdHRlcm4gPSAvXCJbXlwiXFxcXF0qKD86XFxcXC5bXlwiXFxcXF0qKSpcIi87XG4gIGZvciAoY29uc3QgbGluZSBvZiByYXdPdXRwdXQuc3BsaXQob3MuRU9MKSkge1xuICAgIGNvbnN0IHRyaW1tZWRMaW5lID0gbGluZS50cmltKCk7XG4gICAgaWYgKF8uaXNFbXB0eSh0cmltbWVkTGluZSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChbJ2NvbmZpZycsICd0eXBlJywgJ3NwZWMnLCAnUGFja2FnZSddLnNvbWUoKHgpID0+IHRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoeCkpKSB7XG4gICAgICBpc0luQ29uZmlnID0gdHJpbW1lZExpbmUuc3RhcnRzV2l0aChgY29uZmlnICR7Y29uZmlnTWFya2VyfTpgKTtcbiAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbnVsbDtcbiAgICAgIGlzSW5QbHVyYWxHcm91cCA9IGZhbHNlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKCFpc0luQ29uZmlnKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAodHJpbW1lZExpbmUuc3RhcnRzV2l0aCgncmVzb3VyY2UnKSkge1xuICAgICAgaXNJblBsdXJhbEdyb3VwID0gZmFsc2U7XG4gICAgICBjdXJyZW50UmVzb3VyY2VJZCA9IG51bGw7XG5cbiAgICAgIGlmICh0cmltbWVkTGluZS5pbmNsdWRlcygnOnN0cmluZy8nKSkge1xuICAgICAgICBjb25zdCBtYXRjaCA9IC86c3RyaW5nXFwvKFxcUyspOi8uZXhlYyh0cmltbWVkTGluZSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbWF0Y2hbMV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHJpbW1lZExpbmUuaW5jbHVkZXMoJzpwbHVyYWxzLycpKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gLzpwbHVyYWxzXFwvKFxcUyspOi8uZXhlYyh0cmltbWVkTGluZSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbWF0Y2hbMV07XG4gICAgICAgICAgaXNJblBsdXJhbEdyb3VwID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRSZXNvdXJjZUlkICYmIHRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoJyhzdHJpbmcnKSkge1xuICAgICAgY29uc3QgbWF0Y2ggPSBxdW90ZWRTdHJpbmdQYXR0ZXJuLmV4ZWModHJpbW1lZExpbmUpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGFwa1N0cmluZ3NbY3VycmVudFJlc291cmNlSWRdID0gbm9ybWFsaXplU3RyaW5nTWF0Y2gobWF0Y2hbMF0pO1xuICAgICAgfVxuICAgICAgY3VycmVudFJlc291cmNlSWQgPSBudWxsO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRSZXNvdXJjZUlkICYmIGlzSW5QbHVyYWxHcm91cCAmJiB0cmltbWVkTGluZS5pbmNsdWRlcygnOiAoc3RyaW5nJykpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gcXVvdGVkU3RyaW5nUGF0dGVybi5leGVjKHRyaW1tZWRMaW5lKTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBhcGtTdHJpbmdzW2N1cnJlbnRSZXNvdXJjZUlkXSA9IFtcbiAgICAgICAgICAuLi4oYXBrU3RyaW5nc1tjdXJyZW50UmVzb3VyY2VJZF0gfHwgW10pLFxuICAgICAgICAgIG5vcm1hbGl6ZVN0cmluZ01hdGNoKG1hdGNoWzBdKSxcbiAgICAgICAgXTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYXBrU3RyaW5ncztcbn1cblxuLyoqXG4gKiBQYXJzZXMgYXBrIHN0cmluZ3MgZnJvbSBhYXB0MiB0b29sIG91dHB1dFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSByYXdPdXRwdXQgVGhlIGFjdHVhbCB0b29sIG91dHB1dFxuICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZ01hcmtlciBUaGUgY29uZmlnIG1hcmtlci4gVXN1YWxseVxuICogYSBsYW5ndWFnZSBhYmJyZXZpYXRpb24gb3IgYW4gZW1wdHkgc3RyaW5nIGZvciB0aGUgZGVmYXVsdCBvbmVcbiAqIEByZXR1cm5zIHtPYmplY3R9IFN0cmluZ3MgaWRzIHRvIHZhbHVlcyBtYXBwaW5nLiBQbHVyYWxcbiAqIHZhbHVlcyBhcmUgcmVwcmVzZW50ZWQgYXMgYXJyYXlzLiBJZiBubyBjb25maWcgZm91bmQgZm9yIHRoZVxuICogZ2l2ZW4gbWFya2VyIHRoZW4gYW4gZW1wdHkgbWFwcGluZyBpcyByZXR1cm5lZC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VBYXB0MlN0cmluZ3MgKHJhd091dHB1dCwgY29uZmlnTWFya2VyKSB7XG4gIGNvbnN0IGFsbExpbmVzID0gcmF3T3V0cHV0LnNwbGl0KG9zLkVPTCk7XG4gIGZ1bmN0aW9uIGV4dHJhY3RDb250ZW50IChzdGFydElkeCkge1xuICAgIGxldCBpZHggPSBzdGFydElkeDtcbiAgICBjb25zdCBzdGFydENoYXJQb3MgPSBhbGxMaW5lc1tzdGFydElkeF0uaW5kZXhPZignXCInKTtcbiAgICBpZiAoc3RhcnRDaGFyUG9zIDwgMCkge1xuICAgICAgcmV0dXJuIFtudWxsLCBpZHhdO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0ID0gJyc7XG4gICAgd2hpbGUgKGlkeCA8IGFsbExpbmVzLmxlbmd0aCkge1xuICAgICAgY29uc3QgdGVybWluYXRpb25DaGFyTWF0Y2ggPSAvXCIkLy5leGVjKGFsbExpbmVzW2lkeF0pO1xuICAgICAgaWYgKHRlcm1pbmF0aW9uQ2hhck1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHRlcm1pbmF0aW9uQ2hhclBvcyA9IHRlcm1pbmF0aW9uQ2hhck1hdGNoLmluZGV4O1xuICAgICAgICBpZiAoc3RhcnRJZHggPT09IGlkeCkge1xuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBhbGxMaW5lc1tpZHhdLnN1YnN0cmluZyhzdGFydENoYXJQb3MgKyAxLCB0ZXJtaW5hdGlvbkNoYXJQb3MpLFxuICAgICAgICAgICAgaWR4XG4gICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIGAke3Jlc3VsdH1cXFxcbiR7Xy50cmltU3RhcnQoYWxsTGluZXNbaWR4XS5zdWJzdHJpbmcoMCwgdGVybWluYXRpb25DaGFyUG9zKSl9YCxcbiAgICAgICAgICBpZHgsXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICBpZiAoaWR4ID4gc3RhcnRJZHgpIHtcbiAgICAgICAgcmVzdWx0ICs9IGBcXFxcbiR7Xy50cmltU3RhcnQoYWxsTGluZXNbaWR4XSl9YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCArPSBhbGxMaW5lc1tpZHhdLnN1YnN0cmluZyhzdGFydENoYXJQb3MgKyAxKTtcbiAgICAgIH1cbiAgICAgICsraWR4O1xuICAgIH1cbiAgICByZXR1cm4gW3Jlc3VsdCwgaWR4XTtcbiAgfVxuXG4gIGNvbnN0IGFwa1N0cmluZ3MgPSB7fTtcbiAgbGV0IGN1cnJlbnRSZXNvdXJjZUlkID0gbnVsbDtcbiAgbGV0IGlzSW5QbHVyYWxHcm91cCA9IGZhbHNlO1xuICBsZXQgaXNJbkN1cnJlbnRDb25maWcgPSBmYWxzZTtcbiAgbGV0IGxpbmVJbmRleCA9IDA7XG4gIHdoaWxlIChsaW5lSW5kZXggPCBhbGxMaW5lcy5sZW5ndGgpIHtcbiAgICBjb25zdCB0cmltbWVkTGluZSA9IGFsbExpbmVzW2xpbmVJbmRleF0udHJpbSgpO1xuICAgIGlmIChfLmlzRW1wdHkodHJpbW1lZExpbmUpKSB7XG4gICAgICArK2xpbmVJbmRleDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChbJ3R5cGUnLCAnUGFja2FnZSddLnNvbWUoKHgpID0+IHRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoeCkpKSB7XG4gICAgICBjdXJyZW50UmVzb3VyY2VJZCA9IG51bGw7XG4gICAgICBpc0luUGx1cmFsR3JvdXAgPSBmYWxzZTtcbiAgICAgIGlzSW5DdXJyZW50Q29uZmlnID0gZmFsc2U7XG4gICAgICArK2xpbmVJbmRleDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICh0cmltbWVkTGluZS5zdGFydHNXaXRoKCdyZXNvdXJjZScpKSB7XG4gICAgICBpc0luUGx1cmFsR3JvdXAgPSBmYWxzZTtcbiAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbnVsbDtcbiAgICAgIGlzSW5DdXJyZW50Q29uZmlnID0gZmFsc2U7XG5cbiAgICAgIGlmICh0cmltbWVkTGluZS5pbmNsdWRlcygnc3RyaW5nLycpKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gL3N0cmluZ1xcLyhcXFMrKS8uZXhlYyh0cmltbWVkTGluZSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbWF0Y2hbMV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHJpbW1lZExpbmUuaW5jbHVkZXMoJ3BsdXJhbHMvJykpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSAvcGx1cmFsc1xcLyhcXFMrKS8uZXhlYyh0cmltbWVkTGluZSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbWF0Y2hbMV07XG4gICAgICAgICAgaXNJblBsdXJhbEdyb3VwID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgKytsaW5lSW5kZXg7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFJlc291cmNlSWQpIHtcbiAgICAgIGlmIChpc0luUGx1cmFsR3JvdXApIHtcbiAgICAgICAgaWYgKHRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoJygnKSkge1xuICAgICAgICAgIGlzSW5DdXJyZW50Q29uZmlnID0gdHJpbW1lZExpbmUuc3RhcnRzV2l0aChgKCR7Y29uZmlnTWFya2VyfSlgKTtcbiAgICAgICAgICArK2xpbmVJbmRleDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNJbkN1cnJlbnRDb25maWcpIHtcbiAgICAgICAgICBjb25zdCBbY29udGVudCwgaWR4XSA9IGV4dHJhY3RDb250ZW50KGxpbmVJbmRleCk7XG4gICAgICAgICAgbGluZUluZGV4ID0gaWR4O1xuICAgICAgICAgIGlmIChfLmlzU3RyaW5nKGNvbnRlbnQpKSB7XG4gICAgICAgICAgICBhcGtTdHJpbmdzW2N1cnJlbnRSZXNvdXJjZUlkXSA9IFtcbiAgICAgICAgICAgICAgLi4uKGFwa1N0cmluZ3NbY3VycmVudFJlc291cmNlSWRdIHx8IFtdKSxcbiAgICAgICAgICAgICAgY29udGVudCxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoYCgke2NvbmZpZ01hcmtlcn0pYCkpIHtcbiAgICAgICAgY29uc3QgW2NvbnRlbnQsIGlkeF0gPSBleHRyYWN0Q29udGVudChsaW5lSW5kZXgpO1xuICAgICAgICBsaW5lSW5kZXggPSBpZHg7XG4gICAgICAgIGlmIChfLmlzU3RyaW5nKGNvbnRlbnQpKSB7XG4gICAgICAgICAgYXBrU3RyaW5nc1tjdXJyZW50UmVzb3VyY2VJZF0gPSBjb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRSZXNvdXJjZUlkID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgKytsaW5lSW5kZXg7XG4gIH1cbiAgcmV0dXJuIGFwa1N0cmluZ3M7XG59XG5cbi8qKlxuICogRm9ybWF0cyB0aGUgY29uZmlnIG1hcmtlciwgd2hpY2ggaXMgdGhlbiBwYXNzZWQgdG8gcGFyc2UuLiBtZXRob2RzXG4gKiB0byBtYWtlIGl0IGNvbXBhdGlibGUgd2l0aCByZXNvdXJjZSBmb3JtYXRzIGdlbmVyYXRlZCBieSBhYXB0KDIpIHRvb2xcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb25maWdzR2V0dGVyIFRoZSBmdW5jdGlvbiB3aG9zZSByZXN1bHQgaXMgYSBsaXN0XG4gKiBvZiBhcGsgY29uZmlnc1xuICogQHBhcmFtIHtzdHJpbmd9IGRlc2lyZWRNYXJrZXIgVGhlIGRlc2lyZWQgY29uZmlnIG1hcmtlciB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRNYXJrZXIgVGhlIGRlZmF1bHQgY29uZmlnIG1hcmtlciB2YWx1ZVxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIGNvbmZpZyBtYXJrZXJcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZm9ybWF0Q29uZmlnTWFya2VyIChjb25maWdzR2V0dGVyLCBkZXNpcmVkTWFya2VyLCBkZWZhdWx0TWFya2VyKSB7XG4gIGxldCBjb25maWdNYXJrZXIgPSBkZXNpcmVkTWFya2VyIHx8IGRlZmF1bHRNYXJrZXI7XG4gIGlmIChjb25maWdNYXJrZXIuaW5jbHVkZXMoJy0nKSAmJiAhY29uZmlnTWFya2VyLmluY2x1ZGVzKCctcicpKSB7XG4gICAgY29uZmlnTWFya2VyID0gY29uZmlnTWFya2VyLnJlcGxhY2UoJy0nLCAnLXInKTtcbiAgfVxuICBjb25zdCBjb25maWdzID0gYXdhaXQgY29uZmlnc0dldHRlcigpO1xuICBsb2cuZGVidWcoYFJlc291cmNlIGNvbmZpZ3VyYXRpb25zOiAke0pTT04uc3RyaW5naWZ5KGNvbmZpZ3MpfWApO1xuICAvLyBBc3N1bWUgdGhlICdlbicgY29uZmlndXJhdGlvbiBpcyB0aGUgZGVmYXVsdCBvbmVcbiAgaWYgKGNvbmZpZ01hcmtlci50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoJ2VuJylcbiAgICAmJiAhY29uZmlncy5zb21lKCh4KSA9PiB4LnRyaW0oKSA9PT0gY29uZmlnTWFya2VyKSkge1xuICAgIGxvZy5kZWJ1ZyhgUmVzb3VyY2UgY29uZmlndXJhdGlvbiBuYW1lICcke2NvbmZpZ01hcmtlcn0nIGlzIHVua25vd24uIGAgK1xuICAgICAgYFJlcGxhY2luZyBpdCB3aXRoICcke2RlZmF1bHRNYXJrZXJ9J2ApO1xuICAgIGNvbmZpZ01hcmtlciA9IGRlZmF1bHRNYXJrZXI7XG4gIH0gZWxzZSB7XG4gICAgbG9nLmRlYnVnKGBTZWxlY3RlZCBjb25maWd1cmF0aW9uOiAnJHtjb25maWdNYXJrZXJ9J2ApO1xuICB9XG4gIHJldHVybiBjb25maWdNYXJrZXI7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBvdXRwdXQgaW4gSlNPTiBmb3JtYXQgcmV0cmlldmVkIGZyb21cbiAqIHRoZSBjb3JyZXNwb25kaW5nIEFwcGl1bSBTZXR0aW5ncyBicm9hZGNhc3QgY2FsbHNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gb3V0cHV0IFRoZSBhY3R1YWwgY29tbWFuZCBvdXRwdXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbnRpdHlOYW1lIFRoZSBuYW1lIG9mIHRoZSBlbnRpdHkgd2hpY2ggaXNcbiAqIGdvaW5nIHRvIGJlIHBhcnNlZFxuICogQHJldHVybnMge09iamVjdH0gVGhlIHBhcnNlZCBKU09OIG9iamVjdFxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBvdXRwdXQgY2Fubm90IGJlIHBhcnNlZFxuICogYXMgYSB2YWxpZCBKU09OXG4gKi9cbmZ1bmN0aW9uIHBhcnNlSnNvbkRhdGEgKG91dHB1dCwgZW50aXR5TmFtZSkge1xuICBpZiAoIS9cXGJyZXN1bHQ9LTFcXGIvLnRlc3Qob3V0cHV0KSB8fCAhL1xcYmRhdGE9XCIvLnRlc3Qob3V0cHV0KSkge1xuICAgIGxvZy5kZWJ1ZyhvdXRwdXQpO1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJldHJpZXZlICR7ZW50aXR5TmFtZX0gZnJvbSB0aGUgZGV2aWNlLiBgICtcbiAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBmb3IgbW9yZSBkZXRhaWxzJyk7XG4gIH1cbiAgY29uc3QgbWF0Y2ggPSAvXFxiZGF0YT0oXCIuKykvLmV4ZWMob3V0cHV0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIGxvZy5kZWJ1ZyhvdXRwdXQpO1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHBhcnNlICR7ZW50aXR5TmFtZX0gZnJvbSB0aGUgY29tbWFuZCBvdXRwdXQuIGAgK1xuICAgICAgJ0NoZWNrIHRoZSBzZXJ2ZXIgbG9nIGZvciBtb3JlIGRldGFpbHMnKTtcbiAgfVxuICBjb25zdCBqc29uU3RyID0gXy50cmltKG1hdGNoWzFdKS5yZXBsYWNlKC8oXlwiKXwoXCIkKS9nLCAnJyk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoanNvblN0cik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2cuZGVidWcoanNvblN0cik7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcGFyc2UgJHtlbnRpdHlOYW1lfSBmcm9tIHRoZSByZXN1bHRpbmcgZGF0YSBzdHJpbmcuIGAgK1xuICAgICAgJ0NoZWNrIHRoZSBzZXJ2ZXIgbG9nIGZvciBtb3JlIGRldGFpbHMnKTtcbiAgfVxufVxuXG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIGdpdmVuIGxhbmd1YWdlIGFuZCBjb3VudHJ5IGFiYnJldmlhdGlvbnNcbiAqIHRvIEFWRCBhcmd1bWVudHMgYXJyYXlcbiAqXG4gKiBAcGFyYW0gez9zdHJpbmd9IGxhbmd1YWdlIExhbmd1YWdlIG5hbWUsIGZvciBleGFtcGxlICdmcidcbiAqIEBwYXJhbSB7P3N0cmluZ30gY291bnRyeSBDb3VudHJ5IG5hbWUsIGZvciBleGFtcGxlICdDQSdcbiAqIEByZXR1cm5zIHtBcnJheTxzdHJpbmc+fSBUaGUgZ2VuZXJhdGVkIGFyZ3VtZW50cy4gVGhlXG4gKiByZXN1bHRpbmcgYXJyYXkgbWlnaHQgYmUgZW1wdHkgaWYgYm90aCBhcmd1bWVudHMgYXJlIGVtcHR5XG4gKi9cbmZ1bmN0aW9uIHRvQXZkTG9jYWxlQXJncyAobGFuZ3VhZ2UsIGNvdW50cnkpIHtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGlmIChsYW5ndWFnZSAmJiBfLmlzU3RyaW5nKGxhbmd1YWdlKSkge1xuICAgIHJlc3VsdC5wdXNoKCctcHJvcCcsIGBwZXJzaXN0LnN5cy5sYW5ndWFnZT0ke2xhbmd1YWdlLnRvTG93ZXJDYXNlKCl9YCk7XG4gIH1cbiAgaWYgKGNvdW50cnkgJiYgXy5pc1N0cmluZyhjb3VudHJ5KSkge1xuICAgIHJlc3VsdC5wdXNoKCctcHJvcCcsIGBwZXJzaXN0LnN5cy5jb3VudHJ5PSR7Y291bnRyeS50b1VwcGVyQ2FzZSgpfWApO1xuICB9XG4gIGxldCBsb2NhbGU7XG4gIGlmIChfLmlzU3RyaW5nKGxhbmd1YWdlKSAmJiBfLmlzU3RyaW5nKGNvdW50cnkpICYmIGxhbmd1YWdlICYmIGNvdW50cnkpIHtcbiAgICBsb2NhbGUgPSBsYW5ndWFnZS50b0xvd2VyQ2FzZSgpICsgJy0nICsgY291bnRyeS50b1VwcGVyQ2FzZSgpO1xuICB9IGVsc2UgaWYgKGxhbmd1YWdlICYmIF8uaXNTdHJpbmcobGFuZ3VhZ2UpKSB7XG4gICAgbG9jYWxlID0gbGFuZ3VhZ2UudG9Mb3dlckNhc2UoKTtcbiAgfSBlbHNlIGlmIChjb3VudHJ5ICYmIF8uaXNTdHJpbmcoY291bnRyeSkpIHtcbiAgICBsb2NhbGUgPSBjb3VudHJ5O1xuICB9XG4gIGlmIChsb2NhbGUpIHtcbiAgICByZXN1bHQucHVzaCgnLXByb3AnLCBgcGVyc2lzdC5zeXMubG9jYWxlPSR7bG9jYWxlfWApO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBmdWxsIHBhdGggdG8gdGhlIEFuZHJvaWQgcHJlZmVyZW5jZXMgcm9vdFxuICpcbiAqIEByZXR1cm5zIHs/c3RyaW5nfSBUaGUgZnVsbCBwYXRoIHRvIHRoZSBmb2xkZXIgb3IgYG51bGxgIGlmIHRoZSBmb2xkZXIgY2Fubm90IGJlIGZvdW5kXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldEFuZHJvaWRQcmVmc1Jvb3QgKCkge1xuICBsZXQgbG9jYXRpb24gPSBwcm9jZXNzLmVudi5BTkRST0lEX0VNVUxBVE9SX0hPTUU7XG4gIGlmIChhd2FpdCBkaXJFeGlzdHMobG9jYXRpb24pKSB7XG4gICAgcmV0dXJuIGxvY2F0aW9uO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uKSB7XG4gICAgbG9nLndhcm4oYFRoZSB2YWx1ZSBvZiB0aGUgQU5EUk9JRF9FTVVMQVRPUl9IT01FIGVudmlyb25tZW50IHZhcmlhYmxlICcke2xvY2F0aW9ufScgaXMgbm90IGFuIGV4aXN0aW5nIGRpcmVjdG9yeWApO1xuICB9XG5cbiAgY29uc3QgaG9tZSA9IHByb2Nlc3MuZW52LkhPTUUgfHwgcHJvY2Vzcy5lbnYuVVNFUlBST0ZJTEU7XG4gIGlmIChob21lKSB7XG4gICAgbG9jYXRpb24gPSBwYXRoLnJlc29sdmUoaG9tZSwgJy5hbmRyb2lkJyk7XG4gIH1cblxuICBpZiAoIWF3YWl0IGRpckV4aXN0cyhsb2NhdGlvbikpIHtcbiAgICBsb2cuZGVidWcoYEFuZHJvaWQgY29uZmlnIHJvb3QgJyR7bG9jYXRpb259JyBpcyBub3QgYW4gZXhpc3RpbmcgZGlyZWN0b3J5YCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gbG9jYXRpb247XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBwYXRoIGV4aXN0cyBvbiB0aGUgZmlsZXN5c3RlbSBhbmQgaXMgYSBkaXJlY3RvcnlcbiAqXG4gKiBAcGFyYW0gez9zdHJpbmd9IGxvY2F0aW9uIFRoZSBmdWxsIHBhdGggdG8gdGhlIGRpcmVjdG9yeVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRpckV4aXN0cyAobG9jYXRpb24pIHtcbiAgcmV0dXJuIGxvY2F0aW9uXG4gICAgJiYgYXdhaXQgZnMuZXhpc3RzKGxvY2F0aW9uKVxuICAgICYmIChhd2FpdCBmcy5zdGF0KGxvY2F0aW9uKSkuaXNEaXJlY3RvcnkoKTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBjb21tYW5kIGxpbmUgYXJndW1lbnRzLlxuICogVGhpcyBpcyBuZWVkZWQgdG8gYXZvaWQgcG9zc2libGUgaXNzdWVzIHdpdGggaG93IHN5c3RlbSBgc3Bhd25gXG4gKiBjYWxsIGhhbmRsZXMgdGhlbS5cbiAqIFNlZSBodHRwczovL2Rpc2N1c3MuYXBwaXVtLmlvL3QvaG93LXRvLW1vZGlmeS13ZC1wcm94eS1hbmQtdWlhdXRvbWF0b3IyLXNvdXJjZS1jb2RlLXRvLXN1cHBvcnQtdW5pY29kZS8zMzQ2NlxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJnIE5vbi1lc2NhcGVkIGFyZ3VtZW50IHN0cmluZ1xuICogQHJldHVybnMgVGhlIGVzY2FwZWQgYXJndW1lbnRcbiAqL1xuZnVuY3Rpb24gZXNjYXBlU2hlbGxBcmcgKGFyZykge1xuICBhcmcgPSBgJHthcmd9YDtcbiAgaWYgKHN5c3RlbS5pc1dpbmRvd3MoKSkge1xuICAgIHJldHVybiAvWyZ8Xlxcc10vLnRlc3QoYXJnKSA/IGBcIiR7YXJnLnJlcGxhY2UoL1wiL2csICdcIlwiJyl9XCJgIDogYXJnO1xuICB9XG4gIHJldHVybiBhcmcucmVwbGFjZSgvJi9nLCAnXFxcXCYnKTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIG5hbWUgb2YgbGF1bmNoYWJsZSBwYWNrYWdlIGFjdGl2aXR5XG4gKiBmcm9tIGR1bXBzeXMgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBkdW1wc3lzIHRoZSBhY3R1YWwgZHVtcHN5cyBvdXRwdXRcbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gRWl0aGVyIHRoZSBmdWxseSBxdWFsaWZpZWRcbiAqIGFjdGl2aXR5IG5hbWUgYXMgYSBzaW5nbGUgbGlzdCBpdGVtIG9yIGFuIGVtcHR5IGxpc3QgaWYgbm90aGluZyBjb3VsZCBiZSBwYXJzZWQuXG4gKiBJbiBBbmRyb2lkIDYgYW5kIG9sZGVyIHRoZXJlIGlzIG5vIHJlbGlhYmxlIHdheSB0byBkZXRlcm1pbmVcbiAqIHRoZSBjYXRlZ29yeSBuYW1lIGZvciB0aGUgZ2l2ZW4gYWN0aXZpdHksIHNvIHRoaXMgQVBJIGp1c3RcbiAqIHJldHVybnMgYWxsIGFjdGl2aXR5IG5hbWVzIGJlbG9uZ2luZyB0byAnYW5kcm9pZC5pbnRlbnQuYWN0aW9uLk1BSU4nXG4gKiB3aXRoIHRoZSBleHBlY3RhdGlvbiB0aGF0IHRoZSBhcHAgbWFuaWZlc3QgY291bGQgYmUgcGFyc2VkIG5leHRcbiAqIGluIG9yZGVyIHRvIGRldGVybWluZSBjYXRlZ29yeSBuYW1lcyBmb3IgdGhlc2UuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTGF1bmNoYWJsZUFjdGl2aXR5TmFtZXMgKGR1bXBzeXMpIHtcbiAgY29uc3QgbWFpbkFjdGl2aXR5TmFtZVJlID0gbmV3IFJlZ0V4cChgXlxcXFxzKiR7Xy5lc2NhcGVSZWdFeHAoTUFJTl9BQ1RJT04pfTokYCk7XG4gIGNvbnN0IGNhdGVnb3J5TmFtZVJlID0gL15cXHMqQ2F0ZWdvcnk6XFxzK1wiKFthLXpBLVowLTkuXy8tXSspXCIkLztcbiAgY29uc3QgYmxvY2tzID0gW107XG4gIGxldCBibG9ja1N0YXJ0SW5kZW50O1xuICBsZXQgYmxvY2sgPSBbXTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIGR1bXBzeXMuc3BsaXQoJ1xcbicpLm1hcChfLnRyaW1FbmQpKSB7XG4gICAgY29uc3QgY3VycmVudEluZGVudCA9IGxpbmUubGVuZ3RoIC0gXy50cmltU3RhcnQobGluZSkubGVuZ3RoO1xuICAgIGlmIChtYWluQWN0aXZpdHlOYW1lUmUudGVzdChsaW5lKSkge1xuICAgICAgYmxvY2tTdGFydEluZGVudCA9IGN1cnJlbnRJbmRlbnQ7XG4gICAgICBpZiAoIV8uaXNFbXB0eShibG9jaykpIHtcbiAgICAgICAgYmxvY2tzLnB1c2goYmxvY2spO1xuICAgICAgICBibG9jayA9IFtdO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChfLmlzTmlsKGJsb2NrU3RhcnRJbmRlbnQpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudEluZGVudCA+IGJsb2NrU3RhcnRJbmRlbnQpIHtcbiAgICAgIGJsb2NrLnB1c2gobGluZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghXy5pc0VtcHR5KGJsb2NrKSkge1xuICAgICAgICBibG9ja3MucHVzaChibG9jayk7XG4gICAgICAgIGJsb2NrID0gW107XG4gICAgICB9XG4gICAgICBibG9ja1N0YXJ0SW5kZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cbiAgaWYgKCFfLmlzRW1wdHkoYmxvY2spKSB7XG4gICAgYmxvY2tzLnB1c2goYmxvY2spO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGZvciAoY29uc3QgaXRlbSBvZiBibG9ja3MpIHtcbiAgICBsZXQgaGFzQ2F0ZWdvcnkgPSBmYWxzZTtcbiAgICBsZXQgaXNMYXVuY2hlckNhdGVnb3J5ID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGl0ZW0pIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gY2F0ZWdvcnlOYW1lUmUuZXhlYyhsaW5lKTtcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGhhc0NhdGVnb3J5ID0gdHJ1ZTtcbiAgICAgIGlzTGF1bmNoZXJDYXRlZ29yeSA9IG1hdGNoWzFdID09PSBMQVVOQ0hFUl9DQVRFR09SWTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICAvLyBPbiBvbGRlciBBbmRyb2lkIHZlcnNpb25zIHRoZSBjYXRlZ29yeSBuYW1lXG4gICAgLy8gbWlnaHQgbm90IGJlIGxpc3RlZCwgc28gd2UganVzdCB0cnkgdG8gZmV0Y2hcbiAgICAvLyBhbGwgbWF0Y2hlcyBpbnN0ZWFkXG4gICAgaWYgKGhhc0NhdGVnb3J5ICYmICFpc0xhdW5jaGVyQ2F0ZWdvcnkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgYWN0aXZpdHlOYW1lU3RyIG9mIGl0ZW0ubWFwKF8udHJpbSkuZmlsdGVyKEJvb2xlYW4pKSB7XG4gICAgICBjb25zdCBmcUFjdGl2aXR5TmFtZSA9IGFjdGl2aXR5TmFtZVN0ci5zcGxpdCgvXFxzKy8pWzFdO1xuICAgICAgaWYgKCFtYXRjaENvbXBvbmVudE5hbWUoZnFBY3Rpdml0eU5hbWUpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNMYXVuY2hlckNhdGVnb3J5KSB7XG4gICAgICAgIHJldHVybiBbZnFBY3Rpdml0eU5hbWVdO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2goZnFBY3Rpdml0eU5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBnaXZlbiBzdHJpbmcgaXMgYSB2YWxpZCBjb21wb25lbnQgbmFtZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc1N0cmluZyBUaGUgc3RyaW5nIHRvIHZlcmlmeVxuICogQHJldHVybiB7P0FycmF5PE1hdGNoPn0gVGhlIHJlc3VsdCBvZiBSZWdleHAuZXhlYyBvcGVyYXRpb25cbiAqIG9yIF9udWxsXyBpZiBubyBtYXRjaGVzIGFyZSBmb3VuZFxuICovXG5mdW5jdGlvbiBtYXRjaENvbXBvbmVudE5hbWUgKGNsYXNzU3RyaW5nKSB7XG4gIC8vIHNvbWUucGFja2FnZS9zb21lLnBhY2thZ2UuQWN0aXZpdHlcbiAgcmV0dXJuIC9eW2EtejAtOS4vX10rJC9pLmV4ZWMoY2xhc3NTdHJpbmcpO1xufVxuXG5leHBvcnQge1xuICBnZXRBbmRyb2lkUGxhdGZvcm1BbmRQYXRoLCB1bnppcEZpbGUsXG4gIGdldElNRUxpc3RGcm9tT3V0cHV0LCBnZXRKYXZhRm9yT3MsIGlzU2hvd2luZ0xvY2tzY3JlZW4sIGlzQ3VycmVudEZvY3VzT25LZXlndWFyZCxcbiAgZ2V0U3VyZmFjZU9yaWVudGF0aW9uLCBpc1NjcmVlbk9uRnVsbHksIGJ1aWxkU3RhcnRDbWQsIGdldEphdmFIb21lLFxuICByb290RGlyLCBnZXRTZGtUb29sc1ZlcnNpb24sIGdldEFwa3NpZ25lckZvck9zLCBnZXRCdWlsZFRvb2xzRGlycyxcbiAgZ2V0QXBrYW5hbHl6ZXJGb3JPcywgZ2V0T3BlblNzbEZvck9zLCBleHRyYWN0TWF0Y2hpbmdQZXJtaXNzaW9ucywgQVBLU19FWFRFTlNJT04sXG4gIEFQS19JTlNUQUxMX1RJTUVPVVQsIEFQS1NfSU5TVEFMTF9USU1FT1VULCBidWlsZEluc3RhbGxBcmdzLCBBUEtfRVhURU5TSU9OLFxuICBERUZBVUxUX0FEQl9FWEVDX1RJTUVPVVQsIHBhcnNlTWFuaWZlc3QsIHBhcnNlQWFwdFN0cmluZ3MsIHBhcnNlQWFwdDJTdHJpbmdzLFxuICBmb3JtYXRDb25maWdNYXJrZXIsIHBhcnNlSnNvbkRhdGEsIHVuc2lnbkFwaywgdG9BdmRMb2NhbGVBcmdzLCByZXF1aXJlU2RrUm9vdCxcbiAgZ2V0U2RrUm9vdEZyb21FbnYsIGdldEFuZHJvaWRQcmVmc1Jvb3QsIGRpckV4aXN0cywgZXNjYXBlU2hlbGxBcmcsXG4gIHBhcnNlTGF1bmNoYWJsZUFjdGl2aXR5TmFtZXMsIG1hdGNoQ29tcG9uZW50TmFtZSxcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsT0FBTyxHQUFHQyxhQUFBLENBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QkMsT0FBTyxDQUFDQyxHQUFSLENBQVlDLGFBQVosR0FBNEIsSUFBNUIsR0FBbUMsT0FBM0QsQ0FBaEI7OztBQUNBLE1BQU1DLGNBQWMsR0FBRyxPQUF2Qjs7QUFDQSxNQUFNQyxhQUFhLEdBQUcsTUFBdEI7O0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsS0FBNUI7O0FBQ0EsTUFBTUMsb0JBQW9CLEdBQUdELG1CQUFtQixHQUFHLENBQW5EOztBQUNBLE1BQU1FLHdCQUF3QixHQUFHLEtBQWpDOztBQUNBLE1BQU1DLFdBQVcsR0FBRyw0QkFBcEI7QUFDQSxNQUFNQyxpQkFBaUIsR0FBRyxrQ0FBMUI7O0FBT0EsU0FBU0MsaUJBQVQsR0FBOEI7RUFDNUIsT0FBT1YsT0FBTyxDQUFDQyxHQUFSLENBQVlVLFlBQVosSUFBNEJYLE9BQU8sQ0FBQ0MsR0FBUixDQUFZVyxnQkFBL0M7QUFDRDs7QUFTRCxlQUFlQyxjQUFmLENBQStCQyxVQUFVLEdBQUcsSUFBNUMsRUFBa0Q7RUFDaEQsTUFBTUMsT0FBTyxHQUFHRCxVQUFVLElBQUlKLGlCQUFpQixFQUEvQztFQUNBLE1BQU1NLE1BQU0sR0FBRyxtRkFBZjs7RUFDQSxJQUFJQyxlQUFBLENBQUVDLE9BQUYsQ0FBVUgsT0FBVixDQUFKLEVBQXdCO0lBQ3RCLE1BQU0sSUFBSUksS0FBSixDQUFXLGdGQUErRUgsTUFBTyxFQUFqRyxDQUFOO0VBQ0Q7O0VBRUQsSUFBSSxFQUFDLE1BQU1JLFdBQUEsQ0FBR0MsTUFBSCxDQUFVTixP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
|