appium-remote-debugger 10.0.2 → 10.1.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.
Files changed (86) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/index.js +18 -33
  3. package/build/lib/atoms.d.ts +17 -0
  4. package/build/lib/atoms.d.ts.map +1 -0
  5. package/build/lib/atoms.js +75 -50
  6. package/build/lib/atoms.js.map +1 -1
  7. package/build/lib/logger.d.ts +3 -0
  8. package/build/lib/logger.d.ts.map +1 -0
  9. package/build/lib/logger.js +5 -11
  10. package/build/lib/logger.js.map +1 -1
  11. package/build/lib/mixins/connect.d.ts +125 -0
  12. package/build/lib/mixins/connect.d.ts.map +1 -0
  13. package/build/lib/mixins/connect.js +299 -202
  14. package/build/lib/mixins/connect.js.map +1 -1
  15. package/build/lib/mixins/events.d.ts +7 -0
  16. package/build/lib/mixins/events.d.ts.map +1 -0
  17. package/build/lib/mixins/events.js +7 -12
  18. package/build/lib/mixins/events.js.map +1 -1
  19. package/build/lib/mixins/execute.d.ts +38 -0
  20. package/build/lib/mixins/execute.d.ts.map +1 -0
  21. package/build/lib/mixins/execute.js +162 -122
  22. package/build/lib/mixins/execute.js.map +1 -1
  23. package/build/lib/mixins/index.d.ts +5 -0
  24. package/build/lib/mixins/index.d.ts.map +1 -0
  25. package/build/lib/mixins/index.js +14 -23
  26. package/build/lib/mixins/index.js.map +1 -1
  27. package/build/lib/mixins/message-handlers.d.ts +92 -0
  28. package/build/lib/mixins/message-handlers.d.ts.map +1 -0
  29. package/build/lib/mixins/message-handlers.js +160 -97
  30. package/build/lib/mixins/message-handlers.js.map +1 -1
  31. package/build/lib/mixins/navigate.d.ts +92 -0
  32. package/build/lib/mixins/navigate.d.ts.map +1 -0
  33. package/build/lib/mixins/navigate.js +199 -141
  34. package/build/lib/mixins/navigate.js.map +1 -1
  35. package/build/lib/protocol/index.d.ts +14 -0
  36. package/build/lib/protocol/index.d.ts.map +1 -0
  37. package/build/lib/protocol/index.js +192 -118
  38. package/build/lib/protocol/index.js.map +1 -1
  39. package/build/lib/remote-debugger-real-device.d.ts +6 -0
  40. package/build/lib/remote-debugger-real-device.d.ts.map +1 -0
  41. package/build/lib/remote-debugger-real-device.js +29 -32
  42. package/build/lib/remote-debugger-real-device.js.map +1 -1
  43. package/build/lib/remote-debugger.d.ts +119 -0
  44. package/build/lib/remote-debugger.d.ts.map +1 -0
  45. package/build/lib/remote-debugger.js +256 -226
  46. package/build/lib/remote-debugger.js.map +1 -1
  47. package/build/lib/rpc/index.d.ts +4 -0
  48. package/build/lib/rpc/index.d.ts.map +1 -0
  49. package/build/lib/rpc/index.js +10 -21
  50. package/build/lib/rpc/index.js.map +1 -1
  51. package/build/lib/rpc/remote-messages.d.ts +51 -0
  52. package/build/lib/rpc/remote-messages.d.ts.map +1 -0
  53. package/build/lib/rpc/remote-messages.js +203 -224
  54. package/build/lib/rpc/remote-messages.js.map +1 -1
  55. package/build/lib/rpc/rpc-client-real-device.d.ts +6 -0
  56. package/build/lib/rpc/rpc-client-real-device.d.ts.map +1 -0
  57. package/build/lib/rpc/rpc-client-real-device.js +43 -49
  58. package/build/lib/rpc/rpc-client-real-device.js.map +1 -1
  59. package/build/lib/rpc/rpc-client-simulator.d.ts +15 -0
  60. package/build/lib/rpc/rpc-client-simulator.d.ts.map +1 -0
  61. package/build/lib/rpc/rpc-client-simulator.js +138 -125
  62. package/build/lib/rpc/rpc-client-simulator.js.map +1 -1
  63. package/build/lib/rpc/rpc-client.d.ts +142 -0
  64. package/build/lib/rpc/rpc-client.d.ts.map +1 -0
  65. package/build/lib/rpc/rpc-client.js +559 -418
  66. package/build/lib/rpc/rpc-client.js.map +1 -1
  67. package/build/lib/rpc/rpc-message-handler.d.ts +13 -0
  68. package/build/lib/rpc/rpc-message-handler.d.ts.map +1 -0
  69. package/build/lib/rpc/rpc-message-handler.js +181 -166
  70. package/build/lib/rpc/rpc-message-handler.js.map +1 -1
  71. package/build/lib/utils.d.ts +61 -0
  72. package/build/lib/utils.d.ts.map +1 -0
  73. package/build/lib/utils.js +241 -155
  74. package/build/lib/utils.js.map +1 -1
  75. package/lib/atoms.js +25 -4
  76. package/lib/mixins/connect.js +102 -7
  77. package/lib/mixins/execute.js +46 -13
  78. package/lib/mixins/message-handlers.js +44 -1
  79. package/lib/mixins/navigate.js +55 -3
  80. package/lib/remote-debugger.js +112 -0
  81. package/lib/rpc/rpc-client-real-device.js +1 -6
  82. package/lib/rpc/rpc-client-simulator.js +7 -1
  83. package/lib/rpc/rpc-client.js +106 -6
  84. package/lib/rpc/rpc-message-handler.js +1 -1
  85. package/lib/utils.js +31 -1
  86. package/package.json +26 -16
@@ -1,453 +1,594 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = void 0;
8
- require("source-map-support/register");
9
- var _remoteMessages = _interopRequireDefault(require("./remote-messages"));
10
- var _asyncbox = require("asyncbox");
11
- var _logger = _interopRequireDefault(require("../logger"));
12
- var _lodash = _interopRequireDefault(require("lodash"));
13
- var _bluebird = _interopRequireDefault(require("bluebird"));
14
- var _rpcMessageHandler = _interopRequireDefault(require("./rpc-message-handler"));
15
- var _support = require("@appium/support");
16
- const DATA_LOG_LENGTH = {
17
- length: 200
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
4
  };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const remote_messages_1 = __importDefault(require("./remote-messages"));
7
+ const asyncbox_1 = require("asyncbox");
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ const bluebird_1 = __importDefault(require("bluebird"));
11
+ const rpc_message_handler_1 = __importDefault(require("./rpc-message-handler"));
12
+ const support_1 = require("@appium/support");
13
+ const DATA_LOG_LENGTH = { length: 200 };
19
14
  const WAIT_FOR_TARGET_TIMEOUT = 10000;
20
15
  const WAIT_FOR_TARGET_INTERVAL = 1000;
21
16
  const MIN_PLATFORM_FOR_TARGET_BASED = '12.2';
17
+ // `Target.exists` protocol method was removed from WebKit in 13.4
22
18
  const MIN_PLATFORM_NO_TARGET_EXISTS = '13.4';
23
19
  function isTargetBased(isSafari, platformVersion) {
24
- const isHighVersion = _support.util.compareVersions(platformVersion, '>=', MIN_PLATFORM_FOR_TARGET_BASED);
25
- _logger.default.debug(`Checking which communication style to use (${isSafari ? '' : 'non-'}Safari on platform version '${platformVersion}')`);
26
- _logger.default.debug(`Platform version equal or higher than '${MIN_PLATFORM_FOR_TARGET_BASED}': ${isHighVersion}`);
27
- return isHighVersion;
20
+ // On iOS 12.2 the messages get sent through the Target domain
21
+ // On iOS 13.0+, WKWebView also needs to follow the Target domain,
22
+ // so here only check the target OS version as the default behaviour.
23
+ const isHighVersion = support_1.util.compareVersions(platformVersion, '>=', MIN_PLATFORM_FOR_TARGET_BASED);
24
+ logger_1.default.debug(`Checking which communication style to use (${isSafari ? '' : 'non-'}Safari on platform version '${platformVersion}')`);
25
+ logger_1.default.debug(`Platform version equal or higher than '${MIN_PLATFORM_FOR_TARGET_BASED}': ${isHighVersion}`);
26
+ return isHighVersion;
28
27
  }
