israeli-bank-scrapers 6.0.0 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +1 -0
  2. package/lib/assertNever.js +5 -7
  3. package/lib/constants.js +13 -16
  4. package/lib/definitions.js +109 -113
  5. package/lib/helpers/browser.d.ts +8 -0
  6. package/lib/helpers/browser.js +14 -11
  7. package/lib/helpers/dates.js +18 -19
  8. package/lib/helpers/debug.js +9 -9
  9. package/lib/helpers/elements-interactions.js +78 -84
  10. package/lib/helpers/fetch.js +82 -89
  11. package/lib/helpers/navigation.js +24 -31
  12. package/lib/helpers/storage.js +10 -12
  13. package/lib/helpers/transactions.js +33 -35
  14. package/lib/helpers/waiting.js +45 -44
  15. package/lib/index.js +15 -82
  16. package/lib/scrapers/amex.js +11 -13
  17. package/lib/scrapers/base-beinleumi-group.js +233 -252
  18. package/lib/scrapers/base-isracard-amex.js +273 -286
  19. package/lib/scrapers/base-scraper-with-browser.d.ts +2 -1
  20. package/lib/scrapers/base-scraper-with-browser.js +240 -269
  21. package/lib/scrapers/base-scraper.js +82 -86
  22. package/lib/scrapers/behatsdaa.js +98 -107
  23. package/lib/scrapers/beinleumi.js +11 -20
  24. package/lib/scrapers/beyahad-bishvilha.js +132 -138
  25. package/lib/scrapers/discount.js +97 -103
  26. package/lib/scrapers/errors.js +22 -25
  27. package/lib/scrapers/factory.js +66 -67
  28. package/lib/scrapers/hapoalim.js +162 -182
  29. package/lib/scrapers/interface.d.ts +12 -0
  30. package/lib/scrapers/interface.js +2 -5
  31. package/lib/scrapers/isracard.js +11 -13
  32. package/lib/scrapers/leumi.js +167 -176
  33. package/lib/scrapers/massad.js +11 -20
  34. package/lib/scrapers/max.js +256 -268
  35. package/lib/scrapers/mercantile.js +14 -20
  36. package/lib/scrapers/mizrahi.js +158 -159
  37. package/lib/scrapers/one-zero-queries.js +4 -7
  38. package/lib/scrapers/one-zero.js +176 -240
  39. package/lib/scrapers/otsar-hahayal.js +11 -20
  40. package/lib/scrapers/pagi.js +11 -20
  41. package/lib/scrapers/union-bank.js +172 -179
  42. package/lib/scrapers/visa-cal.js +254 -263
  43. package/lib/scrapers/yahav.js +190 -211
  44. package/lib/transactions.js +13 -16
  45. package/package.json +12 -14
  46. package/lib/scrapers/amex.test.d.ts +0 -1
  47. package/lib/scrapers/amex.test.js +0 -54
  48. package/lib/scrapers/base-scraper-with-browser.test.d.ts +0 -1
  49. package/lib/scrapers/base-scraper-with-browser.test.js +0 -58
  50. package/lib/scrapers/behatsdaa.test.d.ts +0 -1
  51. package/lib/scrapers/behatsdaa.test.js +0 -50
  52. package/lib/scrapers/beinleumi.test.d.ts +0 -1
  53. package/lib/scrapers/beinleumi.test.js +0 -52
  54. package/lib/scrapers/beyahad-bishvilha.test.d.ts +0 -1
  55. package/lib/scrapers/beyahad-bishvilha.test.js +0 -52
  56. package/lib/scrapers/discount.test.d.ts +0 -1
  57. package/lib/scrapers/discount.test.js +0 -54
  58. package/lib/scrapers/factory.test.d.ts +0 -1
  59. package/lib/scrapers/factory.test.js +0 -19
  60. package/lib/scrapers/hapoalim.test.d.ts +0 -1
  61. package/lib/scrapers/hapoalim.test.js +0 -52
  62. package/lib/scrapers/isracard.test.d.ts +0 -1
  63. package/lib/scrapers/isracard.test.js +0 -54
  64. package/lib/scrapers/leumi.test.d.ts +0 -1
  65. package/lib/scrapers/leumi.test.js +0 -52
  66. package/lib/scrapers/max.test.d.ts +0 -1
  67. package/lib/scrapers/max.test.js +0 -71
  68. package/lib/scrapers/mercantile.test.d.ts +0 -1
  69. package/lib/scrapers/mercantile.test.js +0 -50
  70. package/lib/scrapers/mizrahi.test.d.ts +0 -1
  71. package/lib/scrapers/mizrahi.test.js +0 -58
  72. package/lib/scrapers/one-zero.test.d.ts +0 -1
  73. package/lib/scrapers/one-zero.test.js +0 -56
  74. package/lib/scrapers/otsar-hahayal.test.d.ts +0 -1
  75. package/lib/scrapers/otsar-hahayal.test.js +0 -52
  76. package/lib/scrapers/pagi.test.d.ts +0 -1
  77. package/lib/scrapers/pagi.test.js +0 -52
  78. package/lib/scrapers/union-bank.test.d.ts +0 -1
  79. package/lib/scrapers/union-bank.test.js +0 -52
  80. package/lib/scrapers/visa-cal.test.d.ts +0 -1
  81. package/lib/scrapers/visa-cal.test.js +0 -54
  82. package/lib/scrapers/yahav.test.d.ts +0 -1
  83. package/lib/scrapers/yahav.test.js +0 -54
