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,328 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
require("source-map-support/register");
|
|
4
|
-
|
|
5
|
-
var _OxygenError = _interopRequireDefault(require("../errors/OxygenError"));
|
|
6
|
-
|
|
7
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
|
-
|
|
9
|
-
/*
|
|
10
|
-
* Copyright (C) 2019-present CloudBeat Limited
|
|
11
|
-
*
|
|
12
|
-
* This program is free software: you can redistribute it and/or modify
|
|
13
|
-
* it under the terms of the GNU General Public License as published by
|
|
14
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
15
|
-
* (at your option) any later version.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @name pdf
|
|
20
|
-
* @description Provides generic methods for working with PDF files.
|
|
21
|
-
*/
|
|
22
|
-
const errHelper = require('../errors/helper');
|
|
23
|
-
|
|
24
|
-
const path = require('path');
|
|
25
|
-
|
|
26
|
-
var PDFParser = require('pdf2json/pdfparser');
|
|
27
|
-
|
|
28
|
-
function countRows(searchStr, rows, reverse) {
|
|
29
|
-
let result = 0;
|
|
30
|
-
var strRegex = new RegExp(searchStr, 'g');
|
|
31
|
-
var reverseStrRegex = reverse ? new RegExp(searchStr.split('').reverse().join(''), 'g') : null;
|
|
32
|
-
Object.keys(rows) // => array of y-positions (type: float)
|
|
33
|
-
.sort((y1, y2) => parseFloat(y1) - parseFloat(y2)) // sort float positions
|
|
34
|
-
.some(y => {
|
|
35
|
-
var line = (rows[y] || []).join('').replace(/\s/g, '');
|
|
36
|
-
var count = (line.match(strRegex) || []).length;
|
|
37
|
-
|
|
38
|
-
if (count === 0 && reverseStrRegex) {
|
|
39
|
-
count = (line.match(reverseStrRegex) || []).length;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
result += count;
|
|
43
|
-
});
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function checkRows(searchStr, rows, reverse) {
|
|
48
|
-
let result = false;
|
|
49
|
-
Object.keys(rows) // => array of y-positions (type: float)
|
|
50
|
-
.sort((y1, y2) => parseFloat(y1) - parseFloat(y2)) // sort float positions
|
|
51
|
-
.some(y => {
|
|
52
|
-
var line = (rows[y] || []).join('').replace(/\s/g, '');
|
|
53
|
-
let inludes;
|
|
54
|
-
|
|
55
|
-
if (reverse) {
|
|
56
|
-
const reverseSearchStr = searchStr.split('').reverse().join('');
|
|
57
|
-
inludes = line.includes(searchStr) || line.includes(reverseSearchStr);
|
|
58
|
-
} else {
|
|
59
|
-
inludes = line.includes(searchStr);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (inludes) {
|
|
63
|
-
result = true;
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function assertion(pdfFilePath, text, pageNum = 0, reverse = false) {
|
|
71
|
-
let rows = {}; // indexed by y-position
|
|
72
|
-
|
|
73
|
-
return new Promise(function (resolve, reject) {
|
|
74
|
-
const searchStr = text.replace(/\s/g, '');
|
|
75
|
-
let pdfParser = new PDFParser();
|
|
76
|
-
pdfParser.on('pdfParser_dataError', function (err) {
|
|
77
|
-
let errorMessage = err.parserError ? err.parserError : 'Error parsing the PDF.';
|
|
78
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, errorMessage);
|
|
79
|
-
});
|
|
80
|
-
pdfParser.on('pdfParser_dataReady', function (pdfData) {
|
|
81
|
-
var totalPages = pdfData.formImage.Pages.length;
|
|
82
|
-
|
|
83
|
-
if (pageNum && totalPages < pageNum - 1) {
|
|
84
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, `Invalid argument - 'pageNum' is ${pageNum}, but PDF contains only ${totalPages} pages`);
|
|
85
|
-
} // locate on a specific page
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (pageNum) {
|
|
89
|
-
processText(rows, pdfData.formImage.Pages[pageNum - 1].Texts);
|
|
90
|
-
let isFound = checkRows(searchStr, rows, reverse);
|
|
91
|
-
resolve(!!isFound);
|
|
92
|
-
return;
|
|
93
|
-
} // locate on any page
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for (let p in pdfData.formImage.Pages) {
|
|
97
|
-
processText(rows, pdfData.formImage.Pages[p].Texts);
|
|
98
|
-
let isFound = checkRows(searchStr, rows, reverse);
|
|
99
|
-
|
|
100
|
-
if (isFound) {
|
|
101
|
-
resolve(true);
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
rows = {}; // clear rows for next page
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
resolve(false);
|
|
109
|
-
});
|
|
110
|
-
pdfParser.loadPDF(pdfFilePath, 0);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function processText(rows, texts) {
|
|
115
|
-
for (var t in texts) {
|
|
116
|
-
var item = texts[t];
|
|
117
|
-
var text = decodeURIComponent(item.R[0].T); // accumulate text items into rows object, per line
|
|
118
|
-
|
|
119
|
-
(rows[item.y] = rows[item.y] || []).push(text);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function count(pdfFilePath, text, pageNum = 0, reverse = false) {
|
|
124
|
-
let rows = {}; // indexed by y-position
|
|
125
|
-
|
|
126
|
-
let totalCount = 0;
|
|
127
|
-
return new Promise(function (resolve, reject) {
|
|
128
|
-
const searchStr = text.replace(/\s/g, '');
|
|
129
|
-
let pdfParser = new PDFParser();
|
|
130
|
-
pdfParser.on('pdfParser_dataError', function (err) {
|
|
131
|
-
let errorMessage = err.parserError ? err.parserError : 'Error parsing the PDF.';
|
|
132
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, errorMessage);
|
|
133
|
-
});
|
|
134
|
-
pdfParser.on('pdfParser_dataReady', function (pdfData) {
|
|
135
|
-
let totalPages = pdfData.formImage.Pages.length;
|
|
136
|
-
|
|
137
|
-
if (pageNum && totalPages < pageNum - 1) {
|
|
138
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, `Invalid argument - 'pageNum' is ${pageNum}, but PDF contains only ${totalPages} pages`);
|
|
139
|
-
} // count on a specific page
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (pageNum) {
|
|
143
|
-
processText(rows, pdfData.formImage.Pages[pageNum - 1].Texts);
|
|
144
|
-
let count = countRows(searchStr, rows, reverse);
|
|
145
|
-
resolve(count);
|
|
146
|
-
return;
|
|
147
|
-
} // count on all pages
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
for (var p in pdfData.formImage.Pages) {
|
|
151
|
-
processText(rows, pdfData.formImage.Pages[p].Texts);
|
|
152
|
-
let count = countRows(searchStr, rows, reverse);
|
|
153
|
-
|
|
154
|
-
if (count > 0) {
|
|
155
|
-
totalCount += count;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
rows = {}; // clear rows for next page
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
resolve(totalCount);
|
|
162
|
-
});
|
|
163
|
-
pdfParser.loadPDF(pdfFilePath, 0);
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function validateString(arg, name) {
|
|
168
|
-
if (arg && typeof arg === 'string' && arg.trim().length > 0) {// text is correct
|
|
169
|
-
} else {
|
|
170
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-empty string.");
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function validatePageNum(arg, name) {
|
|
175
|
-
if (arg === null || arg && typeof arg === 'number' && arg > 0) {// pageNum is correct
|
|
176
|
-
} else {
|
|
177
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-negative number.");
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function validateMessage(arg, name) {
|
|
182
|
-
if (arg === null || arg && typeof arg === 'string' && arg.trim().length > 0) {// pageNum is correct
|
|
183
|
-
} else {
|
|
184
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-empty string.");
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function validateReverse(arg, name) {
|
|
189
|
-
if (arg === null || typeof arg !== 'undefined' && typeof arg === 'boolean') {// pageNum is correct
|
|
190
|
-
} else {
|
|
191
|
-
throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a boolean");
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function resolvePath(pdfFilePath, options) {
|
|
196
|
-
pdfFilePath = pdfFilePath.trim().split('').map((item, idx) => {
|
|
197
|
-
return ![8206, 8296].includes(pdfFilePath.charCodeAt(idx)) ? item : null;
|
|
198
|
-
}).join('');
|
|
199
|
-
|
|
200
|
-
if (pdfFilePath[0] === '~') {
|
|
201
|
-
// resolve path relative to home directory
|
|
202
|
-
return path.join(process.env.HOME, pdfFilePath.slice(1));
|
|
203
|
-
} else {
|
|
204
|
-
let cwd = process.cwd();
|
|
205
|
-
|
|
206
|
-
if (options && options.cwd) {
|
|
207
|
-
cwd = options.cwd;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (options && options.rootPath) {
|
|
211
|
-
cwd = options.rootPath;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
cwd = cwd.trim();
|
|
215
|
-
return path.resolve(cwd, pdfFilePath);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
module.exports = function (options, context, rs, logger, modules, services) {
|
|
220
|
-
module.isInitialized = function () {
|
|
221
|
-
return true;
|
|
222
|
-
};
|
|
223
|
-
/**
|
|
224
|
-
* @summary Asserts that text is present in a PDF file
|
|
225
|
-
* @function assert
|
|
226
|
-
* @param {String} pdfFilePath - Relative or absolute path to the PDF file.
|
|
227
|
-
* @param {String} text - Text to assert.
|
|
228
|
-
* @param {Number=} pageNum - Page number.
|
|
229
|
-
* @param {String=} message - Message to throw if assertion fails.
|
|
230
|
-
* @param {Boolean=} reverse - Check also reverse variant of string.
|
|
231
|
-
*/
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
module.assert = async function (pdfFilePath, text, pageNum = null, message = null, reverse = false) {
|
|
235
|
-
validateString(pdfFilePath, 'pdfFilePath');
|
|
236
|
-
validateString(text, 'text');
|
|
237
|
-
validatePageNum(pageNum, 'pageNum');
|
|
238
|
-
validateMessage(message, 'message');
|
|
239
|
-
validateReverse(reverse, 'reverse');
|
|
240
|
-
pdfFilePath = resolvePath(pdfFilePath, options);
|
|
241
|
-
let error;
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
const ret = await assertion(pdfFilePath, text, pageNum, reverse);
|
|
245
|
-
|
|
246
|
-
if (!ret) {
|
|
247
|
-
if (message) {
|
|
248
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, message);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
let msg = `"${text}" is not found in the PDF ${pageNum ? 'on page ' + pageNum : ''}`;
|
|
252
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, msg);
|
|
253
|
-
}
|
|
254
|
-
} catch (e) {
|
|
255
|
-
error = new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, e.message);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (error) {
|
|
259
|
-
throw error;
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
/**
|
|
263
|
-
* @summary Asserts that text is not present in a PDF file
|
|
264
|
-
* @function assertNot
|
|
265
|
-
* @param {String} pdfFilePath - Relative or absolute path to the pdf file.
|
|
266
|
-
* @param {String} text - Text to assert.
|
|
267
|
-
* @param {Number=} pageNum - Page number.
|
|
268
|
-
* @param {String=} message - Message to throw if assertion fails.
|
|
269
|
-
* @param {Boolean=} reverse - Check also reverse variant of string.
|
|
270
|
-
*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
module.assertNot = async function (pdfFilePath, text, pageNum = null, message = null, reverse = false) {
|
|
274
|
-
validateString(pdfFilePath, 'pdfFilePath');
|
|
275
|
-
validateString(text, 'text');
|
|
276
|
-
validatePageNum(pageNum, 'pageNum');
|
|
277
|
-
validateMessage(message, 'message');
|
|
278
|
-
validateReverse(reverse, 'reverse');
|
|
279
|
-
pdfFilePath = resolvePath(pdfFilePath, options);
|
|
280
|
-
let error;
|
|
281
|
-
|
|
282
|
-
try {
|
|
283
|
-
const ret = await assertion(pdfFilePath, text, pageNum, reverse);
|
|
284
|
-
|
|
285
|
-
if (ret) {
|
|
286
|
-
if (message) {
|
|
287
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, message);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
let msg = `"${text}" is found in the PDF ${pageNum ? 'on page ' + pageNum : ''}`;
|
|
291
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, msg);
|
|
292
|
-
}
|
|
293
|
-
} catch (e) {
|
|
294
|
-
throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, e.message);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (error) {
|
|
298
|
-
throw error;
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* @summary Count the number of times specified text is present in a PDF file.
|
|
303
|
-
* @function count
|
|
304
|
-
* @param {String} pdfFilePath - Relative or absolute path to the pdf file.
|
|
305
|
-
* @param {String} text - Text to count.
|
|
306
|
-
* @param {Number=} pageNum - Page number.
|
|
307
|
-
* @param {Boolean=} reverse - Check also reverse variant of string.
|
|
308
|
-
* @return {Number} Number of times the specified text was found.
|
|
309
|
-
*/
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
module.count = async function (pdfFilePath, text, pageNum = null, reverse = false) {
|
|
313
|
-
validateString(pdfFilePath, 'pdfFilePath');
|
|
314
|
-
validateString(text, 'text');
|
|
315
|
-
validatePageNum(pageNum, 'pageNum');
|
|
316
|
-
validateReverse(reverse, 'reverse');
|
|
317
|
-
pdfFilePath = resolvePath(pdfFilePath, options);
|
|
318
|
-
|
|
319
|
-
try {
|
|
320
|
-
return await count(pdfFilePath, text, pageNum, reverse);
|
|
321
|
-
} catch (e) {
|
|
322
|
-
throw new _OxygenError.default(errHelper.errorCode.PDF_ERROR, e.message || e);
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
return module;
|
|
327
|
-
};
|
|
328
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9veF9tb2R1bGVzL21vZHVsZS1wZGYuanMiXSwibmFtZXMiOlsiZXJySGVscGVyIiwicmVxdWlyZSIsInBhdGgiLCJQREZQYXJzZXIiLCJjb3VudFJvd3MiLCJzZWFyY2hTdHIiLCJyb3dzIiwicmV2ZXJzZSIsInJlc3VsdCIsInN0clJlZ2V4IiwiUmVnRXhwIiwicmV2ZXJzZVN0clJlZ2V4Iiwic3BsaXQiLCJqb2luIiwiT2JqZWN0Iiwia2V5cyIsInNvcnQiLCJ5MSIsInkyIiwicGFyc2VGbG9hdCIsInNvbWUiLCJ5IiwibGluZSIsInJlcGxhY2UiLCJjb3VudCIsIm1hdGNoIiwibGVuZ3RoIiwiY2hlY2tSb3dzIiwiaW5sdWRlcyIsInJldmVyc2VTZWFyY2hTdHIiLCJpbmNsdWRlcyIsImFzc2VydGlvbiIsInBkZkZpbGVQYXRoIiwidGV4dCIsInBhZ2VOdW0iLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInBkZlBhcnNlciIsIm9uIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicGFyc2VyRXJyb3IiLCJPeEVycm9yIiwiZXJyb3JDb2RlIiwiQVNTRVJUX0VSUk9SIiwicGRmRGF0YSIsInRvdGFsUGFnZXMiLCJmb3JtSW1hZ2UiLCJQYWdlcyIsIlNDUklQVF9FUlJPUiIsInByb2Nlc3NUZXh0IiwiVGV4dHMiLCJpc0ZvdW5kIiwicCIsImxvYWRQREYiLCJ0ZXh0cyIsInQiLCJpdGVtIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiUiIsIlQiLCJwdXNoIiwidG90YWxDb3VudCIsInZhbGlkYXRlU3RyaW5nIiwiYXJnIiwibmFtZSIsInRyaW0iLCJ2YWxpZGF0ZVBhZ2VOdW0iLCJ2YWxpZGF0ZU1lc3NhZ2UiLCJ2YWxpZGF0ZVJldmVyc2UiLCJyZXNvbHZlUGF0aCIsIm9wdGlvbnMiLCJtYXAiLCJpZHgiLCJjaGFyQ29kZUF0IiwicHJvY2VzcyIsImVudiIsIkhPTUUiLCJzbGljZSIsImN3ZCIsInJvb3RQYXRoIiwibW9kdWxlIiwiZXhwb3J0cyIsImNvbnRleHQiLCJycyIsImxvZ2dlciIsIm1vZHVsZXMiLCJzZXJ2aWNlcyIsImlzSW5pdGlhbGl6ZWQiLCJhc3NlcnQiLCJtZXNzYWdlIiwiZXJyb3IiLCJyZXQiLCJtc2ciLCJlIiwiYXNzZXJ0Tm90IiwiUERGX0VSUk9SIl0sIm1hcHBpbmdzIjoiOzs7O0FBY0E7Ozs7QUFkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBR0EsTUFBTUEsU0FBUyxHQUFHQyxPQUFPLENBQUMsa0JBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxJQUFJRSxTQUFTLEdBQUdGLE9BQU8sQ0FBQyxvQkFBRCxDQUF2Qjs7QUFFQSxTQUFTRyxTQUFULENBQW1CQyxTQUFuQixFQUE4QkMsSUFBOUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQ3pDLE1BQUlDLE1BQU0sR0FBRyxDQUFiO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLElBQUlDLE1BQUosQ0FBV0wsU0FBWCxFQUFzQixHQUF0QixDQUFmO0FBQ0EsTUFBSU0sZUFBZSxHQUFHSixPQUFPLEdBQUcsSUFBSUcsTUFBSixDQUFXTCxTQUFTLENBQUNPLEtBQVYsQ0FBZ0IsRUFBaEIsRUFBb0JMLE9BQXBCLEdBQThCTSxJQUE5QixDQUFtQyxFQUFuQyxDQUFYLEVBQW1ELEdBQW5ELENBQUgsR0FBNkQsSUFBMUY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlULElBQVosRUFBa0I7QUFBbEIsR0FDS1UsSUFETCxDQUNVLENBQUNDLEVBQUQsRUFBS0MsRUFBTCxLQUFZQyxVQUFVLENBQUNGLEVBQUQsQ0FBVixHQUFpQkUsVUFBVSxDQUFDRCxFQUFELENBRGpELEVBQ3VEO0FBRHZELEdBRUtFLElBRkwsQ0FFVUMsQ0FBQyxJQUFJO0FBQ1AsUUFBSUMsSUFBSSxHQUFHLENBQUNoQixJQUFJLENBQUNlLENBQUQsQ0FBSixJQUFXLEVBQVosRUFBZ0JS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QUEsTUFBTSxDQUFDMUQsS0FBUCxHQUFlLGdCQUFlUSxXQUFmLEVBQTRCQyxJQUE1QixFQUFrQ0MsT0FBTyxHQUFHLElBQTVDLEVBQWtEM0IsT0FBTyxHQUFHLEtBQTVELEVBQW1FO0FBQzlFeUQsSUFBQUEsY0FBYyxDQUFDaEMsV0FBRCxFQUFjLGFBQWQsQ0FBZDtBQUNBZ0MsSUFBQUEsY0FBYyxDQUFDL0IsSUFBRCxFQUFPLE1BQVAsQ0FBZDtBQUNBbUMsSUFBQUEsZUFBZSxDQUFDbEMsT0FBRCxFQUFVLFNBQVYsQ0FBZjtBQUNBb0MsSUFBQUEsZUFBZSxDQUFDL0QsT0FBRCxFQUFVLFNBQVYsQ0FBZjtBQUVBeUIsSUFBQUEsV0FBVyxHQUFHdUMsV0FBVyxDQUFDdkMsV0FBRCxFQUFjd0MsT0FBZCxDQUF6Qjs7QUFFQSxRQUFJO0FBQ0EsYUFBTyxNQUFNaEQsS0FBSyxDQUFDUSxXQUFELEVBQWNDLElBQWQsRUFBb0JDLE9BQXBCLEVBQTZCM0IsT0FBN0IsQ0FBbEI7QUFDSCxLQUZELENBR0EsT0FBT3dGLENBQVAsRUFBVTtBQUNOLFlBQU0sSUFBSXBELG9CQUFKLENBQVkzQyxTQUFTLENBQUM0QyxTQUFWLENBQW9CcUQsU0FBaEMsRUFBMkNGLENBQUMsQ0FBQ0osT0FBRixJQUFhSSxDQUF4RCxDQUFOO0FBQ0g7QUFDSixHQWREOztBQWdCQSxTQUFPYixNQUFQO0FBQ0gsQ0FqSEQiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTktcHJlc2VudCBDbG91ZEJlYXQgTGltaXRlZFxyXG4gKlxyXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxyXG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxyXG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxyXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBAbmFtZSBwZGZcclxuICogQGRlc2NyaXB0aW9uIFByb3ZpZGVzIGdlbmVyaWMgbWV0aG9kcyBmb3Igd29ya2luZyB3aXRoIFBERiBmaWxlcy5cclxuICovXHJcblxyXG5pbXBvcnQgT3hFcnJvciBmcm9tICcuLi9lcnJvcnMvT3h5Z2VuRXJyb3InO1xyXG5jb25zdCBlcnJIZWxwZXIgPSByZXF1aXJlKCcuLi9lcnJvcnMvaGVscGVyJyk7XHJcbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XHJcbnZhciBQREZQYXJzZXIgPSByZXF1aXJlKCdwZGYyanNvbi9wZGZwYXJzZXInKTtcclxuXHJcbmZ1bmN0aW9uIGNvdW50Um93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpIHtcclxuICAgIGxldCByZXN1bHQgPSAwO1xyXG4gICAgdmFyIHN0clJlZ2V4ID0gbmV3IFJlZ0V4cChzZWFyY2hTdHIsICdnJyk7XHJcbiAgICB2YXIgcmV2ZXJzZVN0clJlZ2V4ID0gcmV2ZXJzZSA/IG5ldyBSZWdFeHAoc2VhcmNoU3RyLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyksICdnJykgOiBudWxsO1xyXG5cclxuICAgIE9iamVjdC5rZXlzKHJvd3MpIC8vID0+IGFycmF5IG9mIHktcG9zaXRpb25zICh0eXBlOiBmbG9hdClcclxuICAgICAgICAuc29ydCgoeTEsIHkyKSA9PiBwYXJzZUZsb2F0KHkxKSAtIHBhcnNlRmxvYXQoeTIpKSAvLyBzb3J0IGZsb2F0IHBvc2l0aW9uc1xyXG4gICAgICAgIC5zb21lKHkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgbGluZSA9IChyb3dzW3ldIHx8IFtdKS5qb2luKCcnKS5yZXBsYWNlKC9cXHMvZywgJycpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGNvdW50ID0gKGxpbmUubWF0Y2goc3RyUmVnZXgpIHx8IFtdKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCAmJiByZXZlcnNlU3RyUmVnZXgpIHtcclxuICAgICAgICAgICAgICAgIGNvdW50ID0gKGxpbmUubWF0Y2gocmV2ZXJzZVN0clJlZ2V4KSB8fCBbXSkubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc3VsdCArPSBjb3VudDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjaGVja1Jvd3Moc2VhcmNoU3RyLCByb3dzLCByZXZlcnNlKSB7XHJcbiAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XHJcblxyXG4gICAgT2JqZWN0LmtleXMocm93cykgLy8gPT4gYXJyYXkgb2YgeS1wb3NpdGlvbnMgKHR5cGU6IGZsb2F0KVxyXG4gICAgICAgIC5zb3J0KCh5MSwgeTIpID0+IHBhcnNlRmxvYXQoeTEpIC0gcGFyc2VGbG9hdCh5MikpIC8vIHNvcnQgZmxvYXQgcG9zaXRpb25zXHJcbiAgICAgICAgLnNvbWUoeSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGluZSA9IChyb3dzW3ldIHx8IFtdKS5qb2luKCcnKS5yZXBsYWNlKC9cXHMvZywgJycpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGlubHVkZXM7XHJcblxyXG4gICAgICAgICAgICBpZiAocmV2ZXJzZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmV2ZXJzZVNlYXJjaFN0ciA9IHNlYXJjaFN0ci5zcGxpdCgnJykucmV2ZXJzZSgpLmpvaW4oJycpO1xyXG4gICAgICAgICAgICAgICAgaW5sdWRlcyA9IGxpbmUuaW5jbHVkZXMoc2VhcmNoU3RyKSB8fCBsaW5lLmluY2x1ZGVzKHJldmVyc2VTZWFyY2hTdHIpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaW5sdWRlcyA9IGxpbmUuaW5jbHVkZXMoc2VhcmNoU3RyKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlubHVkZXMpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFzc2VydGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IDAsIHJldmVyc2UgPSBmYWxzZSkge1xyXG4gICAgbGV0IHJvd3MgPSB7fTsgLy8gaW5kZXhlZCBieSB5LXBvc2l0aW9uXHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGNvbnN0IHNlYXJjaFN0ciA9IHRleHQucmVwbGFjZSgvXFxzL2csICcnKTtcclxuXHJcbiAgICAgICAgbGV0IHBkZlBhcnNlciA9IG5ldyBQREZQYXJzZXIoKTtcclxuICAgICAgICBwZGZQYXJzZXIub24oJ3BkZlBhcnNlcl9kYXRhRXJyb3InLCBmdW5jdGlvbihlcnIpIHtcclxuICAgICAgICAgICAgbGV0IGVycm9yTWVzc2FnZSA9IGVyci5wYXJzZXJFcnJvciA/IGVyci5wYXJzZXJFcnJvciA6ICdFcnJvciBwYXJzaW5nIHRoZSBQREYuJztcclxuICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIGVycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHBkZlBhcnNlci5vbigncGRmUGFyc2VyX2RhdGFSZWFkeScsIGZ1bmN0aW9uIChwZGZEYXRhKSB7XHJcbiAgICAgICAgICAgIHZhciB0b3RhbFBhZ2VzID0gcGRmRGF0YS5mb3JtSW1hZ2UuUGFnZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICBpZiAocGFnZU51bSAmJiB0b3RhbFBhZ2VzIDwgcGFnZU51bSAtIDEpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuU0NSSVBUX0VSUk9SLCBgSW52YWxpZCBhcmd1bWVudCAtICdwYWdlTnVtJyBpcyAke3BhZ2VOdW19LCBidXQgUERGIGNvbnRhaW5zIG9ubHkgJHt0b3RhbFBhZ2VzfSBwYWdlc2ApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBsb2NhdGUgb24gYSBzcGVjaWZpYyBwYWdlXHJcbiAgICAgICAgICAgIGlmIChwYWdlTnVtKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twYWdlTnVtLTFdLlRleHRzKTtcclxuICAgICAgICAgICAgICAgIGxldCBpc0ZvdW5kID0gY2hlY2tSb3dzKHNlYXJjaFN0ciwgcm93cywgcmV2ZXJzZSk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKCEhaXNGb3VuZCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGxvY2F0ZSBvbiBhbnkgcGFnZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBwIGluIHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twXS5UZXh0cyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXNGb3VuZCA9IGNoZWNrUm93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRm91bmQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcm93cyA9IHt9OyAvLyBjbGVhciByb3dzIGZvciBuZXh0IHBhZ2VcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGRmUGFyc2VyLmxvYWRQREYocGRmRmlsZVBhdGgsIDApO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByb2Nlc3NUZXh0KHJvd3MsIHRleHRzKSB7XHJcbiAgICBmb3IgKHZhciB0IGluIHRleHRzKSB7XHJcbiAgICAgICAgdmFyIGl0ZW0gPSB0ZXh0c1t0XTtcclxuICAgICAgICB2YXIgdGV4dCA9IGRlY29kZVVSSUNvbXBvbmVudChpdGVtLlJbMF0uVCk7XHJcbiAgICAgICAgLy8gYWNjdW11bGF0ZSB0ZXh0IGl0ZW1zIGludG8gcm93cyBvYmplY3QsIHBlciBsaW5lXHJcbiAgICAgICAgKHJvd3NbaXRlbS55XSA9IHJvd3NbaXRlbS55XSB8fCBbXSkucHVzaCh0ZXh0KTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gY291bnQocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0gPSAwLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgIGxldCByb3dzID0ge307IC8vIGluZGV4ZWQgYnkgeS1wb3NpdGlvblxyXG4gICAgbGV0IHRvdGFsQ291bnQgPSAwO1xyXG5cclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBjb25zdCBzZWFyY2hTdHIgPSB0ZXh0LnJlcGxhY2UoL1xccy9nLCAnJyk7XHJcblxyXG4gICAgICAgIGxldCBwZGZQYXJzZXIgPSBuZXcgUERGUGFyc2VyKCk7XHJcbiAgICAgICAgcGRmUGFyc2VyLm9uKCdwZGZQYXJzZXJfZGF0YUVycm9yJywgZnVuY3Rpb24oZXJyKSB7XHJcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBlcnIucGFyc2VyRXJyb3IgPyBlcnIucGFyc2VyRXJyb3IgOiAnRXJyb3IgcGFyc2luZyB0aGUgUERGLic7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBwZGZQYXJzZXIub24oJ3BkZlBhcnNlcl9kYXRhUmVhZHknLCBmdW5jdGlvbiAocGRmRGF0YSkge1xyXG4gICAgICAgICAgICBsZXQgdG90YWxQYWdlcyA9IHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHBhZ2VOdW0gJiYgdG90YWxQYWdlcyA8IHBhZ2VOdW0gLSAxKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgYEludmFsaWQgYXJndW1lbnQgLSAncGFnZU51bScgaXMgJHtwYWdlTnVtfSwgYnV0IFBERiBjb250YWlucyBvbmx5ICR7dG90YWxQYWdlc30gcGFnZXNgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gY291bnQgb24gYSBzcGVjaWZpYyBwYWdlXHJcbiAgICAgICAgICAgIGlmIChwYWdlTnVtKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twYWdlTnVtLTFdLlRleHRzKTtcclxuICAgICAgICAgICAgICAgIGxldCBjb3VudCA9IGNvdW50Um93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb3VudCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNvdW50IG9uIGFsbCBwYWdlc1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twXS5UZXh0cyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY291bnQgPSBjb3VudFJvd3Moc2VhcmNoU3RyLCByb3dzLCByZXZlcnNlKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3RhbENvdW50ICs9IGNvdW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcm93cyA9IHt9OyAvLyBjbGVhciByb3dzIGZvciBuZXh0IHBhZ2VcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVzb2x2ZSh0b3RhbENvdW50KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwZGZQYXJzZXIubG9hZFBERihwZGZGaWxlUGF0aCwgMCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVTdHJpbmcoYXJnLCBuYW1lKSB7XHJcbiAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnICYmIGFyZy50cmltKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIC8vIHRleHQgaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBub24tZW1wdHkgc3RyaW5nLlwiKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVQYWdlTnVtKGFyZywgbmFtZSkge1xyXG4gICAgaWYgKGFyZyA9PT0gbnVsbCB8fCAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdudW1iZXInICYmIGFyZyA+IDApKSB7XHJcbiAgICAgICAgLy8gcGFnZU51bSBpcyBjb3JyZWN0XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuU0NSSVBUX0VSUk9SLCBcIkludmFsaWQgYXJndW1lbnQgLSAnXCIgKyBuYW1lICsgXCInIHNob3VsZCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuXCIpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB2YWxpZGF0ZU1lc3NhZ2UoYXJnLCBuYW1lKSB7XHJcbiAgICBpZiAoYXJnID09PSBudWxsIHx8IChhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgJiYgYXJnLnRyaW0oKS5sZW5ndGggPiAwKSkge1xyXG4gICAgICAgIC8vIHBhZ2VOdW0gaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBub24tZW1wdHkgc3RyaW5nLlwiKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVSZXZlcnNlKGFyZywgbmFtZSkge1xyXG4gICAgaWYgKGFyZyA9PT0gbnVsbCB8fCAodHlwZW9mIGFyZyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nKSkge1xyXG4gICAgICAgIC8vIHBhZ2VOdW0gaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBib29sZWFuXCIpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucykge1xyXG5cclxuICAgIHBkZkZpbGVQYXRoID0gcGRmRmlsZVBhdGgudHJpbSgpLnNwbGl0KCcnKS5tYXAoKGl0ZW0sIGlkeCkgPT4ge1xyXG4gICAgICAgIHJldHVybiAhWzgyMDYsIDgyOTZdLmluY2x1ZGVzKHBkZkZpbGVQYXRoLmNoYXJDb2RlQXQoaWR4KSkgPyBpdGVtIDogbnVsbDtcclxuICAgIH0pLmpvaW4oJycpO1xyXG5cclxuICAgIGlmIChwZGZGaWxlUGF0aFswXSA9PT0gJ34nKSB7XHJcbiAgICAgICAgLy8gcmVzb2x2ZSBwYXRoIHJlbGF0aXZlIHRvIGhvbWUgZGlyZWN0b3J5XHJcbiAgICAgICAgcmV0dXJuIHBhdGguam9pbihwcm9jZXNzLmVudi5IT01FLCBwZGZGaWxlUGF0aC5zbGljZSgxKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmN3ZCkge1xyXG4gICAgICAgICAgICBjd2QgPSBvcHRpb25zLmN3ZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucm9vdFBhdGgpIHtcclxuICAgICAgICAgICAgY3dkID0gb3B0aW9ucy5yb290UGF0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN3ZCA9IGN3ZC50cmltKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwYXRoLnJlc29sdmUoY3dkLCBwZGZGaWxlUGF0aCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3B0aW9ucywgY29udGV4dCwgcnMsIGxvZ2dlciwgbW9kdWxlcywgc2VydmljZXMpIHtcclxuXHJcbiAgICBtb2R1bGUuaXNJbml0aWFsaXplZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBzdW1tYXJ5IEFzc2VydHMgdGhhdCB0ZXh0IGlzIHByZXNlbnQgaW4gYSBQREYgZmlsZVxyXG4gICAgICogQGZ1bmN0aW9uIGFzc2VydFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgUERGIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gYXNzZXJ0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXI9fSBwYWdlTnVtIC0gUGFnZSBudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZz19IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHRocm93IGlmIGFzc2VydGlvbiBmYWlscy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKi9cclxuICAgIG1vZHVsZS5hc3NlcnQgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwZGZGaWxlUGF0aCwgJ3BkZkZpbGVQYXRoJyk7XHJcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodGV4dCwgJ3RleHQnKTtcclxuICAgICAgICB2YWxpZGF0ZVBhZ2VOdW0ocGFnZU51bSwgJ3BhZ2VOdW0nKTtcclxuICAgICAgICB2YWxpZGF0ZU1lc3NhZ2UobWVzc2FnZSwgJ21lc3NhZ2UnKTtcclxuICAgICAgICB2YWxpZGF0ZVJldmVyc2UocmV2ZXJzZSwgJ3JldmVyc2UnKTtcclxuXHJcbiAgICAgICAgcGRmRmlsZVBhdGggPSByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgIGxldCBlcnJvcjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXQgPSBhd2FpdCBhc3NlcnRpb24ocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0sIHJldmVyc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFyZXQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxldCBtc2cgPSBgXCIke3RleHR9XCIgaXMgbm90IGZvdW5kIGluIHRoZSBQREYgJHtwYWdlTnVtID8gJ29uIHBhZ2UgJyArIHBhZ2VOdW0gOiAnJ31gO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIG1zZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBlcnJvciA9IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHN1bW1hcnkgQXNzZXJ0cyB0aGF0IHRleHQgaXMgbm90IHByZXNlbnQgaW4gYSBQREYgZmlsZVxyXG4gICAgICogQGZ1bmN0aW9uIGFzc2VydE5vdFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgcGRmIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gYXNzZXJ0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXI9fSBwYWdlTnVtIC0gUGFnZSBudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZz19IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHRocm93IGlmIGFzc2VydGlvbiBmYWlscy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKi9cclxuICAgIG1vZHVsZS5hc3NlcnROb3QgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwZGZGaWxlUGF0aCwgJ3BkZkZpbGVQYXRoJyk7XHJcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodGV4dCwgJ3RleHQnKTtcclxuICAgICAgICB2YWxpZGF0ZVBhZ2VOdW0ocGFnZU51bSwgJ3BhZ2VOdW0nKTtcclxuICAgICAgICB2YWxpZGF0ZU1lc3NhZ2UobWVzc2FnZSwgJ21lc3NhZ2UnKTtcclxuICAgICAgICB2YWxpZGF0ZVJldmVyc2UocmV2ZXJzZSwgJ3JldmVyc2UnKTtcclxuXHJcbiAgICAgICAgcGRmRmlsZVBhdGggPSByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgIGxldCBlcnJvcjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXQgPSBhd2FpdCBhc3NlcnRpb24ocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0sIHJldmVyc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHJldCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLkFTU0VSVF9FUlJPUiwgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IG1zZyA9IGBcIiR7dGV4dH1cIiBpcyBmb3VuZCBpbiB0aGUgUERGICR7cGFnZU51bSA/ICdvbiBwYWdlICcgKyBwYWdlTnVtIDogJyd9YDtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBtc2cpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAc3VtbWFyeSBDb3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIHNwZWNpZmllZCB0ZXh0IGlzIHByZXNlbnQgaW4gYSBQREYgZmlsZS5cclxuICAgICAqIEBmdW5jdGlvbiBjb3VudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgcGRmIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gY291bnQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcj19IHBhZ2VOdW0gLSBQYWdlIG51bWJlci5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IE51bWJlciBvZiB0aW1lcyB0aGUgc3BlY2lmaWVkIHRleHQgd2FzIGZvdW5kLlxyXG4gICAgICovXHJcbiAgICBtb2R1bGUuY291bnQgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIHJldmVyc2UgPSBmYWxzZSkge1xyXG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKHBkZkZpbGVQYXRoLCAncGRmRmlsZVBhdGgnKTtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyh0ZXh0LCAndGV4dCcpO1xyXG4gICAgICAgIHZhbGlkYXRlUGFnZU51bShwYWdlTnVtLCAncGFnZU51bScpO1xyXG4gICAgICAgIHZhbGlkYXRlUmV2ZXJzZShyZXZlcnNlLCAncmV2ZXJzZScpO1xyXG5cclxuICAgICAgICBwZGZGaWxlUGF0aCA9IHJlc29sdmVQYXRoKHBkZkZpbGVQYXRoLCBvcHRpb25zKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNvdW50KHBkZkZpbGVQYXRoLCB0ZXh0LCBwYWdlTnVtLCByZXZlcnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5QREZfRVJST1IsIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBtb2R1bGU7XHJcbn07XHJcbiJdfQ==
|