oxygen-cli 1.22.0 → 1.99.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -50
- package/build/core/OxygenCore.js +56 -145
- package/build/errors/OxygenError.js +5 -15
- package/build/errors/helper.js +45 -49
- package/build/index.js +14 -6
- package/build/lib/cli-util.js +19 -19
- package/build/lib/cli.js +4 -2
- package/build/lib/parallel-launcher.js +333 -0
- package/build/lib/param-manager.js +66 -47
- package/build/lib/util.js +38 -9
- package/build/ox_modules/index.js +1 -97
- package/build/ox_modules/module-assert.js +19 -9
- package/build/ox_modules/module-dns.js +220 -0
- package/build/ox_modules/module-http.js +39 -51
- package/build/ox_modules/module-shell.js +19 -75
- package/build/ox_modules/module-utils.js +1 -108
- package/build/ox_modules/utils.js +1 -357
- package/build/reporter/FileReporterBase.js +5 -5
- package/build/reporter/ReportAggregator.js +127 -4
- package/build/runners/WorkerProcess.js +15 -28
- package/build/runners/index.js +2 -6
- package/build/runners/oxygen/OxygenWorker.js +8 -8
- package/build/runners/oxygen/index.js +17 -18
- package/build/runners/oxygen/worker.js +10 -8
- package/package.json +12 -46
- package/build/lib/img-merge.js +0 -163
- package/build/ox_modules/module-db.js +0 -146
- package/build/ox_modules/module-email.js +0 -212
- package/build/ox_modules/module-eyes.js +0 -189
- package/build/ox_modules/module-mailinator.js +0 -207
- package/build/ox_modules/module-mob/commands/alertAccept.js +0 -35
- package/build/ox_modules/module-mob/commands/alertDismiss.js +0 -35
- package/build/ox_modules/module-mob/commands/assertAlert.js +0 -56
- package/build/ox_modules/module-mob/commands/assertText.js +0 -45
- package/build/ox_modules/module-mob/commands/assertTitle.js +0 -43
- package/build/ox_modules/module-mob/commands/assertValue.js +0 -66
- package/build/ox_modules/module-mob/commands/back.js +0 -27
- package/build/ox_modules/module-mob/commands/clear.js +0 -40
- package/build/ox_modules/module-mob/commands/click.js +0 -35
- package/build/ox_modules/module-mob/commands/clickHidden.js +0 -52
- package/build/ox_modules/module-mob/commands/clickLong.js +0 -34
- package/build/ox_modules/module-mob/commands/clickMultipleTimes.js +0 -37
- package/build/ox_modules/module-mob/commands/closeApp.js +0 -27
- package/build/ox_modules/module-mob/commands/debug.js +0 -26
- package/build/ox_modules/module-mob/commands/dragAndDrop.js +0 -38
- package/build/ox_modules/module-mob/commands/enableNetwork.js +0 -75
- package/build/ox_modules/module-mob/commands/execute.js +0 -32
- package/build/ox_modules/module-mob/commands/findElement.js +0 -36
- package/build/ox_modules/module-mob/commands/findElements.js +0 -39
- package/build/ox_modules/module-mob/commands/getAlertText.js +0 -31
- package/build/ox_modules/module-mob/commands/getAppiumLogs.js +0 -26
- package/build/ox_modules/module-mob/commands/getBrowserLogs.js +0 -66
- package/build/ox_modules/module-mob/commands/getCurrentActivity.js +0 -26
- package/build/ox_modules/module-mob/commands/getCurrentPackage.js +0 -26
- package/build/ox_modules/module-mob/commands/getDeviceLogs.js +0 -57
- package/build/ox_modules/module-mob/commands/getDeviceTime.js +0 -27
- package/build/ox_modules/module-mob/commands/getLocation.js +0 -32
- package/build/ox_modules/module-mob/commands/getSource.js +0 -26
- package/build/ox_modules/module-mob/commands/getText.js +0 -36
- package/build/ox_modules/module-mob/commands/getTitle.js +0 -24
- package/build/ox_modules/module-mob/commands/getUrl.js +0 -28
- package/build/ox_modules/module-mob/commands/getValue.js +0 -50
- package/build/ox_modules/module-mob/commands/getWindowHandles.js +0 -27
- package/build/ox_modules/module-mob/commands/hideKeyboard.js +0 -33
- package/build/ox_modules/module-mob/commands/index.js +0 -594
- package/build/ox_modules/module-mob/commands/installApp.js +0 -28
- package/build/ox_modules/module-mob/commands/isAppInstalled.js +0 -28
- package/build/ox_modules/module-mob/commands/isCheckable.js +0 -31
- package/build/ox_modules/module-mob/commands/isChecked.js +0 -31
- package/build/ox_modules/module-mob/commands/isClickable.js +0 -31
- package/build/ox_modules/module-mob/commands/isExist.js +0 -36
- package/build/ox_modules/module-mob/commands/isSelected.js +0 -36
- package/build/ox_modules/module-mob/commands/isVisible.js +0 -36
- package/build/ox_modules/module-mob/commands/isWebViewContext.js +0 -27
- package/build/ox_modules/module-mob/commands/launchApp.js +0 -26
- package/build/ox_modules/module-mob/commands/longPressKeyCode.js +0 -30
- package/build/ox_modules/module-mob/commands/open.js +0 -43
- package/build/ox_modules/module-mob/commands/pause.js +0 -27
- package/build/ox_modules/module-mob/commands/removeApp.js +0 -28
- package/build/ox_modules/module-mob/commands/resetApp.js +0 -26
- package/build/ox_modules/module-mob/commands/scrollIntoElement.js +0 -86
- package/build/ox_modules/module-mob/commands/scrollIntoView.js +0 -40
- package/build/ox_modules/module-mob/commands/select.js +0 -54
- package/build/ox_modules/module-mob/commands/selectFrame.js +0 -53
- package/build/ox_modules/module-mob/commands/selectWindow.js +0 -149
- package/build/ox_modules/module-mob/commands/sendKeys.js +0 -84
- package/build/ox_modules/module-mob/commands/setContext.js +0 -28
- package/build/ox_modules/module-mob/commands/setNativeContext.js +0 -26
- package/build/ox_modules/module-mob/commands/setTimeout.js +0 -33
- package/build/ox_modules/module-mob/commands/setWebViewContext.js +0 -39
- package/build/ox_modules/module-mob/commands/shake.js +0 -27
- package/build/ox_modules/module-mob/commands/smsClickLink.js +0 -32
- package/build/ox_modules/module-mob/commands/smsGetText.js +0 -45
- package/build/ox_modules/module-mob/commands/swipe.js +0 -58
- package/build/ox_modules/module-mob/commands/swipeElement.js +0 -58
- package/build/ox_modules/module-mob/commands/swipeScreen.js +0 -56
- package/build/ox_modules/module-mob/commands/takeScreenshot.js +0 -27
- package/build/ox_modules/module-mob/commands/tap.js +0 -34
- package/build/ox_modules/module-mob/commands/type.js +0 -67
- package/build/ox_modules/module-mob/commands/unlockPattern.js +0 -92
- package/build/ox_modules/module-mob/commands/waitForExist.js +0 -29
- package/build/ox_modules/module-mob/commands/waitForInteractable.js +0 -42
- package/build/ox_modules/module-mob/commands/waitForVisible.js +0 -28
- package/build/ox_modules/module-mob.js +0 -699
- package/build/ox_modules/module-pdf.js +0 -328
- package/build/ox_modules/module-proxy.js +0 -324
- package/build/ox_modules/module-serial.js +0 -187
- package/build/ox_modules/module-soap.js +0 -260
- package/build/ox_modules/module-twilio.js +0 -192
- package/build/ox_modules/module-web/commands/alertAccept.js +0 -35
- package/build/ox_modules/module-web/commands/alertDismiss.js +0 -35
- package/build/ox_modules/module-web/commands/assertAlert.js +0 -55
- package/build/ox_modules/module-web/commands/assertExist.js +0 -28
- package/build/ox_modules/module-web/commands/assertSelectedLabel.js +0 -51
- package/build/ox_modules/module-web/commands/assertSelectedValue.js +0 -45
- package/build/ox_modules/module-web/commands/assertText.js +0 -45
- package/build/ox_modules/module-web/commands/assertTextNotPresent.js +0 -56
- package/build/ox_modules/module-web/commands/assertTextPresent.js +0 -52
- package/build/ox_modules/module-web/commands/assertTitle.js +0 -42
- package/build/ox_modules/module-web/commands/assertValue.js +0 -44
- package/build/ox_modules/module-web/commands/back.js +0 -27
- package/build/ox_modules/module-web/commands/clear.js +0 -41
- package/build/ox_modules/module-web/commands/click.js +0 -112
- package/build/ox_modules/module-web/commands/clickHidden.js +0 -79
- package/build/ox_modules/module-web/commands/closeWindow.js +0 -25
- package/build/ox_modules/module-web/commands/debug.js +0 -25
- package/build/ox_modules/module-web/commands/deleteCookies.js +0 -22
- package/build/ox_modules/module-web/commands/deselect.js +0 -34
- package/build/ox_modules/module-web/commands/doubleClick.js +0 -65
- package/build/ox_modules/module-web/commands/dragAndDrop.js +0 -36
- package/build/ox_modules/module-web/commands/execute.js +0 -36
- package/build/ox_modules/module-web/commands/fileBrowse.js +0 -72
- package/build/ox_modules/module-web/commands/findElement.js +0 -35
- package/build/ox_modules/module-web/commands/findElements.js +0 -38
- package/build/ox_modules/module-web/commands/fullscreenWindow.js +0 -24
- package/build/ox_modules/module-web/commands/getAlertText.js +0 -30
- package/build/ox_modules/module-web/commands/getAttribute.js +0 -38
- package/build/ox_modules/module-web/commands/getBrowserLogs.js +0 -34
- package/build/ox_modules/module-web/commands/getCookies.js +0 -23
- package/build/ox_modules/module-web/commands/getCssValue.js +0 -38
- package/build/ox_modules/module-web/commands/getElementCount.js +0 -29
- package/build/ox_modules/module-web/commands/getHTML.js +0 -30
- package/build/ox_modules/module-web/commands/getSource.js +0 -26
- package/build/ox_modules/module-web/commands/getText.js +0 -36
- package/build/ox_modules/module-web/commands/getTitle.js +0 -22
- package/build/ox_modules/module-web/commands/getUrl.js +0 -26
- package/build/ox_modules/module-web/commands/getValue.js +0 -43
- package/build/ox_modules/module-web/commands/getWindowHandles.js +0 -26
- package/build/ox_modules/module-web/commands/getWindowSize.js +0 -26
- package/build/ox_modules/module-web/commands/getXMLPageSource.js +0 -51
- package/build/ox_modules/module-web/commands/index.js +0 -634
- package/build/ox_modules/module-web/commands/isAlertPresent.js +0 -31
- package/build/ox_modules/module-web/commands/isChecked.js +0 -30
- package/build/ox_modules/module-web/commands/isExist.js +0 -36
- package/build/ox_modules/module-web/commands/isSelected.js +0 -35
- package/build/ox_modules/module-web/commands/isVisible.js +0 -36
- package/build/ox_modules/module-web/commands/makeVisible.js +0 -74
- package/build/ox_modules/module-web/commands/maximizeWindow.js +0 -24
- package/build/ox_modules/module-web/commands/minimizeWindow.js +0 -24
- package/build/ox_modules/module-web/commands/newWindow.js +0 -27
- package/build/ox_modules/module-web/commands/open.js +0 -42
- package/build/ox_modules/module-web/commands/pause.js +0 -26
- package/build/ox_modules/module-web/commands/point.js +0 -37
- package/build/ox_modules/module-web/commands/pointJS.js +0 -56
- package/build/ox_modules/module-web/commands/refresh.js +0 -26
- package/build/ox_modules/module-web/commands/rightClick.js +0 -61
- package/build/ox_modules/module-web/commands/rightClickActions.js +0 -57
- package/build/ox_modules/module-web/commands/scrollToElement.js +0 -33
- package/build/ox_modules/module-web/commands/select.js +0 -55
- package/build/ox_modules/module-web/commands/selectFrame.js +0 -52
- package/build/ox_modules/module-web/commands/selectWindow.js +0 -148
- package/build/ox_modules/module-web/commands/sendKeys.js +0 -56
- package/build/ox_modules/module-web/commands/setAutoWaitForAngular.js +0 -33
- package/build/ox_modules/module-web/commands/setTimeout.js +0 -33
- package/build/ox_modules/module-web/commands/setWindowSize.js +0 -29
- package/build/ox_modules/module-web/commands/takeScreenshot.js +0 -37
- package/build/ox_modules/module-web/commands/type.js +0 -52
- package/build/ox_modules/module-web/commands/waitForAngular.js +0 -83
- package/build/ox_modules/module-web/commands/waitForExist.js +0 -28
- package/build/ox_modules/module-web/commands/waitForInteractable.js +0 -31
- package/build/ox_modules/module-web/commands/waitForNotExist.js +0 -57
- package/build/ox_modules/module-web/commands/waitForNotText.js +0 -45
- package/build/ox_modules/module-web/commands/waitForNotValue.js +0 -45
- package/build/ox_modules/module-web/commands/waitForText.js +0 -45
- package/build/ox_modules/module-web/commands/waitForValue.js +0 -45
- package/build/ox_modules/module-web/commands/waitForVisible.js +0 -28
- package/build/ox_modules/module-web/commands/waitForWindow.js +0 -118
- package/build/ox_modules/module-web.js +0 -909
- package/build/ox_modules/module-win/commands/assertText.js +0 -41
- package/build/ox_modules/module-win/commands/assertTitle.js +0 -38
- package/build/ox_modules/module-win/commands/assertValue.js +0 -62
- package/build/ox_modules/module-win/commands/back.js +0 -21
- package/build/ox_modules/module-win/commands/clear.js +0 -34
- package/build/ox_modules/module-win/commands/click.js +0 -25
- package/build/ox_modules/module-win/commands/clickLong.js +0 -30
- package/build/ox_modules/module-win/commands/clickMultipleTimes.js +0 -33
- package/build/ox_modules/module-win/commands/findElement.js +0 -31
- package/build/ox_modules/module-win/commands/findElements.js +0 -31
- package/build/ox_modules/module-win/commands/getAppiumLogs.js +0 -22
- package/build/ox_modules/module-win/commands/getCurrentWindowHandle.js +0 -25
- package/build/ox_modules/module-win/commands/getLocation.js +0 -26
- package/build/ox_modules/module-win/commands/getSource.js +0 -22
- package/build/ox_modules/module-win/commands/getText.js +0 -32
- package/build/ox_modules/module-win/commands/getValue.js +0 -46
- package/build/ox_modules/module-win/commands/getWindowHandles.js +0 -25
- package/build/ox_modules/module-win/commands/index.js +0 -298
- package/build/ox_modules/module-win/commands/isCheckable.js +0 -26
- package/build/ox_modules/module-win/commands/isChecked.js +0 -26
- package/build/ox_modules/module-win/commands/isClickable.js +0 -26
- package/build/ox_modules/module-win/commands/isExist.js +0 -32
- package/build/ox_modules/module-win/commands/isSelected.js +0 -26
- package/build/ox_modules/module-win/commands/isVisible.js +0 -32
- package/build/ox_modules/module-win/commands/open.js +0 -24
- package/build/ox_modules/module-win/commands/pause.js +0 -23
- package/build/ox_modules/module-win/commands/rightClick.js +0 -30
- package/build/ox_modules/module-win/commands/selectWindow.js +0 -97
- package/build/ox_modules/module-win/commands/sendKeys.js +0 -50
- package/build/ox_modules/module-win/commands/setTimeout.js +0 -29
- package/build/ox_modules/module-win/commands/takeScreenshot.js +0 -26
- package/build/ox_modules/module-win/commands/tap.js +0 -29
- package/build/ox_modules/module-win/commands/type.js +0 -38
- package/build/ox_modules/module-win/commands/waitForExist.js +0 -25
- package/build/ox_modules/module-win/commands/waitForInteractable.js +0 -43
- package/build/ox_modules/module-win/commands/waitForVisible.js +0 -24
- package/build/ox_modules/module-win.js +0 -367
- package/build/ox_services/service-devtools/submodule-network.js +0 -338
- package/build/ox_services/service-devtools.js +0 -83
- package/build/runners/cucumber/CucumberEventListener.js +0 -181
- package/build/runners/cucumber/CucumberReporter.js +0 -277
- package/build/runners/cucumber/CucumberWorker.js +0 -337
- package/build/runners/cucumber/index.js +0 -159
- package/build/runners/cucumber/worker.js +0 -184
|
@@ -1,699 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2015-present CloudBeat Limited
|
|
3
|
-
*
|
|
4
|
-
* This program is free software: you can redistribute it and/or modify
|
|
5
|
-
* it under the terms of the GNU General Public License as published by
|
|
6
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
-
* (at your option) any later version.
|
|
8
|
-
*/
|
|
9
|
-
'use strict';
|
|
10
|
-
/**
|
|
11
|
-
* @name mob
|
|
12
|
-
* @description Provides methods for mobile automation.
|
|
13
|
-
* @sample **Locators:**
|
|
14
|
-
*
|
|
15
|
-
* Native application locators for
|
|
16
|
-
* * `/XPATH` - Locates element using an XPath 1.0 expression.
|
|
17
|
-
* * `~ACCESSIBILITY_ID` - Locates element by its Accessibility Id.
|
|
18
|
-
* * `id=ID` - Locates element by its id.
|
|
19
|
-
* * `class=CLASS` - Locates element by its class.
|
|
20
|
-
* * `text=TEXT` - Locates element by its visible text.
|
|
21
|
-
* * `text-contains=TEXT` - Locates element whose visible text contains the specified string.
|
|
22
|
-
* * `desc=DESCRIPTION` - Locates element by its description.
|
|
23
|
-
* * `desc-contains=DESCRIPTION` - Locates element whose description contains the specified string.
|
|
24
|
-
* * `scrollable` - Locates elements that are scrollable.
|
|
25
|
-
*
|
|
26
|
-
* Native application locators for
|
|
27
|
-
*
|
|
28
|
-
* * `/XPATH` - Locates element using an XPath 1.0 expression.
|
|
29
|
-
* * `id=ID` - Locates element by its ID.
|
|
30
|
-
* * `~ACCESSIBILITY_ID` - Locates element by its Accessibility Id.
|
|
31
|
-
*
|
|
32
|
-
* Hybrid and Web application locators for 
|
|
33
|
-
*
|
|
34
|
-
* * `/XPATH` - Locates element using an XPath 1.0 expression.
|
|
35
|
-
* * `id=ID` - Locates element by its id.
|
|
36
|
-
* * `name=NAME` - Locates element by its name attribute.
|
|
37
|
-
* * `tag=NAME` - Locates element by its tag name.
|
|
38
|
-
* * `link=TEXT` - Locates anchor element whose text matches the given string.
|
|
39
|
-
* * `link-contains=TEXT` - Locates anchor element whose text contains the given string.
|
|
40
|
-
* * `css=CSS_SELECTOR` - Locates element using a CSS selector.
|
|
41
|
-
*
|
|
42
|
-
* **Pattern arguments:**
|
|
43
|
-
*
|
|
44
|
-
* Commands which expect a string matching pattern in their arguments, support following patterns unless specified otherwise:
|
|
45
|
-
*
|
|
46
|
-
* * `regex:PATTERN` - Match using regular expression.
|
|
47
|
-
* * `PATTERN` - Verbatim matching.
|
|
48
|
-
*
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
Object.defineProperty(exports, "__esModule", {
|
|
52
|
-
value: true
|
|
53
|
-
});
|
|
54
|
-
exports.default = void 0;
|
|
55
|
-
|
|
56
|
-
require("source-map-support/register");
|
|
57
|
-
|
|
58
|
-
var _url = _interopRequireDefault(require("url"));
|
|
59
|
-
|
|
60
|
-
var wdio = _interopRequireWildcard(require("webdriverio"));
|
|
61
|
-
|
|
62
|
-
var _WebDriverModule = _interopRequireDefault(require("../core/WebDriverModule"));
|
|
63
|
-
|
|
64
|
-
var _utils = _interopRequireDefault(require("./utils"));
|
|
65
|
-
|
|
66
|
-
var _helper = _interopRequireDefault(require("../errors/helper"));
|
|
67
|
-
|
|
68
|
-
var _OxygenError = _interopRequireDefault(require("../errors/OxygenError"));
|
|
69
|
-
|
|
70
|
-
var _perfectoReporting = _interopRequireDefault(require("perfecto-reporting"));
|
|
71
|
-
|
|
72
|
-
var _request = _interopRequireDefault(require("request"));
|
|
73
|
-
|
|
74
|
-
var _imgMerge = _interopRequireDefault(require("../lib/img-merge"));
|
|
75
|
-
|
|
76
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
77
|
-
|
|
78
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
79
|
-
|
|
80
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
81
|
-
|
|
82
|
-
const MODULE_NAME = 'mob';
|
|
83
|
-
const DEFAULT_APPIUM_URL = 'http://localhost:4723/wd/hub';
|
|
84
|
-
const DEFAULT_BROWSER_NAME = 'default';
|
|
85
|
-
const NO_SCREENSHOT_COMMANDS = ['init', 'assertAlert'];
|
|
86
|
-
const ACTION_COMMANDS = ['open', 'tap', 'click', 'swipe', 'submit', 'setValue'];
|
|
87
|
-
const DEFAULT_WAIT_TIMEOUT = 60 * 1000; // default 60s wait timeout
|
|
88
|
-
|
|
89
|
-
class MobileModule extends _WebDriverModule.default {
|
|
90
|
-
constructor(options, context, rs, logger, modules, services) {
|
|
91
|
-
super(options, context, rs, logger, modules, services);
|
|
92
|
-
this.transactions = {};
|
|
93
|
-
this.lastNavigationStartTime = null;
|
|
94
|
-
this.networkRequests = null;
|
|
95
|
-
this.helpers = {};
|
|
96
|
-
this.appContext = 'NATIVE_APP';
|
|
97
|
-
|
|
98
|
-
this._loadHelperFunctions(); // support backward compatibility (some module commands might refer to this.OxError and this.errHelper)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this.OxError = _OxygenError.default;
|
|
102
|
-
this.errHelper = _helper.default; // holds element operation timeout value
|
|
103
|
-
|
|
104
|
-
this.waitForTimeout = DEFAULT_WAIT_TIMEOUT;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
get name() {
|
|
108
|
-
return MODULE_NAME;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* @function getDriver
|
|
112
|
-
* @summary Returns the underlying WDIO driver.
|
|
113
|
-
* @return {Object} WDIO driver.
|
|
114
|
-
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
getDriver() {
|
|
118
|
-
return super.getDriver();
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* @function getCapabilities
|
|
122
|
-
* @summary Returns currently defined capabilities.
|
|
123
|
-
* @return {Object} Current capabilities object.
|
|
124
|
-
*/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
getCapabilities() {
|
|
128
|
-
return this.caps || super.getCapabilities();
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* @function init
|
|
132
|
-
* @summary Initializes a new Appium session.
|
|
133
|
-
* @param {String=} caps - Desired capabilities. If not specified capabilities will be taken from suite definition.
|
|
134
|
-
* @param {String=} appiumUrl - Remote Appium server URL (default: http://localhost:4723/wd/hub).
|
|
135
|
-
*/
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
async init(caps, appiumUrl) {
|
|
139
|
-
// if reopenSession is true - reinitilize the module
|
|
140
|
-
if (this.isInitialized) {
|
|
141
|
-
if (this.options.reopenSession !== false) {
|
|
142
|
-
// true or false if explisitly set. true on null or undefined.
|
|
143
|
-
this.logger.debug('reopenSession is true - reloading the session...');
|
|
144
|
-
this.driver.reloadSession();
|
|
145
|
-
this._isInitialized = true;
|
|
146
|
-
} else {
|
|
147
|
-
this.logger.debug('mob.init was called for already initialized module. reopenSession is false so the call is ignored.');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return;
|
|
151
|
-
} // FIXME: this should be refactored
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (this.ctx.caps && this.ctx.caps['perfectoMobile:options']) {
|
|
155
|
-
if (caps) {
|
|
156
|
-
delete caps.platformName;
|
|
157
|
-
delete caps.platformVersion;
|
|
158
|
-
delete caps.deviceName;
|
|
159
|
-
delete caps.browserName;
|
|
160
|
-
delete caps.automationName;
|
|
161
|
-
delete caps.udid;
|
|
162
|
-
|
|
163
|
-
if (caps.app) {
|
|
164
|
-
caps.enableAppiumBehavior = true;
|
|
165
|
-
} else {
|
|
166
|
-
caps.useAppiumForWeb = true;
|
|
167
|
-
caps.enableAppiumBehavior = true;
|
|
168
|
-
}
|
|
169
|
-
} else {
|
|
170
|
-
this.ctx.caps.useAppiumForWeb = true;
|
|
171
|
-
this.ctx.caps.enableAppiumBehavior = true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (!appiumUrl) {
|
|
176
|
-
appiumUrl = this.options.appiumUrl || DEFAULT_APPIUM_URL;
|
|
177
|
-
} // merge capabilities from context and from init function argument, give preference to context-passed capabilities
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
this.caps = {};
|
|
181
|
-
|
|
182
|
-
if (this.ctx.caps) {
|
|
183
|
-
this.caps = { ...this.ctx.caps
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (caps) {
|
|
188
|
-
this.caps = { ...this.caps,
|
|
189
|
-
...caps
|
|
190
|
-
};
|
|
191
|
-
} // make sure to clear the existing device logs, if collectDeviceLogs option is true (we want to include logs only relevant for this session)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (this.options.collectDeviceLogs) {
|
|
195
|
-
this.caps.clearDeviceLogsOnStart = true;
|
|
196
|
-
} // if both browserName and appPackage were specified - remove browserName
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (this.caps.browserName && (this.caps.appPackage || this.caps.app)) {
|
|
200
|
-
delete this.caps.browserName;
|
|
201
|
-
} // if no appPackage nor app capability, not browserName are defined, assume we want to run the test against default browser
|
|
202
|
-
else if (!this.caps.browserName && !this.caps.appPackage && !this.caps.app) {
|
|
203
|
-
this.caps.browserName = DEFAULT_BROWSER_NAME;
|
|
204
|
-
} // webdriver expects lower case names
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (this.caps.browserName && typeof this.caps.browserName === 'string') {
|
|
208
|
-
this.caps.browserName = this.caps.browserName.toLowerCase();
|
|
209
|
-
} // adjust capabilities to enable collecting browser and performance stats in Chrome
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (this.options.recordHAR && this.caps.browserName === 'chrome') {
|
|
213
|
-
this.caps['goog:loggingPrefs'] = {
|
|
214
|
-
// for ChromeDriver >= 75
|
|
215
|
-
browser: 'ALL',
|
|
216
|
-
performance: 'ALL'
|
|
217
|
-
};
|
|
218
|
-
} // populate WDIO options
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const url = _url.default.parse(appiumUrl);
|
|
222
|
-
|
|
223
|
-
const protocol = url.protocol.replace(/:$/, '');
|
|
224
|
-
const host = url.hostname;
|
|
225
|
-
const port = parseInt(url.port || (protocol === 'https' ? 443 : 80));
|
|
226
|
-
const path = url.pathname; // auth is needed mostly for cloud providers such as LambdaTest
|
|
227
|
-
|
|
228
|
-
if (url.auth) {
|
|
229
|
-
const auth = url.auth.split(':');
|
|
230
|
-
this.options.wdioOpts = {
|
|
231
|
-
user: auth[0],
|
|
232
|
-
key: auth[1]
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
var wdioOpts = { ...(this.options.wdioOpts || {}),
|
|
237
|
-
protocol: protocol,
|
|
238
|
-
hostname: host,
|
|
239
|
-
port: port,
|
|
240
|
-
path: path,
|
|
241
|
-
capabilities: this.caps,
|
|
242
|
-
logLevel: 'silent',
|
|
243
|
-
runner: 'repl',
|
|
244
|
-
waitforTimeout: 5000,
|
|
245
|
-
// increase the default 3000
|
|
246
|
-
connectionRetryTimeout: 310 * 1000,
|
|
247
|
-
connectionRetryCount: 1
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
let provider = _utils.default.determineProvider(wdioOpts);
|
|
251
|
-
|
|
252
|
-
let name = 'name';
|
|
253
|
-
|
|
254
|
-
if (provider === _utils.default.provider.PERFECTO) {
|
|
255
|
-
wdioOpts.capabilities.maxInstances = 1;
|
|
256
|
-
wdioOpts.path = '/nexperience/perfectomobile/wd/hub';
|
|
257
|
-
wdioOpts.port = 80;
|
|
258
|
-
wdioOpts.protocol = 'http';
|
|
259
|
-
wdioOpts.openDeviceTimeout = 15;
|
|
260
|
-
delete wdioOpts.capabilities.manufacturer;
|
|
261
|
-
delete wdioOpts.capabilities.model;
|
|
262
|
-
delete wdioOpts.capabilities.browserName;
|
|
263
|
-
name = wdioOpts.capabilities['perfectoMobile:options']['name'];
|
|
264
|
-
delete wdioOpts.capabilities['perfectoMobile:options'];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (wdioOpts.capabilities['bstack:options'] && wdioOpts.capabilities['bstack:options']['name']) {
|
|
268
|
-
name = wdioOpts.capabilities['bstack:options']['name'];
|
|
269
|
-
delete wdioOpts.capabilities['bstack:options'];
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
this.wdioOpts = wdioOpts; // init webdriver
|
|
273
|
-
|
|
274
|
-
try {
|
|
275
|
-
this.driver = await wdio.remote(wdioOpts);
|
|
276
|
-
this.driver.provider = provider;
|
|
277
|
-
|
|
278
|
-
if (this.options.seleniumBrowserTimeout) {
|
|
279
|
-
this.driver.seleniumBrowserTimeout = this.options.seleniumBrowserTimeout;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (this.options.seleniumTimeout) {
|
|
283
|
-
this.driver.seleniumTimeout = this.options.seleniumTimeout;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (provider === _utils.default.provider.PERFECTO) {
|
|
287
|
-
const perfectoExecutionContext = await new _perfectoReporting.default.Perfecto.PerfectoExecutionContext({
|
|
288
|
-
webdriver: {
|
|
289
|
-
executeScript: async (command, params) => {
|
|
290
|
-
return await this.driver.execute(command, params);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
this.reportingClient = new _perfectoReporting.default.Perfecto.PerfectoReportingClient(perfectoExecutionContext);
|
|
295
|
-
await this.reportingClient.testStart(name);
|
|
296
|
-
}
|
|
297
|
-
} catch (e) {
|
|
298
|
-
throw _helper.default.getAppiumInitError(e);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
this.appContext = await this.driver.getContext(); // if we are running on Android 7+ emulator, and thus/or using a WebView Browser Tester -
|
|
302
|
-
// perform an actual appContext switch to WEB
|
|
303
|
-
// so Appium will delegate commands to Chrome Driver instead of Appium Driver
|
|
304
|
-
|
|
305
|
-
if (this.caps.browserName === 'chromium-webview') {
|
|
306
|
-
await this.setWebViewContext();
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (provider === _utils.default.provider.BROWSERSTACK) {// ignore
|
|
310
|
-
// fails on browserstack
|
|
311
|
-
} else {
|
|
312
|
-
await this.driver.setTimeout({
|
|
313
|
-
'implicit': this.waitForTimeout
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
super.init(this.driver);
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* @function dispose
|
|
321
|
-
* @summary Ends the current session.
|
|
322
|
-
* @param {String=} status - Test status, either `passed` or `failed`.
|
|
323
|
-
*/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
async dispose(status) {
|
|
327
|
-
if (!status) {
|
|
328
|
-
status = 'passed';
|
|
329
|
-
|
|
330
|
-
if (this.rs.steps && Array.isArray(this.rs.steps) && this.rs.steps.length > 0) {
|
|
331
|
-
const failedFinded = this.rs.steps.find(item => item.status === 'failed');
|
|
332
|
-
|
|
333
|
-
if (failedFinded) {
|
|
334
|
-
status = 'failed';
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (this.driver && this.isInitialized) {
|
|
340
|
-
status = status.toUpperCase();
|
|
341
|
-
|
|
342
|
-
if (this.driver.provider === _utils.default.provider.PERFECTO) {
|
|
343
|
-
await this.reportingClient.testStop({
|
|
344
|
-
status: status === 'PASSED' ? _perfectoReporting.default.Constants.results.passed : _perfectoReporting.default.Constants.results.failed
|
|
345
|
-
});
|
|
346
|
-
} else if (this.driver.provider === _utils.default.provider.BROWSERSTACK) {
|
|
347
|
-
await this._sendResultStatusToBrowserstack(status);
|
|
348
|
-
await this.deleteSession();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
if (!['CANCELED', 'FAILED'].includes(status)) {
|
|
353
|
-
if (this.seleniumSessionTimeout) {// ignore
|
|
354
|
-
// deleteSession will take 5 min to call
|
|
355
|
-
} else {
|
|
356
|
-
await this.driver.deleteSession();
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
} catch (e) {
|
|
360
|
-
this.logger.warn('Error disposing driver: ' + e); // ignore any errors at disposal stage
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
this.driver = null;
|
|
364
|
-
this.lastNavigationStartTime = null;
|
|
365
|
-
super.dispose();
|
|
366
|
-
} else {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* @summary Opens new transaction.
|
|
372
|
-
* @description The transaction will persist till a new one is opened. Transaction names must be
|
|
373
|
-
* unique.
|
|
374
|
-
* @function transaction
|
|
375
|
-
* @param {String} name - The transaction name.
|
|
376
|
-
* @for android, ios, hybrid, web
|
|
377
|
-
*/
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
transaction(name) {
|
|
381
|
-
global._lastTransactionName = name;
|
|
382
|
-
}
|
|
383
|
-
/*
|
|
384
|
-
* Private
|
|
385
|
-
*/
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
_isAction(name) {
|
|
389
|
-
return ACTION_COMMANDS.includes(name);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
_takeScreenshotSilent(name) {
|
|
393
|
-
if (!NO_SCREENSHOT_COMMANDS.includes(name)) {
|
|
394
|
-
let error;
|
|
395
|
-
|
|
396
|
-
try {
|
|
397
|
-
if (this.driver && this.driver.takeScreenshot) {
|
|
398
|
-
let retval;
|
|
399
|
-
this.driver.call(() => {
|
|
400
|
-
return new Promise((resolve, reject) => {
|
|
401
|
-
const waitUntilRetVal = this.driver.waitUntil(async () => {
|
|
402
|
-
try {
|
|
403
|
-
let images = [];
|
|
404
|
-
|
|
405
|
-
const pushImageToImages = async (fetchTitle = true) => {
|
|
406
|
-
const image = await this.driver.takeScreenshot();
|
|
407
|
-
|
|
408
|
-
if (fetchTitle) {
|
|
409
|
-
const title = await this.driver.getTitle();
|
|
410
|
-
|
|
411
|
-
if (title) {
|
|
412
|
-
const textToImage = require('text-to-image');
|
|
413
|
-
|
|
414
|
-
let titleImage = await textToImage.generate(title, {
|
|
415
|
-
debug: false,
|
|
416
|
-
fontFamily: 'Arial'
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
if (titleImage && typeof titleImage === 'string') {
|
|
420
|
-
titleImage = titleImage.replace('data:image/png;base64,', '');
|
|
421
|
-
images.push(titleImage);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
images.push(image);
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
const isWebViewContext = await this.isWebViewContext();
|
|
430
|
-
|
|
431
|
-
if (isWebViewContext) {
|
|
432
|
-
// collect all (screenshot and title) images
|
|
433
|
-
const handles = await this.driver.getWindowHandles();
|
|
434
|
-
|
|
435
|
-
if (handles && Array.isArray(handles) && handles.length > 0) {
|
|
436
|
-
for (const handle of handles) {
|
|
437
|
-
await this.driver.switchToWindow(handle);
|
|
438
|
-
await pushImageToImages();
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
} else {
|
|
442
|
-
await pushImageToImages(false);
|
|
443
|
-
} // merge all images into one
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const mergedImage = await (0, _imgMerge.default)(images, {
|
|
447
|
-
direction: true
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
if (mergedImage && typeof mergedImage === 'string') {
|
|
451
|
-
retval = mergedImage.replace('data:image/jpeg;base64,', '');
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
return true;
|
|
455
|
-
} catch (e) {
|
|
456
|
-
error = e;
|
|
457
|
-
return false;
|
|
458
|
-
}
|
|
459
|
-
}, {
|
|
460
|
-
timeout: 30 * 1000
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
if (waitUntilRetVal && waitUntilRetVal.then) {
|
|
464
|
-
waitUntilRetVal.then(() => {
|
|
465
|
-
resolve();
|
|
466
|
-
}).catch(err => {
|
|
467
|
-
reject(err);
|
|
468
|
-
});
|
|
469
|
-
} else {
|
|
470
|
-
resolve();
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
if (error) {
|
|
476
|
-
this.logger.error('Cannot get screenshot', error);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
return retval;
|
|
480
|
-
}
|
|
481
|
-
} catch (e) {
|
|
482
|
-
this.logger.error('Cannot get screenshot', e);
|
|
483
|
-
|
|
484
|
-
if (error) {
|
|
485
|
-
this.logger.error('Cannot get screenshot inner error', error);
|
|
486
|
-
} // ignore
|
|
487
|
-
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
} // _getLogs(name) {
|
|
491
|
-
// if (!NO_LOGS_COMMANDS.includes(name)) {
|
|
492
|
-
// return this.getLogs();
|
|
493
|
-
// }
|
|
494
|
-
// }
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
_adjustAppiumLog(log, src) {
|
|
498
|
-
if (!log || typeof log !== 'object') {
|
|
499
|
-
return null;
|
|
500
|
-
} // TODO: convert log.timestamp from the device time zone to the local one (so we can later correlate between steps and logs)
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return {
|
|
504
|
-
time: log.timestamp,
|
|
505
|
-
msg: log.message,
|
|
506
|
-
level: log.level,
|
|
507
|
-
src: src
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
_iterationStart() {
|
|
512
|
-
// clear transaction name saved in previous iteration if any
|
|
513
|
-
global._lastTransactionName = null;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
async _iterationEnd(error) {
|
|
517
|
-
if (error && error.type === _helper.default.errorCode.SELENIUM_SESSION_TIMEOUT) {
|
|
518
|
-
this.seleniumSessionTimeout = true;
|
|
519
|
-
return;
|
|
520
|
-
} else {
|
|
521
|
-
this.seleniumSessionTimeout = false;
|
|
522
|
-
} // ignore the rest if mob module is not initialized
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
if (!this.isInitialized) {
|
|
526
|
-
return;
|
|
527
|
-
} // collect all the device logs for this session
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (this.options.collectDeviceLogs) {
|
|
531
|
-
try {
|
|
532
|
-
const logs = await this.getDeviceLogs();
|
|
533
|
-
|
|
534
|
-
if (logs && Array.isArray(logs)) {
|
|
535
|
-
for (let log of logs) {
|
|
536
|
-
this.rs.logs.push(this._adjustAppiumLog(log, 'device'));
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
} catch (e) {
|
|
540
|
-
// ignore errors
|
|
541
|
-
this.logger.error('Cannot retrieve device logs.', e);
|
|
542
|
-
}
|
|
543
|
-
} // collect all the browser logs for this session
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
if (this.options.collectBrowserLogs) {
|
|
547
|
-
try {
|
|
548
|
-
const logs = await this.getBrowserLogs();
|
|
549
|
-
|
|
550
|
-
if (logs && Array.isArray(logs)) {
|
|
551
|
-
for (let log of logs) {
|
|
552
|
-
this.rs.logs.push(this._adjustAppiumLog(log, 'browser'));
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
} catch (e) {
|
|
556
|
-
// ignore errors
|
|
557
|
-
this.logger.error('Cannot retrieve browser logs.', e);
|
|
558
|
-
}
|
|
559
|
-
} // collect all Appium logs for this session
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (this.options.collectAppiumLogs) {
|
|
563
|
-
try {
|
|
564
|
-
const logs = this.getAppiumLogs();
|
|
565
|
-
|
|
566
|
-
if (logs && Array.isArray(logs)) {
|
|
567
|
-
for (var logEntry of logs) {
|
|
568
|
-
this.rs.logs.push(this._adjustAppiumLog(logEntry, 'appium'));
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
} catch (e) {
|
|
572
|
-
// ignore errors
|
|
573
|
-
this.logger.error('Cannot retrieve Appium logs.', e);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
_getWdioLocator(locator) {
|
|
579
|
-
if (!locator) {
|
|
580
|
-
throw new _OxygenError.default(_helper.default.errorCode.SCRIPT_ERROR, 'Invalid argument - locator not specified');
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (typeof locator !== 'string') {
|
|
584
|
-
return locator;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (locator.indexOf('/') === 0) {
|
|
588
|
-
return locator; // leave xpath locator as is
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
const platform = this.caps && this.caps.platformName ? this.caps.platformName.toLowerCase() : null;
|
|
592
|
-
|
|
593
|
-
if (this.appContext === 'NATIVE_APP' && platform === 'android') {
|
|
594
|
-
if (locator.indexOf('id=') === 0) {
|
|
595
|
-
// prepend package name if it's not specified
|
|
596
|
-
// NOTE: getCurrentPackage() seems to crash possibly due to a wdio bug.
|
|
597
|
-
// so we get package name from caps instead.
|
|
598
|
-
locator = locator.substr('id='.length);
|
|
599
|
-
|
|
600
|
-
if (locator.indexOf(':id/') === -1) {
|
|
601
|
-
locator = this.caps.appPackage + ':id/' + locator;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return 'android=new UiSelector().resourceId("' + locator + '")';
|
|
605
|
-
} else if (locator.indexOf('class=') === 0) return 'android=new UiSelector().className("' + locator.substr('class='.length) + '")';else if (locator.indexOf('text=') === 0) return 'android=new UiSelector().text("' + locator.substr('text='.length) + '")';else if (locator.indexOf('text-contains=') === 0) return 'android=new UiSelector().textContains("' + locator.substr('text-contains='.length) + '")';else if (locator.indexOf('desc=') === 0) return 'android=new UiSelector().description("' + locator.substr('desc='.length) + '")';else if (locator.indexOf('desc-contains=') === 0) return 'android=new UiSelector().descriptionContains("' + locator.substr('desc-contains='.length) + '")';else if (locator.indexOf('scrollable') === 0) return 'android=new UiSelector().scrollable(true)';else if (locator.indexOf('~') === 0) // accessibility id
|
|
606
|
-
return locator;
|
|
607
|
-
} else if (this.appContext === 'NATIVE_APP' && platform === 'ios') {
|
|
608
|
-
if (locator.indexOf('~') === 0) // accessibility id
|
|
609
|
-
return locator;
|
|
610
|
-
} else if (this.appContext !== 'NATIVE_APP') {
|
|
611
|
-
// Hybrid or Web application
|
|
612
|
-
if (locator.indexOf('id=') === 0) return '#' + locator.substr('id='.length); // convert 'id=' to '#'
|
|
613
|
-
else if (locator.indexOf('name=') === 0) return '[name=' + locator.substr('name='.length) + ']';else if (locator.indexOf('link=') === 0) return '=' + locator.substr('link='.length);else if (locator.indexOf('link-contains=') === 0) return '*=' + locator.substr('link='.length);else if (locator.indexOf('css=') === 0) return locator.substr('css='.length); // in case of css, just remove css= prefix
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
return locator;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
_loadHelperFunctions() {
|
|
620
|
-
this.helpers.getWdioLocator = this._getWdioLocator;
|
|
621
|
-
this.helpers.matchPattern = _utils.default.matchPattern;
|
|
622
|
-
this.helpers.getElement = _utils.default.getElement;
|
|
623
|
-
this.helpers.getElements = _utils.default.getElements;
|
|
624
|
-
this.helpers.getChildElement = _utils.default.getChildElement;
|
|
625
|
-
this.helpers.getChildElements = _utils.default.getChildElements;
|
|
626
|
-
this.helpers.setTimeoutImplicit = _utils.default.setTimeoutImplicit;
|
|
627
|
-
this.helpers.restoreTimeoutImplicit = _utils.default.restoreTimeoutImplicit;
|
|
628
|
-
this.helpers.assertArgument = _utils.default.assertArgument;
|
|
629
|
-
this.helpers.assertArgumentNonEmptyString = _utils.default.assertArgumentNonEmptyString;
|
|
630
|
-
this.helpers.assertArgumentNumber = _utils.default.assertArgumentNumber;
|
|
631
|
-
this.helpers.assertArgumentNumberNonNegative = _utils.default.assertArgumentNumberNonNegative;
|
|
632
|
-
this.helpers.assertArgumentBool = _utils.default.assertArgumentBool;
|
|
633
|
-
this.helpers.assertArgumentBoolOptional = _utils.default.assertArgumentBoolOptional;
|
|
634
|
-
this.helpers.assertArgumentTimeout = _utils.default.assertArgumentTimeout;
|
|
635
|
-
this.helpers.assertContext = _utils.default.assertContext;
|
|
636
|
-
this.helpers.contextList = _utils.default.contextList;
|
|
637
|
-
this.helpers.getLogTypes = _utils.default.getLogTypes;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
async deleteSession() {
|
|
641
|
-
try {
|
|
642
|
-
if (this.driver && this.driver.deleteSession) {
|
|
643
|
-
await this.driver.deleteSession();
|
|
644
|
-
}
|
|
645
|
-
} catch (e) {
|
|
646
|
-
this.logger.error('deleteSession error', e);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
async _sendResultStatusToBrowserstack(status) {
|
|
651
|
-
return new Promise((resolve, reject) => {
|
|
652
|
-
const requestBody = {
|
|
653
|
-
status: status === 'PASSED' ? 'passed' : 'failed'
|
|
654
|
-
};
|
|
655
|
-
let options;
|
|
656
|
-
|
|
657
|
-
if (this.wdioOpts.capabilities.browserName) {
|
|
658
|
-
options = {
|
|
659
|
-
url: `https://api.browserstack.com/automate/sessions/${this.driver.sessionId}.json`,
|
|
660
|
-
method: 'PUT',
|
|
661
|
-
json: true,
|
|
662
|
-
rejectUnauthorized: false,
|
|
663
|
-
body: requestBody,
|
|
664
|
-
'auth': {
|
|
665
|
-
'user': this.wdioOpts.user,
|
|
666
|
-
'pass': this.wdioOpts.key,
|
|
667
|
-
'sendImmediately': false
|
|
668
|
-
}
|
|
669
|
-
};
|
|
670
|
-
} else {
|
|
671
|
-
options = {
|
|
672
|
-
url: `https://api-cloud.browserstack.com/app-automate/sessions/${this.driver.sessionId}.json`,
|
|
673
|
-
method: 'PUT',
|
|
674
|
-
json: true,
|
|
675
|
-
rejectUnauthorized: false,
|
|
676
|
-
body: requestBody,
|
|
677
|
-
'auth': {
|
|
678
|
-
'user': this.wdioOpts.capabilities['browserstack.user'],
|
|
679
|
-
'pass': this.wdioOpts.capabilities['browserstack.key'],
|
|
680
|
-
'sendImmediately': false
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
try {
|
|
686
|
-
(0, _request.default)(options, (err, res, body) => {
|
|
687
|
-
resolve();
|
|
688
|
-
});
|
|
689
|
-
} catch (e) {
|
|
690
|
-
this.logger.error('Unable to send result status to Browserstack: ' + e.toString());
|
|
691
|
-
resolve();
|
|
692
|
-
}
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
exports.default = MobileModule;
|
|
699
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9veF9tb2R1bGVzL21vZHVsZS1tb2IuanMiXSwibmFtZXMiOlsiTU9EVUxFX05BTUUiLCJERUZBVUxUX0FQUElVTV9VUkwiLCJERUZBVUxUX0JST1dTRVJfTkFNRSIsIk5PX1NDUkVFTlNIT1RfQ09NTUFORFMiLCJBQ1RJT05fQ09NTUFORFMiLCJERUZBVUxUX1dBSVRfVElNRU9VVCIsIk1vYmlsZU1vZHVsZSIsIldlYkRyaXZlck1vZHVsZSIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImNvbnRleHQiLCJycyIsImxvZ2dlciIsIm1vZHVsZXMiLCJzZXJ2aWNlcyIsInRyYW5zYWN0aW9ucyIsImxhc3ROYXZpZ2F0aW9uU3RhcnRUaW1lIiwibmV0d29ya1JlcXVlc3RzIiwiaGVscGVycyIsImFwcENvbnRleHQiLCJfbG9hZEhlbHBlckZ1bmN0aW9ucyIsIk94RXJyb3IiLCJlcnJIZWxwZXIiLCJ3YWl0Rm9yVGltZW91dCIsIm5hbWUiLCJnZXREcml2ZXIiLCJnZXRDYXBhYmlsaXRpZXMiLCJjYXBzIiwiaW5pdCIsImFwcGl1bVVybCIsImlzSW5pdGlhbGl6ZWQiLCJyZW9wZW5TZXNzaW9uIiwiZGVidWciLCJkcml2ZXIiLCJyZWxvYWRTZXNzaW9uIiwiX2lzSW5pdGlhbGl6ZWQiLCJjdHgiLCJwbGF0Zm9ybU5hbWUiLCJwbGF0Zm9ybVZlcnNpb24iLCJkZXZpY2VOYW1lIiwiYnJvd3Nlck5hbWUiLCJhdXRvbWF0aW9uTmFtZSIsInVkaWQiLCJhcHAiLCJlbmFibGVBcHBpdW1CZWhhdmlvciIsInVzZUFwcGl1bUZvcldlYiIsImNvbGxlY3REZXZpY2VMb2dzIiwiY2xlYXJEZXZpY2VMb2dzT25TdGFydCIsImFwcFBhY2thZ2UiLCJ0b0xvd2VyQ2FzZSIsInJlY29yZEhBUiIsImJyb3dzZXIiLCJwZXJmb3JtYW5jZSIsInVybCIsIlVSTCIsInBhcnNlIiwicHJvdG9jb2wiLCJyZXBsYWNlIiwiaG9zdCIsImhvc3RuYW1lIiwicG9ydCIsInBhcnNlSW50IiwicGF0aCIsInBhdGhuYW1lIiwiYXV0aCIsInNwbGl0Iiwid2Rpb09wdHMiLCJ1c2VyIiwia2V5IiwiY2FwYWJpbGl0aWVzIiwibG9nTGV2ZWwiLCJydW5uZXIiLCJ3YWl0Zm9yVGltZW91dCIsImNvbm5lY3Rpb25SZXRyeVRpbWVvdXQiLCJjb25uZWN0aW9uUmV0cnlDb3VudCIsInByb3ZpZGVyIiwibW9kVXRpbHMiLCJkZXRlcm1pbmVQcm92aWRlciIsIlBFUkZFQ1RPIiwibWF4SW5zdGFuY2VzIiwib3BlbkRldmljZVRpbWVvdXQiLCJtYW51ZmFjdHVyZXIiLCJtb2RlbCIsIndkaW8iLCJyZW1vdGUiLCJzZWxlbml1bUJyb3dzZXJUaW1lb3V0Iiwic2VsZW5pdW1UaW1lb3V0IiwicGVyZmVjdG9FeGVjdXRpb25Db250ZXh0IiwicGVyZmVjdG9SZXBvcnRpbmciLCJQZXJmZWN0byIsIlBlcmZlY3RvRXhlY3V0aW9uQ29udGV4dCIsIndlYmRyaXZlciIsImV4ZWN1dGVTY3JpcHQiLCJjb21tYW5kIiwicGFyYW1zIiwiZXhlY3V0ZSIsInJlcG9ydGluZ0NsaWVudCIsIlBlcmZlY3RvUmVwb3J0aW5nQ2xpZW50IiwidGVzdFN0YXJ0IiwiZSIsImdldEFwcGl1bUluaXRFcnJvciIsImdldENvbnRleHQiLCJzZXRXZWJWaWV3Q29udGV4dCIsIkJST1dTRVJTVEFDSyIsInNldFRpbWVvdXQiLCJkaXNwb3NlIiwic3RhdHVzIiwic3RlcHMiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJmYWlsZWRGaW5kZWQiLCJmaW5kIiwiaXRlbSIsInRvVXBwZXJDYXNlIiwidGVzdFN0b3AiLCJDb25zdGFudHMiLCJyZXN1bHRzIiwicGFzc2VkIiwiZmFpbGVkIiwiX3NlbmRSZXN1bHRTdGF0dXNUb0Jyb3dzZXJzdGFjayIsImRlbGV0ZVNlc3Npb24iLCJpbmNsdWRlcyIsInNlbGVuaXVtU2Vzc2lvblRpbWVvdXQiLCJ3YXJuIiwidHJhbnNhY3Rpb24iLCJnbG9iYWwiLCJfbGFzdFRyYW5zYWN0aW9uTmFtZSIsIl9pc0FjdGlvbiIsIl90YWtlU2NyZWVuc2hvdFNpbGVudCIsImVycm9yIiwidGFrZVNjcmVlbnNob3QiLCJyZXR2YWwiLCJjYWxsIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ3YWl0VW50aWxSZXRWYWwiLCJ3YWl0VW50aWwiLCJpbWFnZXMiLCJwdXNoSW1hZ2VUb0ltYWdlcyIsImZldGNoVGl0bGUiLCJpbWFnZSIsInRpdGxlIiwiZ2V0VGl0bGUiLCJ0ZXh0VG9JbWFnZSIsInJlcXVpcmUiLCJ0aXRsZUltYWdlIiwiZ2VuZXJhdGUiLCJmb250RmFtaWx5IiwicHVzaCIsImlzV2ViVmlld0NvbnRleHQiLCJoYW5kbGVzIiwiZ2V0V2luZG93SGFuZGxlcyIsImhhbmRsZSIsInN3aXRjaFRvV2luZG93IiwibWVyZ2VkSW1hZ2UiLCJkaXJlY3Rpb24iLCJ0aW1lb3V0IiwidGhlbiIsImNhdGNoIiwiZXJyIiwiX2FkanVzdEFwcGl1bUxvZyIsImxvZyIsInNyYyIsInRpbWUiLCJ0aW1lc3RhbXAiLCJtc2ciLCJtZXNzYWdlIiwibGV2ZWwiLCJfaXRlcmF0aW9uU3RhcnQiLCJfaXRlcmF0aW9uRW5kIiwidHlwZSIsImVycm9ySGVscGVyIiwiZXJyb3JDb2RlIiwiU0VMRU5JVU1fU0VTU0lPTl9USU1FT1VUIiwibG9ncyIsImdldERldmljZUxvZ3MiLCJjb2xsZWN0QnJvd3NlckxvZ3MiLCJnZXRCcm93c2VyTG9ncyIsImNvbGxlY3RBcHBpdW1Mb2dzIiwiZ2V0QXBwaXVtTG9ncyIsImxvZ0VudHJ5IiwiX2dldFdkaW9Mb2NhdG9yIiwibG9jYXRvciIsIlNDUklQVF9FUlJPUiIsImluZGV4T2YiLCJwbGF0Zm9ybSIsInN1YnN0ciIsImdldFdkaW9Mb2NhdG9yIiwibWF0Y2hQYXR0ZXJuIiwiZ2V0RWxlbWVudCIsImdldEVsZW1lbnRzIiwiZ2V0Q2hpbGRFbGVtZW50IiwiZ2V0Q2hpbGRFbGVtZW50cyIsInNldFRpbWVvdXRJbXBsaWNpdCIsInJlc3RvcmVUaW1lb3V0SW1wbGljaXQiLCJhc3NlcnRBcmd1bWVudCIsImFzc2VydEFyZ3VtZW50Tm9uRW1wdHlTdHJpbmciLCJhc3NlcnRBcmd1bWVudE51bWJlciIsImFzc2VydEFyZ3VtZW50TnVtYmVyTm9uTmVnYXRpdmUiLCJhc3NlcnRBcmd1bWVudEJvb2wiLCJhc3NlcnRBcmd1bWVudEJvb2xPcHRpb25hbCIsImFzc2VydEFyZ3VtZW50VGltZW91dCIsImFzc2VydENvbnRleHQiLCJjb250ZXh0TGlzdCIsImdldExvZ1R5cGVzIiwicmVxdWVzdEJvZHkiLCJzZXNzaW9uSWQiLCJtZXRob2QiLCJqc29uIiwicmVqZWN0VW5hdXRob3JpemVkIiwiYm9keSIsInJlcyIsInRvU3RyaW5nIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBR0EsTUFBTUEsV0FBVyxHQUFHLEtBQXBCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsOEJBQTNCO0FBQ0EsTUFBTUMsb0JBQW9CLEdBQUcsU0FBN0I7QUFDQSxNQUFNQyxzQkFBc0IsR0FBRyxDQUFDLE1BQUQsRUFBUyxhQUFULENBQS9CO0FBQ0EsTUFBTUMsZUFBZSxHQUFHLENBQUMsTUFBRCxFQUFRLEtBQVIsRUFBYyxPQUFkLEVBQXNCLE9BQXRCLEVBQThCLFFBQTlCLEVBQXVDLFVBQXZDLENBQXhCO0FBQ0EsTUFBTUMsb0JBQW9CLEdBQUcsS0FBSyxJQUFsQyxD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Q0FESjtBQUVKLG9CQUFRLEtBQUtILFFBQUwsQ0FBY0csWUFBZCxDQUEyQixrQkFBM0IsQ0FGSjtBQUdKLCtCQUFtQjtBQUhmO0FBTkYsU0FBVjtBQVlIOztBQUVELFVBQUk7QUFDQSw4QkFBUTVELE9BQVIsRUFBaUIsQ0FBQ3dKLEdBQUQsRUFBTW9ELEdBQU4sRUFBV0QsSUFBWCxLQUFvQjtBQUNqQzdFLFVBQUFBLE9BQU87QUFDVixTQUZEO0FBR0gsT0FKRCxDQUlFLE9BQU9wQyxDQUFQLEVBQVU7QUFDUixhQUFLdkYsTUFBTCxDQUFZc0gsS0FBWixDQUFrQixtREFBbUQvQixDQUFDLENBQUNtSCxRQUFGLEVBQXJFO0FBQ0EvRSxRQUFBQSxPQUFPO0FBQ1Y7QUFDSixLQTNDTSxDQUFQO0FBNENIOztBQXBsQnFEIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQ29weXJpZ2h0IChDKSAyMDE1LXByZXNlbnQgQ2xvdWRCZWF0IExpbWl0ZWRcclxuICpcclxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcclxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcclxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cclxuICovXHJcblxyXG4ndXNlIHN0cmljdCc7XHJcbi8qKlxyXG4gKiBAbmFtZSBtb2JcclxuICogQGRlc2NyaXB0aW9uIFByb3ZpZGVzIG1ldGhvZHMgZm9yIG1vYmlsZSBhdXRvbWF0aW9uLlxyXG4gKiBAc2FtcGxlICoqTG9jYXRvcnM6KiogIFxyXG4gKiBcclxuICogTmF0aXZlIGFwcGxpY2F0aW9uIGxvY2F0b3JzIGZvciFbXSguLi8uLi8uZ2l0Ym9vay9hc3NldHMvYW5kcm9pZC5wbmcpICBcclxuICogKiBgL1hQQVRIYCAtIExvY2F0ZXMgZWxlbWVudCB1c2luZyBhbiBYUGF0aCAxLjAgZXhwcmVzc2lvbi5cclxuICogKiBgfkFDQ0VTU0lCSUxJVFlfSURgIC0gTG9jYXRlcyBlbGVtZW50IGJ5IGl0cyBBY2Nlc3NpYmlsaXR5IElkLlxyXG4gKiAqIGBpZD1JRGAgLSBMb2NhdGVzIGVsZW1lbnQgYnkgaXRzIGlkLlxyXG4gKiAqIGBjbGFzcz1DTEFTU2AgLSBMb2NhdGVzIGVsZW1lbnQgYnkgaXRzIGNsYXNzLlxyXG4gKiAqIGB0ZXh0PVRFWFRgIC0gTG9jYXRlcyBlbGVtZW50IGJ5IGl0cyB2aXNpYmxlIHRleHQuXHJcbiAqICogYHRleHQtY29udGFpbnM9VEVYVGAgLSBMb2NhdGVzIGVsZW1lbnQgd2hvc2UgdmlzaWJsZSB0ZXh0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgc3RyaW5nLlxyXG4gKiAqIGBkZXNjPURFU0NSSVBUSU9OYCAtIExvY2F0ZXMgZWxlbWVudCBieSBpdHMgZGVzY3JpcHRpb24uXHJcbiAqICogYGRlc2MtY29udGFpbnM9REVTQ1JJUFRJT05gIC0gTG9jYXRlcyBlbGVtZW50IHdob3NlIGRlc2NyaXB0aW9uIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgc3RyaW5nLlxyXG4gKiAqIGBzY3JvbGxhYmxlYCAtIExvY2F0ZXMgZWxlbWVudHMgdGhhdCBhcmUgc2Nyb2xsYWJsZS4gIFxyXG4gKiAgXHJcbiAqIE5hdGl2ZSBhcHBsaWNhdGlvbiBsb2NhdG9ycyBmb3IhW10oLi4vLi4vLmdpdGJvb2svYXNzZXRzL2FwcGxlLnBuZykgIFxyXG4gKiAgXHJcbiAqICogYC9YUEFUSGAgLSBMb2NhdGVzIGVsZW1lbnQgdXNpbmcgYW4gWFBhdGggMS4wIGV4cHJlc3Npb24uXHJcbiAqICogYGlkPUlEYCAtIExvY2F0ZXMgZWxlbWVudCBieSBpdHMgSUQuXHJcbiAqICogYH5BQ0NFU1NJQklMSVRZX0lEYCAtIExvY2F0ZXMgZWxlbWVudCBieSBpdHMgQWNjZXNzaWJpbGl0eSBJZC4gIFxyXG4gKiAgXHJcbiAqIEh5YnJpZCFbXSguLi8uLi8uZ2l0Ym9vay9hc3NldHMvaHlicmlkLnBuZykgIGFuZCBXZWIhW10oLi4vLi4vLmdpdGJvb2svYXNzZXRzL3dlYi5wbmcpICBhcHBsaWNhdGlvbiBsb2NhdG9ycyBmb3IhW10oLi4vLi4vLmdpdGJvb2svYXNzZXRzL2FuZHJvaWQucG5nKSAgIVtdKC4uLy4uLy5naXRib29rL2Fzc2V0cy9hcHBsZS5wbmcpICBcclxuICogIFxyXG4gKiAqIGAvWFBBVEhgIC0gTG9jYXRlcyBlbGVtZW50IHVzaW5nIGFuIFhQYXRoIDEuMCBleHByZXNzaW9uLlxyXG4gKiAqIGBpZD1JRGAgLSBMb2NhdGVzIGVsZW1lbnQgYnkgaXRzIGlkLlxyXG4gKiAqIGBuYW1lPU5BTUVgIC0gTG9jYXRlcyBlbGVtZW50IGJ5IGl0cyBuYW1lIGF0dHJpYnV0ZS5cclxuICogKiBgdGFnPU5BTUVgIC0gTG9jYXRlcyBlbGVtZW50IGJ5IGl0cyB0YWcgbmFtZS5cclxuICogKiBgbGluaz1URVhUYCAtIExvY2F0ZXMgYW5jaG9yIGVsZW1lbnQgd2hvc2UgdGV4dCBtYXRjaGVzIHRoZSBnaXZlbiBzdHJpbmcuXHJcbiAqICogYGxpbmstY29udGFpbnM9VEVYVGAgLSBMb2NhdGVzIGFuY2hvciBlbGVtZW50IHdob3NlIHRleHQgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZy5cclxuICogKiBgY3NzPUNTU19TRUxFQ1RPUmAgLSBMb2NhdGVzIGVsZW1lbnQgdXNpbmcgYSBDU1Mgc2VsZWN0b3IuXHJcbiAqIFxyXG4gKiAqKlBhdHRlcm4gYXJndW1lbnRzOioqXHJcbiAqIFxyXG4gKiBDb21tYW5kcyB3aGljaCBleHBlY3QgYSBzdHJpbmcgbWF0Y2hpbmcgcGF0dGVybiBpbiB0aGVpciBhcmd1bWVudHMsIHN1cHBvcnQgZm9sbG93aW5nIHBhdHRlcm5zIHVubGVzcyBzcGVjaWZpZWQgb3RoZXJ3aXNlOlxyXG4gKiBcclxuICogKiBgcmVnZXg6UEFUVEVSTmAgLSBNYXRjaCB1c2luZyByZWd1bGFyIGV4cHJlc3Npb24uXHJcbiAqICogYFBBVFRFUk5gIC0gVmVyYmF0aW0gbWF0Y2hpbmcuXHJcbiAqIFxyXG4gKi9cclxuaW1wb3J0IFVSTCBmcm9tICd1cmwnO1xyXG5pbXBvcnQgKiBhcyB3ZGlvIGZyb20gJ3dlYmRyaXZlcmlvJztcclxuaW1wb3J0IFdlYkRyaXZlck1vZHVsZSBmcm9tICcuLi9jb3JlL1dlYkRyaXZlck1vZHVsZSc7XHJcbmltcG9ydCBtb2RVdGlscyBmcm9tICcuL3V0aWxzJztcclxuaW1wb3J0IGVyckhlbHBlciBmcm9tICcuLi9lcnJvcnMvaGVscGVyJztcclxuaW1wb3J0IE94RXJyb3IgZnJvbSAnLi4vZXJyb3JzL094eWdlbkVycm9yJztcclxuaW1wb3J0IHBlcmZlY3RvUmVwb3J0aW5nIGZyb20gJ3BlcmZlY3RvLXJlcG9ydGluZyc7XHJcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3JlcXVlc3QnO1xyXG5pbXBvcnQgbWVyZ2VJbWFnZXMgZnJvbSAnLi4vbGliL2ltZy1tZXJnZSc7XHJcbmltcG9ydCBlcnJvckhlbHBlciBmcm9tICcuLi9lcnJvcnMvaGVscGVyJztcclxuXHJcbmNvbnN0IE1PRFVMRV9OQU1FID0gJ21vYic7XHJcbmNvbnN0IERFRkFVTFRfQVBQSVVNX1VSTCA9ICdodHRwOi8vbG9jYWxob3N0OjQ3MjMvd2QvaHViJztcclxuY29uc3QgREVGQVVMVF9CUk9XU0VSX05BTUUgPSAnZGVmYXVsdCc7XHJcbmNvbnN0IE5PX1NDUkVFTlNIT1RfQ09NTUFORFMgPSBbJ2luaXQnLCAnYXNzZXJ0QWxlcnQnXTtcclxuY29uc3QgQUNUSU9OX0NPTU1BTkRTID0gWydvcGVuJywndGFwJywnY2xpY2snLCdzd2lwZScsJ3N1Ym1pdCcsJ3NldFZhbHVlJ107XHJcbmNvbnN0IERFRkFVTFRfV0FJVF9USU1FT1VUID0gNjAgKiAxMDAwOyAgICAgICAgICAgIC8vIGRlZmF1bHQgNjBzIHdhaXQgdGltZW91dFxyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTW9iaWxlTW9kdWxlIGV4dGVuZHMgV2ViRHJpdmVyTW9kdWxlIHtcclxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMsIGNvbnRleHQsIHJzLCBsb2dnZXIsIG1vZHVsZXMsIHNlcnZpY2VzKSB7XHJcbiAgICAgICAgc3VwZXIob3B0aW9ucywgY29udGV4dCwgcnMsIGxvZ2dlciwgbW9kdWxlcywgc2VydmljZXMpO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25zID0ge307XHJcbiAgICAgICAgdGhpcy5sYXN0TmF2aWdhdGlvblN0YXJ0VGltZSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5uZXR3b3JrUmVxdWVzdHMgPSBudWxsO1xyXG4gICAgICAgIHRoaXMuaGVscGVycyA9IHt9O1xyXG4gICAgICAgIHRoaXMuYXBwQ29udGV4dCA9ICdOQVRJVkVfQVBQJztcclxuICAgICAgICB0aGlzLl9sb2FkSGVscGVyRnVuY3Rpb25zKCk7XHJcbiAgICAgICAgLy8gc3VwcG9ydCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IChzb21lIG1vZHVsZSBjb21tYW5kcyBtaWdodCByZWZlciB0byB0aGlzLk94RXJyb3IgYW5kIHRoaXMuZXJySGVscGVyKVxyXG4gICAgICAgIHRoaXMuT3hFcnJvciA9IE94RXJyb3I7XHJcbiAgICAgICAgdGhpcy5lcnJIZWxwZXIgPSBlcnJIZWxwZXI7XHJcbiAgICAgICAgLy8gaG9sZHMgZWxlbWVudCBvcGVyYXRpb24gdGltZW91dCB2YWx1ZVxyXG4gICAgICAgIHRoaXMud2FpdEZvclRpbWVvdXQgPSBERUZBVUxUX1dBSVRfVElNRU9VVDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gTU9EVUxFX05BTUU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb24gZ2V0RHJpdmVyXHJcbiAgICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIFdESU8gZHJpdmVyLlxyXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBXRElPIGRyaXZlci5cclxuICAgICAqL1xyXG4gICAgZ2V0RHJpdmVyKCkge1xyXG4gICAgICAgIHJldHVybiBzdXBlci5nZXREcml2ZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvbiBnZXRDYXBhYmlsaXRpZXNcclxuICAgICAqIEBzdW1tYXJ5IFJldHVybnMgY3VycmVudGx5IGRlZmluZWQgY2FwYWJpbGl0aWVzLlxyXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGNhcGFiaWxpdGllcyBvYmplY3QuXHJcbiAgICAgKi9cclxuICAgIGdldENhcGFiaWxpdGllcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jYXBzIHx8IHN1cGVyLmdldENhcGFiaWxpdGllcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGZ1bmN0aW9uIGluaXRcclxuICAgICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIGEgbmV3IEFwcGl1bSBzZXNzaW9uLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmc9fSBjYXBzIC0gRGVzaXJlZCBjYXBhYmlsaXRpZXMuIElmIG5vdCBzcGVjaWZpZWQgY2FwYWJpbGl0aWVzIHdpbGwgYmUgdGFrZW4gZnJvbSBzdWl0ZSBkZWZpbml0aW9uLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmc9fSBhcHBpdW1VcmwgLSBSZW1vdGUgQXBwaXVtIHNlcnZlciBVUkwgKGRlZmF1bHQ6IGh0dHA6Ly9sb2NhbGhvc3Q6NDcyMy93ZC9odWIpLlxyXG4gICAgICovXHJcbiAgICBhc3luYyBpbml0KGNhcHMsIGFwcGl1bVVybCkge1xyXG4gICAgICAgIC8vIGlmIHJlb3BlblNlc3Npb24gaXMgdHJ1ZSAtIHJlaW5pdGlsaXplIHRoZSBtb2R1bGVcclxuICAgICAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmVvcGVuU2Vzc2lvbiAhPT0gZmFsc2UpIHsgLy8gdHJ1ZSBvciBmYWxzZSBpZiBleHBsaXNpdGx5IHNldC4gdHJ1ZSBvbiBudWxsIG9yIHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdyZW9wZW5TZXNzaW9uIGlzIHRydWUgLSByZWxvYWRpbmcgdGhlIHNlc3Npb24uLi4nKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJpdmVyLnJlbG9hZFNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2lzSW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoJ21vYi5pbml0IHdhcyBjYWxsZWQgZm9yIGFscmVhZHkgaW5pdGlhbGl6ZWQgbW9kdWxlLiByZW9wZW5TZXNzaW9uIGlzIGZhbHNlIHNvIHRoZSBjYWxsIGlzIGlnbm9yZWQuJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRklYTUU6IHRoaXMgc2hvdWxkIGJlIHJlZmFjdG9yZWRcclxuICAgICAgICBpZiAodGhpcy5jdHguY2FwcyAmJiB0aGlzLmN0eC5jYXBzWydwZXJmZWN0b01vYmlsZTpvcHRpb25zJ10pIHtcclxuICAgICAgICAgICAgaWYgKGNhcHMpIHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYXBzLnBsYXRmb3JtTmFtZTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYXBzLnBsYXRmb3JtVmVyc2lvbjtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYXBzLmRldmljZU5hbWU7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgY2Fwcy5icm93c2VyTmFtZTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYXBzLmF1dG9tYXRpb25OYW1lO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIGNhcHMudWRpZDtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY2Fwcy5hcHApIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXBzLmVuYWJsZUFwcGl1bUJlaGF2aW9yID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2Fwcy51c2VBcHBpdW1Gb3JXZWIgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhcHMuZW5hYmxlQXBwaXVtQmVoYXZpb3IgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdHguY2Fwcy51c2VBcHBpdW1Gb3JXZWIgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdHguY2Fwcy5lbmFibGVBcHBpdW1CZWhhdmlvciA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghYXBwaXVtVXJsKSB7XHJcbiAgICAgICAgICAgIGFwcGl1bVVybCA9IHRoaXMub3B0aW9ucy5hcHBpdW1VcmwgfHwgREVGQVVMVF9BUFBJVU1fVVJMO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gbWVyZ2UgY2FwYWJpbGl0aWVzIGZyb20gY29udGV4dCBhbmQgZnJvbSBpbml0IGZ1bmN0aW9uIGFyZ3VtZW50LCBnaXZlIHByZWZlcmVuY2UgdG8gY29udGV4dC1wYXNzZWQgY2FwYWJpbGl0aWVzXHJcbiAgICAgICAgdGhpcy5jYXBzID0ge307XHJcbiAgICAgICAgaWYgKHRoaXMuY3R4LmNhcHMpIHtcclxuICAgICAgICAgICAgdGhpcy5jYXBzID0geyAuLi50aGlzLmN0eC5jYXBzIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYXBzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FwcyA9IHsgLi4udGhpcy5jYXBzLCAuLi5jYXBzIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBtYWtlIHN1cmUgdG8gY2xlYXIgdGhlIGV4aXN0aW5nIGRldmljZSBsb2dzLCBpZiBjb2xsZWN0RGV2aWNlTG9ncyBvcHRpb24gaXMgdHJ1ZSAod2Ugd2FudCB0byBpbmNsdWRlIGxvZ3Mgb25seSByZWxldmFudCBmb3IgdGhpcyBzZXNzaW9uKVxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY29sbGVjdERldmljZUxvZ3MpIHtcclxuICAgICAgICAgICAgdGhpcy5jYXBzLmNsZWFyRGV2aWNlTG9nc09uU3RhcnQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaWYgYm90aCBicm93c2VyTmFtZSBhbmQgYXBwUGFja2FnZSB3ZXJlIHNwZWNpZmllZCAtIHJlbW92ZSBicm93c2VyTmFtZVxyXG4gICAgICAgIGlmICh0aGlzLmNhcHMuYnJvd3Nlck5hbWUgJiYgKHRoaXMuY2Fwcy5hcHBQYWNrYWdlIHx8IHRoaXMuY2Fwcy5hcHApKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhcHMuYnJvd3Nlck5hbWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIG5vIGFwcFBhY2thZ2Ugbm9yIGFwcCBjYXBhYmlsaXR5LCBub3QgYnJvd3Nlck5hbWUgYXJlIGRlZmluZWQsIGFzc3VtZSB3ZSB3YW50IHRvIHJ1biB0aGUgdGVzdCBhZ2FpbnN0IGRlZmF1bHQgYnJvd3NlclxyXG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmNhcHMuYnJvd3Nlck5hbWUgJiYgIXRoaXMuY2Fwcy5hcHBQYWNrYWdlICYmICF0aGlzLmNhcHMuYXBwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2Fwcy5icm93c2VyTmFtZSA9IERFRkFVTFRfQlJPV1NFUl9OQU1FO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB3ZWJkcml2ZXIgZXhwZWN0cyBsb3dlciBjYXNlIG5hbWVzXHJcbiAgICAgICAgaWYgKHRoaXMuY2Fwcy5icm93c2VyTmFtZSAmJiB0eXBlb2YgdGhpcy5jYXBzLmJyb3dzZXJOYW1lID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB0aGlzLmNhcHMuYnJvd3Nlck5hbWUgPSB0aGlzLmNhcHMuYnJvd3Nlck5hbWUudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYWRqdXN0IGNhcGFiaWxpdGllcyB0byBlbmFibGUgY29sbGVjdGluZyBicm93c2VyIGFuZCBwZXJmb3JtYW5jZSBzdGF0cyBpbiBDaHJvbWUgXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZWNvcmRIQVIgJiYgdGhpcy5jYXBzLmJyb3dzZXJOYW1lID09PSAnY2hyb21lJykge1xyXG4gICAgICAgICAgICB0aGlzLmNhcHNbJ2dvb2c6bG9nZ2luZ1ByZWZzJ10gPSB7ICAgICAvLyBmb3IgQ2hyb21lRHJpdmVyID49IDc1XHJcbiAgICAgICAgICAgICAgICBicm93c2VyOiAnQUxMJyxcclxuICAgICAgICAgICAgICAgIHBlcmZvcm1hbmNlOiAnQUxMJ1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcG9wdWxhdGUgV0RJTyBvcHRpb25zXHJcbiAgICAgICAgY29uc3QgdXJsID0gVVJMLnBhcnNlKGFwcGl1bVVybCk7XHJcbiAgICAgICAgY29uc3QgcHJvdG9jb2wgPSB1cmwucHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJyk7XHJcbiAgICAgICAgY29uc3QgaG9zdCA9IHVybC5ob3N0bmFtZTtcclxuICAgICAgICBjb25zdCBwb3J0ID0gcGFyc2VJbnQodXJsLnBvcnQgfHwgKHByb3RvY29sID09PSAnaHR0cHMnID8gNDQzIDogODApKTtcclxuICAgICAgICBjb25zdCBwYXRoID0gdXJsLnBhdGhuYW1lO1xyXG5cclxuICAgICAgICAvLyBhdXRoIGlzIG5lZWRlZCBtb3N0bHkgZm9yIGNsb3VkIHByb3ZpZGVycyBzdWNoIGFzIExhbWJkYVRlc3RcclxuICAgICAgICBpZiAodXJsLmF1dGgpIHtcclxuICAgICAgICAgICAgY29uc3QgYXV0aCA9IHVybC5hdXRoLnNwbGl0KCc6Jyk7XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy53ZGlvT3B0cyA9IHtcclxuICAgICAgICAgICAgICAgIHVzZXI6IGF1dGhbMF0sXHJcbiAgICAgICAgICAgICAgICBrZXk6IGF1dGhbMV1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciB3ZGlvT3B0cyA9IHtcclxuICAgICAgICAgICAgLi4udGhpcy5vcHRpb25zLndkaW9PcHRzIHx8IHt9LFxyXG4gICAgICAgICAgICBwcm90b2NvbDogcHJvdG9jb2wsXHJcbiAgICAgICAgICAgIGhvc3RuYW1lOiBob3N0LFxyXG4gICAgICAgICAgICBwb3J0OiBwb3J0LFxyXG4gICAgICAgICAgICBwYXRoOiBwYXRoLFxyXG4gICAgICAgICAgICBjYXBhYmlsaXRpZXM6IHRoaXMuY2FwcyxcclxuICAgICAgICAgICAgbG9nTGV2ZWw6ICdzaWxlbnQnLFxyXG4gICAgICAgICAgICBydW5uZXI6ICdyZXBsJyxcclxuICAgICAgICAgICAgd2FpdGZvclRpbWVvdXQ6IDUwMDAsIC8vIGluY3JlYXNlIHRoZSBkZWZhdWx0IDMwMDBcclxuICAgICAgICAgICAgY29ubmVjdGlvblJldHJ5VGltZW91dDogMzEwKjEwMDAsXHJcbiAgICAgICAgICAgIGNvbm5lY3Rpb25SZXRyeUNvdW50OiAxXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgbGV0IHByb3ZpZGVyID0gbW9kVXRpbHMuZGV0ZXJtaW5lUHJvdmlkZXIod2Rpb09wdHMpO1xyXG4gICAgICAgIGxldCBuYW1lID0gJ25hbWUnO1xyXG5cclxuICAgICAgICBpZiAocHJvdmlkZXIgPT09IG1vZFV0aWxzLnByb3ZpZGVyLlBFUkZFQ1RPKSB7XHJcbiAgICAgICAgICAgIHdkaW9PcHRzLmNhcGFiaWxpdGllcy5tYXhJbnN0YW5jZXMgPSAxO1xyXG4gICAgICAgICAgICB3ZGlvT3B0cy5wYXRoID0gJy9uZXhwZXJpZW5jZS9wZXJmZWN0b21vYmlsZS93ZC9odWInO1xyXG4gICAgICAgICAgICB3ZGlvT3B0cy5wb3J0ID0gODA7XHJcbiAgICAgICAgICAgIHdkaW9PcHRzLnByb3RvY29sID0gJ2h0dHAnO1xyXG4gICAgICAgICAgICB3ZGlvT3B0cy5vcGVuRGV2aWNlVGltZW91dCA9IDE1O1xyXG5cclxuICAgICAgICAgICAgZGVsZXRlIHdkaW9PcHRzLmNhcGFiaWxpdGllcy5tYW51ZmFjdHVyZXI7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB3ZGlvT3B0cy5jYXBhYmlsaXRpZXMubW9kZWw7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB3ZGlvT3B0cy5jYXBhYmlsaXRpZXMuYnJvd3Nlck5hbWU7XHJcblxyXG4gICAgICAgICAgICBuYW1lID0gd2Rpb09wdHMuY2FwYWJpbGl0aWVzWydwZXJmZWN0b01vYmlsZTpvcHRpb25zJ11bJ25hbWUnXTtcclxuICAgICAgICAgICAgZGVsZXRlIHdkaW9PcHRzLmNhcGFiaWxpdGllc1sncGVyZmVjdG9Nb2JpbGU6b3B0aW9ucyddO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHdkaW9PcHRzLmNhcGFiaWxpdGllc1snYnN0YWNrOm9wdGlvbnMnXSAmJiB3ZGlvT3B0cy5jYXBhYmlsaXRpZXNbJ2JzdGFjazpvcHRpb25zJ11bJ25hbWUnXSkge1xyXG4gICAgICAgICAgICBuYW1lID0gd2Rpb09wdHMuY2FwYWJpbGl0aWVzWydic3RhY2s6b3B0aW9ucyddWyduYW1lJ107XHJcbiAgICAgICAgICAgIGRlbGV0ZSB3ZGlvT3B0cy5jYXBhYmlsaXRpZXNbJ2JzdGFjazpvcHRpb25zJ107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLndkaW9PcHRzID0gd2Rpb09wdHM7XHJcblxyXG4gICAgICAgIC8vIGluaXQgd2ViZHJpdmVyXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdGhpcy5kcml2ZXIgPSBhd2FpdCB3ZGlvLnJlbW90ZSh3ZGlvT3B0cyk7XHJcbiAgICAgICAgICAgIHRoaXMuZHJpdmVyLnByb3ZpZGVyID0gcHJvdmlkZXI7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNlbGVuaXVtQnJvd3NlclRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJpdmVyLnNlbGVuaXVtQnJvd3NlclRpbWVvdXQgPSB0aGlzLm9wdGlvbnMuc2VsZW5pdW1Ccm93c2VyVGltZW91dDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zZWxlbml1bVRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJpdmVyLnNlbGVuaXVtVGltZW91dCA9IHRoaXMub3B0aW9ucy5zZWxlbml1bVRpbWVvdXQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChwcm92aWRlciA9PT0gbW9kVXRpbHMucHJvdmlkZXIuUEVSRkVDVE8pIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBlcmZlY3RvRXhlY3V0aW9uQ29udGV4dCA9IGF3YWl0IG5ldyBwZXJmZWN0b1JlcG9ydGluZy5QZXJmZWN0by5QZXJmZWN0b0V4ZWN1dGlvbkNvbnRleHQoe1xyXG4gICAgICAgICAgICAgICAgICAgIHdlYmRyaXZlcjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlU2NyaXB0OiBhc3luYyAoY29tbWFuZCwgcGFyYW1zKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5kcml2ZXIuZXhlY3V0ZShjb21tYW5kLCBwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlcG9ydGluZ0NsaWVudCA9IG5ldyBwZXJmZWN0b1JlcG9ydGluZy5QZXJmZWN0by5QZXJmZWN0b1JlcG9ydGluZ0NsaWVudChwZXJmZWN0b0V4ZWN1dGlvbkNvbnRleHQpO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXBvcnRpbmdDbGllbnQudGVzdFN0YXJ0KG5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBlcnJIZWxwZXIuZ2V0QXBwaXVtSW5pdEVycm9yKGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5hcHBDb250ZXh0ID0gYXdhaXQgdGhpcy5kcml2ZXIuZ2V0Q29udGV4dCgpO1xyXG5cclxuICAgICAgICAvLyBpZiB3ZSBhcmUgcnVubmluZyBvbiBBbmRyb2lkIDcrIGVtdWxhdG9yLCBhbmQgdGh1cy9vciB1c2luZyBhIFdlYlZpZXcgQnJvd3NlciBUZXN0ZXIgLVxyXG4gICAgICAgIC8vIHBlcmZvcm0gYW4gYWN0dWFsIGFwcENvbnRleHQgc3dpdGNoIHRvIFdFQlxyXG4gICAgICAgIC8vIHNvIEFwcGl1bSB3aWxsIGRlbGVnYXRlIGNvbW1hbmRzIHRvIENocm9tZSBEcml2ZXIgaW5zdGVhZCBvZiBBcHBpdW0gRHJpdmVyXHJcbiAgICAgICAgaWYgKHRoaXMuY2Fwcy5icm93c2VyTmFtZSA9PT0gICdjaHJvbWl1bS13ZWJ2aWV3Jykge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldFdlYlZpZXdDb250ZXh0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvdmlkZXIgPT09IG1vZFV0aWxzLnByb3ZpZGVyLkJST1dTRVJTVEFDSykge1xyXG4gICAgICAgICAgICAvLyBpZ25vcmVcclxuICAgICAgICAgICAgLy8gZmFpbHMgb24gYnJvd3NlcnN0YWNrXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5kcml2ZXIuc2V0VGltZW91dCh7ICdpbXBsaWNpdCc6IHRoaXMud2FpdEZvclRpbWVvdXQgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHN1cGVyLmluaXQodGhpcy5kcml2ZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGZ1bmN0aW9uIGRpc3Bvc2VcclxuICAgICAqIEBzdW1tYXJ5IEVuZHMgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nPX0gc3RhdHVzIC0gVGVzdCBzdGF0dXMsIGVpdGhlciBgcGFzc2VkYCBvciBgZmFpbGVkYC5cclxuICAgICAqL1xyXG4gICAgYXN5bmMgZGlzcG9zZShzdGF0dXMpIHtcclxuICAgICAgICBpZiAoIXN0YXR1cykge1xyXG4gICAgICAgICAgICBzdGF0dXMgPSAncGFzc2VkJztcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnJzLnN0ZXBzICYmIEFycmF5LmlzQXJyYXkodGhpcy5ycy5zdGVwcykgJiYgdGhpcy5ycy5zdGVwcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmYWlsZWRGaW5kZWQgPSB0aGlzLnJzLnN0ZXBzLmZpbmQoKGl0ZW0pID0+IGl0ZW0uc3RhdHVzID09PSAnZmFpbGVkJyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmFpbGVkRmluZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gJ2ZhaWxlZCc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmRyaXZlciAmJiB0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgICAgICAgc3RhdHVzID0gc3RhdHVzLnRvVXBwZXJDYXNlKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5kcml2ZXIucHJvdmlkZXIgPT09IG1vZFV0aWxzLnByb3ZpZGVyLlBFUkZFQ1RPKSB7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlcG9ydGluZ0NsaWVudC50ZXN0U3RvcCh7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPT09ICdQQVNTRUQnID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJmZWN0b1JlcG9ydGluZy5Db25zdGFudHMucmVzdWx0cy5wYXNzZWQgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmZlY3RvUmVwb3J0aW5nLkNvbnN0YW50cy5yZXN1bHRzLmZhaWxlZFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kcml2ZXIucHJvdmlkZXIgPT09IG1vZFV0aWxzLnByb3ZpZGVyLkJST1dTRVJTVEFDSykge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fc2VuZFJlc3VsdFN0YXR1c1RvQnJvd3NlcnN0YWNrKHN0YXR1cyk7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVNlc3Npb24oKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghWydDQU5DRUxFRCcsICdGQUlMRUQnXS5pbmNsdWRlcyhzdGF0dXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VsZW5pdW1TZXNzaW9uVGltZW91dCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVsZXRlU2Vzc2lvbiB3aWxsIHRha2UgNSBtaW4gdG8gY2FsbFxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZHJpdmVyLmRlbGV0ZVNlc3Npb24oKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oJ0Vycm9yIGRpc3Bvc2luZyBkcml2ZXI6ICcgKyBlKTsgICAgLy8gaWdub3JlIGFueSBlcnJvcnMgYXQgZGlzcG9zYWwgc3RhZ2VcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmRyaXZlciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMubGFzdE5hdmlnYXRpb25TdGFydFRpbWUgPSBudWxsO1xyXG4gICAgICAgICAgICBzdXBlci5kaXNwb3NlKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBzdW1tYXJ5IE9wZW5zIG5ldyB0cmFuc2FjdGlvbi5cclxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgdHJhbnNhY3Rpb24gd2lsbCBwZXJzaXN0IHRpbGwgYSBuZXcgb25lIGlzIG9wZW5lZC4gVHJhbnNhY3Rpb24gbmFtZXMgbXVzdCBiZVxyXG4gICAgICogICAgICAgICAgICAgIHVuaXF1ZS5cclxuICAgICAqIEBmdW5jdGlvbiB0cmFuc2FjdGlvblxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgdHJhbnNhY3Rpb24gbmFtZS5cclxuICAgICAqIEBmb3IgYW5kcm9pZCwgaW9zLCBoeWJyaWQsIHdlYlxyXG4gICAgICovXHJcbiAgICB0cmFuc2FjdGlvbihuYW1lKSB7XHJcbiAgICAgICAgZ2xvYmFsLl9sYXN0VHJhbnNhY3Rpb25OYW1lID0gbmFtZTtcclxuICAgIH1cclxuXHJcbiAgICAvKlxyXG4gICAgICogUHJpdmF0ZVxyXG4gICAgICovXHJcblxyXG4gICAgX2lzQWN0aW9uKG5hbWUpIHtcclxuICAgICAgICByZXR1cm4gQUNUSU9OX0NPTU1BTkRTLmluY2x1ZGVzKG5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIF90YWtlU2NyZWVuc2hvdFNpbGVudChuYW1lKSB7XHJcbiAgICAgICAgaWYgKCFOT19TQ1JFRU5TSE9UX0NPTU1BTkRTLmluY2x1ZGVzKG5hbWUpKSB7XHJcbiAgICAgICAgICAgIGxldCBlcnJvcjtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyaXZlciAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJpdmVyLnRha2VTY3JlZW5zaG90XHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmV0dmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJpdmVyLmNhbGwoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2FpdFVudGlsUmV0VmFsID0gdGhpcy5kcml2ZXIud2FpdFVudGlsKGFzeW5jKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbWFnZXMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHB1c2hJbWFnZVRvSW1hZ2VzID0gYXN5bmMoZmV0Y2hUaXRsZSA9IHRydWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGltYWdlID0gYXdhaXQgdGhpcy5kcml2ZXIudGFrZVNjcmVlbnNob3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmZXRjaFRpdGxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGl0bGUgPSBhd2FpdCB0aGlzLmRyaXZlci5nZXRUaXRsZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aXRsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0VG9JbWFnZSA9IHJlcXVpcmUoJ3RleHQtdG8taW1hZ2UnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRpdGxlSW1hZ2UgPSBhd2FpdCB0ZXh0VG9JbWFnZS5nZW5lcmF0ZSh0aXRsZSwgeyBkZWJ1ZzogZmFsc2UsIGZvbnRGYW1pbHk6ICdBcmlhbCcgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aXRsZUltYWdlICYmIHR5cGVvZiB0aXRsZUltYWdlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGVJbWFnZSA9IHRpdGxlSW1hZ2UucmVwbGFjZSgnZGF0YTppbWFnZS9wbmc7YmFzZTY0LCcsICcnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlcy5wdXNoKHRpdGxlSW1hZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlcy5wdXNoKGltYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzV2ViVmlld0NvbnRleHQgPSBhd2FpdCB0aGlzLmlzV2ViVmlld0NvbnRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzV2ViVmlld0NvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbGxlY3QgYWxsIChzY3JlZW5zaG90IGFuZCB0aXRsZSkgaW1hZ2VzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVzID0gYXdhaXQgdGhpcy5kcml2ZXIuZ2V0V2luZG93SGFuZGxlcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXMgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KGhhbmRsZXMpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcy5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGhhbmRsZSBvZiBoYW5kbGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZHJpdmVyLnN3aXRjaFRvV2luZG93KGhhbmRsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHB1c2hJbWFnZVRvSW1hZ2VzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcHVzaEltYWdlVG9JbWFnZXMoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXJnZSBhbGwgaW1hZ2VzIGludG8gb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lcmdlZEltYWdlID0gYXdhaXQgbWVyZ2VJbWFnZXMoaW1hZ2VzLCB7IGRpcmVjdGlvbjogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1lcmdlZEltYWdlICYmIHR5cGVvZiBtZXJnZWRJbWFnZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHZhbCA9IG1lcmdlZEltYWdlLnJlcGxhY2UoJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHRpbWVvdXQ6IDMwKjEwMDAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdhaXRVbnRpbFJldFZhbCAmJiB3YWl0VW50aWxSZXRWYWwudGhlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhaXRVbnRpbFJldFZhbC50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcignQ2Fubm90IGdldCBzY3JlZW5zaG90JywgZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ0Nhbm5vdCBnZXQgc2NyZWVuc2hvdCcsIGUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ0Nhbm5vdCBnZXQgc2NyZWVuc2hvdCBpbm5lciBlcnJvcicsIGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGlnbm9yZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIF9nZXRMb2dzKG5hbWUpIHtcclxuICAgIC8vICAgICBpZiAoIU5PX0xPR1NfQ09NTUFORFMuaW5jbHVkZXMobmFtZSkpIHtcclxuICAgIC8vICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9ncygpO1xyXG4gICAgLy8gICAgIH1cclxuICAgIC8vIH1cclxuXHJcbiAgICBfYWRqdXN0QXBwaXVtTG9nKGxvZywgc3JjKSB7XHJcbiAgICAgICAgaWYgKCFsb2cgfHwgdHlwZW9mIGxvZyAhPT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFRPRE86IGNvbnZlcnQgbG9nLnRpbWVzdGFtcCBmcm9tIHRoZSBkZXZpY2UgdGltZSB6b25lIHRvIHRoZSBsb2NhbCBvbmUgKHNvIHdlIGNhbiBsYXRlciBjb3JyZWxhdGUgYmV0d2VlbiBzdGVwcyBhbmQgbG9ncykgICAgICAgIFxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHRpbWU6IGxvZy50aW1lc3RhbXAsXHJcbiAgICAgICAgICAgIG1zZzogbG9nLm1lc3NhZ2UsXHJcbiAgICAgICAgICAgIGxldmVsOiBsb2cubGV2ZWwsXHJcbiAgICAgICAgICAgIHNyYzogc3JjXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBfaXRlcmF0aW9uU3RhcnQoKSB7XHJcbiAgICAgICAgLy8gY2xlYXIgdHJhbnNhY3Rpb24gbmFtZSBzYXZlZCBpbiBwcmV2aW91cyBpdGVyYXRpb24gaWYgYW55XHJcbiAgICAgICAgZ2xvYmFsLl9sYXN0VHJhbnNhY3Rpb25OYW1lID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBfaXRlcmF0aW9uRW5kKGVycm9yKSB7XHJcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLnR5cGUgPT09IGVycm9ySGVscGVyLmVycm9yQ29kZS5TRUxFTklVTV9TRVNTSU9OX1RJTUVPVVQpIHtcclxuICAgICAgICAgICAgdGhpcy5zZWxlbml1bVNlc3Npb25UaW1lb3V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZW5pdW1TZXNzaW9uVGltZW91dCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZ25vcmUgdGhlIHJlc3QgaWYgbW9iIG1vZHVsZSBpcyBub3QgaW5pdGlhbGl6ZWRcclxuICAgICAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbGxlY3QgYWxsIHRoZSBkZXZpY2UgbG9ncyBmb3IgdGhpcyBzZXNzaW9uXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb2xsZWN0RGV2aWNlTG9ncykge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9ncyA9IGF3YWl0IHRoaXMuZ2V0RGV2aWNlTG9ncygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxvZ3MgJiYgQXJyYXkuaXNBcnJheShsb2dzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGxvZyBvZiBsb2dzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnMubG9ncy5wdXNoKHRoaXMuX2FkanVzdEFwcGl1bUxvZyhsb2csICdkZXZpY2UnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpZ25vcmUgZXJyb3JzXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcignQ2Fubm90IHJldHJpZXZlIGRldmljZSBsb2dzLicsIGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBjb2xsZWN0IGFsbCB0aGUgYnJvd3NlciBsb2dzIGZvciB0aGlzIHNlc3Npb25cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNvbGxlY3RCcm93c2VyTG9ncykge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9ncyA9IGF3YWl0IHRoaXMuZ2V0QnJvd3NlckxvZ3MoKTtcclxuICAgICAgICAgICAgICAgIGlmIChsb2dzICYmIEFycmF5LmlzQXJyYXkobG9ncykpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBsb2cgb2YgbG9ncykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJzLmxvZ3MucHVzaCh0aGlzLl9hZGp1c3RBcHBpdW1Mb2cobG9nLCAnYnJvd3NlcicpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIC8vIGlnbm9yZSBlcnJvcnNcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCdDYW5ub3QgcmV0cmlldmUgYnJvd3NlciBsb2dzLicsIGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBjb2xsZWN0IGFsbCBBcHBpdW0gbG9ncyBmb3IgdGhpcyBzZXNzaW9uXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb2xsZWN0QXBwaXVtTG9ncykge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9ncyA9IHRoaXMuZ2V0QXBwaXVtTG9ncygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxvZ3MgJiYgQXJyYXkuaXNBcnJheShsb2dzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGxvZ0VudHJ5IG9mIGxvZ3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ycy5sb2dzLnB1c2godGhpcy5fYWRqdXN0QXBwaXVtTG9nKGxvZ0VudHJ5LCAnYXBwaXVtJykpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgLy8gaWdub3JlIGVycm9yc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ0Nhbm5vdCByZXRyaWV2ZSBBcHBpdW0gbG9ncy4nLCBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZ2V0V2Rpb0xvY2F0b3IobG9jYXRvcikge1xyXG4gICAgICAgIGlmICghbG9jYXRvcikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgJ0ludmFsaWQgYXJndW1lbnQgLSBsb2NhdG9yIG5vdCBzcGVjaWZpZWQnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHR5cGVvZiBsb2NhdG9yICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYXRvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxvY2F0b3IuaW5kZXhPZignLycpID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBsb2NhdG9yOyAvLyBsZWF2ZSB4cGF0aCBsb2NhdG9yIGFzIGlzXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBsYXRmb3JtID0gdGhpcy5jYXBzICYmIHRoaXMuY2Fwcy5wbGF0Zm9ybU5hbWUgPyB0aGlzLmNhcHMucGxhdGZvcm1OYW1lLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hcHBDb250ZXh0ID09PSAnTkFUSVZFX0FQUCcgJiYgcGxhdGZvcm0gPT09ICdhbmRyb2lkJykge1xyXG4gICAgICAgICAgICBpZiAobG9jYXRvci5pbmRleE9mKCdpZD0nKSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgLy8gcHJlcGVuZCBwYWNrYWdlIG5hbWUgaWYgaXQncyBub3Qgc3BlY2lmaWVkXHJcbiAgICAgICAgICAgICAgICAvLyBOT1RFOiBnZXRDdXJyZW50UGFja2FnZSgpIHNlZW1zIHRvIGNyYXNoIHBvc3NpYmx5IGR1ZSB0byBhIHdkaW8gYnVnLiBcclxuICAgICAgICAgICAgICAgIC8vICAgICAgIHNvIHdlIGdldCBwYWNrYWdlIG5hbWUgZnJvbSBjYXBzIGluc3RlYWQuXHJcbiAgICAgICAgICAgICAgICBsb2NhdG9yID0gbG9jYXRvci5zdWJzdHIoJ2lkPScubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGlmIChsb2NhdG9yLmluZGV4T2YoJzppZC8nKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2NhdG9yID0gdGhpcy5jYXBzLmFwcFBhY2thZ2UgKyAnOmlkLycgKyBsb2NhdG9yO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdhbmRyb2lkPW5ldyBVaVNlbGVjdG9yKCkucmVzb3VyY2VJZChcIicgKyBsb2NhdG9yICsgJ1wiKSc7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobG9jYXRvci5pbmRleE9mKCdjbGFzcz0nKSA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiAnYW5kcm9pZD1uZXcgVWlTZWxlY3RvcigpLmNsYXNzTmFtZShcIicgKyBsb2NhdG9yLnN1YnN0cignY2xhc3M9Jy5sZW5ndGgpICsgJ1wiKSc7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxvY2F0b3IuaW5kZXhPZigndGV4dD0nKSA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiAnYW5kcm9pZD1uZXcgVWlTZWxlY3RvcigpLnRleHQoXCInICsgbG9jYXRvci5zdWJzdHIoJ3RleHQ9Jy5sZW5ndGgpICsgJ1wiKSc7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxvY2F0b3IuaW5kZXhPZigndGV4dC1jb250YWlucz0nKSA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiAnYW5kcm9pZD1uZXcgVWlTZWxlY3RvcigpLnRleHRDb250YWlucyhcIicgKyBsb2NhdG9yLnN1YnN0cigndGV4dC1jb250YWlucz0nLmxlbmd0aCkgKyAnXCIpJztcclxuICAgICAgICAgICAgZWxzZSBpZiAobG9jYXRvci5pbmRleE9mKCdkZXNjPScpID09PSAwKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdhbmRyb2lkPW5ldyBVaVNlbGVjdG9yKCkuZGVzY3JpcHRpb24oXCInICsgbG9jYXRvci5zdWJzdHIoJ2Rlc2M9Jy5sZW5ndGgpICsgJ1wiKSc7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxvY2F0b3IuaW5kZXhPZignZGVzYy1jb250YWlucz0nKSA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiAnYW5kcm9pZD1uZXcgVWlTZWxlY3RvcigpLmRlc2NyaXB0aW9uQ29udGFpbnMoXCInICsgbG9jYXRvci5zdWJzdHIoJ2Rlc2MtY29udGFpbnM9Jy5sZW5ndGgpICsgJ1wiKSc7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxvY2F0b3IuaW5kZXhPZignc2Nyb2xsYWJsZScpID09PSAwKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdhbmRyb2lkPW5ldyBVaVNlbGVjdG9yKCkuc2Nyb2xsYWJsZSh0cnVlKSc7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxvY2F0b3IuaW5kZXhPZignficpID09PSAwKSAgICAvLyBhY2Nlc3NpYmlsaXR5IGlkXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9jYXRvcjtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXBwQ29udGV4dCA9PT0gJ05BVElWRV9BUFAnICYmIHBsYXRmb3JtID09PSAnaW9zJykge1xyXG4gICAgICAgICAgICBpZiAobG9jYXRvci5pbmRleE9mKCd+JykgPT09IDApIC8vIGFjY2Vzc2liaWxpdHkgaWRcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdG9yO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcHBDb250ZXh0ICE9PSAnTkFUSVZFX0FQUCcpIHsgICAgICAgICAgICAvLyBIeWJyaWQgb3IgV2ViIGFwcGxpY2F0aW9uXHJcbiAgICAgICAgICAgIGlmIChsb2NhdG9yLmluZGV4T2YoJ2lkPScpID09PSAwKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICcjJyArIGxvY2F0b3Iuc3Vic3RyKCdpZD0nLmxlbmd0aCk7ICAgICAgLy8gY29udmVydCAnaWQ9JyB0byAnIydcclxuICAgICAgICAgICAgZWxzZSBpZiAobG9jYXRvci5pbmRleE9mKCduYW1lPScpID09PSAwKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdbbmFtZT0nICsgbG9jYXRvci5zdWJzdHIoJ25hbWU9Jy5sZW5ndGgpICsgJ10nO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChsb2NhdG9yLmluZGV4T2YoJ2xpbms9JykgPT09IDApXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJz0nICsgbG9jYXRvci5zdWJzdHIoJ2xpbms9Jy5sZW5ndGgpO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChsb2NhdG9yLmluZGV4T2YoJ2xpbmstY29udGFpbnM9JykgPT09IDApXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJyo9JyArIGxvY2F0b3Iuc3Vic3RyKCdsaW5rPScubGVuZ3RoKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAobG9jYXRvci5pbmRleE9mKCdjc3M9JykgPT09IDApXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9jYXRvci5zdWJzdHIoJ2Nzcz0nLmxlbmd0aCk7ICAgICAgICAgICAvLyBpbiBjYXNlIG9mIGNzcywganVzdCByZW1vdmUgY3NzPSBwcmVmaXhcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBsb2NhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkSGVscGVyRnVuY3Rpb25zKCkge1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5nZXRXZGlvTG9jYXRvciA9IHRoaXMuX2dldFdkaW9Mb2NhdG9yO1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5tYXRjaFBhdHRlcm4gPSBtb2RVdGlscy5tYXRjaFBhdHRlcm47XHJcbiAgICAgICAgdGhpcy5oZWxwZXJzLmdldEVsZW1lbnQgPSBtb2RVdGlscy5nZXRFbGVtZW50O1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5nZXRFbGVtZW50cyA9IG1vZFV0aWxzLmdldEVsZW1lbnRzO1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5nZXRDaGlsZEVsZW1lbnQgPSBtb2RVdGlscy5nZXRDaGlsZEVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5oZWxwZXJzLmdldENoaWxkRWxlbWVudHMgPSBtb2RVdGlscy5nZXRDaGlsZEVsZW1lbnRzO1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5zZXRUaW1lb3V0SW1wbGljaXQgPSBtb2RVdGlscy5zZXRUaW1lb3V0SW1wbGljaXQ7XHJcbiAgICAgICAgdGhpcy5oZWxwZXJzLnJlc3RvcmVUaW1lb3V0SW1wbGljaXQgPSBtb2RVdGlscy5yZXN0b3JlVGltZW91dEltcGxpY2l0O1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5hc3NlcnRBcmd1bWVudCA9IG1vZFV0aWxzLmFzc2VydEFyZ3VtZW50O1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5hc3NlcnRBcmd1bWVudE5vbkVtcHR5U3RyaW5nID0gbW9kVXRpbHMuYXNzZXJ0QXJndW1lbnROb25FbXB0eVN0cmluZztcclxuICAgICAgICB0aGlzLmhlbHBlcnMuYXNzZXJ0QXJndW1lbnROdW1iZXIgPSBtb2RVdGlscy5hc3NlcnRBcmd1bWVudE51bWJlcjtcclxuICAgICAgICB0aGlzLmhlbHBlcnMuYXNzZXJ0QXJndW1lbnROdW1iZXJOb25OZWdhdGl2ZSA9IG1vZFV0aWxzLmFzc2VydEFyZ3VtZW50TnVtYmVyTm9uTmVnYXRpdmU7XHJcbiAgICAgICAgdGhpcy5oZWxwZXJzLmFzc2VydEFyZ3VtZW50Qm9vbCA9IG1vZFV0aWxzLmFzc2VydEFyZ3VtZW50Qm9vbDtcclxuICAgICAgICB0aGlzLmhlbHBlcnMuYXNzZXJ0QXJndW1lbnRCb29sT3B0aW9uYWwgPSBtb2RVdGlscy5hc3NlcnRBcmd1bWVudEJvb2xPcHRpb25hbDtcclxuICAgICAgICB0aGlzLmhlbHBlcnMuYXNzZXJ0QXJndW1lbnRUaW1lb3V0ID0gbW9kVXRpbHMuYXNzZXJ0QXJndW1lbnRUaW1lb3V0O1xyXG4gICAgICAgIHRoaXMuaGVscGVycy5hc3NlcnRDb250ZXh0ID0gbW9kVXRpbHMuYXNzZXJ0Q29udGV4dDtcclxuICAgICAgICB0aGlzLmhlbHBlcnMuY29udGV4dExpc3QgPSBtb2RVdGlscy5jb250ZXh0TGlzdDtcclxuICAgICAgICB0aGlzLmhlbHBlcnMuZ2V0TG9nVHlwZXMgPSBtb2RVdGlscy5nZXRMb2dUeXBlcztcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBkZWxldGVTZXNzaW9uKCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmRyaXZlciAmJiB0aGlzLmRyaXZlci5kZWxldGVTZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmRyaXZlci5kZWxldGVTZXNzaW9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCdkZWxldGVTZXNzaW9uIGVycm9yJywgZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIF9zZW5kUmVzdWx0U3RhdHVzVG9Ccm93c2Vyc3RhY2soc3RhdHVzKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcmVxdWVzdEJvZHkgPSB7XHJcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cyA9PT0gJ1BBU1NFRCcgPyAncGFzc2VkJyA6ICdmYWlsZWQnXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBsZXQgb3B0aW9ucztcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLndkaW9PcHRzLmNhcGFiaWxpdGllcy5icm93c2VyTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IGBodHRwczovL2FwaS5icm93c2Vyc3RhY2suY29tL2F1dG9tYXRlL3Nlc3Npb25zLyR7dGhpcy5kcml2ZXIuc2Vzc2lvbklkfS5qc29uYCxcclxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQVVQnLFxyXG4gICAgICAgICAgICAgICAgICAgIGpzb246IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0VW5hdXRob3JpemVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiByZXF1ZXN0Qm9keSxcclxuICAgICAgICAgICAgICAgICAgICAnYXV0aCc6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3VzZXInOiB0aGlzLndkaW9PcHRzLnVzZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdwYXNzJzogdGhpcy53ZGlvT3B0cy5rZXksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdzZW5kSW1tZWRpYXRlbHknOiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IGBodHRwczovL2FwaS1jbG91ZC5icm93c2Vyc3RhY2suY29tL2FwcC1hdXRvbWF0ZS9zZXNzaW9ucy8ke3RoaXMuZHJpdmVyLnNlc3Npb25JZH0uanNvbmAsXHJcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnUFVUJyxcclxuICAgICAgICAgICAgICAgICAgICBqc29uOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdFVuYXV0aG9yaXplZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgYm9keTogcmVxdWVzdEJvZHksXHJcbiAgICAgICAgICAgICAgICAgICAgJ2F1dGgnOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2VyJzogdGhpcy53ZGlvT3B0cy5jYXBhYmlsaXRpZXNbJ2Jyb3dzZXJzdGFjay51c2VyJ10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdwYXNzJzogdGhpcy53ZGlvT3B0cy5jYXBhYmlsaXRpZXNbJ2Jyb3dzZXJzdGFjay5rZXknXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbmRJbW1lZGlhdGVseSc6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0KG9wdGlvbnMsIChlcnIsIHJlcywgYm9keSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcignVW5hYmxlIHRvIHNlbmQgcmVzdWx0IHN0YXR1cyB0byBCcm93c2Vyc3RhY2s6ICcgKyBlLnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIl19
|