@@ -1,291 +1,262 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.LoginResults = exports.BaseScraperWithBrowser = void 0;
7
- require("core-js/modules/es.array.iterator.js");
8
- require("core-js/modules/es.promise.js");
9
- require("core-js/modules/es.regexp.constructor.js");
10
- require("core-js/modules/es.regexp.exec.js");
11
- var _puppeteer = _interopRequireDefault(require("puppeteer"));
12
- var _definitions = require("../definitions");
13
- var _debug = require("../helpers/debug");
14
- var _elementsInteractions = require("../helpers/elements-interactions");
15
- var _navigation = require("../helpers/navigation");
16
- var _baseScraper = require("./base-scraper");
17
- var _errors = require("./errors");
18
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
24
- function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
25
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
26
- const VIEWPORT_WIDTH = 1024;
27
- const VIEWPORT_HEIGHT = 768;
28
- const OK_STATUS = 200;
29
- const debug = (0, _debug.getDebug)('base-scraper-with-browser');
30
- var LoginBaseResults = /*#__PURE__*/function (LoginBaseResults) {
31
- LoginBaseResults["Success"] = "SUCCESS";
32
- LoginBaseResults["UnknownError"] = "UNKNOWN_ERROR";
33
- return LoginBaseResults;
34
- }(LoginBaseResults || {});
35
- const {
36
- Timeout,
37
- Generic,
38
- General
39
- } = _errors.ScraperErrorTypes,
40
- rest = _objectWithoutProperties(_errors.ScraperErrorTypes, ["Timeout", "Generic", "General"]);
41
- const LoginResults = exports.LoginResults = _objectSpread(_objectSpread({}, rest), LoginBaseResults);
42
-
43
- // eslint-disable-next-line @typescript-eslint/no-redeclare
44
-
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BaseScraperWithBrowser = exports.LoginResults = void 0;
7
+ const puppeteer_1 = __importDefault(require("puppeteer"));
8
+ const definitions_1 = require("../definitions");
9
+ const debug_1 = require("../helpers/debug");
10
+ const elements_interactions_1 = require("../helpers/elements-interactions");
11
+ const navigation_1 = require("../helpers/navigation");
12
+ const base_scraper_1 = require("./base-scraper");
13
+ const errors_1 = require("./errors");
14
+ const debug = (0, debug_1.getDebug)('base-scraper-with-browser');
15
+ var LoginBaseResults;
16
+ (function (LoginBaseResults) {
17
+ LoginBaseResults["Success"] = "SUCCESS";
18
+ LoginBaseResults["UnknownError"] = "UNKNOWN_ERROR";
19
+ })(LoginBaseResults || (LoginBaseResults = {}));
20
+ const { Timeout, Generic, General, ...rest } = errors_1.ScraperErrorTypes;
21
+ exports.LoginResults = {
22
+ ...rest,
23
+ ...LoginBaseResults,
24
+ };
45
25
  async function getKeyByValue(object, value, page) {
46
- const keys = Object.keys(object);
47
- for (const key of keys) {
48
- // @ts-ignore
49
- const conditions = object[key];
50
- for (const condition of conditions) {
51
- let result = false;
52
- if (condition instanceof RegExp) {
53
- result = condition.test(value);
54
- } else if (typeof condition === 'function') {
55
- result = await condition({
56
- page,
57
- value
58
- });
59
- } else {
60
- result = value.toLowerCase() === condition.toLowerCase();
61
- }
62
- if (result) {
26
+ const keys = Object.keys(object);
27
+ for (const key of keys) {
63
28
  // @ts-ignore
64
- return Promise.resolve(key);
65
- }
29
+ const conditions = object[key];
30
+ for (const condition of conditions) {
31
+ let result = false;
32
+ if (condition instanceof RegExp) {
33
+ result = condition.test(value);
34
+ }
35
+ else if (typeof condition === 'function') {
36
+ result = await condition({ page, value });
37
+ }
38
+ else {
39
+ result = value.toLowerCase() === condition.toLowerCase();
40
+ }
41
+ if (result) {
42
+ // @ts-ignore
43
+ return Promise.resolve(key);
44
+ }
45
+ }
66
46
  }
67
- }
68
- return Promise.resolve(LoginResults.UnknownError);
47
+ return Promise.resolve(exports.LoginResults.UnknownError);
69
48
  }
70
49
  function createGeneralError() {
71
- return {
72
- success: false,
73
- errorType: _errors.ScraperErrorTypes.General
74
- };
50
+ return {
51
+ success: false,
52
+ errorType: errors_1.ScraperErrorTypes.General,
53
+ };
75
54
  }
76
- class BaseScraperWithBrowser extends _baseScraper.BaseScraper {
77
- constructor(...args) {
78
- super(...args);
79
- _defineProperty(this, "cleanups", []);
55
+ class BaseScraperWithBrowser extends base_scraper_1.BaseScraper {
56
+ cleanups = [];
57
+ defaultViewportSize = {
58
+ width: 1024,
59
+ height: 768,
60
+ };
80
61
  // NOTICE - it is discouraged to use bang (!) in general. It is used here because
81
62
  // all the classes that inherit from this base assume is it mandatory.
82
- _defineProperty(this, "page", void 0);
83
- }
84
- getViewPort() {
85
- return {
86
- width: VIEWPORT_WIDTH,
87
- height: VIEWPORT_HEIGHT
88
- };
89
- }
90
- async initialize() {
91
- await super.initialize();
92
- debug('initialize scraper');
93
- this.emitProgress(_definitions.ScraperProgressTypes.Initializing);
94
- const page = await this.initializePage();
95
- await page.setCacheEnabled(false); // Clear cache and avoid 300's response status
96
-
97
- if (!page) {
98
- debug('failed to initiate a browser page, exit');
99
- return;
100
- }
101
- this.page = page;
102
- this.cleanups.push(() => page.close());
103
- if (this.options.defaultTimeout) {
104
- this.page.setDefaultTimeout(this.options.defaultTimeout);
63
+ page;
64
+ getViewPort() {
65
+ return this.options.viewportSize ?? this.defaultViewportSize;
105
66
  }
106
- if (this.options.preparePage) {
107
- debug("execute 'preparePage' interceptor provided in options");
108
- await this.options.preparePage(this.page);
109
- }
110
- const viewport = this.getViewPort();
111
- debug(`set viewport to width ${viewport.width}, height ${viewport.height}`);
112
- await this.page.setViewport({
113
- width: viewport.width,
114
- height: viewport.height
115
- });
116
- this.page.on('requestfailed', request => {
117
- var _request$failure;
118
- debug('Request failed: %s %s', (_request$failure = request.failure()) === null || _request$failure === void 0 ? void 0 : _request$failure.errorText, request.url());
119
- });
120
- }
121
- async initializePage() {
122
- debug('initialize browser page');
123
- if ('browserContext' in this.options) {
124
- debug('Using the browser context provided in options');
125
- return this.options.browserContext.newPage();
67
+ async initialize() {
68
+ await super.initialize();
69
+ debug('initialize scraper');
70
+ this.emitProgress(definitions_1.ScraperProgressTypes.Initializing);
71
+ const page = await this.initializePage();
72
+ await page.setCacheEnabled(false); // Clear cache and avoid 300's response status
73
+ if (!page) {
74
+ debug('failed to initiate a browser page, exit');
75
+ return;
76
+ }
77
+ this.page = page;
78
+ this.cleanups.push(() => page.close());
79
+ if (this.options.defaultTimeout) {
80
+ this.page.setDefaultTimeout(this.options.defaultTimeout);
81
+ }
82
+ if (this.options.preparePage) {
83
+ debug("execute 'preparePage' interceptor provided in options");
84
+ await this.options.preparePage(this.page);
85
+ }
86
+ const viewport = this.getViewPort();
87
+ debug(`set viewport to width ${viewport.width}, height ${viewport.height}`);
88
+ await this.page.setViewport({
89
+ width: viewport.width,
90
+ height: viewport.height,
91
+ });
92
+ this.page.on('requestfailed', request => {
93
+ debug('Request failed: %s %s', request.failure()?.errorText, request.url());
94
+ });
126
95
  }
127
- if ('browser' in this.options) {
128
- debug('Using the browser instance provided in options');
129
- const {
130
- browser
131
- } = this.options;
132
-
133
- /**
134
- * For backward compatibility, we will close the browser even if we didn't create it
135
- */
136
- if (!this.options.skipCloseBrowser) {
96
+ async initializePage() {
97
+ debug('initialize browser page');
98
+ if ('browserContext' in this.options) {
99
+ debug('Using the browser context provided in options');
100
+ return this.options.browserContext.newPage();
101
+ }
102
+ if ('browser' in this.options) {
103
+ debug('Using the browser instance provided in options');
104
+ const { browser } = this.options;
105
+ /**
106
+ * For backward compatibility, we will close the browser even if we didn't create it
107
+ */
108
+ if (!this.options.skipCloseBrowser) {
109
+ this.cleanups.push(async () => {
110
+ debug('closing the browser');
111
+ await browser.close();
112
+ });
113
+ }
114
+ return browser.newPage();
115
+ }
116
+ const { timeout, args, executablePath, showBrowser } = this.options;
117
+ const headless = !showBrowser;
118
+ debug(`launch a browser with headless mode = ${headless}`);
119
+ const browser = await puppeteer_1.default.launch({
120
+ env: this.options.verbose ? { DEBUG: '*', ...process.env } : undefined,
121
+ headless,
122
+ executablePath,
123
+ args,
124
+ timeout,
125
+ });
137
126
  this.cleanups.push(async () => {
138
- debug('closing the browser');
139
- await browser.close();
127
+ debug('closing the browser');
128
+ await browser.close();
140
129
  });
141
- }
142
- return browser.newPage();
143
- }
144
- const {
145
- timeout,
146
- args,
147
- executablePath,
148
- showBrowser
149
- } = this.options;
150
- const headless = !showBrowser;
151
- debug(`launch a browser with headless mode = ${headless}`);
152
- const browser = await _puppeteer.default.launch({
153
- env: this.options.verbose ? _objectSpread({
154
- DEBUG: '*'
155
- }, process.env) : undefined,
156
- headless,
157
- executablePath,
158
- args,
159
- timeout
160
- });
161
- this.cleanups.push(async () => {
162
- debug('closing the browser');
163
- await browser.close();
164
- });
165
- if (this.options.prepareBrowser) {
166
- debug("execute 'prepareBrowser' interceptor provided in options");
167
- await this.options.prepareBrowser(browser);
168
- }
169
- debug('create a new browser page');
170
- return browser.newPage();
171
- }
172
- async navigateTo(url, page, timeout, waitUntil = 'load') {
173
- const pageToUse = page || this.page;
174
- if (!pageToUse) {
175
- return;
176
- }
177
- const options = _objectSpread(_objectSpread({}, timeout === null ? null : {
178
- timeout
179
- }), {}, {
180
- waitUntil
181
- });
182
- const response = await pageToUse.goto(url, options);
183
-
184
- // note: response will be null when navigating to same url while changing the hash part. the condition below will always accept null as valid result.
185
- if (response !== null && (response === undefined || response.status() !== OK_STATUS)) {
186
- throw new Error(`Error while trying to navigate to url ${url}`);
187
- }
188
- }
189
-
190
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
191
- getLoginOptions(_credentials) {
192
- throw new Error(`getLoginOptions() is not created in ${this.options.companyId}`);
193
- }
194
- async fillInputs(pageOrFrame, fields) {
195
- const modified = [...fields];
196
- const input = modified.shift();
197
- if (!input) {
198
- return;
199
- }
200
- await (0, _elementsInteractions.fillInput)(pageOrFrame, input.selector, input.value);
201
- if (modified.length) {
202
- await this.fillInputs(pageOrFrame, modified);
203
- }
204
- }
205
- async login(credentials) {
206
- if (!credentials || !this.page) {
207
- return createGeneralError();
208
- }
209
- debug('execute login process');
210
- const loginOptions = this.getLoginOptions(credentials);
211
- if (loginOptions.userAgent) {
212
- debug('set custom user agent provided in options');
213
- await this.page.setUserAgent(loginOptions.userAgent);
130
+ if (this.options.prepareBrowser) {
131
+ debug("execute 'prepareBrowser' interceptor provided in options");
132
+ await this.options.prepareBrowser(browser);
133
+ }
134
+ debug('create a new browser page');
135
+ return browser.newPage();
214
136
  }
215
- debug('navigate to login url');
216
- await this.navigateTo(loginOptions.loginUrl, undefined, undefined, loginOptions.waitUntil);
217
- if (loginOptions.checkReadiness) {
218
- debug("execute 'checkReadiness' interceptor provided in login options");
219
- await loginOptions.checkReadiness();
220
- } else if (typeof loginOptions.submitButtonSelector === 'string') {
221
- debug('wait until submit button is available');
222
- await (0, _elementsInteractions.waitUntilElementFound)(this.page, loginOptions.submitButtonSelector);
137
+ async navigateTo(url, waitUntil = 'load', retries = this.options.navigationRetryCount ?? 0) {
138
+ const response = await this.page?.goto(url, { waitUntil });
139
+ if (response === null) {
140
+ // note: response will be null when navigating to same url while changing the hash part.
141
+ // the condition below will always accept null as valid result.
142
+ return;
143
+ }
144
+ if (!response) {
145
+ throw new Error(`Error while trying to navigate to url ${url}, response is undefined`);
146
+ }
147
+ if (!response.ok()) {
148
+ const status = response.status();
149
+ if (retries > 0) {
150
+ debug(`Failed to navigate to url ${url}, status code: ${status}, retrying ${retries} more times`);
151
+ await this.navigateTo(url, waitUntil, retries - 1);
152
+ }
153
+ else {
154
+ throw new Error(`Failed to navigate to url ${url}, status code: ${status}`);
155
+ }
156
+ }
223
157
  }
224
- let loginFrameOrPage = this.page;
225
- if (loginOptions.preAction) {
226
- debug("execute 'preAction' interceptor provided in login options");
227
- loginFrameOrPage = (await loginOptions.preAction()) || this.page;
158
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
159
+ getLoginOptions(_credentials) {
160
+ throw new Error(`getLoginOptions() is not created in ${this.options.companyId}`);
228
161
  }
229
- debug('fill login components input with relevant values');
230
- await this.fillInputs(loginFrameOrPage, loginOptions.fields);
231
- debug('click on login submit button');
232
- if (typeof loginOptions.submitButtonSelector === 'string') {
233
- await (0, _elementsInteractions.clickButton)(loginFrameOrPage, loginOptions.submitButtonSelector);
234
- } else {
235
- await loginOptions.submitButtonSelector();
162
+ async fillInputs(pageOrFrame, fields) {
163
+ const modified = [...fields];
164
+ const input = modified.shift();
165
+ if (!input) {
166
+ return;
167
+ }
168
+ await (0, elements_interactions_1.fillInput)(pageOrFrame, input.selector, input.value);
169
+ if (modified.length) {
170
+ await this.fillInputs(pageOrFrame, modified);
171
+ }
236
172
  }
237
- this.emitProgress(_definitions.ScraperProgressTypes.LoggingIn);
238
- if (loginOptions.postAction) {
239
- debug("execute 'postAction' interceptor provided in login options");
240
- await loginOptions.postAction();
241
- } else {
242
- debug('wait for page navigation');
243
- await (0, _navigation.waitForNavigation)(this.page);
173
+ async login(credentials) {
174
+ if (!credentials || !this.page) {
175
+ return createGeneralError();
176
+ }
177
+ debug('execute login process');
178
+ const loginOptions = this.getLoginOptions(credentials);
179
+ if (loginOptions.userAgent) {
180
+ debug('set custom user agent provided in options');
181
+ await this.page.setUserAgent(loginOptions.userAgent);
182
+ }
183
+ debug('navigate to login url');
184
+ await this.navigateTo(loginOptions.loginUrl, loginOptions.waitUntil);
185
+ if (loginOptions.checkReadiness) {
186
+ debug("execute 'checkReadiness' interceptor provided in login options");
187
+ await loginOptions.checkReadiness();
188
+ }
189
+ else if (typeof loginOptions.submitButtonSelector === 'string') {
190
+ debug('wait until submit button is available');
191
+ await (0, elements_interactions_1.waitUntilElementFound)(this.page, loginOptions.submitButtonSelector);
192
+ }
193
+ let loginFrameOrPage = this.page;
194
+ if (loginOptions.preAction) {
195
+ debug("execute 'preAction' interceptor provided in login options");
196
+ loginFrameOrPage = (await loginOptions.preAction()) || this.page;
197
+ }
198
+ debug('fill login components input with relevant values');
199
+ await this.fillInputs(loginFrameOrPage, loginOptions.fields);
200
+ debug('click on login submit button');
201
+ if (typeof loginOptions.submitButtonSelector === 'string') {
202
+ await (0, elements_interactions_1.clickButton)(loginFrameOrPage, loginOptions.submitButtonSelector);
203
+ }
204
+ else {
205
+ await loginOptions.submitButtonSelector();
206
+ }
207
+ this.emitProgress(definitions_1.ScraperProgressTypes.LoggingIn);
208
+ if (loginOptions.postAction) {
209
+ debug("execute 'postAction' interceptor provided in login options");
210
+ await loginOptions.postAction();
211
+ }
212
+ else {
213
+ debug('wait for page navigation');
214
+ await (0, navigation_1.waitForNavigation)(this.page);
215
+ }
216
+ debug('check login result');
217
+ const current = await (0, navigation_1.getCurrentUrl)(this.page, true);
218
+ const loginResult = await getKeyByValue(loginOptions.possibleResults, current, this.page);
219
+ debug(`handle login results ${loginResult}`);
220
+ return this.handleLoginResult(loginResult);
244
221
  }
245
- debug('check login result');
246
- const current = await (0, _navigation.getCurrentUrl)(this.page, true);
247
- const loginResult = await getKeyByValue(loginOptions.possibleResults, current, this.page);
248
- debug(`handle login results ${loginResult}`);
249
- return this.handleLoginResult(loginResult);
250
- }
251
- async terminate(_success) {
252
- debug(`terminating browser with success = ${_success}`);
253
- this.emitProgress(_definitions.ScraperProgressTypes.Terminating);
254
- if (!_success && !!this.options.storeFailureScreenShotPath) {
255
- debug(`create a snapshot before terminated in ${this.options.storeFailureScreenShotPath}`);
256
- await this.page.screenshot({
257
- path: this.options.storeFailureScreenShotPath,
258
- fullPage: true
259
- });
222
+ async terminate(_success) {
223
+ debug(`terminating browser with success = ${_success}`);
224
+ this.emitProgress(definitions_1.ScraperProgressTypes.Terminating);
225
+ if (!_success && !!this.options.storeFailureScreenShotPath) {
226
+ debug(`create a snapshot before terminated in ${this.options.storeFailureScreenShotPath}`);
227
+ await this.page.screenshot({
228
+ path: this.options.storeFailureScreenShotPath,
229
+ fullPage: true,
230
+ });
231
+ }
232
+ await Promise.all(this.cleanups.reverse().map(cleanup => cleanup()));
233
+ this.cleanups = [];
260
234
  }
261
- await Promise.all(this.cleanups.reverse().map(cleanup => cleanup()));
262
- this.cleanups = [];
263
- }
264
- handleLoginResult(loginResult) {
265
- switch (loginResult) {
266
- case LoginResults.Success:
267
- this.emitProgress(_definitions.ScraperProgressTypes.LoginSuccess);
268
- return {
269
- success: true
270
- };
271
- case LoginResults.InvalidPassword:
272
- case LoginResults.UnknownError:
273
- this.emitProgress(_definitions.ScraperProgressTypes.LoginFailed);
274
- return {
275
- success: false,
276
- errorType: loginResult === LoginResults.InvalidPassword ? _errors.ScraperErrorTypes.InvalidPassword : _errors.ScraperErrorTypes.General,
277
- errorMessage: `Login failed with ${loginResult} error`
278
- };
279
- case LoginResults.ChangePassword:
280
- this.emitProgress(_definitions.ScraperProgressTypes.ChangePassword);
281
- return {
282
- success: false,
283
- errorType: _errors.ScraperErrorTypes.ChangePassword
284
- };
285
- default:
286
- throw new Error(`unexpected login result "${loginResult}"`);
235
+ handleLoginResult(loginResult) {
236
+ switch (loginResult) {
237
+ case exports.LoginResults.Success:
238
+ this.emitProgress(definitions_1.ScraperProgressTypes.LoginSuccess);
239
+ return { success: true };
240
+ case exports.LoginResults.InvalidPassword:
241
+ case exports.LoginResults.UnknownError:
242
+ this.emitProgress(definitions_1.ScraperProgressTypes.LoginFailed);
243
+ return {
244
+ success: false,
245
+ errorType: loginResult === exports.LoginResults.InvalidPassword
246
+ ? errors_1.ScraperErrorTypes.InvalidPassword
247
+ : errors_1.ScraperErrorTypes.General,
248
+ errorMessage: `Login failed with ${loginResult} error`,
249
+ };
250
+ case exports.LoginResults.ChangePassword:
251
+ this.emitProgress(definitions_1.ScraperProgressTypes.ChangePassword);
252
+ return {
253
+ success: false,
254
+ errorType: errors_1.ScraperErrorTypes.ChangePassword,
255
+ };
256
+ default:
257
+ throw new Error(`unexpected login result "${loginResult}"`);
258
+ }
287
259
  }
288
- }
289
260
  }
290
261
  exports.BaseScraperWithBrowser = BaseScraperWithBrowser;
291
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcHVwcGV0ZWVyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZGVmaW5pdGlvbnMiLCJfZGVidWciLCJfZWxlbWVudHNJbnRlcmFjdGlvbnMiLCJfbmF2aWdhdGlvbiIsIl9iYXNlU2NyYXBlciIsIl9lcnJvcnMiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJvd25LZXlzIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJfdG9Qcm9wZXJ0eUtleSIsInZhbHVlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJpIiwiX3RvUHJpbWl0aXZlIiwiU3ltYm9sIiwidG9QcmltaXRpdmUiLCJjYWxsIiwiVHlwZUVycm9yIiwiU3RyaW5nIiwiTnVtYmVyIiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UiLCJuIiwiaW5kZXhPZiIsInByb3BlcnR5SXNFbnVtZXJhYmxlIiwiaGFzT3duUHJvcGVydHkiLCJWSUVXUE9SVF9XSURUSCIsIlZJRVdQT1JUX0hFSUdIVCIsIk9LX1NUQVRVUyIsImRlYnVnIiwiZ2V0RGVidWciLCJMb2dpbkJhc2VSZXN1bHRzIiwiVGltZW91dCIsIkdlbmVyaWMiLCJHZW5lcmFsIiwiU2NyYXBlckVycm9yVHlwZXMiLCJyZXN0IiwiTG9naW5SZXN1bHRzIiwiZXhwb3J0cyIsImdldEtleUJ5VmFsdWUiLCJvYmplY3QiLCJwYWdlIiwia2V5IiwiY29uZGl0aW9ucyIsImNvbmRpdGlvbiIsInJlc3VsdCIsIlJlZ0V4cCIsInRlc3QiLCJ0b0xvd2VyQ2FzZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiVW5rbm93bkVycm9yIiwiY3JlYXRlR2VuZXJhbEVycm9yIiwic3VjY2VzcyIsImVycm9yVHlwZSIsIkJhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJCYXNlU2NyYXBlciIsImNvbnN0cnVjdG9yIiwiYXJncyIsImdldFZpZXdQb3J0Iiwid2lkdGgiLCJoZWlnaHQiLCJpbml0aWFsaXplIiwiZW1pdFByb2dyZXNzIiwiU2NyYXBlclByb2dyZXNzVHlwZXMiLCJJbml0aWFsaXppbmciLCJpbml0aWFsaXplUGFnZSIsInNldENhY2hlRW5hYmxlZCIsImNsZWFudXBzIiwiY2xvc2UiLCJvcHRpb25zIiwiZGVmYXVsdFRpbWVvdXQiLCJzZXREZWZhdWx0VGltZW91dCIsInByZXBhcmVQYWdlIiwidmlld3BvcnQiLCJzZXRWaWV3cG9ydCIsIm9uIiwicmVxdWVzdCIsIl9yZXF1ZXN0JGZhaWx1cmUiLCJmYWlsdXJlIiwiZXJyb3JUZXh0IiwidXJsIiwiYnJvd3NlckNvbnRleHQiLCJuZXdQYWdlIiwiYnJvd3NlciIsInNraXBDbG9zZUJyb3dzZXIiLCJ0aW1lb3V0IiwiZXhlY3V0YWJsZVBhdGgiLCJzaG93QnJvd3NlciIsImhlYWRsZXNzIiwicHVwcGV0ZWVyIiwibGF1bmNoIiwiZW52IiwidmVyYm9zZSIsIkRFQlVHIiwicHJvY2VzcyIsInVuZGVmaW5lZCIsInByZXBhcmVCcm93c2VyIiwibmF2aWdhdGVUbyIsIndhaXRVbnRpbCIsInBhZ2VUb1VzZSIsInJlc3BvbnNlIiwiZ290byIsInN0YXR1cyIsIkVycm9yIiwiZ2V0TG9naW5PcHRpb25zIiwiX2NyZWRlbnRpYWxzIiwiY29tcGFueUlkIiwiZmlsbElucHV0cyIsInBhZ2VPckZyYW1lIiwiZmllbGRzIiwibW9kaWZpZWQiLCJpbnB1dCIsInNoaWZ0IiwiZmlsbElucHV0Iiwic2VsZWN0b3IiLCJsb2dpbiIsImNyZWRlbnRpYWxzIiwibG9naW5PcHRpb25zIiwidXNlckFnZW50Iiwic2V0VXNlckFnZW50IiwibG9naW5VcmwiLCJjaGVja1JlYWRpbmVzcyIsInN1Ym1pdEJ1dHRvblNlbGVjdG9yIiwid2FpdFVudGlsRWxlbWVudEZvdW5kIiwibG9naW5GcmFtZU9yUGFnZSIsInByZUFjdGlvbiIsImNsaWNrQnV0dG9uIiwiTG9nZ2luZ0luIiwicG9zdEFjdGlvbiIsIndhaXRGb3JOYXZpZ2F0aW9uIiwiY3VycmVudCIsImdldEN1cnJlbnRVcmwiLCJsb2dpblJlc3VsdCIsInBvc3NpYmxlUmVzdWx0cyIsImhhbmRsZUxvZ2luUmVzdWx0IiwidGVybWluYXRlIiwiX3N1Y2Nlc3MiLCJUZXJtaW5hdGluZyIsInN0b3JlRmFpbHVyZVNjcmVlblNob3RQYXRoIiwic2NyZWVuc2hvdCIsInBhdGgiLCJmdWxsUGFnZSIsImFsbCIsInJldmVyc2UiLCJtYXAiLCJjbGVhbnVwIiwiU3VjY2VzcyIsIkxvZ2luU3VjY2VzcyIsIkludmFsaWRQYXNzd29yZCIsIkxvZ2luRmFpbGVkIiwiZXJyb3JNZXNzYWdlIiwiQ2hhbmdlUGFzc3dvcmQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NyYXBlcnMvYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHVwcGV0ZWVyLCB7IHR5cGUgRnJhbWUsIHR5cGUgR29Ub09wdGlvbnMsIHR5cGUgUGFnZSwgdHlwZSBQdXBwZXRlZXJMaWZlQ3ljbGVFdmVudCB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBTY3JhcGVyUHJvZ3Jlc3NUeXBlcyB9IGZyb20gJy4uL2RlZmluaXRpb25zJztcbmltcG9ydCB7IGdldERlYnVnIH0gZnJvbSAnLi4vaGVscGVycy9kZWJ1Zyc7XG5pbXBvcnQgeyBjbGlja0J1dHRvbiwgZmlsbElucHV0LCB3YWl0VW50aWxFbGVtZW50Rm91bmQgfSBmcm9tICcuLi9oZWxwZXJzL2VsZW1lbnRzLWludGVyYWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRDdXJyZW50VXJsLCB3YWl0Rm9yTmF2aWdhdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyBCYXNlU2NyYXBlciB9IGZyb20gJy4vYmFzZS1zY3JhcGVyJztcbmltcG9ydCB7IFNjcmFwZXJFcnJvclR5cGVzIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgdHlwZSBTY3JhcGVyQ3JlZGVudGlhbHMsIHR5cGUgU2NyYXBlclNjcmFwaW5nUmVzdWx0IH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuXG5jb25zdCBWSUVXUE9SVF9XSURUSCA9IDEwMjQ7XG5jb25zdCBWSUVXUE9SVF9IRUlHSFQgPSA3Njg7XG5jb25zdCBPS19TVEFUVVMgPSAyMDA7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ2Jhc2Utc2NyYXBlci13aXRoLWJyb3dzZXInKTtcblxuZW51bSBMb2dpbkJhc2VSZXN1bHRzIHtcbiAgU3VjY2VzcyA9ICdTVUNDRVNTJyxcbiAgVW5rbm93bkVycm9yID0gJ1VOS05PV05fRVJST1InLFxufVxuXG5jb25zdCB7XG4gIFRpbWVvdXQsIEdlbmVyaWMsIEdlbmVyYWwsIC4uLnJlc3Rcbn0gPSBTY3JhcGVyRXJyb3JUeXBlcztcbmV4cG9ydCBjb25zdCBMb2dpblJlc3VsdHMgPSB7XG4gIC4uLnJlc3QsXG4gIC4uLkxvZ2luQmFzZVJlc3VsdHMsXG59O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IHR5cGUgTG9naW5SZXN1bHRzID1cbiAgfCBFeGNsdWRlPFNjcmFwZXJFcnJvclR5cGVzLCBTY3JhcGVyRXJyb3JUeXBlcy5UaW1lb3V0IHwgU2NyYXBlckVycm9yVHlwZXMuR2VuZXJpYyB8IFNjcmFwZXJFcnJvclR5cGVzLkdlbmVyYWw+XG4gIHwgTG9naW5CYXNlUmVzdWx0cztcblxuZXhwb3J0IHR5cGUgUG9zc2libGVMb2dpblJlc3VsdHMgPSB7XG4gIFtrZXkgaW4gTG9naW5SZXN1bHRzXT86IChzdHJpbmcgfCBSZWdFeHAgfCAoKG9wdGlvbnM/OiB7IHBhZ2U/OiBQYWdlIH0pID0+IFByb21pc2U8Ym9vbGVhbj4pKVtdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBMb2dpbk9wdGlvbnMge1xuICBsb2dpblVybDogc3RyaW5nO1xuICBjaGVja1JlYWRpbmVzcz86ICgpID0+IFByb21pc2U8dm9pZD47XG4gIGZpZWxkczogeyBzZWxlY3Rvcjogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIH1bXTtcbiAgc3VibWl0QnV0dG9uU2VsZWN0b3I6IHN0cmluZyB8ICgoKSA9PiBQcm9taXNlPHZvaWQ+KTtcbiAgcHJlQWN0aW9uPzogKCkgPT4gUHJvbWlzZTxGcmFtZSB8IHZvaWQ+O1xuICBwb3N0QWN0aW9uPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcG9zc2libGVSZXN1bHRzOiBQb3NzaWJsZUxvZ2luUmVzdWx0cztcbiAgdXNlckFnZW50Pzogc3RyaW5nO1xuICB3YWl0VW50aWw/OiBQdXBwZXRlZXJMaWZlQ3ljbGVFdmVudDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0S2V5QnlWYWx1ZShvYmplY3Q6IFBvc3NpYmxlTG9naW5SZXN1bHRzLCB2YWx1ZTogc3RyaW5nLCBwYWdlOiBQYWdlKTogUHJvbWlzZTxMb2dpblJlc3VsdHM+IHtcbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG4gIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgY29uZGl0aW9ucyA9IG9iamVjdFtrZXldO1xuXG4gICAgZm9yIChjb25zdCBjb25kaXRpb24gb2YgY29uZGl0aW9ucykge1xuICAgICAgbGV0IHJlc3VsdCA9IGZhbHNlO1xuXG4gICAgICBpZiAoY29uZGl0aW9uIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHJlc3VsdCA9IGNvbmRpdGlvbi50ZXN0KHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbmRpdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXN1bHQgPSBhd2FpdCBjb25kaXRpb24oeyBwYWdlLCB2YWx1ZSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IHZhbHVlLnRvTG93ZXJDYXNlKCkgPT09IGNvbmRpdGlvbi50b0xvd2VyQ2FzZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoTG9naW5SZXN1bHRzLlVua25vd25FcnJvcik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUdlbmVyYWxFcnJvcigpOiBTY3JhcGVyU2NyYXBpbmdSZXN1bHQge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIGVycm9yVHlwZTogU2NyYXBlckVycm9yVHlwZXMuR2VuZXJhbCxcbiAgfTtcbn1cblxuY2xhc3MgQmFzZVNjcmFwZXJXaXRoQnJvd3NlcjxUQ3JlZGVudGlhbHMgZXh0ZW5kcyBTY3JhcGVyQ3JlZGVudGlhbHM+IGV4dGVuZHMgQmFzZVNjcmFwZXI8VENyZWRlbnRpYWxzPiB7XG4gIHByaXZhdGUgY2xlYW51cHM6IEFycmF5PCgpID0+IFByb21pc2U8dm9pZD4+ID0gW107XG5cbiAgLy8gTk9USUNFIC0gaXQgaXMgZGlzY291cmFnZWQgdG8gdXNlIGJhbmcgKCEpIGluIGdlbmVyYWwuIEl0IGlzIHVzZWQgaGVyZSBiZWNhdXNlXG4gIC8vIGFsbCB0aGUgY2xhc3NlcyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIGJhc2UgYXNzdW1lIGlzIGl0IG1hbmRhdG9yeS5cbiAgcHJvdGVjdGVkIHBhZ2UhOiBQYWdlO1xuXG4gIHByb3RlY3RlZCBnZXRWaWV3UG9ydCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGg6IFZJRVdQT1JUX1dJRFRILFxuICAgICAgaGVpZ2h0OiBWSUVXUE9SVF9IRUlHSFQsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgYXdhaXQgc3VwZXIuaW5pdGlhbGl6ZSgpO1xuICAgIGRlYnVnKCdpbml0aWFsaXplIHNjcmFwZXInKTtcbiAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5Jbml0aWFsaXppbmcpO1xuXG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVBhZ2UoKTtcbiAgICBhd2FpdCBwYWdlLnNldENhY2hlRW5hYmxlZChmYWxzZSk7IC8vIENsZWFyIGNhY2hlIGFuZCBhdm9pZCAzMDAncyByZXNwb25zZSBzdGF0dXNcblxuICAgIGlmICghcGFnZSkge1xuICAgICAgZGVidWcoJ2ZhaWxlZCB0byBpbml0aWF0ZSBhIGJyb3dzZXIgcGFnZSwgZXhpdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGFnZSA9IHBhZ2U7XG5cbiAgICB0aGlzLmNsZWFudXBzLnB1c2goKCkgPT4gcGFnZS5jbG9zZSgpKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVmYXVsdFRpbWVvdXQpIHtcbiAgICAgIHRoaXMucGFnZS5zZXREZWZhdWx0VGltZW91dCh0aGlzLm9wdGlvbnMuZGVmYXVsdFRpbWVvdXQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMucHJlcGFyZVBhZ2UpIHtcbiAgICAgIGRlYnVnKFwiZXhlY3V0ZSAncHJlcGFyZVBhZ2UnIGludGVyY2VwdG9yIHByb3ZpZGVkIGluIG9wdGlvbnNcIik7XG4gICAgICBhd2FpdCB0aGlzLm9wdGlvbnMucHJlcGFyZVBhZ2UodGhpcy5wYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuZ2V0Vmlld1BvcnQoKTtcbiAgICBkZWJ1Zyhgc2V0IHZpZXdwb3J0IHRvIHdpZHRoICR7dmlld3BvcnQud2lkdGh9LCBoZWlnaHQgJHt2aWV3cG9ydC5oZWlnaHR9YCk7XG4gICAgYXdhaXQgdGhpcy5wYWdlLnNldFZpZXdwb3J0KHtcbiAgICAgIHdpZHRoOiB2aWV3cG9ydC53aWR0aCxcbiAgICAgIGhlaWdodDogdmlld3BvcnQuaGVpZ2h0LFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYWdlLm9uKCdyZXF1ZXN0ZmFpbGVkJywgKHJlcXVlc3QpID0+IHtcbiAgICAgIGRlYnVnKCdSZXF1ZXN0IGZhaWxlZDogJXMgJXMnLCByZXF1ZXN0LmZhaWx1cmUoKT8uZXJyb3JUZXh0LCByZXF1ZXN0LnVybCgpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZVBhZ2UoKSB7XG4gICAgZGVidWcoJ2luaXRpYWxpemUgYnJvd3NlciBwYWdlJyk7XG4gICAgaWYgKCdicm93c2VyQ29udGV4dCcgaW4gdGhpcy5vcHRpb25zKSB7XG4gICAgICBkZWJ1ZygnVXNpbmcgdGhlIGJyb3dzZXIgY29udGV4dCBwcm92aWRlZCBpbiBvcHRpb25zJyk7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmJyb3dzZXJDb250ZXh0Lm5ld1BhZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAoJ2Jyb3dzZXInIGluIHRoaXMub3B0aW9ucykge1xuICAgICAgZGVidWcoJ1VzaW5nIHRoZSBicm93c2VyIGluc3RhbmNlIHByb3ZpZGVkIGluIG9wdGlvbnMnKTtcbiAgICAgIGNvbnN0IHsgYnJvd3NlciB9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB3ZSB3aWxsIGNsb3NlIHRoZSBicm93c2VyIGV2ZW4gaWYgd2UgZGlkbid0IGNyZWF0ZSBpdFxuICAgICAgICovXG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5za2lwQ2xvc2VCcm93c2VyKSB7XG4gICAgICAgIHRoaXMuY2xlYW51cHMucHVzaChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgZGVidWcoJ2Nsb3NpbmcgdGhlIGJyb3dzZXInKTtcbiAgICAgICAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnJvd3Nlci5uZXdQYWdlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB0aW1lb3V0LCBhcmdzLCBleGVjdXRhYmxlUGF0aCwgc2hvd0Jyb3dzZXIgfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGNvbnN0IGhlYWRsZXNzID0gIXNob3dCcm93c2VyO1xuICAgIGRlYnVnKGBsYXVuY2ggYSBicm93c2VyIHdpdGggaGVhZGxlc3MgbW9kZSA9ICR7aGVhZGxlc3N9YCk7XG5cbiAgICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaCh7XG4gICAgICBlbnY6IHRoaXMub3B0aW9ucy52ZXJib3NlID8geyBERUJVRzogJyonLCAuLi5wcm9jZXNzLmVudiB9IDogdW5kZWZpbmVkLFxuICAgICAgaGVhZGxlc3MsXG4gICAgICBleGVjdXRhYmxlUGF0aCxcbiAgICAgIGFyZ3MsXG4gICAgICB0aW1lb3V0LFxuICAgIH0pO1xuXG4gICAgdGhpcy5jbGVhbnVwcy5wdXNoKGFzeW5jICgpID0+IHtcbiAgICAgIGRlYnVnKCdjbG9zaW5nIHRoZSBicm93c2VyJyk7XG4gICAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnByZXBhcmVCcm93c2VyKSB7XG4gICAgICBkZWJ1ZyhcImV4ZWN1dGUgJ3ByZXBhcmVCcm93c2VyJyBpbnRlcmNlcHRvciBwcm92aWRlZCBpbiBvcHRpb25zXCIpO1xuICAgICAgYXdhaXQgdGhpcy5vcHRpb25zLnByZXBhcmVCcm93c2VyKGJyb3dzZXIpO1xuICAgIH1cblxuICAgIGRlYnVnKCdjcmVhdGUgYSBuZXcgYnJvd3NlciBwYWdlJyk7XG4gICAgcmV0dXJuIGJyb3dzZXIubmV3UGFnZSgpO1xuICB9XG5cbiAgYXN5bmMgbmF2aWdhdGVUbyhcbiAgICB1cmw6IHN0cmluZyxcbiAgICBwYWdlPzogUGFnZSxcbiAgICB0aW1lb3V0PzogbnVtYmVyLFxuICAgIHdhaXRVbnRpbDogUHVwcGV0ZWVyTGlmZUN5Y2xlRXZlbnQgfCB1bmRlZmluZWQgPSAnbG9hZCcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBhZ2VUb1VzZSA9IHBhZ2UgfHwgdGhpcy5wYWdlO1xuXG4gICAgaWYgKCFwYWdlVG9Vc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zOiBHb1RvT3B0aW9ucyA9IHsgLi4uKHRpbWVvdXQgPT09IG51bGwgPyBudWxsIDogeyB0aW1lb3V0IH0pLCB3YWl0VW50aWwgfTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHBhZ2VUb1VzZS5nb3RvKHVybCwgb3B0aW9ucyk7XG5cbiAgICAvLyBub3RlOiByZXNwb25zZSB3aWxsIGJlIG51bGwgd2hlbiBuYXZpZ2F0aW5nIHRvIHNhbWUgdXJsIHdoaWxlIGNoYW5naW5nIHRoZSBoYXNoIHBhcnQuIHRoZSBjb25kaXRpb24gYmVsb3cgd2lsbCBhbHdheXMgYWNjZXB0IG51bGwgYXMgdmFsaWQgcmVzdWx0LlxuICAgIGlmIChyZXNwb25zZSAhPT0gbnVsbCAmJiAocmVzcG9uc2UgPT09IHVuZGVmaW5lZCB8fCByZXNwb25zZS5zdGF0dXMoKSAhPT0gT0tfU1RBVFVTKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciB3aGlsZSB0cnlpbmcgdG8gbmF2aWdhdGUgdG8gdXJsICR7dXJsfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0TG9naW5PcHRpb25zKF9jcmVkZW50aWFsczogU2NyYXBlckNyZWRlbnRpYWxzKTogTG9naW5PcHRpb25zIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGdldExvZ2luT3B0aW9ucygpIGlzIG5vdCBjcmVhdGVkIGluICR7dGhpcy5vcHRpb25zLmNvbXBhbnlJZH1gKTtcbiAgfVxuXG4gIGFzeW5jIGZpbGxJbnB1dHMocGFnZU9yRnJhbWU6IFBhZ2UgfCBGcmFtZSwgZmllbGRzOiB7IHNlbGVjdG9yOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbW9kaWZpZWQgPSBbLi4uZmllbGRzXTtcbiAgICBjb25zdCBpbnB1dCA9IG1vZGlmaWVkLnNoaWZ0KCk7XG5cbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IGZpbGxJbnB1dChwYWdlT3JGcmFtZSwgaW5wdXQuc2VsZWN0b3IsIGlucHV0LnZhbHVlKTtcbiAgICBpZiAobW9kaWZpZWQubGVuZ3RoKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpbGxJbnB1dHMocGFnZU9yRnJhbWUsIG1vZGlmaWVkKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dpbihjcmVkZW50aWFsczogU2NyYXBlckNyZWRlbnRpYWxzKTogUHJvbWlzZTxTY3JhcGVyU2NyYXBpbmdSZXN1bHQ+IHtcbiAgICBpZiAoIWNyZWRlbnRpYWxzIHx8ICF0aGlzLnBhZ2UpIHtcbiAgICAgIHJldHVybiBjcmVhdGVHZW5lcmFsRXJyb3IoKTtcbiAgICB9XG5cbiAgICBkZWJ1ZygnZXhlY3V0ZSBsb2dpbiBwcm9jZXNzJyk7XG4gICAgY29uc3QgbG9naW5PcHRpb25zID0gdGhpcy5nZXRMb2dpbk9wdGlvbnMoY3JlZGVudGlhbHMpO1xuXG4gICAgaWYgKGxvZ2luT3B0aW9ucy51c2VyQWdlbnQpIHtcbiAgICAgIGRlYnVnKCdzZXQgY3VzdG9tIHVzZXIgYWdlbnQgcHJvdmlkZWQgaW4gb3B0aW9ucycpO1xuICAgICAgYXdhaXQgdGhpcy5wYWdlLnNldFVzZXJBZ2VudChsb2dpbk9wdGlvbnMudXNlckFnZW50KTtcbiAgICB9XG5cbiAgICBkZWJ1ZygnbmF2aWdhdGUgdG8gbG9naW4gdXJsJyk7XG4gICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvKGxvZ2luT3B0aW9ucy5sb2dpblVybCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGxvZ2luT3B0aW9ucy53YWl0VW50aWwpO1xuICAgIGlmIChsb2dpbk9wdGlvbnMuY2hlY2tSZWFkaW5lc3MpIHtcbiAgICAgIGRlYnVnKFwiZXhlY3V0ZSAnY2hlY2tSZWFkaW5lc3MnIGludGVyY2VwdG9yIHByb3ZpZGVkIGluIGxvZ2luIG9wdGlvbnNcIik7XG4gICAgICBhd2FpdCBsb2dpbk9wdGlvbnMuY2hlY2tSZWFkaW5lc3MoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBsb2dpbk9wdGlvbnMuc3VibWl0QnV0dG9uU2VsZWN0b3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICBkZWJ1Zygnd2FpdCB1bnRpbCBzdWJtaXQgYnV0dG9uIGlzIGF2YWlsYWJsZScpO1xuICAgICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKHRoaXMucGFnZSwgbG9naW5PcHRpb25zLnN1Ym1pdEJ1dHRvblNlbGVjdG9yKTtcbiAgICB9XG5cbiAgICBsZXQgbG9naW5GcmFtZU9yUGFnZTogUGFnZSB8IEZyYW1lIHwgbnVsbCA9IHRoaXMucGFnZTtcbiAgICBpZiAobG9naW5PcHRpb25zLnByZUFjdGlvbikge1xuICAgICAgZGVidWcoXCJleGVjdXRlICdwcmVBY3Rpb24nIGludGVyY2VwdG9yIHByb3ZpZGVkIGluIGxvZ2luIG9wdGlvbnNcIik7XG4gICAgICBsb2dpbkZyYW1lT3JQYWdlID0gKGF3YWl0IGxvZ2luT3B0aW9ucy5wcmVBY3Rpb24oKSkgfHwgdGhpcy5wYWdlO1xuICAgIH1cblxuICAgIGRlYnVnKCdmaWxsIGxvZ2luIGNvbXBvbmVudHMgaW5wdXQgd2l0aCByZWxldmFudCB2YWx1ZXMnKTtcbiAgICBhd2FpdCB0aGlzLmZpbGxJbnB1dHMobG9naW5GcmFtZU9yUGFnZSwgbG9naW5PcHRpb25zLmZpZWxkcyk7XG4gICAgZGVidWcoJ2NsaWNrIG9uIGxvZ2luIHN1Ym1pdCBidXR0b24nKTtcbiAgICBpZiAodHlwZW9mIGxvZ2luT3B0aW9ucy5zdWJtaXRCdXR0b25TZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKGxvZ2luRnJhbWVPclBhZ2UsIGxvZ2luT3B0aW9ucy5zdWJtaXRCdXR0b25TZWxlY3Rvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IGxvZ2luT3B0aW9ucy5zdWJtaXRCdXR0b25TZWxlY3RvcigpO1xuICAgIH1cbiAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5Mb2dnaW5nSW4pO1xuXG4gICAgaWYgKGxvZ2luT3B0aW9ucy5wb3N0QWN0aW9uKSB7XG4gICAgICBkZWJ1ZyhcImV4ZWN1dGUgJ3Bvc3RBY3Rpb24nIGludGVyY2VwdG9yIHByb3ZpZGVkIGluIGxvZ2luIG9wdGlvbnNcIik7XG4gICAgICBhd2FpdCBsb2dpbk9wdGlvbnMucG9zdEFjdGlvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Zygnd2FpdCBmb3IgcGFnZSBuYXZpZ2F0aW9uJyk7XG4gICAgICBhd2FpdCB3YWl0Rm9yTmF2aWdhdGlvbih0aGlzLnBhZ2UpO1xuICAgIH1cblxuICAgIGRlYnVnKCdjaGVjayBsb2dpbiByZXN1bHQnKTtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UsIHRydWUpO1xuICAgIGNvbnN0IGxvZ2luUmVzdWx0ID0gYXdhaXQgZ2V0S2V5QnlWYWx1ZShsb2dpbk9wdGlvbnMucG9zc2libGVSZXN1bHRzLCBjdXJyZW50LCB0aGlzLnBhZ2UpO1xuICAgIGRlYnVnKGBoYW5kbGUgbG9naW4gcmVzdWx0cyAke2xvZ2luUmVzdWx0fWApO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZUxvZ2luUmVzdWx0KGxvZ2luUmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIHRlcm1pbmF0ZShfc3VjY2VzczogYm9vbGVhbikge1xuICAgIGRlYnVnKGB0ZXJtaW5hdGluZyBicm93c2VyIHdpdGggc3VjY2VzcyA9ICR7X3N1Y2Nlc3N9YCk7XG4gICAgdGhpcy5lbWl0UHJvZ3Jlc3MoU2NyYXBlclByb2dyZXNzVHlwZXMuVGVybWluYXRpbmcpO1xuXG4gICAgaWYgKCFfc3VjY2VzcyAmJiAhIXRoaXMub3B0aW9ucy5zdG9yZUZhaWx1cmVTY3JlZW5TaG90UGF0aCkge1xuICAgICAgZGVidWcoYGNyZWF0ZSBhIHNuYXBzaG90IGJlZm9yZSB0ZXJtaW5hdGVkIGluICR7dGhpcy5vcHRpb25zLnN0b3JlRmFpbHVyZVNjcmVlblNob3RQYXRofWApO1xuICAgICAgYXdhaXQgdGhpcy5wYWdlLnNjcmVlbnNob3Qoe1xuICAgICAgICBwYXRoOiB0aGlzLm9wdGlvbnMuc3RvcmVGYWlsdXJlU2NyZWVuU2hvdFBhdGgsXG4gICAgICAgIGZ1bGxQYWdlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5jbGVhbnVwcy5yZXZlcnNlKCkubWFwKChjbGVhbnVwKSA9PiBjbGVhbnVwKCkpKTtcbiAgICB0aGlzLmNsZWFudXBzID0gW107XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUxvZ2luUmVzdWx0KGxvZ2luUmVzdWx0OiBMb2dpblJlc3VsdHMpIHtcbiAgICBzd2l0Y2ggKGxvZ2luUmVzdWx0KSB7XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5TdWNjZXNzOlxuICAgICAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5Mb2dpblN1Y2Nlc3MpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmQ6XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5Vbmtub3duRXJyb3I6XG4gICAgICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkxvZ2luRmFpbGVkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvclR5cGU6XG4gICAgICAgICAgICBsb2dpblJlc3VsdCA9PT0gTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZCA/XG4gICAgICAgICAgICAgIFNjcmFwZXJFcnJvclR5cGVzLkludmFsaWRQYXNzd29yZCA6XG4gICAgICAgICAgICAgIFNjcmFwZXJFcnJvclR5cGVzLkdlbmVyYWwsXG4gICAgICAgICAgZXJyb3JNZXNzYWdlOiBgTG9naW4gZmFpbGVkIHdpdGggJHtsb2dpblJlc3VsdH0gZXJyb3JgLFxuICAgICAgICB9O1xuICAgICAgY2FzZSBMb2dpblJlc3VsdHMuQ2hhbmdlUGFzc3dvcmQ6XG4gICAgICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkNoYW5nZVBhc3N3b3JkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvclR5cGU6IFNjcmFwZXJFcnJvclR5cGVzLkNoYW5nZVBhc3N3b3JkLFxuICAgICAgICB9O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmV4cGVjdGVkIGxvZ2luIHJlc3VsdCBcIiR7bG9naW5SZXN1bHR9XCJgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHsgQmFzZVNjcmFwZXJXaXRoQnJvd3NlciB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsSUFBQUEsVUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsWUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsTUFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcscUJBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFdBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFlBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLE9BQUEsR0FBQU4sT0FBQTtBQUE2QyxTQUFBRCx1QkFBQVEsQ0FBQSxXQUFBQSxDQUFBLElBQUFB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
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy9iYXNlLXNjcmFwZXItd2l0aC1icm93c2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDBEQUEyRjtBQUMzRixnREFBc0Q7QUFDdEQsNENBQTRDO0FBQzVDLDRFQUFpRztBQUNqRyxzREFBeUU7QUFDekUsaURBQTZDO0FBQzdDLHFDQUE2QztBQUc3QyxNQUFNLEtBQUssR0FBRyxJQUFBLGdCQUFRLEVBQUMsMkJBQTJCLENBQUMsQ0FBQztBQUVwRCxJQUFLLGdCQUdKO0FBSEQsV0FBSyxnQkFBZ0I7SUFDbkIsdUNBQW1CLENBQUE7SUFDbkIsa0RBQThCLENBQUE7QUFDaEMsQ0FBQyxFQUhJLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFHcEI7QUFFRCxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsR0FBRywwQkFBaUIsQ0FBQztBQUNwRCxRQUFBLFlBQVksR0FBRztJQUMxQixHQUFHLElBQUk7SUFDUCxHQUFHLGdCQUFnQjtDQUNwQixDQUFDO0FBdUJGLEtBQUssVUFBVSxhQUFhLENBQUMsTUFBNEIsRUFBRSxLQUFhLEVBQUUsSUFBVTtJQUNsRixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2pDLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO1FBQ3RCLGFBQWE7UUFDYixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFL0IsS0FBSyxNQUFNLFNBQVMsSUFBSSxVQUFVLEVBQUU7WUFDbEMsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBRW5CLElBQUksU0FBUyxZQUFZLE1BQU0sRUFBRTtnQkFDL0IsTUFBTSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFD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QU87b0JBQ0wsT0FBTyxFQUFFLEtBQUs7b0JBQ2QsU0FBUyxFQUFFLDBCQUFpQixDQUFDLGNBQWM7aUJBQzVDLENBQUM7WUFDSjtnQkFDRSxNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixXQUFXLEdBQUcsQ0FBQyxDQUFDO1NBQy9EO0lBQ0gsQ0FBQztDQUNGO0FBRVEsd0RBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHB1cHBldGVlciwgeyB0eXBlIEZyYW1lLCB0eXBlIFBhZ2UsIHR5cGUgUHVwcGV0ZWVyTGlmZUN5Y2xlRXZlbnQgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgU2NyYXBlclByb2dyZXNzVHlwZXMgfSBmcm9tICcuLi9kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXREZWJ1ZyB9IGZyb20gJy4uL2hlbHBlcnMvZGVidWcnO1xuaW1wb3J0IHsgY2xpY2tCdXR0b24sIGZpbGxJbnB1dCwgd2FpdFVudGlsRWxlbWVudEZvdW5kIH0gZnJvbSAnLi4vaGVscGVycy9lbGVtZW50cy1pbnRlcmFjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0Q3VycmVudFVybCwgd2FpdEZvck5hdmlnYXRpb24gfSBmcm9tICcuLi9oZWxwZXJzL25hdmlnYXRpb24nO1xuaW1wb3J0IHsgQmFzZVNjcmFwZXIgfSBmcm9tICcuL2Jhc2Utc2NyYXBlcic7XG5pbXBvcnQgeyBTY3JhcGVyRXJyb3JUeXBlcyB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IHR5cGUgU2NyYXBlckNyZWRlbnRpYWxzLCB0eXBlIFNjcmFwZXJTY3JhcGluZ1Jlc3VsdCB9IGZyb20gJy4vaW50ZXJmYWNlJztcblxuY29uc3QgZGVidWcgPSBnZXREZWJ1ZygnYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3NlcicpO1xuXG5lbnVtIExvZ2luQmFzZVJlc3VsdHMge1xuICBTdWNjZXNzID0gJ1NVQ0NFU1MnLFxuICBVbmtub3duRXJyb3IgPSAnVU5LTk9XTl9FUlJPUicsXG59XG5cbmNvbnN0IHsgVGltZW91dCwgR2VuZXJpYywgR2VuZXJhbCwgLi4ucmVzdCB9ID0gU2NyYXBlckVycm9yVHlwZXM7XG5leHBvcnQgY29uc3QgTG9naW5SZXN1bHRzID0ge1xuICAuLi5yZXN0LFxuICAuLi5Mb2dpbkJhc2VSZXN1bHRzLFxufTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCB0eXBlIExvZ2luUmVzdWx0cyA9XG4gIHwgRXhjbHVkZTxTY3JhcGVyRXJyb3JUeXBlcywgU2NyYXBlckVycm9yVHlwZXMuVGltZW91dCB8IFNjcmFwZXJFcnJvclR5cGVzLkdlbmVyaWMgfCBTY3JhcGVyRXJyb3JUeXBlcy5HZW5lcmFsPlxuICB8IExvZ2luQmFzZVJlc3VsdHM7XG5cbmV4cG9ydCB0eXBlIFBvc3NpYmxlTG9naW5SZXN1bHRzID0ge1xuICBba2V5IGluIExvZ2luUmVzdWx0c10/OiAoc3RyaW5nIHwgUmVnRXhwIHwgKChvcHRpb25zPzogeyBwYWdlPzogUGFnZSB9KSA9PiBQcm9taXNlPGJvb2xlYW4+KSlbXTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9naW5PcHRpb25zIHtcbiAgbG9naW5Vcmw6IHN0cmluZztcbiAgY2hlY2tSZWFkaW5lc3M/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBmaWVsZHM6IHsgc2VsZWN0b3I6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9W107XG4gIHN1Ym1pdEJ1dHRvblNlbGVjdG9yOiBzdHJpbmcgfCAoKCkgPT4gUHJvbWlzZTx2b2lkPik7XG4gIHByZUFjdGlvbj86ICgpID0+IFByb21pc2U8RnJhbWUgfCB2b2lkPjtcbiAgcG9zdEFjdGlvbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gIHBvc3NpYmxlUmVzdWx0czogUG9zc2libGVMb2dpblJlc3VsdHM7XG4gIHVzZXJBZ2VudD86IHN0cmluZztcbiAgd2FpdFVudGlsPzogUHVwcGV0ZWVyTGlmZUN5Y2xlRXZlbnQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEtleUJ5VmFsdWUob2JqZWN0OiBQb3NzaWJsZUxvZ2luUmVzdWx0cywgdmFsdWU6IHN0cmluZywgcGFnZTogUGFnZSk6IFByb21pc2U8TG9naW5SZXN1bHRzPiB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSBvYmplY3Rba2V5XTtcblxuICAgIGZvciAoY29uc3QgY29uZGl0aW9uIG9mIGNvbmRpdGlvbnMpIHtcbiAgICAgIGxldCByZXN1bHQgPSBmYWxzZTtcblxuICAgICAgaWYgKGNvbmRpdGlvbiBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICByZXN1bHQgPSBjb25kaXRpb24udGVzdCh2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb25kaXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgY29uZGl0aW9uKHsgcGFnZSwgdmFsdWUgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSB2YWx1ZS50b0xvd2VyQ2FzZSgpID09PSBjb25kaXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoa2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKExvZ2luUmVzdWx0cy5Vbmtub3duRXJyb3IpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVHZW5lcmFsRXJyb3IoKTogU2NyYXBlclNjcmFwaW5nUmVzdWx0IHtcbiAgcmV0dXJuIHtcbiAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICBlcnJvclR5cGU6IFNjcmFwZXJFcnJvclR5cGVzLkdlbmVyYWwsXG4gIH07XG59XG5cbmNsYXNzIEJhc2VTY3JhcGVyV2l0aEJyb3dzZXI8VENyZWRlbnRpYWxzIGV4dGVuZHMgU2NyYXBlckNyZWRlbnRpYWxzPiBleHRlbmRzIEJhc2VTY3JhcGVyPFRDcmVkZW50aWFscz4ge1xuICBwcml2YXRlIGNsZWFudXBzOiBBcnJheTwoKSA9PiBQcm9taXNlPHZvaWQ+PiA9IFtdO1xuXG4gIHByaXZhdGUgZGVmYXVsdFZpZXdwb3J0U2l6ZSA9IHtcbiAgICB3aWR0aDogMTAyNCxcbiAgICBoZWlnaHQ6IDc2OCxcbiAgfTtcblxuICAvLyBOT1RJQ0UgLSBpdCBpcyBkaXNjb3VyYWdlZCB0byB1c2UgYmFuZyAoISkgaW4gZ2VuZXJhbC4gSXQgaXMgdXNlZCBoZXJlIGJlY2F1c2VcbiAgLy8gYWxsIHRoZSBjbGFzc2VzIHRoYXQgaW5oZXJpdCBmcm9tIHRoaXMgYmFzZSBhc3N1bWUgaXMgaXQgbWFuZGF0b3J5LlxuICBwcm90ZWN0ZWQgcGFnZSE6IFBhZ2U7XG5cbiAgcHJvdGVjdGVkIGdldFZpZXdQb3J0KCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMudmlld3BvcnRTaXplID8/IHRoaXMuZGVmYXVsdFZpZXdwb3J0U2l6ZTtcbiAgfVxuXG4gIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgYXdhaXQgc3VwZXIuaW5pdGlhbGl6ZSgpO1xuICAgIGRlYnVnKCdpbml0aWFsaXplIHNjcmFwZXInKTtcbiAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5Jbml0aWFsaXppbmcpO1xuXG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVBhZ2UoKTtcbiAgICBhd2FpdCBwYWdlLnNldENhY2hlRW5hYmxlZChmYWxzZSk7IC8vIENsZWFyIGNhY2hlIGFuZCBhdm9pZCAzMDAncyByZXNwb25zZSBzdGF0dXNcblxuICAgIGlmICghcGFnZSkge1xuICAgICAgZGVidWcoJ2ZhaWxlZCB0byBpbml0aWF0ZSBhIGJyb3dzZXIgcGFnZSwgZXhpdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGFnZSA9IHBhZ2U7XG5cbiAgICB0aGlzLmNsZWFudXBzLnB1c2goKCkgPT4gcGFnZS5jbG9zZSgpKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVmYXVsdFRpbWVvdXQpIHtcbiAgICAgIHRoaXMucGFnZS5zZXREZWZhdWx0VGltZW91dCh0aGlzLm9wdGlvbnMuZGVmYXVsdFRpbWVvdXQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMucHJlcGFyZVBhZ2UpIHtcbiAgICAgIGRlYnVnKFwiZXhlY3V0ZSAncHJlcGFyZVBhZ2UnIGludGVyY2VwdG9yIHByb3ZpZGVkIGluIG9wdGlvbnNcIik7XG4gICAgICBhd2FpdCB0aGlzLm9wdGlvbnMucHJlcGFyZVBhZ2UodGhpcy5wYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuZ2V0Vmlld1BvcnQoKTtcbiAgICBkZWJ1Zyhgc2V0IHZpZXdwb3J0IHRvIHdpZHRoICR7dmlld3BvcnQud2lkdGh9LCBoZWlnaHQgJHt2aWV3cG9ydC5oZWlnaHR9YCk7XG4gICAgYXdhaXQgdGhpcy5wYWdlLnNldFZpZXdwb3J0KHtcbiAgICAgIHdpZHRoOiB2aWV3cG9ydC53aWR0aCxcbiAgICAgIGhlaWdodDogdmlld3BvcnQuaGVpZ2h0LFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYWdlLm9uKCdyZXF1ZXN0ZmFpbGVkJywgcmVxdWVzdCA9PiB7XG4gICAgICBkZWJ1ZygnUmVxdWVzdCBmYWlsZWQ6ICVzICVzJywgcmVxdWVzdC5mYWlsdXJlKCk/LmVycm9yVGV4dCwgcmVxdWVzdC51cmwoKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXRpYWxpemVQYWdlKCkge1xuICAgIGRlYnVnKCdpbml0aWFsaXplIGJyb3dzZXIgcGFnZScpO1xuICAgIGlmICgnYnJvd3NlckNvbnRleHQnIGluIHRoaXMub3B0aW9ucykge1xuICAgICAgZGVidWcoJ1VzaW5nIHRoZSBicm93c2VyIGNvbnRleHQgcHJvdmlkZWQgaW4gb3B0aW9ucycpO1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5icm93c2VyQ29udGV4dC5uZXdQYWdlKCk7XG4gICAgfVxuXG4gICAgaWYgKCdicm93c2VyJyBpbiB0aGlzLm9wdGlvbnMpIHtcbiAgICAgIGRlYnVnKCdVc2luZyB0aGUgYnJvd3NlciBpbnN0YW5jZSBwcm92aWRlZCBpbiBvcHRpb25zJyk7XG4gICAgICBjb25zdCB7IGJyb3dzZXIgfSA9IHRoaXMub3B0aW9ucztcblxuICAgICAgLyoqXG4gICAgICAgKiBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgd2Ugd2lsbCBjbG9zZSB0aGUgYnJvd3NlciBldmVuIGlmIHdlIGRpZG4ndCBjcmVhdGUgaXRcbiAgICAgICAqL1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuc2tpcENsb3NlQnJvd3Nlcikge1xuICAgICAgICB0aGlzLmNsZWFudXBzLnB1c2goYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGRlYnVnKCdjbG9zaW5nIHRoZSBicm93c2VyJyk7XG4gICAgICAgICAgYXdhaXQgYnJvd3Nlci5jbG9zZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJyb3dzZXIubmV3UGFnZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdGltZW91dCwgYXJncywgZXhlY3V0YWJsZVBhdGgsIHNob3dCcm93c2VyIH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBjb25zdCBoZWFkbGVzcyA9ICFzaG93QnJvd3NlcjtcbiAgICBkZWJ1ZyhgbGF1bmNoIGEgYnJvd3NlciB3aXRoIGhlYWRsZXNzIG1vZGUgPSAke2hlYWRsZXNzfWApO1xuXG4gICAgY29uc3QgYnJvd3NlciA9IGF3YWl0IHB1cHBldGVlci5sYXVuY2goe1xuICAgICAgZW52OiB0aGlzLm9wdGlvbnMudmVyYm9zZSA/IHsgREVCVUc6ICcqJywgLi4ucHJvY2Vzcy5lbnYgfSA6IHVuZGVmaW5lZCxcbiAgICAgIGhlYWRsZXNzLFxuICAgICAgZXhlY3V0YWJsZVBhdGgsXG4gICAgICBhcmdzLFxuICAgICAgdGltZW91dCxcbiAgICB9KTtcblxuICAgIHRoaXMuY2xlYW51cHMucHVzaChhc3luYyAoKSA9PiB7XG4gICAgICBkZWJ1ZygnY2xvc2luZyB0aGUgYnJvd3NlcicpO1xuICAgICAgYXdhaXQgYnJvd3Nlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wcmVwYXJlQnJvd3Nlcikge1xuICAgICAgZGVidWcoXCJleGVjdXRlICdwcmVwYXJlQnJvd3NlcicgaW50ZXJjZXB0b3IgcHJvdmlkZWQgaW4gb3B0aW9uc1wiKTtcbiAgICAgIGF3YWl0IHRoaXMub3B0aW9ucy5wcmVwYXJlQnJvd3Nlcihicm93c2VyKTtcbiAgICB9XG5cbiAgICBkZWJ1ZygnY3JlYXRlIGEgbmV3IGJyb3dzZXIgcGFnZScpO1xuICAgIHJldHVybiBicm93c2VyLm5ld1BhZ2UoKTtcbiAgfVxuXG4gIGFzeW5jIG5hdmlnYXRlVG8oXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgd2FpdFVudGlsOiBQdXBwZXRlZXJMaWZlQ3ljbGVFdmVudCB8IHVuZGVmaW5lZCA9ICdsb2FkJyxcbiAgICByZXRyaWVzID0gdGhpcy5vcHRpb25zLm5hdmlnYXRpb25SZXRyeUNvdW50ID8/IDAsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wYWdlPy5nb3RvKHVybCwgeyB3YWl0VW50aWwgfSk7XG4gICAgaWYgKHJlc3BvbnNlID09PSBudWxsKSB7XG4gICAgICAvLyBub3RlOiByZXNwb25zZSB3aWxsIGJlIG51bGwgd2hlbiBuYXZpZ2F0aW5nIHRvIHNhbWUgdXJsIHdoaWxlIGNoYW5naW5nIHRoZSBoYXNoIHBhcnQuXG4gICAgICAvLyB0aGUgY29uZGl0aW9uIGJlbG93IHdpbGwgYWx3YXlzIGFjY2VwdCBudWxsIGFzIHZhbGlkIHJlc3VsdC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdoaWxlIHRyeWluZyB0byBuYXZpZ2F0ZSB0byB1cmwgJHt1cmx9LCByZXNwb25zZSBpcyB1bmRlZmluZWRgKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKCkpIHtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cygpO1xuICAgICAgaWYgKHJldHJpZXMgPiAwKSB7XG4gICAgICAgIGRlYnVnKGBGYWlsZWQgdG8gbmF2aWdhdGUgdG8gdXJsICR7dXJsfSwgc3RhdHVzIGNvZGU6ICR7c3RhdHVzfSwgcmV0cnlpbmcgJHtyZXRyaWVzfSBtb3JlIHRpbWVzYCk7XG4gICAgICAgIGF3YWl0IHRoaXMubmF2aWdhdGVUbyh1cmwsIHdhaXRVbnRpbCwgcmV0cmllcyAtIDEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbmF2aWdhdGUgdG8gdXJsICR7dXJsfSwgc3RhdHVzIGNvZGU6ICR7c3RhdHVzfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0TG9naW5PcHRpb25zKF9jcmVkZW50aWFsczogU2NyYXBlckNyZWRlbnRpYWxzKTogTG9naW5PcHRpb25zIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGdldExvZ2luT3B0aW9ucygpIGlzIG5vdCBjcmVhdGVkIGluICR7dGhpcy5vcHRpb25zLmNvbXBhbnlJZH1gKTtcbiAgfVxuXG4gIGFzeW5jIGZpbGxJbnB1dHMocGFnZU9yRnJhbWU6IFBhZ2UgfCBGcmFtZSwgZmllbGRzOiB7IHNlbGVjdG9yOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbW9kaWZpZWQgPSBbLi4uZmllbGRzXTtcbiAgICBjb25zdCBpbnB1dCA9IG1vZGlmaWVkLnNoaWZ0KCk7XG5cbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IGZpbGxJbnB1dChwYWdlT3JGcmFtZSwgaW5wdXQuc2VsZWN0b3IsIGlucHV0LnZhbHVlKTtcbiAgICBpZiAobW9kaWZpZWQubGVuZ3RoKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpbGxJbnB1dHMocGFnZU9yRnJhbWUsIG1vZGlmaWVkKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dpbihjcmVkZW50aWFsczogU2NyYXBlckNyZWRlbnRpYWxzKTogUHJvbWlzZTxTY3JhcGVyU2NyYXBpbmdSZXN1bHQ+IHtcbiAgICBpZiAoIWNyZWRlbnRpYWxzIHx8ICF0aGlzLnBhZ2UpIHtcbiAgICAgIHJldHVybiBjcmVhdGVHZW5lcmFsRXJyb3IoKTtcbiAgICB9XG5cbiAgICBkZWJ1ZygnZXhlY3V0ZSBsb2dpbiBwcm9jZXNzJyk7XG4gICAgY29uc3QgbG9naW5PcHRpb25zID0gdGhpcy5nZXRMb2dpbk9wdGlvbnMoY3JlZGVudGlhbHMpO1xuXG4gICAgaWYgKGxvZ2luT3B0aW9ucy51c2VyQWdlbnQpIHtcbiAgICAgIGRlYnVnKCdzZXQgY3VzdG9tIHVzZXIgYWdlbnQgcHJvdmlkZWQgaW4gb3B0aW9ucycpO1xuICAgICAgYXdhaXQgdGhpcy5wYWdlLnNldFVzZXJBZ2VudChsb2dpbk9wdGlvbnMudXNlckFnZW50KTtcbiAgICB9XG5cbiAgICBkZWJ1ZygnbmF2aWdhdGUgdG8gbG9naW4gdXJsJyk7XG4gICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvKGxvZ2luT3B0aW9ucy5sb2dpblVybCwgbG9naW5PcHRpb25zLndhaXRVbnRpbCk7XG4gICAgaWYgKGxvZ2luT3B0aW9ucy5jaGVja1JlYWRpbmVzcykge1xuICAgICAgZGVidWcoXCJleGVjdXRlICdjaGVja1JlYWRpbmVzcycgaW50ZXJjZXB0b3IgcHJvdmlkZWQgaW4gbG9naW4gb3B0aW9uc1wiKTtcbiAgICAgIGF3YWl0IGxvZ2luT3B0aW9ucy5jaGVja1JlYWRpbmVzcygpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGxvZ2luT3B0aW9ucy5zdWJtaXRCdXR0b25TZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGRlYnVnKCd3YWl0IHVudGlsIHN1Ym1pdCBidXR0b24gaXMgYXZhaWxhYmxlJyk7XG4gICAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCBsb2dpbk9wdGlvbnMuc3VibWl0QnV0dG9uU2VsZWN0b3IpO1xuICAgIH1cblxuICAgIGxldCBsb2dpbkZyYW1lT3JQYWdlOiBQYWdlIHwgRnJhbWUgfCBudWxsID0gdGhpcy5wYWdlO1xuICAgIGlmIChsb2dpbk9wdGlvbnMucHJlQWN0aW9uKSB7XG4gICAgICBkZWJ1ZyhcImV4ZWN1dGUgJ3ByZUFjdGlvbicgaW50ZXJjZXB0b3IgcHJvdmlkZWQgaW4gbG9naW4gb3B0aW9uc1wiKTtcbiAgICAgIGxvZ2luRnJhbWVPclBhZ2UgPSAoYXdhaXQgbG9naW5PcHRpb25zLnByZUFjdGlvbigpKSB8fCB0aGlzLnBhZ2U7XG4gICAgfVxuXG4gICAgZGVidWcoJ2ZpbGwgbG9naW4gY29tcG9uZW50cyBpbnB1dCB3aXRoIHJlbGV2YW50IHZhbHVlcycpO1xuICAgIGF3YWl0IHRoaXMuZmlsbElucHV0cyhsb2dpbkZyYW1lT3JQYWdlLCBsb2dpbk9wdGlvbnMuZmllbGRzKTtcbiAgICBkZWJ1ZygnY2xpY2sgb24gbG9naW4gc3VibWl0IGJ1dHRvbicpO1xuICAgIGlmICh0eXBlb2YgbG9naW5PcHRpb25zLnN1Ym1pdEJ1dHRvblNlbGVjdG9yID09PSAnc3RyaW5nJykge1xuICAgICAgYXdhaXQgY2xpY2tCdXR0b24obG9naW5GcmFtZU9yUGFnZSwgbG9naW5PcHRpb25zLnN1Ym1pdEJ1dHRvblNlbGVjdG9yKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgbG9naW5PcHRpb25zLnN1Ym1pdEJ1dHRvblNlbGVjdG9yKCk7XG4gICAgfVxuICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkxvZ2dpbmdJbik7XG5cbiAgICBpZiAobG9naW5PcHRpb25zLnBvc3RBY3Rpb24pIHtcbiAgICAgIGRlYnVnKFwiZXhlY3V0ZSAncG9zdEFjdGlvbicgaW50ZXJjZXB0b3IgcHJvdmlkZWQgaW4gbG9naW4gb3B0aW9uc1wiKTtcbiAgICAgIGF3YWl0IGxvZ2luT3B0aW9ucy5wb3N0QWN0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCd3YWl0IGZvciBwYWdlIG5hdmlnYXRpb24nKTtcbiAgICAgIGF3YWl0IHdhaXRGb3JOYXZpZ2F0aW9uKHRoaXMucGFnZSk7XG4gICAgfVxuXG4gICAgZGVidWcoJ2NoZWNrIGxvZ2luIHJlc3VsdCcpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBnZXRDdXJyZW50VXJsKHRoaXMucGFnZSwgdHJ1ZSk7XG4gICAgY29uc3QgbG9naW5SZXN1bHQgPSBhd2FpdCBnZXRLZXlCeVZhbHVlKGxvZ2luT3B0aW9ucy5wb3NzaWJsZVJlc3VsdHMsIGN1cnJlbnQsIHRoaXMucGFnZSk7XG4gICAgZGVidWcoYGhhbmRsZSBsb2dpbiByZXN1bHRzICR7bG9naW5SZXN1bHR9YCk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9naW5SZXN1bHQobG9naW5SZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgdGVybWluYXRlKF9zdWNjZXNzOiBib29sZWFuKSB7XG4gICAgZGVidWcoYHRlcm1pbmF0aW5nIGJyb3dzZXIgd2l0aCBzdWNjZXNzID0gJHtfc3VjY2Vzc31gKTtcbiAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5UZXJtaW5hdGluZyk7XG5cbiAgICBpZiAoIV9zdWNjZXNzICYmICEhdGhpcy5vcHRpb25zLnN0b3JlRmFpbHVyZVNjcmVlblNob3RQYXRoKSB7XG4gICAgICBkZWJ1ZyhgY3JlYXRlIGEgc25hcHNob3QgYmVmb3JlIHRlcm1pbmF0ZWQgaW4gJHt0aGlzLm9wdGlvbnMuc3RvcmVGYWlsdXJlU2NyZWVuU2hvdFBhdGh9YCk7XG4gICAgICBhd2FpdCB0aGlzLnBhZ2Uuc2NyZWVuc2hvdCh7XG4gICAgICAgIHBhdGg6IHRoaXMub3B0aW9ucy5zdG9yZUZhaWx1cmVTY3JlZW5TaG90UGF0aCxcbiAgICAgICAgZnVsbFBhZ2U6IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLmNsZWFudXBzLnJldmVyc2UoKS5tYXAoY2xlYW51cCA9PiBjbGVhbnVwKCkpKTtcbiAgICB0aGlzLmNsZWFudXBzID0gW107XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUxvZ2luUmVzdWx0KGxvZ2luUmVzdWx0OiBMb2dpblJlc3VsdHMpIHtcbiAgICBzd2l0Y2ggKGxvZ2luUmVzdWx0KSB7XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5TdWNjZXNzOlxuICAgICAgICB0aGlzLmVtaXRQcm9ncmVzcyhTY3JhcGVyUHJvZ3Jlc3NUeXBlcy5Mb2dpblN1Y2Nlc3MpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmQ6XG4gICAgICBjYXNlIExvZ2luUmVzdWx0cy5Vbmtub3duRXJyb3I6XG4gICAgICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkxvZ2luRmFpbGVkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvclR5cGU6XG4gICAgICAgICAgICBsb2dpblJlc3VsdCA9PT0gTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZFxuICAgICAgICAgICAgICA/IFNjcmFwZXJFcnJvclR5cGVzLkludmFsaWRQYXNzd29yZFxuICAgICAgICAgICAgICA6IFNjcmFwZXJFcnJvclR5cGVzLkdlbmVyYWwsXG4gICAgICAgICAgZXJyb3JNZXNzYWdlOiBgTG9naW4gZmFpbGVkIHdpdGggJHtsb2dpblJlc3VsdH0gZXJyb3JgLFxuICAgICAgICB9O1xuICAgICAgY2FzZSBMb2dpblJlc3VsdHMuQ2hhbmdlUGFzc3dvcmQ6XG4gICAgICAgIHRoaXMuZW1pdFByb2dyZXNzKFNjcmFwZXJQcm9ncmVzc1R5cGVzLkNoYW5nZVBhc3N3b3JkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvclR5cGU6IFNjcmFwZXJFcnJvclR5cGVzLkNoYW5nZVBhc3N3b3JkLFxuICAgICAgICB9O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmV4cGVjdGVkIGxvZ2luIHJlc3VsdCBcIiR7bG9naW5SZXN1bHR9XCJgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHsgQmFzZVNjcmFwZXJXaXRoQnJvd3NlciB9O1xuIl19