29
28
  class RpcClient {
30
- constructor(opts = {}) {
31
- this._targets = [];
32
- this._shouldCheckForTarget = !!opts.shouldCheckForTarget;
33
- const {
34
- bundleId,
35
- platformVersion = {},
36
- isSafari = true,
37
- logAllCommunication = false,
38
- logAllCommunicationHexDump = false,
39
- webInspectorMaxFrameLength,
40
- socketChunkSize,
41
- fullPageInitialization = false
42
- } = opts;
43
- this.isSafari = isSafari;
44
- this.isConnected = false;
45
- this.connId = _support.util.uuidV4();
46
- this.senderId = _support.util.uuidV4();
47
- this.msgId = 0;
48
- this.logAllCommunication = logAllCommunication;
49
- this.logAllCommunicationHexDump = logAllCommunicationHexDump;
50
- this.socketChunkSize = socketChunkSize;
51
- this.webInspectorMaxFrameLength = webInspectorMaxFrameLength;
52
- this.fullPageInitialization = fullPageInitialization;
53
- this.bundleId = bundleId;
54
- this.platformVersion = platformVersion;
55
- this._contexts = [];
56
- this._targets = {};
57
- this.isTargetBased = isTargetBased(isSafari, this.platformVersion);
58
- }
59
- get contexts() {
60
- return this._contexts;
61
- }
62
- get needsTarget() {
63
- return this.shouldCheckForTarget && this.isTargetBased;
64
- }
65
- get targets() {
66
- return this._targets;
67
- }
68
- get shouldCheckForTarget() {
69
- return this._shouldCheckForTarget;
70
- }
71
- set shouldCheckForTarget(shouldCheckForTarget) {
72
- this._shouldCheckForTarget = !!shouldCheckForTarget;
73
- }
74
- get isConnected() {
75
- return this.connected;
76
- }
77
- set isConnected(connected) {
78
- this.connected = !!connected;
79
- }
80
- on(event, listener) {
81
- this.messageHandler.on(event, listener);
82
- return this;
83
- }
84
- once(event, listener) {
85
- this.messageHandler.once(event, listener);
86
- return this;
87
- }
88
- off(event, listener) {
89
- this.messageHandler.off(event, listener);
90
- return this;
91
- }
92
- set isTargetBased(isTargetBased) {
93
- _logger.default.warn(`Setting communication protocol: using ${isTargetBased ? 'Target-based' : 'full Web Inspector protocol'} communication`);
94
- this._isTargetBased = isTargetBased;
95
- if (!this.remoteMessages) {
96
- this.remoteMessages = new _remoteMessages.default(isTargetBased);
97
- } else {
98
- this.remoteMessages.isTargetBased = isTargetBased;
29
+ constructor(opts = {}) {
30
+ this._targets = [];
31
+ this._shouldCheckForTarget = !!opts.shouldCheckForTarget;
32
+ const { bundleId, platformVersion = {}, isSafari = true, logAllCommunication = false, logAllCommunicationHexDump = false, webInspectorMaxFrameLength, socketChunkSize, fullPageInitialization = false, udid, } = opts;
33
+ this.isSafari = isSafari;
34
+ this.isConnected = false;
35
+ this.connId = support_1.util.uuidV4();
36
+ this.senderId = support_1.util.uuidV4();
37
+ this.msgId = 0;
38
+ this.udid = udid;
39
+ this.logAllCommunication = logAllCommunication;
40
+ this.logAllCommunicationHexDump = logAllCommunicationHexDump;
41
+ this.socketChunkSize = socketChunkSize;
42
+ this.webInspectorMaxFrameLength = webInspectorMaxFrameLength;
43
+ this.fullPageInitialization = fullPageInitialization;
44
+ this.bundleId = bundleId;
45
+ this.platformVersion = platformVersion;
46
+ this._contexts = [];
47
+ this._targets = {};
48
+ // start with a best guess for the protocol
49
+ this.isTargetBased = isTargetBased(isSafari, this.platformVersion);
99
50
  }
100
- if (!this.messageHandler) {
101
- this.messageHandler = new _rpcMessageHandler.default(isTargetBased);
102
- this.messageHandler.on('Target.targetCreated', this.addTarget.bind(this));
103
- this.messageHandler.on('Target.didCommitProvisionalTarget', this.updateTarget.bind(this));
104
- this.messageHandler.on('Target.targetDestroyed', this.removeTarget.bind(this));
105
- this.messageHandler.on('Runtime.executionContextCreated', this.onExecutionContextCreated.bind(this));
106
- this.messageHandler.on('Heap.garbageCollected', this.onGarbageCollected.bind(this));
107
- } else {
108
- this.messageHandler.isTargetBased = isTargetBased;
51
+ get contexts() {
52
+ return this._contexts;
109
53
  }
110
- }
111
- get isTargetBased() {
112
- return this._isTargetBased;
113
- }
114
- async waitForTarget(appIdKey, pageIdKey, force = false) {
115
- if (!force && !this.needsTarget) {
116
- return;
54
+ get needsTarget() {
55
+ return this.shouldCheckForTarget && this.isTargetBased;
117
56
  }
118
- if (this.getTarget(appIdKey, pageIdKey)) {
119
- return;
57
+ get targets() {
58
+ return this._targets;
120
59
  }
121
- try {
122
- await (0, _asyncbox.waitForCondition)(() => !_lodash.default.isEmpty(this.getTarget(appIdKey, pageIdKey)), {
123
- waitMs: WAIT_FOR_TARGET_TIMEOUT,
124
- intervalMs: WAIT_FOR_TARGET_INTERVAL,
125
- error: 'No targets found, unable to communicate with device'
126
- });
127
- } catch (err) {
128
- if (!err.message.includes('Condition unmet')) {
129
- throw err;
130
- }
131
- throw new Error('No targets found, unable to communicate with device');
60
+ get shouldCheckForTarget() {
61
+ return this._shouldCheckForTarget;
132
62
  }
133
- }
134
- async send(command, opts = {}, waitForResponse = true) {
135
- const timer = new _support.timing.Timer().start();
136
- const {
137
- appIdKey,
138
- pageIdKey
139
- } = opts;
140
- try {
141
- if (!_lodash.default.isEmpty(appIdKey) && !_lodash.default.isEmpty(pageIdKey)) {
142
- await this.waitForTarget(appIdKey, pageIdKey);
143
- }
144
- return await this.sendToDevice(command, opts, waitForResponse);
145
- } catch (err) {
146
- let {
147
- message = ''
148
- } = err;
149
- message = message.toLowerCase();
150
- if (message.includes(`'target' domain was not found`)) {
151
- _logger.default.info('The target device does not support Target based communication. ' + 'Will follow non-target based communication.');
152
- this.isTargetBased = false;
153
- return await this.sendToDevice(command, opts, waitForResponse);
154
- } else if (message.includes(`domain was not found`) || message.includes(`some arguments of method`) || message.includes(`missing target`)) {
155
- this.isTargetBased = true;
156
- await this.waitForTarget(appIdKey, pageIdKey);
157
- return await this.sendToDevice(command, opts, waitForResponse);
158
- }
159
- throw err;
160
- } finally {
161
- _logger.default.debug(`Sending to Web Inspector took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
63
+ set shouldCheckForTarget(shouldCheckForTarget) {
64
+ this._shouldCheckForTarget = !!shouldCheckForTarget;
162
65
  }
163
- }
164
- async sendToDevice(command, opts = {}, waitForResponse = true) {
165
- return await new _bluebird.default(async (resolve, reject) => {
166
- var _cmd$__argument, _cmd$__argument2;
167
- const msgId = this.msgId++;
168
- let wrapperMsgId = msgId;
169
- if (this.isTargetBased) {
170
- wrapperMsgId = this.msgId++;
171
- this.messageHandler.on(wrapperMsgId.toString(), function (err) {
172
- if (err) {
173
- reject(err);
174
- }
175
- });
176
- }
177
- const appIdKey = opts.appIdKey;
178
- const pageIdKey = opts.pageIdKey;
179
- const targetId = this.getTarget(appIdKey, pageIdKey);
180
- const fullOpts = _lodash.default.defaults({
181
- connId: this.connId,
182
- senderId: this.senderId,
183
- targetId,
184
- id: msgId
185
- }, opts);
186
- const cmd = this.remoteMessages.getRemoteCommand(command, fullOpts);
187
- if (cmd !== null && cmd !== void 0 && (_cmd$__argument = cmd.__argument) !== null && _cmd$__argument !== void 0 && _cmd$__argument.WIRSocketDataKey) {
188
- if (_lodash.default.isNil(cmd.__argument.WIRSocketDataKey.id)) {
189
- cmd.__argument.WIRSocketDataKey.id = wrapperMsgId;
66
+ get isConnected() {
67
+ return this.connected;
68
+ }
69
+ set isConnected(connected) {
70
+ this.connected = !!connected;
71
+ }
72
+ on(event, listener) {
73
+ // @ts-ignore messageHandler must be defined here
74
+ this.messageHandler.on(event, listener);
75
+ return this;
76
+ }
77
+ once(event, listener) {
78
+ // @ts-ignore messageHandler must be defined here
79
+ this.messageHandler.once(event, listener);
80
+ return this;
81
+ }
82
+ off(event, listener) {
83
+ // @ts-ignore messageHandler must be defined here
84
+ this.messageHandler.off(event, listener);
85
+ return this;
86
+ }
87
+ set isTargetBased(isTargetBased) {
88
+ logger_1.default.warn(`Setting communication protocol: using ${isTargetBased ? 'Target-based' : 'full Web Inspector protocol'} communication`);
89
+ this._isTargetBased = isTargetBased;
90
+ if (!this.remoteMessages) {
91
+ this.remoteMessages = new remote_messages_1.default(isTargetBased);
190
92
  }
191
- cmd.__argument.WIRSocketDataKey = Buffer.from(JSON.stringify(cmd.__argument.WIRSocketDataKey));
192
- }
193
- let messageHandled = true;
194
- if (!waitForResponse) {
195
- messageHandled = false;
196
- this.messageHandler.once(msgId.toString(), function (err) {
197
- if (err) {
198
- _logger.default.error(`Received error from send that is not being waited for (id: ${msgId}): '${_lodash.default.truncate(JSON.stringify(err), DATA_LOG_LENGTH)}'`);
199
- reject(err);
200
- }
201
- });
202
- } else if (this.messageHandler.listeners(cmd.__selector).length) {
203
- this.messageHandler.prependOnceListener(cmd.__selector, function (err, ...args) {
204
- if (err) {
205
- return reject(err);
206
- }
207
- _logger.default.debug(`Received response from send (id: ${msgId}): '${_lodash.default.truncate(JSON.stringify(args), DATA_LOG_LENGTH)}'`);
208
- resolve(args);
209
- });
210
- } else if (cmd !== null && cmd !== void 0 && (_cmd$__argument2 = cmd.__argument) !== null && _cmd$__argument2 !== void 0 && _cmd$__argument2.WIRSocketDataKey) {
211
- this.messageHandler.once(msgId.toString(), function (err, value) {
212
- if (err) {
213
- return reject(new Error(`Remote debugger error with code '${err.code}': ${err.message}`));
214
- }
215
- _logger.default.debug(`Received data response from send (id: ${msgId}): '${_lodash.default.truncate(JSON.stringify(value), DATA_LOG_LENGTH)}'`);
216
- resolve(value);
217
- });
218
- } else {
219
- messageHandled = false;
220
- }
221
- const msg = `Sending '${cmd.__selector}' message` + (fullOpts.appIdKey ? ` to app '${fullOpts.appIdKey}'` : '') + (fullOpts.pageIdKey ? `, page '${fullOpts.pageIdKey}'` : '') + (this.needsTarget && targetId ? `, target '${targetId}'` : '') + ` (id: ${msgId}): '${command}'`;
222
- _logger.default.debug(msg);
223
- try {
224
- const res = await this.sendMessage(cmd);
225
- if (!messageHandled) {
226
- resolve(res);
93
+ else {
94
+ this.remoteMessages.isTargetBased = isTargetBased;
95
+ }
96
+ if (!this.messageHandler) {
97
+ this.messageHandler = new rpc_message_handler_1.default(isTargetBased);
98
+ // add handlers for internal events
99
+ this.messageHandler.on('Target.targetCreated', this.addTarget.bind(this));
100
+ this.messageHandler.on('Target.didCommitProvisionalTarget', this.updateTarget.bind(this));
101
+ this.messageHandler.on('Target.targetDestroyed', this.removeTarget.bind(this));
102
+ this.messageHandler.on('Runtime.executionContextCreated', this.onExecutionContextCreated.bind(this));
103
+ this.messageHandler.on('Heap.garbageCollected', this.onGarbageCollected.bind(this));
104
+ }
105
+ else {
106
+ this.messageHandler.isTargetBased = isTargetBased;
227
107
  }
228
- } catch (err) {
229
- return reject(err);
230
- }
231
- });
232
- }
233
- async connect() {
234
- throw new Error(`Sub-classes need to implement a 'connect' function`);
235
- }
236
- async disconnect() {
237
- this.messageHandler.removeAllListeners();
238
- }
239
- async sendMessage() {
240
- throw new Error(`Sub-classes need to implement a 'sendMessage' function`);
241
- }
242
- async receive() {
243
- throw new Error(`Sub-classes need to implement a 'receive' function`);
244
- }
245
- addTarget(err, app, targetInfo) {
246
- if (_lodash.default.isNil(targetInfo === null || targetInfo === void 0 ? void 0 : targetInfo.targetId)) {
247
- _logger.default.warn(`Received 'Target.targetCreated' event for app '${app}' with no target. Skipping`);
248
- return;
249
108
  }
250
- if (_lodash.default.isEmpty(this.pendingTargetNotification) && !targetInfo.isProvisional) {
251
- _logger.default.warn(`Received 'Target.targetCreated' event for app '${app}' with no pending request: ${JSON.stringify(targetInfo)}`);
252
- return;
109
+ get isTargetBased() {
110
+ return this._isTargetBased;
253
111
  }
254
- if (targetInfo.isProvisional) {
255
- _logger.default.debug(`Provisional target created for app '${app}', '${targetInfo.targetId}'. Ignoring until target update event`);
256
- return;
112
+ /**
113
+ *
114
+ * @param {string} appIdKey
115
+ * @param {string} pageIdKey
116
+ * @param {boolean} [force]
117
+ * @returns {Promise<void>}
118
+ */
119
+ async waitForTarget(appIdKey, pageIdKey, force = false) {
120
+ if (!force && !this.needsTarget) {
121
+ return;
122
+ }
123
+ if (this.getTarget(appIdKey, pageIdKey)) {
124
+ return;
125
+ }
126
+ // otherwise waiting is necessary to see what the target is
127
+ try {
128
+ await (0, asyncbox_1.waitForCondition)(() => !lodash_1.default.isEmpty(this.getTarget(appIdKey, pageIdKey)), {
129
+ waitMs: WAIT_FOR_TARGET_TIMEOUT,
130
+ intervalMs: WAIT_FOR_TARGET_INTERVAL,
131
+ error: 'No targets found, unable to communicate with device',
132
+ });
133
+ }
134
+ catch (err) {
135
+ if (!err.message.includes('Condition unmet')) {
136
+ throw err;
137
+ }
138
+ throw new Error('No targets found, unable to communicate with device');
139
+ }
257
140
  }
258
- const [appIdKey, pageIdKey] = this.pendingTargetNotification;
259
- _logger.default.debug(`Target created for app '${appIdKey}' and page '${pageIdKey}': ${JSON.stringify(targetInfo)}`);
260
- if (_lodash.default.has(this.targets[appIdKey], pageIdKey)) {
261
- _logger.default.debug(`There is already a target for this app and page ('${this.targets[appIdKey][pageIdKey]}'). This might cause problems`);
141
+ /**
142
+ *
143
+ * @param {string} command
144
+ * @param {Record<string, any>} [opts]
145
+ * @param {boolean} [waitForResponse]
146
+ * @returns {Promise<any>}
147
+ */
148
+ async send(command, opts = {}, waitForResponse = true) {
149
+ const timer = new support_1.timing.Timer().start();
150
+ const { appIdKey, pageIdKey } = opts;
151
+ try {
152
+ if (!lodash_1.default.isEmpty(appIdKey) && !lodash_1.default.isEmpty(pageIdKey)) {
153
+ await this.waitForTarget(appIdKey, pageIdKey);
154
+ }
155
+ return await this.sendToDevice(command, opts, waitForResponse);
156
+ }
157
+ catch (err) {
158
+ let { message = '' } = err;
159
+ message = message.toLowerCase();
160
+ if (message.includes(`'target' domain was not found`)) {
161
+ logger_1.default.info('The target device does not support Target based communication. ' +
162
+ 'Will follow non-target based communication.');
163
+ this.isTargetBased = false;
164
+ return await this.sendToDevice(command, opts, waitForResponse);
165
+ }
166
+ else if (message.includes(`domain was not found`) ||
167
+ message.includes(`some arguments of method`) ||
168
+ message.includes(`missing target`)) {
169
+ this.isTargetBased = true;
170
+ await this.waitForTarget(appIdKey, pageIdKey);
171
+ return await this.sendToDevice(command, opts, waitForResponse);
172
+ }
173
+ throw err;
174
+ }
175
+ finally {
176
+ logger_1.default.debug(`Sending to Web Inspector took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
177
+ }
262
178
  }
263
- this.targets[app] = this.targets[app] || {};
264
- this.targets[appIdKey][pageIdKey] = targetInfo.targetId;
265
- }
266
- updateTarget(err, app, oldTargetId, newTargetId) {
267
- _logger.default.debug(`Target updated for app '${app}'. Old target: '${oldTargetId}', new target: '${newTargetId}'`);
268
- if (!this.targets[app]) {
269
- _logger.default.warn(`No existing target for app '${app}'. Not sure what to do`);
270
- return;
179
+ /**
180
+ *
181
+ * @param {string} command
182
+ * @param {Record<string, any>} opts
183
+ * @param {boolean} [waitForResponse]
184
+ * @returns {Promise<any>}
185
+ */
186
+ async sendToDevice(command, opts = {}, waitForResponse = true) {
187
+ return await new bluebird_1.default(async (resolve, reject) => {
188
+ // promise to be resolved whenever remote debugger
189
+ // replies to our request
190
+ // keep track of the messages coming and going using a simple sequential id
191
+ const msgId = this.msgId++;
192
+ let wrapperMsgId = msgId;
193
+ if (this.isTargetBased) {
194
+ // for target-base communication, everything is wrapped up
195
+ wrapperMsgId = this.msgId++;
196
+ // acknowledge wrapper message
197
+ // @ts-ignore messageHandler must be defined
198
+ this.messageHandler.on(wrapperMsgId.toString(), function (err) {
199
+ if (err) {
200
+ reject(err);
201
+ }
202
+ });
203
+ }
204
+ const appIdKey = opts.appIdKey;
205
+ const pageIdKey = opts.pageIdKey;
206
+ const targetId = this.getTarget(appIdKey, pageIdKey);
207
+ // retrieve the correct command to send
208
+ const fullOpts = lodash_1.default.defaults({
209
+ connId: this.connId,
210
+ senderId: this.senderId,
211
+ targetId,
212
+ id: msgId,
213
+ }, opts);
214
+ // @ts-ignore remoteMessages must be defined
215
+ const cmd = this.remoteMessages.getRemoteCommand(command, fullOpts);
216
+ if (cmd?.__argument?.WIRSocketDataKey) {
217
+ // make sure the message being sent has all the information that is needed
218
+ if (lodash_1.default.isNil(cmd.__argument.WIRSocketDataKey.id)) {
219
+ cmd.__argument.WIRSocketDataKey.id = wrapperMsgId;
220
+ }
221
+ cmd.__argument.WIRSocketDataKey =
222
+ Buffer.from(JSON.stringify(cmd.__argument.WIRSocketDataKey));
223
+ }
224
+ let messageHandled = true;
225
+ if (!waitForResponse) {
226
+ // the promise will be resolved as soon as the socket has been sent
227
+ messageHandled = false;
228
+ // do not log receipts
229
+ // @ts-ignore messageHandler must be defined
230
+ this.messageHandler.once(msgId.toString(), function (err) {
231
+ if (err) {
232
+ // we are not waiting for this, and if it errors it is most likely
233
+ // a protocol change. Log and check during testing
234
+ logger_1.default.error(`Received error from send that is not being waited for (id: ${msgId}): '${lodash_1.default.truncate(JSON.stringify(err), DATA_LOG_LENGTH)}'`);
235
+ // reject, though it is very rare that this will be triggered, since
236
+ // the promise is resolved directlty after send. On the off chance,
237
+ // though, it will alert of a protocol change.
238
+ reject(err);
239
+ }
240
+ });
241
+ // @ts-ignore messageHandler must be defined
242
+ }
243
+ else if (this.messageHandler.listeners(cmd.__selector).length) {
244
+ // @ts-ignore messageHandler must be defined
245
+ this.messageHandler.prependOnceListener(cmd.__selector, function (err, ...args) {
246
+ if (err) {
247
+ return reject(err);
248
+ }
249
+ logger_1.default.debug(`Received response from send (id: ${msgId}): '${lodash_1.default.truncate(JSON.stringify(args), DATA_LOG_LENGTH)}'`);
250
+ resolve(args);
251
+ });
252
+ }
253
+ else if (cmd?.__argument?.WIRSocketDataKey) {
254
+ // @ts-ignore messageHandler must be defined
255
+ this.messageHandler.once(msgId.toString(), function (err, value) {
256
+ if (err) {
257
+ return reject(new Error(`Remote debugger error with code '${err.code}': ${err.message}`));
258
+ }
259
+ logger_1.default.debug(`Received data response from send (id: ${msgId}): '${lodash_1.default.truncate(JSON.stringify(value), DATA_LOG_LENGTH)}'`);
260
+ resolve(value);
261
+ });
262
+ }
263
+ else {
264
+ // nothing else is handling things, so just resolve when the message is sent
265
+ messageHandled = false;
266
+ }
267
+ const msg = `Sending '${cmd.__selector}' message` +
268
+ (appIdKey ? ` to app '${appIdKey}'` : '') +
269
+ (pageIdKey ? `, page '${pageIdKey}'` : '') +
270
+ (this.needsTarget && targetId ? `, target '${targetId}'` : '') +
271
+ ` (id: ${msgId}): '${command}'`;
272
+ logger_1.default.debug(msg);
273
+ try {
274
+ const res = await this.sendMessage(cmd);
275
+ if (!messageHandled) {
276
+ // There are no handlers waiting for a response before resolving,
277
+ // and no errors sending the message over the socket, so resolve
278
+ resolve(res);
279
+ }
280
+ }
281
+ catch (err) {
282
+ return reject(err);
283
+ }
284
+ });
271
285
  }
272
- this.targets[app].provisional = {
273
- oldTargetId,
274
- newTargetId
275
- };
276
- }
277
- removeTarget(err, app, targetInfo) {
278
- var _this$targets$app;
279
- if (_lodash.default.isNil(targetInfo === null || targetInfo === void 0 ? void 0 : targetInfo.targetId)) {
280
- _logger.default.debug(`Received 'Target.targetDestroyed' event with no target. Skipping`);
281
- return;
286
+ async connect() {
287
+ throw new Error(`Sub-classes need to implement a 'connect' function`);
282
288
  }
283
- _logger.default.debug(`Target destroyed for app '${app}': ${targetInfo.targetId}`);
284
- if (((_this$targets$app = this.targets[app]) === null || _this$targets$app === void 0 || (_this$targets$app = _this$targets$app.provisional) === null || _this$targets$app === void 0 ? void 0 : _this$targets$app.oldTargetId) === targetInfo.targetId) {
285
- const {
286
- oldTargetId,
287
- newTargetId
288
- } = this.targets[app].provisional;
289
- delete this.targets[app].provisional;
290
- const targets = this.targets[app];
291
- for (const [page, targetId] of _lodash.default.toPairs(targets)) {
292
- if (targetId === oldTargetId) {
293
- _logger.default.debug(`Found provisional target for app '${app}'. Old target: '${oldTargetId}', new target: '${newTargetId}'. Updating`);
294
- targets[page] = newTargetId;
295
- return;
296
- }
297
- }
298
- _logger.default.warn(`Provisional target for app '${app}' found, but no suitable existing target found. This may cause problems`);
299
- _logger.default.warn(`Old target: '${oldTargetId}', new target: '${newTargetId}'. Existing targets: ${JSON.stringify(targets)}`);
289
+ async disconnect() {
290
+ this.messageHandler?.removeAllListeners();
291
+ }
292
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
293
+ async sendMessage(command) {
294
+ throw new Error(`Sub-classes need to implement a 'sendMessage' function`);
300
295
  }
301
- const targets = this.targets[app];
302
- for (const [page, targetId] of _lodash.default.toPairs(targets)) {
303
- if (targetId === targetInfo.targetId) {
304
- delete targets[page];
305
- return;
306
- }
296
+ async receive( /* data */) {
297
+ throw new Error(`Sub-classes need to implement a 'receive' function`);
307
298
  }
308
- _logger.default.debug(`Target '${targetInfo.targetId}' deleted for app '${app}', but no such target exists`);
309
- }
310
- getTarget(appIdKey, pageIdKey) {
311
- return (this.targets[appIdKey] || {})[pageIdKey];
312
- }
313
- async selectPage(appIdKey, pageIdKey) {
314
- this.pendingTargetNotification = [appIdKey, pageIdKey];
315
- this.shouldCheckForTarget = false;
316
- const sendOpts = {
317
- appIdKey,
318
- pageIdKey
319
- };
320
- for (const enabled of [true, false]) {
321
- await this.send('indicateWebView', Object.assign({
322
- enabled
323
- }, sendOpts), false);
299
+ /**
300
+ *
301
+ * @param {Error?} err
302
+ * @param {string} app
303
+ * @param {Record<string, any>} targetInfo
304
+ * @returns {void}
305
+ */
306
+ addTarget(err, app, targetInfo) {
307
+ if (lodash_1.default.isNil(targetInfo?.targetId)) {
308
+ logger_1.default.warn(`Received 'Target.targetCreated' event for app '${app}' with no target. Skipping`);
309
+ return;
310
+ }
311
+ if (lodash_1.default.isEmpty(this.pendingTargetNotification) && !targetInfo.isProvisional) {
312
+ logger_1.default.warn(`Received 'Target.targetCreated' event for app '${app}' with no pending request: ${JSON.stringify(targetInfo)}`);
313
+ return;
314
+ }
315
+ if (targetInfo.isProvisional) {
316
+ logger_1.default.debug(`Provisional target created for app '${app}', '${targetInfo.targetId}'. Ignoring until target update event`);
317
+ return;
318
+ }
319
+ // @ts-ignore this.pendingTargetNotification must be defined here
320
+ const [appIdKey, pageIdKey] = this.pendingTargetNotification;
321
+ logger_1.default.debug(`Target created for app '${appIdKey}' and page '${pageIdKey}': ${JSON.stringify(targetInfo)}`);
322
+ if (lodash_1.default.has(this.targets[appIdKey], pageIdKey)) {
323
+ logger_1.default.debug(`There is already a target for this app and page ('${this.targets[appIdKey][pageIdKey]}'). This might cause problems`);
324
+ }
325
+ this.targets[app] = this.targets[app] || {};
326
+ this.targets[appIdKey][pageIdKey] = targetInfo.targetId;
324
327
  }
325
- await this.send('setSenderKey', sendOpts);
326
- _logger.default.debug('Sender key set');
327
- if (this.isTargetBased && _support.util.compareVersions(this.platformVersion, '<', MIN_PLATFORM_NO_TARGET_EXISTS)) {
328
- await this.send('Target.exists', sendOpts, false);
328
+ /**
329
+ *
330
+ * @param {Error?} err
331
+ * @param {string} app
332
+ * @param {string} oldTargetId
333
+ * @param {string} newTargetId
334
+ * @returns {void}
335
+ */
336
+ updateTarget(err, app, oldTargetId, newTargetId) {
337
+ logger_1.default.debug(`Target updated for app '${app}'. Old target: '${oldTargetId}', new target: '${newTargetId}'`);
338
+ if (!this.targets[app]) {
339
+ logger_1.default.warn(`No existing target for app '${app}'. Not sure what to do`);
340
+ return;
341
+ }
342
+ // save this, to be used if/when the existing target is destroyed
343
+ this.targets[app].provisional = {
344
+ oldTargetId,
345
+ newTargetId,
346
+ };
329
347
  }
330
- this.shouldCheckForTarget = true;
331
- if (this.fullPageInitialization) {
332
- await this.initializePageFull(appIdKey, pageIdKey);
333
- } else {
334
- await this.initializePage(appIdKey, pageIdKey);
348
+ /**
349
+ *
350
+ * @param {Error?} err
351
+ * @param {string} app
352
+ * @param {Record<string, any>} targetInfo
353
+ * @returns {void}
354
+ */
355
+ removeTarget(err, app, targetInfo) {
356
+ if (lodash_1.default.isNil(targetInfo?.targetId)) {
357
+ logger_1.default.debug(`Received 'Target.targetDestroyed' event with no target. Skipping`);
358
+ return;
359
+ }
360
+ logger_1.default.debug(`Target destroyed for app '${app}': ${targetInfo.targetId}`);
361
+ // go through the targets and find the one that has a waiting provisional target
362
+ if (this.targets[app]?.provisional?.oldTargetId === targetInfo.targetId) {
363
+ const { oldTargetId, newTargetId } = this.targets[app].provisional;
364
+ delete this.targets[app].provisional;
365
+ // we do not know the page, so go through and find the existing target
366
+ const targets = this.targets[app];
367
+ for (const [page, targetId] of lodash_1.default.toPairs(targets)) {
368
+ if (targetId === oldTargetId) {
369
+ logger_1.default.debug(`Found provisional target for app '${app}'. Old target: '${oldTargetId}', new target: '${newTargetId}'. Updating`);
370
+ targets[page] = newTargetId;
371
+ return;
372
+ }
373
+ }
374
+ logger_1.default.warn(`Provisional target for app '${app}' found, but no suitable existing target found. This may cause problems`);
375
+ logger_1.default.warn(`Old target: '${oldTargetId}', new target: '${newTargetId}'. Existing targets: ${JSON.stringify(targets)}`);
376
+ }
377
+ // if there is no waiting provisional target, just get rid of the existing one
378
+ const targets = this.targets[app];
379
+ for (const [page, targetId] of lodash_1.default.toPairs(targets)) {
380
+ if (targetId === targetInfo.targetId) {
381
+ delete targets[page];
382
+ return;
383
+ }
384
+ }
385
+ logger_1.default.debug(`Target '${targetInfo.targetId}' deleted for app '${app}', but no such target exists`);
335
386
  }
336
- }
337
- async initializePage(appIdKey, pageIdKey) {
338
- const sendOpts = {
339
- appIdKey,
340
- pageIdKey
341
- };
342
- await this.send('Inspector.enable', sendOpts, false);
343
- await this.send('Page.enable', sendOpts, false);
344
- await this.send('Network.enable', sendOpts, false);
345
- await this.send('Runtime.enable', sendOpts, false);
346
- await this.send('Heap.enable', sendOpts, false);
347
- await this.send('Debugger.enable', sendOpts, false);
348
- await this.send('Console.enable', sendOpts, false);
349
- await this.send('Inspector.initialized', sendOpts, false);
350
- }
351
- async initializePageFull(appIdKey, pageIdKey) {
352
- const sendOpts = {
353
- appIdKey,
354
- pageIdKey
355
- };
356
- await this.send('Inspector.enable', sendOpts, false);
357
- await this.send('Page.enable', sendOpts, false);
358
- await this.send('Page.getResourceTree', sendOpts, false);
359
- await this.send('Network.enable', sendOpts, false);
360
- await this.send('Network.setResourceCachingDisabled', Object.assign({
361
- disabled: false
362
- }, sendOpts), false);
363
- await this.send('DOMStorage.enable', sendOpts, false);
364
- await this.send('Database.enable', sendOpts, false);
365
- await this.send('IndexedDB.enable', sendOpts, false);
366
- await this.send('CSS.enable', sendOpts, false);
367
- await this.send('Runtime.enable', sendOpts, false);
368
- await this.send('Heap.enable', sendOpts, false);
369
- await this.send('Memory.enable', sendOpts, false);
370
- await this.send('ApplicationCache.enable', sendOpts, false);
371
- await this.send('ApplicationCache.getFramesWithManifests', sendOpts, false);
372
- await this.send('Timeline.setInstruments', Object.assign({
373
- instruments: ['Timeline', 'ScriptProfiler', 'CPU']
374
- }, sendOpts), false);
375
- await this.send('Timeline.setAutoCaptureEnabled', Object.assign({
376
- enabled: false
377
- }, sendOpts), false);
378
- await this.send('Debugger.enable', sendOpts, false);
379
- await this.send('Debugger.setBreakpointsActive', Object.assign({
380
- active: true
381
- }, sendOpts), false);
382
- await this.send('Debugger.setPauseOnExceptions', Object.assign({
383
- state: 'none'
384
- }, sendOpts), false);
385
- await this.send('Debugger.setPauseOnAssertions', Object.assign({
386
- enabled: false
387
- }, sendOpts), false);
388
- await this.send('Debugger.setAsyncStackTraceDepth', Object.assign({
389
- depth: 200
390
- }, sendOpts), false);
391
- await this.send('Debugger.setPauseForInternalScripts', Object.assign({
392
- shouldPause: false
393
- }, sendOpts), false);
394
- await this.send('LayerTree.enable', sendOpts, false);
395
- await this.send('Worker.enable', sendOpts, false);
396
- await this.send('Canvas.enable', sendOpts, false);
397
- await this.send('Console.enable', sendOpts, false);
398
- await this.send('DOM.getDocument', sendOpts, false);
399
- const loggingChannels = await this.send('Console.getLoggingChannels', sendOpts);
400
- for (const source of (loggingChannels.channels || []).map(entry => entry.source)) {
401
- await this.send('Console.setLoggingChannelLevel', Object.assign({
402
- source,
403
- level: 'verbose'
404
- }, sendOpts), false);
387
+ /**
388
+ * @param {string} appIdKey
389
+ * @param {string} pageIdKey
390
+ * @returns {any}
391
+ */
392
+ getTarget(appIdKey, pageIdKey) {
393
+ return (this.targets[appIdKey] || {})[pageIdKey];
405
394
  }
406
- await this.send('Inspector.initialized', sendOpts, false);
407
- }
408
- async selectApp(appIdKey) {
409
- return await new _bluebird.default((resolve, reject) => {
410
- const onAppChange = (err, dict) => {
411
- if (err) {
412
- return reject(err);
395
+ /**
396
+ * @param {string} appIdKey
397
+ * @param {string} pageIdKey
398
+ * @returns {Promise<void>}
399
+ */
400
+ async selectPage(appIdKey, pageIdKey) {
401
+ /** @type {[string, string]} */
402
+ this.pendingTargetNotification = [appIdKey, pageIdKey];
403
+ this.shouldCheckForTarget = false;
404
+ // go through the steps that the Desktop Safari system
405
+ // goes through to initialize the Web Inspector session
406
+ const sendOpts = {
407
+ appIdKey,
408
+ pageIdKey,
409
+ };
410
+ // highlight and then un-highlight the webview
411
+ for (const enabled of [true, false]) {
412
+ await this.send('indicateWebView', Object.assign({
413
+ enabled,
414
+ }, sendOpts), false);
413
415
  }
414
- const oldAppIdKey = dict.WIRHostApplicationIdentifierKey;
415
- const correctAppIdKey = dict.WIRApplicationIdentifierKey;
416
- if (oldAppIdKey && correctAppIdKey !== oldAppIdKey) {
417
- _logger.default.debug(`We were notified we might have connected to the wrong app. ` + `Using id ${correctAppIdKey} instead of ${oldAppIdKey}`);
416
+ await this.send('setSenderKey', sendOpts);
417
+ logger_1.default.debug('Sender key set');
418
+ if (this.isTargetBased && support_1.util.compareVersions(this.platformVersion, '<', MIN_PLATFORM_NO_TARGET_EXISTS)) {
419
+ await this.send('Target.exists', sendOpts, false);
418
420
  }
419
- reject(new Error('New application has connected'));
420
- };
421
- this.messageHandler.prependOnceListener('_rpc_applicationConnected:', onAppChange);
422
- return (async () => {
423
- let pageDict, connectedAppIdKey;
424
- try {
425
- [connectedAppIdKey, pageDict] = await this.send('connectToApp', {
426
- appIdKey
427
- });
428
- } catch (err) {
429
- _logger.default.warn(`Unable to connect to app: ${err.message}`);
430
- reject(err);
421
+ this.shouldCheckForTarget = true;
422
+ if (this.fullPageInitialization) {
423
+ await this.initializePageFull(appIdKey, pageIdKey);
431
424
  }
432
- if (_lodash.default.isEmpty(pageDict)) {
433
- let msg = 'Empty page dictionary received';
434
- _logger.default.debug(msg);
435
- reject(new Error(msg));
436
- } else {
437
- resolve([connectedAppIdKey, pageDict]);
425
+ else {
426
+ await this.initializePage(appIdKey, pageIdKey);
438
427
  }
439
- })();
440
- });
441
- }
442
- onExecutionContextCreated(err, context) {
443
- this.contexts.push(context.id);
444
- }
445
- onGarbageCollected() {
446
- _logger.default.debug(`Web Inspector garbage collected`);
447
- }
448
- onScriptParsed(err, scriptInfo) {
449
- _logger.default.debug(`Script parsed: ${JSON.stringify(scriptInfo)}`);
450
- }
428
+ }
429
+ /**
430
+ * Perform the minimal initialization to get the Web Inspector working
431
+ * @param {string} appIdKey
432
+ * @param {string} pageIdKey
433
+ * @returns {Promise<void>}
434
+ */
435
+ async initializePage(appIdKey, pageIdKey) {
436
+ const sendOpts = {
437
+ appIdKey,
438
+ pageIdKey,
439
+ };
440
+ await this.send('Inspector.enable', sendOpts, false);
441
+ await this.send('Page.enable', sendOpts, false);
442
+ // go through the tasks to initialize
443
+ await this.send('Network.enable', sendOpts, false);
444
+ await this.send('Runtime.enable', sendOpts, false);
445
+ await this.send('Heap.enable', sendOpts, false);
446
+ await this.send('Debugger.enable', sendOpts, false);
447
+ await this.send('Console.enable', sendOpts, false);
448
+ await this.send('Inspector.initialized', sendOpts, false);
449
+ }
450
+ /**
451
+ * Mimic every step that Desktop Safari Develop tools uses to initialize a
452
+ * Web Inspector session
453
+ *
454
+ * @param {string} appIdKey
455
+ * @param {string} pageIdKey
456
+ * @returns {Promise<void>}
457
+ */
458
+ async initializePageFull(appIdKey, pageIdKey) {
459
+ const sendOpts = {
460
+ appIdKey,
461
+ pageIdKey,
462
+ };
463
+ await this.send('Inspector.enable', sendOpts, false);
464
+ await this.send('Page.enable', sendOpts, false);
465
+ // go through the tasks to initialize
466
+ await this.send('Page.getResourceTree', sendOpts, false);
467
+ await this.send('Network.enable', sendOpts, false);
468
+ await this.send('Network.setResourceCachingDisabled', Object.assign({
469
+ disabled: false,
470
+ }, sendOpts), false);
471
+ await this.send('DOMStorage.enable', sendOpts, false);
472
+ await this.send('Database.enable', sendOpts, false);
473
+ await this.send('IndexedDB.enable', sendOpts, false);
474
+ await this.send('CSS.enable', sendOpts, false);
475
+ await this.send('Runtime.enable', sendOpts, false);
476
+ await this.send('Heap.enable', sendOpts, false);
477
+ await this.send('Memory.enable', sendOpts, false);
478
+ await this.send('ApplicationCache.enable', sendOpts, false);
479
+ await this.send('ApplicationCache.getFramesWithManifests', sendOpts, false);
480
+ await this.send('Timeline.setInstruments', Object.assign({
481
+ instruments: ['Timeline', 'ScriptProfiler', 'CPU'],
482
+ }, sendOpts), false);
483
+ await this.send('Timeline.setAutoCaptureEnabled', Object.assign({
484
+ enabled: false,
485
+ }, sendOpts), false);
486
+ await this.send('Debugger.enable', sendOpts, false);
487
+ await this.send('Debugger.setBreakpointsActive', Object.assign({
488
+ active: true,
489
+ }, sendOpts), false);
490
+ await this.send('Debugger.setPauseOnExceptions', Object.assign({
491
+ state: 'none',
492
+ }, sendOpts), false);
493
+ await this.send('Debugger.setPauseOnAssertions', Object.assign({
494
+ enabled: false,
495
+ }, sendOpts), false);
496
+ await this.send('Debugger.setAsyncStackTraceDepth', Object.assign({
497
+ depth: 200,
498
+ }, sendOpts), false);
499
+ await this.send('Debugger.setPauseForInternalScripts', Object.assign({
500
+ shouldPause: false,
501
+ }, sendOpts), false);
502
+ await this.send('LayerTree.enable', sendOpts, false);
503
+ await this.send('Worker.enable', sendOpts, false);
504
+ await this.send('Canvas.enable', sendOpts, false);
505
+ await this.send('Console.enable', sendOpts, false);
506
+ await this.send('DOM.getDocument', sendOpts, false);
507
+ const loggingChannels = await this.send('Console.getLoggingChannels', sendOpts);
508
+ for (const source of (loggingChannels.channels || []).map((entry) => entry.source)) {
509
+ await this.send('Console.setLoggingChannelLevel', Object.assign({
510
+ source,
511
+ level: 'verbose',
512
+ }, sendOpts), false);
513
+ }
514
+ await this.send('Inspector.initialized', sendOpts, false);
515
+ }
516
+ /**
517
+ *
518
+ * @param {string} appIdKey
519
+ * @returns {Promise<[string, Record<string, any>]>}
520
+ */
521
+ async selectApp(appIdKey) {
522
+ return await new bluebird_1.default((resolve, reject) => {
523
+ // local callback, temporarily added as callback to
524
+ // `_rpc_applicationConnected:` remote debugger response
525
+ // to handle the initial connection
526
+ const onAppChange = (err, dict) => {
527
+ if (err) {
528
+ return reject(err);
529
+ }
530
+ // from the dictionary returned, get the ids
531
+ const oldAppIdKey = dict.WIRHostApplicationIdentifierKey;
532
+ const correctAppIdKey = dict.WIRApplicationIdentifierKey;
533
+ // if this is a report of a proxy redirect from the remote debugger
534
+ // we want to update our dictionary and get a new app id
535
+ if (oldAppIdKey && correctAppIdKey !== oldAppIdKey) {
536
+ logger_1.default.debug(`We were notified we might have connected to the wrong app. ` +
537
+ `Using id ${correctAppIdKey} instead of ${oldAppIdKey}`);
538
+ }
539
+ reject(new Error('New application has connected'));
540
+ };
541
+ // @ts-ignore messageHandler must be defined
542
+ this.messageHandler.prependOnceListener('_rpc_applicationConnected:', onAppChange);
543
+ // do the actual connecting to the app
544
+ return (async () => {
545
+ let pageDict, connectedAppIdKey;
546
+ try {
547
+ ([connectedAppIdKey, pageDict] = await this.send('connectToApp', {
548
+ appIdKey
549
+ }));
550
+ }
551
+ catch (err) {
552
+ logger_1.default.warn(`Unable to connect to app: ${err.message}`);
553
+ reject(err);
554
+ }
555
+ // sometimes the connect logic happens, but with an empty dictionary
556
+ // which leads to the remote debugger getting disconnected, and into a loop
557
+ if (lodash_1.default.isEmpty(pageDict)) {
558
+ let msg = 'Empty page dictionary received';
559
+ logger_1.default.debug(msg);
560
+ reject(new Error(msg));
561
+ }
562
+ else {
563
+ resolve([connectedAppIdKey, pageDict]);
564
+ }
565
+ })();
566
+ });
567
+ }
568
+ /**
569
+ *
570
+ * @param {Error?} err
571
+ * @param {Record<string, any>} context
572
+ */
573
+ onExecutionContextCreated(err, context) {
574
+ // { id: 2, isPageContext: true, name: '', frameId: '0.1' }
575
+ // right now we have no way to map contexts to apps/pages
576
+ // so just store
577
+ this.contexts.push(context.id);
578
+ }
579
+ onGarbageCollected() {
580
+ // just want to log that this is happening, as it can affect opertion
581
+ logger_1.default.debug(`Web Inspector garbage collected`);
582
+ }
583
+ /**
584
+ *
585
+ * @param {Error?} err
586
+ * @param {Record<string, any>} scriptInfo
587
+ */
588
+ onScriptParsed(err, scriptInfo) {
589
+ // { scriptId: '13', url: '', startLine: 0, startColumn: 0, endLine: 82, endColumn: 3 }
590
+ logger_1.default.debug(`Script parsed: ${JSON.stringify(scriptInfo)}`);
591
+ }
451
592
  }
452
593
  exports.default = RpcClient;
453
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVtb3RlTWVzc2FnZXMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9hc3luY2JveCIsIl9sb2dnZXIiLCJfbG9kYXNoIiwiX2JsdWViaXJkIiwiX3JwY01lc3NhZ2VIYW5kbGVyIiwiX3N1cHBvcnQiLCJEQVRBX0xPR19MRU5HVEgiLCJsZW5ndGgiLCJXQUlUX0ZPUl9UQVJHRVRfVElNRU9VVCIsIldBSVRfRk9SX1RBUkdFVF9JTlRFUlZBTCIsIk1JTl9QTEFURk9STV9GT1JfVEFSR0VUX0JBU0VEIiwiTUlOX1BMQVRGT1JNX05PX1RBUkdFVF9FWElTVFMiLCJpc1RhcmdldEJhc2VkIiwiaXNTYWZhcmkiLCJwbGF0Zm9ybVZlcnNpb24iLCJpc0hpZ2hWZXJzaW9uIiwidXRpbCIsImNvbXBhcmVWZXJzaW9ucyIsImxvZyIsImRlYnVnIiwiUnBjQ2xpZW50IiwiY29uc3RydWN0b3IiLCJvcHRzIiwiX3RhcmdldHMiLCJfc2hvdWxkQ2hlY2tGb3JUYXJnZXQiLCJzaG91bGRDaGVja0ZvclRhcmdldCIsImJ1bmRsZUlkIiwibG9nQWxsQ29tbXVuaWNhdGlvbiIsImxvZ0FsbENvbW11bmljYXRpb25IZXhEdW1wIiwid2ViSW5zcGVjdG9yTWF4RnJhbWVMZW5ndGgiLCJzb2NrZXRDaHVua1NpemUiLCJmdWxsUGFnZUluaXRpYWxpemF0aW9uIiwiaXNDb25uZWN0ZWQiLCJjb25uSWQiLCJ1dWlkVjQiLCJzZW5kZXJJZCIsIm1zZ0lkIiwiX2NvbnRleHRzIiwiY29udGV4dHMiLCJuZWVkc1RhcmdldCIsInRhcmdldHMiLCJjb25uZWN0ZWQiLCJvbiIsImV2ZW50IiwibGlzdGVuZXIiLCJtZXNzYWdlSGFuZGxlciIsIm9uY2UiLCJvZmYiLCJ3YXJuIiwiX2lzVGFyZ2V0QmFzZWQiLCJyZW1vdGVNZXNzYWdlcyIsIlJlbW90ZU1lc3NhZ2VzIiwiUnBjTWVzc2FnZUhhbmRsZXIiLCJhZGRUYXJnZXQiLCJiaW5kIiwidXBkYXRlVGFyZ2V0IiwicmVtb3ZlVGFyZ2V0Iiwib25FeGVjdXRpb25Db250ZXh0Q3JlYXRlZCIsIm9uR2FyYmFnZUNvbGxlY3RlZCIsIndhaXRGb3JUYXJnZXQiLCJhcHBJZEtleSIsInBhZ2VJZEtleSIsImZvcmNlIiwiZ2V0VGFyZ2V0Iiwid2FpdEZvckNvbmRpdGlvbiIsIl8iLCJpc0VtcHR5Iiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImVycm9yIiwiZXJyIiwibWVzc2FnZSIsImluY2x1ZGVzIiwiRXJyb3IiLCJzZW5kIiwiY29tbWFuZCIsIndhaXRGb3JSZXNwb25zZSIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInNlbmRUb0RldmljZSIsInRvTG93ZXJDYXNlIiwiaW5mbyIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiQiIsInJlc29sdmUiLCJyZWplY3QiLCJfY21kJF9fYXJndW1lbnQiLCJfY21kJF9fYXJndW1lbnQyIiwid3JhcHBlck1zZ0lkIiwidG9TdHJpbmciLCJ0YXJnZXRJZCIsImZ1bGxPcHRzIiwiZGVmYXVsdHMiLCJpZCIsImNtZCIsImdldFJlbW90ZUNvbW1hbmQiLCJfX2FyZ3VtZW50IiwiV0lSU29ja2V0RGF0YUtleSIsImlzTmlsIiwiQnVmZmVyIiwiZnJvbSIsIkpTT04iLCJzdHJpbmdpZnkiLCJtZXNzYWdlSGFuZGxlZCIsInRydW5jYXRlIiwibGlzdGVuZXJzIiwiX19zZWxlY3RvciIsInByZXBlbmRPbmNlTGlzdGVuZXIiLCJhcmdzIiwidmFsdWUiLCJjb2RlIiwibXNnIiwicmVzIiwic2VuZE1lc3NhZ2UiLCJjb25uZWN0IiwiZGlzY29ubmVjdCIsInJlbW92ZUFsbExpc3RlbmVycyIsInJlY2VpdmUiLCJhcHAiLCJ0YXJnZXRJbmZvIiwicGVuZGluZ1RhcmdldE5vdGlmaWNhdGlvbiIsImlzUHJvdmlzaW9uYWwiLCJoYXMiLCJvbGRUYXJnZXRJZCIsIm5ld1RhcmdldElkIiwicHJvdmlzaW9uYWwiLCJfdGhpcyR0YXJnZXRzJGFwcCIsInBhZ2UiLCJ0b1BhaXJzIiwic2VsZWN0UGFnZSIsInNlbmRPcHRzIiwiZW5hYmxlZCIsIk9iamVjdCIsImFzc2lnbiIsImluaXRpYWxpemVQYWdlRnVsbCIsImluaXRpYWxpemVQYWdlIiwiZGlzYWJsZWQiLCJpbnN0cnVtZW50cyIsImFjdGl2ZSIsInN0YXRlIiwiZGVwdGgiLCJzaG91bGRQYXVzZSIsImxvZ2dpbmdDaGFubmVscyIsInNvdXJjZSIsImNoYW5uZWxzIiwibWFwIiwiZW50cnkiLCJsZXZlbCIsInNlbGVjdEFwcCIsIm9uQXBwQ2hhbmdlIiwiZGljdCIsIm9sZEFwcElkS2V5IiwiV0lSSG9zdEFwcGxpY2F0aW9uSWRlbnRpZmllcktleSIsImNvcnJlY3RBcHBJZEtleSIsIldJUkFwcGxpY2F0aW9uSWRlbnRpZmllcktleSIsInBhZ2VEaWN0IiwiY29ubmVjdGVkQXBwSWRLZXkiLCJjb250ZXh0IiwicHVzaCIsIm9uU2NyaXB0UGFyc2VkIiwic2NyaXB0SW5mbyIsImV4cG9ydHMiLCJkZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3JwYy9ycGMtY2xpZW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZW1vdGVNZXNzYWdlcyBmcm9tICcuL3JlbW90ZS1tZXNzYWdlcyc7XG5pbXBvcnQgeyB3YWl0Rm9yQ29uZGl0aW9uIH0gZnJvbSAnYXN5bmNib3gnO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBScGNNZXNzYWdlSGFuZGxlciBmcm9tICcuL3JwYy1tZXNzYWdlLWhhbmRsZXInO1xuaW1wb3J0IHsgdXRpbCwgdGltaW5nIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcblxuXG5jb25zdCBEQVRBX0xPR19MRU5HVEggPSB7bGVuZ3RoOiAyMDB9O1xuXG5jb25zdCBXQUlUX0ZPUl9UQVJHRVRfVElNRU9VVCA9IDEwMDAwO1xuY29uc3QgV0FJVF9GT1JfVEFSR0VUX0lOVEVSVkFMID0gMTAwMDtcblxuY29uc3QgTUlOX1BMQVRGT1JNX0ZPUl9UQVJHRVRfQkFTRUQgPSAnMTIuMic7XG5cbi8vIGBUYXJnZXQuZXhpc3RzYCBwcm90b2NvbCBtZXRob2Qgd2FzIHJlbW92ZWQgZnJvbSBXZWJLaXQgaW4gMTMuNFxuY29uc3QgTUlOX1BMQVRGT1JNX05PX1RBUkdFVF9FWElTVFMgPSAnMTMuNCc7XG5cbmZ1bmN0aW9uIGlzVGFyZ2V0QmFzZWQgKGlzU2FmYXJpLCBwbGF0Zm9ybVZlcnNpb24pIHtcbiAgLy8gT24gaU9TIDEyLjIgdGhlIG1lc3NhZ2VzIGdldCBzZW50IHRocm91Z2ggdGhlIFRhcmdldCBkb21haW5cbiAgLy8gT24gaU9TIDEzLjArLCBXS1dlYlZpZXcgYWxzbyBuZWVkcyB0byBmb2xsb3cgdGhlIFRhcmdldCBkb21haW4sXG4gIC8vIHNvIGhlcmUgb25seSBjaGVjayB0aGUgdGFyZ2V0IE9TIHZlcnNpb24gYXMgdGhlIGRlZmF1bHQgYmVoYXZpb3VyLlxuICBjb25zdCBpc0hpZ2hWZXJzaW9uID0gdXRpbC5jb21wYXJlVmVyc2lvbnMocGxhdGZvcm1WZXJzaW9uLCAnPj0nLCBNSU5fUExBVEZPUk1fRk9SX1RBUkdFVF9CQVNFRCk7XG4gIGxvZy5kZWJ1ZyhgQ2hlY2tpbmcgd2hpY2ggY29tbXVuaWNhdGlvbiBzdHlsZSB0byB1c2UgKCR7aXNTYWZhcmkgPyAnJyA6ICdub24tJ31TYWZhcmkgb24gcGxhdGZvcm0gdmVyc2lvbiAnJHtwbGF0Zm9ybVZlcnNpb259JylgKTtcbiAgbG9nLmRlYnVnKGBQbGF0Zm9ybSB2ZXJzaW9uIGVxdWFsIG9yIGhpZ2hlciB0aGFuICcke01JTl9QTEFURk9STV9GT1JfVEFSR0VUX0JBU0VEfSc6ICR7aXNIaWdoVmVyc2lvbn1gKTtcbiAgcmV0dXJuIGlzSGlnaFZlcnNpb247XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJwY0NsaWVudCB7XG4gIGNvbnN0cnVjdG9yIChvcHRzID0ge30pIHtcbiAgICB0aGlzLl90YXJnZXRzID0gW107XG4gICAgdGhpcy5fc2hvdWxkQ2hlY2tGb3JUYXJnZXQgPSAhIW9wdHMuc2hvdWxkQ2hlY2tGb3JUYXJnZXQ7XG5cbiAgICBjb25zdCB7XG4gICAgICBidW5kbGVJZCxcbiAgICAgIHBsYXRmb3JtVmVyc2lvbiA9IHt9LFxuICAgICAgaXNTYWZhcmkgPSB0cnVlLFxuICAgICAgbG9nQWxsQ29tbXVuaWNhdGlvbiA9IGZhbHNlLFxuICAgICAgbG9nQWxsQ29tbXVuaWNhdGlvbkhleER1bXAgPSBmYWxzZSxcbiAgICAgIHdlYkluc3BlY3Rvck1heEZyYW1lTGVuZ3RoLFxuICAgICAgc29ja2V0Q2h1bmtTaXplLFxuICAgICAgZnVsbFBhZ2VJbml0aWFsaXphdGlvbiA9IGZhbHNlLFxuICAgIH0gPSBvcHRzO1xuXG4gICAgdGhpcy5pc1NhZmFyaSA9IGlzU2FmYXJpO1xuXG4gICAgdGhpcy5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuY29ubklkID0gdXRpbC51dWlkVjQoKTtcbiAgICB0aGlzLnNlbmRlcklkID0gdXRpbC51dWlkVjQoKTtcbiAgICB0aGlzLm1zZ0lkID0gMDtcblxuICAgIHRoaXMubG9nQWxsQ29tbXVuaWNhdGlvbiA9IGxvZ0FsbENvbW11bmljYXRpb247XG4gICAgdGhpcy5sb2dBbGxDb21tdW5pY2F0aW9uSGV4RHVtcCA9IGxvZ0FsbENvbW11bmljYXRpb25IZXhEdW1wO1xuICAgIHRoaXMuc29ja2V0Q2h1bmtTaXplID0gc29ja2V0Q2h1bmtTaXplO1xuICAgIHRoaXMud2ViSW5zcGVjdG9yTWF4RnJhbWVMZW5ndGggPSB3ZWJJbnNwZWN0b3JNYXhGcmFtZUxlbmd0aDtcblxuICAgIHRoaXMuZnVsbFBhZ2VJbml0aWFsaXphdGlvbiA9IGZ1bGxQYWdlSW5pdGlhbGl6YXRpb247XG5cbiAgICB0aGlzLmJ1bmRsZUlkID0gYnVuZGxlSWQ7XG4gICAgdGhpcy5wbGF0Zm9ybVZlcnNpb24gPSBwbGF0Zm9ybVZlcnNpb247XG5cbiAgICB0aGlzLl9jb250ZXh0cyA9IFtdO1xuICAgIHRoaXMuX3RhcmdldHMgPSB7fTtcblxuICAgIC8vIHN0YXJ0IHdpdGggYSBiZXN0IGd1ZXNzIGZvciB0aGUgcHJvdG9jb2xcbiAgICB0aGlzLmlzVGFyZ2V0QmFzZWQgPSBpc1RhcmdldEJhc2VkKGlzU2FmYXJpLCB0aGlzLnBsYXRmb3JtVmVyc2lvbik7XG4gIH1cblxuICBnZXQgY29udGV4dHMgKCkge1xuICAgIHJldHVybiB0aGlzLl9jb250ZXh0cztcbiAgfVxuXG4gIGdldCBuZWVkc1RhcmdldCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2hvdWxkQ2hlY2tGb3JUYXJnZXQgJiYgdGhpcy5pc1RhcmdldEJhc2VkO1xuICB9XG5cbiAgZ2V0IHRhcmdldHMgKCkge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXRzO1xuICB9XG5cbiAgZ2V0IHNob3VsZENoZWNrRm9yVGFyZ2V0ICgpIHtcbiAgICByZXR1cm4gdGhpcy5fc2hvdWxkQ2hlY2tGb3JUYXJnZXQ7XG4gIH1cblxuICBzZXQgc2hvdWxkQ2hlY2tGb3JUYXJnZXQgKHNob3VsZENoZWNrRm9yVGFyZ2V0KSB7XG4gICAgdGhpcy5fc2hvdWxkQ2hlY2tGb3JUYXJnZXQgPSAhIXNob3VsZENoZWNrRm9yVGFyZ2V0O1xuICB9XG5cbiAgZ2V0IGlzQ29ubmVjdGVkICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG4gIH1cblxuICBzZXQgaXNDb25uZWN0ZWQgKGNvbm5lY3RlZCkge1xuICAgIHRoaXMuY29ubmVjdGVkID0gISFjb25uZWN0ZWQ7XG4gIH1cblxuICBvbiAoZXZlbnQsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbihldmVudCwgbGlzdGVuZXIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgb25jZSAoZXZlbnQsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbmNlKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBvZmYgKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgIHRoaXMubWVzc2FnZUhhbmRsZXIub2ZmKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzZXQgaXNUYXJnZXRCYXNlZCAoaXNUYXJnZXRCYXNlZCkge1xuICAgIGxvZy53YXJuKGBTZXR0aW5nIGNvbW11bmljYXRpb24gcHJvdG9jb2w6IHVzaW5nICR7aXNUYXJnZXRCYXNlZCA/ICdUYXJnZXQtYmFzZWQnIDogJ2Z1bGwgV2ViIEluc3BlY3RvciBwcm90b2NvbCd9IGNvbW11bmljYXRpb25gKTtcbiAgICB0aGlzLl9pc1RhcmdldEJhc2VkID0gaXNUYXJnZXRCYXNlZDtcblxuICAgIGlmICghdGhpcy5yZW1vdGVNZXNzYWdlcykge1xuICAgICAgdGhpcy5yZW1vdGVNZXNzYWdlcyA9IG5ldyBSZW1vdGVNZXNzYWdlcyhpc1RhcmdldEJhc2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZW1vdGVNZXNzYWdlcy5pc1RhcmdldEJhc2VkID0gaXNUYXJnZXRCYXNlZDtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubWVzc2FnZUhhbmRsZXIpIHtcbiAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIgPSBuZXcgUnBjTWVzc2FnZUhhbmRsZXIoaXNUYXJnZXRCYXNlZCk7XG5cbiAgICAgIC8vIGFkZCBoYW5kbGVycyBmb3IgaW50ZXJuYWwgZXZlbnRzXG4gICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyLm9uKCdUYXJnZXQudGFyZ2V0Q3JlYXRlZCcsIHRoaXMuYWRkVGFyZ2V0LmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbignVGFyZ2V0LmRpZENvbW1pdFByb3Zpc2lvbmFsVGFyZ2V0JywgdGhpcy51cGRhdGVUYXJnZXQuYmluZCh0aGlzKSk7XG4gICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyLm9uKCdUYXJnZXQudGFyZ2V0RGVzdHJveWVkJywgdGhpcy5yZW1vdmVUYXJnZXQuYmluZCh0aGlzKSk7XG4gICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyLm9uKCdSdW50aW1lLmV4ZWN1dGlvbkNvbnRleHRDcmVhdGVkJywgdGhpcy5vbkV4ZWN1dGlvbkNvbnRleHRDcmVhdGVkLmJpbmQodGhpcykpO1xuICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbignSGVhcC5nYXJiYWdlQ29sbGVjdGVkJywgdGhpcy5vbkdhcmJhZ2VDb2xsZWN0ZWQuYmluZCh0aGlzKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIuaXNUYXJnZXRCYXNlZCA9IGlzVGFyZ2V0QmFzZWQ7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGlzVGFyZ2V0QmFzZWQgKCkge1xuICAgIHJldHVybiB0aGlzLl9pc1RhcmdldEJhc2VkO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclRhcmdldCAoYXBwSWRLZXksIHBhZ2VJZEtleSwgZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmICghZm9yY2UgJiYgIXRoaXMubmVlZHNUYXJnZXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5nZXRUYXJnZXQoYXBwSWRLZXksIHBhZ2VJZEtleSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBvdGhlcndpc2Ugd2FpdGluZyBpcyBuZWNlc3NhcnkgdG8gc2VlIHdoYXQgdGhlIHRhcmdldCBpc1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB3YWl0Rm9yQ29uZGl0aW9uKCgpID0+ICFfLmlzRW1wdHkodGhpcy5nZXRUYXJnZXQoYXBwSWRLZXksIHBhZ2VJZEtleSkpLCB7XG4gICAgICAgIHdhaXRNczogV0FJVF9GT1JfVEFSR0VUX1RJTUVPVVQsXG4gICAgICAgIGludGVydmFsTXM6IFdBSVRfRk9SX1RBUkdFVF9JTlRFUlZBTCxcbiAgICAgICAgZXJyb3I6ICdObyB0YXJnZXRzIGZvdW5kLCB1bmFibGUgdG8gY29tbXVuaWNhdGUgd2l0aCBkZXZpY2UnLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoIWVyci5tZXNzYWdlLmluY2x1ZGVzKCdDb25kaXRpb24gdW5tZXQnKSkge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHRhcmdldHMgZm91bmQsIHVuYWJsZSB0byBjb21tdW5pY2F0ZSB3aXRoIGRldmljZScpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlbmQgKGNvbW1hbmQsIG9wdHMgPSB7fSwgd2FpdEZvclJlc3BvbnNlID0gdHJ1ZSkge1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgY29uc3Qge1xuICAgICAgYXBwSWRLZXksXG4gICAgICBwYWdlSWRLZXlcbiAgICB9ID0gb3B0cztcbiAgICB0cnkge1xuICAgICAgaWYgKCFfLmlzRW1wdHkoYXBwSWRLZXkpICYmICFfLmlzRW1wdHkocGFnZUlkS2V5KSkge1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JUYXJnZXQoYXBwSWRLZXksIHBhZ2VJZEtleSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kVG9EZXZpY2UoY29tbWFuZCwgb3B0cywgd2FpdEZvclJlc3BvbnNlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxldCB7IG1lc3NhZ2UgPSAnJyB9ID0gZXJyO1xuICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKGAndGFyZ2V0JyBkb21haW4gd2FzIG5vdCBmb3VuZGApKSB7XG4gICAgICAgIGxvZy5pbmZvKCdUaGUgdGFyZ2V0IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IFRhcmdldCBiYXNlZCBjb21tdW5pY2F0aW9uLiAnICtcbiAgICAgICAgICAnV2lsbCBmb2xsb3cgbm9uLXRhcmdldCBiYXNlZCBjb21tdW5pY2F0aW9uLicpO1xuICAgICAgICB0aGlzLmlzVGFyZ2V0QmFzZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFRvRGV2aWNlKGNvbW1hbmQsIG9wdHMsIHdhaXRGb3JSZXNwb25zZSk7XG4gICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoYGRvbWFpbiB3YXMgbm90IGZvdW5kYCkgfHxcbiAgICAgICAgICBtZXNzYWdlLmluY2x1ZGVzKGBzb21lIGFyZ3VtZW50cyBvZiBtZXRob2RgKSB8fFxuICAgICAgICAgIG1lc3NhZ2UuaW5jbHVkZXMoYG1pc3NpbmcgdGFyZ2V0YCkpIHtcbiAgICAgICAgdGhpcy5pc1RhcmdldEJhc2VkID0gdHJ1ZTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yVGFyZ2V0KGFwcElkS2V5LCBwYWdlSWRLZXkpO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kVG9EZXZpY2UoY29tbWFuZCwgb3B0cywgd2FpdEZvclJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgbG9nLmRlYnVnKGBTZW5kaW5nIHRvIFdlYiBJbnNwZWN0b3IgdG9vayAke3RpbWVyLmdldER1cmF0aW9uKCkuYXNNaWxsaVNlY29uZHMudG9GaXhlZCgwKX1tc2ApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlbmRUb0RldmljZSAoY29tbWFuZCwgb3B0cyA9IHt9LCB3YWl0Rm9yUmVzcG9uc2UgPSB0cnVlKSB7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBCKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIHByb21pc2UgdG8gYmUgcmVzb2x2ZWQgd2hlbmV2ZXIgcmVtb3RlIGRlYnVnZ2VyXG4gICAgICAvLyByZXBsaWVzIHRvIG91ciByZXF1ZXN0XG5cbiAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIG1lc3NhZ2VzIGNvbWluZyBhbmQgZ29pbmcgdXNpbmcgYSBzaW1wbGUgc2VxdWVudGlhbCBpZFxuICAgICAgY29uc3QgbXNnSWQgPSB0aGlzLm1zZ0lkKys7XG4gICAgICBsZXQgd3JhcHBlck1zZ0lkID0gbXNnSWQ7XG4gICAgICBpZiAodGhpcy5pc1RhcmdldEJhc2VkKSB7XG4gICAgICAgIC8vIGZvciB0YXJnZXQtYmFzZSBjb21tdW5pY2F0aW9uLCBldmVyeXRoaW5nIGlzIHdyYXBwZWQgdXBcbiAgICAgICAgd3JhcHBlck1zZ0lkID0gdGhpcy5tc2dJZCsrO1xuICAgICAgICAvLyBhY2tub3dsZWRnZSB3cmFwcGVyIG1lc3NhZ2VcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbih3cmFwcGVyTXNnSWQudG9TdHJpbmcoKSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFwcElkS2V5ID0gb3B0cy5hcHBJZEtleTtcbiAgICAgIGNvbnN0IHBhZ2VJZEtleSA9IG9wdHMucGFnZUlkS2V5O1xuICAgICAgY29uc3QgdGFyZ2V0SWQgPSB0aGlzLmdldFRhcmdldChhcHBJZEtleSwgcGFnZUlkS2V5KTtcblxuICAgICAgLy8gcmV0cmlldmUgdGhlIGNvcnJlY3QgY29tbWFuZCB0byBzZW5kXG4gICAgICBjb25zdCBmdWxsT3B0cyA9IF8uZGVmYXVsdHMoe1xuICAgICAgICBjb25uSWQ6IHRoaXMuY29ubklkLFxuICAgICAgICBzZW5kZXJJZDogdGhpcy5zZW5kZXJJZCxcbiAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgIGlkOiBtc2dJZCxcbiAgICAgIH0sIG9wdHMpO1xuICAgICAgY29uc3QgY21kID0gdGhpcy5yZW1vdGVNZXNzYWdlcy5nZXRSZW1vdGVDb21tYW5kKGNvbW1hbmQsIGZ1bGxPcHRzKTtcblxuICAgICAgaWYgKGNtZD8uX19hcmd1bWVudD8uV0lSU29ja2V0RGF0YUtleSkge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIG1lc3NhZ2UgYmVpbmcgc2VudCBoYXMgYWxsIHRoZSBpbmZvcm1hdGlvbiB0aGF0IGlzIG5lZWRlZFxuICAgICAgICBpZiAoXy5pc05pbChjbWQuX19hcmd1bWVudC5XSVJTb2NrZXREYXRhS2V5LmlkKSkge1xuICAgICAgICAgIGNtZC5fX2FyZ3VtZW50LldJUlNvY2tldERhdGFLZXkuaWQgPSB3cmFwcGVyTXNnSWQ7XG4gICAgICAgIH1cbiAgICAgICAgY21kLl9fYXJndW1lbnQuV0lSU29ja2V0RGF0YUtleSA9XG4gICAgICAgICAgQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoY21kLl9fYXJndW1lbnQuV0lSU29ja2V0RGF0YUtleSkpO1xuICAgICAgfVxuXG4gICAgICBsZXQgbWVzc2FnZUhhbmRsZWQgPSB0cnVlO1xuICAgICAgaWYgKCF3YWl0Rm9yUmVzcG9uc2UpIHtcbiAgICAgICAgLy8gdGhlIHByb21pc2Ugd2lsbCBiZSByZXNvbHZlZCBhcyBzb29uIGFzIHRoZSBzb2NrZXQgaGFzIGJlZW4gc2VudFxuICAgICAgICBtZXNzYWdlSGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICAvLyBkbyBub3QgbG9nIHJlY2VpcHRzXG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIub25jZShtc2dJZC50b1N0cmluZygpLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgLy8gd2UgYXJlIG5vdCB3YWl0aW5nIGZvciB0aGlzLCBhbmQgaWYgaXQgZXJyb3JzIGl0IGlzIG1vc3QgbGlrZWx5XG4gICAgICAgICAgICAvLyBhIHByb3RvY29sIGNoYW5nZS4gTG9nIGFuZCBjaGVjayBkdXJpbmcgdGVzdGluZ1xuICAgICAgICAgICAgbG9nLmVycm9yKGBSZWNlaXZlZCBlcnJvciBmcm9tIHNlbmQgdGhhdCBpcyBub3QgYmVpbmcgd2FpdGVkIGZvciAoaWQ6ICR7bXNnSWR9KTogJyR7Xy50cnVuY2F0ZShKU09OLnN0cmluZ2lmeShlcnIpLCBEQVRBX0xPR19MRU5HVEgpfSdgKTtcbiAgICAgICAgICAgIC8vIHJlamVjdCwgdGhvdWdoIGl0IGlzIHZlcnkgcmFyZSB0aGF0IHRoaXMgd2lsbCBiZSB0cmlnZ2VyZWQsIHNpbmNlXG4gICAgICAgICAgICAvLyB0aGUgcHJvbWlzZSBpcyByZXNvbHZlZCBkaXJlY3RsdHkgYWZ0ZXIgc2VuZC4gT24gdGhlIG9mZiBjaGFuY2UsXG4gICAgICAgICAgICAvLyB0aG91Z2gsIGl0IHdpbGwgYWxlcnQgb2YgYSBwcm90b2NvbCBjaGFuZ2UuXG4gICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLm1lc3NhZ2VIYW5kbGVyLmxpc3RlbmVycyhjbWQuX19zZWxlY3RvcikubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIucHJlcGVuZE9uY2VMaXN0ZW5lcihjbWQuX19zZWxlY3RvciwgZnVuY3Rpb24gKGVyciwgLi4uYXJncykge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbG9nLmRlYnVnKGBSZWNlaXZlZCByZXNwb25zZSBmcm9tIHNlbmQgKGlkOiAke21zZ0lkfSk6ICcke18udHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoYXJncyksIERBVEFfTE9HX0xFTkdUSCl9J2ApO1xuICAgICAgICAgIHJlc29sdmUoYXJncyk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChjbWQ/Ll9fYXJndW1lbnQ/LldJUlNvY2tldERhdGFLZXkpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5vbmNlKG1zZ0lkLnRvU3RyaW5nKCksIGZ1bmN0aW9uIChlcnIsIHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYFJlbW90ZSBkZWJ1Z2dlciBlcnJvciB3aXRoIGNvZGUgJyR7ZXJyLmNvZGV9JzogJHtlcnIubWVzc2FnZX1gKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZy5kZWJ1ZyhgUmVjZWl2ZWQgZGF0YSByZXNwb25zZSBmcm9tIHNlbmQgKGlkOiAke21zZ0lkfSk6ICcke18udHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkodmFsdWUpLCBEQVRBX0xPR19MRU5HVEgpfSdgKTtcbiAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBub3RoaW5nIGVsc2UgaXMgaGFuZGxpbmcgdGhpbmdzLCBzbyBqdXN0IHJlc29sdmUgd2hlbiB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICAgIG1lc3NhZ2VIYW5kbGVkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1zZyA9IGBTZW5kaW5nICcke2NtZC5fX3NlbGVjdG9yfScgbWVzc2FnZWAgK1xuICAgICAgICAoZnVsbE9wdHMuYXBwSWRLZXkgPyBgIHRvIGFwcCAnJHtmdWxsT3B0cy5hcHBJZEtleX0nYCA6ICcnKSArXG4gICAgICAgIChmdWxsT3B0cy5wYWdlSWRLZXkgPyBgLCBwYWdlICcke2Z1bGxPcHRzLnBhZ2VJZEtleX0nYCA6ICcnKSArXG4gICAgICAgICh0aGlzLm5lZWRzVGFyZ2V0ICYmIHRhcmdldElkID8gYCwgdGFyZ2V0ICcke3RhcmdldElkfSdgIDogJycpICtcbiAgICAgICAgYCAoaWQ6ICR7bXNnSWR9KTogJyR7Y29tbWFuZH0nYDtcbiAgICAgIGxvZy5kZWJ1Zyhtc2cpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5zZW5kTWVzc2FnZShjbWQpO1xuICAgICAgICBpZiAoIW1lc3NhZ2VIYW5kbGVkKSB7XG4gICAgICAgICAgLy8gVGhlcmUgYXJlIG5vIGhhbmRsZXJzIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2UgYmVmb3JlIHJlc29sdmluZyxcbiAgICAgICAgICAvLyBhbmQgbm8gZXJyb3JzIHNlbmRpbmcgdGhlIG1lc3NhZ2Ugb3ZlciB0aGUgc29ja2V0LCBzbyByZXNvbHZlXG4gICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY29ubmVjdCAoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIHRocm93IG5ldyBFcnJvcihgU3ViLWNsYXNzZXMgbmVlZCB0byBpbXBsZW1lbnQgYSAnY29ubmVjdCcgZnVuY3Rpb25gKTtcbiAgfVxuXG4gIGFzeW5jIGRpc2Nvbm5lY3QgKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICB9XG5cbiAgYXN5bmMgc2VuZE1lc3NhZ2UgKC8qIGNvbW1hbmQgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTdWItY2xhc3NlcyBuZWVkIHRvIGltcGxlbWVudCBhICdzZW5kTWVzc2FnZScgZnVuY3Rpb25gKTtcbiAgfVxuXG4gIGFzeW5jIHJlY2VpdmUgKC8qIGRhdGEgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTdWItY2xhc3NlcyBuZWVkIHRvIGltcGxlbWVudCBhICdyZWNlaXZlJyBmdW5jdGlvbmApO1xuICB9XG5cbiAgYWRkVGFyZ2V0IChlcnIsIGFwcCwgdGFyZ2V0SW5mbykge1xuICAgIGlmIChfLmlzTmlsKHRhcmdldEluZm8/LnRhcmdldElkKSkge1xuICAgICAgbG9nLndhcm4oYFJlY2VpdmVkICdUYXJnZXQudGFyZ2V0Q3JlYXRlZCcgZXZlbnQgZm9yIGFwcCAnJHthcHB9JyB3aXRoIG5vIHRhcmdldC4gU2tpcHBpbmdgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKF8uaXNFbXB0eSh0aGlzLnBlbmRpbmdUYXJnZXROb3RpZmljYXRpb24pICYmICF0YXJnZXRJbmZvLmlzUHJvdmlzaW9uYWwpIHtcbiAgICAgIGxvZy53YXJuKGBSZWNlaXZlZCAnVGFyZ2V0LnRhcmdldENyZWF0ZWQnIGV2ZW50IGZvciBhcHAgJyR7YXBwfScgd2l0aCBubyBwZW5kaW5nIHJlcXVlc3Q6ICR7SlNPTi5zdHJpbmdpZnkodGFyZ2V0SW5mbyl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRhcmdldEluZm8uaXNQcm92aXNpb25hbCkge1xuICAgICAgbG9nLmRlYnVnKGBQcm92aXNpb25hbCB0YXJnZXQgY3JlYXRlZCBmb3IgYXBwICcke2FwcH0nLCAnJHt0YXJnZXRJbmZvLnRhcmdldElkfScuIElnbm9yaW5nIHVudGlsIHRhcmdldCB1cGRhdGUgZXZlbnRgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBbYXBwSWRLZXksIHBhZ2VJZEtleV0gPSB0aGlzLnBlbmRpbmdUYXJnZXROb3RpZmljYXRpb247XG5cbiAgICBsb2cuZGVidWcoYFRhcmdldCBjcmVhdGVkIGZvciBhcHAgJyR7YXBwSWRLZXl9JyBhbmQgcGFnZSAnJHtwYWdlSWRLZXl9JzogJHtKU09OLnN0cmluZ2lmeSh0YXJnZXRJbmZvKX1gKTtcbiAgICBpZiAoXy5oYXModGhpcy50YXJnZXRzW2FwcElkS2V5XSwgcGFnZUlkS2V5KSkge1xuICAgICAgbG9nLmRlYnVnKGBUaGVyZSBpcyBhbHJlYWR5IGEgdGFyZ2V0IGZvciB0aGlzIGFwcCBhbmQgcGFnZSAoJyR7dGhpcy50YXJnZXRzW2FwcElkS2V5XVtwYWdlSWRLZXldfScpLiBUaGlzIG1pZ2h0IGNhdXNlIHByb2JsZW1zYCk7XG4gICAgfVxuICAgIHRoaXMudGFyZ2V0c1thcHBdID0gdGhpcy50YXJnZXRzW2FwcF0gfHwge307XG4gICAgdGhpcy50YXJnZXRzW2FwcElkS2V5XVtwYWdlSWRLZXldID0gdGFyZ2V0SW5mby50YXJnZXRJZDtcbiAgfVxuXG4gIHVwZGF0ZVRhcmdldCAoZXJyLCBhcHAsIG9sZFRhcmdldElkLCBuZXdUYXJnZXRJZCkge1xuICAgIGxvZy5kZWJ1ZyhgVGFyZ2V0IHVwZGF0ZWQgZm9yIGFwcCAnJHthcHB9Jy4gT2xkIHRhcmdldDogJyR7b2xkVGFyZ2V0SWR9JywgbmV3IHRhcmdldDogJyR7bmV3VGFyZ2V0SWR9J2ApO1xuICAgIGlmICghdGhpcy50YXJnZXRzW2FwcF0pIHtcbiAgICAgIGxvZy53YXJuKGBObyBleGlzdGluZyB0YXJnZXQgZm9yIGFwcCAnJHthcHB9Jy4gTm90IHN1cmUgd2hhdCB0byBkb2ApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBzYXZlIHRoaXMsIHRvIGJlIHVzZWQgaWYvd2hlbiB0aGUgZXhpc3RpbmcgdGFyZ2V0IGlzIGRlc3Ryb3llZFxuICAgIHRoaXMudGFyZ2V0c1thcHBdLnByb3Zpc2lvbmFsID0ge1xuICAgICAgb2xkVGFyZ2V0SWQsXG4gICAgICBuZXdUYXJnZXRJZCxcbiAgICB9O1xuICB9XG5cbiAgcmVtb3ZlVGFyZ2V0IChlcnIsIGFwcCwgdGFyZ2V0SW5mbykge1xuICAgIGlmIChfLmlzTmlsKHRhcmdldEluZm8/LnRhcmdldElkKSkge1xuICAgICAgbG9nLmRlYnVnKGBSZWNlaXZlZCAnVGFyZ2V0LnRhcmdldERlc3Ryb3llZCcgZXZlbnQgd2l0aCBubyB0YXJnZXQuIFNraXBwaW5nYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nLmRlYnVnKGBUYXJnZXQgZGVzdHJveWVkIGZvciBhcHAgJyR7YXBwfSc6ICR7dGFyZ2V0SW5mby50YXJnZXRJZH1gKTtcblxuICAgIC8vIGdvIHRocm91Z2ggdGhlIHRhcmdldHMgYW5kIGZpbmQgdGhlIG9uZSB0aGF0IGhhcyBhIHdhaXRpbmcgcHJvdmlzaW9uYWwgdGFyZ2V0XG4gICAgaWYgKHRoaXMudGFyZ2V0c1thcHBdPy5wcm92aXNpb25hbD8ub2xkVGFyZ2V0SWQgPT09IHRhcmdldEluZm8udGFyZ2V0SWQpIHtcbiAgICAgIGNvbnN0IHtvbGRUYXJnZXRJZCwgbmV3VGFyZ2V0SWR9ID0gdGhpcy50YXJnZXRzW2FwcF0ucHJvdmlzaW9uYWw7XG4gICAgICBkZWxldGUgdGhpcy50YXJnZXRzW2FwcF0ucHJvdmlzaW9uYWw7XG5cbiAgICAgIC8vIHdlIGRvIG5vdCBrbm93IHRoZSBwYWdlLCBzbyBnbyB0aHJvdWdoIGFuZCBmaW5kIHRoZSBleGlzdGluZyB0YXJnZXRcbiAgICAgIGNvbnN0IHRhcmdldHMgPSB0aGlzLnRhcmdldHNbYXBwXTtcbiAgICAgIGZvciAoY29uc3QgW3BhZ2UsIHRhcmdldElkXSBvZiBfLnRvUGFpcnModGFyZ2V0cykpIHtcbiAgICAgICAgaWYgKHRhcmdldElkID09PSBvbGRUYXJnZXRJZCkge1xuICAgICAgICAgIGxvZy5kZWJ1ZyhgRm91bmQgcHJvdmlzaW9uYWwgdGFyZ2V0IGZvciBhcHAgJyR7YXBwfScuIE9sZCB0YXJnZXQ6ICcke29sZFRhcmdldElkfScsIG5ldyB0YXJnZXQ6ICcke25ld1RhcmdldElkfScuIFVwZGF0aW5nYCk7XG4gICAgICAgICAgdGFyZ2V0c1twYWdlXSA9IG5ld1RhcmdldElkO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbG9nLndhcm4oYFByb3Zpc2lvbmFsIHRhcmdldCBmb3IgYXBwICcke2FwcH0nIGZvdW5kLCBidXQgbm8gc3VpdGFibGUgZXhpc3RpbmcgdGFyZ2V0IGZvdW5kLiBUaGlzIG1heSBjYXVzZSBwcm9ibGVtc2ApO1xuICAgICAgbG9nLndhcm4oYE9sZCB0YXJnZXQ6ICcke29sZFRhcmdldElkfScsIG5ldyB0YXJnZXQ6ICcke25ld1RhcmdldElkfScuIEV4aXN0aW5nIHRhcmdldHM6ICR7SlNPTi5zdHJpbmdpZnkodGFyZ2V0cyl9YCk7XG4gICAgfVxuXG4gICAgLy8gaWYgdGhlcmUgaXMgbm8gd2FpdGluZyBwcm92aXNpb25hbCB0YXJnZXQsIGp1c3QgZ2V0IHJpZCBvZiB0aGUgZXhpc3Rpbmcgb25lXG4gICAgY29uc3QgdGFyZ2V0cyA9IHRoaXMudGFyZ2V0c1thcHBdO1xuICAgIGZvciAoY29uc3QgW3BhZ2UsIHRhcmdldElkXSBvZiBfLnRvUGFpcnModGFyZ2V0cykpIHtcbiAgICAgIGlmICh0YXJnZXRJZCA9PT0gdGFyZ2V0SW5mby50YXJnZXRJZCkge1xuICAgICAgICBkZWxldGUgdGFyZ2V0c1twYWdlXTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBsb2cuZGVidWcoYFRhcmdldCAnJHt0YXJnZXRJbmZvLnRhcmdldElkfScgZGVsZXRlZCBmb3IgYXBwICcke2FwcH0nLCBidXQgbm8gc3VjaCB0YXJnZXQgZXhpc3RzYCk7XG4gIH1cblxuICBnZXRUYXJnZXQgKGFwcElkS2V5LCBwYWdlSWRLZXkpIHtcbiAgICByZXR1cm4gKHRoaXMudGFyZ2V0c1thcHBJZEtleV0gfHwge30pW3BhZ2VJZEtleV07XG4gIH1cblxuICBhc3luYyBzZWxlY3RQYWdlIChhcHBJZEtleSwgcGFnZUlkS2V5KSB7XG4gICAgdGhpcy5wZW5kaW5nVGFyZ2V0Tm90aWZpY2F0aW9uID0gW2FwcElkS2V5LCBwYWdlSWRLZXldO1xuICAgIHRoaXMuc2hvdWxkQ2hlY2tGb3JUYXJnZXQgPSBmYWxzZTtcblxuICAgIC8vIGdvIHRocm91Z2ggdGhlIHN0ZXBzIHRoYXQgdGhlIERlc2t0b3AgU2FmYXJpIHN5c3RlbVxuICAgIC8vIGdvZXMgdGhyb3VnaCB0byBpbml0aWFsaXplIHRoZSBXZWIgSW5zcGVjdG9yIHNlc3Npb25cblxuICAgIGNvbnN0IHNlbmRPcHRzID0ge1xuICAgICAgYXBwSWRLZXksXG4gICAgICBwYWdlSWRLZXksXG4gICAgfTtcblxuICAgIC8vIGhpZ2hsaWdodCBhbmQgdGhlbiB1bi1oaWdobGlnaHQgdGhlIHdlYnZpZXdcbiAgICBmb3IgKGNvbnN0IGVuYWJsZWQgb2YgW3RydWUsIGZhbHNlXSkge1xuICAgICAgYXdhaXQgdGhpcy5zZW5kKCdpbmRpY2F0ZVdlYlZpZXcnLCBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgZW5hYmxlZCxcbiAgICAgIH0sIHNlbmRPcHRzKSwgZmFsc2UpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuc2VuZCgnc2V0U2VuZGVyS2V5Jywgc2VuZE9wdHMpO1xuICAgIGxvZy5kZWJ1ZygnU2VuZGVyIGtleSBzZXQnKTtcblxuICAgIGlmICh0aGlzLmlzVGFyZ2V0QmFzZWQgJiYgdXRpbC5jb21wYXJlVmVyc2lvbnModGhpcy5wbGF0Zm9ybVZlcnNpb24sICc8JywgTUlOX1BMQVRGT1JNX05PX1RBUkdFVF9FWElTVFMpKSB7XG4gICAgICBhd2FpdCB0aGlzLnNlbmQoJ1RhcmdldC5leGlzdHMnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIH1cblxuICAgIHRoaXMuc2hvdWxkQ2hlY2tGb3JUYXJnZXQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuZnVsbFBhZ2VJbml0aWFsaXphdGlvbikge1xuICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplUGFnZUZ1bGwoYXBwSWRLZXksIHBhZ2VJZEtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVBhZ2UoYXBwSWRLZXksIHBhZ2VJZEtleSk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogUGVyZm9ybSB0aGUgbWluaW1hbCBpbml0aWFsaXphdGlvbiB0byBnZXQgdGhlIFdlYiBJbnNwZWN0b3Igd29ya2luZ1xuICAgKi9cbiAgYXN5bmMgaW5pdGlhbGl6ZVBhZ2UgKGFwcElkS2V5LCBwYWdlSWRLZXkpIHtcbiAgICBjb25zdCBzZW5kT3B0cyA9IHtcbiAgICAgIGFwcElkS2V5LFxuICAgICAgcGFnZUlkS2V5LFxuICAgIH07XG5cbiAgICBhd2FpdCB0aGlzLnNlbmQoJ0luc3BlY3Rvci5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnUGFnZS5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuXG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgdGFza3MgdG8gaW5pdGlhbGl6ZVxuICAgIGF3YWl0IHRoaXMuc2VuZCgnTmV0d29yay5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnUnVudGltZS5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnSGVhcC5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnRGVidWdnZXIuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ0NvbnNvbGUuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ0luc3BlY3Rvci5pbml0aWFsaXplZCcsIHNlbmRPcHRzLCBmYWxzZSk7XG4gIH1cblxuICAvKlxuICAgKiBNaW1pYyBldmVyeSBzdGVwIHRoYXQgRGVza3RvcCBTYWZhcmkgRGV2ZWxvcCB0b29scyB1c2VzIHRvIGluaXRpYWxpemUgYVxuICAgKiBXZWIgSW5zcGVjdG9yIHNlc3Npb25cbiAgICovXG4gIGFzeW5jIGluaXRpYWxpemVQYWdlRnVsbCAoYXBwSWRLZXksIHBhZ2VJZEtleSkge1xuICAgIGNvbnN0IHNlbmRPcHRzID0ge1xuICAgICAgYXBwSWRLZXksXG4gICAgICBwYWdlSWRLZXksXG4gICAgfTtcblxuICAgIGF3YWl0IHRoaXMuc2VuZCgnSW5zcGVjdG9yLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdQYWdlLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG5cbiAgICAvLyBnbyB0aHJvdWdoIHRoZSB0YXNrcyB0byBpbml0aWFsaXplXG4gICAgYXdhaXQgdGhpcy5zZW5kKCdQYWdlLmdldFJlc291cmNlVHJlZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdOZXR3b3JrLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdOZXR3b3JrLnNldFJlc291cmNlQ2FjaGluZ0Rpc2FibGVkJywgT2JqZWN0LmFzc2lnbih7XG4gICAgICBkaXNhYmxlZDogZmFsc2UsXG4gICAgfSwgc2VuZE9wdHMpLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdET01TdG9yYWdlLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdEYXRhYmFzZS5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnSW5kZXhlZERCLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdDU1MuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ1J1bnRpbWUuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ0hlYXAuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ01lbW9yeS5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnQXBwbGljYXRpb25DYWNoZS5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnQXBwbGljYXRpb25DYWNoZS5nZXRGcmFtZXNXaXRoTWFuaWZlc3RzJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ1RpbWVsaW5lLnNldEluc3RydW1lbnRzJywgT2JqZWN0LmFzc2lnbih7XG4gICAgICBpbnN0cnVtZW50czogWydUaW1lbGluZScsICdTY3JpcHRQcm9maWxlcicsICdDUFUnXSxcbiAgICB9LCBzZW5kT3B0cyksIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ1RpbWVsaW5lLnNldEF1dG9DYXB0dXJlRW5hYmxlZCcsIE9iamVjdC5hc3NpZ24oe1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgfSwgc2VuZE9wdHMpLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdEZWJ1Z2dlci5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnRGVidWdnZXIuc2V0QnJlYWtwb2ludHNBY3RpdmUnLCBPYmplY3QuYXNzaWduKHtcbiAgICAgIGFjdGl2ZTogdHJ1ZSxcbiAgICB9LCBzZW5kT3B0cyksIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ0RlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zJywgT2JqZWN0LmFzc2lnbih7XG4gICAgICBzdGF0ZTogJ25vbmUnLFxuICAgIH0sIHNlbmRPcHRzKSwgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnRGVidWdnZXIuc2V0UGF1c2VPbkFzc2VydGlvbnMnLCBPYmplY3QuYXNzaWduKHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgIH0sIHNlbmRPcHRzKSwgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnRGVidWdnZXIuc2V0QXN5bmNTdGFja1RyYWNlRGVwdGgnLCBPYmplY3QuYXNzaWduKHtcbiAgICAgIGRlcHRoOiAyMDAsXG4gICAgfSwgc2VuZE9wdHMpLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdEZWJ1Z2dlci5zZXRQYXVzZUZvckludGVybmFsU2NyaXB0cycsIE9iamVjdC5hc3NpZ24oe1xuICAgICAgc2hvdWxkUGF1c2U6IGZhbHNlLFxuICAgIH0sIHNlbmRPcHRzKSwgZmFsc2UpO1xuXG4gICAgYXdhaXQgdGhpcy5zZW5kKCdMYXllclRyZWUuZW5hYmxlJywgc2VuZE9wdHMsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLnNlbmQoJ1dvcmtlci5lbmFibGUnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGF3YWl0IHRoaXMuc2VuZCgnQ2FudmFzLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdDb25zb2xlLmVuYWJsZScsIHNlbmRPcHRzLCBmYWxzZSk7XG4gICAgYXdhaXQgdGhpcy5zZW5kKCdET00uZ2V0RG9jdW1lbnQnLCBzZW5kT3B0cywgZmFsc2UpO1xuICAgIGNvbnN0IGxvZ2dpbmdDaGFubmVscyA9IGF3YWl0IHRoaXMuc2VuZCgnQ29uc29sZS5nZXRMb2dnaW5nQ2hhbm5lbHMnLCBzZW5kT3B0cyk7XG4gICAgZm9yIChjb25zdCBzb3VyY2Ugb2YgKGxvZ2dpbmdDaGFubmVscy5jaGFubmVscyB8fCBbXSkubWFwKChlbnRyeSkgPT4gZW50cnkuc291cmNlKSkge1xuICAgICAgYXdhaXQgdGhpcy5zZW5kKCdDb25zb2xlLnNldExvZ2dpbmdDaGFubmVsTGV2ZWwnLCBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgc291cmNlLFxuICAgICAgICBsZXZlbDogJ3ZlcmJvc2UnLFxuICAgICAgfSwgc2VuZE9wdHMpLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5zZW5kKCdJbnNwZWN0b3IuaW5pdGlhbGl6ZWQnLCBzZW5kT3B0cywgZmFsc2UpO1xuICB9XG5cbiAgYXN5bmMgc2VsZWN0QXBwIChhcHBJZEtleSkge1xuICAgIHJldHVybiBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBsb2NhbCBjYWxsYmFjaywgdGVtcG9yYXJpbHkgYWRkZWQgYXMgY2FsbGJhY2sgdG9cbiAgICAgIC8vIGBfcnBjX2FwcGxpY2F0aW9uQ29ubmVjdGVkOmAgcmVtb3RlIGRlYnVnZ2VyIHJlc3BvbnNlXG4gICAgICAvLyB0byBoYW5kbGUgdGhlIGluaXRpYWwgY29ubmVjdGlvblxuICAgICAgY29uc3Qgb25BcHBDaGFuZ2UgPSAoZXJyLCBkaWN0KSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZnJvbSB0aGUgZGljdGlvbmFyeSByZXR1cm5lZCwgZ2V0IHRoZSBpZHNcbiAgICAgICAgY29uc3Qgb2xkQXBwSWRLZXkgPSBkaWN0LldJUkhvc3RBcHBsaWNhdGlvbklkZW50aWZpZXJLZXk7XG4gICAgICAgIGNvbnN0IGNvcnJlY3RBcHBJZEtleSA9IGRpY3QuV0lSQXBwbGljYXRpb25JZGVudGlmaWVyS2V5O1xuXG4gICAgICAgIC8vIGlmIHRoaXMgaXMgYSByZXBvcnQgb2YgYSBwcm94eSByZWRpcmVjdCBmcm9tIHRoZSByZW1vdGUgZGVidWdnZXJcbiAgICAgICAgLy8gd2Ugd2FudCB0byB1cGRhdGUgb3VyIGRpY3Rpb25hcnkgYW5kIGdldCBhIG5ldyBhcHAgaWRcbiAgICAgICAgaWYgKG9sZEFwcElkS2V5ICYmIGNvcnJlY3RBcHBJZEtleSAhPT0gb2xkQXBwSWRLZXkpIHtcbiAgICAgICAgICBsb2cuZGVidWcoYFdlIHdlcmUgbm90aWZpZWQgd2UgbWlnaHQgaGF2ZSBjb25uZWN0ZWQgdG8gdGhlIHdyb25nIGFwcC4gYCArXG4gICAgICAgICAgICAgICAgICAgIGBVc2luZyBpZCAke2NvcnJlY3RBcHBJZEtleX0gaW5zdGVhZCBvZiAke29sZEFwcElkS2V5fWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignTmV3IGFwcGxpY2F0aW9uIGhhcyBjb25uZWN0ZWQnKSk7XG4gICAgICB9O1xuICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5wcmVwZW5kT25jZUxpc3RlbmVyKCdfcnBjX2FwcGxpY2F0aW9uQ29ubmVjdGVkOicsIG9uQXBwQ2hhbmdlKTtcblxuICAgICAgLy8gZG8gdGhlIGFjdHVhbCBjb25uZWN0aW5nIHRvIHRoZSBhcHBcbiAgICAgIHJldHVybiAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgcGFnZURpY3QsIGNvbm5lY3RlZEFwcElkS2V5O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIChbY29ubmVjdGVkQXBwSWRLZXksIHBhZ2VEaWN0XSA9IGF3YWl0IHRoaXMuc2VuZCgnY29ubmVjdFRvQXBwJywge1xuICAgICAgICAgICAgYXBwSWRLZXlcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGxvZy53YXJuKGBVbmFibGUgdG8gY29ubmVjdCB0byBhcHA6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzb21ldGltZXMgdGhlIGNvbm5lY3QgbG9naWMgaGFwcGVucywgYnV0IHdpdGggYW4gZW1wdHkgZGljdGlvbmFyeVxuICAgICAgICAvLyB3aGljaCBsZWFkcyB0byB0aGUgcmVtb3RlIGRlYnVnZ2VyIGdldHRpbmcgZGlzY29ubmVjdGVkLCBhbmQgaW50byBhIGxvb3BcbiAgICAgICAgaWYgKF8uaXNFbXB0eShwYWdlRGljdCkpIHtcbiAgICAgICAgICBsZXQgbXNnID0gJ0VtcHR5IHBhZ2UgZGljdGlvbmFyeSByZWNlaXZlZCc7XG4gICAgICAgICAgbG9nLmRlYnVnKG1zZyk7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihtc2cpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKFtjb25uZWN0ZWRBcHBJZEtleSwgcGFnZURpY3RdKTtcbiAgICAgICAgfVxuICAgICAgfSkoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG9uRXhlY3V0aW9uQ29udGV4dENyZWF0ZWQgKGVyciwgY29udGV4dCkge1xuICAgIC8vIHsgaWQ6IDIsIGlzUGFnZUNvbnRleHQ6IHRydWUsIG5hbWU6ICcnLCBmcmFtZUlkOiAnMC4xJyB9XG4gICAgLy8gcmlnaHQgbm93IHdlIGhhdmUgbm8gd2F5IHRvIG1hcCBjb250ZXh0cyB0byBhcHBzL3BhZ2VzXG4gICAgLy8gc28ganVzdCBzdG9yZVxuICAgIHRoaXMuY29udGV4dHMucHVzaChjb250ZXh0LmlkKTtcbiAgfVxuXG4gIG9uR2FyYmFnZUNvbGxlY3RlZCAoKSB7XG4gICAgLy8ganVzdCB3YW50IHRvIGxvZyB0aGF0IHRoaXMgaXMgaGFwcGVuaW5nLCBhcyBpdCBjYW4gYWZmZWN0IG9wZXJ0aW9uXG4gICAgbG9nLmRlYnVnKGBXZWIgSW5zcGVjdG9yIGdhcmJhZ2UgY29sbGVjdGVkYCk7XG4gIH1cblxuICBvblNjcmlwdFBhcnNlZCAoZXJyLCBzY3JpcHRJbmZvKSB7XG4gICAgLy8geyBzY3JpcHRJZDogJzEzJywgdXJsOiAnJywgc3RhcnRMaW5lOiAwLCBzdGFydENvbHVtbjogMCwgZW5kTGluZTogODIsIGVuZENvbHVtbjogMyB9XG4gICAgbG9nLmRlYnVnKGBTY3JpcHQgcGFyc2VkOiAke0pTT04uc3RyaW5naWZ5KHNjcmlwdEluZm8pfWApO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUEsSUFBQUEsZUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUksU0FBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssa0JBQUEsR0FBQU4sc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFNLFFBQUEsR0FBQU4sT0FBQTtBQUdBLE1BQU1PLGVBQWUsR0FBRztFQUFDQyxNQUFNLEVBQUU7QUFBRyxDQUFDO0FBRXJDLE1BQU1DLHVCQUF1QixHQUFHLEtBQUs7QUFDckMsTUFBTUMsd0JBQXdCLEdBQUcsSUFBSTtBQUVyQyxNQUFNQyw2QkFBNkIsR0FBRyxNQUFNO0FBRzVDLE1BQU1DLDZCQUE2QixHQUFHLE1BQU07QUFFNUMsU0FBU0MsYUFBYUEsQ0FBRUMsUUFBUSxFQUFFQyxlQUFlLEVBQUU7RUFJakQsTUFBTUMsYUFBYSxHQUFHQyxhQUFJLENBQUNDLGVBQWUsQ0FBQ0gsZUFBZSxFQUFFLElBQUksRUFBRUosNkJBQTZCLENBQUM7RUFDaEdRLGVBQUcsQ0FB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
594
+ //# sourceMappingURL=rpc-client.js.map