@rongcloud/plugin-call 5.2.4 → 5.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +9 -0
- package/dist/index.d.ts +29 -36
- package/dist/index.esm.js +9 -2643
- package/package.json +4 -4
- package/dist/index.umd.js +0 -5
package/dist/index.esm.js
CHANGED
|
@@ -1,2643 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const n = [];
|
|
10
|
-
do {
|
|
11
|
-
const o = i % t;
|
|
12
|
-
i = (i - o) / t, n.unshift(e[o]);
|
|
13
|
-
} while (i);
|
|
14
|
-
return n.join("");
|
|
15
|
-
}, Ie = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (s) => {
|
|
16
|
-
const e = Math.random() * 16 | 0;
|
|
17
|
-
return (s === "x" ? e : e & 3 | 8).toString(16);
|
|
18
|
-
}), oe = () => {
|
|
19
|
-
let s = Ie();
|
|
20
|
-
return s = `${s.replace(/-/g, "")}0`, s = parseInt(s, 16), s = fe(s), s.length > 22 && (s = s.slice(0, 22)), s;
|
|
21
|
-
}, ee = () => {
|
|
22
|
-
const s = Math.floor(Math.random() * 1e3);
|
|
23
|
-
let e = oe();
|
|
24
|
-
return e = e.replace(/\//g, "0"), [e, Date.now(), s].join("_");
|
|
25
|
-
}, Re = (s, e) => setTimeout(s, e), re = new ie(), Z = (s) => {
|
|
26
|
-
const e = "RCCallDeviceId";
|
|
27
|
-
let t = s.sessionStorage.getItem(e);
|
|
28
|
-
return t || (t = oe(), s.sessionStorage.setItem(e, t)), t;
|
|
29
|
-
};
|
|
30
|
-
var b = /* @__PURE__ */ ((s) => (s[s.OUTGOING = 1] = "OUTGOING", s[s.INCOMING = 2] = "INCOMING", s[s.RINGING = 3] = "RINGING", s[s.CONNECTED = 4] = "CONNECTED", s[s.IDLE = 5] = "IDLE", s[s.ACCEPTED = 6] = "ACCEPTED", s))(b || {}), l = /* @__PURE__ */ ((s) => (s[s.SUCCESS = 1e4] = "SUCCESS", s[s.STATE_MACHINE_EXIT = 53200] = "STATE_MACHINE_EXIT", s[s.SEND_MSG_ERROR = 53201] = "SEND_MSG_ERROR", s[s.REJECTED_BY_BLACKLIST = 53202] = "REJECTED_BY_BLACKLIST", s[s.NOT_IN_GROUP = 53203] = "NOT_IN_GROUP", s[s.GET_LOCAL_AUDIO_TRACK_ERROR = 53301] = "GET_LOCAL_AUDIO_TRACK_ERROR", s[s.GET_LOCAL_VIDEO_TRACK_ERROR = 53302] = "GET_LOCAL_VIDEO_TRACK_ERROR", s[s.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR = 53303] = "GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR", s[s.JOIN_ROOM_ERROR = 53304] = "JOIN_ROOM_ERROR", s[s.AUDIO_PUBLISH_ERROR = 53305] = "AUDIO_PUBLISH_ERROR", s[s.VIDEO_PUBLISH_ERROR = 53306] = "VIDEO_PUBLISH_ERROR", s[s.AUDIO_AND_VIDEO_PUBLISH_ERROR = 53307] = "AUDIO_AND_VIDEO_PUBLISH_ERROR", s[s.QUERY_JOINED_USER_INFO_ERROR = 53308] = "QUERY_JOINED_USER_INFO_ERROR", s[s.MISSING_VIDEO_TRACK_ERROR = 53309] = "MISSING_VIDEO_TRACK_ERROR", s[s.UNPUBLISH_VIDEO_ERROR = 53310] = "UNPUBLISH_VIDEO_ERROR", s[s.CONVERSATION_NOT_GROUP_ERROR = 53311] = "CONVERSATION_NOT_GROUP_ERROR", s[s.NOT_IN_ROOM_ERROR = 53312] = "NOT_IN_ROOM_ERROR", s[s.PARAM_ERROR = 53313] = "PARAM_ERROR", s))(l || {}), g = /* @__PURE__ */ ((s) => (s[s.CANCEL = 1] = "CANCEL", s[s.REJECT = 2] = "REJECT", s[s.HANGUP = 3] = "HANGUP", s[s.BUSY_LINE = 4] = "BUSY_LINE", s[s.NO_RESPONSE = 5] = "NO_RESPONSE", s[s.ENGINE_UNSUPPORTED = 6] = "ENGINE_UNSUPPORTED", s[s.NETWORK_ERROR = 7] = "NETWORK_ERROR", s[s.GET_MEDIA_RESOURCES_ERROR = 8] = "GET_MEDIA_RESOURCES_ERROR", s[s.PUBLISH_ERROR = 9] = "PUBLISH_ERROR", s[s.SUBSCRIBE_ERROR = 10] = "SUBSCRIBE_ERROR", s[s.REMOTE_CANCEL = 11] = "REMOTE_CANCEL", s[s.REMOTE_REJECT = 12] = "REMOTE_REJECT", s[s.REMOTE_HANGUP = 13] = "REMOTE_HANGUP", s[s.REMOTE_BUSY_LINE = 14] = "REMOTE_BUSY_LINE", s[s.REMOTE_NO_RESPONSE = 15] = "REMOTE_NO_RESPONSE", s[s.REMOTE_ENGINE_UNSUPPORTED = 16] = "REMOTE_ENGINE_UNSUPPORTED", s[s.REMOTE_NETWORK_ERROR = 17] = "REMOTE_NETWORK_ERROR", s[s.REMOTE_GET_MEDIA_RESOURCE_ERROR = 18] = "REMOTE_GET_MEDIA_RESOURCE_ERROR", s[s.REMOTE_PUBLISH_ERROR = 19] = "REMOTE_PUBLISH_ERROR", s[s.REMOTE_SUBSCRIBE_ERROR = 20] = "REMOTE_SUBSCRIBE_ERROR", s[s.OTHER_CLIENT_JOINED_CALL = 21] = "OTHER_CLIENT_JOINED_CALL", s[s.OTHER_CLIENT_IN_CALL = 22] = "OTHER_CLIENT_IN_CALL", s[s.KICKED_BY_SERVER = 23] = "KICKED_BY_SERVER", s[s.ACCEPT_SYSTEM_CALL = 24] = "ACCEPT_SYSTEM_CALL", s[s.REMOTE_OTHER_CLIENT_JOINED_CALL = 31] = "REMOTE_OTHER_CLIENT_JOINED_CALL", s[s.REMOTE_OTHER_CLIENT_IN_CALL = 32] = "REMOTE_OTHER_CLIENT_IN_CALL", s[s.REMOTE_KICKED_BY_SERVER = 33] = "REMOTE_KICKED_BY_SERVER", s[s.REMOTE_ACCEPT_SYSTEM_CALL = 34] = "REMOTE_ACCEPT_SYSTEM_CALL", s[s.ACCEPT_BY_OTHER_CLIENT = 101] = "ACCEPT_BY_OTHER_CLIENT", s[s.HANGUP_BY_OTHER_CLIENT = 102] = "HANGUP_BY_OTHER_CLIENT", s[s.ADDED_TO_BLACKLIST = 103] = "ADDED_TO_BLACKLIST", s[s.SERVICE_NOT_OPENED = 104] = "SERVICE_NOT_OPENED", s))(g || {});
|
|
31
|
-
const G = {
|
|
32
|
-
[
|
|
33
|
-
1
|
|
34
|
-
/* CANCEL */
|
|
35
|
-
]: 11,
|
|
36
|
-
[
|
|
37
|
-
2
|
|
38
|
-
/* REJECT */
|
|
39
|
-
]: 12,
|
|
40
|
-
[
|
|
41
|
-
3
|
|
42
|
-
/* HANGUP */
|
|
43
|
-
]: 13,
|
|
44
|
-
[
|
|
45
|
-
4
|
|
46
|
-
/* BUSY_LINE */
|
|
47
|
-
]: 14,
|
|
48
|
-
[
|
|
49
|
-
5
|
|
50
|
-
/* NO_RESPONSE */
|
|
51
|
-
]: 15,
|
|
52
|
-
[
|
|
53
|
-
6
|
|
54
|
-
/* ENGINE_UNSUPPORTED */
|
|
55
|
-
]: 16,
|
|
56
|
-
[
|
|
57
|
-
7
|
|
58
|
-
/* NETWORK_ERROR */
|
|
59
|
-
]: 17,
|
|
60
|
-
[
|
|
61
|
-
8
|
|
62
|
-
/* GET_MEDIA_RESOURCES_ERROR */
|
|
63
|
-
]: 18,
|
|
64
|
-
[
|
|
65
|
-
9
|
|
66
|
-
/* PUBLISH_ERROR */
|
|
67
|
-
]: 19,
|
|
68
|
-
[
|
|
69
|
-
10
|
|
70
|
-
/* SUBSCRIBE_ERROR */
|
|
71
|
-
]: 20,
|
|
72
|
-
[
|
|
73
|
-
21
|
|
74
|
-
/* OTHER_CLIENT_JOINED_CALL */
|
|
75
|
-
]: 31,
|
|
76
|
-
[
|
|
77
|
-
22
|
|
78
|
-
/* OTHER_CLIENT_IN_CALL */
|
|
79
|
-
]: 32,
|
|
80
|
-
[
|
|
81
|
-
23
|
|
82
|
-
/* KICKED_BY_SERVER */
|
|
83
|
-
]: 33,
|
|
84
|
-
[
|
|
85
|
-
15
|
|
86
|
-
/* REMOTE_NO_RESPONSE */
|
|
87
|
-
]: 5,
|
|
88
|
-
[
|
|
89
|
-
24
|
|
90
|
-
/* ACCEPT_SYSTEM_CALL */
|
|
91
|
-
]: 34
|
|
92
|
-
/* REMOTE_ACCEPT_SYSTEM_CALL */
|
|
93
|
-
};
|
|
94
|
-
var R = /* @__PURE__ */ ((s) => (s.VCInvite = "RC:VCInvite", s.VCRinging = "RC:VCRinging", s.VCAccept = "RC:VCAccept", s.VCHangup = "RC:VCHangup", s.VCModifyMem = "RC:VCModifyMem", s.VCModifyMedia = "RC:VCModifyMedia", s))(R || {}), T = /* @__PURE__ */ ((s) => (s[s.WAITING = 0] = "WAITING", s[s.KEEPING = 1] = "KEEPING", s[s.END = 2] = "END", s))(T || {}), m = /* @__PURE__ */ ((s) => (s[s.NONE = 0] = "NONE", s[s.WAITING = 1] = "WAITING", s[s.KEEPING = 2] = "KEEPING", s))(m || {}), $ = /* @__PURE__ */ ((s) => (s[s.RCCallRoomTypeNormalCall = 0] = "RCCallRoomTypeNormalCall", s[s.RCCallRoomTypeAcrossCall = 7] = "RCCallRoomTypeAcrossCall", s))($ || {});
|
|
95
|
-
let V = class {
|
|
96
|
-
constructor(e, t) {
|
|
97
|
-
f(this, "_timerId", 0);
|
|
98
|
-
f(this, "_startTime", 0);
|
|
99
|
-
e && (this._timerId = Re(() => {
|
|
100
|
-
e();
|
|
101
|
-
}, t)), this._startTime = Date.now();
|
|
102
|
-
}
|
|
103
|
-
stop() {
|
|
104
|
-
clearTimeout(this._timerId);
|
|
105
|
-
const e = Date.now();
|
|
106
|
-
let t = e - this._startTime;
|
|
107
|
-
return this._startTime === 0 && (t = 0), {
|
|
108
|
-
startTime: this._startTime,
|
|
109
|
-
endTime: e,
|
|
110
|
-
duration: t
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
reset() {
|
|
114
|
-
this._startTime = 0;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
class F {
|
|
118
|
-
constructor(e, t, i, n, o, r, a, h, c) {
|
|
119
|
-
/**
|
|
120
|
-
* 房间状态
|
|
121
|
-
*/
|
|
122
|
-
f(this, "_sessionState", null);
|
|
123
|
-
/**
|
|
124
|
-
* 用户状态及信息
|
|
125
|
-
*/
|
|
126
|
-
f(this, "_userInfo", {});
|
|
127
|
-
/**
|
|
128
|
-
* 用户计时器映射
|
|
129
|
-
*/
|
|
130
|
-
f(this, "_userTimers", {});
|
|
131
|
-
/**
|
|
132
|
-
* 监听器
|
|
133
|
-
*/
|
|
134
|
-
f(this, "_watchers");
|
|
135
|
-
/**
|
|
136
|
-
* 呼叫超时时间 (单位:毫秒)
|
|
137
|
-
*/
|
|
138
|
-
f(this, "_callTimeout", 60 * 1e3);
|
|
139
|
-
/**
|
|
140
|
-
* 通话建立开始时间
|
|
141
|
-
*/
|
|
142
|
-
f(this, "_beginTimestamp", 0);
|
|
143
|
-
/**
|
|
144
|
-
* 通话结束时间
|
|
145
|
-
*/
|
|
146
|
-
f(this, "_endTimestamp", 0);
|
|
147
|
-
/**
|
|
148
|
-
* 通话结束原因
|
|
149
|
-
*/
|
|
150
|
-
f(this, "_endReason", null);
|
|
151
|
-
/**
|
|
152
|
-
* 主叫 ID
|
|
153
|
-
* 发起邀请为当前用户 ID
|
|
154
|
-
* 收到邀请为 senderUserId
|
|
155
|
-
* 收到人员变更邀请为消息体中 callerId
|
|
156
|
-
*/
|
|
157
|
-
f(this, "_callerId", null);
|
|
158
|
-
/**
|
|
159
|
-
* 当次通话邀请者 ID
|
|
160
|
-
* 发起邀请为当前用户 ID、收到邀请为 senderUserId、收到人员变更邀请为消息体中 senderUserId
|
|
161
|
-
*/
|
|
162
|
-
f(this, "_inviterId", null);
|
|
163
|
-
/**
|
|
164
|
-
* 是否是跨 appkey
|
|
165
|
-
*/
|
|
166
|
-
f(this, "_isCrossAppkey", !1);
|
|
167
|
-
f(this, "_hungupPushConfig");
|
|
168
|
-
this._context = e, this._runtime = t, this._logger = i, this._callMsgHandler = n, this._channelId = o, this._conversationType = r, this._targetId = a, this._mediaType = h, this._callId = c, this._callMsgHandler.registerStateMachineEvent(this._callId, "onRinging", this._onRinging.bind(this)), this._callMsgHandler.registerStateMachineEvent(this._callId, "onAccept", this._onAccept.bind(this)), this._callMsgHandler.registerStateMachineEvent(this._callId, "onMediaModify", this._onMediaModify.bind(this)), this._callMsgHandler.registerStateMachineEvent(this._callId, "onHungup", this._onHungup.bind(this));
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* 获取校正后超时时间
|
|
172
|
-
*/
|
|
173
|
-
_getTimeout(e) {
|
|
174
|
-
let t = this._context.getServerTime() - e;
|
|
175
|
-
t < 0 && (t = 500);
|
|
176
|
-
const i = this._callTimeout - t;
|
|
177
|
-
return this._logger.warn("_", `_getTimeout -> timeout: ${i}`), i;
|
|
178
|
-
}
|
|
179
|
-
_clearTimerById(e) {
|
|
180
|
-
this._logger.debug("_", `[RCCallStateMachine] before _clearTimerById -> userId: ${e} userTimers: ${JSON.stringify(this._userTimers)}`), this._userTimers[e] && (this._userTimers[e].stop(), delete this._userTimers[e]), this._logger.debug("_", `[RCCallStateMachine] after _clearTimerById -> userTimers: ${JSON.stringify(this._userTimers)}`);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* 通知 call 层房间状态变更及原因
|
|
184
|
-
*/
|
|
185
|
-
_notifyStateChange(e, t) {
|
|
186
|
-
var i;
|
|
187
|
-
this._logger.warn("_", `[RCCallStateMachine] notifyStateChange -> info: ${JSON.stringify({
|
|
188
|
-
state: e,
|
|
189
|
-
reason: t
|
|
190
|
-
})}`), this._endReason = t || null, this._sessionState !== e && (this._sessionState = e, (i = this._watchers) == null || i.onStateChange({ state: e, reason: t })), e === T.END && (re.emit("onStateMachineClose", this._callId), this._callMsgHandler.unregisterStateMachineEvent(this._callId));
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* 通知 call 层人员状态变更及原因
|
|
194
|
-
*/
|
|
195
|
-
_notifyUserStateChange(e, t) {
|
|
196
|
-
var i;
|
|
197
|
-
this._logger.warn("_", `[RCCallStateMachine] notifyUserStateChange -> info: ${JSON.stringify({
|
|
198
|
-
user: e,
|
|
199
|
-
reason: t
|
|
200
|
-
})}`), (i = this._watchers) == null || i.onUserStateChange({ user: e, reason: t });
|
|
201
|
-
}
|
|
202
|
-
_otherClientHandle(e) {
|
|
203
|
-
const { senderUserId: t, content: { user: i, reason: n }, messageType: o } = e;
|
|
204
|
-
this._userInfo[t] = {
|
|
205
|
-
userId: t,
|
|
206
|
-
state: m.NONE,
|
|
207
|
-
isCaller: !1,
|
|
208
|
-
isRemote: !1
|
|
209
|
-
};
|
|
210
|
-
for (const a in this._userTimers)
|
|
211
|
-
this._clearTimerById(a);
|
|
212
|
-
let r = g.ACCEPT_BY_OTHER_CLIENT;
|
|
213
|
-
o === R.VCHangup && (n === g.BUSY_LINE ? r = g.OTHER_CLIENT_IN_CALL : n === g.NO_RESPONSE ? r = g.NO_RESPONSE : r = g.HANGUP_BY_OTHER_CLIENT), Object.assign(this._userInfo[t], i), this._notifyUserStateChange(this._userInfo[t], r), this._notifyStateChange(T.END, r);
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* 正在通话中,且不是当前已接通用户设备(deviceId)发来的消息
|
|
217
|
-
*/
|
|
218
|
-
_isRemoteInvalidMsg(e, t) {
|
|
219
|
-
return !this._userInfo[e] || !this._userInfo[e].deviceId || !t ? !1 : this._userInfo[e].state === m.KEEPING && this._userInfo[e].deviceId !== t;
|
|
220
|
-
}
|
|
221
|
-
_onRinging(e) {
|
|
222
|
-
const { senderUserId: t, content: { user: i, deviceId: n } } = e, o = this._isCrossAppkey ? t.split("_")[1] : t;
|
|
223
|
-
if (this._isRemoteInvalidMsg(o, n)) {
|
|
224
|
-
this._logger.debug("_", "[RCCallStateMachine] onRinging -> not the remote device that is currently talking");
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
this._context.getCurrentId() !== o && this._watchers.onRinging({ userId: o, ...i });
|
|
228
|
-
}
|
|
229
|
-
_onAccept(e) {
|
|
230
|
-
const { senderUserId: t, content: { user: i, deviceId: n }, sentTime: o } = e, r = this._isCrossAppkey ? t.split("_")[1] : t, a = this._context.getCurrentId();
|
|
231
|
-
if (this._isRemoteInvalidMsg(r, n)) {
|
|
232
|
-
this._logger.debug("_", "[RCCallStateMachine] _onAccept -> not the remote device that is currently talking");
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
if (a === r) {
|
|
236
|
-
this._otherClientHandle(e);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
this._userTimers[r] && this._clearTimerById(r), (this._conversationType === D.PRIVATE ? [a, r] : [r]).forEach((c) => {
|
|
240
|
-
const _ = c === a;
|
|
241
|
-
this._userInfo[c] = {
|
|
242
|
-
userId: c,
|
|
243
|
-
state: m.KEEPING,
|
|
244
|
-
isCaller: _,
|
|
245
|
-
isRemote: _,
|
|
246
|
-
deviceId: _ ? Z(this._runtime) : n
|
|
247
|
-
}, _ || (this._beginTimestamp = Date.now(), Object.assign(this._userInfo[r], i)), this._notifyUserStateChange(this._userInfo[c]);
|
|
248
|
-
}), this.getCallerId() === a && this._notifyStateChange(T.KEEPING), this._watchers.onAccept({ userId: r });
|
|
249
|
-
}
|
|
250
|
-
_onMediaModify(e) {
|
|
251
|
-
const { senderUserId: t, content: { mediaType: i, user: n, deviceId: o } } = e;
|
|
252
|
-
if (this._isRemoteInvalidMsg(t, o)) {
|
|
253
|
-
this._logger.debug("_", "[RCCallStateMachine] _onMediaModify -> not the remote device that is currently talking");
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
this._context.getCurrentId() !== t && (this._mediaType = i, this._watchers.onMediaModify({
|
|
257
|
-
sender: { userId: t, ...n },
|
|
258
|
-
mediaType: i
|
|
259
|
-
}));
|
|
260
|
-
}
|
|
261
|
-
_onHungup(e) {
|
|
262
|
-
const { senderUserId: t, content: i } = e, n = this._isCrossAppkey ? t.split("_")[1] : t, { reason: o, user: r, deviceId: a } = i, h = this._context.getCurrentId();
|
|
263
|
-
if (this._isRemoteInvalidMsg(n, a)) {
|
|
264
|
-
this._logger.debug("_", "[RCCallStateMachine] _onHungup -> not the remote device that is currently talking");
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
if (h === n) {
|
|
268
|
-
this._otherClientHandle(e);
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
if (this._sessionState === T.END) {
|
|
272
|
-
this._logger.info("_", `[RCCallStateMachine] Invalid hang up message, current room status has ended -> sessionState: ${this._sessionState}`);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
this._userInfo[n] && (this._userInfo[n].state = m.NONE, this._endTimestamp = Date.now(), Object.assign(this._userInfo[n], r), this._notifyUserStateChange(this._userInfo[n], G[o]), delete this._userInfo[n]), G[o] === g.REMOTE_CANCEL ? this.getRemoteUserIds().length < 1 && this._clearTimerById(h) : this.getInviterId() === h ? this._clearTimerById(n) : this.getRemoteUserIds().length < 1 && this._clearTimerById(h);
|
|
276
|
-
const c = Object.keys(this._userInfo).length < 2, _ = this._inviterId === n, u = Object.values(this._userInfo).every((S) => S.state !== m.KEEPING);
|
|
277
|
-
(c || _ && u) && this._notifyStateChange(T.END, G[o]), this._watchers.onHungup({ userId: n, ...r }, G[o]);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* 注册事件监听
|
|
281
|
-
* @params watchers
|
|
282
|
-
*/
|
|
283
|
-
registerEventListener(e) {
|
|
284
|
-
this._watchers = e;
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* 收到 invite 消息时状态机更新(CallEngine 内部调用)
|
|
288
|
-
* @param message 接收消息
|
|
289
|
-
*/
|
|
290
|
-
__onInvite(e) {
|
|
291
|
-
const { senderUserId: t, content: i, sentTime: n } = e, {
|
|
292
|
-
inviteUserIds: o,
|
|
293
|
-
user: r,
|
|
294
|
-
deviceId: a,
|
|
295
|
-
roomType: h
|
|
296
|
-
} = i;
|
|
297
|
-
let c;
|
|
298
|
-
h === $.RCCallRoomTypeAcrossCall ? ([, c] = t.split("_"), this._watchers.crossAppkey(!0), this._isCrossAppkey = !0) : c = t;
|
|
299
|
-
const _ = this._context.getCurrentId();
|
|
300
|
-
if (this._isRemoteInvalidMsg(c, a)) {
|
|
301
|
-
this._logger.debug("_", "[RCCallStateMachine] __onInvite -> not the remote device that is currently talking");
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
if (_ === c)
|
|
305
|
-
return;
|
|
306
|
-
this._callerId = this._inviterId = c;
|
|
307
|
-
const u = [t, ...o];
|
|
308
|
-
this._callMsgHandler.sendRinging({
|
|
309
|
-
conversationType: this._conversationType,
|
|
310
|
-
targetId: this._targetId,
|
|
311
|
-
channelId: this._channelId,
|
|
312
|
-
callId: this._callId,
|
|
313
|
-
userIds: u.filter((d) => this._isCrossAppkey ? d.split("_")[1] !== _ : d !== _)
|
|
314
|
-
});
|
|
315
|
-
const S = this._isCrossAppkey ? [o[0].split("_")[1]] : o;
|
|
316
|
-
[c, ...S].forEach((d) => {
|
|
317
|
-
this._userInfo[d] = {
|
|
318
|
-
userId: d,
|
|
319
|
-
state: m.WAITING,
|
|
320
|
-
isCaller: d === c,
|
|
321
|
-
isRemote: d !== _
|
|
322
|
-
}, d === c && Object.assign(this._userInfo[d], r, { deviceId: a }), this._notifyUserStateChange(this._userInfo[d]), d !== c && (this._userTimers[d] = new V(() => {
|
|
323
|
-
const y = d === _ ? g.NO_RESPONSE : g.REMOTE_NO_RESPONSE;
|
|
324
|
-
d === _ ? this._hungupHandle(y) : (this._userInfo[d] && (this._userInfo[d].state = m.NONE), this._notifyUserStateChange(this._userInfo[d]), this._watchers.onHungup(this._userInfo[d], y), delete this._userInfo[d]);
|
|
325
|
-
}, this._getTimeout(n)));
|
|
326
|
-
}), this._notifyStateChange(T.WAITING);
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* 收到 memberModify 消息时状态机更新(CallEngine 内部调用)
|
|
330
|
-
* @param message 接收消息
|
|
331
|
-
*/
|
|
332
|
-
__onMemberModify(e) {
|
|
333
|
-
const { senderUserId: t, content: i, sentTime: n } = e, {
|
|
334
|
-
user: o,
|
|
335
|
-
existedUserPofiles: r,
|
|
336
|
-
caller: a,
|
|
337
|
-
deviceId: h,
|
|
338
|
-
inviteUserIds: c,
|
|
339
|
-
mediaType: _
|
|
340
|
-
} = i, u = this._context.getCurrentId();
|
|
341
|
-
if (this._isRemoteInvalidMsg(t, h)) {
|
|
342
|
-
this._logger.debug("_", "[RCCallStateMachine] __onMemberModify -> not the remote device that is currently talking");
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (u === t)
|
|
346
|
-
return;
|
|
347
|
-
if (this._callerId = a, this._inviterId = t, c.forEach((C) => {
|
|
348
|
-
r.push({ userId: C, mediaType: _, callStatus: b.INCOMING });
|
|
349
|
-
}), c.includes(u)) {
|
|
350
|
-
const C = [];
|
|
351
|
-
r.forEach((d) => {
|
|
352
|
-
d.userId !== u && C.push(d.userId);
|
|
353
|
-
}), this._callMsgHandler.sendRinging({
|
|
354
|
-
conversationType: this._conversationType,
|
|
355
|
-
targetId: this._targetId,
|
|
356
|
-
channelId: this._channelId,
|
|
357
|
-
callId: this._callId,
|
|
358
|
-
userIds: C
|
|
359
|
-
}), this._notifyStateChange(T.WAITING);
|
|
360
|
-
} else
|
|
361
|
-
this._watchers.onMemberModify({
|
|
362
|
-
sender: { userId: t, ...o },
|
|
363
|
-
invitedUsers: c.map((C) => ({ userId: C }))
|
|
364
|
-
});
|
|
365
|
-
r.forEach((C) => {
|
|
366
|
-
const { userId: d, callStatus: y } = C;
|
|
367
|
-
if (y !== b.IDLE && (this._userInfo[d] = {
|
|
368
|
-
userId: d,
|
|
369
|
-
state: y !== b.CONNECTED ? m.WAITING : m.KEEPING,
|
|
370
|
-
isCaller: t === d,
|
|
371
|
-
isRemote: u !== d
|
|
372
|
-
}, d === t && Object.assign(this._userInfo[d], o, { deviceId: h }), this._notifyUserStateChange(this._userInfo[d]), y !== b.CONNECTED && !this._userTimers[d])) {
|
|
373
|
-
if (!c.includes(d))
|
|
374
|
-
return;
|
|
375
|
-
this._userTimers[d] = new V(() => {
|
|
376
|
-
this._userInfo[d] && (this._userInfo[d].state = m.NONE);
|
|
377
|
-
const U = d === u ? g.NO_RESPONSE : g.REMOTE_NO_RESPONSE;
|
|
378
|
-
this._notifyUserStateChange(this._userInfo[d], U);
|
|
379
|
-
try {
|
|
380
|
-
this._watchers.onHungup(this._userInfo[d], U);
|
|
381
|
-
} catch (E) {
|
|
382
|
-
this._logger.error("_", `[RCCallStateMachine] call onhungup error -> ${E == null ? void 0 : E.stack}`);
|
|
383
|
-
}
|
|
384
|
-
delete this._userInfo[d], (Object.keys(this._userInfo).length < 2 || d === u) && this._notifyStateChange(T.END, U);
|
|
385
|
-
}, this._getTimeout(n));
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* 处理已有 session ,不允许再接听新会话情况
|
|
391
|
-
*/
|
|
392
|
-
__handleInviteInSession() {
|
|
393
|
-
this._logger.info("_", "StateMachine -> __handleInviteInSession");
|
|
394
|
-
for (const e in this._userInfo)
|
|
395
|
-
this._userInfo[e].state && (this._userInfo[e].state = m.NONE), this._notifyUserStateChange(this._userInfo[e]), this._clearTimerById(e);
|
|
396
|
-
this._notifyStateChange(T.END, g.BUSY_LINE), this._callMsgHandler.sendHungup({
|
|
397
|
-
channelId: this._channelId,
|
|
398
|
-
conversationType: this._conversationType,
|
|
399
|
-
targetId: this._targetId,
|
|
400
|
-
callId: this._callId,
|
|
401
|
-
reason: g.BUSY_LINE,
|
|
402
|
-
userIds: this.getRemoteUserIds()
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* 主动呼叫 (CallEngine 内部调用)
|
|
407
|
-
* @param userIds 被邀请用户 ID 列表
|
|
408
|
-
* @param extra 消息的扩展信息
|
|
409
|
-
* @param pushConfig 移动端推送配置
|
|
410
|
-
*/
|
|
411
|
-
async __call(e, t = "", i, n = !1) {
|
|
412
|
-
this._logger.debug("_", `[RCCallStateMachine] invite -> userIds: ${JSON.stringify(e)}`);
|
|
413
|
-
const o = this._callerId = this._inviterId = this._context.getCurrentId(), { code: r, message: a } = await this._callMsgHandler.sendInvite({
|
|
414
|
-
roomType: n ? $.RCCallRoomTypeAcrossCall : $.RCCallRoomTypeNormalCall,
|
|
415
|
-
channelId: this._channelId,
|
|
416
|
-
conversationType: this._conversationType,
|
|
417
|
-
targetId: this._targetId,
|
|
418
|
-
callId: this._callId,
|
|
419
|
-
extra: t,
|
|
420
|
-
pushConfig: i,
|
|
421
|
-
mediaType: this._mediaType,
|
|
422
|
-
inviteUserIds: e.filter((h) => h !== o)
|
|
423
|
-
});
|
|
424
|
-
if (this._isCrossAppkey = n, r === l.SUCCESS) {
|
|
425
|
-
const { sentTime: h } = a;
|
|
426
|
-
(n ? [o, e[0].split("_")[1]] : [o, ...e]).forEach((_) => {
|
|
427
|
-
const u = _ === o;
|
|
428
|
-
this._userInfo[_] = {
|
|
429
|
-
userId: _,
|
|
430
|
-
state: m.WAITING,
|
|
431
|
-
isCaller: u,
|
|
432
|
-
isRemote: !u
|
|
433
|
-
}, this._notifyUserStateChange(this._userInfo[_]), u || (this._userTimers[_] = new V(() => {
|
|
434
|
-
this._userInfo[_] && (this._userInfo[_].state = m.NONE), this._notifyUserStateChange(this._userInfo[_], g.REMOTE_NO_RESPONSE), this._watchers.onHungup(this._userInfo[_], g.REMOTE_NO_RESPONSE), delete this._userInfo[_], Object.keys(this._userInfo).length < 2 && this._notifyStateChange(T.END, g.REMOTE_NO_RESPONSE), this.getRemoteUserIds().length === 0 && this._userInfo[o].state !== m.KEEPING && this._hungupHandle(g.REMOTE_NO_RESPONSE);
|
|
435
|
-
}, this._getTimeout(h)));
|
|
436
|
-
}), this._notifyStateChange(T.WAITING);
|
|
437
|
-
} else {
|
|
438
|
-
const h = r === l.REJECTED_BY_BLACKLIST ? g.ADDED_TO_BLACKLIST : g.NETWORK_ERROR;
|
|
439
|
-
this._notifyStateChange(T.END, h);
|
|
440
|
-
}
|
|
441
|
-
return { code: r };
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* 接听
|
|
445
|
-
*/
|
|
446
|
-
async accept() {
|
|
447
|
-
this._logger.debug("_", "[RCCallStateMachine] accept");
|
|
448
|
-
const e = this._context.getCurrentId(), { code: t, message: i } = await this._callMsgHandler.sendAccept({
|
|
449
|
-
channelId: this._channelId,
|
|
450
|
-
conversationType: this._conversationType,
|
|
451
|
-
targetId: this._targetId,
|
|
452
|
-
callId: this._callId,
|
|
453
|
-
mediaType: this._mediaType,
|
|
454
|
-
userIds: this.getRemoteUserIds()
|
|
455
|
-
});
|
|
456
|
-
if (this._clearTimerById(e), t === l.SUCCESS)
|
|
457
|
-
this._userInfo[e] && (this._userInfo[e].state = m.KEEPING), this._beginTimestamp = Date.now(), this._notifyUserStateChange(this._userInfo[e]), this._notifyStateChange(T.KEEPING);
|
|
458
|
-
else {
|
|
459
|
-
this._userInfo[e] && (this._userInfo[e].state = m.NONE), this._notifyUserStateChange(this._userInfo[e]);
|
|
460
|
-
const n = t === l.REJECTED_BY_BLACKLIST ? g.ADDED_TO_BLACKLIST : g.NETWORK_ERROR;
|
|
461
|
-
this._notifyStateChange(T.END, n);
|
|
462
|
-
}
|
|
463
|
-
return { code: t };
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* 群呼叫中继续邀请
|
|
467
|
-
* @param userIds 被邀请用户 ID 列表
|
|
468
|
-
*/
|
|
469
|
-
async invite(e, t = {}) {
|
|
470
|
-
if (this._conversationType !== D.GROUP)
|
|
471
|
-
return { code: l.CONVERSATION_NOT_GROUP_ERROR };
|
|
472
|
-
this._logger.debug("_", `[RCCallStateMachine] invite -> userIds: ${JSON.stringify(e)}`);
|
|
473
|
-
const i = this._context.getCurrentId(), n = Object.keys(this._userInfo), o = n.map((_) => {
|
|
474
|
-
let u = b.CONNECTED;
|
|
475
|
-
return (e.includes(_) || this._userInfo[_].state === m.WAITING) && (u = b.RINGING), {
|
|
476
|
-
userId: _,
|
|
477
|
-
mediaType: this._mediaType,
|
|
478
|
-
callStatus: u,
|
|
479
|
-
mediaId: _
|
|
480
|
-
};
|
|
481
|
-
}), { extra: r = "", pushConfig: a } = t, { code: h, message: c } = await this._callMsgHandler.sendMemeberModify({
|
|
482
|
-
channelId: this._channelId,
|
|
483
|
-
conversationType: this._conversationType,
|
|
484
|
-
targetId: this._targetId,
|
|
485
|
-
callId: this._callId,
|
|
486
|
-
extra: r,
|
|
487
|
-
pushConfig: a,
|
|
488
|
-
mediaType: this._mediaType,
|
|
489
|
-
// 除自己,其他所有人均需收到 modify 消息,以此更新状态
|
|
490
|
-
inviteUserIds: e.filter((_) => _ !== i),
|
|
491
|
-
callerId: this.getCallerId(),
|
|
492
|
-
existedUserPofiles: o,
|
|
493
|
-
directionalUserIdList: [...n, ...e].filter((_) => _ !== i)
|
|
494
|
-
});
|
|
495
|
-
if (h === l.SUCCESS) {
|
|
496
|
-
const { sentTime: _ } = c;
|
|
497
|
-
e.forEach((u) => {
|
|
498
|
-
this._userInfo[u] = {
|
|
499
|
-
userId: u,
|
|
500
|
-
state: m.WAITING,
|
|
501
|
-
isCaller: !1,
|
|
502
|
-
isRemote: !0
|
|
503
|
-
}, this._notifyUserStateChange(this._userInfo[u]), this._userTimers[u] = new V(() => {
|
|
504
|
-
this._userInfo[u] && (this._userInfo[u].state = m.NONE), this._notifyUserStateChange(this._userInfo[u], g.REMOTE_NO_RESPONSE), this._watchers.onHungup(this._userInfo[u], g.REMOTE_NO_RESPONSE), delete this._userInfo[u], Object.keys(this._userInfo).length < 2 && this._notifyStateChange(T.END, g.REMOTE_NO_RESPONSE);
|
|
505
|
-
}, this._getTimeout(_));
|
|
506
|
-
});
|
|
507
|
-
} else
|
|
508
|
-
e.forEach((_) => {
|
|
509
|
-
this._userInfo[_] = {
|
|
510
|
-
userId: _,
|
|
511
|
-
state: m.NONE,
|
|
512
|
-
isCaller: !1,
|
|
513
|
-
isRemote: !0
|
|
514
|
-
};
|
|
515
|
-
const u = h === l.REJECTED_BY_BLACKLIST ? g.ADDED_TO_BLACKLIST : g.NETWORK_ERROR;
|
|
516
|
-
this._notifyUserStateChange(this._userInfo[_], u);
|
|
517
|
-
});
|
|
518
|
-
return { code: h };
|
|
519
|
-
}
|
|
520
|
-
async _hungupHandle(e) {
|
|
521
|
-
const t = this._context.getCurrentId();
|
|
522
|
-
let i = l.SUCCESS;
|
|
523
|
-
const n = {
|
|
524
|
-
channelId: this._channelId,
|
|
525
|
-
conversationType: this._conversationType,
|
|
526
|
-
targetId: this._targetId,
|
|
527
|
-
callId: this._callId,
|
|
528
|
-
reason: e,
|
|
529
|
-
userIds: this.getRemoteUserIds(),
|
|
530
|
-
pushConfig: this._hungupPushConfig
|
|
531
|
-
};
|
|
532
|
-
if (e === g.OTHER_CLIENT_JOINED_CALL)
|
|
533
|
-
this._callMsgHandler.sendHungup(n);
|
|
534
|
-
else {
|
|
535
|
-
const { code: o } = await this._callMsgHandler.sendHungup(n);
|
|
536
|
-
i = o;
|
|
537
|
-
}
|
|
538
|
-
this._endTimestamp = Date.now();
|
|
539
|
-
for (const o in this._userInfo)
|
|
540
|
-
this._userInfo[o].state = m.NONE, o === t ? this._notifyUserStateChange(this._userInfo[o], e) : this._notifyUserStateChange(this._userInfo[o]), delete this._userInfo[o];
|
|
541
|
-
return Object.keys(this._userInfo).length < 2 && this._notifyStateChange(T.END, e), { code: i };
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* 挂断
|
|
545
|
-
*/
|
|
546
|
-
async hungup() {
|
|
547
|
-
this._logger.debug("_", "[RCCallStateMachine] hungup");
|
|
548
|
-
const e = this._context.getCurrentId();
|
|
549
|
-
let t = g.HANGUP;
|
|
550
|
-
Object.keys(this._userTimers).length > 0 && (this._userInfo[e].isCaller ? t = g.CANCEL : this._userInfo[e].state === m.WAITING && (t = g.REJECT));
|
|
551
|
-
for (const i in this._userTimers)
|
|
552
|
-
this._clearTimerById(i);
|
|
553
|
-
return this._hungupHandle(t);
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* 修改通话媒体类型
|
|
557
|
-
* @param mediaType RCCallMediaType.AUDIO 改为音频通话 | RCCallMediaType.AUDIO_VIDEO 改为音视频通话
|
|
558
|
-
*/
|
|
559
|
-
async changeMediaType(e) {
|
|
560
|
-
this._logger.debug("_", `[RCCallStateMachine] changeMediaType -> mediaType: ${e}`);
|
|
561
|
-
const { code: t } = await this._callMsgHandler.sendMediaModify({
|
|
562
|
-
channelId: this._channelId,
|
|
563
|
-
conversationType: this._conversationType,
|
|
564
|
-
targetId: this._targetId,
|
|
565
|
-
callId: this._callId,
|
|
566
|
-
mediaType: e,
|
|
567
|
-
userIds: this.getRemoteUserIds()
|
|
568
|
-
});
|
|
569
|
-
return t === l.SUCCESS && (this._mediaType = e), { code: t };
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* 用户加入通话补偿机制(rtc userJoin 事件触发)
|
|
573
|
-
* 主叫呼叫后,未收到被叫 accept 消息,但收到了 userJoin 同样补偿更新用户、房间状态、呼叫计时器
|
|
574
|
-
*/
|
|
575
|
-
userJoin(e) {
|
|
576
|
-
this._logger.debug("_", `[RCCallStateMachine] userJoin -> userIds: ${JSON.stringify(e)}`), setTimeout(() => {
|
|
577
|
-
e.forEach((t) => {
|
|
578
|
-
const i = this._userInfo[t];
|
|
579
|
-
i && i.state !== m.KEEPING && (i.state = m.KEEPING, this._notifyUserStateChange(i)), this._sessionState !== T.KEEPING && this._notifyStateChange(T.KEEPING), this._clearTimerById(t);
|
|
580
|
-
});
|
|
581
|
-
}, 300);
|
|
582
|
-
}
|
|
583
|
-
/**
|
|
584
|
-
* 用户离开通话补偿机制(rtc userLeave、kickOff 事件触发)
|
|
585
|
-
* 通话中远端用户挂断,挂断消息未到,但是监听到 rtc userLeave 同样补偿更新用户、房间状态
|
|
586
|
-
*/
|
|
587
|
-
userLeave(e) {
|
|
588
|
-
this._logger.debug("_", `[RCCallStateMachine] userLeave -> userIds: ${JSON.stringify(e)}`), setTimeout(() => {
|
|
589
|
-
e.forEach((t) => {
|
|
590
|
-
const i = this._userInfo[t];
|
|
591
|
-
i && i.state !== m.NONE && (i.state = m.NONE, this._notifyUserStateChange(i, g.REMOTE_HANGUP), this._watchers.onHungup(i, g.REMOTE_HANGUP), delete this._userInfo[t]), new V(() => {
|
|
592
|
-
const n = this.getRemoteUsers();
|
|
593
|
-
n.length === 1 && n[0].state === 1 && this._hungupHandle(g.REMOTE_NETWORK_ERROR);
|
|
594
|
-
}, 6e4), Object.keys(this._userInfo).length < 2 && this._sessionState !== T.END && (this._endTimestamp = Date.now(), this._notifyStateChange(T.END, g.REMOTE_HANGUP));
|
|
595
|
-
});
|
|
596
|
-
}, 300);
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Call 层己方异常失败后调用的方法
|
|
600
|
-
* 触发时机:音视频服务异常、获取资源失败、加入 RTC 房间失败、发布|订阅失败
|
|
601
|
-
*/
|
|
602
|
-
close(e) {
|
|
603
|
-
this._hungupHandle(e);
|
|
604
|
-
}
|
|
605
|
-
setHungupPushConfig(e) {
|
|
606
|
-
this._hungupPushConfig = e;
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* 通话唯一标识
|
|
610
|
-
*/
|
|
611
|
-
getCallId() {
|
|
612
|
-
return this._callId;
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* 多组织 ID
|
|
616
|
-
*/
|
|
617
|
-
getChannelId() {
|
|
618
|
-
return this._channelId;
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* 目标 ID,单呼对方人员 Id, 群呼群组 Id
|
|
622
|
-
*/
|
|
623
|
-
getTargetId() {
|
|
624
|
-
return this._targetId;
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* 获取会话类型
|
|
628
|
-
*/
|
|
629
|
-
getConversationType() {
|
|
630
|
-
return this._conversationType;
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* 获取远端成员 ID 列表
|
|
634
|
-
*/
|
|
635
|
-
getRemoteUserIds() {
|
|
636
|
-
return Object.keys(this._userInfo).filter((i) => this._context.getCurrentId() !== i);
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* 获取远端成员信息列表
|
|
640
|
-
*/
|
|
641
|
-
getRemoteUsers() {
|
|
642
|
-
const e = [], t = this._context.getCurrentId();
|
|
643
|
-
for (const i in this._userInfo) {
|
|
644
|
-
const { userId: n } = this._userInfo[i];
|
|
645
|
-
n !== t && e.push(this._userInfo[i]);
|
|
646
|
-
}
|
|
647
|
-
return e;
|
|
648
|
-
}
|
|
649
|
-
/**
|
|
650
|
-
* 获取房间状态
|
|
651
|
-
*/
|
|
652
|
-
getState() {
|
|
653
|
-
return this._sessionState === null ? T.END : this._sessionState;
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* 获取人员状态
|
|
657
|
-
*/
|
|
658
|
-
getUserState(e) {
|
|
659
|
-
var t;
|
|
660
|
-
return (t = this._userInfo[e]) == null ? void 0 : t.state;
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* 获取会话发起者 Id
|
|
664
|
-
*/
|
|
665
|
-
getCallerId() {
|
|
666
|
-
return this._callerId;
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* 获取当次会话邀请者 Id
|
|
670
|
-
*/
|
|
671
|
-
getInviterId() {
|
|
672
|
-
return this._inviterId;
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* 获取当前通话媒体类型
|
|
676
|
-
*/
|
|
677
|
-
getMediaType() {
|
|
678
|
-
return this._mediaType;
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* 通话挂断后可调用
|
|
682
|
-
*/
|
|
683
|
-
getSummary() {
|
|
684
|
-
const e = this._beginTimestamp, t = this._endTimestamp;
|
|
685
|
-
let i = 0;
|
|
686
|
-
t > e && e !== 0 && (i = t - e);
|
|
687
|
-
const n = {
|
|
688
|
-
conversationType: this._conversationType,
|
|
689
|
-
channelId: this._channelId,
|
|
690
|
-
targetId: this._targetId,
|
|
691
|
-
mediaType: this._mediaType,
|
|
692
|
-
beginTimestamp: e,
|
|
693
|
-
endTimestamp: t,
|
|
694
|
-
duration: i,
|
|
695
|
-
endReason: this._endReason
|
|
696
|
-
};
|
|
697
|
-
return this._logger.debug("_", `[RCCallStateMachine] getSummary -> summary: ${JSON.stringify(n)}`), n;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
var O = /* @__PURE__ */ ((s) => (s[s.AUDIO = 1] = "AUDIO", s[s.AUDIO_VIDEO = 2] = "AUDIO_VIDEO", s))(O || {}), ae = /* @__PURE__ */ ((s) => (s[s.ADD = 1] = "ADD", s[s.REMOVE = 2] = "REMOVE", s))(ae || {}), w = /* @__PURE__ */ ((s) => (s.WEB = "Web", s.IOS = "iOS", s.ANDROID = "Android", s))(w || {});
|
|
701
|
-
class Ce {
|
|
702
|
-
constructor(e, t, i) {
|
|
703
|
-
f(this, "_messages", []);
|
|
704
|
-
f(this, "_channelId");
|
|
705
|
-
f(this, "_conversationType");
|
|
706
|
-
f(this, "_targetId");
|
|
707
|
-
f(this, "_mediaType");
|
|
708
|
-
f(this, "_callId");
|
|
709
|
-
f(this, "_callerId");
|
|
710
|
-
f(this, "_inviterId");
|
|
711
|
-
f(this, "_endReason");
|
|
712
|
-
f(this, "_beginTimestamp", 0);
|
|
713
|
-
f(this, "_endTimestamp", 0);
|
|
714
|
-
this._context = e, this._logger = t, this._onRecord = i;
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* 到 invite | memberModify 结束
|
|
718
|
-
* 原因根据己方是否为主叫,主叫为远端未接听 被叫被己端未接听
|
|
719
|
-
*/
|
|
720
|
-
_doInvite(e) {
|
|
721
|
-
const t = this._context.getCurrentId(), {
|
|
722
|
-
channelId: i,
|
|
723
|
-
conversationType: n,
|
|
724
|
-
targetId: o,
|
|
725
|
-
senderUserId: r,
|
|
726
|
-
content: a
|
|
727
|
-
} = e, { callId: h, mediaType: c } = a;
|
|
728
|
-
this._channelId = i, this._conversationType = n, this._targetId = o, this._callId = h, this._mediaType = c;
|
|
729
|
-
const _ = r === t;
|
|
730
|
-
this._inviterId = r, this._endReason = g.REMOTE_NO_RESPONSE, this._canGenRecord();
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* 到 invite | memberModify 结束
|
|
734
|
-
* 原因根据己方是否为主叫,主叫为远端未接听 被叫被己端未接听
|
|
735
|
-
*/
|
|
736
|
-
_doMemberModify(e) {
|
|
737
|
-
this._doInvite(e);
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* 用 invite | memberModify 计算的离线记录
|
|
741
|
-
*/
|
|
742
|
-
_doRinging(e) {
|
|
743
|
-
this._canGenRecord();
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* 到 accept 说明通话已建立
|
|
747
|
-
* 原因默认己方正常挂断
|
|
748
|
-
*/
|
|
749
|
-
_doAccept(e) {
|
|
750
|
-
this._endReason = g.HANGUP, this._beginTimestamp = e.sentTime, this._canGenRecord();
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* 到 hungup 说明为正常挂断
|
|
754
|
-
* 原因取消息体里挂断原因
|
|
755
|
-
*/
|
|
756
|
-
_doHungup(e) {
|
|
757
|
-
const { content: t, sentTime: i, senderUserId: n } = e, { reason: o } = t, r = this._context.getCurrentId(), a = n === r;
|
|
758
|
-
this._endReason = a ? o : G[o], this._endTimestamp = i, this._canGenRecord();
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* 只修改通话类型
|
|
762
|
-
*/
|
|
763
|
-
_doMediaModify(e) {
|
|
764
|
-
const { content: t } = e, { mediaType: i } = t;
|
|
765
|
-
this._mediaType = i, this._canGenRecord();
|
|
766
|
-
}
|
|
767
|
-
_canGenRecord() {
|
|
768
|
-
if (this._messages.length === 0) {
|
|
769
|
-
let e = 0;
|
|
770
|
-
[
|
|
771
|
-
g.HANGUP,
|
|
772
|
-
g.REMOTE_HANGUP,
|
|
773
|
-
g.OTHER_CLIENT_JOINED_CALL,
|
|
774
|
-
g.REMOTE_OTHER_CLIENT_JOINED_CALL,
|
|
775
|
-
g.KICKED_BY_SERVER,
|
|
776
|
-
g.REMOTE_KICKED_BY_SERVER,
|
|
777
|
-
g.ACCEPT_SYSTEM_CALL,
|
|
778
|
-
g.REMOTE_ACCEPT_SYSTEM_CALL
|
|
779
|
-
].includes(this._endReason) && (e = this._endTimestamp - this._beginTimestamp), this._onRecord({
|
|
780
|
-
channelId: this._channelId,
|
|
781
|
-
conversationType: this._conversationType,
|
|
782
|
-
targetId: this._targetId,
|
|
783
|
-
callId: this._callId,
|
|
784
|
-
inviterId: this._inviterId,
|
|
785
|
-
mediaType: this._mediaType,
|
|
786
|
-
endReason: this._endReason,
|
|
787
|
-
beginTimestamp: this._beginTimestamp,
|
|
788
|
-
endTimestamp: this._endTimestamp,
|
|
789
|
-
duration: e
|
|
790
|
-
});
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
onRecvOfflineMsgs(e) {
|
|
794
|
-
this._messages = e;
|
|
795
|
-
do {
|
|
796
|
-
const t = this._messages.shift(), { messageType: i, content: { callId: n } } = t;
|
|
797
|
-
switch (i) {
|
|
798
|
-
case R.VCInvite:
|
|
799
|
-
this._doInvite(t);
|
|
800
|
-
break;
|
|
801
|
-
case R.VCRinging:
|
|
802
|
-
this._doRinging(t);
|
|
803
|
-
break;
|
|
804
|
-
case R.VCAccept:
|
|
805
|
-
this._doAccept(t);
|
|
806
|
-
break;
|
|
807
|
-
case R.VCModifyMem:
|
|
808
|
-
this._doMemberModify(t);
|
|
809
|
-
break;
|
|
810
|
-
case R.VCModifyMedia:
|
|
811
|
-
this._doMediaModify(t);
|
|
812
|
-
break;
|
|
813
|
-
case R.VCHangup:
|
|
814
|
-
this._doHungup(t);
|
|
815
|
-
break;
|
|
816
|
-
default:
|
|
817
|
-
this._logger.debug("_", `[OfflineRecorder] onRecvOfflineMsgs -> unexpected message: ${JSON.stringify(t)}`);
|
|
818
|
-
break;
|
|
819
|
-
}
|
|
820
|
-
} while (this._messages.length > 0);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
const Ee = ["RC:VCAccept", "RC:VCRinging", "RC:VCSummary", "RC:VCHangup", "RC:VCInvite", "RC:VCModifyMedia", "RC:VCModifyMem"], me = {
|
|
824
|
-
[W.REJECTED_BY_BLACKLIST]: l.REJECTED_BY_BLACKLIST,
|
|
825
|
-
[W.NOT_IN_GROUP]: l.NOT_IN_GROUP
|
|
826
|
-
};
|
|
827
|
-
class Te extends ie {
|
|
828
|
-
constructor(t, i, n, o = 60 * 1e3, r) {
|
|
829
|
-
super();
|
|
830
|
-
f(this, "_watchers", {});
|
|
831
|
-
f(this, "_userInfo", {});
|
|
832
|
-
f(this, "_msgBufferList", []);
|
|
833
|
-
f(this, "_hadHandleMsgTimer", !1);
|
|
834
|
-
f(this, "_offlineRecorder");
|
|
835
|
-
f(this, "_deviceId", "");
|
|
836
|
-
this._context = t, this._runtime = i, this._logger = n, this._offlineMsgItv = o, this._getStateMachine = r, this._deviceId = Z(i), this._context.onmessage = this._onMessage.bind(this), this._offlineRecorder = new Ce(this._context, this._logger, (a) => {
|
|
837
|
-
this._logger.info("_", `[CallMessageHandler] offlineRecorder -> ${JSON.stringify(a)}`), this._watchers.onOfflineRecord && this._watchers.onOfflineRecord(a);
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
_onMessage(t) {
|
|
841
|
-
if (Ee.includes(t.messageType)) {
|
|
842
|
-
this._logger.debug("_", `[CallMessageHandler] _onMessage -> call message: ${JSON.stringify(t)}`);
|
|
843
|
-
try {
|
|
844
|
-
const n = Date.now(), { sentTime: o } = t;
|
|
845
|
-
let r = 0;
|
|
846
|
-
this._msgBufferList.forEach(({ msg: { sentTime: a } }, h) => {
|
|
847
|
-
o >= a && (r = h + 1);
|
|
848
|
-
}), this._msgBufferList.splice(r, 0, {
|
|
849
|
-
markTime: n,
|
|
850
|
-
msg: t
|
|
851
|
-
}), this._logger.warn("_", `onMessage -> msgBufferList: ${this._msgBufferList.length}`);
|
|
852
|
-
} catch (n) {
|
|
853
|
-
this._logger.error("_", `[CallMessageHandler] splice buffer msg error -> ${n.message}`);
|
|
854
|
-
}
|
|
855
|
-
return this._handleBufferMsgs(), !0;
|
|
856
|
-
}
|
|
857
|
-
return !1;
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* 在线消息抛给状态机处理
|
|
861
|
-
*/
|
|
862
|
-
_onRecvOnlineCallMsg(t) {
|
|
863
|
-
this._logger.info("_", `onMessage -> _onRecvOnlineCallMsg: ${t.messageType}`);
|
|
864
|
-
const { content: { callId: i } } = t;
|
|
865
|
-
switch (t.messageType) {
|
|
866
|
-
case R.VCInvite:
|
|
867
|
-
this._watchers.onInvite && this._watchers.onInvite(t);
|
|
868
|
-
break;
|
|
869
|
-
case R.VCRinging:
|
|
870
|
-
super.emit(`${i}onRinging`, t);
|
|
871
|
-
break;
|
|
872
|
-
case R.VCAccept:
|
|
873
|
-
super.emit(`${i}onAccept`, t);
|
|
874
|
-
break;
|
|
875
|
-
case R.VCModifyMem:
|
|
876
|
-
this._watchers.onInvite && this._watchers.onInvite(t);
|
|
877
|
-
break;
|
|
878
|
-
case R.VCModifyMedia:
|
|
879
|
-
super.emit(`${i}onMediaModify`, t);
|
|
880
|
-
break;
|
|
881
|
-
case R.VCHangup:
|
|
882
|
-
super.emit(`${i}onHungup`, t);
|
|
883
|
-
break;
|
|
884
|
-
default:
|
|
885
|
-
this._logger.warn("_", `[CallMessageHandler] onRecvOnlineCallMsg -> unexpected message: ${JSON.stringify(t)}`);
|
|
886
|
-
break;
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
/**
|
|
890
|
-
* 消息 buffer 列表处理逻辑
|
|
891
|
-
* 1、每 20ms 检查一次 buffer list
|
|
892
|
-
* 2、取出已经延迟 200 的消息列表进行消费 | 无延迟 200ms 内消息直接递归
|
|
893
|
-
* 3、消费分为 离线消息消费逻辑、在线消息消费逻辑,消费后递归
|
|
894
|
-
*/
|
|
895
|
-
_handleBufferMsgs() {
|
|
896
|
-
if (this._msgBufferList.length === 0 || this._hadHandleMsgTimer) {
|
|
897
|
-
this._logger.warn("_", "_handleBufferMsgs return");
|
|
898
|
-
return;
|
|
899
|
-
}
|
|
900
|
-
this._hadHandleMsgTimer = !0, setTimeout(() => {
|
|
901
|
-
const t = Date.now(), i = this._msgBufferList.filter((n) => t - n.markTime >= 200);
|
|
902
|
-
if (this._logger.debug("_", `[CallMessageHandler] handleBufferMsgs -> lists over 200ms : ${JSON.stringify(i.map(({ msg: { messageUId: n, isOffLineMessage: o, content: { callId: r } } }) => ({ messageUId: n, isOffLineMessage: o, callId: r })))}`), i.length === 0) {
|
|
903
|
-
this._hadHandleMsgTimer = !1, this._handleBufferMsgs();
|
|
904
|
-
return;
|
|
905
|
-
}
|
|
906
|
-
if (i[0].msg.isOffLineMessage) {
|
|
907
|
-
let n = this._msgBufferList.filter((o) => o.msg.isOffLineMessage);
|
|
908
|
-
do {
|
|
909
|
-
const {
|
|
910
|
-
conversationType: o,
|
|
911
|
-
messageType: r,
|
|
912
|
-
sentTime: a,
|
|
913
|
-
senderUserId: h,
|
|
914
|
-
content: { callId: c, inviteUserIds: _ }
|
|
915
|
-
} = n[0].msg, u = [R.VCInvite, R.VCModifyMem].includes(r), S = this._context.getServerTime() - a, C = S < this._offlineMsgItv;
|
|
916
|
-
if (C || this._logger.warn("_", `offline msg delayTime: ${S}ms`), u) {
|
|
917
|
-
const d = [];
|
|
918
|
-
for (let E = 0; E < n.length; E++) {
|
|
919
|
-
const M = n[E].msg, { content: { callId: N } } = M;
|
|
920
|
-
if (c === N)
|
|
921
|
-
d.push(M);
|
|
922
|
-
else
|
|
923
|
-
break;
|
|
924
|
-
}
|
|
925
|
-
if (this._logger.warn("_", `taskMsgList length: ${d.length}`), d.length > 0) {
|
|
926
|
-
const E = this._msgBufferList.findIndex((N) => N.msg.messageUId === d[d.length - 1].messageUId);
|
|
927
|
-
this._msgBufferList = this._msgBufferList.slice(E + 1);
|
|
928
|
-
const M = n.findIndex((N) => N.msg.messageUId === d[d.length - 1].messageUId);
|
|
929
|
-
n = n.slice(M + 1);
|
|
930
|
-
}
|
|
931
|
-
const y = (() => {
|
|
932
|
-
if (o !== D.PRIVATE)
|
|
933
|
-
return !1;
|
|
934
|
-
const E = d.length === 1, M = d.every((N) => [R.VCInvite, R.VCModifyMedia, R.VCRinging].includes(N.messageType));
|
|
935
|
-
return E || M;
|
|
936
|
-
})(), U = (() => {
|
|
937
|
-
if (o !== D.GROUP)
|
|
938
|
-
return !1;
|
|
939
|
-
let E = !1, M = !0, N = [h, ..._], A = !1;
|
|
940
|
-
for (let v = 0; v < d.length; v++) {
|
|
941
|
-
const { senderUserId: I, messageType: L } = d[v];
|
|
942
|
-
if (L === R.VCHangup && I === this._context.getCurrentId())
|
|
943
|
-
break;
|
|
944
|
-
L === R.VCHangup && (A = h === I, N = N.filter((k) => I !== k)), L === R.VCAccept && (M = !1);
|
|
945
|
-
}
|
|
946
|
-
return !(M && A) && N.length > 1 && (E = !0), E;
|
|
947
|
-
})();
|
|
948
|
-
C && (y || U) && d.forEach(this._onRecvOnlineCallMsg, this), this._offlineRecorder.onRecvOfflineMsgs(d);
|
|
949
|
-
} else
|
|
950
|
-
C && this._getStateMachine(c) ? this._onRecvOnlineCallMsg(n[0].msg) : this._logger.debug("_", `[CallMessageHandler] unexcepted offline msg -> ${JSON.stringify(n[0].msg)}`), n.shift(), this._msgBufferList.shift();
|
|
951
|
-
} while (n.length > 0);
|
|
952
|
-
} else {
|
|
953
|
-
i.forEach(({ msg: o }) => {
|
|
954
|
-
this._onRecvOnlineCallMsg(o);
|
|
955
|
-
});
|
|
956
|
-
const n = i.length;
|
|
957
|
-
this._msgBufferList.splice(0, n), this._logger.debug("_", `timer online msg handle -> delCount: ${n} msgBufferList: ${this._msgBufferList.length}`);
|
|
958
|
-
}
|
|
959
|
-
this._hadHandleMsgTimer = !1, this._handleBufferMsgs();
|
|
960
|
-
}, 20);
|
|
961
|
-
}
|
|
962
|
-
registerEventListener(t) {
|
|
963
|
-
Object.assign(this._watchers, t);
|
|
964
|
-
}
|
|
965
|
-
registerStateMachineEvent(t, i, n) {
|
|
966
|
-
const o = t + i;
|
|
967
|
-
super.on(o, n);
|
|
968
|
-
}
|
|
969
|
-
unregisterStateMachineEvent(t) {
|
|
970
|
-
["onRinging", "onAccept", "onHungup", "onMediaModify"].forEach((i) => {
|
|
971
|
-
const n = t + i;
|
|
972
|
-
super.removeAll(n);
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
registerUserInfo(t) {
|
|
976
|
-
this._userInfo = t;
|
|
977
|
-
}
|
|
978
|
-
/**
|
|
979
|
-
* 发送 IM 消息
|
|
980
|
-
*/
|
|
981
|
-
async _sendCallMessage(t) {
|
|
982
|
-
this._logger.debug("_", `CallMessageHandler] sendCallMesage -> message: ${JSON.stringify(t)}`);
|
|
983
|
-
const {
|
|
984
|
-
channelId: i,
|
|
985
|
-
conversationType: n,
|
|
986
|
-
targetId: o,
|
|
987
|
-
content: r,
|
|
988
|
-
messageType: a,
|
|
989
|
-
directionalUserIdList: h,
|
|
990
|
-
pushConfig: c
|
|
991
|
-
} = t, _ = {
|
|
992
|
-
channelId: i,
|
|
993
|
-
messageType: a,
|
|
994
|
-
content: r,
|
|
995
|
-
directionalUserIdList: h
|
|
996
|
-
};
|
|
997
|
-
if ([R.VCInvite, R.VCModifyMem, R.VCHangup].includes(a)) {
|
|
998
|
-
const C = c || { pushTitle: "", pushContent: "", pushData: "" };
|
|
999
|
-
C.androidConfig = Object.assign((c == null ? void 0 : c.androidConfig) || {}, {
|
|
1000
|
-
categoryHW: "VOIP",
|
|
1001
|
-
categoryVivo: "IM"
|
|
1002
|
-
}), C.iOSConfig = Object.assign(C.iOSConfig || {}, {
|
|
1003
|
-
apnsCollapseId: r.callId
|
|
1004
|
-
}), C.disablePushTitle = !1, C.forceShowDetailContent = !1, _.pushConfig = C;
|
|
1005
|
-
}
|
|
1006
|
-
const { code: u, data: S } = await this._context.sendMessage(n, o, _);
|
|
1007
|
-
return u !== W.SUCCESS ? (this._logger.error("_", `CallMessageHandler] sendCallMesage error -> code: ${u}`), {
|
|
1008
|
-
code: me[u] || l.SEND_MSG_ERROR
|
|
1009
|
-
}) : { code: l.SUCCESS, message: S };
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* 发送邀请消息
|
|
1013
|
-
*/
|
|
1014
|
-
async sendInvite(t) {
|
|
1015
|
-
const {
|
|
1016
|
-
roomType: i,
|
|
1017
|
-
channelId: n,
|
|
1018
|
-
conversationType: o,
|
|
1019
|
-
targetId: r,
|
|
1020
|
-
callId: a,
|
|
1021
|
-
mediaType: h,
|
|
1022
|
-
inviteUserIds: c,
|
|
1023
|
-
extra: _,
|
|
1024
|
-
pushConfig: u
|
|
1025
|
-
} = t;
|
|
1026
|
-
this._logger.warn("_", "CallMessageHandler] sendCallMesage sendInvite", JSON.stringify(t)), this._watchers.sendAccept && this._watchers.sendAccept({ callId: a });
|
|
1027
|
-
const S = {
|
|
1028
|
-
platform: w.WEB,
|
|
1029
|
-
deviceId: this._deviceId,
|
|
1030
|
-
callId: a,
|
|
1031
|
-
roomType: i,
|
|
1032
|
-
extra: _,
|
|
1033
|
-
engineType: 4,
|
|
1034
|
-
channelInfo: { Id: a, Key: "" },
|
|
1035
|
-
mediaType: h,
|
|
1036
|
-
inviteUserIds: c,
|
|
1037
|
-
observerUserIds: [],
|
|
1038
|
-
user: this._userInfo
|
|
1039
|
-
};
|
|
1040
|
-
return u && (u.pushData = JSON.stringify({
|
|
1041
|
-
mediaType: h,
|
|
1042
|
-
userIdList: c,
|
|
1043
|
-
callId: a
|
|
1044
|
-
})), this._sendCallMessage({
|
|
1045
|
-
channelId: n,
|
|
1046
|
-
conversationType: o,
|
|
1047
|
-
targetId: r,
|
|
1048
|
-
content: S,
|
|
1049
|
-
messageType: R.VCInvite,
|
|
1050
|
-
directionalUserIdList: o === D.GROUP ? c : [r],
|
|
1051
|
-
pushConfig: u
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
/**
|
|
1055
|
-
* 发送人员变更消息
|
|
1056
|
-
*/
|
|
1057
|
-
async sendMemeberModify(t) {
|
|
1058
|
-
const {
|
|
1059
|
-
channelId: i,
|
|
1060
|
-
conversationType: n,
|
|
1061
|
-
targetId: o,
|
|
1062
|
-
callId: r,
|
|
1063
|
-
mediaType: a,
|
|
1064
|
-
inviteUserIds: h,
|
|
1065
|
-
callerId: c,
|
|
1066
|
-
existedUserPofiles: _,
|
|
1067
|
-
directionalUserIdList: u,
|
|
1068
|
-
extra: S,
|
|
1069
|
-
pushConfig: C
|
|
1070
|
-
} = t, d = {
|
|
1071
|
-
platform: w.WEB,
|
|
1072
|
-
// TODO 与 IM 一致
|
|
1073
|
-
deviceId: this._deviceId,
|
|
1074
|
-
callId: r,
|
|
1075
|
-
extra: S,
|
|
1076
|
-
engineType: 4,
|
|
1077
|
-
channelInfo: { Id: r, Key: "" },
|
|
1078
|
-
mediaType: a,
|
|
1079
|
-
inviteUserIds: h,
|
|
1080
|
-
observerUserIds: [],
|
|
1081
|
-
user: this._userInfo,
|
|
1082
|
-
caller: c,
|
|
1083
|
-
modifyMemType: ae.ADD,
|
|
1084
|
-
existedUserPofiles: _
|
|
1085
|
-
};
|
|
1086
|
-
return C && (C.pushData = JSON.stringify({
|
|
1087
|
-
mediaType: a,
|
|
1088
|
-
userIdList: h,
|
|
1089
|
-
callId: r
|
|
1090
|
-
})), this._sendCallMessage({
|
|
1091
|
-
channelId: i,
|
|
1092
|
-
conversationType: n,
|
|
1093
|
-
targetId: o,
|
|
1094
|
-
content: d,
|
|
1095
|
-
messageType: R.VCModifyMem,
|
|
1096
|
-
directionalUserIdList: u,
|
|
1097
|
-
pushConfig: C
|
|
1098
|
-
});
|
|
1099
|
-
}
|
|
1100
|
-
/**
|
|
1101
|
-
* 发送响铃消息
|
|
1102
|
-
*/
|
|
1103
|
-
sendRinging(t) {
|
|
1104
|
-
const {
|
|
1105
|
-
channelId: i,
|
|
1106
|
-
conversationType: n,
|
|
1107
|
-
targetId: o,
|
|
1108
|
-
callId: r,
|
|
1109
|
-
userIds: a
|
|
1110
|
-
} = t, h = {
|
|
1111
|
-
platform: w.WEB,
|
|
1112
|
-
deviceId: this._deviceId,
|
|
1113
|
-
callId: r,
|
|
1114
|
-
user: this._userInfo
|
|
1115
|
-
};
|
|
1116
|
-
return this._sendCallMessage({
|
|
1117
|
-
channelId: i,
|
|
1118
|
-
conversationType: n,
|
|
1119
|
-
targetId: o,
|
|
1120
|
-
content: h,
|
|
1121
|
-
messageType: R.VCRinging,
|
|
1122
|
-
directionalUserIdList: a
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* 发送同意接听消息
|
|
1127
|
-
*/
|
|
1128
|
-
sendAccept(t) {
|
|
1129
|
-
const {
|
|
1130
|
-
channelId: i,
|
|
1131
|
-
conversationType: n,
|
|
1132
|
-
targetId: o,
|
|
1133
|
-
callId: r,
|
|
1134
|
-
mediaType: a,
|
|
1135
|
-
userIds: h
|
|
1136
|
-
} = t, c = {
|
|
1137
|
-
platform: w.WEB,
|
|
1138
|
-
deviceId: this._deviceId,
|
|
1139
|
-
callId: r,
|
|
1140
|
-
mediaType: a,
|
|
1141
|
-
user: this._userInfo
|
|
1142
|
-
};
|
|
1143
|
-
return this._sendCallMessage({
|
|
1144
|
-
channelId: i,
|
|
1145
|
-
conversationType: n,
|
|
1146
|
-
targetId: o,
|
|
1147
|
-
content: c,
|
|
1148
|
-
messageType: R.VCAccept,
|
|
1149
|
-
directionalUserIdList: h
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* 发送挂断消息
|
|
1154
|
-
*/
|
|
1155
|
-
sendHungup(t) {
|
|
1156
|
-
const {
|
|
1157
|
-
channelId: i,
|
|
1158
|
-
conversationType: n,
|
|
1159
|
-
targetId: o,
|
|
1160
|
-
callId: r,
|
|
1161
|
-
reason: a,
|
|
1162
|
-
userIds: h,
|
|
1163
|
-
pushConfig: c
|
|
1164
|
-
} = t, _ = {
|
|
1165
|
-
platform: w.WEB,
|
|
1166
|
-
deviceId: this._deviceId,
|
|
1167
|
-
callId: r,
|
|
1168
|
-
reason: a,
|
|
1169
|
-
user: this._userInfo
|
|
1170
|
-
};
|
|
1171
|
-
return c && (c.pushData = JSON.stringify({
|
|
1172
|
-
callId: r,
|
|
1173
|
-
reason: a
|
|
1174
|
-
})), this._sendCallMessage({
|
|
1175
|
-
channelId: i,
|
|
1176
|
-
conversationType: n,
|
|
1177
|
-
targetId: o,
|
|
1178
|
-
content: _,
|
|
1179
|
-
messageType: R.VCHangup,
|
|
1180
|
-
pushConfig: c,
|
|
1181
|
-
directionalUserIdList: h
|
|
1182
|
-
});
|
|
1183
|
-
}
|
|
1184
|
-
/**
|
|
1185
|
-
* 发送媒体变更消息
|
|
1186
|
-
*/
|
|
1187
|
-
sendMediaModify(t) {
|
|
1188
|
-
const {
|
|
1189
|
-
channelId: i,
|
|
1190
|
-
conversationType: n,
|
|
1191
|
-
targetId: o,
|
|
1192
|
-
callId: r,
|
|
1193
|
-
mediaType: a,
|
|
1194
|
-
userIds: h
|
|
1195
|
-
} = t, c = {
|
|
1196
|
-
platform: w.WEB,
|
|
1197
|
-
deviceId: this._deviceId,
|
|
1198
|
-
callId: r,
|
|
1199
|
-
mediaType: a,
|
|
1200
|
-
user: this._userInfo
|
|
1201
|
-
};
|
|
1202
|
-
return this._sendCallMessage({
|
|
1203
|
-
channelId: i,
|
|
1204
|
-
conversationType: n,
|
|
1205
|
-
targetId: o,
|
|
1206
|
-
content: c,
|
|
1207
|
-
messageType: R.VCModifyMedia,
|
|
1208
|
-
directionalUserIdList: h
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
var P = /* @__PURE__ */ ((s) => (s.ZH = "zh", s.EN = "en", s))(P || {});
|
|
1213
|
-
const Se = {
|
|
1214
|
-
PushTitle: {
|
|
1215
|
-
AUDIO: "You have a voice call",
|
|
1216
|
-
VIDEO: "You have a video call"
|
|
1217
|
-
}
|
|
1218
|
-
}, pe = {
|
|
1219
|
-
PushTitle: {
|
|
1220
|
-
AUDIO: "您有一条音频通话",
|
|
1221
|
-
VIDEO: "您有一条视频通话"
|
|
1222
|
-
}
|
|
1223
|
-
};
|
|
1224
|
-
class ce {
|
|
1225
|
-
static set(e) {
|
|
1226
|
-
this._lang = e;
|
|
1227
|
-
}
|
|
1228
|
-
static get() {
|
|
1229
|
-
return this._lang === P.EN ? Se : pe;
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
f(ce, "_lang", P.ZH);
|
|
1233
|
-
class Oe {
|
|
1234
|
-
/**
|
|
1235
|
-
* 初始化
|
|
1236
|
-
*/
|
|
1237
|
-
constructor(e, t, i, n, o) {
|
|
1238
|
-
f(this, "_stateMachine", {});
|
|
1239
|
-
f(this, "_callMsgHandler");
|
|
1240
|
-
this._context = e, this._runtime = t, this._logger = i, this._watchers = n, this._options = o, this._logger.warn("_", "RCCallEngine Version: 5.2.4 CommitId: 0a7b424ef05373eeea5ff3c35af1286656a750fd"), Z(t), this._callMsgHandler = new Te(this._context, this._runtime, this._logger, this._options.offlineMsgItv, this._getStateMachine.bind(this)), this._callMsgHandler.registerEventListener({
|
|
1241
|
-
onInvite: this._onInvite.bind(this),
|
|
1242
|
-
sendAccept: this._handleSendAccept.bind(this),
|
|
1243
|
-
onOfflineRecord: this._watchers.onOfflineRecord
|
|
1244
|
-
}), re.on("onStateMachineClose", (r) => {
|
|
1245
|
-
delete this._stateMachine[r];
|
|
1246
|
-
}), ce.set(o.lang);
|
|
1247
|
-
}
|
|
1248
|
-
_onInvite(e) {
|
|
1249
|
-
const {
|
|
1250
|
-
channelId: t,
|
|
1251
|
-
conversationType: i,
|
|
1252
|
-
targetId: n,
|
|
1253
|
-
content: o,
|
|
1254
|
-
messageType: r,
|
|
1255
|
-
senderUserId: a,
|
|
1256
|
-
pushConfig: h
|
|
1257
|
-
} = e;
|
|
1258
|
-
this._logger.warn("_", `RCCallEngine _onInvite:targetId ${n} senderUserId: ${a}`);
|
|
1259
|
-
const {
|
|
1260
|
-
mediaType: c,
|
|
1261
|
-
callId: _,
|
|
1262
|
-
extra: u,
|
|
1263
|
-
roomType: S
|
|
1264
|
-
} = o;
|
|
1265
|
-
let C;
|
|
1266
|
-
S !== $.RCCallRoomTypeAcrossCall ? C = a : [, C] = a.split("_");
|
|
1267
|
-
const d = this._context.getCurrentId();
|
|
1268
|
-
if (this._context.getCurrentId() === C || r === R.VCModifyMem && o.existedUserPofiles.some((E) => E.userId === d) && !this._stateMachine[_])
|
|
1269
|
-
return;
|
|
1270
|
-
this._stateMachine[_] ? r === R.VCModifyMem && this._stateMachine[_].__onMemberModify(e) : (this._stateMachine[_] = new F(
|
|
1271
|
-
this._context,
|
|
1272
|
-
this._runtime,
|
|
1273
|
-
this._logger,
|
|
1274
|
-
this._callMsgHandler,
|
|
1275
|
-
t,
|
|
1276
|
-
i,
|
|
1277
|
-
n,
|
|
1278
|
-
c,
|
|
1279
|
-
_
|
|
1280
|
-
), this._logger.info("_", `[RCCallEngine] RCCallStateMachine successfully created -> callId: ${_}`), r === R.VCInvite ? this._stateMachine[_].__onInvite(e) : r === R.VCModifyMem && this._stateMachine[_].__onMemberModify(e), this._watchers.onInvite(this._stateMachine[_], u), Object.keys(this._stateMachine).filter((E) => _ !== E).length > 0 && !this._options.isAllowAcceptNewCall && this._stateMachine[_].__handleInviteInSession());
|
|
1281
|
-
}
|
|
1282
|
-
/**
|
|
1283
|
-
* 允许接听新的通话时,接听完新的通话后,挂断其他通话
|
|
1284
|
-
*/
|
|
1285
|
-
_handleSendAccept(e) {
|
|
1286
|
-
if (this._options.isAllowAcceptNewCall) {
|
|
1287
|
-
const { callId: t } = e;
|
|
1288
|
-
for (const i in this._stateMachine)
|
|
1289
|
-
t !== i && (this._stateMachine[i].hungup(), delete this._stateMachine[i]);
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
/**
|
|
1293
|
-
* 根据 callId 获取状态机
|
|
1294
|
-
*/
|
|
1295
|
-
_getStateMachine(e) {
|
|
1296
|
-
return this._stateMachine[e];
|
|
1297
|
-
}
|
|
1298
|
-
/**
|
|
1299
|
-
* 注册用户信息, 发送 call 消息时用户信息携带
|
|
1300
|
-
*/
|
|
1301
|
-
registerUserInfo(e) {
|
|
1302
|
-
this._logger.debug("_", `[RCCallEngine] registerUserInfo -> userInfo: ${JSON.stringify(e)}`), this._callMsgHandler.registerUserInfo(e);
|
|
1303
|
-
}
|
|
1304
|
-
/**
|
|
1305
|
-
* 单呼
|
|
1306
|
-
* @param channelId 组织 ID
|
|
1307
|
-
* @param targetId 对方 ID
|
|
1308
|
-
* @param mediaType 媒体类型
|
|
1309
|
-
* @param extra 消息扩展信息
|
|
1310
|
-
* @param pushConfig 推送配置
|
|
1311
|
-
*/
|
|
1312
|
-
async call(e, t, i, n = "", o, r = !1) {
|
|
1313
|
-
this._logger.debug("_", `[RCCallEngine] call -> args: ${JSON.stringify({
|
|
1314
|
-
channelId: e,
|
|
1315
|
-
targetId: t,
|
|
1316
|
-
mediaType: i,
|
|
1317
|
-
extra: n,
|
|
1318
|
-
pushConfig: o
|
|
1319
|
-
})}`);
|
|
1320
|
-
const a = ee();
|
|
1321
|
-
if (Object.keys(this._stateMachine).length > 0)
|
|
1322
|
-
return { code: l.STATE_MACHINE_EXIT };
|
|
1323
|
-
this._stateMachine[a] = new F(
|
|
1324
|
-
this._context,
|
|
1325
|
-
this._runtime,
|
|
1326
|
-
this._logger,
|
|
1327
|
-
this._callMsgHandler,
|
|
1328
|
-
e,
|
|
1329
|
-
D.PRIVATE,
|
|
1330
|
-
t,
|
|
1331
|
-
i,
|
|
1332
|
-
a
|
|
1333
|
-
);
|
|
1334
|
-
const { code: c } = await this._stateMachine[a].__call([t], n, o, r);
|
|
1335
|
-
return c === l.SUCCESS ? {
|
|
1336
|
-
code: l.SUCCESS,
|
|
1337
|
-
stateMachine: this._stateMachine[a]
|
|
1338
|
-
} : { code: c };
|
|
1339
|
-
}
|
|
1340
|
-
/**
|
|
1341
|
-
* 群呼
|
|
1342
|
-
* @param channelId 组织 ID
|
|
1343
|
-
* @param targetId 群组 ID
|
|
1344
|
-
* @param mediaType 媒体类型
|
|
1345
|
-
* @param userIds 被邀请人员列表
|
|
1346
|
-
* @param extra 消息扩展信息
|
|
1347
|
-
* @param pushConfig 推送配置
|
|
1348
|
-
*/
|
|
1349
|
-
async callInGroup(e, t, i, n, o = "", r) {
|
|
1350
|
-
this._logger.debug("_", `[RCCallEngine] callInGroup -> args: ${JSON.stringify({ channelId: e, targetId: t, mediaType: i })}`);
|
|
1351
|
-
const a = ee();
|
|
1352
|
-
if (Object.keys(this._stateMachine).length > 0)
|
|
1353
|
-
return { code: l.STATE_MACHINE_EXIT };
|
|
1354
|
-
this._stateMachine[a] = new F(
|
|
1355
|
-
this._context,
|
|
1356
|
-
this._runtime,
|
|
1357
|
-
this._logger,
|
|
1358
|
-
this._callMsgHandler,
|
|
1359
|
-
e,
|
|
1360
|
-
D.GROUP,
|
|
1361
|
-
t,
|
|
1362
|
-
i,
|
|
1363
|
-
a
|
|
1364
|
-
);
|
|
1365
|
-
const { code: c } = await this._stateMachine[a].__call(n, o, r);
|
|
1366
|
-
return c === l.SUCCESS ? {
|
|
1367
|
-
code: l.SUCCESS,
|
|
1368
|
-
stateMachine: this._stateMachine[a]
|
|
1369
|
-
} : { code: c };
|
|
1370
|
-
}
|
|
1371
|
-
/**
|
|
1372
|
-
* 销毁当前的状态机
|
|
1373
|
-
*/
|
|
1374
|
-
destroy() {
|
|
1375
|
-
this._logger.debug("_", "[RCCallEngine] destroy"), this._stateMachine = {};
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
var x = /* @__PURE__ */ ((s) => (s[s.CALLER = 1] = "CALLER", s[s.CALLEE = 2] = "CALLEE", s))(x || {});
|
|
1379
|
-
class ye {
|
|
1380
|
-
constructor() {
|
|
1381
|
-
f(this, "list", {});
|
|
1382
|
-
}
|
|
1383
|
-
on(e, t) {
|
|
1384
|
-
return (this.list[e] || (this.list[e] = [])).push(t), this;
|
|
1385
|
-
}
|
|
1386
|
-
once(e, t) {
|
|
1387
|
-
const i = (n) => {
|
|
1388
|
-
this.off(e, i), t.call(this, n);
|
|
1389
|
-
};
|
|
1390
|
-
i.fun = t, this.on(e, i);
|
|
1391
|
-
}
|
|
1392
|
-
off(e, t) {
|
|
1393
|
-
const i = this.list[e];
|
|
1394
|
-
if (!i)
|
|
1395
|
-
return !1;
|
|
1396
|
-
if (!t)
|
|
1397
|
-
i && (i.length = 0);
|
|
1398
|
-
else {
|
|
1399
|
-
let n;
|
|
1400
|
-
for (let o = 0, { length: r } = i; o < r; o++)
|
|
1401
|
-
if (n = i[o], n === t || n.fun === t) {
|
|
1402
|
-
i.splice(o, 1);
|
|
1403
|
-
break;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
emit(e, t) {
|
|
1408
|
-
const i = [...this.list[e]];
|
|
1409
|
-
if (!i || i.length === 0)
|
|
1410
|
-
return !1;
|
|
1411
|
-
i.forEach((n) => {
|
|
1412
|
-
n.call(this, t);
|
|
1413
|
-
});
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
const B = new ye();
|
|
1417
|
-
function Me(s) {
|
|
1418
|
-
return Object.values(P).includes(s);
|
|
1419
|
-
}
|
|
1420
|
-
function Ne(s) {
|
|
1421
|
-
return Object.values(ne).includes(s);
|
|
1422
|
-
}
|
|
1423
|
-
function Ae(s) {
|
|
1424
|
-
return [K.DEBUG, K.INFO, K.WARN, K.ERROR].includes(s);
|
|
1425
|
-
}
|
|
1426
|
-
const Ue = (s) => {
|
|
1427
|
-
if (!s)
|
|
1428
|
-
return { result: !1, msg: "Initialization missing parameter -> options" };
|
|
1429
|
-
if (typeof s != "object")
|
|
1430
|
-
return { result: !1, msg: "Initialization options must be an object" };
|
|
1431
|
-
const e = ["rtcClient", "onSession", "onSessionClose"], t = Object.keys(s), i = [];
|
|
1432
|
-
return e.forEach((n) => {
|
|
1433
|
-
t.includes(n) || i.push(n);
|
|
1434
|
-
}), i.length ? { result: !1, msg: `Initialization missing parameter -> "${i.join(",")}"` } : typeof s.rtcClient != "object" ? { result: !1, msg: "Initialization 'rtcClient' parameter must be of type 'object'" } : typeof s.onSession != "function" ? { result: !1, msg: "Initialization 'onSession' parameter must be of type 'function'" } : typeof s.onSessionClose != "function" ? { result: !1, msg: "Initialization 'onSessionClose' parameter must be of type 'function'" } : typeof s.isAllowSubscribeRetry < "u" && typeof s.isAllowSubscribeRetry != "boolean" ? { result: !1, msg: "Initialization 'isAllowSubscribeRetry' parameter must be of type 'boolean'" } : typeof s.isAllowPublishRetry < "u" && typeof s.isAllowPublishRetry != "boolean" ? { result: !1, msg: "Initialization 'isAllowPublishRetry' parameter must be of type 'boolean'" } : typeof s.isOffCameraWhenVideoDisable < "u" && typeof s.isOffCameraWhenVideoDisable != "boolean" ? { result: !1, msg: "Initialization 'isOffCameraWhenVideoDisable' parameter must be of type 'boolean'" } : typeof s.joinType < "u" && !Ne(s.joinType) ? { result: !1, msg: "Initialization 'joinType' parameter must be of type correct type" } : typeof s.isAllowDemotionGetStream < "u" && typeof s.isAllowDemotionGetStream != "boolean" ? { result: !1, msg: "Initialization 'isAllowDemotionGetStream' parameter must be of type 'boolean'" } : typeof s.lang < "u" && !Me(s.lang) ? { result: !1, msg: "Initialization 'lang' parameter must be of type correct type" } : typeof s.logOutputLevel < "u" && !Ae(s.logOutputLevel) ? { result: !1, msg: "Initialization 'logOutputLevel' parameter must be of type correct type" } : { result: !0 };
|
|
1435
|
-
}, j = (s) => {
|
|
1436
|
-
if (!s)
|
|
1437
|
-
return { result: !1, msg: "missing parameter -> listener" };
|
|
1438
|
-
if (typeof s != "object")
|
|
1439
|
-
return { result: !1, msg: "listener must be an object" };
|
|
1440
|
-
const e = ["onRinging", "onAccept", "onHungup", "onTrackReady"], t = Object.keys(s), i = [];
|
|
1441
|
-
return e.forEach((n) => {
|
|
1442
|
-
t.includes(n) || i.push(n);
|
|
1443
|
-
}), i.length ? { result: !1, msg: `missing parameter -> "${i.join(",")}"` } : typeof s.onRinging != "function" ? { result: !1, msg: "'onRinging' parameter must be of type 'function'" } : typeof s.onAccept != "function" ? { result: !1, msg: "'onAccept' parameter must be of type 'function'" } : typeof s.onHungup != "function" ? { result: !1, msg: "'onHungup' parameter must be of type 'function'" } : typeof s.onTrackReady != "function" ? { result: !1, msg: "'onTrackReady' parameter must be of type 'function'" } : { result: !0 };
|
|
1444
|
-
}, te = (s) => s && typeof s == "string" ? { result: !0 } : { result: !1, msg: "'targetId' parameter is required, must be of type 'string'" }, se = (s) => s === O.AUDIO || s === O.AUDIO_VIDEO ? { result: !0 } : { result: !1, msg: "'mediaType' parameter is required, must be of type 'RCCallMediaType'" }, X = (s) => typeof s == "string" ? { result: !0 } : { result: !1, msg: "'extra' parameter must be of type 'string'" }, J = (s) => {
|
|
1445
|
-
const e = ["pushTitle", "pushContent", "pushData", "iOSConfig", "androidConfig", "disablePushTitle", "templateId"];
|
|
1446
|
-
if (!Object.keys(s).every((a) => e.includes(a)))
|
|
1447
|
-
return {
|
|
1448
|
-
code: l.PARAM_ERROR,
|
|
1449
|
-
errorMsg: `right key: ${e.join(",")}`
|
|
1450
|
-
};
|
|
1451
|
-
for (let a = 0; a < e.length; a++) {
|
|
1452
|
-
const h = e[a];
|
|
1453
|
-
if (h === "disablePushTitle") {
|
|
1454
|
-
if (!ge(s[h]) && !de(s[h]))
|
|
1455
|
-
return {
|
|
1456
|
-
code: l.PARAM_ERROR,
|
|
1457
|
-
errorMsg: `${h} type is boolean`
|
|
1458
|
-
};
|
|
1459
|
-
} else if ((h === "pushTitle" || h === "templateId") && s[h] && !Y(s[h]))
|
|
1460
|
-
return {
|
|
1461
|
-
code: l.PARAM_ERROR,
|
|
1462
|
-
errorMsg: `${h} type is string`
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
|
-
const { iOSConfig: i, androidConfig: n } = s, o = ve(i || {});
|
|
1466
|
-
if (o.code !== l.SUCCESS)
|
|
1467
|
-
return o;
|
|
1468
|
-
const r = Le(n || {});
|
|
1469
|
-
return r.code !== l.SUCCESS ? r : { code: l.SUCCESS };
|
|
1470
|
-
}, ve = (s) => {
|
|
1471
|
-
const { threadId: e, richMediaUri: t } = s || {};
|
|
1472
|
-
return e && !Y(e) ? {
|
|
1473
|
-
code: l.PARAM_ERROR,
|
|
1474
|
-
errorMsg: "iOSConfig.threadId type is string"
|
|
1475
|
-
} : t && !Y(t) ? {
|
|
1476
|
-
code: l.PARAM_ERROR,
|
|
1477
|
-
errorMsg: "iOSConfig.richMediaUri type is string"
|
|
1478
|
-
} : { code: l.SUCCESS };
|
|
1479
|
-
}, Le = (s) => {
|
|
1480
|
-
const e = ["notificationId", "channelIdMi", "miLargeIconUrl", "channelIdHW", "categoryHW", "importanceHW", "imageUrlHW", "channelIdOPPO", "typeVivo", "categoryVivo", "fcmChannelId", "fcmCollapseKey", "fcmImageUrl", "importanceHonor", "imageUrlHonor"];
|
|
1481
|
-
if (!Object.keys(s).every((i) => e.includes(i)))
|
|
1482
|
-
return {
|
|
1483
|
-
code: l.PARAM_ERROR,
|
|
1484
|
-
errorMsg: `right key: ${e.join(",")}`
|
|
1485
|
-
};
|
|
1486
|
-
for (let i = 0; i < e.length; i++) {
|
|
1487
|
-
const n = e[i];
|
|
1488
|
-
if (n === "importanceHW" || n === "importanceHonor") {
|
|
1489
|
-
if (s[n] && s[n] !== "LOW" && s[n] !== "NORMAL")
|
|
1490
|
-
return {
|
|
1491
|
-
code: l.PARAM_ERROR,
|
|
1492
|
-
errorMsg: `androidConfig.${n} value is NORMAL|LOW`
|
|
1493
|
-
};
|
|
1494
|
-
} else if (s[n] && !Y(s[n]))
|
|
1495
|
-
return {
|
|
1496
|
-
code: l.PARAM_ERROR,
|
|
1497
|
-
errorMsg: `androidConfig.${n} type is string`
|
|
1498
|
-
};
|
|
1499
|
-
}
|
|
1500
|
-
return { code: l.SUCCESS };
|
|
1501
|
-
}, le = (s) => Array.isArray(s) ? s.length ? s.every((e) => typeof e == "string" && e.length > 0) ? { result: !0 } : { result: !1, msg: "'userIds' parameter is required" } : { result: !1, msg: "'userIds' parameter is required, must be of type 'string[]'" } : { result: !1, msg: "'userIds' parameter is required, must be of type 'string[]'" };
|
|
1502
|
-
function De(s) {
|
|
1503
|
-
return ["FPS_10", "FPS_15", "FPS_24", "FPS_30"].includes(s);
|
|
1504
|
-
}
|
|
1505
|
-
const ke = (s) => !!ue[s], be = (s) => s && s.audio && typeof s.audio.micphoneId < "u" && typeof s.audio.micphoneId != "string" ? { result: !1, msg: "'constraints.audio.micphoneId' must be of type 'string'" } : s && s.audio && typeof s.audio.sampleRate < "u" && typeof s.audio.sampleRate != "number" ? { result: !1, msg: "'constraints.audio.sampleRate' must be of type 'number'" } : s && s.video && typeof s.video.cameraId < "u" && typeof s.video.cameraId != "string" ? { result: !1, msg: "'constraints.video.cameraId' must be of type 'string'" } : s && s.video && typeof s.video.frameRate < "u" && typeof s.video.frameRate != "string" ? { result: !1, msg: "'constraints.video.frameRate' must be of type 'string'" } : s && s.video && typeof s.video.frameRate < "u" && !De(s.video.frameRate) ? { result: !1, msg: "'frameRate' value is out of range" } : s && s.video && typeof s.video.resolution < "u" && typeof s.video.resolution != "string" ? { result: !1, msg: "'constraints.video.frameRate' must be of type 'string'" } : s && s.video && typeof s.video.resolution < "u" && !ke(s.video.resolution) ? { result: !1, msg: "'resolution' value is out of range" } : s && s.video && (!s.video.frameRate || !s.video.resolution) ? { result: !1, msg: "'resolution' and 'resolution' is required" } : { result: !0 }, we = (s, e) => setTimeout(s, e);
|
|
1506
|
-
class Pe {
|
|
1507
|
-
constructor(e, t) {
|
|
1508
|
-
f(this, "_timerId", 0);
|
|
1509
|
-
f(this, "_startTime", 0);
|
|
1510
|
-
e && (this._timerId = we(() => {
|
|
1511
|
-
e();
|
|
1512
|
-
}, t)), this._startTime = Date.now();
|
|
1513
|
-
}
|
|
1514
|
-
stop() {
|
|
1515
|
-
clearTimeout(this._timerId);
|
|
1516
|
-
const e = Date.now();
|
|
1517
|
-
let t = e - this._startTime;
|
|
1518
|
-
return this._startTime === 0 && (t = 0), {
|
|
1519
|
-
startTime: this._startTime,
|
|
1520
|
-
endTime: e,
|
|
1521
|
-
duration: t
|
|
1522
|
-
};
|
|
1523
|
-
}
|
|
1524
|
-
reset() {
|
|
1525
|
-
this._startTime = 0;
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
class z {
|
|
1529
|
-
constructor(e, t, i, n = {}) {
|
|
1530
|
-
/**
|
|
1531
|
-
* RTC房间实例
|
|
1532
|
-
*/
|
|
1533
|
-
f(this, "_room");
|
|
1534
|
-
/**
|
|
1535
|
-
* 用户传进来的 对session的监听 (要在RCCallClient的_onInvite里判断,要求执行完onSession必须注册session的监听,所以这里是public)
|
|
1536
|
-
*/
|
|
1537
|
-
f(this, "_listener", null);
|
|
1538
|
-
/**
|
|
1539
|
-
* RTC订阅、发布重试的次数
|
|
1540
|
-
*/
|
|
1541
|
-
f(this, "_RETRYCOUNT", 2);
|
|
1542
|
-
/**
|
|
1543
|
-
* 加入房间定时器
|
|
1544
|
-
*/
|
|
1545
|
-
f(this, "joinRoomTimer", null);
|
|
1546
|
-
this._stateMachine = e, this._rtcClient = t, this._logger = i, this._options = n, this._stateMachine.registerEventListener({
|
|
1547
|
-
/**
|
|
1548
|
-
* 用户状态变更
|
|
1549
|
-
* @param info
|
|
1550
|
-
*/
|
|
1551
|
-
onUserStateChange: ({ user: o, reason: r }) => {
|
|
1552
|
-
this._logger.info("_", `[RCCallSession onUserStateChange] userId->${o == null ? void 0 : o.userId} state->${o == null ? void 0 : o.state} reason->${r}`);
|
|
1553
|
-
},
|
|
1554
|
-
/**
|
|
1555
|
-
* 房间状态变更
|
|
1556
|
-
* @param
|
|
1557
|
-
*/
|
|
1558
|
-
onStateChange: async (o) => {
|
|
1559
|
-
const { state: r, reason: a } = o;
|
|
1560
|
-
if (this._logger.info("_", `[RCCallSession onStateChange] : state->${r} reason->${a}`), r === T.KEEPING) {
|
|
1561
|
-
const h = this._stateMachine.getCallId();
|
|
1562
|
-
this._logger.info("_", `[RCCallSession onStateChange] roomId: ${h}`);
|
|
1563
|
-
try {
|
|
1564
|
-
await this._joinRoom(h);
|
|
1565
|
-
} catch (c) {
|
|
1566
|
-
this._exceptionClose(g.NETWORK_ERROR), this._logger.error("_", `[RCCallSession onStateChange] joinRoom throw exception roomId -> ${h}`), console.error(c);
|
|
1567
|
-
}
|
|
1568
|
-
} else if (r === T.END) {
|
|
1569
|
-
if (!this._room) {
|
|
1570
|
-
this._options.localTracks && this._destroyTracks(this._options.localTracks);
|
|
1571
|
-
const h = this._stateMachine.getSummary();
|
|
1572
|
-
B.emit("sessionClose", { session: this, summaryInfo: h });
|
|
1573
|
-
return;
|
|
1574
|
-
}
|
|
1575
|
-
this._options.localTracks && this._destroyTracks(this._options.localTracks), this._logger.info("_", "[RCCallSession onStateChange] localTracks destroyed"), this._leaveRoom(), this._room = null;
|
|
1576
|
-
}
|
|
1577
|
-
},
|
|
1578
|
-
/**
|
|
1579
|
-
* 收到响铃
|
|
1580
|
-
* @param sender 发起用户信息
|
|
1581
|
-
*/
|
|
1582
|
-
onRinging: (o) => {
|
|
1583
|
-
this._logger.info("_", `[RCCallSession onRinging]sender: sender.userId -> ${o.userId}`);
|
|
1584
|
-
try {
|
|
1585
|
-
this._listener.onRinging(o, this);
|
|
1586
|
-
} catch (r) {
|
|
1587
|
-
this._logger.error("_", "[RCCallSession onRinging] method exception -> onRinging"), console.error(r);
|
|
1588
|
-
}
|
|
1589
|
-
},
|
|
1590
|
-
/**
|
|
1591
|
-
* 当远端用户同意接听
|
|
1592
|
-
*/
|
|
1593
|
-
onAccept: (o) => {
|
|
1594
|
-
this._logger.info("_", `[RCCallSession onAccept]sender: sender.userId -> ${o.userId}`);
|
|
1595
|
-
try {
|
|
1596
|
-
this._listener.onAccept(o, this);
|
|
1597
|
-
} catch (r) {
|
|
1598
|
-
this._logger.error("_", "[RCCallSession onAccept] method exception -> onAccept"), console.error(r);
|
|
1599
|
-
}
|
|
1600
|
-
},
|
|
1601
|
-
/**
|
|
1602
|
-
* 当有远端用户挂断
|
|
1603
|
-
*/
|
|
1604
|
-
onHungup: (o, r) => {
|
|
1605
|
-
this._logger.info("_", `[RCCallSession onHungup]sender: sender.userId -> ${o.userId} reason->${r}`);
|
|
1606
|
-
try {
|
|
1607
|
-
this._listener.onHungup(o, r, this);
|
|
1608
|
-
} catch (a) {
|
|
1609
|
-
this._logger.error("_", "[RCCallSession onHungup] method exception -> onHungup"), console.error(a);
|
|
1610
|
-
}
|
|
1611
|
-
},
|
|
1612
|
-
/**
|
|
1613
|
-
* 收到人员变更
|
|
1614
|
-
* @param sender 发起用户信息
|
|
1615
|
-
*/
|
|
1616
|
-
onMemberModify: ({ sender: o, invitedUsers: r }) => {
|
|
1617
|
-
this._logger.info("_", `[RCCallSession onMemberModify] sender.userId -> ${o.userId}`);
|
|
1618
|
-
try {
|
|
1619
|
-
this._listener.onMemberModify(o, r, this);
|
|
1620
|
-
} catch (a) {
|
|
1621
|
-
this._logger.error("_", "[RCCallSession onMemberModify] method exception -> onMemberModify"), console.error(a);
|
|
1622
|
-
}
|
|
1623
|
-
},
|
|
1624
|
-
/**
|
|
1625
|
-
* 收到通话类型变更 (通话降级)
|
|
1626
|
-
* @param sender 发起用户信息
|
|
1627
|
-
*/
|
|
1628
|
-
onMediaModify: ({ sender: o, mediaType: r }) => {
|
|
1629
|
-
this._logger.info("_", `[RCCallSession onMediaModify]sender: sender.userId -> ${o.userId} mediaType: ${r}`), r === O.AUDIO && this._setMediaTypeToAudio();
|
|
1630
|
-
try {
|
|
1631
|
-
this._listener.onMediaModify(o, r, this);
|
|
1632
|
-
} catch (a) {
|
|
1633
|
-
this._logger.error("_", "[RCCallSession onMediaModify] method exception -> onMediaModify"), console.error(a);
|
|
1634
|
-
}
|
|
1635
|
-
},
|
|
1636
|
-
/**
|
|
1637
|
-
* 是否跨appkey
|
|
1638
|
-
* @param sender 发起用户信息
|
|
1639
|
-
*/
|
|
1640
|
-
crossAppkey: (o) => {
|
|
1641
|
-
this._logger.info("_", `[RCCallSession crossAppkey] 是否跨 appkey: ${o}`), this._options.isCrossAppkey = o;
|
|
1642
|
-
}
|
|
1643
|
-
}), this._stateMachine.setHungupPushConfig(this._options.hungupPushConfig || { pushTitle: "", pushContent: "" });
|
|
1644
|
-
}
|
|
1645
|
-
/**
|
|
1646
|
-
* 加入房间
|
|
1647
|
-
*/
|
|
1648
|
-
async _joinRoom(e) {
|
|
1649
|
-
let t;
|
|
1650
|
-
try {
|
|
1651
|
-
this._options.isCrossAppkey ? t = await this._rtcClient.joinCrossRTCRoom(e, this._options.joinType) : t = await this._rtcClient.joinRTCRoom(e, this._options.joinType);
|
|
1652
|
-
const { code: i, userIds: n, room: o } = t;
|
|
1653
|
-
if (i !== p.SUCCESS)
|
|
1654
|
-
return i === p.NOT_OPEN_VIDEO_AUDIO_SERVER && this._exceptionClose(g.SERVICE_NOT_OPENED), i === p.SIGNAL_JOIN_RTC_ROOM_REFUSED ? this._exceptionClose(g.OTHER_CLIENT_IN_CALL) : this._exceptionClose(g.NETWORK_ERROR), this._logger.info("_", `[RCCallClient _joinRoom] join room failed: roomId -> ${e} RCRTCCode -> ${i}`), { code: l.JOIN_ROOM_ERROR };
|
|
1655
|
-
if (this._stateMachine.getConversationType() === D.GROUP && this._stateMachine.userJoin([this._rtcClient.getCurrentId()]), this._stateMachine.getState() === T.END)
|
|
1656
|
-
return await this._rtcClient.leaveRoom(o), this._room = null, { code: l.SUCCESS };
|
|
1657
|
-
n.length < 1 && (this.joinRoomTimer = new Pe(() => {
|
|
1658
|
-
this._exceptionClose(g.REMOTE_NETWORK_ERROR);
|
|
1659
|
-
}, 6e4)), this._room = o;
|
|
1660
|
-
} catch (i) {
|
|
1661
|
-
return this._exceptionClose(g.NETWORK_ERROR), this._logger.error("_", `[RCCallSession _joinRoom] _rtcClient.joinRTCRoom throw exception roomId -> ${e}`), console.error(i), { code: l.JOIN_ROOM_ERROR };
|
|
1662
|
-
}
|
|
1663
|
-
this._registerRoomEventListener(), this._registerReportListener();
|
|
1664
|
-
try {
|
|
1665
|
-
await this._subscribeInRoomRemoteTrack();
|
|
1666
|
-
} catch (i) {
|
|
1667
|
-
return this._exceptionClose(g.SUBSCRIBE_ERROR), this._logger.error("_", `[RCCallSession _joinRoom] _subscribeInRoomRemoteTrack Exception roomId -> ${e}`), console.error(i), { code: l.JOIN_ROOM_ERROR };
|
|
1668
|
-
}
|
|
1669
|
-
try {
|
|
1670
|
-
await this._publish();
|
|
1671
|
-
} catch (i) {
|
|
1672
|
-
return this._exceptionClose(g.PUBLISH_ERROR), this._logger.error("_", `[RCCallSession _joinRoom] _publish Exception roomId -> ${e}`), console.error(i), { code: l.JOIN_ROOM_ERROR };
|
|
1673
|
-
}
|
|
1674
|
-
return { code: l.SUCCESS };
|
|
1675
|
-
}
|
|
1676
|
-
/**
|
|
1677
|
-
* (初始化房间的时候) 订阅远程的流,把远程的流抛给用户
|
|
1678
|
-
*/
|
|
1679
|
-
async _subscribeInRoomRemoteTrack() {
|
|
1680
|
-
const e = this._room.getRemoteTracks();
|
|
1681
|
-
if (e.length) {
|
|
1682
|
-
const { code: t } = await this._subscribeRetry(e, this._options.isAllowSubscribeRetry, this._RETRYCOUNT);
|
|
1683
|
-
t !== p.SUCCESS && (this._exceptionClose(g.SUBSCRIBE_ERROR), this._logger.error("_", `[RCCallSession _subscribeInRoomRemoteTrack] Resource subscription failed roomId -> ${this._stateMachine.getCallId()} RTC code -> ${t}`));
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
/**
|
|
1687
|
-
* 可以重试的订阅
|
|
1688
|
-
* @param params.tracks tracks
|
|
1689
|
-
* @param params.isAllowSubscribeRetry 是否允许重试
|
|
1690
|
-
* @param params.count 允许重试的次数
|
|
1691
|
-
*/
|
|
1692
|
-
async _subscribeRetry(e, t = !1, i = 0) {
|
|
1693
|
-
const { code: n } = await this._room.subscribe(e);
|
|
1694
|
-
if (n !== p.SUCCESS) {
|
|
1695
|
-
try {
|
|
1696
|
-
this._listener.onTrackSubscribeFail && this._listener.onTrackSubscribeFail(n, this);
|
|
1697
|
-
} catch (o) {
|
|
1698
|
-
this._logger.error("_", "[RCCallSession] _listener.onTrackSubscribeFail exception"), console.error(o);
|
|
1699
|
-
}
|
|
1700
|
-
if (!t)
|
|
1701
|
-
return { code: n };
|
|
1702
|
-
if (i > 0)
|
|
1703
|
-
return i--, this._subscribeRetry(e, t, i);
|
|
1704
|
-
}
|
|
1705
|
-
return { code: n };
|
|
1706
|
-
}
|
|
1707
|
-
/**
|
|
1708
|
-
* 发布本地资源的逻辑
|
|
1709
|
-
*
|
|
1710
|
-
*/
|
|
1711
|
-
async _publish() {
|
|
1712
|
-
const e = this._options.localTracks, { code: t } = await this._publishRetry(e, this._options.isAllowPublishRetry, this._RETRYCOUNT);
|
|
1713
|
-
if (t !== p.SUCCESS) {
|
|
1714
|
-
this._exceptionClose(g.PUBLISH_ERROR), this._logger.info("_", `[RCCallSession _publist] Resource publishing failed: roomId -> ${this._stateMachine.getCallId()} RCRTCCode -> ${t}`);
|
|
1715
|
-
return;
|
|
1716
|
-
}
|
|
1717
|
-
this._options.produceType === x.CALLEE && this._notifyTrackReady(e);
|
|
1718
|
-
}
|
|
1719
|
-
/**
|
|
1720
|
-
* 可以重试的发布
|
|
1721
|
-
* @param params.tracks tracks
|
|
1722
|
-
* @param params.isAllowPublishRetry 是否允许重试
|
|
1723
|
-
* @param params.count 允许重试的次数
|
|
1724
|
-
*/
|
|
1725
|
-
async _publishRetry(e, t = !1, i = 0) {
|
|
1726
|
-
const { code: n } = await this._room.publish(e);
|
|
1727
|
-
if (n !== p.SUCCESS) {
|
|
1728
|
-
try {
|
|
1729
|
-
this._listener.onTrackPublishFail && this._listener.onTrackPublishFail(n, this);
|
|
1730
|
-
} catch (o) {
|
|
1731
|
-
this._logger.error("_", "[RCCallSession] _listener.onTrackPublishFail exception"), console.error(o);
|
|
1732
|
-
}
|
|
1733
|
-
if (!t)
|
|
1734
|
-
return { code: n };
|
|
1735
|
-
if (i > 0)
|
|
1736
|
-
return i--, this._publishRetry(e, t, i);
|
|
1737
|
-
}
|
|
1738
|
-
return { code: n };
|
|
1739
|
-
}
|
|
1740
|
-
/**
|
|
1741
|
-
* 退出房间
|
|
1742
|
-
*/
|
|
1743
|
-
async _leaveRoom() {
|
|
1744
|
-
try {
|
|
1745
|
-
const e = await this._rtcClient.leaveRoom(this._room);
|
|
1746
|
-
this._logger.info("_", `[RCCallSession _leaveRoom] Successfully exited the room code: ${e.code}`);
|
|
1747
|
-
} catch (e) {
|
|
1748
|
-
this._logger.error("_", "[RCCallSession _leaveRoom] leaveRoom throw exception"), console.error(e);
|
|
1749
|
-
} finally {
|
|
1750
|
-
const e = this._stateMachine.getSummary();
|
|
1751
|
-
B.emit("sessionClose", { session: this, summaryInfo: e });
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
/**
|
|
1755
|
-
* 出现异常后要处理的逻辑,
|
|
1756
|
-
* @param endReason 原因
|
|
1757
|
-
*/
|
|
1758
|
-
_exceptionClose(e) {
|
|
1759
|
-
this._options.localTracks && this._destroyTracks(this._options.localTracks), this._stateMachine.close(e);
|
|
1760
|
-
}
|
|
1761
|
-
/**
|
|
1762
|
-
* 用户调用的,注册session上的监听
|
|
1763
|
-
*/
|
|
1764
|
-
registerSessionListener(e) {
|
|
1765
|
-
const t = j(e);
|
|
1766
|
-
if (!t.result)
|
|
1767
|
-
throw new Error(`[RCCallSession registerSessionListener] ${t.msg}`);
|
|
1768
|
-
this._listener = { ...e };
|
|
1769
|
-
}
|
|
1770
|
-
/**
|
|
1771
|
-
* 调RTC API 获得本地流
|
|
1772
|
-
*/
|
|
1773
|
-
async _getLocalTrackCore(e, t) {
|
|
1774
|
-
if (e === O.AUDIO) {
|
|
1775
|
-
const { code: o, track: r } = await this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC", t && t.audio && { ...t.audio });
|
|
1776
|
-
return o !== p.SUCCESS ? (this._logger.error("_", `[RCCallSession _getLocalTrackCore] get Audio local tracks failed RCT code -> ${o}`), { code: l.GET_LOCAL_AUDIO_TRACK_ERROR }) : (this._logger.info("_", "[RCCallSession _getLocalTrackCore] successfully get Audio local tracks"), { code: l.SUCCESS, tracks: [r] });
|
|
1777
|
-
}
|
|
1778
|
-
const { code: i, tracks: n } = await this._rtcClient.createMicrophoneAndCameraTracks("RongCloudRTC", t && { ...t });
|
|
1779
|
-
return i !== p.SUCCESS ? (this._logger.error("_", `[RCCallSession _getLocalTrackCore] get Audio and Video local tracks failed RCT code -> ${i}`), { code: l.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR }) : (this._logger.info("_", "[RCCallSession _getLocalTrackCore] successfully get audio and video local tracks"), { code: l.SUCCESS, tracks: n });
|
|
1780
|
-
}
|
|
1781
|
-
async _getLocalTrack(e, t) {
|
|
1782
|
-
if (this._options.isAllowDemotionGetStream && e === O.AUDIO_VIDEO) {
|
|
1783
|
-
const { code: o, tracks: r } = await this._getLocalTrackCore(O.AUDIO_VIDEO, t);
|
|
1784
|
-
if (o !== l.SUCCESS) {
|
|
1785
|
-
const { code: a, tracks: h } = await this._getLocalTrackCore(O.AUDIO, t);
|
|
1786
|
-
return a !== l.SUCCESS ? (this._exceptionClose(g.GET_MEDIA_RESOURCES_ERROR), { code: a }) : { code: a, tracks: h };
|
|
1787
|
-
}
|
|
1788
|
-
return { code: o, tracks: r };
|
|
1789
|
-
}
|
|
1790
|
-
const { code: i, tracks: n } = await this._getLocalTrackCore(e, t);
|
|
1791
|
-
return i !== l.SUCCESS ? (this._exceptionClose(g.GET_MEDIA_RESOURCES_ERROR), { code: i }) : { code: i, tracks: n };
|
|
1792
|
-
}
|
|
1793
|
-
/**
|
|
1794
|
-
* 通话中更换音频设备
|
|
1795
|
-
*/
|
|
1796
|
-
async changeAudioDevice(e) {
|
|
1797
|
-
const t = [], i = [], { code: n, track: o } = await this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC", e);
|
|
1798
|
-
if (n !== p.SUCCESS)
|
|
1799
|
-
return this._logger.error("_", `[RCCallSession changeDevice] get local Audio tracks failed RCTLib code -> ${n}`), { code: l.GET_LOCAL_AUDIO_TRACK_ERROR };
|
|
1800
|
-
if (this._options.localTracks && this._options.localTracks.forEach((r) => {
|
|
1801
|
-
r.isAudioTrack() || i.push(r);
|
|
1802
|
-
}), t.push(o), i.push(o), this._options.localTracks = i, this._notifyTrackReady(t), this._room) {
|
|
1803
|
-
const { code: r } = await this._room.publish(t);
|
|
1804
|
-
if (r !== p.SUCCESS)
|
|
1805
|
-
return { code: l.AUDIO_PUBLISH_ERROR };
|
|
1806
|
-
}
|
|
1807
|
-
return { code: l.SUCCESS };
|
|
1808
|
-
}
|
|
1809
|
-
/**
|
|
1810
|
-
* 群呼叫中继续邀请
|
|
1811
|
-
* @param userIds 被邀请用户 ID 列表
|
|
1812
|
-
* @param options.extra 消息的扩展信息
|
|
1813
|
-
* @deprecated 5.1.2 废弃 options.pushTitle 通知的标题
|
|
1814
|
-
* @deprecated 5.1.2 废弃 options.pushContent 通知内容
|
|
1815
|
-
*/
|
|
1816
|
-
async invite(e, t = {}) {
|
|
1817
|
-
const { extra: i = "" } = t, n = this._options.callPushConfig ? this._options.callPushConfig : t.pushConfig, o = [le(e), X(i)];
|
|
1818
|
-
if (n) {
|
|
1819
|
-
const { code: c, errorMsg: _ } = J(n);
|
|
1820
|
-
if (c !== l.SUCCESS)
|
|
1821
|
-
return this._logger.error("_", `[RCCallSession invite] param error, errorMsg: ${_}`), { code: c };
|
|
1822
|
-
}
|
|
1823
|
-
const r = [];
|
|
1824
|
-
if (!o.every((c) => (!c.result && r.push(c.msg), c.result)))
|
|
1825
|
-
throw new Error(`[RCCallClient invite] ${r.join(`
|
|
1826
|
-
`)}`);
|
|
1827
|
-
const { code: h } = await this._stateMachine.invite(e, {
|
|
1828
|
-
extra: i,
|
|
1829
|
-
pushConfig: n
|
|
1830
|
-
});
|
|
1831
|
-
return { code: h };
|
|
1832
|
-
}
|
|
1833
|
-
/**
|
|
1834
|
-
* 同意接听
|
|
1835
|
-
*/
|
|
1836
|
-
async accept(e) {
|
|
1837
|
-
const t = be(e);
|
|
1838
|
-
if (!t.result)
|
|
1839
|
-
throw new Error(`[RCCallSession accept] ${t.msg}`);
|
|
1840
|
-
B.emit("hungupOtherSession", { session: this });
|
|
1841
|
-
const i = this._stateMachine.getMediaType(), { code: n, tracks: o } = await this._getLocalTrack(i, e);
|
|
1842
|
-
if (n !== l.SUCCESS)
|
|
1843
|
-
return { code: n };
|
|
1844
|
-
this._options.localTracks = o;
|
|
1845
|
-
const { code: r } = await this._stateMachine.accept();
|
|
1846
|
-
return r !== l.SUCCESS ? (this._logger.error("_", `[RCCallSession accept]Send accept message failed -> code: ${r}`), { code: r }) : { code: r };
|
|
1847
|
-
}
|
|
1848
|
-
/**
|
|
1849
|
-
* 挂断
|
|
1850
|
-
*/
|
|
1851
|
-
async hungup() {
|
|
1852
|
-
return this._stateMachine.hungup();
|
|
1853
|
-
}
|
|
1854
|
-
/**
|
|
1855
|
-
* 通话媒体变更
|
|
1856
|
-
* @param mediaType RCCallMediaType.AUDIO 改为音频通话 | RCCallMediaType.AUDIO_VIDEO 改为音视频通话
|
|
1857
|
-
*/
|
|
1858
|
-
async _changeMediaType(e) {
|
|
1859
|
-
const { code: t } = await this._stateMachine.changeMediaType(e);
|
|
1860
|
-
return t !== l.SUCCESS && this._logger.error("_", `[RCCallSession _changeMediaType] change media type fail code-> ${t}`), { code: t };
|
|
1861
|
-
}
|
|
1862
|
-
/**
|
|
1863
|
-
* 获得本地视频
|
|
1864
|
-
*/
|
|
1865
|
-
_getLocalVideoTracks() {
|
|
1866
|
-
let e = [];
|
|
1867
|
-
return this._room && this._options.localTracks && (e = this._options.localTracks.filter((t) => t.isVideoTrack())), e;
|
|
1868
|
-
}
|
|
1869
|
-
/**
|
|
1870
|
-
* 获得本地音频
|
|
1871
|
-
*/
|
|
1872
|
-
_getLocalAudioTracks() {
|
|
1873
|
-
let e = [];
|
|
1874
|
-
return this._room && this._options.localTracks && (e = this._options.localTracks.filter((t) => t.isAudioTrack())), e;
|
|
1875
|
-
}
|
|
1876
|
-
/**
|
|
1877
|
-
* 把通话的MediaType升级到音视频
|
|
1878
|
-
*/
|
|
1879
|
-
async _setMediaTypeToAudioAndVideo() {
|
|
1880
|
-
const { code: e, track: t } = await this._rtcClient.createCameraVideoTrack();
|
|
1881
|
-
if (e !== p.SUCCESS)
|
|
1882
|
-
return { code: l.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR };
|
|
1883
|
-
const { code: i } = await this._room.publish([t]);
|
|
1884
|
-
if (i !== p.SUCCESS) {
|
|
1885
|
-
this._logger.error("_", `[RCCallSession _enableVideo] Resource publishing failed: RCRTCCode -> ${e}`);
|
|
1886
|
-
return;
|
|
1887
|
-
}
|
|
1888
|
-
this._notifyTrackReady([t]), this._changeMediaType(O.AUDIO_VIDEO);
|
|
1889
|
-
}
|
|
1890
|
-
/**
|
|
1891
|
-
* 把通话的MediaType降级到音频
|
|
1892
|
-
* @param isSendMesssage 是否需要发消息, 默认发消息
|
|
1893
|
-
*/
|
|
1894
|
-
async _setMediaTypeToAudio() {
|
|
1895
|
-
const e = this._getLocalVideoTracks();
|
|
1896
|
-
if (e.length) {
|
|
1897
|
-
e.forEach((i) => {
|
|
1898
|
-
i.mute();
|
|
1899
|
-
});
|
|
1900
|
-
const { code: t } = await this._room.unpublish(e);
|
|
1901
|
-
t !== p.SUCCESS && this._logger.error("_", `[RCCallSession disableVideo] unpublish failed -> ${t}`), this._destroyTracks(e);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
/**
|
|
1905
|
-
* 通话降级,目前需求只做通话降级,音视频可以降级为音频,音频不能升到音视频, 发消息成功才算降级成功
|
|
1906
|
-
*
|
|
1907
|
-
*/
|
|
1908
|
-
async descendAbility() {
|
|
1909
|
-
const { code: e } = await this._changeMediaType(O.AUDIO);
|
|
1910
|
-
return e === l.SUCCESS && this._setMediaTypeToAudio(), { code: e };
|
|
1911
|
-
}
|
|
1912
|
-
/**
|
|
1913
|
-
* 禁用视频track
|
|
1914
|
-
*/
|
|
1915
|
-
async disableVideoTrack() {
|
|
1916
|
-
if (!this._room)
|
|
1917
|
-
return this._logger.error("_", `[RCCallSession disableAudioTrack] Room missing audio track -> ${l.NOT_IN_ROOM_ERROR}`), { code: l.NOT_IN_ROOM_ERROR };
|
|
1918
|
-
const e = this._getLocalVideoTracks();
|
|
1919
|
-
if (!e.length)
|
|
1920
|
-
return this._logger.error("_", `[RCCallSession disableVideoTrack] Room missing video track -> ${l.MISSING_VIDEO_TRACK_ERROR}`), { code: l.MISSING_VIDEO_TRACK_ERROR };
|
|
1921
|
-
if (e.forEach((i) => {
|
|
1922
|
-
i.mute();
|
|
1923
|
-
}), !this._options.isOffCameraWhenVideoDisable)
|
|
1924
|
-
return { code: l.SUCCESS };
|
|
1925
|
-
const { code: t } = await this._room.unpublish(e);
|
|
1926
|
-
return t !== p.SUCCESS ? (this._logger.error("_", `[RCCallSession disableVideo] unpublish failed -> ${t}`), { code: l.UNPUBLISH_VIDEO_ERROR }) : (e.forEach((i) => {
|
|
1927
|
-
i.destroy();
|
|
1928
|
-
}), { code: l.SUCCESS });
|
|
1929
|
-
}
|
|
1930
|
-
/**
|
|
1931
|
-
* 启用视频track
|
|
1932
|
-
*/
|
|
1933
|
-
async enableVideoTrack() {
|
|
1934
|
-
if (!this._room)
|
|
1935
|
-
return this._logger.error("_", `[RCCallSession disableAudioTrack] Room missing audio track -> ${l.NOT_IN_ROOM_ERROR}`), { code: l.NOT_IN_ROOM_ERROR };
|
|
1936
|
-
if (!this._options.isOffCameraWhenVideoDisable) {
|
|
1937
|
-
const o = this._getLocalVideoTracks();
|
|
1938
|
-
return o.length ? (o.forEach((r) => {
|
|
1939
|
-
r.unmute();
|
|
1940
|
-
}), { code: l.SUCCESS }) : (this._logger.error("_", `[RCCallSession EnableVideoTrack] Room missing video track -> ${l.MISSING_VIDEO_TRACK_ERROR}`), { code: l.MISSING_VIDEO_TRACK_ERROR });
|
|
1941
|
-
}
|
|
1942
|
-
const { code: e, track: t } = await this._rtcClient.createCameraVideoTrack();
|
|
1943
|
-
if (e !== p.SUCCESS)
|
|
1944
|
-
return this._logger.error("_", `[RCCallSession EnableVideoTrack] Get Resource failed: RCRTCCode -> ${e}`), { code: l.GET_LOCAL_VIDEO_TRACK_ERROR };
|
|
1945
|
-
const i = [];
|
|
1946
|
-
this._options.localTracks && this._options.localTracks.forEach((o) => {
|
|
1947
|
-
o.isVideoTrack() ? o.destroy() : i.push(o);
|
|
1948
|
-
}), i.push(t), this._options.localTracks = i, t.mute();
|
|
1949
|
-
const { code: n } = await this._room.publish([t]);
|
|
1950
|
-
return n !== p.SUCCESS ? (this._logger.error("_", `[RCCallSession EnableVideoTrack] Resource publishing failed: RCRTCCode -> ${e}`), { code: l.VIDEO_PUBLISH_ERROR }) : (t.unmute(), this._notifyTrackReady([t]), { code: l.SUCCESS });
|
|
1951
|
-
}
|
|
1952
|
-
/**
|
|
1953
|
-
* 禁用音频track
|
|
1954
|
-
*/
|
|
1955
|
-
async disableAudioTrack() {
|
|
1956
|
-
if (!this._room)
|
|
1957
|
-
return this._logger.error("_", `[RCCallSession disableAudioTrack] Room missing audio track -> ${l.NOT_IN_ROOM_ERROR}`), { code: l.NOT_IN_ROOM_ERROR };
|
|
1958
|
-
this._getLocalAudioTracks().forEach((t) => {
|
|
1959
|
-
t.mute();
|
|
1960
|
-
});
|
|
1961
|
-
}
|
|
1962
|
-
/**
|
|
1963
|
-
* 启用音频track
|
|
1964
|
-
*/
|
|
1965
|
-
async enableAudioTrack() {
|
|
1966
|
-
if (!this._room)
|
|
1967
|
-
return this._logger.error("_", `[RCCallSession disableAudioTrack] Room missing audio track -> ${l.NOT_IN_ROOM_ERROR}`), { code: l.NOT_IN_ROOM_ERROR };
|
|
1968
|
-
const e = this._getLocalAudioTracks();
|
|
1969
|
-
if (!e.length)
|
|
1970
|
-
return this._logger.error("_", `[RCCallSession disableAudioTrack] Room missing audio track -> ${l.MISSING_VIDEO_TRACK_ERROR}`), { code: l.MISSING_VIDEO_TRACK_ERROR };
|
|
1971
|
-
e.forEach((t) => {
|
|
1972
|
-
t.unmute();
|
|
1973
|
-
});
|
|
1974
|
-
}
|
|
1975
|
-
/**
|
|
1976
|
-
* 销毁本地流
|
|
1977
|
-
*/
|
|
1978
|
-
_destroyTracks(e) {
|
|
1979
|
-
e.forEach((t) => {
|
|
1980
|
-
t.destroy();
|
|
1981
|
-
});
|
|
1982
|
-
}
|
|
1983
|
-
/**
|
|
1984
|
-
* 向外抛出本地流
|
|
1985
|
-
*/
|
|
1986
|
-
_notifyTrackReady(e) {
|
|
1987
|
-
e.forEach((t) => {
|
|
1988
|
-
try {
|
|
1989
|
-
this._listener.onTrackReady(t, this);
|
|
1990
|
-
} catch (i) {
|
|
1991
|
-
this._logger.error("_", "[RCCallSession _notifyTrackReady] _listener onTrackReady exception"), console.error(i);
|
|
1992
|
-
}
|
|
1993
|
-
});
|
|
1994
|
-
}
|
|
1995
|
-
/**
|
|
1996
|
-
* 房间上注册事件
|
|
1997
|
-
*/
|
|
1998
|
-
_registerRoomEventListener() {
|
|
1999
|
-
this._room.registerRoomEventListener(
|
|
2000
|
-
{
|
|
2001
|
-
/**
|
|
2002
|
-
* 本端被踢出房间时触发
|
|
2003
|
-
* @description 被踢出房间可能是由于服务端超出一定时间未能收到 rtcPing 消息,所以认为己方离线。
|
|
2004
|
-
* 另一种可能是己方 rtcPing 失败次数超出上限,故而主动断线
|
|
2005
|
-
* @param byServer
|
|
2006
|
-
* 当值为 false 时,说明本端 rtcPing 超时
|
|
2007
|
-
* 当值为 true 时,说明本端收到被踢出房间通知
|
|
2008
|
-
*/
|
|
2009
|
-
onKickOff: (e, t) => {
|
|
2010
|
-
const i = this._rtcClient.getCurrentId();
|
|
2011
|
-
this._stateMachine.userLeave([i]), e ? (t === Q.SERVER_KICK && this._exceptionClose(g.KICKED_BY_SERVER), t === Q.OTHER_KICK && this._exceptionClose(g.OTHER_CLIENT_JOINED_CALL)) : this._exceptionClose(g.NETWORK_ERROR);
|
|
2012
|
-
},
|
|
2013
|
-
/**
|
|
2014
|
-
* 接收到房间信令时回调,用户可通过房间实例的 `sendMessage(name, content)` 接口发送信令
|
|
2015
|
-
* @param name 信令名
|
|
2016
|
-
* @param content 信令内容
|
|
2017
|
-
* @param senderUserId 发送者 Id
|
|
2018
|
-
* @param messageUId 消息唯一标识
|
|
2019
|
-
*/
|
|
2020
|
-
onMessageReceive(e, t, i, n) {
|
|
2021
|
-
},
|
|
2022
|
-
/**
|
|
2023
|
-
* 监听房间属性变更通知
|
|
2024
|
-
* @param name
|
|
2025
|
-
* @param content
|
|
2026
|
-
*/
|
|
2027
|
-
onRoomAttributeChange(e, t) {
|
|
2028
|
-
},
|
|
2029
|
-
/**
|
|
2030
|
-
* 发布者禁用/启用音频
|
|
2031
|
-
* @param audioTrack RCRemoteAudioTrack 类实例
|
|
2032
|
-
*/
|
|
2033
|
-
onAudioMuteChange: (e) => {
|
|
2034
|
-
this._logger.info("_", `[RCCallSession onAudioMuteChange] userId->${e.getUserId()} muted -> ${e.isOwnerMuted()}`);
|
|
2035
|
-
const t = {
|
|
2036
|
-
userId: e.getUserId(),
|
|
2037
|
-
muted: e.isOwnerMuted(),
|
|
2038
|
-
kind: "audio",
|
|
2039
|
-
trackId: e.getTrackId()
|
|
2040
|
-
};
|
|
2041
|
-
try {
|
|
2042
|
-
this._listener.onAudioMuteChange(t, this);
|
|
2043
|
-
} catch (i) {
|
|
2044
|
-
this._logger.error("_", "[RCCallSession onAudioMuteChange] Missing listening method -> onTrackMuteChange"), console.error(i);
|
|
2045
|
-
}
|
|
2046
|
-
},
|
|
2047
|
-
/**
|
|
2048
|
-
* 发布者禁用/启用视频
|
|
2049
|
-
* @param videoTrack RCRemoteVideoTrack 类实例对象
|
|
2050
|
-
*/
|
|
2051
|
-
onVideoMuteChange: (e) => {
|
|
2052
|
-
this._logger.info("_", `[RCCallSession onVideoMuteChange]userId->${e.getUserId()} muted -> ${e.isOwnerMuted()}`);
|
|
2053
|
-
const t = {
|
|
2054
|
-
userId: e.getUserId(),
|
|
2055
|
-
muted: e.isOwnerMuted(),
|
|
2056
|
-
kind: "video",
|
|
2057
|
-
trackId: e.getTrackId()
|
|
2058
|
-
};
|
|
2059
|
-
try {
|
|
2060
|
-
this._listener.onVideoMuteChange(t, this);
|
|
2061
|
-
} catch (i) {
|
|
2062
|
-
this._logger.error("_", "[RCCallSession onVideoMuteChange] Missing listening method -> onVideoMuteChange"), console.error(i);
|
|
2063
|
-
}
|
|
2064
|
-
},
|
|
2065
|
-
/**
|
|
2066
|
-
* 房间内其他用户新发布资源时触发
|
|
2067
|
-
* 如需获取加入房间之前房间内某个用户发布的资源列表,可使用 room.getRemoteTracksByUserId('userId') 获取
|
|
2068
|
-
* @param tracks 新发布的音轨与视轨数据列表,包含新发布的 RCRemoteAudioTrack 与 RCRemoteVideoTrack 实例
|
|
2069
|
-
*/
|
|
2070
|
-
onTrackPublish: async (e) => {
|
|
2071
|
-
if (this._room) {
|
|
2072
|
-
const { code: t } = await this._room.subscribe(e);
|
|
2073
|
-
t !== p.SUCCESS && this._logger.error("_", `[RCCallSession onTrackPublish] subscribe failed RTCCode ->${t}`);
|
|
2074
|
-
}
|
|
2075
|
-
},
|
|
2076
|
-
/**
|
|
2077
|
-
* 房间用户取消发布资源
|
|
2078
|
-
* @param tracks 被取消发布的音轨与视轨数据列表
|
|
2079
|
-
* @description 当资源被取消发布时,SDK 内部会取消对相关资源的订阅,业务层仅需处理 UI 业务
|
|
2080
|
-
*/
|
|
2081
|
-
onTrackUnpublish: (e) => {
|
|
2082
|
-
},
|
|
2083
|
-
/**
|
|
2084
|
-
* 订阅的音视频流通道已建立, track 已可以进行播放
|
|
2085
|
-
* @param track RCRemoteTrack 类实例
|
|
2086
|
-
*/
|
|
2087
|
-
onTrackReady: (e) => {
|
|
2088
|
-
this._stateMachine.getMediaType() === O.AUDIO && e.isVideoTrack() || this._notifyTrackReady([e]);
|
|
2089
|
-
},
|
|
2090
|
-
/**
|
|
2091
|
-
* 人员加入
|
|
2092
|
-
* @param userIds 加入的人员 id 列表
|
|
2093
|
-
*/
|
|
2094
|
-
onUserJoin: (e) => {
|
|
2095
|
-
this.joinRoomTimer && this.joinRoomTimer.stop(), this._stateMachine.userJoin(e);
|
|
2096
|
-
},
|
|
2097
|
-
/**
|
|
2098
|
-
* 人员退出
|
|
2099
|
-
* @param userIds
|
|
2100
|
-
*/
|
|
2101
|
-
onUserLeave: (e) => {
|
|
2102
|
-
this._logger.info("_", `[RCCallSession onUserLeave] listening onUserLeave userIds -> ${e == null ? void 0 : e.join(",")}`), this._stateMachine.userLeave(e);
|
|
2103
|
-
},
|
|
2104
|
-
/**
|
|
2105
|
-
* RTC 每次 Ping 结果
|
|
2106
|
-
*/
|
|
2107
|
-
onPing: (e) => {
|
|
2108
|
-
this._logger.info("_", `[RCCallSession onPing]${e}`);
|
|
2109
|
-
try {
|
|
2110
|
-
this._listener.onPing && this._listener.onPing(e, this);
|
|
2111
|
-
} catch (t) {
|
|
2112
|
-
this._logger.error("_", "[RCCallSession onPing] listening onPing exception"), console.error(t);
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
);
|
|
2117
|
-
}
|
|
2118
|
-
/**
|
|
2119
|
-
* 注册房间质量数据监听器
|
|
2120
|
-
*/
|
|
2121
|
-
_registerReportListener() {
|
|
2122
|
-
this._room.registerReportListener({
|
|
2123
|
-
/**
|
|
2124
|
-
* 用于接收状态数据报告
|
|
2125
|
-
* @param report
|
|
2126
|
-
*/
|
|
2127
|
-
onStateReport: (e) => {
|
|
2128
|
-
try {
|
|
2129
|
-
this._listener.onRTCStateReport && this._listener.onRTCStateReport(e, this);
|
|
2130
|
-
} catch (t) {
|
|
2131
|
-
this._logger.error("_", "[RCCallSession onStateReport] listener onStateReport exception"), console.error(t);
|
|
2132
|
-
}
|
|
2133
|
-
},
|
|
2134
|
-
/**
|
|
2135
|
-
* ~ICE 连接状态变更通知~
|
|
2136
|
-
* @since version 5.1.5
|
|
2137
|
-
*/
|
|
2138
|
-
onICEConnectionStateChange: (e) => {
|
|
2139
|
-
try {
|
|
2140
|
-
this._listener.onICEConnectionStateChange && this._listener.onICEConnectionStateChange(e, this);
|
|
2141
|
-
} catch (t) {
|
|
2142
|
-
this._logger.error("_", "[RCCallSession onICEConnectionStateChange] onICEConnectionStateChange exception"), console.error(t);
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
});
|
|
2146
|
-
}
|
|
2147
|
-
/**
|
|
2148
|
-
* 通话唯一标识
|
|
2149
|
-
*/
|
|
2150
|
-
getSessionId() {
|
|
2151
|
-
return this._stateMachine.getCallId();
|
|
2152
|
-
}
|
|
2153
|
-
/**
|
|
2154
|
-
* 获取房间当前会话 Id,当房间内已无成员时房间会回收,重新加入时 sessionId 将更新,(用户录制资源用的)
|
|
2155
|
-
*/
|
|
2156
|
-
getRTCSessionId() {
|
|
2157
|
-
return this._room ? this._room.getSessionId() : null;
|
|
2158
|
-
}
|
|
2159
|
-
/**
|
|
2160
|
-
* 目标 ID,单呼对方人员 Id, 群呼群组 Id
|
|
2161
|
-
*/
|
|
2162
|
-
getTargetId() {
|
|
2163
|
-
return this._stateMachine.getTargetId();
|
|
2164
|
-
}
|
|
2165
|
-
/**
|
|
2166
|
-
* 获取会话类型
|
|
2167
|
-
*/
|
|
2168
|
-
getConversationType() {
|
|
2169
|
-
return this._stateMachine.getConversationType();
|
|
2170
|
-
}
|
|
2171
|
-
/**
|
|
2172
|
-
* 组织 ID
|
|
2173
|
-
*/
|
|
2174
|
-
getChannelId() {
|
|
2175
|
-
return this._stateMachine.getChannelId();
|
|
2176
|
-
}
|
|
2177
|
-
/**
|
|
2178
|
-
* 房间人员列表,不包含本端信息
|
|
2179
|
-
*/
|
|
2180
|
-
getRemoteUsers() {
|
|
2181
|
-
return this._stateMachine.getRemoteUsers();
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* 房间人员列表,不包含本端信息
|
|
2185
|
-
*/
|
|
2186
|
-
getUsers() {
|
|
2187
|
-
return this._stateMachine.getRemoteUsers();
|
|
2188
|
-
}
|
|
2189
|
-
/**
|
|
2190
|
-
* 获取人员状态
|
|
2191
|
-
*/
|
|
2192
|
-
getUserState(e) {
|
|
2193
|
-
if (!e || typeof e != "string")
|
|
2194
|
-
throw new Error("userId is required, must be of type 'string'");
|
|
2195
|
-
return this._stateMachine.getUserState(e);
|
|
2196
|
-
}
|
|
2197
|
-
/**
|
|
2198
|
-
* 获取session状态
|
|
2199
|
-
*/
|
|
2200
|
-
getState() {
|
|
2201
|
-
return this._stateMachine.getState();
|
|
2202
|
-
}
|
|
2203
|
-
/**
|
|
2204
|
-
* 获得会话发起者id
|
|
2205
|
-
*/
|
|
2206
|
-
getCallerId() {
|
|
2207
|
-
return this._stateMachine.getCallerId();
|
|
2208
|
-
}
|
|
2209
|
-
/**
|
|
2210
|
-
* 获得mediaType
|
|
2211
|
-
*/
|
|
2212
|
-
getMediaType() {
|
|
2213
|
-
return this._stateMachine.getMediaType();
|
|
2214
|
-
}
|
|
2215
|
-
}
|
|
2216
|
-
class He {
|
|
2217
|
-
constructor(e, t, i, n) {
|
|
2218
|
-
/**
|
|
2219
|
-
* rtc实例
|
|
2220
|
-
*/
|
|
2221
|
-
f(this, "_rtcClient");
|
|
2222
|
-
/**
|
|
2223
|
-
* callEngine层实例
|
|
2224
|
-
*/
|
|
2225
|
-
f(this, "_callEngine");
|
|
2226
|
-
/**
|
|
2227
|
-
* 其它参数
|
|
2228
|
-
*/
|
|
2229
|
-
f(this, "_options");
|
|
2230
|
-
/**
|
|
2231
|
-
* session列表
|
|
2232
|
-
*/
|
|
2233
|
-
f(this, "_sessionList", []);
|
|
2234
|
-
/**
|
|
2235
|
-
* 移动端呼叫推送配置
|
|
2236
|
-
*/
|
|
2237
|
-
f(this, "_callPushConfig");
|
|
2238
|
-
/**
|
|
2239
|
-
* 移动端挂断推送配置
|
|
2240
|
-
*/
|
|
2241
|
-
f(this, "_hungupPushConfig");
|
|
2242
|
-
this._context = e, this._runtime = t, this._logger = i, this._rtcClient = n.rtcClient, this._options = {
|
|
2243
|
-
/**
|
|
2244
|
-
* 是否允许发布重试, 默认不允许
|
|
2245
|
-
*/
|
|
2246
|
-
isAllowPublishRetry: !1,
|
|
2247
|
-
/**
|
|
2248
|
-
* 是否允许订阅重试,默认不允许
|
|
2249
|
-
*/
|
|
2250
|
-
isAllowSubscribeRetry: !1,
|
|
2251
|
-
/**
|
|
2252
|
-
* 禁用视频时关摄像头, 默认关闭
|
|
2253
|
-
*/
|
|
2254
|
-
isOffCameraWhenVideoDisable: !0,
|
|
2255
|
-
/**
|
|
2256
|
-
* RTC 房间加入类型,默认 RTCJoinType.COEXIST = 2 两个设备共存
|
|
2257
|
-
* RTCJoinType.KICK = 0,踢前一个设备
|
|
2258
|
-
* RTCJoinType.REFUSE = 1,当前加入拒绝
|
|
2259
|
-
* RTCJoinType.COEXIST = 2 两个设备共存
|
|
2260
|
-
*/
|
|
2261
|
-
joinType: ne.COEXIST,
|
|
2262
|
-
/**
|
|
2263
|
-
* 允许降级获得流,获得音视频不成功 ,降级获得音频, 默认不允许
|
|
2264
|
-
*/
|
|
2265
|
-
isAllowDemotionGetStream: !1,
|
|
2266
|
-
/**
|
|
2267
|
-
* 语言设置 (推送), 不传默认为中文
|
|
2268
|
-
*/
|
|
2269
|
-
lang: P.ZH,
|
|
2270
|
-
...n
|
|
2271
|
-
}, this._callEngine = new Oe(this._context, t, this._logger, {
|
|
2272
|
-
/**
|
|
2273
|
-
* 监听收到invite
|
|
2274
|
-
*/
|
|
2275
|
-
onInvite: this._onInvite.bind(this),
|
|
2276
|
-
/**
|
|
2277
|
-
* 监听离线消息报告
|
|
2278
|
-
*/
|
|
2279
|
-
onOfflineRecord: this._onOfflineRecord.bind(this)
|
|
2280
|
-
}, {
|
|
2281
|
-
/**
|
|
2282
|
-
* 语言设置 (推送), 不传默认为中文
|
|
2283
|
-
*/
|
|
2284
|
-
lang: this._options.lang || P.ZH
|
|
2285
|
-
}), B.on("sessionClose", ({ session: o, summaryInfo: r }) => {
|
|
2286
|
-
this._removeSession(o);
|
|
2287
|
-
try {
|
|
2288
|
-
this._options.onSessionClose(o, r);
|
|
2289
|
-
} catch (a) {
|
|
2290
|
-
this._logger.error("_", "[RCCCallClient] options.onSessionClose exception"), console.log(a);
|
|
2291
|
-
}
|
|
2292
|
-
}), B.on("hungupOtherSession", ({ session: o }) => {
|
|
2293
|
-
const r = o.getSessionId();
|
|
2294
|
-
this._logger.info("_", `[RCCallClient hungupOtherSession] sessionId ready to accept -> ${r}`), this._logger.info("_", `[RCCallClient hungupOtherSession] sessionList ->${this._sessionList.map((h) => h.getSessionId()).join(",")}`);
|
|
2295
|
-
let a = 0;
|
|
2296
|
-
for (; this._sessionList.length > 1; )
|
|
2297
|
-
this._sessionList[a].getSessionId() !== r ? (this._sessionList[a].hungup(), this._sessionList.splice(a, 1)) : a++;
|
|
2298
|
-
this._logger.info("_", `[RCCallClient hungupOtherSession] current sessionList length ->${this._sessionList.length}`);
|
|
2299
|
-
});
|
|
2300
|
-
}
|
|
2301
|
-
/**
|
|
2302
|
-
* 监听onInvite
|
|
2303
|
-
*/
|
|
2304
|
-
_onInvite(e, t) {
|
|
2305
|
-
this._logger.info("_", "[RCCallClient _onInvite] Received invite message");
|
|
2306
|
-
const i = new z(e, this._rtcClient, this._logger, {
|
|
2307
|
-
// 是否允许订阅重试
|
|
2308
|
-
isAllowSubscribeRetry: this._options.isAllowSubscribeRetry,
|
|
2309
|
-
// 是否允许发布重试
|
|
2310
|
-
isAllowPublishRetry: this._options.isAllowPublishRetry,
|
|
2311
|
-
/**
|
|
2312
|
-
* 禁用视频时关摄像头
|
|
2313
|
-
*/
|
|
2314
|
-
isOffCameraWhenVideoDisable: this._options.isOffCameraWhenVideoDisable,
|
|
2315
|
-
/**
|
|
2316
|
-
* RTC 房间加入类型
|
|
2317
|
-
*/
|
|
2318
|
-
joinType: this._options.joinType,
|
|
2319
|
-
// 允许降级获得流,获得音视频不成功 ,降级获得音频, 默认不允许
|
|
2320
|
-
isAllowDemotionGetStream: this._options.isAllowDemotionGetStream,
|
|
2321
|
-
// 标明是被叫产生的session
|
|
2322
|
-
produceType: x.CALLEE,
|
|
2323
|
-
callPushConfig: this._callPushConfig,
|
|
2324
|
-
hungupPushConfig: this._hungupPushConfig
|
|
2325
|
-
});
|
|
2326
|
-
this._logger.info("_", "[RCCallClient _onInvite] Received invite message, successfully created session"), this._sessionList.push(i);
|
|
2327
|
-
try {
|
|
2328
|
-
this._options.onSession(i, t);
|
|
2329
|
-
} catch (n) {
|
|
2330
|
-
this._logger.error("_", "[RCCallClient _options.onSession] onSession exception"), console.log(n);
|
|
2331
|
-
}
|
|
2332
|
-
if (i._listener) {
|
|
2333
|
-
const n = j(i._listener);
|
|
2334
|
-
if (!n.result)
|
|
2335
|
-
throw new Error(n.msg);
|
|
2336
|
-
} else
|
|
2337
|
-
throw this._logger.error("_", "[RCCallClient _options.onSession] session Must Have Listener"), new Error("[RCCallSession _options.onSession] session Must Have Listener");
|
|
2338
|
-
}
|
|
2339
|
-
/**
|
|
2340
|
-
* 监听离线消息报告
|
|
2341
|
-
* @param record
|
|
2342
|
-
*/
|
|
2343
|
-
_onOfflineRecord(e) {
|
|
2344
|
-
try {
|
|
2345
|
-
this._options.onOfflineRecord && this._options.onOfflineRecord(e);
|
|
2346
|
-
} catch (t) {
|
|
2347
|
-
this._logger.error("_", "[RCCallClient _options.onOfflineRecord] onOfflineRecord exception"), console.log(t);
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
/**
|
|
2351
|
-
* 注册用户信息。注册后,在发起邀请或挂断等操作时,会将该信息一并发送给对端
|
|
2352
|
-
* @param info.name 用户名称
|
|
2353
|
-
* @param info.portraitUri 用户头像信息
|
|
2354
|
-
* @param info.extra 预留拓展字段
|
|
2355
|
-
*/
|
|
2356
|
-
registerUserInfo(e = {}) {
|
|
2357
|
-
this._callEngine.registerUserInfo(e), this._logger.info("_", "[RCCallClient registerUserInfo] successfully register user info data");
|
|
2358
|
-
}
|
|
2359
|
-
/**
|
|
2360
|
-
* 跨App单呼,发送invite消息,回调回来接收stateMachine, 建session
|
|
2361
|
-
* @param params.targetId 被呼叫一方的用户 id 必填
|
|
2362
|
-
* @param params.mediaType 音频呼叫 or 音视频呼叫 必填
|
|
2363
|
-
* @param params.listener (session上的监听) 必填
|
|
2364
|
-
* @param params.constraints 获取音频或音视频资源时的参数 可选
|
|
2365
|
-
* @param params.channelId 组织 Id 可选
|
|
2366
|
-
* @param params.extra 消息扩展信息
|
|
2367
|
-
* @deprecated 5.1.2 版本废弃 params.pushTitle 通知的标题
|
|
2368
|
-
* @deprecated 5.1.2 版本废弃 params.pushContent 通知的内容
|
|
2369
|
-
* @param params.bitrate 需要设置的码率参数
|
|
2370
|
-
*
|
|
2371
|
-
*/
|
|
2372
|
-
async startCrossCall({
|
|
2373
|
-
targetId: e,
|
|
2374
|
-
mediaType: t = O.AUDIO,
|
|
2375
|
-
listener: i,
|
|
2376
|
-
constraints: n,
|
|
2377
|
-
channelId: o = "",
|
|
2378
|
-
extra: r = "",
|
|
2379
|
-
pushTitle: a = "",
|
|
2380
|
-
pushContent: h = "",
|
|
2381
|
-
bitrate: c
|
|
2382
|
-
}) {
|
|
2383
|
-
return this.__call({
|
|
2384
|
-
targetId: e,
|
|
2385
|
-
mediaType: t,
|
|
2386
|
-
listener: i,
|
|
2387
|
-
constraints: n,
|
|
2388
|
-
channelId: o,
|
|
2389
|
-
extra: r,
|
|
2390
|
-
pushTitle: a,
|
|
2391
|
-
pushContent: h,
|
|
2392
|
-
bitrate: c,
|
|
2393
|
-
isCrossAppkey: !0
|
|
2394
|
-
});
|
|
2395
|
-
}
|
|
2396
|
-
/**
|
|
2397
|
-
* 单呼,发送invite消息,回调回来接收stateMachine, 建session
|
|
2398
|
-
* @param params.targetId 被呼叫一方的用户 id 必填
|
|
2399
|
-
* @param params.mediaType 音频呼叫 or 音视频呼叫 必填
|
|
2400
|
-
* @param params.listener (session上的监听) 必填
|
|
2401
|
-
* @param params.constraints 获取音频或音视频资源时的参数 可选
|
|
2402
|
-
* @param params.channelId 组织 Id 可选
|
|
2403
|
-
* @param params.extra 消息扩展信息
|
|
2404
|
-
* @deprecated 5.1.2 版本废弃 params.pushTitle 通知的标题
|
|
2405
|
-
* @deprecated 5.1.2 版本废弃 params.pushContent 通知的内容
|
|
2406
|
-
* @param params.bitrate 需要设置的码率参数
|
|
2407
|
-
*
|
|
2408
|
-
*/
|
|
2409
|
-
async call({
|
|
2410
|
-
targetId: e,
|
|
2411
|
-
mediaType: t = O.AUDIO,
|
|
2412
|
-
listener: i,
|
|
2413
|
-
constraints: n,
|
|
2414
|
-
channelId: o = "",
|
|
2415
|
-
extra: r = "",
|
|
2416
|
-
pushTitle: a = "",
|
|
2417
|
-
pushContent: h = "",
|
|
2418
|
-
bitrate: c
|
|
2419
|
-
}) {
|
|
2420
|
-
return this.__call({
|
|
2421
|
-
targetId: e,
|
|
2422
|
-
mediaType: t,
|
|
2423
|
-
listener: i,
|
|
2424
|
-
constraints: n,
|
|
2425
|
-
channelId: o,
|
|
2426
|
-
extra: r,
|
|
2427
|
-
pushTitle: a,
|
|
2428
|
-
pushContent: h,
|
|
2429
|
-
bitrate: c
|
|
2430
|
-
});
|
|
2431
|
-
}
|
|
2432
|
-
async __call({
|
|
2433
|
-
targetId: e,
|
|
2434
|
-
mediaType: t = O.AUDIO,
|
|
2435
|
-
listener: i,
|
|
2436
|
-
constraints: n,
|
|
2437
|
-
channelId: o = "",
|
|
2438
|
-
extra: r = "",
|
|
2439
|
-
pushTitle: a = "",
|
|
2440
|
-
pushContent: h = "",
|
|
2441
|
-
bitrate: c,
|
|
2442
|
-
isCrossAppkey: _ = !1
|
|
2443
|
-
}) {
|
|
2444
|
-
const u = this._callPushConfig ? this._callPushConfig : { pushTitle: a, pushContent: h };
|
|
2445
|
-
this._logger.info("_", `[RCCallClient call] extra->${r} pushConfig->${JSON.stringify(u)}`);
|
|
2446
|
-
const S = [te(e), se(t), j(i), X(r)], C = [];
|
|
2447
|
-
if (!S.every((I) => (!I.result && C.push(I.msg), I.result)))
|
|
2448
|
-
throw new Error(`[RCCallClient call] ${C.join(`
|
|
2449
|
-
`)}`);
|
|
2450
|
-
const { code: y, errorMsg: U } = J(u);
|
|
2451
|
-
if (y !== l.SUCCESS)
|
|
2452
|
-
return this._logger.error("_", `[RCCallClient call] param error, errorMsg: ${U}`), { code: y };
|
|
2453
|
-
let E = [];
|
|
2454
|
-
const { code: M, tracks: N } = await this._getLocalTrack(t, n);
|
|
2455
|
-
if (M !== l.SUCCESS)
|
|
2456
|
-
return { code: M };
|
|
2457
|
-
E = N, E.forEach((I) => {
|
|
2458
|
-
var L, k, H;
|
|
2459
|
-
I.isAudioTrack() && (c != null && c.audio) && I.setBitrate(c == null ? void 0 : c.audio), I.isVideoTrack() && (c != null && c.video) && I.setBitrate((L = c == null ? void 0 : c.video) == null ? void 0 : L.max, (k = c == null ? void 0 : c.video) == null ? void 0 : k.min, (H = c == null ? void 0 : c.video) == null ? void 0 : H.start), i.onTrackReady(I);
|
|
2460
|
-
});
|
|
2461
|
-
const { code: A, stateMachine: v } = await this._callEngine.call(o, e, t, r, u, _);
|
|
2462
|
-
if (A === l.SUCCESS && v) {
|
|
2463
|
-
this._logger.info("_", "[RCCallClient call] successfully created state machine");
|
|
2464
|
-
const I = new z(v, this._rtcClient, this._logger, {
|
|
2465
|
-
localTracks: E,
|
|
2466
|
-
// 是否允许订阅重试
|
|
2467
|
-
isAllowSubscribeRetry: this._options.isAllowSubscribeRetry,
|
|
2468
|
-
// 是否允许订阅重试
|
|
2469
|
-
isAllowPublishRetry: this._options.isAllowPublishRetry,
|
|
2470
|
-
/**
|
|
2471
|
-
* 禁用视频时关摄像头
|
|
2472
|
-
*/
|
|
2473
|
-
isOffCameraWhenVideoDisable: this._options.isOffCameraWhenVideoDisable,
|
|
2474
|
-
/**
|
|
2475
|
-
* RTC 房间加入类型
|
|
2476
|
-
*/
|
|
2477
|
-
joinType: this._options.joinType,
|
|
2478
|
-
// 允许降级获得流,获得音视频不成功 ,降级获得音频, 默认不允许
|
|
2479
|
-
isAllowDemotionGetStream: this._options.isAllowDemotionGetStream,
|
|
2480
|
-
// 标明是主叫产生的session
|
|
2481
|
-
produceType: x.CALLER,
|
|
2482
|
-
isCrossAppkey: _,
|
|
2483
|
-
callPushConfig: this._callPushConfig,
|
|
2484
|
-
hungupPushConfig: this._hungupPushConfig
|
|
2485
|
-
});
|
|
2486
|
-
return I.registerSessionListener(i), this._sessionList.push(I), this._logger.info("_", `[RCCallClient call] successfully created session object, sessionId: ${I.getSessionId()}`), { code: A, session: I };
|
|
2487
|
-
}
|
|
2488
|
-
return this._logger.error("_", `[RCCallClient call] call failed code ->: ${A}`), E.forEach((I) => {
|
|
2489
|
-
I.mute(), I.destroy();
|
|
2490
|
-
}), { code: A };
|
|
2491
|
-
}
|
|
2492
|
-
/**
|
|
2493
|
-
* 发起群组呼叫
|
|
2494
|
-
* @param params.targetId 群组 Id 必填
|
|
2495
|
-
* @param params.userIds 被呼叫的群内成员 Id 必填
|
|
2496
|
-
* @param params.mediaType 音频呼叫 or 音视频呼叫 必填
|
|
2497
|
-
* @param params.listener (session上的监听) 必填
|
|
2498
|
-
* @param params.constraints 获取音频或音视频资源时的参数 可选
|
|
2499
|
-
* @param params.channelId 组织 Id 可选
|
|
2500
|
-
* @param params.extra 消息扩展信息 可选
|
|
2501
|
-
* @deprecated 5.1.2 版本废弃 params.pushTitle 通知的标题
|
|
2502
|
-
* @deprecated 5.1.2 版本废弃 params.pushContent 通知的内容
|
|
2503
|
-
* @param params.bitrate 需要设置的码率参数
|
|
2504
|
-
*/
|
|
2505
|
-
async callInGroup({
|
|
2506
|
-
targetId: e,
|
|
2507
|
-
userIds: t,
|
|
2508
|
-
mediaType: i = O.AUDIO,
|
|
2509
|
-
listener: n,
|
|
2510
|
-
constraints: o,
|
|
2511
|
-
channelId: r = "",
|
|
2512
|
-
extra: a = "",
|
|
2513
|
-
pushTitle: h = "",
|
|
2514
|
-
pushContent: c = "",
|
|
2515
|
-
bitrate: _
|
|
2516
|
-
}) {
|
|
2517
|
-
const u = this._callPushConfig ? this._callPushConfig : { pushTitle: h, pushContent: c }, S = [te(e), le(t), se(i), j(n), X(a)], C = [];
|
|
2518
|
-
if (!S.every((I) => (!I.result && C.push(I.msg), I.result)))
|
|
2519
|
-
throw new Error(`[RCCallClient callInGroup] ${C.join(`
|
|
2520
|
-
`)}`);
|
|
2521
|
-
const { code: y, errorMsg: U } = J(u);
|
|
2522
|
-
if (y !== l.SUCCESS)
|
|
2523
|
-
return this._logger.error("_", `[RCCallClient call] param error, errorMsg: ${U}`), { code: y };
|
|
2524
|
-
let E = [];
|
|
2525
|
-
const { code: M, tracks: N } = await this._getLocalTrack(i, o);
|
|
2526
|
-
if (M !== l.SUCCESS)
|
|
2527
|
-
return { code: M };
|
|
2528
|
-
E = N, E.forEach((I) => {
|
|
2529
|
-
var L, k, H;
|
|
2530
|
-
I.isAudioTrack() && (_ != null && _.audio) && I.setBitrate(_ == null ? void 0 : _.audio), I.isVideoTrack() && (_ != null && _.video) && I.setBitrate((L = _ == null ? void 0 : _.video) == null ? void 0 : L.max, (k = _ == null ? void 0 : _.video) == null ? void 0 : k.min, (H = _ == null ? void 0 : _.video) == null ? void 0 : H.start), n.onTrackReady(I);
|
|
2531
|
-
});
|
|
2532
|
-
const { code: A, stateMachine: v } = await this._callEngine.callInGroup(r, e, i, t, a, u);
|
|
2533
|
-
if (A === l.SUCCESS && v) {
|
|
2534
|
-
this._logger.info("_", "[RCCallClient callInGroup] successfully created state machine");
|
|
2535
|
-
const I = new z(v, this._rtcClient, this._logger, {
|
|
2536
|
-
localTracks: E,
|
|
2537
|
-
// 是否允许订阅重试
|
|
2538
|
-
isAllowSubscribeRetry: this._options.isAllowSubscribeRetry,
|
|
2539
|
-
// 是否允许发布重试
|
|
2540
|
-
isAllowPublishRetry: this._options.isAllowPublishRetry,
|
|
2541
|
-
/**
|
|
2542
|
-
* 禁用视频时关摄像头
|
|
2543
|
-
*/
|
|
2544
|
-
isOffCameraWhenVideoDisable: this._options.isOffCameraWhenVideoDisable,
|
|
2545
|
-
/**
|
|
2546
|
-
* RTC 房间加入类型
|
|
2547
|
-
*/
|
|
2548
|
-
joinType: this._options.joinType,
|
|
2549
|
-
// 允许降级获得流,获得音视频不成功 ,降级获得音频, 默认不允许
|
|
2550
|
-
isAllowDemotionGetStream: this._options.isAllowDemotionGetStream,
|
|
2551
|
-
// 标明是主叫产生的session
|
|
2552
|
-
produceType: x.CALLER,
|
|
2553
|
-
callPushConfig: this._callPushConfig,
|
|
2554
|
-
hungupPushConfig: this._hungupPushConfig
|
|
2555
|
-
});
|
|
2556
|
-
return I.registerSessionListener(n), this._sessionList.push(I), this._logger.info("_", `[RCCallClient callInGroup] successfully created session object, sessionId: ${I.getSessionId()}`), { code: A, session: I };
|
|
2557
|
-
}
|
|
2558
|
-
return this._logger.info("_", `[RCCallClient callInGroup] callInGroup failed code -> ${A}`), E.forEach((I) => {
|
|
2559
|
-
I.mute(), I.destroy();
|
|
2560
|
-
}), { code: A };
|
|
2561
|
-
}
|
|
2562
|
-
/**
|
|
2563
|
-
* 调RTC API 获得本地流
|
|
2564
|
-
*/
|
|
2565
|
-
async _getLocalTrackCore(e, t) {
|
|
2566
|
-
if (e === O.AUDIO) {
|
|
2567
|
-
const { code: o, track: r } = await this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC", t && t.audio && { ...t.audio });
|
|
2568
|
-
return o !== p.SUCCESS ? (this._logger.error("_", `[RCCallClient _getTrack] get Audio local tracks failed RCT code -> ${o}`), { code: l.GET_LOCAL_AUDIO_TRACK_ERROR }) : (this._logger.info("_", "[RCCallClient _getTrack] successfully get Audio local tracks"), { code: l.SUCCESS, tracks: [r] });
|
|
2569
|
-
}
|
|
2570
|
-
const { code: i, tracks: n } = await this._rtcClient.createMicrophoneAndCameraTracks("RongCloudRTC", t && { ...t });
|
|
2571
|
-
return i !== p.SUCCESS ? (this._logger.error("_", `[RCCallClient _getTrack] get Audio and Video local tracks failed RCT code -> ${i}`), { code: l.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR }) : (this._logger.info("_", "[RCCallClient _getTrack] successfully get audio and video local tracks"), { code: l.SUCCESS, tracks: n });
|
|
2572
|
-
}
|
|
2573
|
-
async _getLocalTrack(e, t) {
|
|
2574
|
-
if (this._options.isAllowDemotionGetStream && e === O.AUDIO_VIDEO) {
|
|
2575
|
-
const { code: o, tracks: r } = await this._getLocalTrackCore(O.AUDIO_VIDEO, t);
|
|
2576
|
-
if (o !== l.SUCCESS) {
|
|
2577
|
-
const { code: a, tracks: h } = await this._getLocalTrackCore(O.AUDIO, t);
|
|
2578
|
-
return a !== l.SUCCESS ? { code: a } : { code: a, tracks: h };
|
|
2579
|
-
}
|
|
2580
|
-
return { code: o, tracks: r };
|
|
2581
|
-
}
|
|
2582
|
-
const { code: i, tracks: n } = await this._getLocalTrackCore(e, t);
|
|
2583
|
-
return i !== l.SUCCESS ? { code: i } : { code: i, tracks: n };
|
|
2584
|
-
}
|
|
2585
|
-
/**
|
|
2586
|
-
* 从sessionList删除某个session
|
|
2587
|
-
*/
|
|
2588
|
-
_removeSession(e) {
|
|
2589
|
-
const t = e.getSessionId();
|
|
2590
|
-
this._sessionList = this._sessionList.filter((i) => i.getSessionId() !== t);
|
|
2591
|
-
}
|
|
2592
|
-
/**
|
|
2593
|
-
* 获取己方其他端加入通话(已加入 RTC 房间)的用户信息
|
|
2594
|
-
*/
|
|
2595
|
-
async getJoinedRoomInfo() {
|
|
2596
|
-
const { code: e, data: t } = await this._context.getRTCJoinedUserInfo(this._context.getCurrentId());
|
|
2597
|
-
return e !== W.SUCCESS ? (this._logger.error("_", `getJoinedUserInfo error code: ${e}`), { code: l.QUERY_JOINED_USER_INFO_ERROR }) : { code: l.SUCCESS, data: t };
|
|
2598
|
-
}
|
|
2599
|
-
/**
|
|
2600
|
-
* 设置呼叫、挂断推送数据
|
|
2601
|
-
* @param callPushConfig 呼叫推送配置
|
|
2602
|
-
* @param callPushConfig.pushTitle 呼叫推送标题
|
|
2603
|
-
* @param callPushConfig.pushContent 呼叫推送内容
|
|
2604
|
-
* @param hungupPushConfig 挂断推送配置
|
|
2605
|
-
* @param hungupPushConfig.pushTitle 挂断推送标题
|
|
2606
|
-
* @param hungupPushConfig.pushContent 挂断推送内容
|
|
2607
|
-
*/
|
|
2608
|
-
setPushConfig(e, t) {
|
|
2609
|
-
const i = [e, t].map((n) => J(n));
|
|
2610
|
-
for (const { code: n, errorMsg: o } of i)
|
|
2611
|
-
if (n !== l.SUCCESS)
|
|
2612
|
-
return this._logger.error("_", `[RCCallClient setPushConfig] param error, errorMsg: ${o}`), { code: n };
|
|
2613
|
-
this._callPushConfig = e, this._hungupPushConfig = t;
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
q.add("plugin-call", "5.2.4");
|
|
2617
|
-
const Be = {
|
|
2618
|
-
tag: "RCCall",
|
|
2619
|
-
verify(s) {
|
|
2620
|
-
return s.tag === "browser";
|
|
2621
|
-
},
|
|
2622
|
-
setup(s, e, t) {
|
|
2623
|
-
const i = Ue(t);
|
|
2624
|
-
if (!i.result)
|
|
2625
|
-
throw new Error(`[RCCallLib installer steup]${i.msg}`);
|
|
2626
|
-
if (!q.validEngine("5.9.0"))
|
|
2627
|
-
throw new Error(`The current engine version '${q.getInfo().engine}' error, plugin-call required engine version at least '5.9.0'.`);
|
|
2628
|
-
const n = s.createLogger("RCCall", "RTC");
|
|
2629
|
-
return t.logOutputLevel && n.setOutputLevel(t.logOutputLevel), typeof t.logLevel < "u" && n.warn("_", "The 'logLevel' parameter is deprecated, please use 'logOutputLevel' instead."), n.warn("_", "RCCall Version: 5.2.4, Commit: 0a7b424ef05373eeea5ff3c35af1286656a750fd"), new He(s, e, n, t);
|
|
2630
|
-
}
|
|
2631
|
-
};
|
|
2632
|
-
export {
|
|
2633
|
-
He as RCCallClient,
|
|
2634
|
-
g as RCCallEndReason,
|
|
2635
|
-
l as RCCallErrorCode,
|
|
2636
|
-
P as RCCallLanguage,
|
|
2637
|
-
O as RCCallMediaType,
|
|
2638
|
-
z as RCCallSession,
|
|
2639
|
-
T as RCCallSessionState,
|
|
2640
|
-
m as RCCallUserState,
|
|
2641
|
-
Be as installer
|
|
2642
|
-
};
|
|
2643
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZXNtLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9lbmdpbmUvaGVscGVyLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvZW51bXMvTXNnQ2FsbFN0YXR1cy50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL2VudW1zL1JDQ2FsbENvZGUudHMiLCIuLi8uLi8uLi9lbmdpbmUvY29yZS9lbnVtcy9SQ0NhbGxFbmRSZWFzb24udHMiLCIuLi8uLi8uLi9lbmdpbmUvY29yZS9lbnVtcy9SQ0NhbGxNZXNzYWdlVHlwZS50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL2VudW1zL1JDQ2FsbFNlc3Npb25TdGF0ZS50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL2VudW1zL1JDQ2FsbFVzZXJTdGF0ZS50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL2VudW1zL1JDQ3Jvc3NDYWxsVHlwZS50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL1RpbWVyLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvU3RhdGVNYWNoaW5lLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvZW51bXMvUkNDYWxsTWVkaWFUeXBlLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvZW51bXMvTWVtYmVyTW9kaWZ5VHlwZS50cyIsIi4uLy4uLy4uL2VuZ2luZS9jb3JlL2VudW1zL1BsYXRmb3JtLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvT2ZmbGluZVJlY29yZGVyLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvTWVzc2FnZUhhbmRsZXIudHMiLCIuLi8uLi8uLi9lbmdpbmUvY29yZS9lbnVtcy9SQ0NhbGxMYW5nLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvbG9jYWxlL2VuLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvbG9jYWxlL3poLnRzIiwiLi4vLi4vLi4vZW5naW5lL2NvcmUvbG9jYWxlL2luZGV4LnRzIiwiLi4vLi4vLi4vZW5naW5lL2luZGV4LnRzIiwiLi4vLi4vLi4vc3JjL2VudW1zLnRzIiwiLi4vLi4vLi4vc3JjL3V0aWxzLnRzIiwiLi4vLi4vLi4vc3JjL2V2ZW50RW1pdHRlci50cyIsIi4uLy4uLy4uL3NyYy92YWxpZGF0aW9uLnRzIiwiLi4vLi4vLi4vc3JjL2hlbHBlci50cyIsIi4uLy4uLy4uL3NyYy90aW1lci50cyIsIi4uLy4uLy4uL3NyYy9SQ0NhbGxTZXNzaW9uLnRzIiwiLi4vLi4vLi4vc3JjL1JDQ2FsbENsaWVudC50cyIsIi4uLy4uLy4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFdmVudEVtaXR0ZXIsIElSdW50aW1lIH0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuXG5jb25zdCBzdHJpbmcxMHRvNjQgPSAobnVtYmVyOiBudW1iZXIpID0+IHtcbiAgY29uc3QgY2hhcnMgPSAnMDEyMzQ1Njc4OWFiY2RlZmdoaWdrbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJR0tMTU5PUFFSU1RVVldYWVorLycuc3BsaXQoJycpO1xuICBjb25zdCByYWRpeCA9IGNoYXJzLmxlbmd0aCArIDE7XG4gIGxldCBxdXRpZW50ID0gK251bWJlcjtcbiAgY29uc3QgYXJyID0gW107XG4gIGRvIHtcbiAgICBjb25zdCBtb2QgPSBxdXRpZW50ICUgcmFkaXg7XG4gICAgcXV0aWVudCA9IChxdXRpZW50IC0gbW9kKSAvIHJhZGl4O1xuICAgIGFyci51bnNoaWZ0KGNoYXJzW21vZF0pO1xuICB9IHdoaWxlIChxdXRpZW50KTtcbiAgcmV0dXJuIGFyci5qb2luKCcnKTtcbn07XG5cbmNvbnN0IGdldFVVSUQgPSAoKSA9PiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIChjKSA9PiB7XG4gIGNvbnN0IHIgPSBNYXRoLnJhbmRvbSgpICogMTYgfCAwO1xuICBjb25zdCB2ID0gYyA9PT0gJ3gnID8gciA6IChyICYgMHgzIHwgMHg4KTtcbiAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xufSk7XG5cbi8qIOiOt+WPliAyMiDkvY3nmoQgVVVJRCAqL1xuZXhwb3J0IGNvbnN0IGdldFVVSUQyMiA9ICgpID0+IHtcbiAgbGV0IHV1aWQ6IHN0cmluZyB8IG51bWJlciA9IGdldFVVSUQoKTtcbiAgdXVpZCA9IGAke3V1aWQucmVwbGFjZSgvLS9nLCAnJyl9MGA7XG4gIHV1aWQgPSBwYXJzZUludCh1dWlkLCAxNik7XG4gIHV1aWQgPSBzdHJpbmcxMHRvNjQodXVpZCk7XG4gIGlmICh1dWlkLmxlbmd0aCA+IDIyKSB7XG4gICAgdXVpZCA9IHV1aWQuc2xpY2UoMCwgMjIpO1xuICB9XG4gIHJldHVybiB1dWlkO1xufTtcblxuLyoqXG4gKiDnlJ/miJDpmo/mnLogaWQg5a2X56ym5LiyXG4gKi9cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVJhbmRvbUlkID0gKCk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmRvbSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDApO1xuICBsZXQgdXVpZCA9IGdldFVVSUQyMigpO1xuICB1dWlkID0gdXVpZC5yZXBsYWNlKC9cXC8vZywgJzAnKTtcbiAgY29uc3QgaW5mbyA9IFt1dWlkLCBEYXRlLm5vdygpLCByYW5kb21dO1xuICByZXR1cm4gaW5mby5qb2luKCdfJyk7XG59O1xuXG5leHBvcnQgY29uc3QgdGltZXJTZXRUaW1lb3V0ID0gKGZ1bmM6IEZ1bmN0aW9uLCB0aW1lb3V0OiBudW1iZXIpOiBudW1iZXIgPT4gc2V0VGltZW91dChmdW5jLCB0aW1lb3V0KSBhcyBudW1iZXI7XG5cbmV4cG9ydCBjb25zdCB0aW1lckludGVydmFsID0gKGZ1bjogRnVuY3Rpb24sIGl0djogbnVtYmVyKTogbnVtYmVyID0+IHNldEludGVydmFsKGZ1biwgaXR2KSBhcyBudW1iZXI7XG5cbmV4cG9ydCBjb25zdCBldmVudEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbi8qKlxuICogY2FsbCBkZXZpY2VJZCDlrZjlgqjlnKggc2Vzc2lvblN0b3JhZ2Ug5LitXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRDYWxsRGV2aWNlSWQgPSAocnVudGltZTogSVJ1bnRpbWUpID0+IHtcbiAgY29uc3Qga2V5ID0gJ1JDQ2FsbERldmljZUlkJztcbiAgbGV0IHV1aWQgPSBydW50aW1lLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgaWYgKCF1dWlkKSB7XG4gICAgdXVpZCA9IGdldFVVSUQyMigpO1xuICAgIHJ1bnRpbWUuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShrZXksIHV1aWQpO1xuICB9XG4gIHJldHVybiB1dWlkO1xufTtcbiIsIi8qKlxuICog5rOo6YeKXG4gKiBUT0RPXG4gKi9cbmV4cG9ydCBlbnVtIE1zZ0NhbGxTdGF0dXMge1xuICBPVVRHT0lORyA9IDEsIC8vIHdhaXRpbmdcbiAgSU5DT01JTkcsIC8vIHdhaXRpbmdcbiAgUklOR0lORywgLy8gd2FpdGluZ1xuICBDT05ORUNURUQsIC8vIGtlZXBpbmdcbiAgSURMRSwgLy8gZW5kXG4gIEFDQ0VQVEVEIC8vIHdhaXRpbmdcbn1cbiIsIi8qKlxuICog6ZSZ6K+v56CB77yM5LiO56e75Yqo56uv5a+56b2QXG4gKiBAZGVzY3JpcHRpb25cbiAqIDEuIGA1MTAwMCAtIDUxOTk5YCDkuLogQW5kcm9pZCDkuJPnlKjmrrVcbiAqIDIuIGA1MjAwMCAtIDUyOTk5YCDkuLogaU9TIOS4k+eUqOautVxuICogMy4gYDUzMDAwIC0gNTMxOTlgIOS4uiBXZWIgUlRDIOS4k+eUqOautVxuICogNC4gYDUzMjAwIC0gNTM0OTlgIOS4uiBXZWIgQ2FsbExpYiDkuJPnlKjmrrVcbiAqICogIGA1MzIwMCAtIDUzMjk5YCDkuLogV2ViIENhbGxFbmdpbmUg5LiT55So56uvXG4gKiAqICBgNTMzMDAgLSA1MzQ5OWAg5Li6IFdlYiBDYWxsIOS4k+eUqOerr1xuICogNS4gYDUzNTAwIC0gNTM5OTlgIOS4uiBXZWIg5L+d55WZ5q61XG4gKi9cbmV4cG9ydCBlbnVtIFJDQ2FsbEVycm9yQ29kZSB7XG4gIC8qKlxuICAgKiDmiJDlip9cbiAgICovXG4gIFNVQ0NFU1MgPSAxMDAwMCxcbiAgLyoqXG4gICAqIOWtmOWcqOacque7k+adn+eahOeKtuaAgeaculxuICAgKi9cbiAgU1RBVEVfTUFDSElORV9FWElUID0gNTMyMDAsXG4gIC8qKlxuICAgKiDlj5HpgIEgSU0g5raI5oGv5aSx6LSlXG4gICAqL1xuICBTRU5EX01TR19FUlJPUiA9IDUzMjAxLFxuICAvKipcbiAgICog6KKr5a+55pa55Yqg5YWl6buR5ZCN5Y2VXG4gICAqL1xuICBSRUpFQ1RFRF9CWV9CTEFDS0xJU1QgPSA1MzIwMixcbiAgLyoqXG4gICAqIOW9k+WJjeeUqOaIt+S4jeWGjee+pOe7hOS4rVxuICAgKi9cbiAgTk9UX0lOX0dST1VQID0gNTMyMDMsXG5cbiAgLyoqXG4gICAqIENhbGwg55u45YWzXG4gICAqL1xuICAvKipcbiAgICog6I635b6X5pys5Zyw6Z+z6aKR5rWB5aSx6LSlXG4gICAqL1xuICBHRVRfTE9DQUxfQVVESU9fVFJBQ0tfRVJST1IgPSA1MzMwMSxcblxuICAvKipcbiAgICog6I635b6X5pys5Zyw6KeG6aKR5rWB5aSx6LSlXG4gICAqL1xuICBHRVRfTE9DQUxfVklERU9fVFJBQ0tfRVJST1IgPSA1MzMwMixcblxuICAvKipcbiAgICog6I635b6X5pys5Zyw6Z+z6KeG6aKR5rWB5aSx6LSlXG4gICAqL1xuICBHRVRfTE9DQUxfQVVESU9fQU5EX1ZJREVPX1RSQUNLX0VSUk9SID0gNTMzMDMsXG5cbiAgLyoqXG4gICAqIOWKoOWFpeaIv+mXtOWksei0pVxuICAgKi9cbiAgSk9JTl9ST09NX0VSUk9SID0gNTMzMDQsXG5cbiAgLyoqXG4gICAqIOWPkeW4g+mfs+mikeWksei0pVxuICAgKi9cbiAgQVVESU9fUFVCTElTSF9FUlJPUiA9IDUzMzA1LFxuXG4gIC8qKlxuICAgKiDlj5HluIPop4bpopHlpLHotKVcbiAgICovXG4gIFZJREVPX1BVQkxJU0hfRVJST1IgPSA1MzMwNixcblxuICAvKipcbiAgICog5Y+R5biD6Z+z6KeG6aKR5aSx6LSlXG4gICAqL1xuICBBVURJT19BTkRfVklERU9fUFVCTElTSF9FUlJPUiA9IDUzMzA3LFxuXG4gIC8qKlxuICAgKiDmn6Xor6LmiL/pl7TnlKjmiLfkv6Hmga/lpLHotKVcbiAgICovXG4gIFFVRVJZX0pPSU5FRF9VU0VSX0lORk9fRVJST1IgPSA1MzMwOCxcblxuICAvKipcbiAgICog56aB55So5ZCv55So6KeG6aKR5pe277yM5oi/6Ze05YaF57y65bCR6KeG6aKR5rWBXG4gICAqL1xuICBNSVNTSU5HX1ZJREVPX1RSQUNLX0VSUk9SID0gNTMzMDksXG5cbiAgLyoqXG4gICAqIOWPlua2iOWPkeW4g+inhumikeWksei0pVxuICAgKi9cbiAgVU5QVUJMSVNIX1ZJREVPX0VSUk9SID0gNTMzMTAsXG5cbiAgLyoqXG4gICAqIOS8muivneS4jeaYr+e+pOe7hFxuICAgKi9cbiAgQ09OVkVSU0FUSU9OX05PVF9HUk9VUF9FUlJPUiA9IDUzMzExLFxuXG4gIC8qKlxuICAqIOS4jeWcqHJvb23kuK3npoHnlKjpn7Pop4bpopFcbiAgKi9cbiAgTk9UX0lOX1JPT01fRVJST1IgPSA1MzMxMixcblxuICAvKipcbiAgICog5Y+C5pWw6ZSZ6K+vXG4gICAqL1xuICBQQVJBTV9FUlJPUiA9IDUzMzEzXG59XG4iLCIvKipcbiAqIOaMguaWreWOn+WboFxuICogQGRlc2NyaXB0aW9uXG4gKiDmoLnmja7ljp/mnIkgSGFuZ3VwUmVhc29uIOiuvuiuoe+8jOW3seaWueWOn+WboOS4juWvueaWueWOn+WboOacieebuOW3riAxMCDnmoTlt67ot50uXG4gKiDnjrDmnInmnKzlnLDljp/lm6Dlj5blgLzojIPlm7Q6IDEgfiAxMCwg6L+c56uv5Y6f5Zug5Y+W5YC86IyD5Zu0OiAxMSB+IDIwLlxuICog5Li65L6/5LqOIEhhbmd1cFJlYXNvbiDmianlsZXvvIzkv53nlZkgMTAwIOS7peWGheeahOWPluWAvC5cbiAqIOmcgOimgeWGjeasoeaJqeWxleaXtu+8jOW3seaWueWOn+WboOS9v+eUqDogMjEgfiAzMCwg5a+55bqU5a+55pa55Y6f5Zug5L2/55SoOiAzMSB+IDQwLFxuICog5Lul5q2k57G75o6o77yMXG4gKiDlt7Hmlrnljp/lm6Dkvb/nlKg6IDQxIH4gNTAsIOWvueaWueWOn+WboOS9v+eUqDogNTEgfiA2MCxcbiAqIOW3seaWueWOn+WboOS9v+eUqDogNjEgfiA3MCwg5a+55pa55Y6f5Zug5L2/55SoOiA3MSB+IDgwLFxuICog5bex5pa55Y6f5Zug5L2/55SoOiA3MSB+IDkwLCDlr7nmlrnljp/lm6Dkvb/nlKg6IDkxIH4gMTAwLlxuICpcbiAqIOWQhOW5s+WPsOeLrOacieWtl+auteiMg+WbtFxuICogQW5kcm9pZCAyMDEgfiAyOTlcbiAqIGlPUyAgICAgMzAxIH4gMzk5XG4gKiBXZWIgICAgIDQwMSB+IDQ5OVxuICog6K+m57uG5paH5qGj77yaaHR0cHM6Ly9naXRib29rLnJvbmdjbG91ZC5uZXQvcnRjLWRvY3MvIy9ydGMtY2xpZW50L2lvcy9hbmFseXNpcy9jYWxsbGliL0hhbmd1cFJlYXNvblxuICovXG5leHBvcnQgZW51bSBSQ0NhbGxFbmRSZWFzb24ge1xuICAvKipcbiAgICog5bex5pa55Y+W5raI5bey5Y+R5Ye655qE6YCa6K+d6K+35rGCXG4gICAqL1xuICBDQU5DRUwgPSAxLFxuICAvKipcbiAgICog5bex5pa55ouS57ud5pS25Yiw55qE6YCa6K+d6K+35rGCXG4gICAqL1xuICBSRUpFQ1QgPSAyLFxuICAvKipcbiAgICog5bex5pa55oyC5patXG4gICAqL1xuICBIQU5HVVAgPSAzLFxuICAvKipcbiAgICog5bex5pa55b+Z56KMXG4gICAqL1xuICBCVVNZX0xJTkUgPSA0LFxuICAvKipcbiAgICog5bex5pa55pyq5o6l5ZCsXG4gICAqL1xuICBOT19SRVNQT05TRSA9IDUsXG4gIC8qKlxuICAgKiDlt7HmlrnkuI3mlK/mjIHlvZPliY3pn7Pop4bpopHlvJXmk45cbiAgICovXG4gIEVOR0lORV9VTlNVUFBPUlRFRCA9IDYsXG4gIC8qKlxuICAgKiDlt7HmlrnnvZHnu5zplJnor69cbiAgICovXG4gIE5FVFdPUktfRVJST1IgPSA3LFxuICAvKipcbiAgICog5bex5pa55pGE5YOP5aS06LWE5rqQ6I635Y+W5aSx6LSl77yM5Y+v6IO95piv5p2D6ZmQ5Y6f5ZugXG4gICAqL1xuICBHRVRfTUVESUFfUkVTT1VSQ0VTX0VSUk9SID0gOCxcbiAgLyoqXG4gICAqIOW3seaWuei1hOa6kOWPkeW4g+Wksei0pVxuICAgKi9cbiAgUFVCTElTSF9FUlJPUiA9IDksXG4gIC8qKlxuICAgKiDlt7HmlrnorqLpmIXotYTmupDlpLHotKVcbiAgICovXG4gIFNVQlNDUklCRV9FUlJPUiA9IDEwLFxuICAvKipcbiAgICog5a+55pa55Y+W5raI5Y+R5Ye655qE6YCa6K+d6K+35rGCXG4gICAqL1xuICBSRU1PVEVfQ0FOQ0VMID0gMTEsXG4gIC8qKlxuICAgKiDlr7nmlrnmi5Lnu53mlLbliLDnmoTpgJror53or7fmsYJcbiAgICovXG4gIFJFTU9URV9SRUpFQ1QgPSAxMixcbiAgLyoqXG4gICAqIOmAmuivnei/h+eoi+S4reWvueaWueaMguaWrVxuICAgKi9cbiAgUkVNT1RFX0hBTkdVUCA9IDEzLFxuICAvKipcbiAgICog5a+55pa55b+Z56KMXG4gICAqL1xuICBSRU1PVEVfQlVTWV9MSU5FID0gMTQsXG4gIC8qKlxuICAgKiDlr7nmlrnmnKrmjqXlkKxcbiAgICovXG4gIFJFTU9URV9OT19SRVNQT05TRSA9IDE1LFxuICAvKipcbiAgICog5a+55pa55byV5pOO5LiN5pSv5oyBXG4gICAqL1xuICBSRU1PVEVfRU5HSU5FX1VOU1VQUE9SVEVEID0gMTYsXG4gIC8qKlxuICAgKiDlr7nmlrnnvZHnu5zplJnor69cbiAgICovXG4gIFJFTU9URV9ORVRXT1JLX0VSUk9SID0gMTcsXG4gIC8qKlxuICAgKiDlr7nmlrnmkYTlg4/lpLTotYTmupDojrflj5blpLHotKXvvIzlj6/og73mmK/mnYPpmZDljp/lm6BcbiAgICovXG4gIFJFTU9URV9HRVRfTUVESUFfUkVTT1VSQ0VfRVJST1IgPSAxOCxcbiAgLyoqXG4gICAqIOi/nOerr+i1hOa6kOWPkeW4g+Wksei0pVxuICAgKi9cbiAgUkVNT1RFX1BVQkxJU0hfRVJST1IgPSAxOSxcbiAgLyoqXG4gICAqIOi/nOerr+iuoumYhei1hOa6kOWksei0pVxuICAgKi9cbiAgUkVNT1RFX1NVQlNDUklCRV9FUlJPUiA9IDIwLFxuICAvKipcbiAgICog5bex5pa55YW25LuW56uv5bey5Yqg5YWl5paw6YCa6K+dXG4gICAqL1xuICBPVEhFUl9DTElFTlRfSk9JTkVEX0NBTEwgPSAyMSxcbiAgLyoqXG4gICAqIOW3seaWueWFtuS7luerr+W3suWcqOmAmuivneS4rVxuICAgKi9cbiAgT1RIRVJfQ0xJRU5UX0lOX0NBTEwgPSAyMixcbiAgLyoqXG4gICAqIOW3seaWueiiq+emgeatoumAmuivnVxuICAgKi9cbiAgS0lDS0VEX0JZX1NFUlZFUiA9IDIzLFxuICAvKipcbiAgICog5bex5pa55o6l5ZCs57O757uf6YCa6K+d77yI56e75Yqo56uv54m55pyJ77yJXG4gICovXG4gIEFDQ0VQVF9TWVNURU1fQ0FMTCA9IDI0LFxuICAvKipcbiAgICog6L+c56uv5YW25LuW56uv5bey5Yqg5YWl5paw6YCa6K+dXG4gICAqL1xuICBSRU1PVEVfT1RIRVJfQ0xJRU5UX0pPSU5FRF9DQUxMID0gMzEsXG4gIC8qKlxuICAgKiDov5znq6/lhbbku5bnq6/lt7LlnKjpgJror53kuK1cbiAgICovXG4gIFJFTU9URV9PVEhFUl9DTElFTlRfSU5fQ0FMTCA9IDMyLFxuICAvKipcbiAgICog6L+c56uv6KKr56aB5q2i6YCa6K+dXG4gICAqL1xuICBSRU1PVEVfS0lDS0VEX0JZX1NFUlZFUiA9IDMzLFxuICAvKipcbiAgICog6L+c56uv5o6l5ZCs57O757uf6YCa6K+d77yI56e75Yqo56uv54m55pyJ77yJXG4gICovXG4gIFJFTU9URV9BQ0NFUFRfU1lTVEVNX0NBTEwgPSAzNCxcbiAgLyoqXG4gICAqIOWFtuS7luerr+aOpeWQrFxuICAgKi9cbiAgQUNDRVBUX0JZX09USEVSX0NMSUVOVCA9IDEwMSxcbiAgLyoqXG4gICAqIOWFtuS7luerr+aMguaWrVxuICAgKi9cbiAgSEFOR1VQX0JZX09USEVSX0NMSUVOVCA9IDEwMixcbiAgLyoqXG4gICAqIOW3seaWueiiq+WvueaWueWKoOWFpem7keWQjeWNlVxuICAgKi9cbiAgQURERURfVE9fQkxBQ0tMSVNUID0gMTAzLFxuICAvKipcbiAgICog6Z+z6KeG6aKR5pyN5Yqh5pyq5byA6YCaXG4gICAqL1xuICBTRVJWSUNFX05PVF9PUEVORUQgPSAxMDRcbn1cblxuLyoqXG4gKiDlt7Hmlrnljp/lm6DovazkuLrlr7nmlrnljp/lm6BcbiAqL1xuZXhwb3J0IGNvbnN0IENhbGxSZW1vdGVFbmRSZWFzb246IHsgW2tleTogbnVtYmVyXTogUkNDYWxsRW5kUmVhc29uIH0gPSB7XG4gIFtSQ0NhbGxFbmRSZWFzb24uQ0FOQ0VMXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9DQU5DRUwsXG4gIFtSQ0NhbGxFbmRSZWFzb24uUkVKRUNUXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9SRUpFQ1QsXG4gIFtSQ0NhbGxFbmRSZWFzb24uSEFOR1VQXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9IQU5HVVAsXG4gIFtSQ0NhbGxFbmRSZWFzb24uQlVTWV9MSU5FXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9CVVNZX0xJTkUsXG4gIFtSQ0NhbGxFbmRSZWFzb24uTk9fUkVTUE9OU0VdOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05PX1JFU1BPTlNFLFxuICBbUkNDYWxsRW5kUmVhc29uLkVOR0lORV9VTlNVUFBPUlRFRF06IFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfRU5HSU5FX1VOU1VQUE9SVEVELFxuICBbUkNDYWxsRW5kUmVhc29uLk5FVFdPUktfRVJST1JdOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05FVFdPUktfRVJST1IsXG4gIFtSQ0NhbGxFbmRSZWFzb24uR0VUX01FRElBX1JFU09VUkNFU19FUlJPUl06IFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfR0VUX01FRElBX1JFU09VUkNFX0VSUk9SLFxuICBbUkNDYWxsRW5kUmVhc29uLlBVQkxJU0hfRVJST1JdOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX1BVQkxJU0hfRVJST1IsXG4gIFtSQ0NhbGxFbmRSZWFzb24uU1VCU0NSSUJFX0VSUk9SXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9TVUJTQ1JJQkVfRVJST1IsXG4gIFtSQ0NhbGxFbmRSZWFzb24uT1RIRVJfQ0xJRU5UX0pPSU5FRF9DQUxMXTogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9PVEhFUl9DTElFTlRfSk9JTkVEX0NBTEwsXG4gIFtSQ0NhbGxFbmRSZWFzb24uT1RIRVJfQ0xJRU5UX0lOX0NBTExdOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX09USEVSX0NMSUVOVF9JTl9DQUxMLFxuICBbUkNDYWxsRW5kUmVhc29uLktJQ0tFRF9CWV9TRVJWRVJdOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX0tJQ0tFRF9CWV9TRVJWRVIsXG4gIFtSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05PX1JFU1BPTlNFXTogUkNDYWxsRW5kUmVhc29uLk5PX1JFU1BPTlNFLFxuICBbUkNDYWxsRW5kUmVhc29uLkFDQ0VQVF9TWVNURU1fQ0FMTF06IFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfQUNDRVBUX1NZU1RFTV9DQUxMLFxufTtcbiIsImV4cG9ydCBlbnVtIFJDQ2FsbE1lc3NhZ2VUeXBlIHtcbiAgLyoqXG4gICAqIOmCgOivt+a2iOaBr1xuICAgKi9cbiAgVkNJbnZpdGUgPSAnUkM6VkNJbnZpdGUnLFxuICAvKipcbiAgICog5ZON6ZOD5raI5oGvXG4gICAqL1xuICBWQ1JpbmdpbmcgPSAnUkM6VkNSaW5naW5nJyxcbiAgLyoqXG4gICAqIOaOpeWQrOa2iOaBr1xuICAgKi9cbiAgVkNBY2NlcHQgPSAnUkM6VkNBY2NlcHQnLFxuICAvKipcbiAgICog5oyC5pat5raI5oGvXG4gICAqL1xuICBWQ0hhbmd1cCA9ICdSQzpWQ0hhbmd1cCcsXG4gIC8qKlxuICAgKiDnvqTlkbzkuK0g5Lq65ZGY5Y+Y5pu05raI5oGvXG4gICAqL1xuICBWQ01vZGlmeU1lbSA9ICdSQzpWQ01vZGlmeU1lbScsXG4gIC8qKlxuICAgKiDlqpLkvZPnsbvlnovkv67mlLnmtojmga9cbiAgICovXG4gIFZDTW9kaWZ5TWVkaWEgPSAnUkM6VkNNb2RpZnlNZWRpYScsXG59XG4iLCJleHBvcnQgZW51bSBSQ0NhbGxTZXNzaW9uU3RhdGUge1xuICAvKipcbiAgICog562J5b6F5bu656uL6L+e5o6lXG4gICAqL1xuICBXQUlUSU5HLFxuICAvKipcbiAgICog5Lya6K+d57u05oyB5LitXG4gICAqL1xuICBLRUVQSU5HLFxuICAvKipcbiAgICog5Lya6K+d5bey57uT5p2fXG4gICAqL1xuICBFTkRcbn1cbiIsImV4cG9ydCBlbnVtIFJDQ2FsbFVzZXJTdGF0ZSB7XG4gIC8qKlxuICAgKiDnlKjmiLfkuI3lrZjlnKjkuo7pgJror53kuK1cbiAgICovXG4gIE5PTkUgPSAwLFxuICAvKipcbiAgICog562J5b6F5o6l5ZCsXG4gICAqL1xuICBXQUlUSU5HLFxuICAvKipcbiAgICog6YCa6K+d5LitXG4gICAqL1xuICBLRUVQSU5HLFxufVxuIiwiZXhwb3J0IGVudW0gUkNDcm9zc0NhbGxUeXBlIHtcbiAgLyohXG4gIOWQjEFwcOmAmuivnVxuICAqL1xuICBSQ0NhbGxSb29tVHlwZU5vcm1hbENhbGwgPSAwLFxuICAvKiFcbiAg6LeoQXBw6YCa6K+dXG4gICovXG4gIFJDQ2FsbFJvb21UeXBlQWNyb3NzQ2FsbCA9IDdcbn1cbiIsImltcG9ydCB7IHRpbWVyU2V0VGltZW91dCB9IGZyb20gJy4uL2hlbHBlcic7XG5cbmV4cG9ydCBjbGFzcyBUaW1lciB7XG4gIHByaXZhdGUgX3RpbWVySWQ6IG51bWJlciA9IDBcblxuICBwcml2YXRlIF9zdGFydFRpbWU6IG51bWJlciA9IDBcblxuICBjb25zdHJ1Y3RvcihjYWxsYmFjazogRnVuY3Rpb24sIHRpbWVvdXQ6IG51bWJlcikge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgdGhpcy5fdGltZXJJZCA9IHRpbWVyU2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICB9LCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdGhpcy5fc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfVxuXG4gIHN0b3AoKToge1xuICAgIHN0YXJ0VGltZTogbnVtYmVyLFxuICAgIGVuZFRpbWU6IG51bWJlcixcbiAgICBkdXJhdGlvbjogbnVtYmVyXG4gICAgfSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVySWQpO1xuXG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgbGV0IGR1cmF0aW9uID0gZW5kVGltZSAtIHRoaXMuX3N0YXJ0VGltZTtcbiAgICBpZiAodGhpcy5fc3RhcnRUaW1lID09PSAwKSB7XG4gICAgICBkdXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0VGltZTogdGhpcy5fc3RhcnRUaW1lLFxuICAgICAgZW5kVGltZSxcbiAgICAgIGR1cmF0aW9uLFxuICAgIH07XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl9zdGFydFRpbWUgPSAwO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBDb252ZXJzYXRpb25UeXBlLCBJTG9nZ2VyLCBJUmVjZWl2ZWRNZXNzYWdlLCBJUnVudGltZSwgUlRDUGx1Z2luQ29udGV4dCxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgZXZlbnRFbWl0dGVyLCBnZXRDYWxsRGV2aWNlSWQgfSBmcm9tICcuLi9oZWxwZXInO1xuaW1wb3J0IHsgTXNnQ2FsbFN0YXR1cyB9IGZyb20gJy4vZW51bXMvTXNnQ2FsbFN0YXR1cyc7XG5pbXBvcnQgeyBSQ0NhbGxFcnJvckNvZGUgfSBmcm9tICcuL2VudW1zL1JDQ2FsbENvZGUnO1xuaW1wb3J0IHsgQ2FsbFJlbW90ZUVuZFJlYXNvbiwgUkNDYWxsRW5kUmVhc29uIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxFbmRSZWFzb24nO1xuaW1wb3J0IHsgUkNDYWxsTWVkaWFUeXBlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxNZWRpYVR5cGUnO1xuaW1wb3J0IHsgUkNDYWxsTWVzc2FnZVR5cGUgfSBmcm9tICcuL2VudW1zL1JDQ2FsbE1lc3NhZ2VUeXBlJztcbmltcG9ydCB7IFJDQ2FsbFNlc3Npb25TdGF0ZSB9IGZyb20gJy4vZW51bXMvUkNDYWxsU2Vzc2lvblN0YXRlJztcbmltcG9ydCB7IFJDQ2FsbFVzZXJTdGF0ZSB9IGZyb20gJy4vZW51bXMvUkNDYWxsVXNlclN0YXRlJztcbmltcG9ydCB7XG4gIElFeGlzdGVkVXNlclBvZmlsZXMsIElIdW5ndXBNc2dDb250ZW50LCBJSW52aXRlTXNnQ29udGVudCwgSU1lbWJlck1vZGlmeU1zZ0NvbnRlbnQsIElSaW5naW5nTXNnQ29udGVudCxcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL0lNZXNzYWdlSGFuZGxlcic7XG5pbXBvcnQge1xuICBJQ2FsbFN0YXRlTWFjaGluZVdhdGNoZXJzLCBJRW5kU3VtbWFyeSwgSUludml0ZWRVc2VycywgSVVzZXJEYXRhLCBJVXNlclByb2ZpbGUsIElJbnZpdGVPcHRpb25zLFxufSBmcm9tICcuL2ludGVyZmFjZXMvSVN0YXRlTWFjaGluZSc7XG5pbXBvcnQgeyBDYWxsTWVzc2FnZUhhbmRsZXIgfSBmcm9tICcuL01lc3NhZ2VIYW5kbGVyJztcbmltcG9ydCB7IFJDQ3Jvc3NDYWxsVHlwZSB9IGZyb20gJy4vZW51bXMvUkNDcm9zc0NhbGxUeXBlJztcbmltcG9ydCB7IFRpbWVyIH0gZnJvbSAnLi9UaW1lcic7XG5pbXBvcnQgeyBJUHVzaENvbmZpZyB9IGZyb20gJy4uLy4uL3NyYy9pbnRlcmZhY2UnO1xuXG5leHBvcnQgY2xhc3MgUkNDYWxsU3RhdGVNYWNoaW5lIHtcbiAgLyoqXG4gICAqIOaIv+mXtOeKtuaAgVxuICAgKi9cbiAgcHJpdmF0ZSBfc2Vzc2lvblN0YXRlOiBSQ0NhbGxTZXNzaW9uU3RhdGUgfCBudWxsID0gbnVsbFxuXG4gIC8qKlxuICAgKiDnlKjmiLfnirbmgIHlj4rkv6Hmga9cbiAgICovXG4gIHByaXZhdGUgX3VzZXJJbmZvOiB7IFt1c2VySWQ6IHN0cmluZ106IElVc2VyRGF0YSB9ID0ge31cblxuICAvKipcbiAgICog55So5oi36K6h5pe25Zmo5pig5bCEXG4gICAqL1xuICBwcml2YXRlIF91c2VyVGltZXJzOiB7IFt1c2VySWQ6IHN0cmluZ106IFRpbWVyIH0gPSB7fVxuXG4gIC8qKlxuICAgKiDnm5HlkKzlmahcbiAgICovXG4gIHByaXZhdGUgX3dhdGNoZXJzITogSUNhbGxTdGF0ZU1hY2hpbmVXYXRjaGVyc1xuXG4gIC8qKlxuICAgKiDlkbzlj6votoXml7bml7bpl7QgKOWNleS9je+8muavq+enkilcbiAgICovXG4gIHByaXZhdGUgX2NhbGxUaW1lb3V0OiBudW1iZXIgPSA2MCAqIDEwMDBcblxuICAvKipcbiAgICog6YCa6K+d5bu656uL5byA5aeL5pe26Ze0XG4gICAqL1xuICBwcml2YXRlIF9iZWdpblRpbWVzdGFtcDogbnVtYmVyID0gMFxuXG4gIC8qKlxuICAgKiDpgJror53nu5PmnZ/ml7bpl7RcbiAgICovXG4gIHByaXZhdGUgX2VuZFRpbWVzdGFtcDogbnVtYmVyID0gMFxuXG4gIC8qKlxuICAgKiDpgJror53nu5PmnZ/ljp/lm6BcbiAgICovXG4gIHByaXZhdGUgX2VuZFJlYXNvbjogUkNDYWxsRW5kUmVhc29uIHwgbnVsbCA9IG51bGxcblxuICAvKipcbiAgICog5Li75Y+rIElEXG4gICAqIOWPkei1t+mCgOivt+S4uuW9k+WJjeeUqOaItyBJRFxuICAgKiDmlLbliLDpgoDor7fkuLogc2VuZGVyVXNlcklkXG4gICAqIOaUtuWIsOS6uuWRmOWPmOabtOmCgOivt+S4uua2iOaBr+S9k+S4rSBjYWxsZXJJZFxuICAgKi9cbiAgcHJpdmF0ZSBfY2FsbGVySWQ6IHN0cmluZyB8IG51bGwgPSBudWxsXG5cbiAgLyoqXG4gICAqIOW9k+asoemAmuivnemCgOivt+iAhSBJRFxuICAgKiDlj5HotbfpgoDor7fkuLrlvZPliY3nlKjmiLcgSUTjgIHmlLbliLDpgoDor7fkuLogc2VuZGVyVXNlcklk44CB5pS25Yiw5Lq65ZGY5Y+Y5pu06YKA6K+35Li65raI5oGv5L2T5LitIHNlbmRlclVzZXJJZFxuICAgKi9cbiAgcHJpdmF0ZSBfaW52aXRlcklkOiBzdHJpbmcgfCBudWxsID0gbnVsbFxuXG4gIC8qKlxuICAgKiDmmK/lkKbmmK/ot6ggYXBwa2V5XG4gICAqL1xuICBwcml2YXRlIF9pc0Nyb3NzQXBwa2V5OiBib29sZWFuID0gZmFsc2VcblxuICBwcml2YXRlIF9odW5ndXBQdXNoQ29uZmlnPzogSVB1c2hDb25maWdcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jb250ZXh0OiBSVENQbHVnaW5Db250ZXh0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3J1bnRpbWU6IElSdW50aW1lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogSUxvZ2dlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jYWxsTXNnSGFuZGxlcjogQ2FsbE1lc3NhZ2VIYW5kbGVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5uZWxJZDogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnZlcnNhdGlvblR5cGU6IENvbnZlcnNhdGlvblR5cGUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfdGFyZ2V0SWQ6IHN0cmluZyxcbiAgICBwcml2YXRlIF9tZWRpYVR5cGU6IFJDQ2FsbE1lZGlhVHlwZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jYWxsSWQ6IHN0cmluZyxcbiAgKSB7XG4gICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIucmVnaXN0ZXJTdGF0ZU1hY2hpbmVFdmVudCh0aGlzLl9jYWxsSWQsICdvblJpbmdpbmcnLCB0aGlzLl9vblJpbmdpbmcuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIucmVnaXN0ZXJTdGF0ZU1hY2hpbmVFdmVudCh0aGlzLl9jYWxsSWQsICdvbkFjY2VwdCcsIHRoaXMuX29uQWNjZXB0LmJpbmQodGhpcykpO1xuICAgIHRoaXMuX2NhbGxNc2dIYW5kbGVyLnJlZ2lzdGVyU3RhdGVNYWNoaW5lRXZlbnQodGhpcy5fY2FsbElkLCAnb25NZWRpYU1vZGlmeScsIHRoaXMuX29uTWVkaWFNb2RpZnkuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIucmVnaXN0ZXJTdGF0ZU1hY2hpbmVFdmVudCh0aGlzLl9jYWxsSWQsICdvbkh1bmd1cCcsIHRoaXMuX29uSHVuZ3VwLmJpbmQodGhpcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluagoeato+WQjui2heaXtuaXtumXtFxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0VGltZW91dChzZW50VGltZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgZGVsYXlUaW1lID0gdGhpcy5fY29udGV4dC5nZXRTZXJ2ZXJUaW1lKCkgLSBzZW50VGltZTtcbiAgICBpZiAoZGVsYXlUaW1lIDwgMCkge1xuICAgICAgZGVsYXlUaW1lID0gNTAwOyAvLyDlgYforr7lu7bov5/ml7bpl7TkuLogNTAwIG1zXG4gICAgfVxuICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLl9jYWxsVGltZW91dCAtIGRlbGF5VGltZTtcbiAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBfZ2V0VGltZW91dCAtPiB0aW1lb3V0OiAke3RpbWVvdXR9YCk7XG4gICAgcmV0dXJuIHRpbWVvdXQ7XG4gIH1cblxuICBwcml2YXRlIF9jbGVhclRpbWVyQnlJZCh1c2VySWQ6IHN0cmluZykge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsIGBbUkNDYWxsU3RhdGVNYWNoaW5lXSBiZWZvcmUgX2NsZWFyVGltZXJCeUlkICAtPiB1c2VySWQ6ICR7dXNlcklkfSB1c2VyVGltZXJzOiAke0pTT04uc3RyaW5naWZ5KHRoaXMuX3VzZXJUaW1lcnMpfWApO1xuICAgIGlmICh0aGlzLl91c2VyVGltZXJzW3VzZXJJZF0pIHtcbiAgICAgIHRoaXMuX3VzZXJUaW1lcnNbdXNlcklkXS5zdG9wKCk7XG4gICAgICBkZWxldGUgdGhpcy5fdXNlclRpbWVyc1t1c2VySWRdO1xuICAgIH1cbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gYWZ0ZXIgX2NsZWFyVGltZXJCeUlkIC0+IHVzZXJUaW1lcnM6ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5fdXNlclRpbWVycyl9YCk7XG4gIH1cblxuICAvKipcbiAgICog6YCa55+lIGNhbGwg5bGC5oi/6Ze054q25oCB5Y+Y5pu05Y+K5Y6f5ZugXG4gICAqL1xuICBwcml2YXRlIF9ub3RpZnlTdGF0ZUNoYW5nZShzdGF0ZTogUkNDYWxsU2Vzc2lvblN0YXRlLCByZWFzb24/OiBSQ0NhbGxFbmRSZWFzb24pIHtcbiAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBbUkNDYWxsU3RhdGVNYWNoaW5lXSBub3RpZnlTdGF0ZUNoYW5nZSAtPiBpbmZvOiAke0pTT04uc3RyaW5naWZ5KHtcbiAgICAgIHN0YXRlLCByZWFzb24sXG4gICAgfSl9YCk7XG5cbiAgICB0aGlzLl9lbmRSZWFzb24gPSByZWFzb24gfHwgbnVsbDtcbiAgICBpZiAodGhpcy5fc2Vzc2lvblN0YXRlICE9PSBzdGF0ZSkge1xuICAgICAgdGhpcy5fc2Vzc2lvblN0YXRlID0gc3RhdGU7XG4gICAgICB0aGlzLl93YXRjaGVycz8ub25TdGF0ZUNoYW5nZSh7IHN0YXRlLCByZWFzb24gfSk7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gUkNDYWxsU2Vzc2lvblN0YXRlLkVORCkge1xuICAgICAgLy8g5b2T54q25oCB5py657uT5p2f5pe277yM6ZyA5ZyoIENhbGxFbmdpbmUg5riF6ZmkXG4gICAgICBldmVudEVtaXR0ZXIuZW1pdCgnb25TdGF0ZU1hY2hpbmVDbG9zZScsIHRoaXMuX2NhbGxJZCk7XG4gICAgICB0aGlzLl9jYWxsTXNnSGFuZGxlci51bnJlZ2lzdGVyU3RhdGVNYWNoaW5lRXZlbnQodGhpcy5fY2FsbElkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6YCa55+lIGNhbGwg5bGC5Lq65ZGY54q25oCB5Y+Y5pu05Y+K5Y6f5ZugXG4gICAqL1xuICBwcml2YXRlIF9ub3RpZnlVc2VyU3RhdGVDaGFuZ2UodXNlcjogSVVzZXJEYXRhLCByZWFzb24/OiBSQ0NhbGxFbmRSZWFzb24pIHtcbiAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBbUkNDYWxsU3RhdGVNYWNoaW5lXSBub3RpZnlVc2VyU3RhdGVDaGFuZ2UgLT4gaW5mbzogJHtKU09OLnN0cmluZ2lmeSh7XG4gICAgICB1c2VyLCByZWFzb24sXG4gICAgfSl9YCk7XG4gICAgdGhpcy5fd2F0Y2hlcnM/Lm9uVXNlclN0YXRlQ2hhbmdlKHsgdXNlciwgcmVhc29uIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3RoZXJDbGllbnRIYW5kbGUobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIGNvbnN0IHsgc2VuZGVyVXNlcklkLCBjb250ZW50OiB7IHVzZXI6IHVzZXJQcm9maWxlLCByZWFzb246IGh1bmd1cFJlYXNvbiB9LCBtZXNzYWdlVHlwZSB9ID0gbWVzc2FnZTtcbiAgICB0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdID0ge1xuICAgICAgdXNlcklkOiBzZW5kZXJVc2VySWQsXG4gICAgICBzdGF0ZTogUkNDYWxsVXNlclN0YXRlLk5PTkUsXG4gICAgICBpc0NhbGxlcjogZmFsc2UsXG4gICAgICBpc1JlbW90ZTogZmFsc2UsXG4gICAgfTtcbiAgICAvLyDlpJrnq6/mjqXlkKzjgIHlpJrnq6/mi5Lnu53vvIzmuIXpmaTmlLbliLDpgoDor7flkI7otbfnmoTorqHml7blmahcbiAgICBmb3IgKGNvbnN0IHVzZXJJZCBpbiB0aGlzLl91c2VyVGltZXJzKSB7XG4gICAgICB0aGlzLl9jbGVhclRpbWVyQnlJZCh1c2VySWQpO1xuICAgIH1cbiAgICAvLyDlhbbku5bnq6/mjqXlkKxcbiAgICBsZXQgZW5kUmVhc29uID0gUkNDYWxsRW5kUmVhc29uLkFDQ0VQVF9CWV9PVEhFUl9DTElFTlQ7XG4gICAgaWYgKG1lc3NhZ2VUeXBlID09PSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ0hhbmd1cCkge1xuICAgICAgaWYgKGh1bmd1cFJlYXNvbiA9PT0gUkNDYWxsRW5kUmVhc29uLkJVU1lfTElORSkge1xuICAgICAgICBlbmRSZWFzb24gPSBSQ0NhbGxFbmRSZWFzb24uT1RIRVJfQ0xJRU5UX0lOX0NBTEw7XG4gICAgICB9IGVsc2UgaWYgKGh1bmd1cFJlYXNvbiA9PT0gUkNDYWxsRW5kUmVhc29uLk5PX1JFU1BPTlNFKSB7XG4gICAgICAgIGVuZFJlYXNvbiA9IFJDQ2FsbEVuZFJlYXNvbi5OT19SRVNQT05TRTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZFJlYXNvbiA9IFJDQ2FsbEVuZFJlYXNvbi5IQU5HVVBfQllfT1RIRVJfQ0xJRU5UO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyDmt7vliqDnlKjmiLfnroDopoHkv6Hmga9cbiAgICBPYmplY3QuYXNzaWduKHRoaXMuX3VzZXJJbmZvW3NlbmRlclVzZXJJZF0sIDxJVXNlclByb2ZpbGU+dXNlclByb2ZpbGUpO1xuICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdLCBlbmRSZWFzb24pO1xuICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlKFJDQ2FsbFNlc3Npb25TdGF0ZS5FTkQsIGVuZFJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICog5q2j5Zyo6YCa6K+d5Lit77yM5LiU5LiN5piv5b2T5YmN5bey5o6l6YCa55So5oi36K6+5aSH77yIZGV2aWNlSWTvvInlj5HmnaXnmoTmtojmga9cbiAgKi9cbiAgcHJpdmF0ZSBfaXNSZW1vdGVJbnZhbGlkTXNnKHJlbW90ZVVzZXJJZDogc3RyaW5nLCBtc2dEZXZpY2VJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLl91c2VySW5mb1tyZW1vdGVVc2VySWRdKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl91c2VySW5mb1tyZW1vdGVVc2VySWRdLmRldmljZUlkIHx8ICFtc2dEZXZpY2VJZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICgodGhpcy5fdXNlckluZm9bcmVtb3RlVXNlcklkXS5zdGF0ZSA9PT0gUkNDYWxsVXNlclN0YXRlLktFRVBJTkcgJiYgdGhpcy5fdXNlckluZm9bcmVtb3RlVXNlcklkXS5kZXZpY2VJZCAhPT0gbXNnRGV2aWNlSWQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIF9vblJpbmdpbmcobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIGNvbnN0IHsgc2VuZGVyVXNlcklkOiBzdWlkLCBjb250ZW50OiB7IHVzZXI6IHVzZXJQcm9maWxlLCBkZXZpY2VJZCB9IH0gPSBtZXNzYWdlO1xuICAgIGNvbnN0IHNlbmRlclVzZXJJZCA9IHRoaXMuX2lzQ3Jvc3NBcHBrZXkgPyBzdWlkLnNwbGl0KCdfJylbMV0gOiBzdWlkO1xuICAgIC8vIOato+WcqOmAmuivneS4re+8jOi/nOerr+Wkmuerr+WPkeeahOa2iOaBr+ebtOaOpei/h+a7pFxuICAgIGlmICh0aGlzLl9pc1JlbW90ZUludmFsaWRNc2coc2VuZGVyVXNlcklkLCBkZXZpY2VJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsU3RhdGVNYWNoaW5lXSBvblJpbmdpbmcgLT4gbm90IHRoZSByZW1vdGUgZGV2aWNlIHRoYXQgaXMgY3VycmVudGx5IHRhbGtpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSA9PT0gc2VuZGVyVXNlcklkKSB7XG4gICAgICByZXR1cm47IC8vIOWkmuerr+WkhOeQhlxuICAgIH1cbiAgICB0aGlzLl93YXRjaGVycy5vblJpbmdpbmcoeyB1c2VySWQ6IHNlbmRlclVzZXJJZCwgLi4uPElVc2VyUHJvZmlsZT51c2VyUHJvZmlsZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX29uQWNjZXB0KG1lc3NhZ2U6IElSZWNlaXZlZE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7IHNlbmRlclVzZXJJZDogc3VpZCwgY29udGVudDogeyB1c2VyOiB1c2VyUHJvZmlsZSwgZGV2aWNlSWQ6IHNlbmRlckRldmljZUlkIH0sIHNlbnRUaW1lIH0gPSBtZXNzYWdlO1xuICAgIGNvbnN0IHNlbmRlclVzZXJJZCA9IHRoaXMuX2lzQ3Jvc3NBcHBrZXkgPyBzdWlkLnNwbGl0KCdfJylbMV0gOiBzdWlkO1xuICAgIGNvbnN0IGN1cnJlbnRVc2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIC8vIOato+WcqOmAmuivneS4re+8jOi/nOerr+Wkmuerr+WPkeeahOa2iOaBr+ebtOaOpei/h+a7pFxuICAgIGlmICh0aGlzLl9pc1JlbW90ZUludmFsaWRNc2coc2VuZGVyVXNlcklkLCBzZW5kZXJEZXZpY2VJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsU3RhdGVNYWNoaW5lXSBfb25BY2NlcHQgLT4gbm90IHRoZSByZW1vdGUgZGV2aWNlIHRoYXQgaXMgY3VycmVudGx5IHRhbGtpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFVzZXJJZCA9PT0gc2VuZGVyVXNlcklkKSB7XG4gICAgICAvLyDlpJrnq6/lpITnkIZcbiAgICAgIHRoaXMuX290aGVyQ2xpZW50SGFuZGxlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOe+pOe7hOmAmuivneaXtu+8miBB44CBQiDpgJror50gQemCgOivt0MsIEPlkIzmhI/mjqXlkKzvvIzov5nml7ZC5rKh5pyJQ+eahHVzZXJJZOWvueW6lOeahOiuoeaXtuWZqO+8jOaJgOS7pei/memHjOWIpOaWreS4gOS4i1xuICAgIGlmICh0aGlzLl91c2VyVGltZXJzW3NlbmRlclVzZXJJZF0pIHtcbiAgICAgIC8vIOa4hemZpOWRvOWPq+i2heaXtuiuoeaXtuWZqFxuICAgICAgdGhpcy5fY2xlYXJUaW1lckJ5SWQoc2VuZGVyVXNlcklkKTtcbiAgICB9XG5cbiAgICAvLyDkv67mlLnlubbpgJrnn6XmiL/pl7TkurrlkZjnirbmgIFcbiAgICBjb25zdCBpZHMgPSAodGhpcy5fY29udmVyc2F0aW9uVHlwZSA9PT0gQ29udmVyc2F0aW9uVHlwZS5QUklWQVRFKSA/IFtjdXJyZW50VXNlcklkLCBzZW5kZXJVc2VySWRdIDogW3NlbmRlclVzZXJJZF07XG4gICAgaWRzLmZvckVhY2goKHVzZXJJZCkgPT4ge1xuICAgICAgY29uc3QgaXNDdXJyZW50VXNlcklkID0gdXNlcklkID09PSBjdXJyZW50VXNlcklkO1xuICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSA9IHtcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBzdGF0ZTogUkNDYWxsVXNlclN0YXRlLktFRVBJTkcsXG4gICAgICAgIGlzQ2FsbGVyOiBpc0N1cnJlbnRVc2VySWQsXG4gICAgICAgIGlzUmVtb3RlOiBpc0N1cnJlbnRVc2VySWQsXG4gICAgICAgIGRldmljZUlkOiBpc0N1cnJlbnRVc2VySWQgPyBnZXRDYWxsRGV2aWNlSWQodGhpcy5fcnVudGltZSkgOiBzZW5kZXJEZXZpY2VJZCxcbiAgICAgIH07XG4gICAgICBpZiAoIWlzQ3VycmVudFVzZXJJZCkge1xuICAgICAgICB0aGlzLl9iZWdpblRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgIC8vIOa3u+WKoOeUqOaIt+eugOimgeS/oeaBr1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMuX3VzZXJJbmZvW3NlbmRlclVzZXJJZF0sIDxJVXNlclByb2ZpbGU+dXNlclByb2ZpbGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0pO1xuICAgIH0pO1xuICAgIGlmICh0aGlzLmdldENhbGxlcklkKCkgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlKFJDQ2FsbFNlc3Npb25TdGF0ZS5LRUVQSU5HKTtcbiAgICB9XG4gICAgLy8g5oqb5Ye6b25BY2NlcHTml7bnirbmgIHlt7Lnu4/lsLHnu6pcbiAgICB0aGlzLl93YXRjaGVycy5vbkFjY2VwdCh7IHVzZXJJZDogc2VuZGVyVXNlcklkIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25NZWRpYU1vZGlmeShtZXNzYWdlOiBJUmVjZWl2ZWRNZXNzYWdlKSB7XG4gICAgY29uc3QgeyBzZW5kZXJVc2VySWQsIGNvbnRlbnQ6IHsgbWVkaWFUeXBlLCB1c2VyOiB1c2VyUHJvZmlsZSwgZGV2aWNlSWQgfSB9ID0gbWVzc2FnZTtcbiAgICAvLyDmraPlnKjpgJror53kuK3vvIzov5znq6/lpJrnq6/lj5HnmoTmtojmga/nm7TmjqXov4fmu6RcbiAgICBpZiAodGhpcy5faXNSZW1vdGVJbnZhbGlkTXNnKHNlbmRlclVzZXJJZCwgZGV2aWNlSWQpKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCAnW1JDQ2FsbFN0YXRlTWFjaGluZV0gX29uTWVkaWFNb2RpZnkgLT4gbm90IHRoZSByZW1vdGUgZGV2aWNlIHRoYXQgaXMgY3VycmVudGx5IHRhbGtpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKSA9PT0gc2VuZGVyVXNlcklkKSB7IC8vIOWkmuerr+WkhOeQhlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOabtOaWsCBtZWRpYVR5cGVcbiAgICB0aGlzLl9tZWRpYVR5cGUgPSBtZWRpYVR5cGU7XG4gICAgdGhpcy5fd2F0Y2hlcnMub25NZWRpYU1vZGlmeSh7XG4gICAgICBzZW5kZXI6IHsgdXNlcklkOiBzZW5kZXJVc2VySWQsIC4uLjxJVXNlclByb2ZpbGU+dXNlclByb2ZpbGUgfSxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX29uSHVuZ3VwKG1lc3NhZ2U6IElSZWNlaXZlZE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7IHNlbmRlclVzZXJJZDogc3VpZCwgY29udGVudCB9ID0gbWVzc2FnZTtcbiAgICBjb25zdCBzZW5kZXJVc2VySWQgPSB0aGlzLl9pc0Nyb3NzQXBwa2V5ID8gc3VpZC5zcGxpdCgnXycpWzFdIDogc3VpZDtcbiAgICBjb25zdCB7IHJlYXNvbiwgdXNlcjogdXNlclByb2ZpbGUsIGRldmljZUlkIH0gPSBjb250ZW50IGFzIElIdW5ndXBNc2dDb250ZW50O1xuICAgIGNvbnN0IGN1cnJlbnRVc2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIC8vIOato+WcqOmAmuivneS4re+8jOi/nOerr+Wkmuerr+WPkeeahOa2iOaBr+ebtOaOpei/h+a7pFxuICAgIGlmICh0aGlzLl9pc1JlbW90ZUludmFsaWRNc2coc2VuZGVyVXNlcklkLCBkZXZpY2VJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsU3RhdGVNYWNoaW5lXSBfb25IdW5ndXAgLT4gbm90IHRoZSByZW1vdGUgZGV2aWNlIHRoYXQgaXMgY3VycmVudGx5IHRhbGtpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFVzZXJJZCA9PT0gc2VuZGVyVXNlcklkKSB7IC8vIOWkmuerr+WkhOeQhiDmipvlh7rlpJrnq6/lt7LlpITnkIYgcmVhc29uXG4gICAgICB0aGlzLl9vdGhlckNsaWVudEhhbmRsZShtZXNzYWdlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc2Vzc2lvblN0YXRlID09PSBSQ0NhbGxTZXNzaW9uU3RhdGUuRU5EKSB7XG4gICAgICAvLyDlpoLmnpzlt7HmlrnmiL/pl7TnirbmgIHlt7Lnu5PmnZ/vvIzlho3mlLbliLAgaHVuZ3VwIOa2iOaBr+S4jeWGjeWkhOeQhlxuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gSW52YWxpZCBoYW5nIHVwIG1lc3NhZ2UsIGN1cnJlbnQgcm9vbSBzdGF0dXMgaGFzIGVuZGVkIC0+IHNlc3Npb25TdGF0ZTogJHt0aGlzLl9zZXNzaW9uU3RhdGV9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3VzZXJJbmZvW3NlbmRlclVzZXJJZF0pIHtcbiAgICAgIC8vIOS/ruaUueWGheWtmOaAgeaVsOaNruW5tumAmuefpVxuICAgICAgdGhpcy5fdXNlckluZm9bc2VuZGVyVXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FO1xuICAgICAgdGhpcy5fZW5kVGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgIC8vIOa3u+WKoOeUqOaIt+eugOimgeS/oeaBr1xuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdLCA8SVVzZXJQcm9maWxlPnVzZXJQcm9maWxlKTtcbiAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdLCBDYWxsUmVtb3RlRW5kUmVhc29uW3JlYXNvbl0pO1xuICAgICAgZGVsZXRlIHRoaXMuX3VzZXJJbmZvW3NlbmRlclVzZXJJZF07XG4gICAgfVxuXG4gICAgLy8gdGltZXIg5riF6ZmkXG4gICAgaWYgKENhbGxSZW1vdGVFbmRSZWFzb25bcmVhc29uXSA9PT0gUkNDYWxsRW5kUmVhc29uLlJFTU9URV9DQU5DRUwpIHtcbiAgICAgIC8vIOi/nOerr+WPlua2iOmAmuivne+8jOayoeaciei/nOerr+eUqOaIt++8jOa4hemZpOW3seerr+eahOaOpeWQrOi2heaXtuiuoeaXtuWZqFxuICAgICAgdGhpcy5nZXRSZW1vdGVVc2VySWRzKCkubGVuZ3RoIDwgMSAmJiB0aGlzLl9jbGVhclRpbWVyQnlJZChjdXJyZW50VXNlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0SW52aXRlcklkKCkgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgIC8vIOi/nOerr+aLkue7neOAgeW/meeijOOAgeacquaOpeWQrOetie+8jOmAmui/h+iHquW3seaYr+WQpuaYr+S4u+WPq+adpeWIpOaWreimgea4hemZpOWRvOWPq+i2heaXtuiuoeaXtuWZqCDmiJYg5o6l5ZCs6LaF5pe26K6h5pe25ZmoXG4gICAgICB0aGlzLl9jbGVhclRpbWVyQnlJZChzZW5kZXJVc2VySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdldFJlbW90ZVVzZXJJZHMoKS5sZW5ndGggPCAxICYmIHRoaXMuX2NsZWFyVGltZXJCeUlkKGN1cnJlbnRVc2VySWQpO1xuICAgIH1cblxuICAgIC8vIOaIv+mXtOS6uuWRmOS/oeaBr+WwkeS6juS4pOS4qu+8jOmAmuefpeaIv+mXtOeKtuaAgee7k+adn1xuICAgIGNvbnN0IGlzTGVzc1RoYW5Ud28gPSBPYmplY3Qua2V5cyh0aGlzLl91c2VySW5mbykubGVuZ3RoIDwgMjtcbiAgICAvLyDnvqTlkbzkuK3pgoDor7fogIXmjILmlq3vvIjpnZ7lkbzlj6vlj5HotbfogIXvvInkuJTmiL/pl7TkuK3ooqvpgoDor7fogIXpg73mnKrmjqXlkKzvvIzpgJrnn6XmiL/pl7TnirbmgIHnu5PmnZ9cbiAgICBjb25zdCBpc0ludml0ZVVzZXIgPSB0aGlzLl9pbnZpdGVySWQgPT09IHNlbmRlclVzZXJJZDtcbiAgICBjb25zdCBpc05vT25lQW5zd2VyZWQgPSBPYmplY3QudmFsdWVzKHRoaXMuX3VzZXJJbmZvKS5ldmVyeSgodXNlcikgPT4gdXNlci5zdGF0ZSAhPT0gUkNDYWxsVXNlclN0YXRlLktFRVBJTkcpO1xuICAgIGlmIChpc0xlc3NUaGFuVHdvIHx8IChpc0ludml0ZVVzZXIgJiYgaXNOb09uZUFuc3dlcmVkKSkge1xuICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgQ2FsbFJlbW90ZUVuZFJlYXNvbltyZWFzb25dKTtcbiAgICB9XG5cbiAgICAvLyDmipvlh7ogb25IdW5ndXAg5pe254q25oCB5bey57uP5bCx57uqXG4gICAgdGhpcy5fd2F0Y2hlcnMub25IdW5ndXAoeyB1c2VySWQ6IHNlbmRlclVzZXJJZCwgLi4uPElVc2VyUHJvZmlsZT51c2VyUHJvZmlsZSB9LCBDYWxsUmVtb3RlRW5kUmVhc29uW3JlYXNvbl0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOazqOWGjOS6i+S7tuebkeWQrFxuICAgKiBAcGFyYW1zIHdhdGNoZXJzXG4gICAqL1xuICByZWdpc3RlckV2ZW50TGlzdGVuZXIod2F0Y2hlcnM6IElDYWxsU3RhdGVNYWNoaW5lV2F0Y2hlcnMpIHtcbiAgICB0aGlzLl93YXRjaGVycyA9IHdhdGNoZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIOaUtuWIsCBpbnZpdGUg5raI5oGv5pe254q25oCB5py65pu05paw77yIQ2FsbEVuZ2luZSDlhoXpg6josIPnlKjvvIlcbiAgICogQHBhcmFtIG1lc3NhZ2Ug5o6l5pS25raI5oGvXG4gICAqL1xuICBfX29uSW52aXRlKG1lc3NhZ2U6IElSZWNlaXZlZE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7IHNlbmRlclVzZXJJZDogc3VpZCwgY29udGVudCwgc2VudFRpbWUgfSA9IG1lc3NhZ2U7XG4gICAgY29uc3Qge1xuICAgICAgaW52aXRlVXNlcklkczogaW5pZHMsIHVzZXI6IHVzZXJQcm9maWxlLCBkZXZpY2VJZCwgcm9vbVR5cGUsXG4gICAgfSA9IGNvbnRlbnQgYXMgSUludml0ZU1zZ0NvbnRlbnQ7XG4gICAgLy8g5aSE55CG6LeoIGFwcGtleSDpgoDor7cgc2VuZGVyVXNlcklkIOW4puaciSBhcHBrZXkg5LiO5pys5ZywIGN1cnJlbnRVc2VySWQg5Yy56YWN6Zeu6aKYXG4gICAgLy8g5ZCM5pe26K6w5b2V5pys5Zyw5piv5ZCm5Li66LeoIGFwcGtleSDnirbmgIFcbiAgICBsZXQgc2VuZGVyVXNlcklkOiBzdHJpbmc7XG4gICAgaWYgKHJvb21UeXBlID09PSBSQ0Nyb3NzQ2FsbFR5cGUuUkNDYWxsUm9vbVR5cGVBY3Jvc3NDYWxsKSB7XG4gICAgICBbLCBzZW5kZXJVc2VySWRdID0gc3VpZC5zcGxpdCgnXycpO1xuICAgICAgdGhpcy5fd2F0Y2hlcnMuY3Jvc3NBcHBrZXkodHJ1ZSk7XG4gICAgICB0aGlzLl9pc0Nyb3NzQXBwa2V5ID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VuZGVyVXNlcklkID0gc3VpZDtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgLy8g5q2j5Zyo6YCa6K+d5Lit77yM6L+c56uv5aSa56uv5Y+R55qE5raI5oGv55u05o6l6L+H5rukXG4gICAgaWYgKHRoaXMuX2lzUmVtb3RlSW52YWxpZE1zZyhzZW5kZXJVc2VySWQsIGRldmljZUlkKSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgJ1tSQ0NhbGxTdGF0ZU1hY2hpbmVdIF9fb25JbnZpdGUgLT4gbm90IHRoZSByZW1vdGUgZGV2aWNlIHRoYXQgaXMgY3VycmVudGx5IHRhbGtpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFVzZXJJZCA9PT0gc2VuZGVyVXNlcklkKSB7XG4gICAgICAvLyDlpJrnq6/lpITnkIZcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9jYWxsZXJJZCA9IHRoaXMuX2ludml0ZXJJZCA9IHNlbmRlclVzZXJJZDtcbiAgICBjb25zdCB1c2VySWRMaXN0ID0gW3N1aWQsIC4uLmluaWRzXTtcbiAgICAvLyDmlLbliLDpgoDor7flkI7vvIzlhoXpg6jlm57lupTlk43pk4Pmtojmga8sIHVzZXJJZHMg5Lyg6Zmk6Ieq5bex55qE5omA5pyJ5Lq6XG4gICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIuc2VuZFJpbmdpbmcoe1xuICAgICAgY29udmVyc2F0aW9uVHlwZTogdGhpcy5fY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkOiB0aGlzLl90YXJnZXRJZCxcbiAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgY2FsbElkOiB0aGlzLl9jYWxsSWQsXG4gICAgICB1c2VySWRzOiB1c2VySWRMaXN0LmZpbHRlcigoaWQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2lzQ3Jvc3NBcHBrZXkpIHtcbiAgICAgICAgICByZXR1cm4gaWQuc3BsaXQoJ18nKVsxXSAhPT0gY3VycmVudFVzZXJJZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaWQgIT09IGN1cnJlbnRVc2VySWQ7XG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGludml0ZVVzZXJJZHMgPSB0aGlzLl9pc0Nyb3NzQXBwa2V5ID8gW2luaWRzWzBdLnNwbGl0KCdfJylbMV1dIDogaW5pZHM7XG5cbiAgICAvLyDlkIzmraXmnKzlnLDnlKjmiLfliJfooajpnIDopoHkvb/nlKjmi4bliIblkI7nmoQgVXNlcklkIOS/neivgeacrOWcsOWFtuS7luaWueazleWMuemFjSB1c2VyaWRcbiAgICBjb25zdCBhbGxVc2VySWRzID0gW3NlbmRlclVzZXJJZCwgLi4uaW52aXRlVXNlcklkc107XG5cbiAgICAvLyDkv67mlLnlubbpgJrnn6XmiL/pl7TkurrlkZjnirbmgIFcbiAgICBhbGxVc2VySWRzLmZvckVhY2goKHVzZXJJZCkgPT4ge1xuICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSA9IHtcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBzdGF0ZTogUkNDYWxsVXNlclN0YXRlLldBSVRJTkcsXG4gICAgICAgIGlzQ2FsbGVyOiB1c2VySWQgPT09IHNlbmRlclVzZXJJZCxcbiAgICAgICAgaXNSZW1vdGU6IHVzZXJJZCAhPT0gY3VycmVudFVzZXJJZCxcbiAgICAgIH07XG4gICAgICBpZiAodXNlcklkID09PSBzZW5kZXJVc2VySWQpIHtcbiAgICAgICAgLy8g57uZIHNlbmRlclVzZXIg5re75Yqg55So5oi3566A6KaB5L+h5oGv5Y+KIGRldmljZUlkXG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5fdXNlckluZm9bdXNlcklkXSwgPElVc2VyUHJvZmlsZT51c2VyUHJvZmlsZSwgeyBkZXZpY2VJZCB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1t1c2VySWRdKTtcbiAgICAgIC8vIOe7meaJgOacieiiq+mCgOivt+S6uuWQr+WKqOaOpeWQrOiuoeaXtuWZqFxuICAgICAgaWYgKHVzZXJJZCAhPT0gc2VuZGVyVXNlcklkKSB7XG4gICAgICAgIHRoaXMuX3VzZXJUaW1lcnNbdXNlcklkXSA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVhc29uID0gdXNlcklkID09PSBjdXJyZW50VXNlcklkID8gUkNDYWxsRW5kUmVhc29uLk5PX1JFU1BPTlNFIDogUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRTtcbiAgICAgICAgICBpZiAodXNlcklkID09PSBjdXJyZW50VXNlcklkKSB7IC8vIOe+pOiBiuS4reW3seaWuei2heaXtumcgOWPkemAgeaMguaWrVxuICAgICAgICAgICAgdGhpcy5faHVuZ3VwSGFuZGxlKHJlYXNvbik7XG4gICAgICAgICAgfSBlbHNlIHsgLy8g5YW25LuW5Lq65ZGY6LaF5pe25Y+q6YCa55+l5Lq65ZGY54q25oCB5Y+Y5pu0XG4gICAgICAgICAgICB0aGlzLl91c2VySW5mb1t1c2VySWRdICYmICh0aGlzLl91c2VySW5mb1t1c2VySWRdLnN0YXRlID0gUkNDYWxsVXNlclN0YXRlLk5PTkUpO1xuICAgICAgICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0pO1xuICAgICAgICAgICAgdGhpcy5fd2F0Y2hlcnMub25IdW5ndXAodGhpcy5fdXNlckluZm9bdXNlcklkXSwgcmVhc29uKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl91c2VySW5mb1t1c2VySWRdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcy5fZ2V0VGltZW91dChzZW50VGltZSkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIOaIv+mXtOeKtuaAgemAmuefpVxuICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlKFJDQ2FsbFNlc3Npb25TdGF0ZS5XQUlUSU5HKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmlLbliLAgbWVtYmVyTW9kaWZ5IOa2iOaBr+aXtueKtuaAgeacuuabtOaWsO+8iENhbGxFbmdpbmUg5YaF6YOo6LCD55So77yJXG4gICAqIEBwYXJhbSBtZXNzYWdlIOaOpeaUtua2iOaBr1xuICAgKi9cbiAgX19vbk1lbWJlck1vZGlmeShtZXNzYWdlOiBJUmVjZWl2ZWRNZXNzYWdlKSB7XG4gICAgY29uc3QgeyBzZW5kZXJVc2VySWQsIGNvbnRlbnQsIHNlbnRUaW1lIH0gPSBtZXNzYWdlO1xuICAgIGNvbnN0IHtcbiAgICAgIHVzZXI6IHVzZXJQcm9maWxlLCBleGlzdGVkVXNlclBvZmlsZXMsIGNhbGxlciwgZGV2aWNlSWQsIGludml0ZVVzZXJJZHMsIG1lZGlhVHlwZSxcbiAgICB9ID0gY29udGVudCBhcyBJTWVtYmVyTW9kaWZ5TXNnQ29udGVudDtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICAvLyDmraPlnKjpgJror53kuK3vvIzov5znq6/lpJrnq6/lj5HnmoTmtojmga/nm7TmjqXov4fmu6RcbiAgICAvLyB0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdICYmICF0aGlzLl91c2VySW5mb1tzZW5kZXJVc2VySWRdLmRldmljZUlkICYmICFkZXZpY2VJZCAmJlxuICAgIGlmICh0aGlzLl9pc1JlbW90ZUludmFsaWRNc2coc2VuZGVyVXNlcklkLCBkZXZpY2VJZCkpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsU3RhdGVNYWNoaW5lXSBfX29uTWVtYmVyTW9kaWZ5IC0+IG5vdCB0aGUgcmVtb3RlIGRldmljZSB0aGF0IGlzIGN1cnJlbnRseSB0YWxraW5nJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjdXJyZW50VXNlcklkID09PSBzZW5kZXJVc2VySWQpIHtcbiAgICAgIC8vIOWkmuerr+WkhOeQhlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9jYWxsZXJJZCA9IGNhbGxlcjtcbiAgICB0aGlzLl9pbnZpdGVySWQgPSBzZW5kZXJVc2VySWQ7XG4gICAgaW52aXRlVXNlcklkcy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgZXhpc3RlZFVzZXJQb2ZpbGVzLnB1c2goeyB1c2VySWQ6IGlkLCBtZWRpYVR5cGUsIGNhbGxTdGF0dXM6IE1zZ0NhbGxTdGF0dXMuSU5DT01JTkcgfSk7XG4gICAgfSk7XG4gICAgLy8g5bex5pa554q25oCB5Li6IE5PTkUgKOacquWtmOWcqOW3seaWueeUqOaIt+S/oeaBrykg6K+05piO6Ieq5bex5Li66KKr6YKA6K+36ICFLCDpnIDlj5HpgIEgcmluZ2luZ1xuICAgIGNvbnN0IGlzTmV3SW52aXRlZFVzZXIgPSBpbnZpdGVVc2VySWRzLmluY2x1ZGVzKGN1cnJlbnRVc2VySWQpO1xuICAgIGlmIChpc05ld0ludml0ZWRVc2VyKSB7XG4gICAgICBjb25zdCBuZWVkUmluZ2luZ1VzZXJJZHM6IHN0cmluZ1tdID0gW107XG4gICAgICBleGlzdGVkVXNlclBvZmlsZXMuZm9yRWFjaCgodXNlckluZm8pID0+IHtcbiAgICAgICAgaWYgKHVzZXJJbmZvLnVzZXJJZCAhPT0gY3VycmVudFVzZXJJZCkge1xuICAgICAgICAgIG5lZWRSaW5naW5nVXNlcklkcy5wdXNoKHVzZXJJbmZvLnVzZXJJZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIuc2VuZFJpbmdpbmcoe1xuICAgICAgICBjb252ZXJzYXRpb25UeXBlOiB0aGlzLl9jb252ZXJzYXRpb25UeXBlLFxuICAgICAgICB0YXJnZXRJZDogdGhpcy5fdGFyZ2V0SWQsXG4gICAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgICBjYWxsSWQ6IHRoaXMuX2NhbGxJZCxcbiAgICAgICAgdXNlcklkczogbmVlZFJpbmdpbmdVc2VySWRzLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIOiiq+mCgOivt+iAhemAmuefpSBjYWxsIOWxguaIv+mXtOeKtuaAgeWPmOabtFxuICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLldBSVRJTkcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDlt7LlnKjpgJror53mtYHnqIvkuK3nlKjmiLfvvIzmipvlh7rkurrlkZjlj5jmm7Tnm5HlkKxcbiAgICAgIHRoaXMuX3dhdGNoZXJzLm9uTWVtYmVyTW9kaWZ5KHtcbiAgICAgICAgc2VuZGVyOiB7IHVzZXJJZDogc2VuZGVyVXNlcklkLCAuLi51c2VyUHJvZmlsZSB9LFxuICAgICAgICBpbnZpdGVkVXNlcnM6IGludml0ZVVzZXJJZHMubWFwKChpZCkgPT4gKHsgdXNlcklkOiBpZCB9KSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyDmm7TmlrDlhajph4/nlKjmiLfnirbmgIFcbiAgICBleGlzdGVkVXNlclBvZmlsZXMuZm9yRWFjaCgodXNlckluZm8pID0+IHtcbiAgICAgIGNvbnN0IHsgdXNlcklkLCBjYWxsU3RhdHVzIH0gPSB1c2VySW5mbztcbiAgICAgIC8vIOS6uuWRmOS4uue7k+adn+eKtuaAgeaXtu+8jOS4jeWGjeabtOaWsFxuICAgICAgaWYgKGNhbGxTdGF0dXMgPT09IE1zZ0NhbGxTdGF0dXMuSURMRSkgcmV0dXJuO1xuICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSA9IHtcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBzdGF0ZTogY2FsbFN0YXR1cyAhPT0gTXNnQ2FsbFN0YXR1cy5DT05ORUNURUQgPyBSQ0NhbGxVc2VyU3RhdGUuV0FJVElORyA6IFJDQ2FsbFVzZXJTdGF0ZS5LRUVQSU5HLFxuICAgICAgICBpc0NhbGxlcjogc2VuZGVyVXNlcklkID09PSB1c2VySWQsXG4gICAgICAgIGlzUmVtb3RlOiBjdXJyZW50VXNlcklkICE9PSB1c2VySWQsXG4gICAgICB9O1xuICAgICAgLy8g57uZIHNlbmRlclVzZXIg5re75Yqg55So5oi3566A6KaB5L+h5oGvIOWPiiBkZXZpY2VJZFxuICAgICAgaWYgKHVzZXJJZCA9PT0gc2VuZGVyVXNlcklkKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5fdXNlckluZm9bdXNlcklkXSwgPElVc2VyUHJvZmlsZT51c2VyUHJvZmlsZSwgeyBkZXZpY2VJZCB9KTtcbiAgICAgIH1cbiAgICAgIC8vIOmAmuefpeS6uuWRmOWPmOabtFxuICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0pO1xuICAgICAgLy8g6Zmk5LqGIGNhbGxNc2dTdGF0dXMuY29ubmVjdGVkICzlhbbku5bkurrpg73otbforqHml7blmahcblxuICAgICAgaWYgKGNhbGxTdGF0dXMgIT09IE1zZ0NhbGxTdGF0dXMuQ09OTkVDVEVEICYmICF0aGlzLl91c2VyVGltZXJzW3VzZXJJZF0pIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOS7hee7meiiq+mCgOivt+aIkOWRmOWQr+WKqOWumuaXtuWZqFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKCFpbnZpdGVVc2VySWRzLmluY2x1ZGVzKHVzZXJJZCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8g5ZCv5Yqo6K6h5pe25ZmoXG4gICAgICAgIHRoaXMuX3VzZXJUaW1lcnNbdXNlcklkXSA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICAgICAgLy8g5ZG85Y+r6LaF5pe25aSE55CG54q25oCB44CB5bm26YCa55+lIGNhbGwg5bGCXG4gICAgICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSAmJiAodGhpcy5fdXNlckluZm9bdXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FKTtcbiAgICAgICAgICBjb25zdCByZWFzb24gPSB1c2VySWQgPT09IGN1cnJlbnRVc2VySWQgPyBSQ0NhbGxFbmRSZWFzb24uTk9fUkVTUE9OU0UgOiBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05PX1JFU1BPTlNFO1xuICAgICAgICAgIC8vIOmAmuefpSBjYWxsIOWxguS6uuWRmOeKtuaAgeWPmOabtFxuICAgICAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1t1c2VySWRdLCByZWFzb24pO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyDlkbzlj6votoXml7bmnKrmjqXmipvlh7pvbkh1bmd1cFxuICAgICAgICAgICAgdGhpcy5fd2F0Y2hlcnMub25IdW5ndXAodGhpcy5fdXNlckluZm9bdXNlcklkXSwgcmVhc29uKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gY2FsbCBvbmh1bmd1cCBlcnJvciAtPiAke2Vycm9yPy5zdGFja31gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWxldGUgdGhpcy5fdXNlckluZm9bdXNlcklkXTtcbiAgICAgICAgICAvLyDmiL/pl7TkurrlkZjkv6Hmga/lsJHkuo7kuKTkuKog5oiWIOacquaOpeWQrOeahOaYr+iHquW3se+8jOmAmuefpeaIv+mXtOeKtuaAgee7k+adn1xuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl91c2VySW5mbykubGVuZ3RoIDwgMiB8fCB1c2VySWQgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgICAgICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlKFJDQ2FsbFNlc3Npb25TdGF0ZS5FTkQsIHJlYXNvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzLl9nZXRUaW1lb3V0KHNlbnRUaW1lKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5aSE55CG5bey5pyJIHNlc3Npb24g77yM5LiN5YWB6K645YaN5o6l5ZCs5paw5Lya6K+d5oOF5Ya1XG4gICAqL1xuICBfX2hhbmRsZUludml0ZUluU2Vzc2lvbigpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdTdGF0ZU1hY2hpbmUgLT4gX19oYW5kbGVJbnZpdGVJblNlc3Npb24nKTtcbiAgICAvLyDkv67mlLnmiYDmnInnlKjmiLfnirbmgIHlubbmipvlh7rvvIzmuIXnqbrorqHml7blmahcbiAgICBmb3IgKGNvbnN0IHVzZXJJZCBpbiB0aGlzLl91c2VySW5mbykge1xuICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXS5zdGF0ZSAmJiAodGhpcy5fdXNlckluZm9bdXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FKTtcbiAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1t1c2VySWRdKTtcbiAgICAgIC8vIOWwhuW3suWtmOWcqOeahOiuoeaXtuWZqOmDvea4heaOiVxuICAgICAgdGhpcy5fY2xlYXJUaW1lckJ5SWQodXNlcklkKTtcbiAgICB9XG4gICAgLy8g55u05o6l57uI5q2i5b2T5YmNIHNlc3Npb24g54q25oCBXG4gICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgUkNDYWxsRW5kUmVhc29uLkJVU1lfTElORSk7XG4gICAgLy8g5Y+R6YCB5oyC5pat5raI5oGv77yM5bm25pC65bimIOW3seaWueW/meeijCDljp/lm6BcbiAgICB0aGlzLl9jYWxsTXNnSGFuZGxlci5zZW5kSHVuZ3VwKHtcbiAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgY29udmVyc2F0aW9uVHlwZTogdGhpcy5fY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkOiB0aGlzLl90YXJnZXRJZCxcbiAgICAgIGNhbGxJZDogdGhpcy5fY2FsbElkLFxuICAgICAgcmVhc29uOiBSQ0NhbGxFbmRSZWFzb24uQlVTWV9MSU5FLFxuICAgICAgdXNlcklkczogdGhpcy5nZXRSZW1vdGVVc2VySWRzKCksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5Li75Yqo5ZG85Y+rIChDYWxsRW5naW5lIOWGhemDqOiwg+eUqClcbiAgICogQHBhcmFtIHVzZXJJZHMg6KKr6YKA6K+355So5oi3IElEIOWIl+ihqFxuICAgKiBAcGFyYW0gZXh0cmEg5raI5oGv55qE5omp5bGV5L+h5oGvXG4gICAqIEBwYXJhbSBwdXNoQ29uZmlnIOenu+WKqOerr+aOqOmAgemFjee9rlxuICAgKi9cbiAgYXN5bmMgX19jYWxsKHVzZXJJZHM6IHN0cmluZ1tdLCBleHRyYTogc3RyaW5nID0gJycsIHB1c2hDb25maWc6IElQdXNoQ29uZmlnLCBpc0Nyb3NzQXBwa2V5ID0gZmFsc2UpIHtcbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gaW52aXRlIC0+IHVzZXJJZHM6ICR7SlNPTi5zdHJpbmdpZnkodXNlcklkcyl9YCk7XG4gICAgLy8g5Y+R6YCB6YKA6K+35raI5oGvXG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NhbGxlcklkID0gdGhpcy5faW52aXRlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCB7IGNvZGUsIG1lc3NhZ2UgfSA9IGF3YWl0IHRoaXMuX2NhbGxNc2dIYW5kbGVyLnNlbmRJbnZpdGUoe1xuICAgICAgcm9vbVR5cGU6IGlzQ3Jvc3NBcHBrZXkgPyBSQ0Nyb3NzQ2FsbFR5cGUuUkNDYWxsUm9vbVR5cGVBY3Jvc3NDYWxsIDogUkNDcm9zc0NhbGxUeXBlLlJDQ2FsbFJvb21UeXBlTm9ybWFsQ2FsbCxcbiAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgY29udmVyc2F0aW9uVHlwZTogdGhpcy5fY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkOiB0aGlzLl90YXJnZXRJZCxcbiAgICAgIGNhbGxJZDogdGhpcy5fY2FsbElkLFxuICAgICAgZXh0cmEsXG4gICAgICBwdXNoQ29uZmlnLFxuICAgICAgbWVkaWFUeXBlOiB0aGlzLl9tZWRpYVR5cGUsXG4gICAgICBpbnZpdGVVc2VySWRzOiB1c2VySWRzLmZpbHRlcigoaWQpID0+IGlkICE9PSBjdXJyZW50VXNlcklkKSxcbiAgICB9KTtcblxuICAgIHRoaXMuX2lzQ3Jvc3NBcHBrZXkgPSBpc0Nyb3NzQXBwa2V5O1xuXG4gICAgaWYgKGNvZGUgPT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICBjb25zdCB7IHNlbnRUaW1lIH0gPSBtZXNzYWdlITtcblxuICAgICAgLyoqXG4gICAgICAgKiDot6ggYXBwa2V5IOS7heWtmOWcqOWNleiBiu+8jOWvueerryB1c2VySWQg6ZyA5Y+W5LiL5YiS57q/5ZCO6Z2i55qE6YOo5YiGXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IGlkcyA9IGlzQ3Jvc3NBcHBrZXkgPyBbY3VycmVudFVzZXJJZCwgLi4uW3VzZXJJZHNbMF0uc3BsaXQoJ18nKVsxXV1dIDogW2N1cnJlbnRVc2VySWQsIC4uLnVzZXJJZHNdO1xuXG4gICAgICAvLyDpgY3ljobmm7TmlrDmiL/pl7TmiYDmnInkurrlkZjnirbmgIHjgIHlubbnu5nooqvlj6vlkK/liqjorqHml7blmahcbiAgICAgIGlkcy5mb3JFYWNoKCh1c2VySWQpID0+IHtcbiAgICAgICAgY29uc3QgaXNDYWxsZXIgPSB1c2VySWQgPT09IGN1cnJlbnRVc2VySWQ7XG4gICAgICAgIHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0gPSB7XG4gICAgICAgICAgdXNlcklkLFxuICAgICAgICAgIHN0YXRlOiBSQ0NhbGxVc2VyU3RhdGUuV0FJVElORyxcbiAgICAgICAgICBpc0NhbGxlcixcbiAgICAgICAgICBpc1JlbW90ZTogIWlzQ2FsbGVyLFxuICAgICAgICB9O1xuICAgICAgICAvLyDpgJrnn6UgY2FsbCDlsYLkurrlkZjnirbmgIHlj5jmm7RcbiAgICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0pO1xuXG4gICAgICAgIC8vIOWQr+WKqOWRvOWPq+i2heaXtuiuoeaXtuWZqFxuICAgICAgICBpZiAoIWlzQ2FsbGVyKSB7XG4gICAgICAgICAgdGhpcy5fdXNlclRpbWVyc1t1c2VySWRdID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgICAgICAgIC8vIOWRvOWPq+i2heaXtuWkhOeQhueKtuaAgeOAgeW5tumAmuefpSBjYWxsIOWxglxuICAgICAgICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSAmJiAodGhpcy5fdXNlckluZm9bdXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FKTtcbiAgICAgICAgICAgIC8vIOmAmuefpSBjYWxsIOWxguS6uuWRmOeKtuaAgeWPmOabtFxuICAgICAgICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0sIFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfTk9fUkVTUE9OU0UpO1xuXG4gICAgICAgICAgICAvLyDlkbzlj6votoXml7bmnKrmjqXmipvlh7pvbkh1bmd1cFxuICAgICAgICAgICAgdGhpcy5fd2F0Y2hlcnMub25IdW5ndXAodGhpcy5fdXNlckluZm9bdXNlcklkXSwgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRSk7XG5cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl91c2VySW5mb1t1c2VySWRdO1xuICAgICAgICAgICAgLy8g5oi/6Ze05Lq65ZGY5L+h5oGv5bCR5LqO5Lik5Liq77yM6YCa55+l5oi/6Ze054q25oCBXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModGhpcy5fdXNlckluZm8pLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDov5znq6/kurrlkZjlpKfkuo4gMSDkuJTlt7HmlrnkuI3kuLrmraPlnKjpgJror53ml7bvvIzlj5HpgIEgaHVuZ3VwLCDlkYror4nov5znq6/oh6rlt7HpgIDlh7rpgJror51cbiAgICAgICAgICAgIGNvbnN0IGlzTmVlZFNlbmRIdW5ndXAgPSB0aGlzLmdldFJlbW90ZVVzZXJJZHMoKS5sZW5ndGggPT09IDAgJiYgKHRoaXMuX3VzZXJJbmZvW2N1cnJlbnRVc2VySWRdLnN0YXRlICE9PSBSQ0NhbGxVc2VyU3RhdGUuS0VFUElORyk7XG4gICAgICAgICAgICBpZiAoaXNOZWVkU2VuZEh1bmd1cCkge1xuICAgICAgICAgICAgICB0aGlzLl9odW5ndXBIYW5kbGUoUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgdGhpcy5fZ2V0VGltZW91dChzZW50VGltZSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8g6YCa55+lIGNhbGwg5bGC5oi/6Ze054q25oCB5Y+Y5pu0XG4gICAgICB0aGlzLl9ub3RpZnlTdGF0ZUNoYW5nZShSQ0NhbGxTZXNzaW9uU3RhdGUuV0FJVElORyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGVuZENvZGUgPSBjb2RlID09PSBSQ0NhbGxFcnJvckNvZGUuUkVKRUNURURfQllfQkxBQ0tMSVNUID8gUkNDYWxsRW5kUmVhc29uLkFEREVEX1RPX0JMQUNLTElTVCA6IFJDQ2FsbEVuZFJlYXNvbi5ORVRXT1JLX0VSUk9SO1xuICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgZW5kQ29kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOaOpeWQrFxuICAgKi9cbiAgYXN5bmMgYWNjZXB0KCk6IFByb21pc2U8eyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUgfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsU3RhdGVNYWNoaW5lXSBhY2NlcHQnKTtcblxuICAgIC8vIOWPkemAgeaOpeWQrOa2iOaBr1xuICAgIGNvbnN0IGN1cnJlbnRVc2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIGNvbnN0IHsgY29kZSwgbWVzc2FnZSB9ID0gYXdhaXQgdGhpcy5fY2FsbE1zZ0hhbmRsZXIuc2VuZEFjY2VwdCh7XG4gICAgICBjaGFubmVsSWQ6IHRoaXMuX2NoYW5uZWxJZCxcbiAgICAgIGNvbnZlcnNhdGlvblR5cGU6IHRoaXMuX2NvbnZlcnNhdGlvblR5cGUsXG4gICAgICB0YXJnZXRJZDogdGhpcy5fdGFyZ2V0SWQsXG4gICAgICBjYWxsSWQ6IHRoaXMuX2NhbGxJZCxcbiAgICAgIG1lZGlhVHlwZTogdGhpcy5fbWVkaWFUeXBlLFxuICAgICAgdXNlcklkczogdGhpcy5nZXRSZW1vdGVVc2VySWRzKCksXG4gICAgfSk7XG5cbiAgICAvLyDmuIXpmaTmjqXlkKzotoXml7borqHml7blmahcbiAgICB0aGlzLl9jbGVhclRpbWVyQnlJZChjdXJyZW50VXNlcklkKTtcbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIGNvbnN0IHsgc2VudFRpbWUgfSA9IG1lc3NhZ2UhO1xuICAgICAgdGhpcy5fdXNlckluZm9bY3VycmVudFVzZXJJZF0gJiYgKHRoaXMuX3VzZXJJbmZvW2N1cnJlbnRVc2VySWRdLnN0YXRlID0gUkNDYWxsVXNlclN0YXRlLktFRVBJTkcpO1xuICAgICAgdGhpcy5fYmVnaW5UaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgLy8g6YCa55+lIGNhbGwg5bGC5Lq65ZGY54q25oCB5Y+Y5pu0XG4gICAgICB0aGlzLl9ub3RpZnlVc2VyU3RhdGVDaGFuZ2UodGhpcy5fdXNlckluZm9bY3VycmVudFVzZXJJZF0pO1xuICAgICAgLy8g5L+u5pS55bm26YCa55+lIGNhbGwg5bGC5oi/6Ze054q25oCB5Y+Y5pu0XG4gICAgICB0aGlzLl9ub3RpZnlTdGF0ZUNoYW5nZShSQ0NhbGxTZXNzaW9uU3RhdGUuS0VFUElORyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3VzZXJJbmZvW2N1cnJlbnRVc2VySWRdICYmICh0aGlzLl91c2VySW5mb1tjdXJyZW50VXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FKTtcbiAgICAgIC8vIOmAmuefpSBjYWxsIOWxguS6uuWRmOeKtuaAgeWPmOabtFxuICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW2N1cnJlbnRVc2VySWRdKTtcbiAgICAgIC8vIOS/ruaUueW5tumAmuefpSBjYWxsIOWxguaIv+mXtOeKtuaAgeWPmOabtFxuICAgICAgY29uc3QgZW5kUmVhc29uID0gY29kZSA9PT0gUkNDYWxsRXJyb3JDb2RlLlJFSkVDVEVEX0JZX0JMQUNLTElTVCA/IFJDQ2FsbEVuZFJlYXNvbi5BRERFRF9UT19CTEFDS0xJU1QgOiBSQ0NhbGxFbmRSZWFzb24uTkVUV09SS19FUlJPUjtcbiAgICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlKFJDQ2FsbFNlc3Npb25TdGF0ZS5FTkQsIGVuZFJlYXNvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOe+pOWRvOWPq+S4ree7p+e7remCgOivt1xuICAgKiBAcGFyYW0gdXNlcklkcyDooqvpgoDor7fnlKjmiLcgSUQg5YiX6KGoXG4gICAqL1xuICBhc3luYyBpbnZpdGUodXNlcklkczogc3RyaW5nW10sIG9wdGlvbnM6IElJbnZpdGVPcHRpb25zID0ge30pOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBpZiAodGhpcy5fY29udmVyc2F0aW9uVHlwZSAhPT0gQ29udmVyc2F0aW9uVHlwZS5HUk9VUCkge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLkNPTlZFUlNBVElPTl9OT1RfR1JPVVBfRVJST1IgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gaW52aXRlIC0+IHVzZXJJZHM6ICR7SlNPTi5zdHJpbmdpZnkodXNlcklkcyl9YCk7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgY29uc3QgZXhpc3RlZFVzZXJJZHMgPSBPYmplY3Qua2V5cyh0aGlzLl91c2VySW5mbyk7XG4gICAgY29uc3QgZXhpc3RlZFVzZXJQb2ZpbGVzOiBJRXhpc3RlZFVzZXJQb2ZpbGVzW10gPSBleGlzdGVkVXNlcklkcy5tYXAoKHVzZXJJZCkgPT4ge1xuICAgICAgbGV0IGNhbGxTdGF0dXMgPSBNc2dDYWxsU3RhdHVzLkNPTk5FQ1RFRDtcbiAgICAgIC8vIOWMheWQq+iiq+mCgOivt+iAhe+8jOaIluiAheeUqOaIt+eKtuaAgeS4uiB3YXRpbmcg5pe277yM54q25oCB5Li6IOWTjemTg1xuICAgICAgaWYgKHVzZXJJZHMuaW5jbHVkZXModXNlcklkKSB8fCB0aGlzLl91c2VySW5mb1t1c2VySWRdLnN0YXRlID09PSBSQ0NhbGxVc2VyU3RhdGUuV0FJVElORykge1xuICAgICAgICBjYWxsU3RhdHVzID0gTXNnQ2FsbFN0YXR1cy5SSU5HSU5HO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBtZWRpYVR5cGU6IHRoaXMuX21lZGlhVHlwZSxcbiAgICAgICAgY2FsbFN0YXR1cyxcbiAgICAgICAgbWVkaWFJZDogdXNlcklkLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgZXh0cmEgPSAnJywgcHVzaENvbmZpZyB9ID0gb3B0aW9ucztcblxuICAgIC8vIOWPkemAgeS6uuWRmOWPmOabtOa2iOaBr1xuICAgIGNvbnN0IHsgY29kZSwgbWVzc2FnZSB9ID0gYXdhaXQgdGhpcy5fY2FsbE1zZ0hhbmRsZXIuc2VuZE1lbWViZXJNb2RpZnkoe1xuICAgICAgY2hhbm5lbElkOiB0aGlzLl9jaGFubmVsSWQsXG4gICAgICBjb252ZXJzYXRpb25UeXBlOiB0aGlzLl9jb252ZXJzYXRpb25UeXBlLFxuICAgICAgdGFyZ2V0SWQ6IHRoaXMuX3RhcmdldElkLFxuICAgICAgY2FsbElkOiB0aGlzLl9jYWxsSWQsXG4gICAgICBleHRyYSxcbiAgICAgIHB1c2hDb25maWcsXG4gICAgICBtZWRpYVR5cGU6IHRoaXMuX21lZGlhVHlwZSxcbiAgICAgIC8vIOmZpOiHquW3se+8jOWFtuS7luaJgOacieS6uuWdh+mcgOaUtuWIsCBtb2RpZnkg5raI5oGv77yM5Lul5q2k5pu05paw54q25oCBXG4gICAgICBpbnZpdGVVc2VySWRzOiB1c2VySWRzLmZpbHRlcigoaWQpID0+IGlkICE9PSBjdXJyZW50VXNlcklkKSxcbiAgICAgIGNhbGxlcklkOiB0aGlzLmdldENhbGxlcklkKCksXG4gICAgICBleGlzdGVkVXNlclBvZmlsZXMsXG4gICAgICBkaXJlY3Rpb25hbFVzZXJJZExpc3Q6IFsuLi5leGlzdGVkVXNlcklkcywgLi4udXNlcklkc10uZmlsdGVyKChpZCkgPT4gaWQgIT09IGN1cnJlbnRVc2VySWQpLFxuICAgIH0pO1xuXG4gICAgaWYgKGNvZGUgPT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICBjb25zdCB7IHNlbnRUaW1lIH0gPSBtZXNzYWdlITtcbiAgICAgIC8vIOS/ruaUueiiq+mCgOivt+S6uueKtuaAge+8jOW5tumAmuefpVxuICAgICAgdXNlcklkcy5mb3JFYWNoKCh1c2VySWQpID0+IHtcbiAgICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSA9IHtcbiAgICAgICAgICB1c2VySWQsXG4gICAgICAgICAgc3RhdGU6IFJDQ2FsbFVzZXJTdGF0ZS5XQUlUSU5HLFxuICAgICAgICAgIGlzQ2FsbGVyOiBmYWxzZSxcbiAgICAgICAgICBpc1JlbW90ZTogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8g6YCa55+lIGNhbGwg5bGC5Lq65ZGY54q25oCB5Y+Y5pu0XG4gICAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1t1c2VySWRdKTtcbiAgICAgICAgLy8g5ZCv5Yqo5ZG85Y+r6K6h5pe25ZmoXG4gICAgICAgIHRoaXMuX3VzZXJUaW1lcnNbdXNlcklkXSA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICAgICAgLy8g5ZG85Y+r6LaF5pe25aSE55CG54q25oCB44CB5bm26YCa55+lIGNhbGwg5bGCXG4gICAgICAgICAgdGhpcy5fdXNlckluZm9bdXNlcklkXSAmJiAodGhpcy5fdXNlckluZm9bdXNlcklkXS5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FKTtcbiAgICAgICAgICAvLyDpgJrnn6UgY2FsbCDlsYLkurrlkZjnirbmgIHlj5jmm7RcbiAgICAgICAgICB0aGlzLl9ub3RpZnlVc2VyU3RhdGVDaGFuZ2UodGhpcy5fdXNlckluZm9bdXNlcklkXSwgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRSk7XG5cbiAgICAgICAgICAvLyDlkbzlj6votoXml7bmnKrmjqXmipvlh7pvbkh1bmd1cFxuICAgICAgICAgIHRoaXMuX3dhdGNoZXJzLm9uSHVuZ3VwKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0sIFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfTk9fUkVTUE9OU0UpO1xuXG4gICAgICAgICAgZGVsZXRlIHRoaXMuX3VzZXJJbmZvW3VzZXJJZF07XG4gICAgICAgICAgLy8g5oi/6Ze05Lq65ZGY5L+h5oGv5bCR5LqO5Lik5Liq77yM6YCa55+l5oi/6Ze054q25oCBXG4gICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuX3VzZXJJbmZvKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aGlzLl9ub3RpZnlTdGF0ZUNoYW5nZShSQ0NhbGxTZXNzaW9uU3RhdGUuRU5ELCBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05PX1JFU1BPTlNFKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMuX2dldFRpbWVvdXQoc2VudFRpbWUpKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDpgJrnn6XkurrlkZjlj5jmm7RcbiAgICAgIHVzZXJJZHMuZm9yRWFjaCgodXNlcklkKSA9PiB7XG4gICAgICAgIHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0gPSB7XG4gICAgICAgICAgdXNlcklkLFxuICAgICAgICAgIHN0YXRlOiBSQ0NhbGxVc2VyU3RhdGUuTk9ORSxcbiAgICAgICAgICBpc0NhbGxlcjogZmFsc2UsXG4gICAgICAgICAgaXNSZW1vdGU6IHRydWUsXG4gICAgICAgIH07XG4gICAgICAgIC8vIOmAmuefpSBjYWxsIOWxguS6uuWRmOeKtuaAgeWPmOabtFxuXG4gICAgICAgIGNvbnN0IGVuZFJlYXNvbiA9IGNvZGUgPT09IFJDQ2FsbEVycm9yQ29kZS5SRUpFQ1RFRF9CWV9CTEFDS0xJU1QgPyBSQ0NhbGxFbmRSZWFzb24uQURERURfVE9fQkxBQ0tMSVNUIDogUkNDYWxsRW5kUmVhc29uLk5FVFdPUktfRVJST1I7XG4gICAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh0aGlzLl91c2VySW5mb1t1c2VySWRdLCBlbmRSZWFzb24pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfaHVuZ3VwSGFuZGxlKHJlYXNvbjogUkNDYWxsRW5kUmVhc29uKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSB9PiB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgLy8g5Y+R6YCB5oyC5pat57G75Z6L5raI5oGvXG4gICAgbGV0IGNvZGUgPSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUztcblxuICAgIGNvbnN0IGhhbmd1cFBhcmFtcyA9IHtcbiAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgY29udmVyc2F0aW9uVHlwZTogdGhpcy5fY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkOiB0aGlzLl90YXJnZXRJZCxcbiAgICAgIGNhbGxJZDogdGhpcy5fY2FsbElkLFxuICAgICAgcmVhc29uLFxuICAgICAgdXNlcklkczogdGhpcy5nZXRSZW1vdGVVc2VySWRzKCksXG4gICAgICBwdXNoQ29uZmlnOiB0aGlzLl9odW5ndXBQdXNoQ29uZmlnLFxuICAgIH07XG5cbiAgICBpZiAocmVhc29uID09PSBSQ0NhbGxFbmRSZWFzb24uT1RIRVJfQ0xJRU5UX0pPSU5FRF9DQUxMKSB7XG4gICAgICAvLyDlt7Hnq6/ooqvlpJrnq6/liqDlhaUgUlRDIOaIv+mXtOaMpOaOieWQju+8jOS4jeWGjeetieWPkeaMguaWrea2iOaBr+eahOe7k+aenO+8jOmYsuatoui1sCB1c2VyTGVhdmUg5a+86Ie05oyC5pat5Y6f5Zug5LiN5YeG56GuXG4gICAgICB0aGlzLl9jYWxsTXNnSGFuZGxlci5zZW5kSHVuZ3VwKGhhbmd1cFBhcmFtcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHsgY29kZTogbXNnQ29kZSB9ID0gYXdhaXQgdGhpcy5fY2FsbE1zZ0hhbmRsZXIuc2VuZEh1bmd1cChoYW5ndXBQYXJhbXMpO1xuICAgICAgY29kZSA9IG1zZ0NvZGU7XG4gICAgfVxuXG4gICAgdGhpcy5fZW5kVGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAvLyDmm7TmlrDpgJror53kurrlkZjnirbmgIHjgIHpgJror53nu5PmnZ/ml7bpl7Qg5bm26YCa55+lXG4gICAgZm9yIChjb25zdCB1c2VySWQgaW4gdGhpcy5fdXNlckluZm8pIHtcbiAgICAgIHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0uc3RhdGUgPSBSQ0NhbGxVc2VyU3RhdGUuTk9ORTtcbiAgICAgIGlmICh1c2VySWQgPT09IGN1cnJlbnRVc2VySWQpIHtcbiAgICAgICAgdGhpcy5fbm90aWZ5VXNlclN0YXRlQ2hhbmdlKHRoaXMuX3VzZXJJbmZvW3VzZXJJZF0sIHJlYXNvbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9ub3RpZnlVc2VyU3RhdGVDaGFuZ2UodGhpcy5fdXNlckluZm9bdXNlcklkXSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgdGhpcy5fdXNlckluZm9bdXNlcklkXTtcbiAgICB9XG5cbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5fdXNlckluZm8pLmxlbmd0aCA8IDIpIHtcbiAgICAgIC8vIOa4heepuuWGheWtmOaAgeaVsOaNru+8jOW5tumAmuefpVxuICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgcmVhc29uKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog5oyC5patXG4gICAqL1xuICBhc3luYyBodW5ndXAoKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSB9PiB7XG4gICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgJ1tSQ0NhbGxTdGF0ZU1hY2hpbmVdIGh1bmd1cCcpO1xuICAgIGNvbnN0IGN1cnJlbnRVc2VySWQgPSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpO1xuICAgIC8vIOm7mOiupOaMguaWrSByZWFzb24g5Li66YCa6K+d6L+H56iL5Lit77yM5bex5pa55q2j5bi45Y+W5raI6YCa6K+dXG4gICAgbGV0IHJlYXNvbiA9IFJDQ2FsbEVuZFJlYXNvbi5IQU5HVVA7XG4gICAgLyoqXG4gICAgICog6Iul6LaF5pe26K6h5pe25Zmo5a2Y5ZyoLCDlt7HmlrnkuLogY2FsbGVyIOWOn+WboOS4uuW3seaWueWPlua2iOmAmuivnSxcbiAgICAgKiDlt7HmlrnkuLogY2FsbGVlIOS4lOacqui/m+WFpemAmuivneS4re+8jOWOn+WboOS4uuW3seaWueaLkue7nemAmuivnVxuICAgICAqL1xuICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl91c2VyVGltZXJzKS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodGhpcy5fdXNlckluZm9bY3VycmVudFVzZXJJZF0uaXNDYWxsZXIpIHtcbiAgICAgICAgcmVhc29uID0gUkNDYWxsRW5kUmVhc29uLkNBTkNFTDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fdXNlckluZm9bY3VycmVudFVzZXJJZF0uc3RhdGUgPT09IFJDQ2FsbFVzZXJTdGF0ZS5XQUlUSU5HKSB7XG4gICAgICAgIHJlYXNvbiA9IFJDQ2FsbEVuZFJlYXNvbi5SRUpFQ1Q7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g5riF6Zmk5omA5pyJ6LaF5pe26K6h5pe25ZmoXG4gICAgZm9yIChjb25zdCB1c2VySWQgaW4gdGhpcy5fdXNlclRpbWVycykge1xuICAgICAgdGhpcy5fY2xlYXJUaW1lckJ5SWQodXNlcklkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2h1bmd1cEhhbmRsZShyZWFzb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIOS/ruaUuemAmuivneWqkuS9k+exu+Wei1xuICAgKiBAcGFyYW0gbWVkaWFUeXBlIFJDQ2FsbE1lZGlhVHlwZS5BVURJTyDmlLnkuLrpn7PpopHpgJror50gfCBSQ0NhbGxNZWRpYVR5cGUuQVVESU9fVklERU8g5pS55Li66Z+z6KeG6aKR6YCa6K+dXG4gICAqL1xuICBhc3luYyBjaGFuZ2VNZWRpYVR5cGUobWVkaWFUeXBlOiBSQ0NhbGxNZWRpYVR5cGUpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gY2hhbmdlTWVkaWFUeXBlIC0+IG1lZGlhVHlwZTogJHttZWRpYVR5cGV9YCk7XG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9jYWxsTXNnSGFuZGxlci5zZW5kTWVkaWFNb2RpZnkoe1xuICAgICAgY2hhbm5lbElkOiB0aGlzLl9jaGFubmVsSWQsXG4gICAgICBjb252ZXJzYXRpb25UeXBlOiB0aGlzLl9jb252ZXJzYXRpb25UeXBlLFxuICAgICAgdGFyZ2V0SWQ6IHRoaXMuX3RhcmdldElkLFxuICAgICAgY2FsbElkOiB0aGlzLl9jYWxsSWQsXG4gICAgICBtZWRpYVR5cGUsXG4gICAgICB1c2VySWRzOiB0aGlzLmdldFJlbW90ZVVzZXJJZHMoKSxcbiAgICB9KTtcbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX21lZGlhVHlwZSA9IG1lZGlhVHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOeUqOaIt+WKoOWFpemAmuivneihpeWBv+acuuWItu+8iHJ0YyB1c2VySm9pbiDkuovku7bop6blj5HvvIlcbiAgICog5Li75Y+r5ZG85Y+r5ZCO77yM5pyq5pS25Yiw6KKr5Y+rIGFjY2VwdCDmtojmga/vvIzkvYbmlLbliLDkuoYgdXNlckpvaW4g5ZCM5qC36KGl5YG/5pu05paw55So5oi344CB5oi/6Ze054q25oCB44CB5ZG85Y+r6K6h5pe25ZmoXG4gICAqL1xuICB1c2VySm9pbih1c2VySWRzOiBzdHJpbmdbXSkge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsIGBbUkNDYWxsU3RhdGVNYWNoaW5lXSB1c2VySm9pbiAtPiB1c2VySWRzOiAke0pTT04uc3RyaW5naWZ5KHVzZXJJZHMpfWApO1xuICAgIC8vIOW7tui/nyAzMDBtcyDpmLLmraIgdXNlckppb24g5ZKMIGFjY2VwdCDmtojmga/pg73mnInnmoTmg4XlhrXkuIvvvIwgdXNlckpvaW4g5q+UIGFjY2VwdCDlhYjliLBcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHVzZXJJZHMuZm9yRWFjaCgodXNlcklkKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXJJbmZvID0gdGhpcy5fdXNlckluZm9bdXNlcklkXTtcbiAgICAgICAgLy8g5pu05paw5Lq65ZGY54q25oCBICgvLyDnvqTnu4TpgJror53ml7bvvJogQeWQkULjgIFD5Y+R6LW36YCa6K+dIELlhYjmjqXlkKzvvIxD5ZCO5o6l5ZCs77yM6L+Z5pe2QuayoeaciUPnmoR1c2VySWTlr7nlupTnmoRfdXNlckluZm/vvIzmiYDku6Xov5nph4zliKTmlq3kuIDkuIspXG4gICAgICAgIGlmICh1c2VySW5mbyAmJiB1c2VySW5mby5zdGF0ZSAhPT0gUkNDYWxsVXNlclN0YXRlLktFRVBJTkcpIHtcbiAgICAgICAgICB1c2VySW5mby5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5LRUVQSU5HO1xuICAgICAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh1c2VySW5mbyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5pu05paw5oi/6Ze054q25oCBXG4gICAgICAgIGlmICh0aGlzLl9zZXNzaW9uU3RhdGUgIT09IFJDQ2FsbFNlc3Npb25TdGF0ZS5LRUVQSU5HKSB7XG4gICAgICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLktFRVBJTkcpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOWBnOatouW5tua4hemZpOWRvOWPq+iuoeaXtuWZqFxuICAgICAgICB0aGlzLl9jbGVhclRpbWVyQnlJZCh1c2VySWQpO1xuICAgICAgfSk7XG4gICAgfSwgMzAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnlKjmiLfnprvlvIDpgJror53ooaXlgb/mnLrliLbvvIhydGMgdXNlckxlYXZl44CBa2lja09mZiDkuovku7bop6blj5HvvIlcbiAgICog6YCa6K+d5Lit6L+c56uv55So5oi35oyC5pat77yM5oyC5pat5raI5oGv5pyq5Yiw77yM5L2G5piv55uR5ZCs5YiwIHJ0YyB1c2VyTGVhdmUg5ZCM5qC36KGl5YG/5pu05paw55So5oi344CB5oi/6Ze054q25oCBXG4gICAqL1xuICB1c2VyTGVhdmUodXNlcklkczogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gdXNlckxlYXZlIC0+IHVzZXJJZHM6ICR7SlNPTi5zdHJpbmdpZnkodXNlcklkcyl9YCk7XG4gICAgLy8g5bu26L+fIDMwMG1zIOmYsuatoiB1c2VyTGVhdmUg5ZKMIGh1bmd1cCDmtojmga/pg73mnInnmoTmg4XlhrXkuIvvvIx1c2VyTGVhdmUg5q+UIGh1bmd1cCDlhYjliLBcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHVzZXJJZHMuZm9yRWFjaCgodXNlcklkKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXJJbmZvID0gdGhpcy5fdXNlckluZm9bdXNlcklkXTtcbiAgICAgICAgLy8g5pu05paw5Lq65ZGY54q25oCBXG4gICAgICAgIGlmICh1c2VySW5mbyAmJiB1c2VySW5mby5zdGF0ZSAhPT0gUkNDYWxsVXNlclN0YXRlLk5PTkUpIHtcbiAgICAgICAgICB1c2VySW5mby5zdGF0ZSA9IFJDQ2FsbFVzZXJTdGF0ZS5OT05FO1xuICAgICAgICAgIHRoaXMuX25vdGlmeVVzZXJTdGF0ZUNoYW5nZSh1c2VySW5mbywgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9IQU5HVVApO1xuICAgICAgICAgIHRoaXMuX3dhdGNoZXJzLm9uSHVuZ3VwKHVzZXJJbmZvLCBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX0hBTkdVUCk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuX3VzZXJJbmZvW3VzZXJJZF07XG4gICAgICAgIH1cbiAgICAgICAgLy8g5Li75Y+r5pa5576k6IGK6YKA6K+36KKr5Y+r5pa55ZCO56a757q/77yM5Li75Y+r5pa55q2k5pe25Li6562J5b6F54q25oCB5ZCO5LiN5YaN5LiK57q/77yM6KKr5Y+r5pa55o6l5ZCs5ZCO5oyC5pat6Iez5Ymp5L2Z5LiA5Lq65pe2562J5b6F5LiA5YiG6ZKf5ZCO5oyC5patXG4gICAgICAgIGNvbnN0IHJlbW90ZVVzZXJzVGltZXIgPSBuZXcgVGltZXIoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlbW90ZVVzZXJzID0gdGhpcy5nZXRSZW1vdGVVc2VycygpO1xuICAgICAgICAgIC8vIOi/nOerr+WPquacieS4gOS4queUqOaIt+S4lOaYr+etieW+heeKtuaAge+8jOetieW+heS4gOWIhumSn+WQjuaMguaWrVxuICAgICAgICAgIGlmIChyZW1vdGVVc2Vycy5sZW5ndGggPT09IDEgJiYgcmVtb3RlVXNlcnNbMF0uc3RhdGUgPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2h1bmd1cEhhbmRsZShSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05FVFdPUktfRVJST1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgNjAwMDApO1xuICAgICAgICAvLyDmm7TmlrDmiL/pl7TnirbmgIFcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuX3VzZXJJbmZvKS5sZW5ndGggPCAyICYmIHRoaXMuX3Nlc3Npb25TdGF0ZSAhPT0gUkNDYWxsU2Vzc2lvblN0YXRlLkVORCkge1xuICAgICAgICAgIHRoaXMuX2VuZFRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2UoUkNDYWxsU2Vzc2lvblN0YXRlLkVORCwgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9IQU5HVVApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9LCAzMDApO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGwg5bGC5bex5pa55byC5bi45aSx6LSl5ZCO6LCD55So55qE5pa55rOVXG4gICAqIOinpuWPkeaXtuacuu+8mumfs+inhumikeacjeWKoeW8guW4uOOAgeiOt+WPlui1hOa6kOWksei0peOAgeWKoOWFpSBSVEMg5oi/6Ze05aSx6LSl44CB5Y+R5biDfOiuoumYheWksei0pVxuICAgKi9cbiAgY2xvc2UocmVhc29uOiBSQ0NhbGxFbmRSZWFzb24pIHtcbiAgICB0aGlzLl9odW5ndXBIYW5kbGUocmVhc29uKTtcbiAgfVxuXG4gIHNldEh1bmd1cFB1c2hDb25maWcocHVzaENvbmZpZzogSVB1c2hDb25maWcpIHtcbiAgICB0aGlzLl9odW5ndXBQdXNoQ29uZmlnID0gcHVzaENvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53llK/kuIDmoIfor4ZcbiAgICovXG4gIGdldENhbGxJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9jYWxsSWQ7XG4gIH1cblxuICAvKipcbiAgICog5aSa57uE57uHIElEXG4gICAqL1xuICBnZXRDaGFubmVsSWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY2hhbm5lbElkO1xuICB9XG5cbiAgLyoqXG4gICAqIOebruaghyBJRO+8jOWNleWRvOWvueaWueS6uuWRmCBJZCwg576k5ZG8576k57uEIElkXG4gICAqL1xuICBnZXRUYXJnZXRJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXRJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bkvJror53nsbvlnotcbiAgICovXG4gIGdldENvbnZlcnNhdGlvblR5cGUoKTogQ29udmVyc2F0aW9uVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnZlcnNhdGlvblR5cGU7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W6L+c56uv5oiQ5ZGYIElEIOWIl+ihqFxuICAgKi9cbiAgZ2V0UmVtb3RlVXNlcklkcygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgYWxsVXNlcklkcyA9IE9iamVjdC5rZXlzKHRoaXMuX3VzZXJJbmZvKTtcbiAgICBjb25zdCByZW1vdGVVc2VySWRzID0gYWxsVXNlcklkcy5maWx0ZXIoKGlkKSA9PiB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpICE9PSBpZCk7XG4gICAgcmV0dXJuIHJlbW90ZVVzZXJJZHM7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W6L+c56uv5oiQ5ZGY5L+h5oGv5YiX6KGoXG4gICAqL1xuICBnZXRSZW1vdGVVc2VycygpOiBJVXNlckRhdGFbXSB7XG4gICAgY29uc3QgcmVtb3RlVXNlcjogSVVzZXJEYXRhW10gPSBbXTtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBmb3IgKGNvbnN0IHVpZCBpbiB0aGlzLl91c2VySW5mbykge1xuICAgICAgY29uc3QgeyB1c2VySWQgfSA9IHRoaXMuX3VzZXJJbmZvW3VpZF07XG4gICAgICBpZiAodXNlcklkICE9PSBjdXJyZW50VXNlcklkKSB7XG4gICAgICAgIHJlbW90ZVVzZXIucHVzaCh0aGlzLl91c2VySW5mb1t1aWRdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlbW90ZVVzZXI7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5oi/6Ze054q25oCBXG4gICAqL1xuICBnZXRTdGF0ZSgpOiBSQ0NhbGxTZXNzaW9uU3RhdGUge1xuICAgIHJldHVybiB0aGlzLl9zZXNzaW9uU3RhdGUgPT09IG51bGwgPyBSQ0NhbGxTZXNzaW9uU3RhdGUuRU5EIDogdGhpcy5fc2Vzc2lvblN0YXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluS6uuWRmOeKtuaAgVxuICAgKi9cbiAgZ2V0VXNlclN0YXRlKHVzZXJJZDogc3RyaW5nKTogUkNDYWxsVXNlclN0YXRlIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlckluZm9bdXNlcklkXT8uc3RhdGU7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5Lya6K+d5Y+R6LW36ICFIElkXG4gICAqL1xuICBnZXRDYWxsZXJJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9jYWxsZXJJZCE7XG4gIH1cblxuICAvKipcbiAgICog6I635Y+W5b2T5qyh5Lya6K+d6YKA6K+36ICFIElkXG4gICAqL1xuICBnZXRJbnZpdGVySWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5faW52aXRlcklkITtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5blvZPliY3pgJror53lqpLkvZPnsbvlnotcbiAgICovXG4gIGdldE1lZGlhVHlwZSgpOiBSQ0NhbGxNZWRpYVR5cGUge1xuICAgIHJldHVybiB0aGlzLl9tZWRpYVR5cGU7XG4gIH1cblxuICAvKipcbiAgICog6YCa6K+d5oyC5pat5ZCO5Y+v6LCD55SoXG4gICAqL1xuICBnZXRTdW1tYXJ5KCk6IElFbmRTdW1tYXJ5IHtcbiAgICAvLyDpgJror53ml7bpl7TorqHnrpdcbiAgICBjb25zdCBiZWdpblRpbWVzdGFtcCA9IHRoaXMuX2JlZ2luVGltZXN0YW1wO1xuICAgIGNvbnN0IGVuZFRpbWVzdGFtcCA9IHRoaXMuX2VuZFRpbWVzdGFtcDtcbiAgICBsZXQgZHVyYXRpb24gPSAwO1xuICAgIGlmIChlbmRUaW1lc3RhbXAgPiBiZWdpblRpbWVzdGFtcCAmJiBiZWdpblRpbWVzdGFtcCAhPT0gMCkge1xuICAgICAgZHVyYXRpb24gPSBlbmRUaW1lc3RhbXAgLSBiZWdpblRpbWVzdGFtcDtcbiAgICB9XG5cbiAgICBjb25zdCBzdW1tYXJ5ID0ge1xuICAgICAgY29udmVyc2F0aW9uVHlwZTogdGhpcy5fY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIGNoYW5uZWxJZDogdGhpcy5fY2hhbm5lbElkLFxuICAgICAgdGFyZ2V0SWQ6IHRoaXMuX3RhcmdldElkLFxuICAgICAgbWVkaWFUeXBlOiB0aGlzLl9tZWRpYVR5cGUsXG4gICAgICBiZWdpblRpbWVzdGFtcCxcbiAgICAgIGVuZFRpbWVzdGFtcCxcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgZW5kUmVhc29uOiB0aGlzLl9lbmRSZWFzb24hLFxuICAgIH07XG5cbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbFN0YXRlTWFjaGluZV0gZ2V0U3VtbWFyeSAtPiBzdW1tYXJ5OiAke0pTT04uc3RyaW5naWZ5KHN1bW1hcnkpfWApO1xuICAgIHJldHVybiBzdW1tYXJ5O1xuICB9XG59XG4iLCIvKipcbiAqIOmAmuivneWqkuS9k+exu+Wei1xuICovXG5leHBvcnQgZW51bSBSQ0NhbGxNZWRpYVR5cGUge1xuICAvKipcbiAgICog6Z+z6aKR6YCa6K+dXG4gICAqL1xuICBBVURJTyA9IDEsXG4gIC8qKlxuICAgKiDop4bpopHpgJror51cbiAgICovXG4gIEFVRElPX1ZJREVPXG59XG4iLCJleHBvcnQgZW51bSBNZW1iZXJNb2RpZnlUeXBlIHtcbiAgQUREID0gMSxcbiAgUkVNT1ZFXG59XG4iLCIvKipcbiAqIOW5s+WPsFxuICovXG5leHBvcnQgZW51bSBQbGF0Zm9ybSB7XG4gIFdFQiA9ICdXZWInLFxuICBJT1MgPSAnaU9TJyxcbiAgQU5EUk9JRCA9ICdBbmRyb2lkJ1xufVxuIiwiaW1wb3J0IHtcbiAgQ29udmVyc2F0aW9uVHlwZSwgSUxvZ2dlciwgSVJlY2VpdmVkTWVzc2FnZSwgUlRDUGx1Z2luQ29udGV4dCxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHsgQ2FsbFJlbW90ZUVuZFJlYXNvbiwgUkNDYWxsRW5kUmVhc29uIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxFbmRSZWFzb24nO1xuaW1wb3J0IHsgUkNDYWxsTWVkaWFUeXBlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxNZWRpYVR5cGUnO1xuaW1wb3J0IHsgUkNDYWxsTWVzc2FnZVR5cGUgfSBmcm9tICcuL2VudW1zL1JDQ2FsbE1lc3NhZ2VUeXBlJztcbmltcG9ydCB7IElIdW5ndXBNc2dDb250ZW50LCBJSW52aXRlTXNnQ29udGVudCwgSU1lZGlhTW9kaWZ5TXNnQ29udGVudCB9IGZyb20gJy4vaW50ZXJmYWNlcy9JTWVzc2FnZUhhbmRsZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIElPZmZsaW5lUmVjb3JkIHtcbiAgY2hhbm5lbElkOiBzdHJpbmcsXG4gIGNvbnZlcnNhdGlvblR5cGU6IENvbnZlcnNhdGlvblR5cGUsXG4gIHRhcmdldElkOiBzdHJpbmcsXG4gIG1lZGlhVHlwZTogUkNDYWxsTWVkaWFUeXBlLFxuICBjYWxsSWQ6IHN0cmluZyxcbiAgaW52aXRlcklkOiBzdHJpbmcsXG4gIGVuZFJlYXNvbjogUkNDYWxsRW5kUmVhc29uLFxuICBiZWdpblRpbWVzdGFtcDogbnVtYmVyLFxuICBlbmRUaW1lc3RhbXA6IG51bWJlcixcbiAgZHVyYXRpb246IG51bWJlclxufVxuXG4vKipcbiAqIOemu+e6v+mAmuivneiusOW9leWZqFxuICovXG5leHBvcnQgY2xhc3MgT2ZmbGluZVJlY29yZGVyIHtcbiAgcHJpdmF0ZSBfbWVzc2FnZXM6IElSZWNlaXZlZE1lc3NhZ2VbXSB8IFtdID0gW11cblxuICBwcml2YXRlIF9jaGFubmVsSWQhOiBzdHJpbmdcblxuICBwcml2YXRlIF9jb252ZXJzYXRpb25UeXBlITogQ29udmVyc2F0aW9uVHlwZVxuXG4gIHByaXZhdGUgX3RhcmdldElkITogc3RyaW5nXG5cbiAgcHJpdmF0ZSBfbWVkaWFUeXBlITogUkNDYWxsTWVkaWFUeXBlXG5cbiAgcHJpdmF0ZSBfY2FsbElkITogc3RyaW5nXG5cbiAgcHJpdmF0ZSBfY2FsbGVySWQhOiBzdHJpbmdcblxuICBwcml2YXRlIF9pbnZpdGVySWQhOiBzdHJpbmdcblxuICBwcml2YXRlIF9lbmRSZWFzb24hOiBSQ0NhbGxFbmRSZWFzb25cblxuICBwcml2YXRlIF9iZWdpblRpbWVzdGFtcDogbnVtYmVyID0gMFxuXG4gIHByaXZhdGUgX2VuZFRpbWVzdGFtcDogbnVtYmVyID0gMFxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRleHQ6IFJUQ1BsdWdpbkNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBJTG9nZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX29uUmVjb3JkOiAocmVjb3JkOiBJT2ZmbGluZVJlY29yZCkgPT4gdm9pZCxcbiAgKSB7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiDliLAgaW52aXRlIHwgbWVtYmVyTW9kaWZ5IOe7k+adn1xuICAgKiDljp/lm6DmoLnmja7lt7HmlrnmmK/lkKbkuLrkuLvlj6vvvIzkuLvlj6vkuLrov5znq6/mnKrmjqXlkKwg6KKr5Y+r6KKr5bex56uv5pyq5o6l5ZCsXG4gICAqL1xuICBwcml2YXRlIF9kb0ludml0ZShtZXNzYWdlOiBJUmVjZWl2ZWRNZXNzYWdlKSB7XG4gICAgY29uc3QgY3VycmVudFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgY29uc3Qge1xuICAgICAgY2hhbm5lbElkLCBjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgc2VuZGVyVXNlcklkLCBjb250ZW50LFxuICAgIH0gPSBtZXNzYWdlO1xuICAgIGNvbnN0IHsgY2FsbElkLCBtZWRpYVR5cGUgfSA9IGNvbnRlbnQgYXMgSUludml0ZU1zZ0NvbnRlbnQ7XG4gICAgdGhpcy5fY2hhbm5lbElkID0gY2hhbm5lbElkITtcbiAgICB0aGlzLl9jb252ZXJzYXRpb25UeXBlID0gY29udmVyc2F0aW9uVHlwZTtcbiAgICB0aGlzLl90YXJnZXRJZCA9IHRhcmdldElkO1xuICAgIHRoaXMuX2NhbGxJZCA9IGNhbGxJZDtcbiAgICB0aGlzLl9tZWRpYVR5cGUgPSBtZWRpYVR5cGU7XG4gICAgY29uc3QgaXNDYWxsZXIgPSBzZW5kZXJVc2VySWQgPT09IGN1cnJlbnRVc2VySWQ7XG4gICAgdGhpcy5faW52aXRlcklkID0gc2VuZGVyVXNlcklkO1xuICAgIHRoaXMuX2VuZFJlYXNvbiA9IGlzQ2FsbGVyID8gUkNDYWxsRW5kUmVhc29uLlJFTU9URV9OT19SRVNQT05TRSA6IFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfTk9fUkVTUE9OU0U7XG4gICAgdGhpcy5fY2FuR2VuUmVjb3JkKCk7XG4gIH1cblxuICAvKipcbiAgICog5YiwIGludml0ZSB8IG1lbWJlck1vZGlmeSDnu5PmnZ9cbiAgICog5Y6f5Zug5qC55o2u5bex5pa55piv5ZCm5Li65Li75Y+r77yM5Li75Y+r5Li66L+c56uv5pyq5o6l5ZCsIOiiq+WPq+iiq+W3seerr+acquaOpeWQrFxuICAgKi9cbiAgcHJpdmF0ZSBfZG9NZW1iZXJNb2RpZnkobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIHRoaXMuX2RvSW52aXRlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIOeUqCBpbnZpdGUgfCBtZW1iZXJNb2RpZnkg6K6h566X55qE56a757q/6K6w5b2VXG4gICAqL1xuICBwcml2YXRlIF9kb1JpbmdpbmcobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIHRoaXMuX2NhbkdlblJlY29yZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIsCBhY2NlcHQg6K+05piO6YCa6K+d5bey5bu656uLXG4gICAqIOWOn+WboOm7mOiupOW3seaWueato+W4uOaMguaWrVxuICAgKi9cbiAgcHJpdmF0ZSBfZG9BY2NlcHQobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIHRoaXMuX2VuZFJlYXNvbiA9IFJDQ2FsbEVuZFJlYXNvbi5IQU5HVVA7XG4gICAgdGhpcy5fYmVnaW5UaW1lc3RhbXAgPSBtZXNzYWdlLnNlbnRUaW1lO1xuICAgIHRoaXMuX2NhbkdlblJlY29yZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWIsCBodW5ndXAg6K+05piO5Li65q2j5bi45oyC5patXG4gICAqIOWOn+WboOWPlua2iOaBr+S9k+mHjOaMguaWreWOn+WboFxuICAgKi9cbiAgcHJpdmF0ZSBfZG9IdW5ndXAobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIGNvbnN0IHsgY29udGVudCwgc2VudFRpbWUsIHNlbmRlclVzZXJJZCB9ID0gbWVzc2FnZTtcbiAgICBjb25zdCB7IHJlYXNvbiB9ID0gY29udGVudCBhcyBJSHVuZ3VwTXNnQ29udGVudDtcbiAgICBjb25zdCBjdXJyZW50VXNlcklkID0gdGhpcy5fY29udGV4dC5nZXRDdXJyZW50SWQoKTtcbiAgICBjb25zdCBpc1NlbGZTZW5kID0gc2VuZGVyVXNlcklkID09PSBjdXJyZW50VXNlcklkO1xuICAgIHRoaXMuX2VuZFJlYXNvbiA9IGlzU2VsZlNlbmQgPyByZWFzb24gOiBDYWxsUmVtb3RlRW5kUmVhc29uW3JlYXNvbl07XG4gICAgdGhpcy5fZW5kVGltZXN0YW1wID0gc2VudFRpbWU7XG5cbiAgICB0aGlzLl9jYW5HZW5SZWNvcmQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlj6rkv67mlLnpgJror53nsbvlnotcbiAgICovXG4gIHByaXZhdGUgX2RvTWVkaWFNb2RpZnkobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIGNvbnN0IHsgY29udGVudCB9ID0gbWVzc2FnZTtcbiAgICBjb25zdCB7IG1lZGlhVHlwZSB9ID0gY29udGVudCBhcyBJTWVkaWFNb2RpZnlNc2dDb250ZW50O1xuICAgIHRoaXMuX21lZGlhVHlwZSA9IG1lZGlhVHlwZTtcbiAgICB0aGlzLl9jYW5HZW5SZWNvcmQoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhbkdlblJlY29yZCgpIHtcbiAgICBpZiAodGhpcy5fbWVzc2FnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBsZXQgZHVyYXRpb24gPSAwO1xuICAgICAgY29uc3QgaXNOZWVkRHVyYXRpb25SZWFzb24gPSBbXG4gICAgICAgIFJDQ2FsbEVuZFJlYXNvbi5IQU5HVVAsXG4gICAgICAgIFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfSEFOR1VQLFxuICAgICAgICBSQ0NhbGxFbmRSZWFzb24uT1RIRVJfQ0xJRU5UX0pPSU5FRF9DQUxMLFxuICAgICAgICBSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX09USEVSX0NMSUVOVF9KT0lORURfQ0FMTCxcbiAgICAgICAgUkNDYWxsRW5kUmVhc29uLktJQ0tFRF9CWV9TRVJWRVIsXG4gICAgICAgIFJDQ2FsbEVuZFJlYXNvbi5SRU1PVEVfS0lDS0VEX0JZX1NFUlZFUixcbiAgICAgICAgUkNDYWxsRW5kUmVhc29uLkFDQ0VQVF9TWVNURU1fQ0FMTCxcbiAgICAgICAgUkNDYWxsRW5kUmVhc29uLlJFTU9URV9BQ0NFUFRfU1lTVEVNX0NBTEwsXG4gICAgICBdLmluY2x1ZGVzKHRoaXMuX2VuZFJlYXNvbik7XG4gICAgICBpZiAoaXNOZWVkRHVyYXRpb25SZWFzb24pIHtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLl9lbmRUaW1lc3RhbXAgLSB0aGlzLl9iZWdpblRpbWVzdGFtcDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX29uUmVjb3JkKHtcbiAgICAgICAgY2hhbm5lbElkOiB0aGlzLl9jaGFubmVsSWQsXG4gICAgICAgIGNvbnZlcnNhdGlvblR5cGU6IHRoaXMuX2NvbnZlcnNhdGlvblR5cGUsXG4gICAgICAgIHRhcmdldElkOiB0aGlzLl90YXJnZXRJZCxcbiAgICAgICAgY2FsbElkOiB0aGlzLl9jYWxsSWQsXG4gICAgICAgIGludml0ZXJJZDogdGhpcy5faW52aXRlcklkLFxuICAgICAgICBtZWRpYVR5cGU6IHRoaXMuX21lZGlhVHlwZSxcbiAgICAgICAgZW5kUmVhc29uOiB0aGlzLl9lbmRSZWFzb24sXG4gICAgICAgIGJlZ2luVGltZXN0YW1wOiB0aGlzLl9iZWdpblRpbWVzdGFtcCxcbiAgICAgICAgZW5kVGltZXN0YW1wOiB0aGlzLl9lbmRUaW1lc3RhbXAsXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgb25SZWN2T2ZmbGluZU1zZ3MobWVzc2FnZXM6IElSZWNlaXZlZE1lc3NhZ2VbXSkge1xuICAgIHRoaXMuX21lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgZG8ge1xuICAgICAgY29uc3QgbXNnID0gdGhpcy5fbWVzc2FnZXMuc2hpZnQoKSE7XG4gICAgICBjb25zdCB7IG1lc3NhZ2VUeXBlLCBjb250ZW50OiB7IGNhbGxJZCB9IH0gPSBtc2c7XG4gICAgICBzd2l0Y2ggKG1lc3NhZ2VUeXBlKSB7XG4gICAgICAgIGNhc2UgUkNDYWxsTWVzc2FnZVR5cGUuVkNJbnZpdGU6XG4gICAgICAgICAgdGhpcy5fZG9JbnZpdGUobXNnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ1Jpbmdpbmc6XG4gICAgICAgICAgdGhpcy5fZG9SaW5naW5nKG1zZyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgUkNDYWxsTWVzc2FnZVR5cGUuVkNBY2NlcHQ6XG4gICAgICAgICAgdGhpcy5fZG9BY2NlcHQobXNnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ01vZGlmeU1lbTpcbiAgICAgICAgICB0aGlzLl9kb01lbWJlck1vZGlmeShtc2cpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFJDQ2FsbE1lc3NhZ2VUeXBlLlZDTW9kaWZ5TWVkaWE6XG4gICAgICAgICAgdGhpcy5fZG9NZWRpYU1vZGlmeShtc2cpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFJDQ2FsbE1lc3NhZ2VUeXBlLlZDSGFuZ3VwOlxuICAgICAgICAgIHRoaXMuX2RvSHVuZ3VwKG1zZyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgYFtPZmZsaW5lUmVjb3JkZXJdIG9uUmVjdk9mZmxpbmVNc2dzIC0+IHVuZXhwZWN0ZWQgbWVzc2FnZTogJHtKU09OLnN0cmluZ2lmeShtc2cpfWApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKHRoaXMuX21lc3NhZ2VzLmxlbmd0aCA+IDApO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBDb252ZXJzYXRpb25UeXBlLCBFcnJvckNvZGUsIEV2ZW50RW1pdHRlciwgSUxvZ2dlciwgSVB1c2hDb25maWcgYXMgSUVuZ2luZVB1c2hDb25maWcsIElSZWNlaXZlZE1lc3NhZ2UsIElSdW50aW1lLCBJU2VuZE1zZ09wdGlvbnMsIFJUQ1BsdWdpbkNvbnRleHQsXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IE1lbWJlck1vZGlmeVR5cGUgfSBmcm9tICcuL2VudW1zL01lbWJlck1vZGlmeVR5cGUnO1xuaW1wb3J0IHsgUkNDYWxsRXJyb3JDb2RlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxDb2RlJztcbmltcG9ydCB7IFJDQ2FsbE1lc3NhZ2VUeXBlIH0gZnJvbSAnLi9lbnVtcy9SQ0NhbGxNZXNzYWdlVHlwZSc7XG5pbXBvcnQgeyBJVXNlclByb2ZpbGUgfSBmcm9tICcuL2ludGVyZmFjZXMvSVN0YXRlTWFjaGluZSc7XG5pbXBvcnQge1xuICBJQWNjZXB0TXNnQ29udGVudCwgSUFjY2VwdE1zZ09wdGlvbnMsIElDYWxsTXNnT3B0aW9uLCBJSHVuZ3VwTXNnQ29udGVudCwgSUh1bmd1cE1zZ09wdGlvbnMsXG4gIElJbnZpdGVNc2dDb250ZW50LCBJSW52aXRlTXNnT3B0aW9ucywgSU1lZGlhTW9kaWZ5TXNnQ29udGVudCwgSU1lZGlhTW9kaWZ5TXNnT3B0aW9ucywgSU1lbWJlck1vZGlmeU1zZ0NvbnRlbnQsXG4gIElNZW1iZXJNb2RpZnlNc2dPcHRpb25zLCBJTXNnTGlzdGVuZXIsIElSaW5naW5nTXNnQ29udGVudCwgSVJpbmdpbmdNc2dPcHRpb25zLFxufSBmcm9tICcuL2ludGVyZmFjZXMvSU1lc3NhZ2VIYW5kbGVyJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnLi9lbnVtcy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBnZXRDYWxsRGV2aWNlSWQgfSBmcm9tICcuLi9oZWxwZXInO1xuaW1wb3J0IHsgSU9mZmxpbmVSZWNvcmQsIE9mZmxpbmVSZWNvcmRlciB9IGZyb20gJy4vT2ZmbGluZVJlY29yZGVyJztcbmltcG9ydCB7IFJDQ2FsbFN0YXRlTWFjaGluZSB9IGZyb20gJy4uJztcblxuY29uc3QgY2FsbE1zZ1R5cGVzID0gWydSQzpWQ0FjY2VwdCcsICdSQzpWQ1JpbmdpbmcnLCAnUkM6VkNTdW1tYXJ5JywgJ1JDOlZDSGFuZ3VwJywgJ1JDOlZDSW52aXRlJywgJ1JDOlZDTW9kaWZ5TWVkaWEnLCAnUkM6VkNNb2RpZnlNZW0nXTtcblxudHlwZSBNc2dMaXN0ZW5lcktleXMgPSBrZXlvZiBJTXNnTGlzdGVuZXJcblxuaW50ZXJmYWNlIElNc2dCdWZmZXJJdGVtIHtcbiAgbWFya1RpbWU6IG51bWJlcixcbiAgbXNnOiBJUmVjZWl2ZWRNZXNzYWdlXG59XG5cbmNvbnN0IEVuZ2luZUVycm9yQ29kZVRvQ2FsbEVycm9yQ29kZTogeyBba2V5OiBudW1iZXJdOiBSQ0NhbGxFcnJvckNvZGUgfSA9IHtcbiAgW0Vycm9yQ29kZS5SRUpFQ1RFRF9CWV9CTEFDS0xJU1RdOiBSQ0NhbGxFcnJvckNvZGUuUkVKRUNURURfQllfQkxBQ0tMSVNULFxuICBbRXJyb3JDb2RlLk5PVF9JTl9HUk9VUF06IFJDQ2FsbEVycm9yQ29kZS5OT1RfSU5fR1JPVVAsXG59O1xuXG4vKipcbiAqIOa2iOaBr+aOpeaUtuWkhOeQhjog5Zyo57q/5raI5oGv44CB56a757q/5raI5oGvXG4gKiDlj5HpgIHmtojmga/lpITnkIY6IOWPkemAgeS4jeWQjOexu+Wei+a2iOaBr+WwgeijhVxuICovXG5leHBvcnQgY2xhc3MgQ2FsbE1lc3NhZ2VIYW5kbGVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgcHJpdmF0ZSBfd2F0Y2hlcnM6IElNc2dMaXN0ZW5lciA9IHt9XG5cbiAgcHJpdmF0ZSBfdXNlckluZm86IElVc2VyUHJvZmlsZSA9IHt9XG5cbiAgcHJpdmF0ZSBfbXNnQnVmZmVyTGlzdDogSU1zZ0J1ZmZlckl0ZW1bXSA9IFtdXG5cbiAgcHJpdmF0ZSBfaGFkSGFuZGxlTXNnVGltZXI6IGJvb2xlYW4gPSBmYWxzZVxuXG4gIHByaXZhdGUgX29mZmxpbmVSZWNvcmRlciE6IE9mZmxpbmVSZWNvcmRlclxuXG4gIHByaXZhdGUgX2RldmljZUlkOiBzdHJpbmcgPSAnJ1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRleHQ6IFJUQ1BsdWdpbkNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcnVudGltZTogSVJ1bnRpbWUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBJTG9nZ2VyLFxuICAgIC8qKlxuICAgICAqIOemu+e6v+a2iOaBr+WkhOeQhuaXtumXtOmXtOmalFxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX29mZmxpbmVNc2dJdHY6IG51bWJlciA9IDYwICogMTAwMCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9nZXRTdGF0ZU1hY2hpbmU6IChjYWxsSWQ6IHN0cmluZykgPT4gUkNDYWxsU3RhdGVNYWNoaW5lIHwgbnVsbCxcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICAvLyBkZXZpY2VJZFxuICAgIHRoaXMuX2RldmljZUlkID0gZ2V0Q2FsbERldmljZUlkKF9ydW50aW1lKTtcbiAgICAvLyDlpITnkIbmtojmga/mlLblj5FcbiAgICB0aGlzLl9jb250ZXh0Lm9ubWVzc2FnZSA9IHRoaXMuX29uTWVzc2FnZS5iaW5kKHRoaXMpO1xuICAgIC8vIOWkhOeQhuemu+e6v+a2iOaBr+iusOW9lVxuICAgIHRoaXMuX29mZmxpbmVSZWNvcmRlciA9IG5ldyBPZmZsaW5lUmVjb3JkZXIodGhpcy5fY29udGV4dCwgdGhpcy5fbG9nZ2VyLCAocmVjb3JkOiBJT2ZmbGluZVJlY29yZCkgPT4ge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW0NhbGxNZXNzYWdlSGFuZGxlcl0gb2ZmbGluZVJlY29yZGVyIC0+ICR7SlNPTi5zdHJpbmdpZnkocmVjb3JkKX1gKTtcbiAgICAgIHRoaXMuX3dhdGNoZXJzLm9uT2ZmbGluZVJlY29yZCAmJiB0aGlzLl93YXRjaGVycy5vbk9mZmxpbmVSZWNvcmQocmVjb3JkKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX29uTWVzc2FnZShtZXNzYWdlOiBJUmVjZWl2ZWRNZXNzYWdlKSB7XG4gICAgY29uc3QgaXNDYWxsTXNnID0gY2FsbE1zZ1R5cGVzLmluY2x1ZGVzKG1lc3NhZ2UubWVzc2FnZVR5cGUpO1xuICAgIGlmIChpc0NhbGxNc2cpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsIGBbQ2FsbE1lc3NhZ2VIYW5kbGVyXSBfb25NZXNzYWdlIC0+IGNhbGwgbWVzc2FnZTogJHtKU09OLnN0cmluZ2lmeShtZXNzYWdlKX1gKTtcbiAgICAgIC8vIOmAmui/h+mBjeWOhiBidWZmZXJMaXN0IOafpeaJvuimgeaPkuWFpeeahOiKgueCuVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbWFya1RpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICBjb25zdCB7IHNlbnRUaW1lOiBjdXJyZW50TXNnU2VudFRpbWUgfSA9IG1lc3NhZ2U7XG4gICAgICAgIGxldCBpbnNlcnRJbmRleCA9IDA7XG4gICAgICAgIC8vIOmcgOmBjeWOhuaVsOe7hOWFqOmDqOmhue+8jOaVheS9v+eUqCBmb3JFYWNoLCBmaW5kSW5kZXgg5om+5Yiw56ys5LiA5Liq56ym5ZCI5p2h5Lu255qE5bCx5Lya57uI5q2iXG4gICAgICAgIHRoaXMuX21zZ0J1ZmZlckxpc3QuZm9yRWFjaCgoeyBtc2c6IHsgc2VudFRpbWUgfSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgIGlmIChjdXJyZW50TXNnU2VudFRpbWUgPj0gc2VudFRpbWUpIHtcbiAgICAgICAgICAgIC8vIGluc2VydEluZGV4IOmcgOS4uuW9k+WJjeespuWQiOadoeS7tuWFg+e0oOeahOWQjuS4gOS9je+8jOaVhSArMVxuICAgICAgICAgICAgaW5zZXJ0SW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbXNnQnVmZmVyTGlzdC5zcGxpY2UoaW5zZXJ0SW5kZXgsIDAsIHtcbiAgICAgICAgICBtYXJrVGltZSxcbiAgICAgICAgICBtc2c6IG1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBvbk1lc3NhZ2UgLT4gbXNnQnVmZmVyTGlzdDogJHt0aGlzLl9tc2dCdWZmZXJMaXN0Lmxlbmd0aH1gKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbQ2FsbE1lc3NhZ2VIYW5kbGVyXSBzcGxpY2UgYnVmZmVyIG1zZyBlcnJvciAtPiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIOWQr+WKqOa2iOaBr+WkhOeQhlxuICAgICAgdGhpcy5faGFuZGxlQnVmZmVyTXNncygpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlnKjnur/mtojmga/mipvnu5nnirbmgIHmnLrlpITnkIZcbiAgICovXG4gIHByaXZhdGUgX29uUmVjdk9ubGluZUNhbGxNc2cobWVzc2FnZTogSVJlY2VpdmVkTWVzc2FnZSkge1xuICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYG9uTWVzc2FnZSAtPiBfb25SZWN2T25saW5lQ2FsbE1zZzogJHttZXNzYWdlLm1lc3NhZ2VUeXBlfWApO1xuICAgIGNvbnN0IHsgY29udGVudDogeyBjYWxsSWQgfSB9ID0gbWVzc2FnZTtcbiAgICAvLyDlnKjnur/mtojmga/nm7TmjqXmipvlh7pcbiAgICBzd2l0Y2ggKG1lc3NhZ2UubWVzc2FnZVR5cGUpIHtcbiAgICAgIGNhc2UgUkNDYWxsTWVzc2FnZVR5cGUuVkNJbnZpdGU6XG4gICAgICAgIHRoaXMuX3dhdGNoZXJzLm9uSW52aXRlICYmIHRoaXMuX3dhdGNoZXJzLm9uSW52aXRlKG1lc3NhZ2UpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUkNDYWxsTWVzc2FnZVR5cGUuVkNSaW5naW5nOlxuICAgICAgICBzdXBlci5lbWl0KGAke2NhbGxJZH1vblJpbmdpbmdgLCBtZXNzYWdlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFJDQ2FsbE1lc3NhZ2VUeXBlLlZDQWNjZXB0OlxuICAgICAgICBzdXBlci5lbWl0KGAke2NhbGxJZH1vbkFjY2VwdGAsIG1lc3NhZ2UpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUkNDYWxsTWVzc2FnZVR5cGUuVkNNb2RpZnlNZW06XG4gICAgICAgIC8vIOaUtuWIsOS6uuWRmOWPmOabtOaKm+WHuiBvbkludml0ZSDnlJ/miJDnirbmgIHmnLrlrp7kvotcbiAgICAgICAgdGhpcy5fd2F0Y2hlcnMub25JbnZpdGUgJiYgdGhpcy5fd2F0Y2hlcnMub25JbnZpdGUobWVzc2FnZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ01vZGlmeU1lZGlhOlxuICAgICAgICBzdXBlci5lbWl0KGAke2NhbGxJZH1vbk1lZGlhTW9kaWZ5YCwgbWVzc2FnZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ0hhbmd1cDpcbiAgICAgICAgc3VwZXIuZW1pdChgJHtjYWxsSWR9b25IdW5ndXBgLCBtZXNzYWdlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBbQ2FsbE1lc3NhZ2VIYW5kbGVyXSBvblJlY3ZPbmxpbmVDYWxsTXNnIC0+IHVuZXhwZWN0ZWQgbWVzc2FnZTogJHtKU09OLnN0cmluZ2lmeShtZXNzYWdlKX1gKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOa2iOaBryBidWZmZXIg5YiX6KGo5aSE55CG6YC76L6RXG4gICAqIDHjgIHmr48gMjBtcyDmo4Dmn6XkuIDmrKEgYnVmZmVyIGxpc3RcbiAgICogMuOAgeWPluWHuuW3sue7j+W7tui/nyAyMDAg55qE5raI5oGv5YiX6KGo6L+b6KGM5raI6LS5IHwg5peg5bu26L+fIDIwMG1zIOWGhea2iOaBr+ebtOaOpemAkuW9klxuICAgKiAz44CB5raI6LS55YiG5Li6IOemu+e6v+a2iOaBr+a2iOi0uemAu+i+keOAgeWcqOe6v+a2iOaBr+a2iOi0uemAu+i+ke+8jOa2iOi0ueWQjumAkuW9klxuICAqL1xuICBwcml2YXRlIF9oYW5kbGVCdWZmZXJNc2dzKCkge1xuICAgIC8vIOa2iOaBryBidWZmZXIg5YiX6KGo6ZW/5bqm5Li6IDAg5pe25Yqg6ZSBXG4gICAgaWYgKHRoaXMuX21zZ0J1ZmZlckxpc3QubGVuZ3RoID09PSAwIHx8IHRoaXMuX2hhZEhhbmRsZU1zZ1RpbWVyKSB7XG4gICAgICB0aGlzLl9sb2dnZXIud2FybignXycsICdfaGFuZGxlQnVmZmVyTXNncyByZXR1cm4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8g6ZyA6KaB5Yqg6ZSB77yM5pS25Yiw5aSa5qyh5raI5oGv5ZCO77yM5Y+v6IO95Lya6LW35aSa5LiqIHRpbWVyXG4gICAgdGhpcy5faGFkSGFuZGxlTXNnVGltZXIgPSB0cnVlO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8g5Y+W5Ye65aSn5LqOIDIwMCBtcyDmtojmga/liJfooahcbiAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGJ1ZmZlcnMgPSB0aGlzLl9tc2dCdWZmZXJMaXN0LmZpbHRlcigoaXRlbSkgPT4gY3VycmVudFRpbWUgLSBpdGVtLm1hcmtUaW1lID49IDIwMCk7XG4gICAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW0NhbGxNZXNzYWdlSGFuZGxlcl0gaGFuZGxlQnVmZmVyTXNncyAtPiBsaXN0cyBvdmVyIDIwMG1zIDogJHtKU09OLnN0cmluZ2lmeShidWZmZXJzLm1hcCgoeyBtc2c6IHsgbWVzc2FnZVVJZCwgaXNPZmZMaW5lTWVzc2FnZSwgY29udGVudDogeyBjYWxsSWQgfSB9IH0pID0+ICh7IG1lc3NhZ2VVSWQsIGlzT2ZmTGluZU1lc3NhZ2UsIGNhbGxJZCB9KSkpfWApO1xuICAgICAgaWYgKGJ1ZmZlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIOayoeacieW7tui/nyAyMDBtcyDnmoTmtojmga/vvIzmtojotLnpgLvovpHop6PplIHlubbpgJLlvZLmiafooYxcbiAgICAgICAgdGhpcy5faGFkSGFuZGxlTXNnVGltZXIgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5faGFuZGxlQnVmZmVyTXNncygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChidWZmZXJzWzBdLm1zZy5pc09mZkxpbmVNZXNzYWdlKSB7XG4gICAgICAgIC8vIOW9k+esrOS4gOadoea2iOaBr+S4uuemu+e6v+a2iOaBr+aXtu+8jOebtOaOpeS7jiBidWZmZXIg5Lit5Y+W5Ye65omA5pyJ56a757q/5raI5oGv77yM6L+b6KGM5raI5oGvXG4gICAgICAgIGxldCBvZmZsaW5lQnVmZmVycyA9IHRoaXMuX21zZ0J1ZmZlckxpc3QuZmlsdGVyKChpdGVtKSA9PiBpdGVtLm1zZy5pc09mZkxpbmVNZXNzYWdlKTtcblxuICAgICAgICAvLyDnprvnur/mtojmga/lpITnkIbpgLvovpFcbiAgICAgICAgZG8ge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGNvbnZlcnNhdGlvblR5cGUsIG1lc3NhZ2VUeXBlLCBzZW50VGltZSwgc2VuZGVyVXNlcklkLCBjb250ZW50OiB7IGNhbGxJZDogaW52aXRlQ2FsbElkLCBpbnZpdGVVc2VySWRzIH0sXG4gICAgICAgICAgfSA9IG9mZmxpbmVCdWZmZXJzWzBdLm1zZztcblxuICAgICAgICAgIGNvbnN0IGlzSW52aXRlTXNnVHlwZSA9IFtSQ0NhbGxNZXNzYWdlVHlwZS5WQ0ludml0ZSwgUkNDYWxsTWVzc2FnZVR5cGUuVkNNb2RpZnlNZW1dLmluY2x1ZGVzKG1lc3NhZ2VUeXBlIGFzIFJDQ2FsbE1lc3NhZ2VUeXBlKTtcblxuICAgICAgICAgIC8vIOiuoeeul+W9k+WJjeaXtumXtOS4jua2iOaBr+WPkemAgeaXtumXtOW3rlxuICAgICAgICAgIGNvbnN0IGRlbGF5VGltZSA9IHRoaXMuX2NvbnRleHQuZ2V0U2VydmVyVGltZSgpIC0gc2VudFRpbWU7XG4gICAgICAgICAgY29uc3QgaXNMZXNzVGhhbk9mZmxpbmVNc2dJdHYgPSBkZWxheVRpbWUgPCB0aGlzLl9vZmZsaW5lTXNnSXR2O1xuXG4gICAgICAgICAgaWYgKCFpc0xlc3NUaGFuT2ZmbGluZU1zZ0l0dikge1xuICAgICAgICAgICAgdGhpcy5fbG9nZ2VyLndhcm4oJ18nLCBgb2ZmbGluZSBtc2cgZGVsYXlUaW1lOiAke2RlbGF5VGltZX1tc2ApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpc0ludml0ZU1zZ1R5cGUpIHsgLy8g5Y+W5Ye655qE56ys5LiA5p2h5raI5oGv5Li6IGludml0ZSB8IG1lbU1vZGlmeVxuICAgICAgICAgICAgLy8g5Y+W5Ye655u45ZCMIENhbGxJZCDmtojmga/liJfooahcbiAgICAgICAgICAgIGNvbnN0IHRhc2tNc2dMaXN0OiBJUmVjZWl2ZWRNZXNzYWdlW10gPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2ZmbGluZUJ1ZmZlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IG9mZmxpbmVCdWZmZXJzW2ldLm1zZztcbiAgICAgICAgICAgICAgY29uc3QgeyBjb250ZW50OiB7IGNhbGxJZDogb3RoZXJDYWxsSWQgfSB9ID0gaXRlbTtcbiAgICAgICAgICAgICAgaWYgKGludml0ZUNhbGxJZCA9PT0gb3RoZXJDYWxsSWQpIHtcbiAgICAgICAgICAgICAgICB0YXNrTXNnTGlzdC5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGB0YXNrTXNnTGlzdCBsZW5ndGg6ICR7dGFza01zZ0xpc3QubGVuZ3RofWApO1xuXG4gICAgICAgICAgICBpZiAodGFza01zZ0xpc3QubGVuZ3RoID4gMCkgeyAvLyDpmLLmraIgdGFza01zZ0xpc3Qg5Li6IDBcbiAgICAgICAgICAgICAgLy8g5om+5Ye6IG1zZ0J1ZmZlckxpc3Qg5Lit5bey5raI6LS555qE5raI5oGv5pyA5aSnIGluZGV4XG4gICAgICAgICAgICAgIGNvbnN0IGRlbEluZGV4ID0gdGhpcy5fbXNnQnVmZmVyTGlzdC5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0ubXNnLm1lc3NhZ2VVSWQgPT09IHRhc2tNc2dMaXN0W3Rhc2tNc2dMaXN0Lmxlbmd0aCAtIDFdLm1lc3NhZ2VVSWQpO1xuICAgICAgICAgICAgICAvLyDliKDpmaTmtojotLnov4cgbXNnQnVmZmVyTGlzdCDnmoTmtojmga9cbiAgICAgICAgICAgICAgdGhpcy5fbXNnQnVmZmVyTGlzdCA9IHRoaXMuX21zZ0J1ZmZlckxpc3Quc2xpY2UoZGVsSW5kZXggKyAxKTtcblxuICAgICAgICAgICAgICAvLyDmib7lh7ogb2ZmbGluZU1zZ3Mg5Lit5bey5raI6LS555qE5raI5oGv5pyA5aSnIGluZGV4XG4gICAgICAgICAgICAgIGNvbnN0IGRlbE9mZmxpbmVJbmRleCA9IG9mZmxpbmVCdWZmZXJzLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS5tc2cubWVzc2FnZVVJZCA9PT0gdGFza01zZ0xpc3RbdGFza01zZ0xpc3QubGVuZ3RoIC0gMV0ubWVzc2FnZVVJZCk7XG4gICAgICAgICAgICAgIC8vIOWIoOmZpOa2iOi0uei/hyBvZmZsaW5lQnVmZmVycyDnmoTmtojmga9cbiAgICAgICAgICAgICAgb2ZmbGluZUJ1ZmZlcnMgPSBvZmZsaW5lQnVmZmVycy5zbGljZShkZWxPZmZsaW5lSW5kZXggKyAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICog5Y2V6IGK5pyq57uT5p2f6YCa6K+d5Yik5patXG4gICAgICAgICAgICAgKiDlpoLmnpzmtojmga/lnKggNjBzIOWGhe+8jOWIpOaWreaYr+WQpuacquaIkOWvue+8iOWPquaciSBpbnZpdGUg5oiW5Y+q5pyJIGludml0ZSDmiJYgcmluZ2luZyDmiJDlr7nmipvnu5kg56a757q/6K6w5b2V5Zmo77yM5pyq5oiQ5a+55oqb57uZ54q25oCB5py6XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IGlzVW5maW5pc2hlZFByaXZhdGVDYWxsOiBib29sZWFuID0gKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGNvbnZlcnNhdGlvblR5cGUgIT09IENvbnZlcnNhdGlvblR5cGUuUFJJVkFURSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICBjb25zdCBpc09ubHlJbnZpdGUgPSB0YXNrTXNnTGlzdC5sZW5ndGggPT09IDE7XG4gICAgICAgICAgICAgIGNvbnN0IGhhc0ludml0ZUFuZFJpbmdpbmcgPSB0YXNrTXNnTGlzdC5ldmVyeSgoaXRlbSkgPT4gW1JDQ2FsbE1lc3NhZ2VUeXBlLlZDSW52aXRlLCBSQ0NhbGxNZXNzYWdlVHlwZS5WQ01vZGlmeU1lZGlhLCBSQ0NhbGxNZXNzYWdlVHlwZS5WQ1JpbmdpbmddLmluY2x1ZGVzKGl0ZW0ubWVzc2FnZVR5cGUgYXMgUkNDYWxsTWVzc2FnZVR5cGUpKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGlzT25seUludml0ZSB8fCBoYXNJbnZpdGVBbmRSaW5naW5nO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICog576k6IGK5pyq57uT5p2f6YCa6K+d5Yik5patXG4gICAgICAgICAgICAgKiDpgJrov4cgbGlzdCDkuK0gaW52aXRlIOWSjCBtZW1iZXJNb2RpZnkg5raI5oGv5Lit5Y+W5Ye65omA5pyJ5Y+C5LiO6YCa6K+d55qEIHVzZXJJZFxuICAgICAgICAgICAgICog6YGN5Y6GIGxpc3Qg5om+5Ye65omA5pyJIGhhbmd1cCDnmoQgc2VuZFVzZXJJZFxuICAgICAgICAgICAgICogICAgIOaAu+S6uuaVsCAtIOaMguaWreS6uuaVsCA+IDEgIOS4lOWJqeS9meS6uuaVsOWMheWQq+iHquW3se+8jOiupOS4uumAmuivneacquaMguaWrei/m+eKtuaAgeaculxuICAgICAgICAgICAgICogICAgIOaAu+S6uuaVsCAtIOaMguaWreS6uuaVsCA8PSAxIOmAmuivneaMguaWre+8jOi/m+emu+e6v+a2iOaBr+WkhOeQhuWZqFxuICAgICAgICAgICAgICogICAgIOS4u+WPq+ebtOaOpeaMguaWreS4lOWFtuS7luS6uuacquaOpeWQrOebtOaOpei/m+emu+e6v+WkhOeQhuWZqFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBpc1VuZmluaXNoZWRHcnBDYWxsOiBib29sZWFuID0gKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGNvbnZlcnNhdGlvblR5cGUgIT09IENvbnZlcnNhdGlvblR5cGUuR1JPVVApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgbGV0IGlzVW5maW5pc2hlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICBsZXQgbm9PbmVBY2NlcHQgPSB0cnVlO1xuICAgICAgICAgICAgICBsZXQgYWxsVXNlcklkcyA9IFtzZW5kZXJVc2VySWQsIC4uLmludml0ZVVzZXJJZHNdO1xuICAgICAgICAgICAgICBsZXQgaXNDYWxsZXJIdW5ndXAgPSBmYWxzZTtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXNrTXNnTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgc2VuZGVyVXNlcklkOiB0YXNrTXNnU2VuZGVyVXNlcklkLCBtZXNzYWdlVHlwZSB9ID0gdGFza01zZ0xpc3RbaV07XG4gICAgICAgICAgICAgICAgLy8g5Y+q6KaB6Ieq5bex5oyC5pat55u05o6l6Lez5Ye65b6q546v77yM6L+b56a757q/5raI5oGvXG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VUeXBlID09PSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ0hhbmd1cCAmJiB0YXNrTXNnU2VuZGVyVXNlcklkID09PSB0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpKSB7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8g5om+5Ye65omA5pyJ5oyC5pat55qE5Lq65ZGY77yM5Lul5Y+K6YCa6K+d5Y+R6LW36ICF5piv5ZCm5oyC5patXG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VUeXBlID09PSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ0hhbmd1cCkge1xuICAgICAgICAgICAgICAgICAgaXNDYWxsZXJIdW5ndXAgPSBzZW5kZXJVc2VySWQgPT09IHRhc2tNc2dTZW5kZXJVc2VySWQ7XG4gICAgICAgICAgICAgICAgICBhbGxVc2VySWRzID0gYWxsVXNlcklkcy5maWx0ZXIoKGlkKSA9PiB0YXNrTXNnU2VuZGVyVXNlcklkICE9PSBpZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIOWIpOaWreaYr+WQpuaXoOS6uuaOpeWQrFxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlVHlwZSA9PT0gUkNDYWxsTWVzc2FnZVR5cGUuVkNBY2NlcHQpIHtcbiAgICAgICAgICAgICAgICAgIG5vT25lQWNjZXB0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIOS4jeaYr+S4u+WPq+aMguaWreS4lOaXoOS6uuaOpeWQrO+8jOS4lOWJqeS9meS6uuaVsOWkp+S6jiAxXG4gICAgICAgICAgICAgIGlmICghKG5vT25lQWNjZXB0ICYmIGlzQ2FsbGVySHVuZ3VwKSAmJiBhbGxVc2VySWRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBpc1VuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBpc1VuZmluaXNoZWQ7XG4gICAgICAgICAgICB9KSgpO1xuXG4gICAgICAgICAgICBpZiAoaXNMZXNzVGhhbk9mZmxpbmVNc2dJdHYgJiYgKGlzVW5maW5pc2hlZFByaXZhdGVDYWxsIHx8IGlzVW5maW5pc2hlZEdycENhbGwpKSB7XG4gICAgICAgICAgICAgIHRhc2tNc2dMaXN0LmZvckVhY2godGhpcy5fb25SZWN2T25saW5lQ2FsbE1zZywgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZsaW5lUmVjb3JkZXIub25SZWN2T2ZmbGluZU1zZ3ModGFza01zZ0xpc3QpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoaXNMZXNzVGhhbk9mZmxpbmVNc2dJdHYgJiYgdGhpcy5fZ2V0U3RhdGVNYWNoaW5lKGludml0ZUNhbGxJZCkpIHtcbiAgICAgICAgICAgICAgdGhpcy5fb25SZWN2T25saW5lQ2FsbE1zZyhvZmZsaW5lQnVmZmVyc1swXS5tc2cpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgYFtDYWxsTWVzc2FnZUhhbmRsZXJdIHVuZXhjZXB0ZWQgb2ZmbGluZSBtc2cgLT4gJHtKU09OLnN0cmluZ2lmeShvZmZsaW5lQnVmZmVyc1swXS5tc2cpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2ZmbGluZUJ1ZmZlcnMuc2hpZnQoKTtcbiAgICAgICAgICAgIHRoaXMuX21zZ0J1ZmZlckxpc3Quc2hpZnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gd2hpbGUgKG9mZmxpbmVCdWZmZXJzLmxlbmd0aCA+IDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g5Zyo57q/5raI5oGv5aSE55CG6YC76L6RXG4gICAgICAgIGJ1ZmZlcnMuZm9yRWFjaCgoeyBtc2cgfSkgPT4ge1xuICAgICAgICAgIHRoaXMuX29uUmVjdk9ubGluZUNhbGxNc2cobXNnISk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyDmib7lh7ogbXNnQnVmZmVyTGlzdCDkuK3lt7LmtojotLnnmoTmtojmga/mnIDlpKcgaW5kZXhcbiAgICAgICAgY29uc3QgZGVsQ291bnQgPSBidWZmZXJzLmxlbmd0aDtcbiAgICAgICAgLy8g5Yig6Zmk5raI6LS56L+H55qE5raI5oGvXG4gICAgICAgIHRoaXMuX21zZ0J1ZmZlckxpc3Quc3BsaWNlKDAsIGRlbENvdW50KTtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgYHRpbWVyIG9ubGluZSBtc2cgaGFuZGxlIC0+IGRlbENvdW50OiAke2RlbENvdW50fSBtc2dCdWZmZXJMaXN0OiAke3RoaXMuX21zZ0J1ZmZlckxpc3QubGVuZ3RofWApO1xuICAgICAgfVxuICAgICAgdGhpcy5faGFkSGFuZGxlTXNnVGltZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMuX2hhbmRsZUJ1ZmZlck1zZ3MoKTtcbiAgICB9LCAyMCk7XG4gIH1cblxuICByZWdpc3RlckV2ZW50TGlzdGVuZXIobGlzdGVuZXI6IElNc2dMaXN0ZW5lcikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5fd2F0Y2hlcnMsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJlZ2lzdGVyU3RhdGVNYWNoaW5lRXZlbnQoY2FsbElkOiBzdHJpbmcsIGZ1bmNOYW1lOiBNc2dMaXN0ZW5lcktleXMsIGV2ZW50OiAoLi4uYXJnczogYW55W10pID0+IHZvaWQpIHtcbiAgICBjb25zdCBldmVudFR5cGUgPSBjYWxsSWQgKyBmdW5jTmFtZTtcbiAgICBzdXBlci5vbihldmVudFR5cGUsIGV2ZW50KTtcbiAgfVxuXG4gIHVucmVnaXN0ZXJTdGF0ZU1hY2hpbmVFdmVudChjYWxsSWQ6IHN0cmluZykge1xuICAgIFsnb25SaW5naW5nJywgJ29uQWNjZXB0JywgJ29uSHVuZ3VwJywgJ29uTWVkaWFNb2RpZnknXS5mb3JFYWNoKChmdW5jTmFtZSkgPT4ge1xuICAgICAgY29uc3QgZXZlbnRUeXBlID0gY2FsbElkICsgZnVuY05hbWU7XG4gICAgICBzdXBlci5yZW1vdmVBbGwoZXZlbnRUeXBlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlZ2lzdGVyVXNlckluZm8odXNlckluZm86IElVc2VyUHJvZmlsZSkge1xuICAgIHRoaXMuX3VzZXJJbmZvID0gdXNlckluZm87XG4gIH1cblxuICAvKipcbiAgICog5Y+R6YCBIElNIOa2iOaBr1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfc2VuZENhbGxNZXNzYWdlKG9wdGlvbnM6IElDYWxsTXNnT3B0aW9uKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgbWVzc2FnZT86IElSZWNlaXZlZE1lc3NhZ2UgfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsIGBDYWxsTWVzc2FnZUhhbmRsZXJdIHNlbmRDYWxsTWVzYWdlIC0+IG1lc3NhZ2U6ICR7SlNPTi5zdHJpbmdpZnkob3B0aW9ucyl9YCk7XG4gICAgY29uc3Qge1xuICAgICAgY2hhbm5lbElkLCBjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgY29udGVudCwgbWVzc2FnZVR5cGUsIGRpcmVjdGlvbmFsVXNlcklkTGlzdCwgcHVzaENvbmZpZyxcbiAgICB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBzZW5kT3B0czogSVNlbmRNc2dPcHRpb25zID0ge1xuICAgICAgY2hhbm5lbElkLFxuICAgICAgbWVzc2FnZVR5cGUsXG4gICAgICBjb250ZW50LFxuICAgICAgZGlyZWN0aW9uYWxVc2VySWRMaXN0LFxuICAgIH07XG5cbiAgICBpZiAoW1JDQ2FsbE1lc3NhZ2VUeXBlLlZDSW52aXRlLCBSQ0NhbGxNZXNzYWdlVHlwZS5WQ01vZGlmeU1lbSwgUkNDYWxsTWVzc2FnZVR5cGUuVkNIYW5ndXBdLmluY2x1ZGVzKG1lc3NhZ2VUeXBlKSkge1xuICAgICAgY29uc3QgbmV3UHVzaENvbmZpZyA9IHB1c2hDb25maWcgfHwgeyBwdXNoVGl0bGU6ICcnLCBwdXNoQ29udGVudDogJycsIHB1c2hEYXRhOiAnJyB9O1xuICAgICAgbmV3UHVzaENvbmZpZy5hbmRyb2lkQ29uZmlnID0gT2JqZWN0LmFzc2lnbihwdXNoQ29uZmlnPy5hbmRyb2lkQ29uZmlnIHx8IHt9LCB7XG4gICAgICAgIGNhdGVnb3J5SFc6ICdWT0lQJyxcbiAgICAgICAgY2F0ZWdvcnlWaXZvOiAnSU0nLFxuICAgICAgfSk7XG4gICAgICBuZXdQdXNoQ29uZmlnLmlPU0NvbmZpZyA9IE9iamVjdC5hc3NpZ24obmV3UHVzaENvbmZpZy5pT1NDb25maWcgfHwge30sIHtcbiAgICAgICAgYXBuc0NvbGxhcHNlSWQ6IGNvbnRlbnQuY2FsbElkLFxuICAgICAgfSk7XG4gICAgICBuZXdQdXNoQ29uZmlnLmRpc2FibGVQdXNoVGl0bGUgPSBmYWxzZTtcbiAgICAgIG5ld1B1c2hDb25maWcuZm9yY2VTaG93RGV0YWlsQ29udGVudCA9IGZhbHNlO1xuICAgICAgc2VuZE9wdHMucHVzaENvbmZpZyA9IG5ld1B1c2hDb25maWcgYXMgSUVuZ2luZVB1c2hDb25maWc7XG4gICAgfVxuICAgIGNvbnN0IHsgY29kZSwgZGF0YTogbWVzc2FnZSB9ID0gYXdhaXQgdGhpcy5fY29udGV4dC5zZW5kTWVzc2FnZShjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgc2VuZE9wdHMpO1xuICAgIGlmIChjb2RlICE9PSBFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYENhbGxNZXNzYWdlSGFuZGxlcl0gc2VuZENhbGxNZXNhZ2UgZXJyb3IgLT4gY29kZTogJHtjb2RlfWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogRW5naW5lRXJyb3JDb2RlVG9DYWxsRXJyb3JDb2RlW2NvZGVdIHx8IFJDQ2FsbEVycm9yQ29kZS5TRU5EX01TR19FUlJPUixcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLCBtZXNzYWdlIH07XG4gIH1cblxuICAvKipcbiAgICog5Y+R6YCB6YKA6K+35raI5oGvXG4gICAqL1xuICBhc3luYyBzZW5kSW52aXRlKG9wdGlvbnM6IElJbnZpdGVNc2dPcHRpb25zKSB7XG4gICAgY29uc3Qge1xuICAgICAgcm9vbVR5cGUsIGNoYW5uZWxJZCwgY29udmVyc2F0aW9uVHlwZSwgdGFyZ2V0SWQsIGNhbGxJZCwgbWVkaWFUeXBlLCBpbnZpdGVVc2VySWRzLCBleHRyYSwgcHVzaENvbmZpZyxcbiAgICB9ID0gb3B0aW9ucztcbiAgICB0aGlzLl9sb2dnZXIud2FybignXycsICdDYWxsTWVzc2FnZUhhbmRsZXJdIHNlbmRDYWxsTWVzYWdlIHNlbmRJbnZpdGUnLCBKU09OLnN0cmluZ2lmeShvcHRpb25zKSk7XG4gICAgdGhpcy5fd2F0Y2hlcnMuc2VuZEFjY2VwdCAmJiB0aGlzLl93YXRjaGVycy5zZW5kQWNjZXB0KHsgY2FsbElkIH0pO1xuICAgIGNvbnN0IGNvbnRlbnQ6IElJbnZpdGVNc2dDb250ZW50ID0ge1xuICAgICAgcGxhdGZvcm06IFBsYXRmb3JtLldFQixcbiAgICAgIGRldmljZUlkOiB0aGlzLl9kZXZpY2VJZCxcbiAgICAgIGNhbGxJZCxcbiAgICAgIHJvb21UeXBlLFxuICAgICAgZXh0cmEsXG4gICAgICBlbmdpbmVUeXBlOiA0LFxuICAgICAgY2hhbm5lbEluZm86IHsgSWQ6IGNhbGxJZCwgS2V5OiAnJyB9LFxuICAgICAgbWVkaWFUeXBlLFxuICAgICAgaW52aXRlVXNlcklkcyxcbiAgICAgIG9ic2VydmVyVXNlcklkczogW10sXG4gICAgICB1c2VyOiB0aGlzLl91c2VySW5mbyxcbiAgICB9O1xuXG4gICAgaWYgKHB1c2hDb25maWcpIHtcbiAgICAgIHB1c2hDb25maWcucHVzaERhdGEgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgICAgdXNlcklkTGlzdDogaW52aXRlVXNlcklkcyxcbiAgICAgICAgY2FsbElkLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3NlbmRDYWxsTWVzc2FnZSh7XG4gICAgICBjaGFubmVsSWQsXG4gICAgICBjb252ZXJzYXRpb25UeXBlLFxuICAgICAgdGFyZ2V0SWQsXG4gICAgICBjb250ZW50LFxuICAgICAgbWVzc2FnZVR5cGU6IFJDQ2FsbE1lc3NhZ2VUeXBlLlZDSW52aXRlLFxuICAgICAgZGlyZWN0aW9uYWxVc2VySWRMaXN0OiBjb252ZXJzYXRpb25UeXBlID09PSBDb252ZXJzYXRpb25UeXBlLkdST1VQID8gaW52aXRlVXNlcklkcyA6IFt0YXJnZXRJZF0sXG4gICAgICBwdXNoQ29uZmlnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPkemAgeS6uuWRmOWPmOabtOa2iOaBr1xuICAgKi9cbiAgYXN5bmMgc2VuZE1lbWViZXJNb2RpZnkob3B0aW9uczogSU1lbWJlck1vZGlmeU1zZ09wdGlvbnMpIHtcbiAgICBjb25zdCB7XG4gICAgICBjaGFubmVsSWQsIGNvbnZlcnNhdGlvblR5cGUsIHRhcmdldElkLCBjYWxsSWQsIG1lZGlhVHlwZSwgaW52aXRlVXNlcklkcywgY2FsbGVySWQsXG4gICAgICBleGlzdGVkVXNlclBvZmlsZXMsIGRpcmVjdGlvbmFsVXNlcklkTGlzdCwgZXh0cmEsIHB1c2hDb25maWcsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgY29udGVudDogSU1lbWJlck1vZGlmeU1zZ0NvbnRlbnQgPSB7XG4gICAgICBwbGF0Zm9ybTogUGxhdGZvcm0uV0VCLCAvLyBUT0RPIOS4jiBJTSDkuIDoh7RcbiAgICAgIGRldmljZUlkOiB0aGlzLl9kZXZpY2VJZCxcbiAgICAgIGNhbGxJZCxcbiAgICAgIGV4dHJhLFxuICAgICAgZW5naW5lVHlwZTogNCxcbiAgICAgIGNoYW5uZWxJbmZvOiB7IElkOiBjYWxsSWQsIEtleTogJycgfSxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICAgIGludml0ZVVzZXJJZHMsXG4gICAgICBvYnNlcnZlclVzZXJJZHM6IFtdLFxuICAgICAgdXNlcjogdGhpcy5fdXNlckluZm8sXG4gICAgICBjYWxsZXI6IGNhbGxlcklkLFxuICAgICAgbW9kaWZ5TWVtVHlwZTogTWVtYmVyTW9kaWZ5VHlwZS5BREQsXG4gICAgICBleGlzdGVkVXNlclBvZmlsZXMsXG4gICAgfTtcblxuICAgIGlmIChwdXNoQ29uZmlnKSB7XG4gICAgICBwdXNoQ29uZmlnLnB1c2hEYXRhID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBtZWRpYVR5cGUsXG4gICAgICAgIHVzZXJJZExpc3Q6IGludml0ZVVzZXJJZHMsXG4gICAgICAgIGNhbGxJZCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWxJZCxcbiAgICAgIGNvbnZlcnNhdGlvblR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIGNvbnRlbnQsXG4gICAgICBtZXNzYWdlVHlwZTogUkNDYWxsTWVzc2FnZVR5cGUuVkNNb2RpZnlNZW0sXG4gICAgICBkaXJlY3Rpb25hbFVzZXJJZExpc3QsXG4gICAgICBwdXNoQ29uZmlnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPkemAgeWTjemTg+a2iOaBr1xuICAgKi9cbiAgc2VuZFJpbmdpbmcob3B0aW9uczogSVJpbmdpbmdNc2dPcHRpb25zKSB7XG4gICAgY29uc3Qge1xuICAgICAgY2hhbm5lbElkLCBjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgY2FsbElkLCB1c2VySWRzLFxuICAgIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGNvbnRlbnQ6IElSaW5naW5nTXNnQ29udGVudCA9IHtcbiAgICAgIHBsYXRmb3JtOiBQbGF0Zm9ybS5XRUIsXG4gICAgICBkZXZpY2VJZDogdGhpcy5fZGV2aWNlSWQsXG4gICAgICBjYWxsSWQsXG4gICAgICB1c2VyOiB0aGlzLl91c2VySW5mbyxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLl9zZW5kQ2FsbE1lc3NhZ2Uoe1xuICAgICAgY2hhbm5lbElkLFxuICAgICAgY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkLFxuICAgICAgY29udGVudCxcbiAgICAgIG1lc3NhZ2VUeXBlOiBSQ0NhbGxNZXNzYWdlVHlwZS5WQ1JpbmdpbmcsXG4gICAgICBkaXJlY3Rpb25hbFVzZXJJZExpc3Q6IHVzZXJJZHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5Y+R6YCB5ZCM5oSP5o6l5ZCs5raI5oGvXG4gICAqL1xuICBzZW5kQWNjZXB0KG9wdGlvbnM6IElBY2NlcHRNc2dPcHRpb25zKSB7XG4gICAgY29uc3Qge1xuICAgICAgY2hhbm5lbElkLCBjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgY2FsbElkLCBtZWRpYVR5cGUsIHVzZXJJZHMsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgY29udGVudDogSUFjY2VwdE1zZ0NvbnRlbnQgPSB7XG4gICAgICBwbGF0Zm9ybTogUGxhdGZvcm0uV0VCLFxuICAgICAgZGV2aWNlSWQ6IHRoaXMuX2RldmljZUlkLFxuICAgICAgY2FsbElkLFxuICAgICAgbWVkaWFUeXBlLFxuICAgICAgdXNlcjogdGhpcy5fdXNlckluZm8sXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWxJZCxcbiAgICAgIGNvbnZlcnNhdGlvblR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIGNvbnRlbnQsXG4gICAgICBtZXNzYWdlVHlwZTogUkNDYWxsTWVzc2FnZVR5cGUuVkNBY2NlcHQsXG4gICAgICBkaXJlY3Rpb25hbFVzZXJJZExpc3Q6IHVzZXJJZHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5Y+R6YCB5oyC5pat5raI5oGvXG4gICAqL1xuICBzZW5kSHVuZ3VwKG9wdGlvbnM6IElIdW5ndXBNc2dPcHRpb25zKSB7XG4gICAgY29uc3Qge1xuICAgICAgY2hhbm5lbElkLCBjb252ZXJzYXRpb25UeXBlLCB0YXJnZXRJZCwgY2FsbElkLCByZWFzb24sIHVzZXJJZHMsIHB1c2hDb25maWcsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgY29udGVudDogSUh1bmd1cE1zZ0NvbnRlbnQgPSB7XG4gICAgICBwbGF0Zm9ybTogUGxhdGZvcm0uV0VCLFxuICAgICAgZGV2aWNlSWQ6IHRoaXMuX2RldmljZUlkLFxuICAgICAgY2FsbElkLFxuICAgICAgcmVhc29uLFxuICAgICAgdXNlcjogdGhpcy5fdXNlckluZm8sXG4gICAgfTtcblxuICAgIGlmIChwdXNoQ29uZmlnKSB7XG4gICAgICBwdXNoQ29uZmlnLnB1c2hEYXRhID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBjYWxsSWQsIHJlYXNvbixcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zZW5kQ2FsbE1lc3NhZ2Uoe1xuICAgICAgY2hhbm5lbElkLFxuICAgICAgY29udmVyc2F0aW9uVHlwZSxcbiAgICAgIHRhcmdldElkLFxuICAgICAgY29udGVudCxcbiAgICAgIG1lc3NhZ2VUeXBlOiBSQ0NhbGxNZXNzYWdlVHlwZS5WQ0hhbmd1cCxcbiAgICAgIHB1c2hDb25maWcsXG4gICAgICBkaXJlY3Rpb25hbFVzZXJJZExpc3Q6IHVzZXJJZHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5Y+R6YCB5aqS5L2T5Y+Y5pu05raI5oGvXG4gICAqL1xuICBzZW5kTWVkaWFNb2RpZnkob3B0aW9uczogSU1lZGlhTW9kaWZ5TXNnT3B0aW9ucykge1xuICAgIGNvbnN0IHtcbiAgICAgIGNoYW5uZWxJZCwgY29udmVyc2F0aW9uVHlwZSwgdGFyZ2V0SWQsIGNhbGxJZCwgbWVkaWFUeXBlLCB1c2VySWRzLFxuICAgIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGNvbnRlbnQ6IElNZWRpYU1vZGlmeU1zZ0NvbnRlbnQgPSB7XG4gICAgICBwbGF0Zm9ybTogUGxhdGZvcm0uV0VCLFxuICAgICAgZGV2aWNlSWQ6IHRoaXMuX2RldmljZUlkLFxuICAgICAgY2FsbElkLFxuICAgICAgbWVkaWFUeXBlLFxuICAgICAgdXNlcjogdGhpcy5fdXNlckluZm8sXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5fc2VuZENhbGxNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWxJZCxcbiAgICAgIGNvbnZlcnNhdGlvblR5cGUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIGNvbnRlbnQsXG4gICAgICBtZXNzYWdlVHlwZTogUkNDYWxsTWVzc2FnZVR5cGUuVkNNb2RpZnlNZWRpYSxcbiAgICAgIGRpcmVjdGlvbmFsVXNlcklkTGlzdDogdXNlcklkcyxcbiAgICB9KTtcbiAgfVxufVxuIiwiZXhwb3J0IGVudW0gUkNDYWxsTGFuZ3VhZ2Uge1xuICBaSCA9ICd6aCcsXG4gIEVOID0gJ2VuJ1xufVxuIiwiZXhwb3J0IGNvbnN0IEVOID0ge1xuICBQdXNoVGl0bGU6IHtcbiAgICBBVURJTzogJ1lvdSBoYXZlIGEgdm9pY2UgY2FsbCcsXG4gICAgVklERU86ICdZb3UgaGF2ZSBhIHZpZGVvIGNhbGwnLFxuICB9LFxufTtcbiIsImV4cG9ydCBjb25zdCBaSCA9IHtcbiAgUHVzaFRpdGxlOiB7XG4gICAgQVVESU86ICfmgqjmnInkuIDmnaHpn7PpopHpgJror50nLFxuICAgIFZJREVPOiAn5oKo5pyJ5LiA5p2h6KeG6aKR6YCa6K+dJyxcbiAgfSxcbn07XG4iLCJpbXBvcnQgeyBSQ0NhbGxMYW5ndWFnZSB9IGZyb20gJy4uL2VudW1zL1JDQ2FsbExhbmcnO1xuaW1wb3J0IHsgRU4gfSBmcm9tICcuL2VuJztcbmltcG9ydCB7IFpIIH0gZnJvbSAnLi96aCc7XG5cbi8qKlxuICogQ2FsbEVuZ2luZSDlhajlsYDor63oqIDorr7nva7vvIzlvZPliY3ku4XmlK/mjIHkuK3jgIHoi7HmlodcbiAqL1xuZXhwb3J0IGNsYXNzIExvY2FsIHtcbiAgc3RhdGljIF9sYW5nOiBSQ0NhbGxMYW5ndWFnZSA9IFJDQ2FsbExhbmd1YWdlLlpIXG5cbiAgc3RhdGljIHNldChsYW5nOiBSQ0NhbGxMYW5ndWFnZSkge1xuICAgIHRoaXMuX2xhbmcgPSBsYW5nO1xuICB9XG5cbiAgc3RhdGljIGdldCgpIHtcbiAgICBpZiAodGhpcy5fbGFuZyA9PT0gUkNDYWxsTGFuZ3VhZ2UuRU4pIHtcbiAgICAgIHJldHVybiBFTjtcbiAgICB9XG4gICAgcmV0dXJuIFpIO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBCYXNpY0xvZ2dlciwgQ29udmVyc2F0aW9uVHlwZSwgSVJlY2VpdmVkTWVzc2FnZSwgSVJ1bnRpbWUsIFJUQ1BsdWdpbkNvbnRleHQsXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7IFJDQ2FsbFN0YXRlTWFjaGluZSB9IGZyb20gJy4vY29yZS9TdGF0ZU1hY2hpbmUnO1xuaW1wb3J0IHtcbiAgSUNhbGxTdGF0ZU1hY2hpbmVXYXRjaGVycywgSUVuZFN1bW1hcnksIElJbnZpdGVkVXNlcnMsIElNZWRpYU1vZGlmeUluZm8sIElNZW1iZXJNb2RpZnlJbmZvLCBJU2VuZGVySW5mbywgSVN0YXRlQ2hhbmdlSW5mbywgSVVzZXJQcm9maWxlLCBJVXNlclN0YXRlQ2hhbmdlSW5mbywgSVVzZXJEYXRhLCBJSW52aXRlT3B0aW9ucyxcbn0gZnJvbSAnLi9jb3JlL2ludGVyZmFjZXMvSVN0YXRlTWFjaGluZSc7XG5pbXBvcnQgeyBSQ0NhbGxFcnJvckNvZGUgfSBmcm9tICcuL2NvcmUvZW51bXMvUkNDYWxsQ29kZSc7XG5pbXBvcnQgeyBSQ0NhbGxVc2VyU3RhdGUgfSBmcm9tICcuL2NvcmUvZW51bXMvUkNDYWxsVXNlclN0YXRlJztcbmltcG9ydCB7IFJDQ2FsbFNlc3Npb25TdGF0ZSB9IGZyb20gJy4vY29yZS9lbnVtcy9SQ0NhbGxTZXNzaW9uU3RhdGUnO1xuaW1wb3J0IHsgUkNDYWxsRW5kUmVhc29uIH0gZnJvbSAnLi9jb3JlL2VudW1zL1JDQ2FsbEVuZFJlYXNvbic7XG5pbXBvcnQgeyBSQ0NhbGxNZWRpYVR5cGUgfSBmcm9tICcuL2NvcmUvZW51bXMvUkNDYWxsTWVkaWFUeXBlJztcbmltcG9ydCB7IENhbGxNZXNzYWdlSGFuZGxlciB9IGZyb20gJy4vY29yZS9NZXNzYWdlSGFuZGxlcic7XG5pbXBvcnQgeyBldmVudEVtaXR0ZXIsIGdlbmVyYXRlUmFuZG9tSWQsIGdldENhbGxEZXZpY2VJZCB9IGZyb20gJy4vaGVscGVyJztcbmltcG9ydCB7IFJDQ2FsbExhbmd1YWdlIH0gZnJvbSAnLi9jb3JlL2VudW1zL1JDQ2FsbExhbmcnO1xuaW1wb3J0IHsgSUNhbGxFbmdpbmVPcHRpb25zLCBJQ2FsbEVuZ2luZVdhdGNoZXJzIH0gZnJvbSAnLi9jb3JlL2ludGVyZmFjZXMvSUNhbGxFbmdpbmUnO1xuaW1wb3J0IHsgUkNDYWxsTWVzc2FnZVR5cGUgfSBmcm9tICcuL2NvcmUvZW51bXMvUkNDYWxsTWVzc2FnZVR5cGUnO1xuaW1wb3J0IHsgSUludml0ZU1zZ0NvbnRlbnQgfSBmcm9tICcuL2NvcmUvaW50ZXJmYWNlcy9JTWVzc2FnZUhhbmRsZXInO1xuaW1wb3J0IHsgTG9jYWwgfSBmcm9tICcuL2NvcmUvbG9jYWxlJztcbmltcG9ydCB7IElPZmZsaW5lUmVjb3JkIH0gZnJvbSAnLi9jb3JlL09mZmxpbmVSZWNvcmRlcic7XG5pbXBvcnQgeyBSQ0Nyb3NzQ2FsbFR5cGUgfSBmcm9tICcuL2NvcmUvZW51bXMvUkNDcm9zc0NhbGxUeXBlJztcbmltcG9ydCB7IElQdXNoQ29uZmlnIH0gZnJvbSAnLi4vc3JjL2ludGVyZmFjZSc7XG5cbmNsYXNzIFJDQ2FsbEVuZ2luZSB7XG4gIHByaXZhdGUgX3N0YXRlTWFjaGluZTogeyBbY2FsbElkOiBzdHJpbmddOiBSQ0NhbGxTdGF0ZU1hY2hpbmUgfSA9IHt9XG5cbiAgcHJpdmF0ZSBfY2FsbE1zZ0hhbmRsZXI6IENhbGxNZXNzYWdlSGFuZGxlclxuXG4gIC8qKlxuICAgKiDliJ3lp4vljJZcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIGVuZ2luZSBQbGd1aW5Db250ZXh0IOWunuS+i1xuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRleHQ6IFJUQ1BsdWdpbkNvbnRleHQsXG4gICAgLyoqXG4gICAgICog6L+Q6KGM5pe255u45YWzXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcnVudGltZTogSVJ1bnRpbWUsXG4gICAgLyoqXG4gICAgICogZW5naW5lIOaXpeW/l+aooeWdl+WunuS+i++8jOeUsSBDYWxsTGliIOWxguWIneWni+WMllxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xvZ2dlcjogQmFzaWNMb2dnZXIsXG4gICAgLyoqXG4gICAgICog55uR5ZCs5pa55rOVXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfd2F0Y2hlcnM6IElDYWxsRW5naW5lV2F0Y2hlcnMsXG4gICAgLyoqXG4gICAgICog5YW25LuW6YWN572u6aG5XG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfb3B0aW9uczogSUNhbGxFbmdpbmVPcHRpb25zLFxuICApIHtcbiAgICB0aGlzLl9sb2dnZXIud2FybignXycsIGBSQ0NhbGxFbmdpbmUgVmVyc2lvbjogJHtfX1ZFUlNJT05fX30gQ29tbWl0SWQ6ICR7X19DT01NSVRfSURfX31gKTtcbiAgICAvLyDorr7nva4gRGV2aWNlSWRcbiAgICBnZXRDYWxsRGV2aWNlSWQoX3J1bnRpbWUpO1xuICAgIC8vIOebkeWQrCBJTSDmtojmga9cbiAgICB0aGlzLl9jYWxsTXNnSGFuZGxlciA9IG5ldyBDYWxsTWVzc2FnZUhhbmRsZXIodGhpcy5fY29udGV4dCwgdGhpcy5fcnVudGltZSwgdGhpcy5fbG9nZ2VyLCB0aGlzLl9vcHRpb25zLm9mZmxpbmVNc2dJdHYsIHRoaXMuX2dldFN0YXRlTWFjaGluZS5iaW5kKHRoaXMpKTtcbiAgICAvLyDms6jlhozmtojmga/mqKHlnZfnm5HlkKxcbiAgICB0aGlzLl9jYWxsTXNnSGFuZGxlci5yZWdpc3RlckV2ZW50TGlzdGVuZXIoe1xuICAgICAgb25JbnZpdGU6IHRoaXMuX29uSW52aXRlLmJpbmQodGhpcyksXG4gICAgICBzZW5kQWNjZXB0OiB0aGlzLl9oYW5kbGVTZW5kQWNjZXB0LmJpbmQodGhpcyksXG4gICAgICBvbk9mZmxpbmVSZWNvcmQ6IHRoaXMuX3dhdGNoZXJzLm9uT2ZmbGluZVJlY29yZCxcbiAgICB9KTtcbiAgICAvLyDnm5HlkKznirbmgIHmnLrlhbPpl61cbiAgICBldmVudEVtaXR0ZXIub24oJ29uU3RhdGVNYWNoaW5lQ2xvc2UnLCAoY2FsbElkOiBzdHJpbmcpID0+IHtcbiAgICAgIGRlbGV0ZSB0aGlzLl9zdGF0ZU1hY2hpbmVbY2FsbElkXTtcbiAgICB9KTtcbiAgICAvLyDorr7nva7or63oqIBcbiAgICBMb2NhbC5zZXQoX29wdGlvbnMubGFuZyk7XG4gIH1cblxuICBwcml2YXRlIF9vbkludml0ZShtc2c6IElSZWNlaXZlZE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7XG4gICAgICBjaGFubmVsSWQsIGNvbnZlcnNhdGlvblR5cGUsIHRhcmdldElkLCBjb250ZW50LCBtZXNzYWdlVHlwZSwgc2VuZGVyVXNlcklkOiBzdWlkLCBwdXNoQ29uZmlnLFxuICAgIH0gPSBtc2c7XG4gICAgdGhpcy5fbG9nZ2VyLndhcm4oJ18nLCBgUkNDYWxsRW5naW5lIF9vbkludml0ZTp0YXJnZXRJZCAke3RhcmdldElkfSBzZW5kZXJVc2VySWQ6ICR7c3VpZH1gKTtcbiAgICBjb25zdCB7XG4gICAgICBtZWRpYVR5cGUsIGNhbGxJZCwgZXh0cmEsIHJvb21UeXBlLFxuICAgIH0gPSBjb250ZW50IGFzIElJbnZpdGVNc2dDb250ZW50O1xuICAgIGxldCBzZW5kZXJVc2VySWQ6IHN0cmluZztcbiAgICBpZiAocm9vbVR5cGUgIT09IFJDQ3Jvc3NDYWxsVHlwZS5SQ0NhbGxSb29tVHlwZUFjcm9zc0NhbGwpIHtcbiAgICAgIHNlbmRlclVzZXJJZCA9IHN1aWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIFssIHNlbmRlclVzZXJJZF0gPSBzdWlkLnNwbGl0KCdfJyk7XG4gICAgfVxuICAgIGNvbnN0IGNydFVzZXJJZCA9IHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCk7XG4gICAgaWYgKHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudElkKCkgPT09IHNlbmRlclVzZXJJZCkgeyAvLyDlpJrnq6/lpITnkIZcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDnvqTogYrpgJror53mnInlhbbku5bnq6/lpITnkIbml7bvvIzkuI3lho3lpITnkIbmraTpgJror53kuK3nmoTpgoDor7fmtojmga9cbiAgICAgKiDmnaHku7YxOiDmraTkurrlt7LooqvpgoDor7fpgJror51cbiAgICAgKiDmnaHku7YyOiDmnKznq6/ml6DmraTpgJror53nmoTnirbmgIHmnLpcbiAgICAgKi9cbiAgICBpZiAobWVzc2FnZVR5cGUgPT09IFJDQ2FsbE1lc3NhZ2VUeXBlLlZDTW9kaWZ5TWVtKSB7XG4gICAgICBjb25zdCBpc0tlZXBpbmcgPSBjb250ZW50LmV4aXN0ZWRVc2VyUG9maWxlcy5zb21lKChpdGVtOiB7IHVzZXJJZDogc3RyaW5nIH0pID0+IChpdGVtLnVzZXJJZCA9PT0gY3J0VXNlcklkKSk7XG4gICAgICBpZiAoaXNLZWVwaW5nICYmICF0aGlzLl9zdGF0ZU1hY2hpbmVbY2FsbElkXSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdGVNYWNoaW5lID0gdGhpcy5fc3RhdGVNYWNoaW5lW2NhbGxJZF07XG4gICAgaWYgKCFzdGF0ZU1hY2hpbmUpIHtcbiAgICAgIHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdID0gbmV3IFJDQ2FsbFN0YXRlTWFjaGluZShcbiAgICAgICAgdGhpcy5fY29udGV4dCxcbiAgICAgICAgdGhpcy5fcnVudGltZSxcbiAgICAgICAgdGhpcy5fbG9nZ2VyLFxuICAgICAgICB0aGlzLl9jYWxsTXNnSGFuZGxlcixcbiAgICAgICAgY2hhbm5lbElkISxcbiAgICAgICAgY29udmVyc2F0aW9uVHlwZSxcbiAgICAgICAgdGFyZ2V0SWQsXG4gICAgICAgIG1lZGlhVHlwZSxcbiAgICAgICAgY2FsbElkLFxuICAgICAgKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxFbmdpbmVdIFJDQ2FsbFN0YXRlTWFjaGluZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCAtPiBjYWxsSWQ6ICR7Y2FsbElkfWApO1xuXG4gICAgICBpZiAobWVzc2FnZVR5cGUgPT09IFJDQ2FsbE1lc3NhZ2VUeXBlLlZDSW52aXRlKSB7XG4gICAgICAgIC8vIOeKtuaAgeacuuWGhemDqOWkhOeQhiBpbnZpdGUg5raI5oGvXG4gICAgICAgIHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdLl9fb25JbnZpdGUobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAobWVzc2FnZVR5cGUgPT09IFJDQ2FsbE1lc3NhZ2VUeXBlLlZDTW9kaWZ5TWVtKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdLl9fb25NZW1iZXJNb2RpZnkobXNnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3dhdGNoZXJzLm9uSW52aXRlKHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdLCBleHRyYSk7XG5cbiAgICAgIGNvbnN0IGhhc090aGVyU3RhdGVNYWNoaW5lID0gT2JqZWN0LmtleXModGhpcy5fc3RhdGVNYWNoaW5lKS5maWx0ZXIoKG90aGVyQ2FsbElkKSA9PiBjYWxsSWQgIT09IG90aGVyQ2FsbElkKS5sZW5ndGggPiAwO1xuICAgICAgaWYgKGhhc090aGVyU3RhdGVNYWNoaW5lICYmICEodGhpcy5fb3B0aW9ucy5pc0FsbG93QWNjZXB0TmV3Q2FsbCB8fCBmYWxzZSkpIHtcbiAgICAgICAgdGhpcy5fc3RhdGVNYWNoaW5lW2NhbGxJZF0uX19oYW5kbGVJbnZpdGVJblNlc3Npb24oKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG1lc3NhZ2VUeXBlID09PSBSQ0NhbGxNZXNzYWdlVHlwZS5WQ01vZGlmeU1lbSkge1xuICAgICAgdGhpcy5fc3RhdGVNYWNoaW5lW2NhbGxJZF0uX19vbk1lbWJlck1vZGlmeShtc2cpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDlhYHorrjmjqXlkKzmlrDnmoTpgJror53ml7bvvIzmjqXlkKzlrozmlrDnmoTpgJror53lkI7vvIzmjILmlq3lhbbku5bpgJror51cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZVNlbmRBY2NlcHQoaW5mbzogeyBjYWxsSWQ6IHN0cmluZyB9KSB7XG4gICAgaWYgKHRoaXMuX29wdGlvbnMuaXNBbGxvd0FjY2VwdE5ld0NhbGwpIHtcbiAgICAgIGNvbnN0IHsgY2FsbElkIH0gPSBpbmZvO1xuICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLl9zdGF0ZU1hY2hpbmUpIHtcbiAgICAgICAgaWYgKGNhbGxJZCAhPT0gaWQpIHtcbiAgICAgICAgICB0aGlzLl9zdGF0ZU1hY2hpbmVbaWRdLmh1bmd1cCgpO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zdGF0ZU1hY2hpbmVbaWRdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOagueaNriBjYWxsSWQg6I635Y+W54q25oCB5py6XG4gICovXG4gIHByaXZhdGUgX2dldFN0YXRlTWFjaGluZShjYWxsSWQ6IHN0cmluZyk6IFJDQ2FsbFN0YXRlTWFjaGluZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmVbY2FsbElkXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDms6jlhoznlKjmiLfkv6Hmga8sIOWPkemAgSBjYWxsIOa2iOaBr+aXtueUqOaIt+S/oeaBr+aQuuW4plxuICAgKi9cbiAgcmVnaXN0ZXJVc2VySW5mbyh1c2VySW5mbzogSVVzZXJQcm9maWxlKSB7XG4gICAgdGhpcy5fbG9nZ2VyLmRlYnVnKCdfJywgYFtSQ0NhbGxFbmdpbmVdIHJlZ2lzdGVyVXNlckluZm8gLT4gdXNlckluZm86ICR7SlNPTi5zdHJpbmdpZnkodXNlckluZm8pfWApO1xuXG4gICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIucmVnaXN0ZXJVc2VySW5mbyh1c2VySW5mbyk7XG4gIH1cblxuICAvKipcbiAgICog5Y2V5ZG8XG4gICAqIEBwYXJhbSBjaGFubmVsSWQg57uE57uHIElEXG4gICAqIEBwYXJhbSB0YXJnZXRJZCAg5a+55pa5IElEXG4gICAqIEBwYXJhbSBtZWRpYVR5cGUg5aqS5L2T57G75Z6LXG4gICAqIEBwYXJhbSBleHRyYSDmtojmga/mianlsZXkv6Hmga9cbiAgICogQHBhcmFtIHB1c2hDb25maWcg5o6o6YCB6YWN572uXG4gICAqL1xuICBhc3luYyBjYWxsKFxuICAgIGNoYW5uZWxJZDogc3RyaW5nLFxuICAgIHRhcmdldElkOiBzdHJpbmcsXG4gICAgbWVkaWFUeXBlOiBudW1iZXIsXG4gICAgZXh0cmE6IHN0cmluZyA9ICcnLFxuICAgIHB1c2hDb25maWc6IElQdXNoQ29uZmlnLFxuICAgIGlzQ3Jvc3NBcHBrZXkgPSBmYWxzZSxcbiAgKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgc3RhdGVNYWNoaW5lPzogUkNDYWxsU3RhdGVNYWNoaW5lIH0+IHtcbiAgICB0aGlzLl9sb2dnZXIuZGVidWcoJ18nLCBgW1JDQ2FsbEVuZ2luZV0gY2FsbCAtPiBhcmdzOiAke0pTT04uc3RyaW5naWZ5KHtcbiAgICAgIGNoYW5uZWxJZCwgdGFyZ2V0SWQsIG1lZGlhVHlwZSwgZXh0cmEsIHB1c2hDb25maWcsXG4gICAgfSl9YCk7XG4gICAgY29uc3QgY2FsbElkID0gZ2VuZXJhdGVSYW5kb21JZCgpO1xuICAgIGNvbnN0IGhhc1N0YXRlTWFjaGluZSA9IE9iamVjdC5rZXlzKHRoaXMuX3N0YXRlTWFjaGluZSkubGVuZ3RoID4gMDtcbiAgICBpZiAoaGFzU3RhdGVNYWNoaW5lKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1RBVEVfTUFDSElORV9FWElUIH07XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdID0gbmV3IFJDQ2FsbFN0YXRlTWFjaGluZShcbiAgICAgIHRoaXMuX2NvbnRleHQsXG4gICAgICB0aGlzLl9ydW50aW1lLFxuICAgICAgdGhpcy5fbG9nZ2VyLFxuICAgICAgdGhpcy5fY2FsbE1zZ0hhbmRsZXIsXG4gICAgICBjaGFubmVsSWQsXG4gICAgICBDb252ZXJzYXRpb25UeXBlLlBSSVZBVEUsXG4gICAgICB0YXJnZXRJZCxcbiAgICAgIG1lZGlhVHlwZSxcbiAgICAgIGNhbGxJZCxcbiAgICApO1xuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fc3RhdGVNYWNoaW5lW2NhbGxJZF0uX19jYWxsKFt0YXJnZXRJZF0sIGV4dHJhLCBwdXNoQ29uZmlnLCBpc0Nyb3NzQXBwa2V5KTtcbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLFxuICAgICAgICBzdGF0ZU1hY2hpbmU6IHRoaXMuX3N0YXRlTWFjaGluZVtjYWxsSWRdLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOe+pOWRvFxuICAgKiBAcGFyYW0gY2hhbm5lbElkIOe7hOe7hyBJRFxuICAgKiBAcGFyYW0gdGFyZ2V0SWQgIOe+pOe7hCBJRFxuICAgKiBAcGFyYW0gbWVkaWFUeXBlIOWqkuS9k+exu+Wei1xuICAgKiBAcGFyYW0gdXNlcklkcyDooqvpgoDor7fkurrlkZjliJfooahcbiAgICogQHBhcmFtIGV4dHJhIOa2iOaBr+aJqeWxleS/oeaBr1xuICAgKiBAcGFyYW0gcHVzaENvbmZpZyDmjqjpgIHphY3nva5cbiAgICovXG4gIGFzeW5jIGNhbGxJbkdyb3VwKFxuICAgIGNoYW5uZWxJZDogc3RyaW5nLFxuICAgIHRhcmdldElkOiBzdHJpbmcsXG4gICAgbWVkaWFUeXBlOiBudW1iZXIsXG4gICAgdXNlcklkczogc3RyaW5nW10sXG4gICAgZXh0cmE6IHN0cmluZyA9ICcnLFxuICAgIHB1c2hDb25maWc6IElQdXNoQ29uZmlnLFxuICApOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLCBzdGF0ZU1hY2hpbmU/OiBSQ0NhbGxTdGF0ZU1hY2hpbmUgfT4ge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsIGBbUkNDYWxsRW5naW5lXSBjYWxsSW5Hcm91cCAtPiBhcmdzOiAke0pTT04uc3RyaW5naWZ5KHsgY2hhbm5lbElkLCB0YXJnZXRJZCwgbWVkaWFUeXBlIH0pfWApO1xuICAgIGNvbnN0IGNhbGxJZCA9IGdlbmVyYXRlUmFuZG9tSWQoKTtcbiAgICBjb25zdCBoYXNTdGF0ZU1hY2hpbmUgPSBPYmplY3Qua2V5cyh0aGlzLl9zdGF0ZU1hY2hpbmUpLmxlbmd0aCA+IDA7XG4gICAgaWYgKGhhc1N0YXRlTWFjaGluZSkge1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLlNUQVRFX01BQ0hJTkVfRVhJVCB9O1xuICAgIH1cbiAgICB0aGlzLl9zdGF0ZU1hY2hpbmVbY2FsbElkXSA9IG5ldyBSQ0NhbGxTdGF0ZU1hY2hpbmUoXG4gICAgICB0aGlzLl9jb250ZXh0LFxuICAgICAgdGhpcy5fcnVudGltZSxcbiAgICAgIHRoaXMuX2xvZ2dlcixcbiAgICAgIHRoaXMuX2NhbGxNc2dIYW5kbGVyLFxuICAgICAgY2hhbm5lbElkLFxuICAgICAgQ29udmVyc2F0aW9uVHlwZS5HUk9VUCxcbiAgICAgIHRhcmdldElkLFxuICAgICAgbWVkaWFUeXBlLFxuICAgICAgY2FsbElkLFxuICAgICk7XG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9zdGF0ZU1hY2hpbmVbY2FsbElkXS5fX2NhbGwodXNlcklkcywgZXh0cmEsIHB1c2hDb25maWcpO1xuICAgIGlmIChjb2RlID09PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MsXG4gICAgICAgIHN0YXRlTWFjaGluZTogdGhpcy5fc3RhdGVNYWNoaW5lW2NhbGxJZF0sXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog6ZSA5q+B5b2T5YmN55qE54q25oCB5py6XG4gICAqL1xuICBkZXN0cm95KCkge1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygnXycsICdbUkNDYWxsRW5naW5lXSBkZXN0cm95Jyk7XG4gICAgdGhpcy5fc3RhdGVNYWNoaW5lID0ge307XG4gIH1cbn1cblxuZXhwb3J0IHtcbiAgUkNDYWxsRW5naW5lLFxuICBSQ0NhbGxTdGF0ZU1hY2hpbmUsIFJDQ2FsbEVycm9yQ29kZSxcbiAgUkNDYWxsVXNlclN0YXRlLFxuICBSQ0NhbGxTZXNzaW9uU3RhdGUsXG4gIFJDQ2FsbEVuZFJlYXNvbixcbiAgUkNDYWxsTWVkaWFUeXBlLFxuICBSQ0NhbGxMYW5ndWFnZSxcbn07XG5cbmV4cG9ydCB0eXBlIHtcbiAgSUNhbGxTdGF0ZU1hY2hpbmVXYXRjaGVycywgSUVuZFN1bW1hcnksXG4gIElDYWxsRW5naW5lV2F0Y2hlcnMsXG4gIElVc2VyU3RhdGVDaGFuZ2VJbmZvLFxuICBJU3RhdGVDaGFuZ2VJbmZvLFxuICBJU2VuZGVySW5mbyxcbiAgSU1lbWJlck1vZGlmeUluZm8sXG4gIElNZWRpYU1vZGlmeUluZm8sXG4gIElJbnZpdGVkVXNlcnMsXG4gIElVc2VyRGF0YSxcbiAgSVVzZXJQcm9maWxlLFxuICBJT2ZmbGluZVJlY29yZCxcbiAgSUludml0ZU9wdGlvbnMsXG59O1xuIiwiLyoqXG4gKiDkuqfnlJ9zZXNzaW9u55qE5Zy65pmvXG4gKi9cbmV4cG9ydCBlbnVtIFByb2R1Y2VUeXBlcyB7XG4gIC8qKlxuICAgKiDkuLvlj6tcbiAgICovXG4gIENBTExFUiA9IDEsXG5cbiAgLyoqXG4gICAqIOiiq+WPq1xuICAgKi9cbiAgQ0FMTEVFID0gMlxufVxuIiwiY2xhc3MgRXZlbnRFbWl0dGVyIHtcbiAgcHJpdmF0ZSBsaXN0OiB7W3Byb3BOYW1lOiBzdHJpbmddOiBhbnlbXX0gPSB7fVxuXG4gIHB1YmxpYyBvbihldmVudDogc3RyaW5nLCBmdW46KGRhdGE/OmFueSk9PnZvaWQpIHtcbiAgICAodGhpcy5saXN0W2V2ZW50XSB8fCAodGhpcy5saXN0W2V2ZW50XSA9IFtdKSkucHVzaChmdW4pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIG9uY2UoZXZlbnQ6IHN0cmluZywgZnVuOihkYXRhPzphbnkpPT52b2lkKSB7XG4gICAgY29uc3Qgb24gPSAoZGF0YT86YW55KSA9PiB7XG4gICAgICB0aGlzLm9mZihldmVudCwgb24pO1xuICAgICAgZnVuLmNhbGwodGhpcywgZGF0YSk7XG4gICAgfTtcbiAgICBvbi5mdW4gPSBmdW47XG4gICAgdGhpcy5vbihldmVudCwgb24pO1xuICB9XG5cbiAgcHVibGljIG9mZihldmVudDogc3RyaW5nLCBmdW4/OihkYXRhPzphbnkpPT52b2lkKSB7XG4gICAgY29uc3QgZnVucyA9IHRoaXMubGlzdFtldmVudF07XG4gICAgaWYgKCFmdW5zKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghZnVuKSB7XG4gICAgICAvLyDlpoLmnpzmsqHmnInkvKAgZm4g55qE6K+d77yM5bCx5Lya5bCGIGV2ZW50IOWAvOWvueW6lOe8k+WtmOWIl+ihqOS4reeahCBmdW4g6YO95riF56m6XG4gICAgICBmdW5zICYmIChmdW5zLmxlbmd0aCA9IDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDoi6XmnIkgZnVu77yM6YGN5Y6G57yT5a2Y5YiX6KGo77yM55yL55yL5Lyg5YWl55qEIGZuIOS4juWTquS4quWHveaVsOebuOWQjO+8jOWmguaenOebuOWQjOWwseebtOaOpeS7jue8k+WtmOWIl+ihqOS4reWIoOaOieWNs+WPr1xuICAgICAgbGV0IGNiO1xuICAgICAgZm9yIChsZXQgaSA9IDAsIHsgbGVuZ3RoIH0gPSBmdW5zOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY2IgPSBmdW5zW2ldO1xuICAgICAgICBpZiAoY2IgPT09IGZ1biB8fCBjYi5mdW4gPT09IGZ1bikge1xuICAgICAgICAgIGZ1bnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGVtaXQoZXZlbnQ6IHN0cmluZywgZGF0YT86YW55KSB7XG4gICAgLy8g56ys5LiA5Liq5Y+C5pWw5piv5a+55bqU55qEIGV2ZW50IOWAvO+8jOebtOaOpeeUqOaVsOe7hOeahCBzaGlmdCDmlrnms5Xlj5blh7pcbiAgICBjb25zdCBmdW5zID0gWy4uLnRoaXMubGlzdFtldmVudF1dO1xuXG4gICAgLy8g5aaC5p6c57yT5a2Y5YiX6KGo6YeM5rKh5pyJIGZ1biDlsLHov5Tlm54gZmFsc2VcbiAgICBpZiAoIWZ1bnMgfHwgZnVucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8g6YGN5Y6GIGV2ZW50IOWAvOWvueW6lOeahOe8k+WtmOWIl+ihqO+8jOS+neasoeaJp+ihjCBmblxuICAgIGZ1bnMuZm9yRWFjaCgoZnVuKSA9PiB7XG4gICAgICBmdW4uY2FsbCh0aGlzLCBkYXRhKTtcbiAgICB9KTtcbiAgfVxufVxuZXhwb3J0IHtcbiAgRXZlbnRFbWl0dGVyLFxufTtcbiIsImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBuZXcgRXZlbnRFbWl0dGVyKCk7XG4iLCJpbXBvcnQge1xuICBSVENKb2luVHlwZSwgTG9nTCwgaXNVbmRlZmluZWQsIGlzQm9vbGVhbiwgaXNTdHJpbmcsIElpT1NQdXNoQ29uZmlnLFxufSBmcm9tICdAcm9uZ2Nsb3VkL2VuZ2luZSc7XG5pbXBvcnQgeyBSQ0NhbGxFcnJvckNvZGUsIFJDQ2FsbExhbmd1YWdlLCBSQ0NhbGxNZWRpYVR5cGUgfSBmcm9tICdAcmMtZW1iZWQvY2FsbC1lbmdpbmUnO1xuaW1wb3J0IHsgUkNSZXNvbHV0aW9uIH0gZnJvbSAnQHJvbmdjbG91ZC9wbHVnaW4tcnRjJztcblxuaW1wb3J0IHtcbiAgSVNlc3Npb25MaXN0ZW5lciwgSVJDQ2FsbEluaXRPcHRpb25zLCBJVmFsaWRhdGlvblJlc3VsdCwgSU1lZGlhU3RyZWFtQ29uc3RyYWludHMsIElQdXNoQ29uZmlnLFxufSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmZ1bmN0aW9uIGlzTGFuZ3VhZ2UodmFsOiBzdHJpbmcpIHtcbiAgY29uc3QgdmFsdWVzOiBzdHJpbmdbXSA9IE9iamVjdC52YWx1ZXMoUkNDYWxsTGFuZ3VhZ2UpO1xuICByZXR1cm4gdmFsdWVzLmluY2x1ZGVzKHZhbCk7XG59XG5cbmZ1bmN0aW9uIGlzSm9pblR5cGUodmFsOiBudW1iZXIpIHtcbiAgY29uc3QgdmFsdWVzID0gT2JqZWN0LnZhbHVlcyhSVENKb2luVHlwZSkgYXMgbnVtYmVyW107XG4gIHJldHVybiB2YWx1ZXMuaW5jbHVkZXModmFsKTtcbn1cblxuZnVuY3Rpb24gaXNMb2dMZXZlbCh2YWw6IG51bWJlcikge1xuICByZXR1cm4gW0xvZ0wuREVCVUcsIExvZ0wuSU5GTywgTG9nTC5XQVJOLCBMb2dMLkVSUk9SXS5pbmNsdWRlcyh2YWwpO1xufVxuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVDYWxsSW5pdE9wdGlvbnMgPSAob3B0aW9uczogSVJDQ2FsbEluaXRPcHRpb25zKTogSVZhbGlkYXRpb25SZXN1bHQgPT4ge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBtaXNzaW5nIHBhcmFtZXRlciAtPiBvcHRpb25zJyB9O1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0JyB9O1xuICB9XG4gIGNvbnN0IGtleU5hbWVzOiBzdHJpbmdbXSA9IFsncnRjQ2xpZW50JywgJ29uU2Vzc2lvbicsICdvblNlc3Npb25DbG9zZSddO1xuICBjb25zdCBrZXlzOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKG9wdGlvbnMpO1xuICBjb25zdCBtaXNzaW5nS2V5czogc3RyaW5nW10gPSBbXTtcblxuICAvLyDmoKHpqozloavpobnmmK/lkKbpg73ljIXlkKvvvIzlpoLmnpzlk6rkuKrkuI3ljIXlkKvlsLHmlLbpm4botbfmnaVcbiAga2V5TmFtZXMuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgbWlzc2luZ0tleXMucHVzaChrZXkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8g5aaC5p6c57y65bCR5b+F5aGr55qE55uR5ZCs5Ye95pWw5oiW5a+56LGhXG4gIGlmIChtaXNzaW5nS2V5cy5sZW5ndGgpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6IGBJbml0aWFsaXphdGlvbiBtaXNzaW5nIHBhcmFtZXRlciAtPiBcIiR7bWlzc2luZ0tleXMuam9pbignLCcpfVwiYCB9O1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5ydGNDbGllbnQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gXFwncnRjQ2xpZW50XFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnb2JqZWN0XFwnJyB9O1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5vblNlc3Npb24gIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBcXCdvblNlc3Npb25cXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdmdW5jdGlvblxcJycgfTtcbiAgfVxuICBpZiAodHlwZW9mIG9wdGlvbnMub25TZXNzaW9uQ2xvc2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBcXCdvblNlc3Npb25DbG9zZVxcJyBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIFxcJ2Z1bmN0aW9uXFwnJyB9O1xuICB9XG5cbiAgLy8g5aaC5p6c5Lyg5LqGaXNBbGxvd1N1YnNjcmliZVJldHJ5IOS9huS4jeaYr2Jvb2xlYW7nsbvlnotcbiAgaWYgKHR5cGVvZiBvcHRpb25zLmlzQWxsb3dTdWJzY3JpYmVSZXRyeSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdGlvbnMuaXNBbGxvd1N1YnNjcmliZVJldHJ5ICE9PSAnYm9vbGVhbicpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdJbml0aWFsaXphdGlvbiBcXCdpc0FsbG93U3Vic2NyaWJlUmV0cnlcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdib29sZWFuXFwnJyB9O1xuICB9XG5cbiAgLy8g5aaC5p6c5Lyg5LqG77yM5L2G5LiN5pivYm9vbGVhbuexu+Wei1xuICBpZiAodHlwZW9mIG9wdGlvbnMuaXNBbGxvd1B1Ymxpc2hSZXRyeSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdGlvbnMuaXNBbGxvd1B1Ymxpc2hSZXRyeSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gXFwnaXNBbGxvd1B1Ymxpc2hSZXRyeVxcJyBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIFxcJ2Jvb2xlYW5cXCcnIH07XG4gIH1cblxuICAvLyDlpoLmnpzkvKDkuobvvIzkvYbkuI3mmK9ib29sZWFu57G75Z6LXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5pc09mZkNhbWVyYVdoZW5WaWRlb0Rpc2FibGUgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRpb25zLmlzT2ZmQ2FtZXJhV2hlblZpZGVvRGlzYWJsZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gXFwnaXNPZmZDYW1lcmFXaGVuVmlkZW9EaXNhYmxlXFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnYm9vbGVhblxcJycgfTtcbiAgfVxuXG4gIC8vIOWmguaenOS8oOS6hu+8jOS9huS4jeaYr1JUQ0pvaW5UeXBl55qE5p6a5Li+XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5qb2luVHlwZSAhPT0gJ3VuZGVmaW5lZCcgJiYgIWlzSm9pblR5cGUob3B0aW9ucy5qb2luVHlwZSEpKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gXFwnam9pblR5cGVcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBjb3JyZWN0IHR5cGUnIH07XG4gIH1cblxuICAvLyDlpoLmnpzkvKDkuobvvIzkvYbkuI3mmK9ib29sZWFu57G75Z6LXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5pc0FsbG93RGVtb3Rpb25HZXRTdHJlYW0gIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRpb25zLmlzQWxsb3dEZW1vdGlvbkdldFN0cmVhbSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnSW5pdGlhbGl6YXRpb24gXFwnaXNBbGxvd0RlbW90aW9uR2V0U3RyZWFtXFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnYm9vbGVhblxcJycgfTtcbiAgfVxuXG4gIC8vIOWmguaenOS8oOS6hu+8jOS9huS4jeaYr1JDQ2FsbExhbmd1YWdl55qE5p6a5Li+XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5sYW5nICE9PSAndW5kZWZpbmVkJyAmJiAhaXNMYW5ndWFnZShvcHRpb25zLmxhbmchKSkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ0luaXRpYWxpemF0aW9uIFxcJ2xhbmdcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBjb3JyZWN0IHR5cGUnIH07XG4gIH1cblxuICBpZiAodHlwZW9mIG9wdGlvbnMubG9nT3V0cHV0TGV2ZWwgIT09ICd1bmRlZmluZWQnICYmICFpc0xvZ0xldmVsKG9wdGlvbnMubG9nT3V0cHV0TGV2ZWwhKSkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ0luaXRpYWxpemF0aW9uIFxcJ2xvZ091dHB1dExldmVsXFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgY29ycmVjdCB0eXBlJyB9O1xuICB9XG4gIHJldHVybiB7IHJlc3VsdDogdHJ1ZSB9O1xufTtcblxuLyoqXG4gKiDmoKHpqoxyZWdpc3RlclNlc3Npb25MaXN0ZW5lcuWPguaVsFxuICovXG5leHBvcnQgY29uc3QgdmFsaWRhdGVMaXN0ZW5lciA9IChsaXN0ZW5lcjogSVNlc3Npb25MaXN0ZW5lcik6IElWYWxpZGF0aW9uUmVzdWx0ID0+IHtcbiAgaWYgKCFsaXN0ZW5lcikge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ21pc3NpbmcgcGFyYW1ldGVyIC0+IGxpc3RlbmVyJyB9O1xuICB9XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnbGlzdGVuZXIgbXVzdCBiZSBhbiBvYmplY3QnIH07XG4gIH1cbiAgY29uc3Qga2V5TmFtZXM6IHN0cmluZ1tdID0gWydvblJpbmdpbmcnLCAnb25BY2NlcHQnLCAnb25IdW5ndXAnLCAnb25UcmFja1JlYWR5J107XG4gIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gT2JqZWN0LmtleXMobGlzdGVuZXIpO1xuICBjb25zdCBtaXNzaW5nS2V5czogc3RyaW5nW10gPSBbXTtcbiAga2V5TmFtZXMuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgbWlzc2luZ0tleXMucHVzaChrZXkpO1xuICAgIH1cbiAgfSk7XG4gIGlmIChtaXNzaW5nS2V5cy5sZW5ndGgpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6IGBtaXNzaW5nIHBhcmFtZXRlciAtPiBcIiR7bWlzc2luZ0tleXMuam9pbignLCcpfVwiYCB9O1xuICB9XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIub25SaW5naW5nICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnXFwnb25SaW5naW5nXFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnZnVuY3Rpb25cXCcnIH07XG4gIH1cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lci5vbkFjY2VwdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ29uQWNjZXB0XFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnZnVuY3Rpb25cXCcnIH07XG4gIH1cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lci5vbkh1bmd1cCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ29uSHVuZ3VwXFwnIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgXFwnZnVuY3Rpb25cXCcnIH07XG4gIH1cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lci5vblRyYWNrUmVhZHkgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdvblRyYWNrUmVhZHlcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdmdW5jdGlvblxcJycgfTtcbiAgfVxuICByZXR1cm4geyByZXN1bHQ6IHRydWUgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVRhcmdldElkID0gKHRhcmdldElkOiBzdHJpbmcpOiBJVmFsaWRhdGlvblJlc3VsdCA9PiB7XG4gIGlmICh0YXJnZXRJZCAmJiB0eXBlb2YgdGFyZ2V0SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiB0cnVlIH07XG4gIH1cbiAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnXFwndGFyZ2V0SWRcXCcgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLCBtdXN0IGJlIG9mIHR5cGUgXFwnc3RyaW5nXFwnJyB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHZhbGlkYXRlTWVkaWFUeXBlID0gKG1lZGlhVHlwZTogbnVtYmVyKTogSVZhbGlkYXRpb25SZXN1bHQgPT4ge1xuICBpZiAobWVkaWFUeXBlID09PSBSQ0NhbGxNZWRpYVR5cGUuQVVESU8gfHwgbWVkaWFUeXBlID09PSBSQ0NhbGxNZWRpYVR5cGUuQVVESU9fVklERU8pIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IHRydWUgfTtcbiAgfVxuICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdtZWRpYVR5cGVcXCcgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLCBtdXN0IGJlIG9mIHR5cGUgXFwnUkNDYWxsTWVkaWFUeXBlXFwnJyB9O1xufTtcbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUV4dHJhID0gKGV4dHJhOiBzdHJpbmcpOiBJVmFsaWRhdGlvblJlc3VsdCA9PiB7XG4gIGlmICh0eXBlb2YgZXh0cmEgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiB0cnVlIH07XG4gIH1cbiAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnXFwnZXh0cmFcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdzdHJpbmdcXCcnIH07XG59O1xuZXhwb3J0IGNvbnN0IHZhbGlkYXRlUHVzaFRpdGxlID0gKHB1c2hUaXRsZTogc3RyaW5nKTogSVZhbGlkYXRpb25SZXN1bHQgPT4ge1xuICBpZiAodHlwZW9mIHB1c2hUaXRsZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IHRydWUgfTtcbiAgfVxuICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdwdXNoVGl0bGVcXCcgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBcXCdzdHJpbmdcXCcnIH07XG59O1xuZXhwb3J0IGNvbnN0IHZhbGlkYXRlUHVzaENvbnRlbnQgPSAocHVzaENvbnRlbnQ6IHN0cmluZyk6IElWYWxpZGF0aW9uUmVzdWx0ID0+IHtcbiAgaWYgKHR5cGVvZiBwdXNoQ29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IHRydWUgfTtcbiAgfVxuICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdwdXNoQ29udGVudFxcJyBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIFxcJ3N0cmluZ1xcJycgfTtcbn07XG5cbi8qKlxuICog5qCh6aqMIHB1c2hDb25maWdcbiAqL1xuZXhwb3J0IGNvbnN0IHZhbGlkYXRlUHVzaENvbmZpZyA9IChwdXNoQ29uZmlnOiBJUHVzaENvbmZpZykgPT4ge1xuICBjb25zdCBwdXNoQ29uZmlnS2V5cyA9IFsncHVzaFRpdGxlJywgJ3B1c2hDb250ZW50JywgJ3B1c2hEYXRhJywgJ2lPU0NvbmZpZycsICdhbmRyb2lkQ29uZmlnJywgJ2Rpc2FibGVQdXNoVGl0bGUnLCAndGVtcGxhdGVJZCddO1xuICBjb25zdCBrZXlJc1JpZ2h0ID0gT2JqZWN0LmtleXMocHVzaENvbmZpZykuZXZlcnkoKGtleSkgPT4gcHVzaENvbmZpZ0tleXMuaW5jbHVkZXMoa2V5KSk7XG4gIGlmICgha2V5SXNSaWdodCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUEFSQU1fRVJST1IsXG4gICAgICBlcnJvck1zZzogYHJpZ2h0IGtleTogJHtwdXNoQ29uZmlnS2V5cy5qb2luKCcsJyl9YCxcbiAgICB9O1xuICB9XG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHB1c2hDb25maWdLZXlzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgIGNvbnN0IGtleSA9IHB1c2hDb25maWdLZXlzW2luZGV4XTtcbiAgICAvKipcbiAgICAgKiDmoKHpqowgYm9vbGVhbiDnsbvlnotcbiAgICAgKi9cbiAgICBpZiAoa2V5ID09PSAnZGlzYWJsZVB1c2hUaXRsZScpIHtcbiAgICAgIGlmICghaXNVbmRlZmluZWQocHVzaENvbmZpZ1trZXldKSAmJiAhaXNCb29sZWFuKHB1c2hDb25maWdba2V5XSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUEFSQU1fRVJST1IsXG4gICAgICAgICAgZXJyb3JNc2c6IGAke2tleX0gdHlwZSBpcyBib29sZWFuYCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ3B1c2hUaXRsZSdcbiAgICAgIHx8IGtleSA9PT0gJ3RlbXBsYXRlSWQnKSB7XG4gICAgICAvKipcbiAgICAgICAqIOagoemqjCBzdHJpbmcg57G75Z6LXG4gICAgICAgKi9cbiAgICAgIGlmIChwdXNoQ29uZmlnW2tleV0gJiYgIWlzU3RyaW5nKHB1c2hDb25maWdba2V5XSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUEFSQU1fRVJST1IsXG4gICAgICAgICAgZXJyb3JNc2c6IGAke2tleX0gdHlwZSBpcyBzdHJpbmdgLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB7IGlPU0NvbmZpZywgYW5kcm9pZENvbmZpZyB9ID0gcHVzaENvbmZpZztcblxuICAvKipcbiAgICog5qCh6aqMIGlPU0NvbmZpZ1xuICAgKi9cbiAgY29uc3QgdmFsaWRhdGVJT1NDb25maWdSZXMgPSB2YWxpZGF0ZUlPU0NvbmZpZyhpT1NDb25maWcgfHwge30pO1xuICBpZiAodmFsaWRhdGVJT1NDb25maWdSZXMuY29kZSAhPT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICByZXR1cm4gdmFsaWRhdGVJT1NDb25maWdSZXM7XG4gIH1cblxuICAvKipcbiAgICog5qCh6aqMIGFuZHJvaWRDb25maWdcbiAgICovXG4gIGNvbnN0IHZhbGlkYXRlQW5kcm9pZENvbmZpZ1JlcyA9IHZhbGlkYXRlQW5kcm9pZENvbmZpZyhhbmRyb2lkQ29uZmlnIHx8IHt9KTtcbiAgaWYgKHZhbGlkYXRlQW5kcm9pZENvbmZpZ1Jlcy5jb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgIHJldHVybiB2YWxpZGF0ZUFuZHJvaWRDb25maWdSZXM7XG4gIH1cblxuICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUyB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJT1NDb25maWcgPSAoaU9TQ29uZmlnOiBJaU9TUHVzaENvbmZpZykgPT4ge1xuICBjb25zdCB7IHRocmVhZElkLCByaWNoTWVkaWFVcmkgfSA9IGlPU0NvbmZpZyB8fCB7fTtcbiAgaWYgKHRocmVhZElkICYmICFpc1N0cmluZyh0aHJlYWRJZCkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29kZTogUkNDYWxsRXJyb3JDb2RlLlBBUkFNX0VSUk9SLFxuICAgICAgZXJyb3JNc2c6ICdpT1NDb25maWcudGhyZWFkSWQgdHlwZSBpcyBzdHJpbmcnLFxuICAgIH07XG4gIH1cblxuICBpZiAocmljaE1lZGlhVXJpICYmICFpc1N0cmluZyhyaWNoTWVkaWFVcmkpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5QQVJBTV9FUlJPUixcbiAgICAgIGVycm9yTXNnOiAnaU9TQ29uZmlnLnJpY2hNZWRpYVVyaSB0eXBlIGlzIHN0cmluZycsXG4gICAgfTtcbiAgfVxuICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUyB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVBbmRyb2lkQ29uZmlnID0gKGFuZHJvaWRDb25maWc6IGFueSkgPT4ge1xuICBjb25zdCBhbmRyb2lkQ29uZmlnS2V5cyA9IFsnbm90aWZpY2F0aW9uSWQnLCAnY2hhbm5lbElkTWknLCAnbWlMYXJnZUljb25VcmwnLCAnY2hhbm5lbElkSFcnLCAnY2F0ZWdvcnlIVycsICdpbXBvcnRhbmNlSFcnLCAnaW1hZ2VVcmxIVycsICdjaGFubmVsSWRPUFBPJywgJ3R5cGVWaXZvJywgJ2NhdGVnb3J5Vml2bycsICdmY21DaGFubmVsSWQnLCAnZmNtQ29sbGFwc2VLZXknLCAnZmNtSW1hZ2VVcmwnLCAnaW1wb3J0YW5jZUhvbm9yJywgJ2ltYWdlVXJsSG9ub3InXTtcbiAgY29uc3Qga2V5SXNSaWdodCA9IE9iamVjdC5rZXlzKGFuZHJvaWRDb25maWcpLmV2ZXJ5KChrZXkpID0+IGFuZHJvaWRDb25maWdLZXlzLmluY2x1ZGVzKGtleSkpO1xuICBpZiAoIWtleUlzUmlnaHQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29kZTogUkNDYWxsRXJyb3JDb2RlLlBBUkFNX0VSUk9SLFxuICAgICAgZXJyb3JNc2c6IGByaWdodCBrZXk6ICR7YW5kcm9pZENvbmZpZ0tleXMuam9pbignLCcpfWAsXG4gICAgfTtcbiAgfVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBhbmRyb2lkQ29uZmlnS2V5cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBjb25zdCBrZXkgPSBhbmRyb2lkQ29uZmlnS2V5c1tpbmRleF07XG4gICAgaWYgKGtleSA9PT0gJ2ltcG9ydGFuY2VIVycgfHwga2V5ID09PSAnaW1wb3J0YW5jZUhvbm9yJykge1xuICAgICAgaWYgKGFuZHJvaWRDb25maWdba2V5XSAmJiBhbmRyb2lkQ29uZmlnW2tleV0gIT09ICdMT1cnICYmIGFuZHJvaWRDb25maWdba2V5XSAhPT0gJ05PUk1BTCcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUEFSQU1fRVJST1IsXG4gICAgICAgICAgZXJyb3JNc2c6IGBhbmRyb2lkQ29uZmlnLiR7a2V5fSB2YWx1ZSBpcyBOT1JNQUx8TE9XYCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGFuZHJvaWRDb25maWdba2V5XSAmJiAhaXNTdHJpbmcoYW5kcm9pZENvbmZpZ1trZXldKSkge1xuICAgICAgLyoqXG4gICAgICAgKiDmoKHpqowgc3RyaW5nIOexu+Wei1xuICAgICAgICovXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUEFSQU1fRVJST1IsXG4gICAgICAgIGVycm9yTXNnOiBgYW5kcm9pZENvbmZpZy4ke2tleX0gdHlwZSBpcyBzdHJpbmdgLFxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVVzZXJJZHMgPSAodXNlcklkczogc3RyaW5nW10pOiBJVmFsaWRhdGlvblJlc3VsdCA9PiB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh1c2VySWRzKSkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ3VzZXJJZHNcXCcgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLCBtdXN0IGJlIG9mIHR5cGUgXFwnc3RyaW5nW11cXCcnIH07XG4gIH1cbiAgaWYgKCF1c2VySWRzLmxlbmd0aCkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ3VzZXJJZHNcXCcgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLCBtdXN0IGJlIG9mIHR5cGUgXFwnc3RyaW5nW11cXCcnIH07XG4gIH1cbiAgaWYgKCF1c2VySWRzLmV2ZXJ5KChzdHIpID0+IHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnICYmIHN0ci5sZW5ndGggPiAwKSkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ3VzZXJJZHNcXCcgcGFyYW1ldGVyIGlzIHJlcXVpcmVkJyB9O1xuICB9XG4gIHJldHVybiB7IHJlc3VsdDogdHJ1ZSB9O1xufTtcblxuZnVuY3Rpb24gaXNSQ0ZyYW1lUmF0ZSh2YWw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBhcnJzID0gWydGUFNfMTAnLCAnRlBTXzE1JywgJ0ZQU18yNCcsICdGUFNfMzAnXTtcbiAgcmV0dXJuIGFycnMuaW5jbHVkZXModmFsKTtcbn1cblxuY29uc3QgaXNWYWxpZFJlc29sdXRpb24gPSAocmVzb2x1dGlvbj86IFJDUmVzb2x1dGlvbik6IGJvb2xlYW4gPT4gISFSQ1Jlc29sdXRpb25bcmVzb2x1dGlvbiFdO1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0gKGNvbnN0cmFpbnRzOiBJTWVkaWFTdHJlYW1Db25zdHJhaW50cyk6IElWYWxpZGF0aW9uUmVzdWx0ID0+IHtcbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLmF1ZGlvICYmIHR5cGVvZiBjb25zdHJhaW50cy5hdWRpby5taWNwaG9uZUlkICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29uc3RyYWludHMuYXVkaW8ubWljcGhvbmVJZCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdjb25zdHJhaW50cy5hdWRpby5taWNwaG9uZUlkXFwnIG11c3QgYmUgb2YgdHlwZSBcXCdzdHJpbmdcXCcnIH07XG4gIH1cbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLmF1ZGlvICYmIHR5cGVvZiBjb25zdHJhaW50cy5hdWRpby5zYW1wbGVSYXRlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29uc3RyYWludHMuYXVkaW8uc2FtcGxlUmF0ZSAhPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdjb25zdHJhaW50cy5hdWRpby5zYW1wbGVSYXRlXFwnIG11c3QgYmUgb2YgdHlwZSBcXCdudW1iZXJcXCcnIH07XG4gIH1cbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLnZpZGVvICYmIHR5cGVvZiBjb25zdHJhaW50cy52aWRlby5jYW1lcmFJZCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGNvbnN0cmFpbnRzLnZpZGVvLmNhbWVyYUlkICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ2NvbnN0cmFpbnRzLnZpZGVvLmNhbWVyYUlkXFwnIG11c3QgYmUgb2YgdHlwZSBcXCdzdHJpbmdcXCcnIH07XG4gIH1cbiAgLy8gaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLnZpZGVvICYmIHR5cGVvZiBjb25zdHJhaW50cy52aWRlby5mYWNlTW9kZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uc3RyYWludHMudmlkZW8uY2FtZXJhSWQgIT09ICd1c2VyJyAmJiBjb25zdHJhaW50cy52aWRlby5mYWNlTW9kZSAhPT0gJ2Vudmlyb25tZW50Jykge1xuICAvLyAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ2NvbnN0cmFpbnRzLnZpZGVvLmNhbWVyYUlkXFwnIG11c3QgYmUgIFxcJ3VzZXJcXCcgb3IgXFwnZW52aXJvbm1lbnRcXCcnIH1cbiAgLy8gfVxuXG4gIGlmIChjb25zdHJhaW50cyAmJiBjb25zdHJhaW50cy52aWRlbyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8uZnJhbWVSYXRlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8uZnJhbWVSYXRlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ2NvbnN0cmFpbnRzLnZpZGVvLmZyYW1lUmF0ZVxcJyBtdXN0IGJlIG9mIHR5cGUgXFwnc3RyaW5nXFwnJyB9O1xuICB9XG5cbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLnZpZGVvICYmIHR5cGVvZiBjb25zdHJhaW50cy52aWRlby5mcmFtZVJhdGUgIT09ICd1bmRlZmluZWQnICYmICFpc1JDRnJhbWVSYXRlKGNvbnN0cmFpbnRzLnZpZGVvLmZyYW1lUmF0ZSkpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdmcmFtZVJhdGVcXCcgdmFsdWUgaXMgb3V0IG9mIHJhbmdlJyB9O1xuICB9XG5cbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLnZpZGVvICYmIHR5cGVvZiBjb25zdHJhaW50cy52aWRlby5yZXNvbHV0aW9uICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8ucmVzb2x1dGlvbiAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCBtc2c6ICdcXCdjb25zdHJhaW50cy52aWRlby5mcmFtZVJhdGVcXCcgbXVzdCBiZSBvZiB0eXBlIFxcJ3N0cmluZ1xcJycgfTtcbiAgfVxuXG4gIGlmIChjb25zdHJhaW50cyAmJiBjb25zdHJhaW50cy52aWRlbyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8ucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgIWlzVmFsaWRSZXNvbHV0aW9uKGNvbnN0cmFpbnRzLnZpZGVvLnJlc29sdXRpb24pKSB7XG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgbXNnOiAnXFwncmVzb2x1dGlvblxcJyB2YWx1ZSBpcyBvdXQgb2YgcmFuZ2UnIH07XG4gIH1cbiAgaWYgKGNvbnN0cmFpbnRzICYmIGNvbnN0cmFpbnRzLnZpZGVvICYmICghY29uc3RyYWludHMudmlkZW8uZnJhbWVSYXRlIHx8ICFjb25zdHJhaW50cy52aWRlby5yZXNvbHV0aW9uKSkge1xuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIG1zZzogJ1xcJ3Jlc29sdXRpb25cXCcgYW5kIFxcJ3Jlc29sdXRpb25cXCcgaXMgcmVxdWlyZWQnIH07XG4gIH1cblxuICByZXR1cm4geyByZXN1bHQ6IHRydWUgfTtcbn07XG4iLCJleHBvcnQgY29uc3QgdGltZXJTZXRUaW1lb3V0ID0gKGZ1bmM6IEZ1bmN0aW9uLCB0aW1lb3V0OiBudW1iZXIpOiBudW1iZXIgPT4gc2V0VGltZW91dChmdW5jLCB0aW1lb3V0KSBhcyBudW1iZXI7XG4iLCJpbXBvcnQgeyB0aW1lclNldFRpbWVvdXQgfSBmcm9tICcuL2hlbHBlcic7XG5cbmV4cG9ydCBjbGFzcyBUaW1lciB7XG4gIHByaXZhdGUgX3RpbWVySWQ6IG51bWJlciA9IDBcblxuICBwcml2YXRlIF9zdGFydFRpbWU6IG51bWJlciA9IDBcblxuICBjb25zdHJ1Y3RvcihjYWxsYmFjazogRnVuY3Rpb24sIHRpbWVvdXQ6IG51bWJlcikge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgdGhpcy5fdGltZXJJZCA9IHRpbWVyU2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICB9LCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdGhpcy5fc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfVxuXG4gIHN0b3AoKToge1xuICAgIHN0YXJ0VGltZTogbnVtYmVyLFxuICAgIGVuZFRpbWU6IG51bWJlcixcbiAgICBkdXJhdGlvbjogbnVtYmVyXG4gICAgfSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVySWQpO1xuXG4gICAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gICAgbGV0IGR1cmF0aW9uID0gZW5kVGltZSAtIHRoaXMuX3N0YXJ0VGltZTtcbiAgICBpZiAodGhpcy5fc3RhcnRUaW1lID09PSAwKSB7XG4gICAgICBkdXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0VGltZTogdGhpcy5fc3RhcnRUaW1lLFxuICAgICAgZW5kVGltZSxcbiAgICAgIGR1cmF0aW9uLFxuICAgIH07XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl9zdGFydFRpbWUgPSAwO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb252ZXJzYXRpb25UeXBlLCBJTG9nZ2VyIH0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHtcbiAgSU1lZGlhTW9kaWZ5SW5mbyxcbiAgSU1lbWJlck1vZGlmeUluZm8sXG4gIElTZW5kZXJJbmZvLFxuICBJU3RhdGVDaGFuZ2VJbmZvLFxuICBJVXNlckRhdGEsXG4gIElVc2VyU3RhdGVDaGFuZ2VJbmZvLFxuICBJSW52aXRlT3B0aW9ucyxcbiAgUkNDYWxsRW5kUmVhc29uLFxuICBSQ0NhbGxFcnJvckNvZGUsXG4gIFJDQ2FsbE1lZGlhVHlwZSxcbiAgUkNDYWxsU2Vzc2lvblN0YXRlLFxuICBSQ0NhbGxTdGF0ZU1hY2hpbmUsXG4gIFJDQ2FsbFVzZXJTdGF0ZSxcbn0gZnJvbSAnQHJjLWVtYmVkL2NhbGwtZW5naW5lJztcbmltcG9ydCB7XG4gIElSQ1JUQ1N0YXRlUmVwb3J0LFxuICBSQ0tpY2tSZWFzb24sXG4gIFJDTG9jYWxUcmFjayxcbiAgUkNSZW1vdGVBdWRpb1RyYWNrLFxuICBSQ1JlbW90ZVRyYWNrLFxuICBSQ1JlbW90ZVZpZGVvVHJhY2ssXG4gIFJDUlRDQ2xpZW50LFxuICBSQ1JUQ0NvZGUsXG4gIFJDUlRDUGluZ1Jlc3VsdCxcbiAgUkNSVENSb29tLFxuICBJTWljcGhvbmVBdWRpb1Byb2ZpbGUsXG59IGZyb20gJ0Byb25nY2xvdWQvcGx1Z2luLXJ0Yyc7XG5cbmltcG9ydCB7IFByb2R1Y2VUeXBlcyB9IGZyb20gJy4vZW51bXMnO1xuXG5pbXBvcnQge1xuICBJRGV2aWNlQ2hhbmdlUGFyYW1zLFxuICBJTWVkaWFTdHJlYW1Db25zdHJhaW50cyxcbiAgSU11dGVVc2VyLFxuICBJUkNDYWxsU2Vzc2lvbk9wdGlvbnMsXG4gIElTZXNzaW9uTGlzdGVuZXIsXG4gIElWYWxpZGF0aW9uUmVzdWx0LFxufSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgZXZlbnRFbWl0dGVyIGZyb20gJy4vZXZlbnRFbWl0dGVyJztcbmltcG9ydCB7XG4gIHZhbGlkYXRlTGlzdGVuZXIsIHZhbGlkYXRlTWVkaWFTdHJlYW1Db25zdHJhaW50cywgdmFsaWRhdGVVc2VySWRzLCB2YWxpZGF0ZUV4dHJhLCB2YWxpZGF0ZVB1c2hUaXRsZSwgdmFsaWRhdGVQdXNoQ29udGVudCwgdmFsaWRhdGVQdXNoQ29uZmlnLFxufSBmcm9tICcuL3ZhbGlkYXRpb24nO1xuaW1wb3J0IHsgVGltZXIgfSBmcm9tICcuL3RpbWVyJztcblxuZXhwb3J0IGNsYXNzIFJDQ2FsbFNlc3Npb24ge1xuICAvKipcbiAgICogUlRD5oi/6Ze05a6e5L6LXG4gICAqL1xuICBwcml2YXRlIF9yb29tITogUkNSVENSb29tXG5cbiAgLyoqXG4gICAqIOeUqOaIt+S8oOi/m+adpeeahCDlr7lzZXNzaW9u55qE55uR5ZCsICjopoHlnKhSQ0NhbGxDbGllbnTnmoRfb25JbnZpdGXph4zliKTmlq3vvIzopoHmsYLmiafooYzlroxvblNlc3Npb27lv4Xpobvms6jlhoxzZXNzaW9u55qE55uR5ZCs77yM5omA5Lul6L+Z6YeM5pivcHVibGljKVxuICAgKi9cbiAgcHVibGljIF9saXN0ZW5lcjogSVNlc3Npb25MaXN0ZW5lciB8IG51bGwgPSBudWxsXG5cbiAgLyoqXG4gICAqIFJUQ+iuoumYheOAgeWPkeW4g+mHjeivleeahOasoeaVsFxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfUkVUUllDT1VOVDogbnVtYmVyID0gMlxuXG4gIC8qKlxuICAgKiDliqDlhaXmiL/pl7Tlrprml7blmahcbiAgICovXG5cbiAgcHJpdmF0ZSBqb2luUm9vbVRpbWVyOiBhbnkgPSBudWxsXG5cbiAgY29uc3RydWN0b3IoXG5cbiAgICAvKipcbiAgICAgKiDnirbmgIHmnLrlrp7kvotcbiAgICAgKi9cbiAgICBwcml2YXRlIF9zdGF0ZU1hY2hpbmU6IFJDQ2FsbFN0YXRlTWFjaGluZSxcblxuICAgIC8qKlxuICAgICAqIHJ0Y+WunuS+i1xuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3J0Y0NsaWVudDogUkNSVENDbGllbnQsXG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9sb2dnZXI6IElMb2dnZXIsXG5cbiAgICAvKipcbiAgICAgKiBzZXNzaW9u55qE5YW25a6D6YCJ6aG5XG4gICAgICovXG4gICAgcHJpdmF0ZSBfb3B0aW9uczogSVJDQ2FsbFNlc3Npb25PcHRpb25zID0ge30sXG5cbiAgKSB7XG4gICAgLy8g55uR5ZCs54q25oCB5py6XG4gICAgdGhpcy5fc3RhdGVNYWNoaW5lLnJlZ2lzdGVyRXZlbnRMaXN0ZW5lcih7XG4gICAgICAvKipcbiAgICAgICAqIOeUqOaIt+eKtuaAgeWPmOabtFxuICAgICAgICogQHBhcmFtIGluZm9cbiAgICAgICAqL1xuICAgICAgb25Vc2VyU3RhdGVDaGFuZ2U6ICh7IHVzZXIsIHJlYXNvbiB9OiBJVXNlclN0YXRlQ2hhbmdlSW5mbykgPT4ge1xuICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsU2Vzc2lvbiBvblVzZXJTdGF0ZUNoYW5nZV0gdXNlcklkLT4ke3VzZXI/LnVzZXJJZH0gc3RhdGUtPiR7dXNlcj8uc3RhdGV9IHJlYXNvbi0+JHtyZWFzb259YCk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIOaIv+mXtOeKtuaAgeWPmOabtFxuICAgICAgICogQHBhcmFtXG4gICAgICAgKi9cbiAgICAgIG9uU3RhdGVDaGFuZ2U6IGFzeW5jIChpbmZvOiBJU3RhdGVDaGFuZ2VJbmZvKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc3RhdGUsIHJlYXNvbiB9ID0gaW5mbztcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFNlc3Npb24gb25TdGF0ZUNoYW5nZV0gOiBzdGF0ZS0+JHtzdGF0ZX0gcmVhc29uLT4ke3JlYXNvbn1gKTtcblxuICAgICAgICAvLyDlpoLmnpzlnKjpgJror53kuK3vvIzlsLHliqDmiL/pl7RcbiAgICAgICAgaWYgKHN0YXRlID09PSBSQ0NhbGxTZXNzaW9uU3RhdGUuS0VFUElORykge1xuICAgICAgICAgIGNvbnN0IHJvb21JZDogc3RyaW5nID0gdGhpcy5fc3RhdGVNYWNoaW5lLmdldENhbGxJZCgpO1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uU3RhdGVDaGFuZ2VdIHJvb21JZDogJHtyb29tSWR9YCk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIOWKoOaIv+mXtFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fam9pblJvb20ocm9vbUlkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5fZXhjZXB0aW9uQ2xvc2UoUkNDYWxsRW5kUmVhc29uLk5FVFdPUktfRVJST1IpO1xuICAgICAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uU3RhdGVDaGFuZ2VdIGpvaW5Sb29tIHRocm93IGV4Y2VwdGlvbiByb29tSWQgLT4gJHtyb29tSWR9YCk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiAg5Lul5LiL5LiJ5p2h5Y+q6KaB5ruh6Laz5LiA5p2h77yM54q25oCB5Lya5Y+Y5oiQUkNDYWxsU2Vzc2lvblN0YXRlLkVORFxuICAgICAgICAgICAqICAx44CB5pys56uv55So5oi36Ieq5bex5Li75Yqo5oyC5patXG4gICAgICAgICAgICogIDLjgIHmnI3liqHnq6/miormnKznq6/nlKjmiLfouKLlh7pSVEPmiL/pl7RcbiAgICAgICAgICAgKiAgM+OAgeaIv+mXtOmHjOWwj+S6jjLkuKrkurpcbiAgICAgICAgICAgKi9cbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gUkNDYWxsU2Vzc2lvblN0YXRlLkVORCkge1xuICAgICAgICAgIC8vIOi/mOacquWKoOWFpeaIv+mXtOWwseaMguaWrVxuICAgICAgICAgIGlmICghdGhpcy5fcm9vbSkge1xuICAgICAgICAgICAgLy8g6ZSA5q+B5pys5Zyw5rWB77yM5YWz6Zet5pGE5YOP5aS0XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzICYmIHRoaXMuX2Rlc3Ryb3lUcmFja3ModGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyk7XG4gICAgICAgICAgICBjb25zdCBzdW1tYXJ5SW5mbyA9IHRoaXMuX3N0YXRlTWFjaGluZS5nZXRTdW1tYXJ5KCk7XG4gICAgICAgICAgICBldmVudEVtaXR0ZXIuZW1pdCgnc2Vzc2lvbkNsb3NlJywgeyBzZXNzaW9uOiB0aGlzLCBzdW1tYXJ5SW5mbyB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzICYmIHRoaXMuX2Rlc3Ryb3lUcmFja3ModGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyk7XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCAnW1JDQ2FsbFNlc3Npb24gb25TdGF0ZUNoYW5nZV0gbG9jYWxUcmFja3MgZGVzdHJveWVkJyk7XG4gICAgICAgICAgdGhpcy5fbGVhdmVSb29tKCk7XG4gICAgICAgICAgdGhpcy5fcm9vbSA9IG51bGwgYXMgdW5rbm93biBhcyBSQ1JUQ1Jvb207XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICog5pS25Yiw5ZON6ZODXG4gICAgICAgKiBAcGFyYW0gc2VuZGVyIOWPkei1t+eUqOaIt+S/oeaBr1xuICAgICAgICovXG4gICAgICBvblJpbmdpbmc6IChzZW5kZXI6IElTZW5kZXJJbmZvKSA9PiB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uUmluZ2luZ11zZW5kZXI6IHNlbmRlci51c2VySWQgLT4gJHtzZW5kZXIudXNlcklkfWApO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8g6YCa55+l55So5oi35ZON6ZODXG4gICAgICAgICAgdGhpcy5fbGlzdGVuZXIhLm9uUmluZ2luZyhzZW5kZXIsIHRoaXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBvblJpbmdpbmddIG1ldGhvZCBleGNlcHRpb24gLT4gb25SaW5naW5nJyk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICAgKiDlvZPov5znq6/nlKjmiLflkIzmhI/mjqXlkKxcbiAgICAgICAgICovXG4gICAgICBvbkFjY2VwdDogKHNlbmRlcjogSVNlbmRlckluZm8pID0+IHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFNlc3Npb24gb25BY2NlcHRdc2VuZGVyOiBzZW5kZXIudXNlcklkIC0+ICR7c2VuZGVyLnVzZXJJZH1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDpgJrnn6XmnKznq6/vvIzov5znq6/nlKjmiLflt7LmjqXlkKxcbiAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25BY2NlcHQoc2VuZGVyLCB0aGlzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb24gb25BY2NlcHRdIG1ldGhvZCBleGNlcHRpb24gLT4gb25BY2NlcHQnKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgICAqIOW9k+aciei/nOerr+eUqOaIt+aMguaWrVxuICAgICAgICAgKi9cbiAgICAgIG9uSHVuZ3VwOiAoc2VuZGVyOiBJU2VuZGVySW5mbywgcmVhc29uOiBSQ0NhbGxFbmRSZWFzb24pID0+IHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFNlc3Npb24gb25IdW5ndXBdc2VuZGVyOiBzZW5kZXIudXNlcklkIC0+ICR7c2VuZGVyLnVzZXJJZH0gcmVhc29uLT4ke3JlYXNvbn1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDpgJrnn6XmnKznq6/vvIzov5znq6/nlKjmiLflt7LmjILmlq1cbiAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25IdW5ndXAoc2VuZGVyLCByZWFzb24sIHRoaXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBvbkh1bmd1cF0gbWV0aG9kIGV4Y2VwdGlvbiAtPiBvbkh1bmd1cCcpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIOaUtuWIsOS6uuWRmOWPmOabtFxuICAgICAgICogQHBhcmFtIHNlbmRlciDlj5HotbfnlKjmiLfkv6Hmga9cbiAgICAgICAqL1xuICAgICAgb25NZW1iZXJNb2RpZnk6ICh7IHNlbmRlciwgaW52aXRlZFVzZXJzIH06IElNZW1iZXJNb2RpZnlJbmZvKSA9PiB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uTWVtYmVyTW9kaWZ5XSBzZW5kZXIudXNlcklkIC0+ICR7c2VuZGVyLnVzZXJJZH1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDpgJrnn6XnlKjmiLfkurrlkZjlj5jmm7RcbiAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25NZW1iZXJNb2RpZnkoc2VuZGVyLCBpbnZpdGVkVXNlcnMsIHRoaXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBvbk1lbWJlck1vZGlmeV0gbWV0aG9kIGV4Y2VwdGlvbiAtPiBvbk1lbWJlck1vZGlmeScpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIOaUtuWIsOmAmuivneexu+Wei+WPmOabtCAo6YCa6K+d6ZmN57qnKVxuICAgICAgICogQHBhcmFtIHNlbmRlciDlj5HotbfnlKjmiLfkv6Hmga9cbiAgICAgICAqL1xuICAgICAgb25NZWRpYU1vZGlmeTogKHsgc2VuZGVyLCBtZWRpYVR5cGUgfTogSU1lZGlhTW9kaWZ5SW5mbykgPT4ge1xuICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsU2Vzc2lvbiBvbk1lZGlhTW9kaWZ5XXNlbmRlcjogc2VuZGVyLnVzZXJJZCAtPiAke3NlbmRlci51c2VySWR9IG1lZGlhVHlwZTogJHttZWRpYVR5cGV9YCk7XG4gICAgICAgIGlmIChtZWRpYVR5cGUgPT09IFJDQ2FsbE1lZGlhVHlwZS5BVURJTykge1xuICAgICAgICAgIC8vIOi/nOerr+aUtuWIsOmAmuivnemZjee6p+mAmuefpeWQju+8jOi/nOerr+aJp+ihjOmZjee6p+mAmuivnSjkuI3lj5Hmtojmga8pXG4gICAgICAgICAgdGhpcy5fc2V0TWVkaWFUeXBlVG9BdWRpbygpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5fbGlzdGVuZXIhLm9uTWVkaWFNb2RpZnkoc2VuZGVyLCBtZWRpYVR5cGUsIHRoaXMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBvbk1lZGlhTW9kaWZ5XSBtZXRob2QgZXhjZXB0aW9uIC0+IG9uTWVkaWFNb2RpZnknKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8qKlxuICAgICAgICog5piv5ZCm6LeoYXBwa2V5XG4gICAgICAgKiBAcGFyYW0gc2VuZGVyIOWPkei1t+eUqOaIt+S/oeaBr1xuICAgICAgICovXG4gICAgICBjcm9zc0FwcGtleTogKGlzQ3Jvc3NBcHBrZXk6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFNlc3Npb24gY3Jvc3NBcHBrZXldIOaYr+WQpui3qCBhcHBrZXk6ICR7aXNDcm9zc0FwcGtleX1gKTtcbiAgICAgICAgdGhpcy5fb3B0aW9ucy5pc0Nyb3NzQXBwa2V5ID0gaXNDcm9zc0FwcGtleTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiDorr7nva7mjILmlq3nmoTmjqjpgIHkv6Hmga9cbiAgICAgKi9cbiAgICB0aGlzLl9zdGF0ZU1hY2hpbmUuc2V0SHVuZ3VwUHVzaENvbmZpZyh0aGlzLl9vcHRpb25zLmh1bmd1cFB1c2hDb25maWcgfHwgeyBwdXNoVGl0bGU6ICcnLCBwdXNoQ29udGVudDogJycgfSk7XG4gIH1cblxuICAvKipcbiAgICogIOWKoOWFpeaIv+mXtFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfam9pblJvb20ocm9vbUlkOiBzdHJpbmcpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBsZXQgY2FsbEJhY2s7XG4gICAgdHJ5IHtcbiAgICAgIC8vIOWKoOaIv+mXtFxuICAgICAgaWYgKHRoaXMuX29wdGlvbnMuaXNDcm9zc0FwcGtleSkge1xuICAgICAgICBjYWxsQmFjayA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5qb2luQ3Jvc3NSVENSb29tKHJvb21JZCwgdGhpcy5fb3B0aW9ucy5qb2luVHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsQmFjayA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5qb2luUlRDUm9vbShyb29tSWQsIHRoaXMuX29wdGlvbnMuam9pblR5cGUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGNvZGUsIHVzZXJJZHMsIHJvb20gfSA9IGNhbGxCYWNrO1xuXG4gICAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgLy8g5aaC5p6c6Z+z6KeG6aKR5pyN5Yqh5pyq5byA6YCaXG4gICAgICAgIGlmIChjb2RlID09PSBSQ1JUQ0NvZGUuTk9UX09QRU5fVklERU9fQVVESU9fU0VSVkVSKSB7XG4gICAgICAgICAgdGhpcy5fZXhjZXB0aW9uQ2xvc2UoUkNDYWxsRW5kUmVhc29uLlNFUlZJQ0VfTk9UX09QRU5FRCk7XG4gICAgICAgICAgLy8g5bex5pa55YW25LuW56uv5bey5Zyo6YCa6K+d5LitXG4gICAgICAgIH0gaWYgKGNvZGUgPT09IFJDUlRDQ29kZS5TSUdOQUxfSk9JTl9SVENfUk9PTV9SRUZVU0VEKSB7XG4gICAgICAgICAgdGhpcy5fZXhjZXB0aW9uQ2xvc2UoUkNDYWxsRW5kUmVhc29uLk9USEVSX0NMSUVOVF9JTl9DQUxMKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uTkVUV09SS19FUlJPUik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsQ2xpZW50IF9qb2luUm9vbV0gam9pbiByb29tIGZhaWxlZDogcm9vbUlkIC0+ICR7cm9vbUlkfSBSQ1JUQ0NvZGUgLT4gJHtjb2RlfWApO1xuICAgICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuSk9JTl9ST09NX0VSUk9SIH07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICog576k6IGK5pys56uv5Yqg5YWl5oi/6Ze05ZCO77yM5pu05paw5Lq65ZGY54q25oCB5Li66YCa6K+d5LitXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IGNvbnZlcnNhdGlvblR5cGUgPSB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0Q29udmVyc2F0aW9uVHlwZSgpO1xuICAgICAgY29udmVyc2F0aW9uVHlwZSA9PT0gQ29udmVyc2F0aW9uVHlwZS5HUk9VUCAmJiB0aGlzLl9zdGF0ZU1hY2hpbmUudXNlckpvaW4oW3RoaXMuX3J0Y0NsaWVudC5nZXRDdXJyZW50SWQoKV0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIOmSiOWvueengeacieS6kSBAcm9uZ2Nsb3VkL3BsdWdpbi1ydGNANS4xLjEwLWVudGVycHJpc2UuNyDlop7liqDooaXkuIHvvIxcbiAgICAgICAqIOengeacieS6keWNh+WujCBSVEMgc2RrIOeJiOacrOWQjuWIoOaOieatpOihpeS4gVxuICAgICAgICog5Yqg5a6M5oi/6Ze05ZCO77yM5a+55pa55oyC5pat5LqG77yM6ZyA6YCA5Ye65oi/6Ze0XG4gICAgICAgKi9cbiAgICAgIGlmICh0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0U3RhdGUoKSA9PT0gUkNDYWxsU2Vzc2lvblN0YXRlLkVORCkge1xuICAgICAgICBhd2FpdCB0aGlzLl9ydGNDbGllbnQubGVhdmVSb29tKHJvb20hKTtcbiAgICAgICAgdGhpcy5fcm9vbSA9IG51bGwgYXMgdW5rbm93biBhcyBSQ1JUQ1Jvb207XG4gICAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTIH07XG4gICAgICB9XG5cbiAgICAgIC8vIOiiq+WPq+aWueWKoOWFpeaIv+mXtOaIkOWKn++8jOS9huS4u+WPq+aWueWcqOWKoOWFpeaIv+mXtOWJjeemu+e6v1xuICAgICAgaWYgKHVzZXJJZHMhLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgdGhpcy5qb2luUm9vbVRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uUkVNT1RFX05FVFdPUktfRVJST1IpO1xuICAgICAgICB9LCA2MDAwMCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9yb29tID0gcm9vbSBhcyBSQ1JUQ1Jvb207XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuX2V4Y2VwdGlvbkNsb3NlKFJDQ2FsbEVuZFJlYXNvbi5ORVRXT1JLX0VSUk9SKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBfam9pblJvb21dIF9ydGNDbGllbnQuam9pblJUQ1Jvb20gdGhyb3cgZXhjZXB0aW9uIHJvb21JZCAtPiAke3Jvb21JZH1gKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLkpPSU5fUk9PTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8vIOaIv+mXtOS4iuazqOWGjOebkeWQrOS6i+S7tlxuICAgIHRoaXMuX3JlZ2lzdGVyUm9vbUV2ZW50TGlzdGVuZXIoKTtcblxuICAgIC8vIOazqOWGjOaIv+mXtOi0qOmHj+aVsOaNruebkeWQrOWZqFxuICAgIHRoaXMuX3JlZ2lzdGVyUmVwb3J0TGlzdGVuZXIoKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyDorqLpmIXov5znqIvnmoTmtYHvvIzmiorov5znqIvnmoTmtYHmipvnu5nnlKjmiLdcbiAgICAgIGF3YWl0IHRoaXMuX3N1YnNjcmliZUluUm9vbVJlbW90ZVRyYWNrKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIOe7k+adn+mAmuivnXNlc3Npb25cbiAgICAgIHRoaXMuX2V4Y2VwdGlvbkNsb3NlKFJDQ2FsbEVuZFJlYXNvbi5TVUJTQ1JJQkVfRVJST1IpO1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIF9qb2luUm9vbV0gX3N1YnNjcmliZUluUm9vbVJlbW90ZVRyYWNrIEV4Y2VwdGlvbiByb29tSWQgLT4gJHtyb29tSWR9YCk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5KT0lOX1JPT01fRVJST1IgfTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8g5b6A5oi/6Ze06YeM5Y+R5biD5pys5Zyw6LWE5rqQXG4gICAgICBhd2FpdCB0aGlzLl9wdWJsaXNoKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIOe7k+adn+mAmuivnXNlc3Npb25cbiAgICAgIHRoaXMuX2V4Y2VwdGlvbkNsb3NlKFJDQ2FsbEVuZFJlYXNvbi5QVUJMSVNIX0VSUk9SKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBfam9pblJvb21dIF9wdWJsaXNoIEV4Y2VwdGlvbiByb29tSWQgLT4gJHtyb29tSWR9YCk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5KT0lOX1JPT01fRVJST1IgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiAo5Yid5aeL5YyW5oi/6Ze055qE5pe25YCZKSDorqLpmIXov5znqIvnmoTmtYHvvIzmiorov5znqIvnmoTmtYHmipvnu5nnlKjmiLdcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX3N1YnNjcmliZUluUm9vbVJlbW90ZVRyYWNrKCkge1xuICAgIC8vIOiOt+WPluaJgOaciei/nOeoi+W3suWPkeW4g+eahOmfs+inhumikei1hOa6kOWIl+ihqFxuICAgIGNvbnN0IHRyYWNrczogUkNSZW1vdGVUcmFja1tdID0gdGhpcy5fcm9vbS5nZXRSZW1vdGVUcmFja3MoKTtcbiAgICBpZiAodHJhY2tzLmxlbmd0aCkge1xuICAgICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9zdWJzY3JpYmVSZXRyeSh0cmFja3MsIHRoaXMuX29wdGlvbnMuaXNBbGxvd1N1YnNjcmliZVJldHJ5LCB0aGlzLl9SRVRSWUNPVU5UKTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uU1VCU0NSSUJFX0VSUk9SKTtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIF9zdWJzY3JpYmVJblJvb21SZW1vdGVUcmFja10gUmVzb3VyY2Ugc3Vic2NyaXB0aW9uIGZhaWxlZCByb29tSWQgLT4gJHt0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0Q2FsbElkKCl9IFJUQyBjb2RlIC0+ICR7Y29kZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5Y+v5Lul6YeN6K+V55qE6K6i6ZiFXG4gICAqIEBwYXJhbSBwYXJhbXMudHJhY2tzIHRyYWNrc1xuICAgKiBAcGFyYW0gcGFyYW1zLmlzQWxsb3dTdWJzY3JpYmVSZXRyeSDmmK/lkKblhYHorrjph43or5VcbiAgICogQHBhcmFtIHBhcmFtcy5jb3VudCDlhYHorrjph43or5XnmoTmrKHmlbBcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX3N1YnNjcmliZVJldHJ5KHRyYWNrczogUkNSZW1vdGVUcmFja1tdLCBpc0FsbG93U3Vic2NyaWJlUmV0cnk6IGJvb2xlYW4gPSBmYWxzZSwgY291bnQ6IG51bWJlciA9IDApOiBQcm9taXNlPHsgY29kZTogUkNSVENDb2RlIH0+IHtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3Jvb20uc3Vic2NyaWJlKHRyYWNrcyk7XG4gICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl9saXN0ZW5lciEub25UcmFja1N1YnNjcmliZUZhaWwgJiYgdGhpcy5fbGlzdGVuZXIhLm9uVHJhY2tTdWJzY3JpYmVGYWlsKGNvZGUsIHRoaXMpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgJ1tSQ0NhbGxTZXNzaW9uXSBfbGlzdGVuZXIub25UcmFja1N1YnNjcmliZUZhaWwgZXhjZXB0aW9uJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICAvLyDlpoLmnpzkuI3lhYHorrjph43or5XvvIznm7TmjqXov5Tlm55cbiAgICAgIGlmICghaXNBbGxvd1N1YnNjcmliZVJldHJ5KSB7XG4gICAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICAgIH1cbiAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgY291bnQtLTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N1YnNjcmliZVJldHJ5KHRyYWNrcywgaXNBbGxvd1N1YnNjcmliZVJldHJ5LCBjb3VudCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlj5HluIPmnKzlnLDotYTmupDnmoTpgLvovpFcbiAgICpcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX3B1Ymxpc2goKSB7XG4gICAgY29uc3QgdHJhY2tzID0gdGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyE7XG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9wdWJsaXNoUmV0cnkodHJhY2tzLCB0aGlzLl9vcHRpb25zLmlzQWxsb3dQdWJsaXNoUmV0cnksIHRoaXMuX1JFVFJZQ09VTlQpO1xuXG4gICAgLy8g6Iul6LWE5rqQ5Y+R5biD5aSx6LSlXG4gICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uUFVCTElTSF9FUlJPUik7XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsU2Vzc2lvbiBfcHVibGlzdF0gUmVzb3VyY2UgcHVibGlzaGluZyBmYWlsZWQ6IHJvb21JZCAtPiAke3RoaXMuX3N0YXRlTWFjaGluZS5nZXRDYWxsSWQoKX0gUkNSVENDb2RlIC0+ICR7Y29kZX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDlpoLmnpzmmK/kuLvliqjlj5HotbfnmoTlkbzlj6vvvIzlt7Lmj5DliY3mipvlh7rkuobotYTmupAsIOiiq+WKqOWRvOWPq++8jOi/memHjOaJjemcgOimgeaKm+WHulxuICAgIGlmICh0aGlzLl9vcHRpb25zLnByb2R1Y2VUeXBlID09PSBQcm9kdWNlVHlwZXMuQ0FMTEVFKSB7XG4gICAgICAvLyDlkJHlpJbmipvlh7rmnKzlnLDmtYEsIOmAmuefpeS4muWKoeWxgnRyYWNrUmVhZHlcbiAgICAgIHRoaXMuX25vdGlmeVRyYWNrUmVhZHkodHJhY2tzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog5Y+v5Lul6YeN6K+V55qE5Y+R5biDXG4gICAqIEBwYXJhbSBwYXJhbXMudHJhY2tzIHRyYWNrc1xuICAgKiBAcGFyYW0gcGFyYW1zLmlzQWxsb3dQdWJsaXNoUmV0cnkg5piv5ZCm5YWB6K646YeN6K+VXG4gICAqIEBwYXJhbSBwYXJhbXMuY291bnQg5YWB6K646YeN6K+V55qE5qyh5pWwXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9wdWJsaXNoUmV0cnkodHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSwgaXNBbGxvd1B1Ymxpc2hSZXRyeTogYm9vbGVhbiA9IGZhbHNlLCBjb3VudDogbnVtYmVyID0gMCk6IFByb21pc2U8eyBjb2RlOiBSQ1JUQ0NvZGUgfT4ge1xuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fcm9vbS5wdWJsaXNoKHRyYWNrcyk7XG4gICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl9saXN0ZW5lciEub25UcmFja1B1Ymxpc2hGYWlsICYmIHRoaXMuX2xpc3RlbmVyIS5vblRyYWNrUHVibGlzaEZhaWwoY29kZSwgdGhpcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb25dIF9saXN0ZW5lci5vblRyYWNrUHVibGlzaEZhaWwgZXhjZXB0aW9uJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICAvLyDlpoLmnpzkuI3lhYHorrjph43or5XvvIznm7TmjqXov5Tlm55cbiAgICAgIGlmICghaXNBbGxvd1B1Ymxpc2hSZXRyeSkge1xuICAgICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgICB9XG4gICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgIGNvdW50LS07XG4gICAgICAgIHJldHVybiB0aGlzLl9wdWJsaXNoUmV0cnkodHJhY2tzLCBpc0FsbG93UHVibGlzaFJldHJ5LCBjb3VudCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpgIDlh7rmiL/pl7RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2xlYXZlUm9vbSgpIHtcbiAgICB0cnkge1xuICAgICAgLy8g6YCA5Ye65oi/6Ze0XG4gICAgICBjb25zdCBjYWxsQmFjayA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5sZWF2ZVJvb20odGhpcy5fcm9vbSk7XG4gICAgICAvLyDmiJDlip/pgIDlh7rmiL/pl7TvvIzop6blj5FSQ0NhbGxDbGllbnTlrp7kvovkuIrnmoRvblNlc3Npb25DbG9zZeebkeWQrO+8jOaKm+e7meeUqOaIt+S/oeaBr1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbFNlc3Npb24gX2xlYXZlUm9vbV0gU3VjY2Vzc2Z1bGx5IGV4aXRlZCB0aGUgcm9vbSBjb2RlOiAke2NhbGxCYWNrLmNvZGV9YCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBfbGVhdmVSb29tXSBsZWF2ZVJvb20gdGhyb3cgZXhjZXB0aW9uJyk7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgY29uc3Qgc3VtbWFyeUluZm8gPSB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0U3VtbWFyeSgpO1xuICAgICAgZXZlbnRFbWl0dGVyLmVtaXQoJ3Nlc3Npb25DbG9zZScsIHsgc2Vzc2lvbjogdGhpcywgc3VtbWFyeUluZm8gfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOWHuueOsOW8guW4uOWQjuimgeWkhOeQhueahOmAu+i+kSxcbiAgICogQHBhcmFtIGVuZFJlYXNvbiDljp/lm6BcbiAgICovXG4gIHByaXZhdGUgX2V4Y2VwdGlvbkNsb3NlKGVuZFJlYXNvbjogUkNDYWxsRW5kUmVhc29uKSB7XG4gICAgLy8g6ZSA5q+B5pys5Zyw5rWBXG4gICAgdGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyAmJiB0aGlzLl9kZXN0cm95VHJhY2tzKHRoaXMuX29wdGlvbnMubG9jYWxUcmFja3MpO1xuXG4gICAgLy8g57uT5p2f54q25oCB5py6XG4gICAgdGhpcy5fc3RhdGVNYWNoaW5lLmNsb3NlKGVuZFJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICog55So5oi36LCD55So55qE77yM5rOo5YaMc2Vzc2lvbuS4iueahOebkeWQrFxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyU2Vzc2lvbkxpc3RlbmVyKGxpc3RlbmVyOiBJU2Vzc2lvbkxpc3RlbmVyKTogdm9pZCB7XG4gICAgLy8g5YWI5qCh6aqMbGlzdGVuZXIsIOWmguaenOS4jemAmui/h++8jOS8mnRyb3cgZXJyb3JcbiAgICBjb25zdCBjb25jbHVzaW9uOiBJVmFsaWRhdGlvblJlc3VsdCA9IHZhbGlkYXRlTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgIGlmICghY29uY2x1c2lvbi5yZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgW1JDQ2FsbFNlc3Npb24gcmVnaXN0ZXJTZXNzaW9uTGlzdGVuZXJdICR7Y29uY2x1c2lvbi5tc2d9YCk7XG4gICAgfVxuICAgIHRoaXMuX2xpc3RlbmVyID0geyAuLi5saXN0ZW5lciB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOiwg1JUQyBBUEkg6I635b6X5pys5Zyw5rWBXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9nZXRMb2NhbFRyYWNrQ29yZShtZWRpYVR5cGU6IFJDQ2FsbE1lZGlhVHlwZSwgY29uc3RyYWludHM/OiBJTWVkaWFTdHJlYW1Db25zdHJhaW50cyk6IFByb21pc2U8eyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUsIHRyYWNrcz86IFJDTG9jYWxUcmFja1tdIH0+IHtcbiAgICAvLyDmo4DmtYvmmK/lkKbog73lpJ/ojrflvpfmnKzlnLDmtYFcbiAgICBpZiAobWVkaWFUeXBlID09PSBSQ0NhbGxNZWRpYVR5cGUuQVVESU8pIHtcbiAgICAgIGNvbnN0IHsgY29kZSwgdHJhY2sgfSA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5jcmVhdGVNaWNyb3Bob25lQXVkaW9UcmFjaygnUm9uZ0Nsb3VkUlRDJywgY29uc3RyYWludHMgJiYgY29uc3RyYWludHMuYXVkaW8gJiYgeyAuLi5jb25zdHJhaW50cy5hdWRpbyB9KTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gX2dldExvY2FsVHJhY2tDb3JlXSBnZXQgQXVkaW8gbG9jYWwgdHJhY2tzIGZhaWxlZCBSQ1QgY29kZSAtPiAke2NvZGV9YCk7XG4gICAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5HRVRfTE9DQUxfQVVESU9fVFJBQ0tfRVJST1IgfTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgJ1tSQ0NhbGxTZXNzaW9uIF9nZXRMb2NhbFRyYWNrQ29yZV0gc3VjY2Vzc2Z1bGx5IGdldCBBdWRpbyBsb2NhbCB0cmFja3MnKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLCB0cmFja3M6IFt0cmFjayFdIH07XG4gICAgfVxuICAgIGNvbnN0IHsgY29kZSwgdHJhY2tzIH0gPSBhd2FpdCB0aGlzLl9ydGNDbGllbnQuY3JlYXRlTWljcm9waG9uZUFuZENhbWVyYVRyYWNrcygnUm9uZ0Nsb3VkUlRDJywgY29uc3RyYWludHMgJiYgeyAuLi5jb25zdHJhaW50cyB9KTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBfZ2V0TG9jYWxUcmFja0NvcmVdIGdldCBBdWRpbyBhbmQgVmlkZW8gbG9jYWwgdHJhY2tzIGZhaWxlZCBSQ1QgY29kZSAtPiAke2NvZGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuR0VUX0xPQ0FMX0FVRElPX0FORF9WSURFT19UUkFDS19FUlJPUiB9O1xuICAgIH1cbiAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdbUkNDYWxsU2Vzc2lvbiBfZ2V0TG9jYWxUcmFja0NvcmVdIHN1Y2Nlc3NmdWxseSBnZXQgYXVkaW8gYW5kIHZpZGVvIGxvY2FsIHRyYWNrcycpO1xuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLCB0cmFja3MgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2dldExvY2FsVHJhY2sobWVkaWFUeXBlOiBSQ0NhbGxNZWRpYVR5cGUsIGNvbnN0cmFpbnRzPzogSU1lZGlhU3RyZWFtQ29uc3RyYWludHMpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLCB0cmFja3M/OiBSQ0xvY2FsVHJhY2tbXSB9PiB7XG4gICAgLy8g5bm25LiU5piv6I635b6X6Z+z6KeG6aKRLCDlubbkuJQg77yI5aaC5p6c6I635b6X6Z+z6KeG6aKR5LiN5oiQ5Yqf77yM5YWB6K646ZmN57qn6I635b6X6Z+z6aKR77yJXG4gICAgaWYgKHRoaXMuX29wdGlvbnMuaXNBbGxvd0RlbW90aW9uR2V0U3RyZWFtICYmIG1lZGlhVHlwZSA9PT0gUkNDYWxsTWVkaWFUeXBlLkFVRElPX1ZJREVPKSB7XG4gICAgICBjb25zdCB7IGNvZGUsIHRyYWNrcyB9ID0gYXdhaXQgdGhpcy5fZ2V0TG9jYWxUcmFja0NvcmUoUkNDYWxsTWVkaWFUeXBlLkFVRElPX1ZJREVPLCBjb25zdHJhaW50cyk7XG5cbiAgICAgIC8vIOWmguaenOmfs+inhumikeS4jeiDveiOt+W+l++8jOWwsemZjee6p+iOt+W+l+mfs+mikVxuICAgICAgaWYgKGNvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgIGNvbnN0IHsgY29kZSwgdHJhY2tzIH0gPSBhd2FpdCB0aGlzLl9nZXRMb2NhbFRyYWNrQ29yZShSQ0NhbGxNZWRpYVR5cGUuQVVESU8sIGNvbnN0cmFpbnRzKTtcbiAgICAgICAgaWYgKGNvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgICAgLy8g6I635Y+W6LWE5rqQ5aSx6LSl77yM6ZyA6KaB6LCD54q25oCB5py6c3RhdGUg5Li6IGVuZFxuICAgICAgICAgIHRoaXMuX2V4Y2VwdGlvbkNsb3NlKFJDQ2FsbEVuZFJlYXNvbi5HRVRfTUVESUFfUkVTT1VSQ0VTX0VSUk9SKTtcbiAgICAgICAgICByZXR1cm4geyBjb2RlIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY29kZSwgdHJhY2tzIH07XG4gICAgICB9XG4gICAgICByZXR1cm4geyBjb2RlLCB0cmFja3MgfTtcbiAgICB9XG4gICAgY29uc3QgeyBjb2RlOiBfY29kZSwgdHJhY2tzIH0gPSBhd2FpdCB0aGlzLl9nZXRMb2NhbFRyYWNrQ29yZShtZWRpYVR5cGUsIGNvbnN0cmFpbnRzKTtcbiAgICBpZiAoX2NvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICAvLyDojrflj5botYTmupDlpLHotKXvvIzpnIDopoHosIPnirbmgIHmnLpzdGF0ZSDkuLogZW5kXG4gICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uR0VUX01FRElBX1JFU09VUkNFU19FUlJPUik7XG5cbiAgICAgIHJldHVybiB7IGNvZGU6IF9jb2RlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGU6IF9jb2RlLCB0cmFja3MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53kuK3mm7TmjaLpn7PpopHorr7lpIdcbiAgICovXG4gIHB1YmxpYyBhc3luYyBjaGFuZ2VBdWRpb0RldmljZShhdWRpb0NvbnN0cmFpbnRzPzogSU1pY3Bob25lQXVkaW9Qcm9maWxlKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSB9PiB7XG4gICAgLy8g5paw6K6+5aSH55qEdHJhY2tcbiAgICBjb25zdCByZWNlbnRUcmFja3M6IFJDTG9jYWxUcmFja1tdID0gW107XG5cbiAgICAvLyDmlbTnkIblkI7nmoTmnKzlnLB0cmFja1xuICAgIGNvbnN0IGxvY2FsVHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IFtdO1xuICAgIGNvbnN0IHsgY29kZSwgdHJhY2sgfSA9IGF3YWl0IHRoaXMuX3J0Y0NsaWVudC5jcmVhdGVNaWNyb3Bob25lQXVkaW9UcmFjaygnUm9uZ0Nsb3VkUlRDJywgYXVkaW9Db25zdHJhaW50cyk7XG4gICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gY2hhbmdlRGV2aWNlXSBnZXQgbG9jYWwgQXVkaW8gdHJhY2tzIGZhaWxlZCBSQ1RMaWIgY29kZSAtPiAke2NvZGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuR0VUX0xPQ0FMX0FVRElPX1RSQUNLX0VSUk9SIH07XG4gICAgfVxuXG4gICAgdGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyAmJiB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzLmZvckVhY2goKHRyYWNrOiBSQ0xvY2FsVHJhY2spID0+IHtcbiAgICAgIGlmICh0cmFjay5pc0F1ZGlvVHJhY2soKSkge1xuICAgICAgICAvLyDkuYvliY3nmoTpn7PpopHpg73plIDmr4HvvIzvvIhSVENMaWIgU0RL5YaF6YOo5Lya5ZyoIGFkZExvY2FsVHJhY2sg5riF55CG5ZCM57G75Z6L6L2o6YGT5pWw5o2u77yM5omA5Lul6L+Z6YeM5rOo6YeK5o6J77yJXG4gICAgICAgIC8vIHRyYWNrLmRlc3Ryb3koKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g5Y+q5oqK5LmL5YmN55qE6KeG6aKR55WZ5LiLXG4gICAgICAgIGxvY2FsVHJhY2tzLnB1c2godHJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVjZW50VHJhY2tzLnB1c2godHJhY2shKTtcblxuICAgIC8vIOWKoOS4iuacrOWcsOaWsOS6p+eUn+eahOmfs+mikVxuICAgIGxvY2FsVHJhY2tzLnB1c2godHJhY2shKTtcbiAgICB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzID0gbG9jYWxUcmFja3M7XG4gICAgLy8g6YCa55+l5Lia5Yqh5bGCdHJhY2tSZWFkeVxuICAgIHRoaXMuX25vdGlmeVRyYWNrUmVhZHkocmVjZW50VHJhY2tzKTtcblxuICAgIC8vIOWmguaenOW9k+WJjeW3suWKoOWFpeaIv+mXtO+8jOWPkeW4g+aWsOa1gVxuICAgIGlmICh0aGlzLl9yb29tKSB7XG4gICAgICAvLyDlj5HluIPmlrDmtYFcbiAgICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fcm9vbS5wdWJsaXNoKHJlY2VudFRyYWNrcyk7XG4gICAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLkFVRElPX1BVQkxJU0hfRVJST1IgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnvqTlkbzlj6vkuK3nu6fnu63pgoDor7dcbiAgICogQHBhcmFtIHVzZXJJZHMg6KKr6YKA6K+355So5oi3IElEIOWIl+ihqFxuICAgKiBAcGFyYW0gb3B0aW9ucy5leHRyYSDmtojmga/nmoTmianlsZXkv6Hmga9cbiAgICogQGRlcHJlY2F0ZWQgNS4xLjIg5bqf5byDIG9wdGlvbnMucHVzaFRpdGxlIOmAmuefpeeahOagh+mimFxuICAgKiBAZGVwcmVjYXRlZCA1LjEuMiDlup/lvIMgb3B0aW9ucy5wdXNoQ29udGVudCDpgJrnn6XlhoXlrrlcbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbnZpdGUodXNlcklkczogc3RyaW5nW10sIG9wdGlvbnM6IElJbnZpdGVPcHRpb25zID0ge30pOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBjb25zdCB7IGV4dHJhID0gJycgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgcHVzaENvbmZpZyA9IHRoaXMuX29wdGlvbnMuY2FsbFB1c2hDb25maWcgPyB0aGlzLl9vcHRpb25zLmNhbGxQdXNoQ29uZmlnIDogb3B0aW9ucy5wdXNoQ29uZmlnO1xuICAgIGNvbnN0IGNvbmNsdXNpb246IElWYWxpZGF0aW9uUmVzdWx0W10gPSBbdmFsaWRhdGVVc2VySWRzKHVzZXJJZHMpLCB2YWxpZGF0ZUV4dHJhKGV4dHJhKV07XG4gICAgaWYgKHB1c2hDb25maWcpIHtcbiAgICAgIGNvbnN0IHsgY29kZSwgZXJyb3JNc2cgfSA9IHZhbGlkYXRlUHVzaENvbmZpZyhwdXNoQ29uZmlnKTtcbiAgICAgIGlmIChjb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gaW52aXRlXSBwYXJhbSBlcnJvciwgZXJyb3JNc2c6ICR7ZXJyb3JNc2d9YCk7XG4gICAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgbWVzc2FnZXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgcmVzdWx0ID0gY29uY2x1c2lvbi5ldmVyeSgob2JqOiBJVmFsaWRhdGlvblJlc3VsdCkgPT4ge1xuICAgICAgIW9iai5yZXN1bHQgJiYgbWVzc2FnZXMucHVzaChvYmoubXNnISk7XG4gICAgICByZXR1cm4gb2JqLnJlc3VsdDtcbiAgICB9KTtcblxuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFtSQ0NhbGxDbGllbnQgaW52aXRlXSAke21lc3NhZ2VzLmpvaW4oJ1xcbicpfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fc3RhdGVNYWNoaW5lLmludml0ZSh1c2VySWRzLCB7XG4gICAgICBleHRyYSwgcHVzaENvbmZpZyxcbiAgICB9KTtcbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog5ZCM5oSP5o6l5ZCsXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgYWNjZXB0KGNvbnN0cmFpbnRzPzogSU1lZGlhU3RyZWFtQ29uc3RyYWludHMpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBjb25zdCBjb25jbHVzaW9uOiBJVmFsaWRhdGlvblJlc3VsdCA9IHZhbGlkYXRlTWVkaWFTdHJlYW1Db25zdHJhaW50cyhjb25zdHJhaW50cyEpO1xuICAgIGlmICghY29uY2x1c2lvbi5yZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgW1JDQ2FsbFNlc3Npb24gYWNjZXB0XSAke2NvbmNsdXNpb24ubXNnfWApO1xuICAgIH1cblxuICAgIC8vIOaOpeWQrOS5i+WJje+8jOWFiOaMguaWreW9k+WJjeS5i+WklueahHNlc3Npb27vvIznjrDpmLbmrrXkuI3lhYHorrjnlKjmiLflhYjmi6nmjqXlkKxzZXNzaW9u77yM5LqL5YWI5Lya5Zyo54q25oCB5py65YaF6YOo5oyC5pat77yM6L+Z6YeM5oqb5Ye65Y6777yM5Lya5riF55CG5YW25a6D55qEc2Vlc2lvblxuICAgIGV2ZW50RW1pdHRlci5lbWl0KCdodW5ndXBPdGhlclNlc3Npb24nLCB7IHNlc3Npb246IHRoaXMgfSk7XG4gICAgY29uc3QgbWVkaWFUeXBlID0gdGhpcy5fc3RhdGVNYWNoaW5lLmdldE1lZGlhVHlwZSgpO1xuICAgIGNvbnN0IHsgY29kZTogX2NvZGUsIHRyYWNrcyB9ID0gYXdhaXQgdGhpcy5fZ2V0TG9jYWxUcmFjayhtZWRpYVR5cGUsIGNvbnN0cmFpbnRzKTtcbiAgICBpZiAoX2NvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBfY29kZSB9O1xuICAgIH1cbiAgICB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzID0gdHJhY2tzO1xuXG4gICAgLy8g5Y+R6YCB5o6l5ZCs55qE5raI5oGvXG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9zdGF0ZU1hY2hpbmUuYWNjZXB0KCk7XG4gICAgaWYgKGNvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gYWNjZXB0XVNlbmQgYWNjZXB0IG1lc3NhZ2UgZmFpbGVkIC0+IGNvZGU6ICR7Y29kZX1gKTtcbiAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOaMguaWrVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGh1bmd1cCgpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlOyB9PiB7XG4gICAgLy8gY29uc3Qgc3VtbWFyeUluZm8gPSB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0U3VtbWFyeSgpXG4gICAgLy8gZXZlbnRFbWl0dGVyLmVtaXQoJ3Nlc3Npb25DbG9zZScsIHsgc2Vzc2lvbjogdGhpcywgc3VtbWFyeUluZm8gfSlcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVNYWNoaW5lLmh1bmd1cCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOmAmuivneWqkuS9k+WPmOabtFxuICAgKiAgQHBhcmFtIG1lZGlhVHlwZSBSQ0NhbGxNZWRpYVR5cGUuQVVESU8g5pS55Li66Z+z6aKR6YCa6K+dIHwgUkNDYWxsTWVkaWFUeXBlLkFVRElPX1ZJREVPIOaUueS4uumfs+inhumikemAmuivnVxuICAgKi9cbiAgcHVibGljIGFzeW5jIF9jaGFuZ2VNZWRpYVR5cGUobWVkaWFUeXBlOiBSQ0NhbGxNZWRpYVR5cGUpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3N0YXRlTWFjaGluZS5jaGFuZ2VNZWRpYVR5cGUobWVkaWFUeXBlKTtcbiAgICBpZiAoY29kZSAhPT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBfY2hhbmdlTWVkaWFUeXBlXSBjaGFuZ2UgbWVkaWEgdHlwZSBmYWlsIGNvZGUtPiAke2NvZGV9YCk7XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflvpfmnKzlnLDop4bpopFcbiAgICovXG4gIHByaXZhdGUgX2dldExvY2FsVmlkZW9UcmFja3MoKTogUkNMb2NhbFRyYWNrW10ge1xuICAgIGxldCBsb2NhbFZpZGVvVHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IFtdO1xuICAgIGlmICghdGhpcy5fcm9vbSkge1xuICAgICAgcmV0dXJuIGxvY2FsVmlkZW9UcmFja3M7XG4gICAgfVxuICAgIGlmICh0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzKSB7XG4gICAgICBsb2NhbFZpZGVvVHJhY2tzID0gdGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcy5maWx0ZXIoKHRyYWNrKSA9PiB0cmFjay5pc1ZpZGVvVHJhY2soKSk7XG4gICAgfVxuICAgIHJldHVybiBsb2NhbFZpZGVvVHJhY2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+W+l+acrOWcsOmfs+mikVxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0TG9jYWxBdWRpb1RyYWNrcygpOiBSQ0xvY2FsVHJhY2tbXSB7XG4gICAgbGV0IGxvY2FsQXVkaW90cmFja3M6IFJDTG9jYWxUcmFja1tdID0gW107XG4gICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICByZXR1cm4gbG9jYWxBdWRpb3RyYWNrcztcbiAgICB9XG4gICAgaWYgKHRoaXMuX29wdGlvbnMubG9jYWxUcmFja3MpIHtcbiAgICAgIGxvY2FsQXVkaW90cmFja3MgPSB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzLmZpbHRlcigodHJhY2spID0+IHRyYWNrLmlzQXVkaW9UcmFjaygpKTtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2FsQXVkaW90cmFja3M7XG4gIH1cblxuICAvKipcbiAgICog5oqK6YCa6K+d55qETWVkaWFUeXBl5Y2H57qn5Yiw6Z+z6KeG6aKRXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIF9zZXRNZWRpYVR5cGVUb0F1ZGlvQW5kVmlkZW8oKSB7XG4gICAgLy8g6I635b6X5pys56uv6KeG6aKR6LWE5rqQXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjQ2xpZW50LmNyZWF0ZUNhbWVyYVZpZGVvVHJhY2soKTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5HRVRfTE9DQUxfQVVESU9fQU5EX1ZJREVPX1RSQUNLX0VSUk9SIH07XG4gICAgfVxuXG4gICAgLy8g5Y+R5biD5pys56uv6KeG6aKR6LWE5rqQXG4gICAgY29uc3QgeyBjb2RlOiBfY29kZSB9ID0gYXdhaXQgdGhpcy5fcm9vbS5wdWJsaXNoKFt0cmFjayFdKTtcblxuICAgIC8vIOiLpei1hOa6kOWPkeW4g+Wksei0pVxuICAgIGlmIChfY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBfZW5hYmxlVmlkZW9dIFJlc291cmNlIHB1Ymxpc2hpbmcgZmFpbGVkOiBSQ1JUQ0NvZGUgLT4gJHtjb2RlfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOmAmuefpeS4muWKoeWxgnRyYWNrUmVhZHlcbiAgICB0aGlzLl9ub3RpZnlUcmFja1JlYWR5KFt0cmFjayFdKTtcblxuICAgIC8vIOWPkea2iOaBr1xuICAgIHRoaXMuX2NoYW5nZU1lZGlhVHlwZShSQ0NhbGxNZWRpYVR5cGUuQVVESU9fVklERU8pO1xuICB9XG5cbiAgLyoqXG4gICAqIOaKiumAmuivneeahE1lZGlhVHlwZemZjee6p+WIsOmfs+mikVxuICAgKiBAcGFyYW0gaXNTZW5kTWVzc3NhZ2Ug5piv5ZCm6ZyA6KaB5Y+R5raI5oGvLCDpu5jorqTlj5Hmtojmga9cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX3NldE1lZGlhVHlwZVRvQXVkaW8oKSB7XG4gICAgY29uc3QgdHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IHRoaXMuX2dldExvY2FsVmlkZW9UcmFja3MoKTtcbiAgICBpZiAodHJhY2tzLmxlbmd0aCkge1xuICAgICAgLy8g56aB55So6KeG6aKRXG4gICAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IFJDTG9jYWxUcmFjaykgPT4ge1xuICAgICAgICB0cmFjay5tdXRlKCk7XG4gICAgICB9KTtcblxuICAgICAgLy8g5Y+W5raI5Y+R5biD6KeG6aKRXG4gICAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3Jvb20udW5wdWJsaXNoKHRyYWNrcyk7XG4gICAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIGRpc2FibGVWaWRlb10gdW5wdWJsaXNoIGZhaWxlZCAtPiAke2NvZGV9YCk7XG4gICAgICB9XG5cbiAgICAgIC8vIOWFs+mXreaRhOWDj+WktFxuICAgICAgdGhpcy5fZGVzdHJveVRyYWNrcyh0cmFja3MpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDpgJror53pmY3nuqfvvIznm67liY3pnIDmsYLlj6rlgZrpgJror53pmY3nuqfvvIzpn7Pop4bpopHlj6/ku6XpmY3nuqfkuLrpn7PpopHvvIzpn7PpopHkuI3og73ljYfliLDpn7Pop4bpopEsIOWPkea2iOaBr+aIkOWKn+aJjeeul+mZjee6p+aIkOWKn1xuICAgKlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRlc2NlbmRBYmlsaXR5KCk6IFByb21pc2U8eyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUgfT4ge1xuICAgIGNvbnN0IHsgY29kZSB9ID0gYXdhaXQgdGhpcy5fY2hhbmdlTWVkaWFUeXBlKFJDQ2FsbE1lZGlhVHlwZS5BVURJTyk7XG4gICAgaWYgKGNvZGUgPT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9zZXRNZWRpYVR5cGVUb0F1ZGlvKCk7XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnpoHnlKjop4bpopF0cmFja1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc2FibGVWaWRlb1RyYWNrKCk6IFByb21pc2U8eyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUgfT4ge1xuICAgIGlmICghdGhpcy5fcm9vbSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIGRpc2FibGVBdWRpb1RyYWNrXSBSb29tIG1pc3NpbmcgYXVkaW8gdHJhY2sgLT4gJHtSQ0NhbGxFcnJvckNvZGUuTk9UX0lOX1JPT01fRVJST1J9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuTk9UX0lOX1JPT01fRVJST1IgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmFja3M6IFJDTG9jYWxUcmFja1tdID0gdGhpcy5fZ2V0TG9jYWxWaWRlb1RyYWNrcygpO1xuICAgIGlmICghdHJhY2tzLmxlbmd0aCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIGRpc2FibGVWaWRlb1RyYWNrXSBSb29tIG1pc3NpbmcgdmlkZW8gdHJhY2sgLT4gJHtSQ0NhbGxFcnJvckNvZGUuTUlTU0lOR19WSURFT19UUkFDS19FUlJPUn1gKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5NSVNTSU5HX1ZJREVPX1RSQUNLX0VSUk9SIH07XG4gICAgfVxuXG4gICAgLy8g56aB55So6KeG6aKRXG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrOiBSQ0xvY2FsVHJhY2spID0+IHtcbiAgICAgIHRyYWNrLm11dGUoKTtcbiAgICB9KTtcblxuICAgIC8vIOWmguaenOS4jemcgOWFs+mXreaRhOWDj+WktFxuICAgIGlmICghdGhpcy5fb3B0aW9ucy5pc09mZkNhbWVyYVdoZW5WaWRlb0Rpc2FibGUpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTIH07XG4gICAgfVxuXG4gICAgLy8g5Y+W5raI5Y+R5biD6KeG6aKRXG4gICAgY29uc3QgeyBjb2RlIH0gPSBhd2FpdCB0aGlzLl9yb29tLnVucHVibGlzaCh0cmFja3MpO1xuICAgIGlmIChjb2RlICE9PSBSQ1JUQ0NvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIGRpc2FibGVWaWRlb10gdW5wdWJsaXNoIGZhaWxlZCAtPiAke2NvZGV9YCk7XG5cbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5VTlBVQkxJU0hfVklERU9fRVJST1IgfTtcbiAgICB9XG5cbiAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IFJDTG9jYWxUcmFjaykgPT4ge1xuICAgICAgLy8g5YWz6Zet5pGE5YOP5aS0XG4gICAgICB0cmFjay5kZXN0cm95KCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWQr+eUqOinhumikXRyYWNrXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW5hYmxlVmlkZW9UcmFjaygpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlIH0+IHtcbiAgICBpZiAoIXRoaXMuX3Jvb20pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBkaXNhYmxlQXVkaW9UcmFja10gUm9vbSBtaXNzaW5nIGF1ZGlvIHRyYWNrIC0+ICR7UkNDYWxsRXJyb3JDb2RlLk5PVF9JTl9ST09NX0VSUk9SfWApO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLk5PVF9JTl9ST09NX0VSUk9SIH07XG4gICAgfVxuXG4gICAgLy8g5aaC5p6c5LiN6ZyA5YWz6Zet5pGE5YOP5aS0XG4gICAgaWYgKCF0aGlzLl9vcHRpb25zLmlzT2ZmQ2FtZXJhV2hlblZpZGVvRGlzYWJsZSkge1xuICAgICAgY29uc3QgdHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IHRoaXMuX2dldExvY2FsVmlkZW9UcmFja3MoKTtcbiAgICAgIGlmICghdHJhY2tzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gRW5hYmxlVmlkZW9UcmFja10gUm9vbSBtaXNzaW5nIHZpZGVvIHRyYWNrIC0+ICR7UkNDYWxsRXJyb3JDb2RlLk1JU1NJTkdfVklERU9fVFJBQ0tfRVJST1J9YCk7XG4gICAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5NSVNTSU5HX1ZJREVPX1RSQUNLX0VSUk9SIH07XG4gICAgICB9XG5cbiAgICAgIC8vIOWQr+eUqOinhumikVxuICAgICAgdHJhY2tzLmZvckVhY2goKHRyYWNrOiBSQ0xvY2FsVHJhY2spID0+IHtcbiAgICAgICAgdHJhY2sudW5tdXRlKCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTIH07XG4gICAgfVxuXG4gICAgLy8g6I635b6X5pys56uv6KeG6aKR6LWE5rqQXG4gICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjQ2xpZW50LmNyZWF0ZUNhbWVyYVZpZGVvVHJhY2soKTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBFbmFibGVWaWRlb1RyYWNrXSBHZXQgUmVzb3VyY2UgZmFpbGVkOiBSQ1JUQ0NvZGUgLT4gJHtjb2RlfWApO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLkdFVF9MT0NBTF9WSURFT19UUkFDS19FUlJPUiB9O1xuICAgIH1cbiAgICBjb25zdCBsb2NhbFRyYWNrczogUkNMb2NhbFRyYWNrW10gPSBbXTtcbiAgICB0aGlzLl9vcHRpb25zLmxvY2FsVHJhY2tzICYmIHRoaXMuX29wdGlvbnMubG9jYWxUcmFja3MuZm9yRWFjaCgodHJhY2s6IFJDTG9jYWxUcmFjaykgPT4ge1xuICAgICAgaWYgKHRyYWNrLmlzVmlkZW9UcmFjaygpKSB7XG4gICAgICAgIC8vIOS5i+WJjeeahOinhumikemDvemUgOavgVxuICAgICAgICB0cmFjay5kZXN0cm95KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDlj6rnlZnkuIvkuYvliY3nmoTpn7PpopFcbiAgICAgICAgbG9jYWxUcmFja3MucHVzaCh0cmFjayk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyDliqDkuIrmnKzlnLDmlrDkuqfnlJ/nmoTop4bpopFcbiAgICBsb2NhbFRyYWNrcy5wdXNoKHRyYWNrISk7XG4gICAgdGhpcy5fb3B0aW9ucy5sb2NhbFRyYWNrcyA9IGxvY2FsVHJhY2tzO1xuXG4gICAgLy8g5Li65LqG6Kem5Y+R5a+55pa555qEb25WaWRlb011dGVDaGFuZ2Ug5YWI56aB55SoXG4gICAgdHJhY2shLm11dGUoKTtcblxuICAgIC8vIOWPkeW4g+acrOerr+inhumikei1hOa6kFxuICAgIGNvbnN0IHsgY29kZTogX2NvZGUgfSA9IGF3YWl0IHRoaXMuX3Jvb20ucHVibGlzaChbdHJhY2shXSk7XG5cbiAgICAvLyDoi6XotYTmupDlj5HluIPlpLHotKVcbiAgICBpZiAoX2NvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gRW5hYmxlVmlkZW9UcmFja10gUmVzb3VyY2UgcHVibGlzaGluZyBmYWlsZWQ6IFJDUlRDQ29kZSAtPiAke2NvZGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuVklERU9fUFVCTElTSF9FUlJPUiB9O1xuICAgIH1cblxuICAgIC8vIOWQr+eUqFxuICAgIHRyYWNrIS51bm11dGUoKTtcblxuICAgIC8vIOmAmuefpeS4muWKoeWxgnRyYWNrUmVhZHlcbiAgICB0aGlzLl9ub3RpZnlUcmFja1JlYWR5KFt0cmFjayFdKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOemgeeUqOmfs+mikXRyYWNrXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzYWJsZUF1ZGlvVHJhY2soKSB7XG4gICAgaWYgKCF0aGlzLl9yb29tKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbFNlc3Npb24gZGlzYWJsZUF1ZGlvVHJhY2tdIFJvb20gbWlzc2luZyBhdWRpbyB0cmFjayAtPiAke1JDQ2FsbEVycm9yQ29kZS5OT1RfSU5fUk9PTV9FUlJPUn1gKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5OT1RfSU5fUk9PTV9FUlJPUiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrczogUkNMb2NhbFRyYWNrW10gPSB0aGlzLl9nZXRMb2NhbEF1ZGlvVHJhY2tzKCk7XG5cbiAgICAvLyDnpoHnlKjpn7PpopFcbiAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IFJDTG9jYWxUcmFjaykgPT4ge1xuICAgICAgdHJhY2subXV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWQr+eUqOmfs+mikXRyYWNrXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW5hYmxlQXVkaW9UcmFjaygpIHtcbiAgICBpZiAoIXRoaXMuX3Jvb20pIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsU2Vzc2lvbiBkaXNhYmxlQXVkaW9UcmFja10gUm9vbSBtaXNzaW5nIGF1ZGlvIHRyYWNrIC0+ICR7UkNDYWxsRXJyb3JDb2RlLk5PVF9JTl9ST09NX0VSUk9SfWApO1xuICAgICAgcmV0dXJuIHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLk5PVF9JTl9ST09NX0VSUk9SIH07XG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSA9IHRoaXMuX2dldExvY2FsQXVkaW9UcmFja3MoKTtcblxuICAgIGlmICghdHJhY2tzLmxlbmd0aCkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIGRpc2FibGVBdWRpb1RyYWNrXSBSb29tIG1pc3NpbmcgYXVkaW8gdHJhY2sgLT4gJHtSQ0NhbGxFcnJvckNvZGUuTUlTU0lOR19WSURFT19UUkFDS19FUlJPUn1gKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5NSVNTSU5HX1ZJREVPX1RSQUNLX0VSUk9SIH07XG4gICAgfVxuXG4gICAgLy8g5ZCv55So6Z+z6aKRXG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrOiBSQ0xvY2FsVHJhY2spID0+IHtcbiAgICAgIHRyYWNrLnVubXV0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOmUgOavgeacrOWcsOa1gVxuICAgKi9cbiAgcHJpdmF0ZSBfZGVzdHJveVRyYWNrcyh0cmFja3M6IFJDTG9jYWxUcmFja1tdKSB7XG4gICAgdHJhY2tzLmZvckVhY2goKHRyYWNrOiBSQ0xvY2FsVHJhY2spID0+IHtcbiAgICAgIHRyYWNrLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlkJHlpJbmipvlh7rmnKzlnLDmtYFcbiAgICovXG4gIHByaXZhdGUgX25vdGlmeVRyYWNrUmVhZHkodHJhY2tzOiBSQ0xvY2FsVHJhY2tbXSB8IFJDUmVtb3RlVHJhY2tbXSkge1xuICAgIHRyYWNrcy5mb3JFYWNoKCh0cmFjazogUkNMb2NhbFRyYWNrIHwgUkNSZW1vdGVUcmFjaykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXIhLm9uVHJhY2tSZWFkeSh0cmFjaywgdGhpcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb24gX25vdGlmeVRyYWNrUmVhZHldIF9saXN0ZW5lciBvblRyYWNrUmVhZHkgZXhjZXB0aW9uJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOaIv+mXtOS4iuazqOWGjOS6i+S7tlxuICAgKi9cbiAgcHJpdmF0ZSBfcmVnaXN0ZXJSb29tRXZlbnRMaXN0ZW5lcigpIHtcbiAgICB0aGlzLl9yb29tLnJlZ2lzdGVyUm9vbUV2ZW50TGlzdGVuZXIoXG4gICAgICB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiDmnKznq6/ooqvouKLlh7rmiL/pl7Tml7bop6blj5FcbiAgICAgICAgICogQGRlc2NyaXB0aW9uIOiiq+i4ouWHuuaIv+mXtOWPr+iDveaYr+eUseS6juacjeWKoeerr+i2heWHuuS4gOWumuaXtumXtOacquiDveaUtuWIsCBydGNQaW5nIOa2iOaBr++8jOaJgOS7peiupOS4uuW3seaWueemu+e6v+OAglxuICAgICAgICAgKiDlj6bkuIDnp43lj6/og73mmK/lt7HmlrkgcnRjUGluZyDlpLHotKXmrKHmlbDotoXlh7rkuIrpmZDvvIzmlYXogIzkuLvliqjmlq3nur9cbiAgICAgICAgICogQHBhcmFtIGJ5U2VydmVyXG4gICAgICAgICAqIOW9k+WAvOS4uiBmYWxzZSDml7bvvIzor7TmmI7mnKznq68gcnRjUGluZyDotoXml7ZcbiAgICAgICAgICog5b2T5YC85Li6IHRydWUg5pe277yM6K+05piO5pys56uv5pS25Yiw6KKr6Lii5Ye65oi/6Ze06YCa55+lXG4gICAgICAgICAqL1xuICAgICAgICBvbktpY2tPZmY6IChieVNlcnZlcjogYm9vbGVhbiwgc3RhdGU/OiBSQ0tpY2tSZWFzb24gfCB1bmRlZmluZWQpID0+IHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXNlcklkOiBzdHJpbmcgPSB0aGlzLl9ydGNDbGllbnQuZ2V0Q3VycmVudElkKCk7XG4gICAgICAgICAgdGhpcy5fc3RhdGVNYWNoaW5lLnVzZXJMZWF2ZShbY3VycmVudFVzZXJJZF0pO1xuXG4gICAgICAgICAgaWYgKCFieVNlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5fZXhjZXB0aW9uQ2xvc2UoUkNDYWxsRW5kUmVhc29uLk5FVFdPUktfRVJST1IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09IFJDS2lja1JlYXNvbi5TRVJWRVJfS0lDSykge1xuICAgICAgICAgICAgICB0aGlzLl9leGNlcHRpb25DbG9zZShSQ0NhbGxFbmRSZWFzb24uS0lDS0VEX0JZX1NFUlZFUik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09IFJDS2lja1JlYXNvbi5PVEhFUl9LSUNLKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2V4Y2VwdGlvbkNsb3NlKFJDQ2FsbEVuZFJlYXNvbi5PVEhFUl9DTElFTlRfSk9JTkVEX0NBTEwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOaOpeaUtuWIsOaIv+mXtOS/oeS7pOaXtuWbnuiwg++8jOeUqOaIt+WPr+mAmui/h+aIv+mXtOWunuS+i+eahCBgc2VuZE1lc3NhZ2UobmFtZSwgY29udGVudClgIOaOpeWPo+WPkemAgeS/oeS7pFxuICAgICAgICAgKiBAcGFyYW0gbmFtZSDkv6Hku6TlkI1cbiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQg5L+h5Luk5YaF5a65XG4gICAgICAgICAqIEBwYXJhbSBzZW5kZXJVc2VySWQg5Y+R6YCB6ICFIElkXG4gICAgICAgICAqIEBwYXJhbSBtZXNzYWdlVUlkIOa2iOaBr+WUr+S4gOagh+ivhlxuICAgICAgICAgKi9cbiAgICAgICAgb25NZXNzYWdlUmVjZWl2ZShuYW1lOiBzdHJpbmcsIGNvbnRlbnQ6IGFueSwgc2VuZGVyVXNlcklkOiBzdHJpbmcsIG1lc3NhZ2VVSWQ6IHN0cmluZykge1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICog55uR5ZCs5oi/6Ze05bGe5oCn5Y+Y5pu06YCa55+lXG4gICAgICAgICAqIEBwYXJhbSBuYW1lXG4gICAgICAgICAqIEBwYXJhbSBjb250ZW50XG4gICAgICAgICAqL1xuICAgICAgICBvblJvb21BdHRyaWJ1dGVDaGFuZ2UobmFtZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpIHtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOWPkeW4g+iAheemgeeUqC/lkK/nlKjpn7PpopFcbiAgICAgICAgICogQHBhcmFtIGF1ZGlvVHJhY2sgUkNSZW1vdGVBdWRpb1RyYWNrIOexu+WunuS+i1xuICAgICAgICAgKi9cbiAgICAgICAgb25BdWRpb011dGVDaGFuZ2U6IChhdWRpb1RyYWNrOiBSQ1JlbW90ZUF1ZGlvVHJhY2spID0+IHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsU2Vzc2lvbiBvbkF1ZGlvTXV0ZUNoYW5nZV0gdXNlcklkLT4ke2F1ZGlvVHJhY2suZ2V0VXNlcklkKCl9IG11dGVkIC0+ICR7YXVkaW9UcmFjay5pc093bmVyTXV0ZWQoKX1gKTtcbiAgICAgICAgICBjb25zdCBtdXRlVXNlcjogSU11dGVVc2VyID0ge1xuICAgICAgICAgICAgdXNlcklkOiBhdWRpb1RyYWNrLmdldFVzZXJJZCgpLFxuICAgICAgICAgICAgbXV0ZWQ6IGF1ZGlvVHJhY2suaXNPd25lck11dGVkKCksXG4gICAgICAgICAgICBraW5kOiAnYXVkaW8nLFxuICAgICAgICAgICAgdHJhY2tJZDogYXVkaW9UcmFjay5nZXRUcmFja0lkKCksXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8g6YCa55+l57uZ5Lia5YqhXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25BdWRpb011dGVDaGFuZ2UobXV0ZVVzZXIsIHRoaXMpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb24gb25BdWRpb011dGVDaGFuZ2VdIE1pc3NpbmcgbGlzdGVuaW5nIG1ldGhvZCAtPiBvblRyYWNrTXV0ZUNoYW5nZScpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICog5Y+R5biD6ICF56aB55SoL+WQr+eUqOinhumikVxuICAgICAgICAgKiBAcGFyYW0gdmlkZW9UcmFjayBSQ1JlbW90ZVZpZGVvVHJhY2sg57G75a6e5L6L5a+56LGhXG4gICAgICAgICAqL1xuICAgICAgICBvblZpZGVvTXV0ZUNoYW5nZTogKHZpZGVvVHJhY2s6IFJDUmVtb3RlVmlkZW9UcmFjaykgPT4ge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uVmlkZW9NdXRlQ2hhbmdlXXVzZXJJZC0+JHt2aWRlb1RyYWNrLmdldFVzZXJJZCgpfSBtdXRlZCAtPiAke3ZpZGVvVHJhY2suaXNPd25lck11dGVkKCl9YCk7XG4gICAgICAgICAgY29uc3QgbXV0ZVVzZXI6IElNdXRlVXNlciA9IHtcbiAgICAgICAgICAgIHVzZXJJZDogdmlkZW9UcmFjay5nZXRVc2VySWQoKSxcbiAgICAgICAgICAgIG11dGVkOiB2aWRlb1RyYWNrLmlzT3duZXJNdXRlZCgpLFxuICAgICAgICAgICAga2luZDogJ3ZpZGVvJyxcbiAgICAgICAgICAgIHRyYWNrSWQ6IHZpZGVvVHJhY2suZ2V0VHJhY2tJZCgpLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8g6YCa55+l57uZ5Lia5YqhXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25WaWRlb011dGVDaGFuZ2UobXV0ZVVzZXIsIHRoaXMpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb24gb25WaWRlb011dGVDaGFuZ2VdIE1pc3NpbmcgbGlzdGVuaW5nIG1ldGhvZCAtPiBvblZpZGVvTXV0ZUNoYW5nZScpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICog5oi/6Ze05YaF5YW25LuW55So5oi35paw5Y+R5biD6LWE5rqQ5pe26Kem5Y+RXG4gICAgICAgICAqIOWmgumcgOiOt+WPluWKoOWFpeaIv+mXtOS5i+WJjeaIv+mXtOWGheafkOS4queUqOaIt+WPkeW4g+eahOi1hOa6kOWIl+ihqO+8jOWPr+S9v+eUqCByb29tLmdldFJlbW90ZVRyYWNrc0J5VXNlcklkKCd1c2VySWQnKSDojrflj5ZcbiAgICAgICAgICogQHBhcmFtIHRyYWNrcyDmlrDlj5HluIPnmoTpn7PovajkuI7op4bovajmlbDmja7liJfooajvvIzljIXlkKvmlrDlj5HluIPnmoQgUkNSZW1vdGVBdWRpb1RyYWNrIOS4jiBSQ1JlbW90ZVZpZGVvVHJhY2sg5a6e5L6LXG4gICAgICAgICAqL1xuICAgICAgICBvblRyYWNrUHVibGlzaDogYXN5bmMgKHRyYWNrczogUkNSZW1vdGVUcmFja1tdKSA9PiB7XG4gICAgICAgICAgLy8g6YCA5Ye65oi/6Ze05ZCO77yM6L+Y5Lya6LWw5Yiw6L+Z77yf77yf77yM5omA5Lul5Yik5pat5LiA5LiL77yM5rKh5pyJcm9vbeS4jeaJp+ihjOiuoumYhVxuICAgICAgICAgIGlmICh0aGlzLl9yb29tKSB7XG4gICAgICAgICAgICAvLyDmjInkuJrliqHpnIDmsYLpgInmi6npnIDopoHorqLpmIXotYTmupDvvIzpgJrov4cgcm9vbS5zdWJzY3JpYmUg5o6l5Y+j6L+b6KGM6K6i6ZiFXG4gICAgICAgICAgICBjb25zdCB7IGNvZGUgfSA9IGF3YWl0IHRoaXMuX3Jvb20uc3Vic2NyaWJlKHRyYWNrcyk7XG4gICAgICAgICAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgICAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uVHJhY2tQdWJsaXNoXSBzdWJzY3JpYmUgZmFpbGVkIFJUQ0NvZGUgLT4ke2NvZGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICog5oi/6Ze055So5oi35Y+W5raI5Y+R5biD6LWE5rqQXG4gICAgICAgICAqIEBwYXJhbSB0cmFja3Mg6KKr5Y+W5raI5Y+R5biD55qE6Z+z6L2o5LiO6KeG6L2o5pWw5o2u5YiX6KGoXG4gICAgICAgICAqIEBkZXNjcmlwdGlvbiDlvZPotYTmupDooqvlj5bmtojlj5HluIPml7bvvIxTREsg5YaF6YOo5Lya5Y+W5raI5a+555u45YWz6LWE5rqQ55qE6K6i6ZiF77yM5Lia5Yqh5bGC5LuF6ZyA5aSE55CGIFVJIOS4muWKoVxuICAgICAgICAgKi9cbiAgICAgICAgb25UcmFja1VucHVibGlzaDogKHRyYWNrczogUkNSZW1vdGVUcmFja1tdKSA9PiB7XG5cbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOiuoumYheeahOmfs+inhumikea1gemAmumBk+W3suW7uueriywgdHJhY2sg5bey5Y+v5Lul6L+b6KGM5pKt5pS+XG4gICAgICAgICAqIEBwYXJhbSB0cmFjayBSQ1JlbW90ZVRyYWNrIOexu+WunuS+i1xuICAgICAgICAgKi9cbiAgICAgICAgb25UcmFja1JlYWR5OiAodHJhY2s6IFJDUmVtb3RlVHJhY2spID0+IHtcbiAgICAgICAgICBjb25zdCBtZWRpYVR5cGUgPSB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0TWVkaWFUeXBlKCk7XG5cbiAgICAgICAgICAvLyDmnInml7blr7nmlrnmsqHmnInpmY3nuqfmiJDlip/vvIzmiZTmipvov4fmnaXop4bpopHvvIzov5nml7bnmoTop4bpopHkuI3lr7nlpJbmipvlh7pcbiAgICAgICAgICBpZiAobWVkaWFUeXBlID09PSBSQ0NhbGxNZWRpYVR5cGUuQVVESU8gJiYgdHJhY2suaXNWaWRlb1RyYWNrKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDmiafooYznlKjmiLfnmoRvblRyYWNrUmVhZHnnm5HlkKxcbiAgICAgICAgICB0aGlzLl9ub3RpZnlUcmFja1JlYWR5KFt0cmFja10pO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICog5Lq65ZGY5Yqg5YWlXG4gICAgICAgICAqIEBwYXJhbSB1c2VySWRzIOWKoOWFpeeahOS6uuWRmCBpZCDliJfooahcbiAgICAgICAgICovXG4gICAgICAgIG9uVXNlckpvaW46ICh1c2VySWRzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICAgIC8vIOacieS6uuWKoOWFpea4hemZpOWumuaXtuWZqFxuICAgICAgICAgIGlmICh0aGlzLmpvaW5Sb29tVGltZXIpIHtcbiAgICAgICAgICAgIHRoaXMuam9pblJvb21UaW1lci5zdG9wKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX3N0YXRlTWFjaGluZS51c2VySm9pbih1c2VySWRzKTtcbiAgICAgICAgfSxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIOS6uuWRmOmAgOWHulxuICAgICAgICAgKiBAcGFyYW0gdXNlcklkc1xuICAgICAgICAgKi9cbiAgICAgICAgb25Vc2VyTGVhdmU6ICh1c2VySWRzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxTZXNzaW9uIG9uVXNlckxlYXZlXSBsaXN0ZW5pbmcgb25Vc2VyTGVhdmUgdXNlcklkcyAtPiAke3VzZXJJZHM/LmpvaW4oJywnKX1gKTtcbiAgICAgICAgICB0aGlzLl9zdGF0ZU1hY2hpbmUudXNlckxlYXZlKHVzZXJJZHMpO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICogUlRDIOavj+asoSBQaW5nIOe7k+aenFxuICAgICAgICAgKi9cbiAgICAgICAgb25QaW5nOiAocmVzdWx0OiBSQ1JUQ1BpbmdSZXN1bHQpID0+IHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsIGBbUkNDYWxsU2Vzc2lvbiBvblBpbmddJHtyZXN1bHR9YCk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIOmAmuefpee7meS4muWKoVxuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXIhLm9uUGluZyAmJiB0aGlzLl9saXN0ZW5lciEub25QaW5nKHJlc3VsdCwgdGhpcyk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsU2Vzc2lvbiBvblBpbmddIGxpc3RlbmluZyBvblBpbmcgZXhjZXB0aW9uJyk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5rOo5YaM5oi/6Ze06LSo6YeP5pWw5o2u55uR5ZCs5ZmoXG4gICAqL1xuICBwcml2YXRlIF9yZWdpc3RlclJlcG9ydExpc3RlbmVyKCkge1xuICAgIC8vIOazqOWGjOaIv+mXtOi0qOmHj+aVsOaNruebkeWQrOWZqFxuICAgIHRoaXMuX3Jvb20ucmVnaXN0ZXJSZXBvcnRMaXN0ZW5lcih7XG4gICAgICAvKipcbiAgICAgICAqIOeUqOS6juaOpeaUtueKtuaAgeaVsOaNruaKpeWRilxuICAgICAgICogQHBhcmFtIHJlcG9ydFxuICAgICAgICovXG4gICAgICBvblN0YXRlUmVwb3J0OiAocmVwb3J0OiBJUkNSVENTdGF0ZVJlcG9ydCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuX2xpc3RlbmVyIS5vblJUQ1N0YXRlUmVwb3J0ICYmIHRoaXMuX2xpc3RlbmVyIS5vblJUQ1N0YXRlUmVwb3J0KHJlcG9ydCwgdGhpcyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgJ1tSQ0NhbGxTZXNzaW9uIG9uU3RhdGVSZXBvcnRdIGxpc3RlbmVyIG9uU3RhdGVSZXBvcnQgZXhjZXB0aW9uJyk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogfklDRSDov57mjqXnirbmgIHlj5jmm7TpgJrnn6V+XG4gICAgICAgKiBAc2luY2UgdmVyc2lvbiA1LjEuNVxuICAgICAgICovXG4gICAgICBvbklDRUNvbm5lY3Rpb25TdGF0ZUNoYW5nZTogKHN0YXRlOiBSVENJY2VDb25uZWN0aW9uU3RhdGUpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLl9saXN0ZW5lciEub25JQ0VDb25uZWN0aW9uU3RhdGVDaGFuZ2UgJiYgdGhpcy5fbGlzdGVuZXIhLm9uSUNFQ29ubmVjdGlvblN0YXRlQ2hhbmdlKHN0YXRlLCB0aGlzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ2FsbFNlc3Npb24gb25JQ0VDb25uZWN0aW9uU3RhdGVDaGFuZ2VdIG9uSUNFQ29ubmVjdGlvblN0YXRlQ2hhbmdlIGV4Y2VwdGlvbicpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogIOmAmuivneWUr+S4gOagh+ivhlxuICAgKi9cbiAgcHVibGljIGdldFNlc3Npb25JZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0Q2FsbElkKCk7XG4gIH1cblxuICAvKipcbiAgICogIOiOt+WPluaIv+mXtOW9k+WJjeS8muivnSBJZO+8jOW9k+aIv+mXtOWGheW3suaXoOaIkOWRmOaXtuaIv+mXtOS8muWbnuaUtu+8jOmHjeaWsOWKoOWFpeaXtiBzZXNzaW9uSWQg5bCG5pu05paw77yMKOeUqOaIt+W9leWItui1hOa6kOeUqOeahClcbiAgICovXG4gIHB1YmxpYyBnZXRSVENTZXNzaW9uSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3Jvb20gPyB0aGlzLl9yb29tLmdldFNlc3Npb25JZCgpIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiAg55uu5qCHIElE77yM5Y2V5ZG85a+55pa55Lq65ZGYIElkLCDnvqTlkbznvqTnu4QgSWRcbiAgICovXG4gIHB1YmxpYyBnZXRUYXJnZXRJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0VGFyZ2V0SWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAg6I635Y+W5Lya6K+d57G75Z6LXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29udmVyc2F0aW9uVHlwZSgpOiBDb252ZXJzYXRpb25UeXBlIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVNYWNoaW5lLmdldENvbnZlcnNhdGlvblR5cGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAg57uE57uHIElEXG4gICAqL1xuICBwdWJsaWMgZ2V0Q2hhbm5lbElkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlTWFjaGluZS5nZXRDaGFubmVsSWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmiL/pl7TkurrlkZjliJfooajvvIzkuI3ljIXlkKvmnKznq6/kv6Hmga9cbiAgICovXG4gIHB1YmxpYyBnZXRSZW1vdGVVc2VycygpOiBJVXNlckRhdGFbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlTWFjaGluZS5nZXRSZW1vdGVVc2VycygpO1xuICB9XG5cbiAgLyoqXG4gKiDmiL/pl7TkurrlkZjliJfooajvvIzkuI3ljIXlkKvmnKznq6/kv6Hmga9cbiAqL1xuICBwdWJsaWMgZ2V0VXNlcnMoKTogSVVzZXJEYXRhW10ge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0UmVtb3RlVXNlcnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5bkurrlkZjnirbmgIFcbiAgICovXG4gIHB1YmxpYyBnZXRVc2VyU3RhdGUodXNlcklkOiBzdHJpbmcpOiBSQ0NhbGxVc2VyU3RhdGUge1xuICAgIGlmICghdXNlcklkIHx8IHR5cGVvZiB1c2VySWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXJJZCBpcyByZXF1aXJlZCwgbXVzdCBiZSBvZiB0eXBlIFxcJ3N0cmluZ1xcJycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RhdGVNYWNoaW5lLmdldFVzZXJTdGF0ZSh1c2VySWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPlnNlc3Npb27nirbmgIFcbiAgICovXG4gIHB1YmxpYyBnZXRTdGF0ZSgpOiBSQ0NhbGxTZXNzaW9uU3RhdGUge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0U3RhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflvpfkvJror53lj5HotbfogIVpZFxuICAgKi9cbiAgcHVibGljIGdldENhbGxlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlTWFjaGluZS5nZXRDYWxsZXJJZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+W+l21lZGlhVHlwZVxuICAgKi9cbiAgcHVibGljIGdldE1lZGlhVHlwZSgpOiBSQ0NhbGxNZWRpYVR5cGUge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZU1hY2hpbmUuZ2V0TWVkaWFUeXBlKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIFJUQ1BsdWdpbkNvbnRleHQsIElSdW50aW1lLCBJUlRDSm9pbmVkSW5mbywgRXJyb3JDb2RlLCBSVENKb2luVHlwZSwgSUxvZ2dlciwgQmFzaWNMb2dnZXIsXG59IGZyb20gJ0Byb25nY2xvdWQvZW5naW5lJztcbmltcG9ydCB7XG4gIFJDQ2FsbEVuZ2luZSwgUkNDYWxsU3RhdGVNYWNoaW5lLCBSQ0NhbGxFcnJvckNvZGUsIFJDQ2FsbExhbmd1YWdlLCBSQ0NhbGxNZWRpYVR5cGUsIElPZmZsaW5lUmVjb3JkLFxufSBmcm9tICdAcmMtZW1iZWQvY2FsbC1lbmdpbmUnO1xuaW1wb3J0IHsgUkNSVENDbGllbnQsIFJDUlRDQ29kZSwgUkNMb2NhbFRyYWNrIH0gZnJvbSAnQHJvbmdjbG91ZC9wbHVnaW4tcnRjJztcbmltcG9ydCB7XG4gIElSQ0NhbGxJbkdyb3VwUGFyYW1zLCBJUkNDYWxsSW5pdE9wdGlvbnMsIElSQ0NhbGxQYXJhbXMsIElNZWRpYVN0cmVhbUNvbnN0cmFpbnRzLCBJVmFsaWRhdGlvblJlc3VsdCwgSVB1c2hDb25maWcsXG59IGZyb20gJy4vaW50ZXJmYWNlJztcbmltcG9ydCB7IFByb2R1Y2VUeXBlcyB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IGV2ZW50RW1pdHRlciBmcm9tICcuL2V2ZW50RW1pdHRlcic7XG5pbXBvcnQgeyBSQ0NhbGxTZXNzaW9uIH0gZnJvbSAnLi9SQ0NhbGxTZXNzaW9uJztcbmltcG9ydCB7XG4gIHZhbGlkYXRlTGlzdGVuZXIsIHZhbGlkYXRlVGFyZ2V0SWQsIHZhbGlkYXRlTWVkaWFUeXBlLCB2YWxpZGF0ZVVzZXJJZHMsIHZhbGlkYXRlRXh0cmEsIHZhbGlkYXRlUHVzaENvbmZpZyxcbn0gZnJvbSAnLi92YWxpZGF0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUkNDYWxsQ2xpZW50IHtcbiAgLyoqXG4gICAqIHJ0Y+WunuS+i1xuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfcnRjQ2xpZW50OiBSQ1JUQ0NsaWVudFxuXG4gIC8qKlxuICAgKiBjYWxsRW5naW5l5bGC5a6e5L6LXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9jYWxsRW5naW5lOiBSQ0NhbGxFbmdpbmVcblxuICAvKipcbiAgICog5YW25a6D5Y+C5pWwXG4gICAqL1xuICBwcml2YXRlIF9vcHRpb25zOiBJUkNDYWxsSW5pdE9wdGlvbnNcblxuICAvKipcbiAgICogc2Vzc2lvbuWIl+ihqFxuICAgKi9cbiAgcHJpdmF0ZSBfc2Vzc2lvbkxpc3Q6IFJDQ2FsbFNlc3Npb25bXSA9IFtdXG5cbiAgLyoqXG4gICAqIOenu+WKqOerr+WRvOWPq+aOqOmAgemFjee9rlxuICAgKi9cbiAgcHJpdmF0ZSBfY2FsbFB1c2hDb25maWc/OiBJUHVzaENvbmZpZ1xuXG4gIC8qKlxuICAgKiDnp7vliqjnq6/mjILmlq3mjqjpgIHphY3nva5cbiAgICovXG4gIHByaXZhdGUgX2h1bmd1cFB1c2hDb25maWc/OiBJUHVzaENvbmZpZ1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2NvbnRleHQ6IFJUQ1BsdWdpbkNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcnVudGltZTogSVJ1bnRpbWUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbG9nZ2VyOiBCYXNpY0xvZ2dlcixcbiAgICBfb3B0aW9uczogSVJDQ2FsbEluaXRPcHRpb25zLFxuICApIHtcbiAgICB0aGlzLl9ydGNDbGllbnQgPSBfb3B0aW9ucy5ydGNDbGllbnQ7XG5cbiAgICB0aGlzLl9vcHRpb25zID0geyAvKipcbiAgICAgICAqIOaYr+WQpuWFgeiuuOWPkeW4g+mHjeivle+8jCDpu5jorqTkuI3lhYHorrhcbiAgICAgICAqL1xuICAgICAgaXNBbGxvd1B1Ymxpc2hSZXRyeTogZmFsc2UsXG5cbiAgICAgIC8qKlxuICAgICAgICog5piv5ZCm5YWB6K646K6i6ZiF6YeN6K+V77yM6buY6K6k5LiN5YWB6K64XG4gICAgICAgKi9cbiAgICAgIGlzQWxsb3dTdWJzY3JpYmVSZXRyeTogZmFsc2UsXG4gICAgICAvKipcbiAgICAgICAqIOemgeeUqOinhumikeaXtuWFs+aRhOWDj+WktCwg6buY6K6k5YWz6ZetXG4gICAgICAgKi9cbiAgICAgIGlzT2ZmQ2FtZXJhV2hlblZpZGVvRGlzYWJsZTogdHJ1ZSxcbiAgICAgIC8qKlxuICAgICAgICogUlRDIOaIv+mXtOWKoOWFpeexu+Wei++8jOm7mOiupCAgIFJUQ0pvaW5UeXBlLkNPRVhJU1QgPSAyIOS4pOS4quiuvuWkh+WFseWtmFxuICAgICAgICogICAgIFJUQ0pvaW5UeXBlLktJQ0sgPSAwLOi4ouWJjeS4gOS4quiuvuWkh1xuICAgICAgICogICAgIFJUQ0pvaW5UeXBlLlJFRlVTRSA9IDEs5b2T5YmN5Yqg5YWl5ouS57udXG4gICAgICAgKiAgICAgUlRDSm9pblR5cGUuQ09FWElTVCA9IDIg5Lik5Liq6K6+5aSH5YWx5a2YXG4gICAgICAgKi9cbiAgICAgIGpvaW5UeXBlOiBSVENKb2luVHlwZS5DT0VYSVNULFxuXG4gICAgICAvKipcbiAgICAgICAqIOWFgeiuuOmZjee6p+iOt+W+l+a1ge+8jOiOt+W+l+mfs+inhumikeS4jeaIkOWKnyDvvIzpmY3nuqfojrflvpfpn7PpopEsIOm7mOiupOS4jeWFgeiuuFxuICAgICAgICovXG4gICAgICBpc0FsbG93RGVtb3Rpb25HZXRTdHJlYW06IGZhbHNlLFxuXG4gICAgICAvKipcbiAgICAgICAqIOivreiogOiuvue9riAo5o6o6YCBKSwg5LiN5Lyg6buY6K6k5Li65Lit5paHXG4gICAgICAgKi9cbiAgICAgIGxhbmc6IFJDQ2FsbExhbmd1YWdlLlpILFxuICAgICAgLi4uX29wdGlvbnMsXG4gICAgfTtcblxuICAgIC8vIOWIneWni+WMlmNhbGxFbmdpbmUsIOW5tuebkeWQrG9uSW52aXRlXG4gICAgdGhpcy5fY2FsbEVuZ2luZSA9IG5ldyBSQ0NhbGxFbmdpbmUodGhpcy5fY29udGV4dCwgX3J1bnRpbWUsIHRoaXMuX2xvZ2dlciwge1xuXG4gICAgICAvKipcbiAgICAgICAqIOebkeWQrOaUtuWIsGludml0ZVxuICAgICAgICovXG4gICAgICBvbkludml0ZTogdGhpcy5fb25JbnZpdGUuYmluZCh0aGlzKSxcblxuICAgICAgLyoqXG4gICAgICAgKiDnm5HlkKznprvnur/mtojmga/miqXlkYpcbiAgICAgICAqL1xuICAgICAgb25PZmZsaW5lUmVjb3JkOiB0aGlzLl9vbk9mZmxpbmVSZWNvcmQuYmluZCh0aGlzKSxcbiAgICB9LCB7XG5cbiAgICAgIC8qKlxuICAgICAgICog6K+t6KiA6K6+572uICjmjqjpgIEpLCDkuI3kvKDpu5jorqTkuLrkuK3mlodcbiAgICAgICAqL1xuICAgICAgbGFuZzogdGhpcy5fb3B0aW9ucy5sYW5nIHx8IFJDQ2FsbExhbmd1YWdlLlpILFxuXG4gICAgfSk7XG5cbiAgICBldmVudEVtaXR0ZXIub24oJ3Nlc3Npb25DbG9zZScsICh7IHNlc3Npb24sIHN1bW1hcnlJbmZvIH0pID0+IHtcbiAgICAgIC8vIOS7jnNlc3Npb25MaXN05Y675o6J6L+Z5Liq5YWz6Zet55qEc2Vzc2lvblxuICAgICAgdGhpcy5fcmVtb3ZlU2Vzc2lvbihzZXNzaW9uKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucy5vblNlc3Npb25DbG9zZShzZXNzaW9uLCBzdW1tYXJ5SW5mbyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCAnW1JDQ0NhbGxDbGllbnRdIG9wdGlvbnMub25TZXNzaW9uQ2xvc2UgZXhjZXB0aW9uJyk7XG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIOaOpeWQrOS5i+WJjeaMguaWreWFtuWug+eahHNlc3Npb25cbiAgICBldmVudEVtaXR0ZXIub24oJ2h1bmd1cE90aGVyU2Vzc2lvbicsICh7IHNlc3Npb24gfSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSBzZXNzaW9uLmdldFNlc3Npb25JZCgpO1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbENsaWVudCBodW5ndXBPdGhlclNlc3Npb25dIHNlc3Npb25JZCByZWFkeSB0byBhY2NlcHQgLT4gJHtpZH1gKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxDbGllbnQgaHVuZ3VwT3RoZXJTZXNzaW9uXSBzZXNzaW9uTGlzdCAtPiR7dGhpcy5fc2Vzc2lvbkxpc3QubWFwKChzZXMpID0+IHNlcy5nZXRTZXNzaW9uSWQoKSkuam9pbignLCcpfWApO1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgd2hpbGUgKHRoaXMuX3Nlc3Npb25MaXN0Lmxlbmd0aCA+IDEpIHtcbiAgICAgICAgLy8g5aaC5p6c5LiO6KaB5o6l5ZCs55qEc2Vzc2lvbuS4jeS4gOiHtFxuICAgICAgICBpZiAodGhpcy5fc2Vzc2lvbkxpc3RbaV0uZ2V0U2Vzc2lvbklkKCkgIT09IGlkKSB7XG4gICAgICAgICAgLy8g5oyC5patXG4gICAgICAgICAgdGhpcy5fc2Vzc2lvbkxpc3RbaV0uaHVuZ3VwKCk7XG5cbiAgICAgICAgICAvLyDmjILmlq3lkI7liKDpmaRcbiAgICAgICAgICB0aGlzLl9zZXNzaW9uTGlzdC5zcGxpY2UoaSwgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8g5aaC5p6c5piv6KaB5o6l5ZCs55qEc2Vzc2lvbu+8jOi3s+i/h+i/meS4que0ouW8le+8jOaJgOS7peWKoDFcbiAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxDbGllbnQgaHVuZ3VwT3RoZXJTZXNzaW9uXSBjdXJyZW50IHNlc3Npb25MaXN0IGxlbmd0aCAtPiR7dGhpcy5fc2Vzc2lvbkxpc3QubGVuZ3RofWApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOebkeWQrG9uSW52aXRlXG4gICAqL1xuICBwcml2YXRlIF9vbkludml0ZShzdGF0ZU1hY2hpbmU6IFJDQ2FsbFN0YXRlTWFjaGluZSwgZXh0cmE/OiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdbUkNDYWxsQ2xpZW50IF9vbkludml0ZV0gUmVjZWl2ZWQgaW52aXRlIG1lc3NhZ2UnKTtcbiAgICBjb25zdCBzZXNzaW9uID0gbmV3IFJDQ2FsbFNlc3Npb24oc3RhdGVNYWNoaW5lLCB0aGlzLl9ydGNDbGllbnQsIHRoaXMuX2xvZ2dlciwge1xuXG4gICAgICAvLyDmmK/lkKblhYHorrjorqLpmIXph43or5VcbiAgICAgIGlzQWxsb3dTdWJzY3JpYmVSZXRyeTogdGhpcy5fb3B0aW9ucy5pc0FsbG93U3Vic2NyaWJlUmV0cnksXG5cbiAgICAgIC8vIOaYr+WQpuWFgeiuuOWPkeW4g+mHjeivlVxuICAgICAgaXNBbGxvd1B1Ymxpc2hSZXRyeTogdGhpcy5fb3B0aW9ucy5pc0FsbG93UHVibGlzaFJldHJ5LFxuXG4gICAgICAvKipcbiAgICAgICAqIOemgeeUqOinhumikeaXtuWFs+aRhOWDj+WktFxuICAgICAgICovXG4gICAgICBpc09mZkNhbWVyYVdoZW5WaWRlb0Rpc2FibGU6IHRoaXMuX29wdGlvbnMuaXNPZmZDYW1lcmFXaGVuVmlkZW9EaXNhYmxlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFJUQyDmiL/pl7TliqDlhaXnsbvlnotcbiAgICAgICAqL1xuICAgICAgam9pblR5cGU6IHRoaXMuX29wdGlvbnMuam9pblR5cGUsXG5cbiAgICAgIC8vIOWFgeiuuOmZjee6p+iOt+W+l+a1ge+8jOiOt+W+l+mfs+inhumikeS4jeaIkOWKnyDvvIzpmY3nuqfojrflvpfpn7PpopEsIOm7mOiupOS4jeWFgeiuuFxuICAgICAgaXNBbGxvd0RlbW90aW9uR2V0U3RyZWFtOiB0aGlzLl9vcHRpb25zLmlzQWxsb3dEZW1vdGlvbkdldFN0cmVhbSxcblxuICAgICAgLy8g5qCH5piO5piv6KKr5Y+r5Lqn55Sf55qEc2Vzc2lvblxuICAgICAgcHJvZHVjZVR5cGU6IFByb2R1Y2VUeXBlcy5DQUxMRUUsXG5cbiAgICAgIGNhbGxQdXNoQ29uZmlnOiB0aGlzLl9jYWxsUHVzaENvbmZpZyxcblxuICAgICAgaHVuZ3VwUHVzaENvbmZpZzogdGhpcy5faHVuZ3VwUHVzaENvbmZpZyxcbiAgICB9KTtcbiAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdbUkNDYWxsQ2xpZW50IF9vbkludml0ZV0gUmVjZWl2ZWQgaW52aXRlIG1lc3NhZ2UsIHN1Y2Nlc3NmdWxseSBjcmVhdGVkIHNlc3Npb24nKTtcblxuICAgIC8qKlxuICAgICAqIOWmguaenOmAmuivneeahOaXtuWAmeS4jeWFgeiuuOaOpeWQrOaWsOeahOmAmuivne+8jOebtOaOpeaMguaWre+8jCDov5nkupvlt6XkvZzlnKhjYWxsRW5naW5l6YeM5a6M5oiQXG4gICAgICovXG4gICAgdGhpcy5fc2Vzc2lvbkxpc3QucHVzaChzZXNzaW9uKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyDmiafooYznlKjmiLdBUEnnmoTnm5HlkKxcbiAgICAgIHRoaXMuX29wdGlvbnMub25TZXNzaW9uKHNlc3Npb24sIGV4dHJhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgJ1tSQ0NhbGxDbGllbnQgX29wdGlvbnMub25TZXNzaW9uXSBvblNlc3Npb24gZXhjZXB0aW9uJyk7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgfVxuXG4gICAgLy8g5b+F6aG75Zyob25TZXNzaW9u6YeM5rOo5YaMc2Vzc2lvbuebkeWQrOS6i+S7tu+8jOi/memHjOajgOa1i+S4gOS4i+acieayoeacieazqOWGjFxuICAgIGlmIChzZXNzaW9uLl9saXN0ZW5lcikge1xuICAgICAgY29uc3QgY29uY2x1c2lvbjogSVZhbGlkYXRpb25SZXN1bHQgPSB2YWxpZGF0ZUxpc3RlbmVyKHNlc3Npb24uX2xpc3RlbmVyKTtcbiAgICAgIGlmICghY29uY2x1c2lvbi5yZXN1bHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGNvbmNsdXNpb24ubXNnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgJ1tSQ0NhbGxDbGllbnQgX29wdGlvbnMub25TZXNzaW9uXSBzZXNzaW9uIE11c3QgSGF2ZSBMaXN0ZW5lcicpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbUkNDYWxsU2Vzc2lvbiAgX29wdGlvbnMub25TZXNzaW9uXSBzZXNzaW9uIE11c3QgSGF2ZSBMaXN0ZW5lcicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDnm5HlkKznprvnur/mtojmga/miqXlkYpcbiAgICogQHBhcmFtIHJlY29yZFxuICAgKi9cbiAgcHVibGljIF9vbk9mZmxpbmVSZWNvcmQocmVjb3JkOiBJT2ZmbGluZVJlY29yZCkge1xuICAgIHRyeSB7XG4gICAgICAvLyDmiafooYznlKjmiLdBUEnnmoTnm5HlkKxcbiAgICAgIHRoaXMuX29wdGlvbnMub25PZmZsaW5lUmVjb3JkICYmIHRoaXMuX29wdGlvbnMub25PZmZsaW5lUmVjb3JkKHJlY29yZCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsICdbUkNDYWxsQ2xpZW50IF9vcHRpb25zLm9uT2ZmbGluZVJlY29yZF0gb25PZmZsaW5lUmVjb3JkIGV4Y2VwdGlvbicpO1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDms6jlhoznlKjmiLfkv6Hmga/jgILms6jlhozlkI7vvIzlnKjlj5HotbfpgoDor7fmiJbmjILmlq3nrYnmk43kvZzml7bvvIzkvJrlsIbor6Xkv6Hmga/kuIDlubblj5HpgIHnu5nlr7nnq69cbiAgICogQHBhcmFtIGluZm8ubmFtZSAgICAgICAg55So5oi35ZCN56ewXG4gICAqIEBwYXJhbSBpbmZvLnBvcnRyYWl0VXJpIOeUqOaIt+WktOWDj+S/oeaBr1xuICAgKiBAcGFyYW0gaW5mby5leHRyYSAgICAgICDpooTnlZnmi5PlsZXlrZfmrrVcbiAgICovXG4gIHB1YmxpYyByZWdpc3RlclVzZXJJbmZvKGluZm86IHsgbmFtZT86IHN0cmluZzsgcG9ydHJhaXRVcmk/OiBzdHJpbmc7IGV4dHJhPzogc3RyaW5nOyB9ID0ge30pIHtcbiAgICB0aGlzLl9jYWxsRW5naW5lLnJlZ2lzdGVyVXNlckluZm8oaW5mbyk7XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCAnW1JDQ2FsbENsaWVudCByZWdpc3RlclVzZXJJbmZvXSBzdWNjZXNzZnVsbHkgcmVnaXN0ZXIgdXNlciBpbmZvIGRhdGEnKTtcbiAgfVxuXG4gIC8qKlxuICAqIOi3qEFwcOWNleWRvO+8jFxi5Y+R6YCBaW52aXRl5raI5oGv77yM5Zue6LCD5Zue5p2l5o6l5pS2c3RhdGVNYWNoaW5lLCDlu7pzZXNzaW9uXG4gICogQHBhcmFtIHBhcmFtcy50YXJnZXRJZCDooqvlkbzlj6vkuIDmlrnnmoTnlKjmiLcgaWQg5b+F5aGrXG4gICogQHBhcmFtIHBhcmFtcy5tZWRpYVR5cGUg6Z+z6aKR5ZG85Y+rIG9yIOmfs+inhumikeWRvOWPqyAg5b+F5aGrXG4gICogQHBhcmFtIHBhcmFtcy5saXN0ZW5lciAoc2Vzc2lvbuS4iueahOebkeWQrCkg5b+F5aGrXG4gICogQHBhcmFtIHBhcmFtcy5jb25zdHJhaW50cyDojrflj5bpn7PpopHmiJbpn7Pop4bpopHotYTmupDml7bnmoTlj4LmlbAg5Y+v6YCJXG4gICogQHBhcmFtIHBhcmFtcy5jaGFubmVsSWQg57uE57uHIElkIOWPr+mAiVxuICAqIEBwYXJhbSBwYXJhbXMuZXh0cmEg5raI5oGv5omp5bGV5L+h5oGvXG4gICogQGRlcHJlY2F0ZWQgNS4xLjIg54mI5pys5bqf5byDIHBhcmFtcy5wdXNoVGl0bGUg6YCa55+l55qE5qCH6aKYXG4gICogQGRlcHJlY2F0ZWQgNS4xLjIg54mI5pys5bqf5byDIHBhcmFtcy5wdXNoQ29udGVudCDpgJrnn6XnmoTlhoXlrrlcbiAgKiBAcGFyYW0gcGFyYW1zLmJpdHJhdGUg6ZyA6KaB6K6+572u55qE56CB546H5Y+C5pWwXG4gICpcbiAgKi9cbiAgcHVibGljIGFzeW5jIHN0YXJ0Q3Jvc3NDYWxsKHtcbiAgICB0YXJnZXRJZCwgbWVkaWFUeXBlID0gUkNDYWxsTWVkaWFUeXBlLkFVRElPLCBsaXN0ZW5lciwgY29uc3RyYWludHMsIGNoYW5uZWxJZCA9ICcnLCBleHRyYSA9ICcnLCBwdXNoVGl0bGUgPSAnJywgcHVzaENvbnRlbnQgPSAnJywgYml0cmF0ZSxcbiAgfTogSVJDQ2FsbFBhcmFtcyk6IFByb21pc2U8eyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUsIHNlc3Npb24/OiBSQ0NhbGxTZXNzaW9uIH0+IHtcbiAgICByZXR1cm4gdGhpcy5fX2NhbGwoe1xuICAgICAgdGFyZ2V0SWQsIG1lZGlhVHlwZSwgbGlzdGVuZXIsIGNvbnN0cmFpbnRzLCBjaGFubmVsSWQsIGV4dHJhLCBwdXNoVGl0bGUsIHB1c2hDb250ZW50LCBiaXRyYXRlLCBpc0Nyb3NzQXBwa2V5OiB0cnVlLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWNleWRvO+8jFxi5Y+R6YCBaW52aXRl5raI5oGv77yM5Zue6LCD5Zue5p2l5o6l5pS2c3RhdGVNYWNoaW5lLCDlu7pzZXNzaW9uXG4gICAqIEBwYXJhbSBwYXJhbXMudGFyZ2V0SWQg6KKr5ZG85Y+r5LiA5pa555qE55So5oi3IGlkIOW/heWhq1xuICAgKiBAcGFyYW0gcGFyYW1zLm1lZGlhVHlwZSDpn7PpopHlkbzlj6sgb3Ig6Z+z6KeG6aKR5ZG85Y+rICDlv4XloatcbiAgICogQHBhcmFtIHBhcmFtcy5saXN0ZW5lciAoc2Vzc2lvbuS4iueahOebkeWQrCkg5b+F5aGrXG4gICAqIEBwYXJhbSBwYXJhbXMuY29uc3RyYWludHMg6I635Y+W6Z+z6aKR5oiW6Z+z6KeG6aKR6LWE5rqQ5pe255qE5Y+C5pWwIOWPr+mAiVxuICAgKiBAcGFyYW0gcGFyYW1zLmNoYW5uZWxJZCDnu4Tnu4cgSWQg5Y+v6YCJXG4gICAqIEBwYXJhbSBwYXJhbXMuZXh0cmEg5raI5oGv5omp5bGV5L+h5oGvXG4gICAqIEBkZXByZWNhdGVkIDUuMS4yIOeJiOacrOW6n+W8gyBwYXJhbXMucHVzaFRpdGxlIOmAmuefpeeahOagh+mimFxuICAgKiBAZGVwcmVjYXRlZCA1LjEuMiDniYjmnKzlup/lvIMgcGFyYW1zLnB1c2hDb250ZW50IOmAmuefpeeahOWGheWuuVxuICAgKiBAcGFyYW0gcGFyYW1zLmJpdHJhdGUg6ZyA6KaB6K6+572u55qE56CB546H5Y+C5pWwXG4gICAqXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY2FsbCh7XG4gICAgdGFyZ2V0SWQsIG1lZGlhVHlwZSA9IFJDQ2FsbE1lZGlhVHlwZS5BVURJTywgbGlzdGVuZXIsIGNvbnN0cmFpbnRzLCBjaGFubmVsSWQgPSAnJywgZXh0cmEgPSAnJywgcHVzaFRpdGxlID0gJycsIHB1c2hDb250ZW50ID0gJycsIGJpdHJhdGUsXG4gIH06IElSQ0NhbGxQYXJhbXMpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLCBzZXNzaW9uPzogUkNDYWxsU2Vzc2lvbiB9PiB7XG4gICAgcmV0dXJuIHRoaXMuX19jYWxsKHtcbiAgICAgIHRhcmdldElkLCBtZWRpYVR5cGUsIGxpc3RlbmVyLCBjb25zdHJhaW50cywgY2hhbm5lbElkLCBleHRyYSwgcHVzaFRpdGxlLCBwdXNoQ29udGVudCwgYml0cmF0ZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX19jYWxsKHtcbiAgICB0YXJnZXRJZCwgbWVkaWFUeXBlID0gUkNDYWxsTWVkaWFUeXBlLkFVRElPLCBsaXN0ZW5lciwgY29uc3RyYWludHMsIGNoYW5uZWxJZCA9ICcnLCBleHRyYSA9ICcnLCBwdXNoVGl0bGUgPSAnJywgcHVzaENvbnRlbnQgPSAnJywgYml0cmF0ZSwgaXNDcm9zc0FwcGtleSA9IGZhbHNlLFxuICB9OiBJUkNDYWxsUGFyYW1zKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgc2Vzc2lvbj86IFJDQ2FsbFNlc3Npb24gfT4ge1xuICAgIGNvbnN0IHB1c2hDb25maWcgPSB0aGlzLl9jYWxsUHVzaENvbmZpZyA/IHRoaXMuX2NhbGxQdXNoQ29uZmlnIDogeyBwdXNoVGl0bGUsIHB1c2hDb250ZW50IH07XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbENsaWVudCBjYWxsXSBleHRyYS0+JHtleHRyYX0gcHVzaENvbmZpZy0+JHtKU09OLnN0cmluZ2lmeShwdXNoQ29uZmlnKX1gKTtcbiAgICBjb25zdCBjb25jbHVzaW9uOiBJVmFsaWRhdGlvblJlc3VsdFtdID0gW3ZhbGlkYXRlVGFyZ2V0SWQodGFyZ2V0SWQpLCB2YWxpZGF0ZU1lZGlhVHlwZShtZWRpYVR5cGUpLCB2YWxpZGF0ZUxpc3RlbmVyKGxpc3RlbmVyKSwgdmFsaWRhdGVFeHRyYShleHRyYSldO1xuICAgIGNvbnN0IG1lc3NhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHJlc3VsdCA9IGNvbmNsdXNpb24uZXZlcnkoKG9iajogSVZhbGlkYXRpb25SZXN1bHQpID0+IHtcbiAgICAgICFvYmoucmVzdWx0ICYmIG1lc3NhZ2VzLnB1c2gob2JqLm1zZyEpO1xuICAgICAgcmV0dXJuIG9iai5yZXN1bHQ7XG4gICAgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgW1JDQ2FsbENsaWVudCBjYWxsXSAke21lc3NhZ2VzLmpvaW4oJ1xcbicpfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29kZTogdmFsaWRhdGVQdXNoQ29kZSwgZXJyb3JNc2cgfSA9IHZhbGlkYXRlUHVzaENvbmZpZyhwdXNoQ29uZmlnKTtcbiAgICBpZiAodmFsaWRhdGVQdXNoQ29kZSAhPT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsQ2xpZW50IGNhbGxdIHBhcmFtIGVycm9yLCBlcnJvck1zZzogJHtlcnJvck1zZ31gKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IHZhbGlkYXRlUHVzaENvZGUgfTtcbiAgICB9XG5cbiAgICBsZXQgbG9jYWxUcmFja3M6IFJDTG9jYWxUcmFja1tdID0gW107XG5cbiAgICBjb25zdCB7IGNvZGU6IF9jb2RlLCB0cmFja3MgfSA9IGF3YWl0IHRoaXMuX2dldExvY2FsVHJhY2sobWVkaWFUeXBlLCBjb25zdHJhaW50cyk7XG4gICAgaWYgKF9jb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgcmV0dXJuIHsgY29kZTogX2NvZGUgfTtcbiAgICB9XG4gICAgbG9jYWxUcmFja3MgPSB0cmFja3MhO1xuXG4gICAgbG9jYWxUcmFja3MuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgIC8vIOiuvue9rueggeeOh1xuICAgICAgaWYgKHRyYWNrLmlzQXVkaW9UcmFjaygpICYmIGJpdHJhdGU/LmF1ZGlvKSB7XG4gICAgICAgIHRyYWNrLnNldEJpdHJhdGUoYml0cmF0ZT8uYXVkaW8pO1xuICAgICAgfVxuICAgICAgaWYgKHRyYWNrLmlzVmlkZW9UcmFjaygpICYmIGJpdHJhdGU/LnZpZGVvKSB7XG4gICAgICAgIHRyYWNrLnNldEJpdHJhdGUoYml0cmF0ZT8udmlkZW8/Lm1heCwgYml0cmF0ZT8udmlkZW8/Lm1pbiwgYml0cmF0ZT8udmlkZW8/LnN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIC8vIOWQkeWkluaKm+WHuuacrOWcsOa1gVxuICAgICAgbGlzdGVuZXIub25UcmFja1JlYWR5KHRyYWNrKTtcbiAgICB9KTtcblxuICAgIC8vIOiwg+eUqGNhbGxFbmdpbmXnmoRjYWxs6L+U5Zue5LiA5Liq54q25oCB5py655qE5a6e5L6LXG4gICAgY29uc3QgeyBjb2RlLCBzdGF0ZU1hY2hpbmUgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuY2FsbChjaGFubmVsSWQsIHRhcmdldElkLCBtZWRpYVR5cGUsIGV4dHJhLCBwdXNoQ29uZmlnLCBpc0Nyb3NzQXBwa2V5KTtcbiAgICBpZiAoY29kZSA9PT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MgJiYgc3RhdGVNYWNoaW5lKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdbUkNDYWxsQ2xpZW50IGNhbGxdIHN1Y2Nlc3NmdWxseSBjcmVhdGVkIHN0YXRlIG1hY2hpbmUnKTtcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgUkNDYWxsU2Vzc2lvbihzdGF0ZU1hY2hpbmUsIHRoaXMuX3J0Y0NsaWVudCwgdGhpcy5fbG9nZ2VyLCB7XG4gICAgICAgIGxvY2FsVHJhY2tzLFxuXG4gICAgICAgIC8vIOaYr+WQpuWFgeiuuOiuoumYhemHjeivlVxuICAgICAgICBpc0FsbG93U3Vic2NyaWJlUmV0cnk6IHRoaXMuX29wdGlvbnMuaXNBbGxvd1N1YnNjcmliZVJldHJ5LFxuXG4gICAgICAgIC8vIOaYr+WQpuWFgeiuuOiuoumYhemHjeivlVxuICAgICAgICBpc0FsbG93UHVibGlzaFJldHJ5OiB0aGlzLl9vcHRpb25zLmlzQWxsb3dQdWJsaXNoUmV0cnksXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIOemgeeUqOinhumikeaXtuWFs+aRhOWDj+WktFxuICAgICAgICAgKi9cbiAgICAgICAgaXNPZmZDYW1lcmFXaGVuVmlkZW9EaXNhYmxlOiB0aGlzLl9vcHRpb25zLmlzT2ZmQ2FtZXJhV2hlblZpZGVvRGlzYWJsZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogUlRDIOaIv+mXtOWKoOWFpeexu+Wei1xuICAgICAgICAgKi9cbiAgICAgICAgam9pblR5cGU6IHRoaXMuX29wdGlvbnMuam9pblR5cGUsXG5cbiAgICAgICAgLy8g5YWB6K646ZmN57qn6I635b6X5rWB77yM6I635b6X6Z+z6KeG6aKR5LiN5oiQ5YqfIO+8jOmZjee6p+iOt+W+l+mfs+mikSwg6buY6K6k5LiN5YWB6K64XG4gICAgICAgIGlzQWxsb3dEZW1vdGlvbkdldFN0cmVhbTogdGhpcy5fb3B0aW9ucy5pc0FsbG93RGVtb3Rpb25HZXRTdHJlYW0sXG5cbiAgICAgICAgLy8g5qCH5piO5piv5Li75Y+r5Lqn55Sf55qEc2Vzc2lvblxuICAgICAgICBwcm9kdWNlVHlwZTogUHJvZHVjZVR5cGVzLkNBTExFUixcblxuICAgICAgICBpc0Nyb3NzQXBwa2V5LFxuXG4gICAgICAgIGNhbGxQdXNoQ29uZmlnOiB0aGlzLl9jYWxsUHVzaENvbmZpZyxcblxuICAgICAgICBodW5ndXBQdXNoQ29uZmlnOiB0aGlzLl9odW5ndXBQdXNoQ29uZmlnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIHNlc3Npb27kuIrms6jlhoznm5HlkKzkuovku7ZcbiAgICAgIHNlc3Npb24ucmVnaXN0ZXJTZXNzaW9uTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICB0aGlzLl9zZXNzaW9uTGlzdC5wdXNoKHNlc3Npb24pO1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbENsaWVudCBjYWxsXSBzdWNjZXNzZnVsbHkgY3JlYXRlZCBzZXNzaW9uIG9iamVjdCwgc2Vzc2lvbklkOiAke3Nlc3Npb24uZ2V0U2Vzc2lvbklkKCl9YCk7XG4gICAgICByZXR1cm4geyBjb2RlLCBzZXNzaW9uIH07XG4gICAgfVxuICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsQ2xpZW50IGNhbGxdIGNhbGwgZmFpbGVkIGNvZGUgLT46ICR7Y29kZX1gKTtcbiAgICBsb2NhbFRyYWNrcy5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgLy8g56aB55So6KeG6aKRXG4gICAgICB0cmFjay5tdXRlKCk7XG5cbiAgICAgIC8vIOWFs+mXreaRhOWDj+WktFxuICAgICAgdHJhY2suZGVzdHJveSgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgY29kZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWPkei1t+e+pOe7hOWRvOWPq1xuICAgKiBAcGFyYW0gcGFyYW1zLnRhcmdldElkIOe+pOe7hCBJZCDlv4XloatcbiAgICogQHBhcmFtIHBhcmFtcy51c2VySWRzIOiiq+WRvOWPq+eahOe+pOWGheaIkOWRmCBJZCDlv4XloatcbiAgICogQHBhcmFtIHBhcmFtcy5tZWRpYVR5cGUg6Z+z6aKR5ZG85Y+rIG9yIOmfs+inhumikeWRvOWPqyDlv4XloatcbiAgICogQHBhcmFtIHBhcmFtcy5saXN0ZW5lciAoc2Vzc2lvbuS4iueahOebkeWQrCkg5b+F5aGrXG4gICAqIEBwYXJhbSBwYXJhbXMuY29uc3RyYWludHMg6I635Y+W6Z+z6aKR5oiW6Z+z6KeG6aKR6LWE5rqQ5pe255qE5Y+C5pWwIOWPr+mAiVxuICAgKiBAcGFyYW0gcGFyYW1zLmNoYW5uZWxJZCDnu4Tnu4cgSWQg5Y+v6YCJXG4gICAqIEBwYXJhbSBwYXJhbXMuZXh0cmEg5raI5oGv5omp5bGV5L+h5oGvIOWPr+mAiVxuICAgKiBAZGVwcmVjYXRlZCA1LjEuMiDniYjmnKzlup/lvIMgcGFyYW1zLnB1c2hUaXRsZSDpgJrnn6XnmoTmoIfpophcbiAgICogQGRlcHJlY2F0ZWQgNS4xLjIg54mI5pys5bqf5byDIHBhcmFtcy5wdXNoQ29udGVudCDpgJrnn6XnmoTlhoXlrrlcbiAgICogQHBhcmFtIHBhcmFtcy5iaXRyYXRlIOmcgOimgeiuvue9rueahOeggeeOh+WPguaVsFxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNhbGxJbkdyb3VwKHtcbiAgICB0YXJnZXRJZCwgdXNlcklkcywgbWVkaWFUeXBlID0gUkNDYWxsTWVkaWFUeXBlLkFVRElPLCBsaXN0ZW5lciwgY29uc3RyYWludHMsIGNoYW5uZWxJZCA9ICcnLCBleHRyYSA9ICcnLCBwdXNoVGl0bGUgPSAnJywgcHVzaENvbnRlbnQgPSAnJywgYml0cmF0ZSxcbiAgfTogSVJDQ2FsbEluR3JvdXBQYXJhbXMpOiBQcm9taXNlPHsgY29kZTogUkNDYWxsRXJyb3JDb2RlLCBzZXNzaW9uPzogUkNDYWxsU2Vzc2lvbiB9PiB7XG4gICAgY29uc3QgcHVzaENvbmZpZyA9IHRoaXMuX2NhbGxQdXNoQ29uZmlnID8gdGhpcy5fY2FsbFB1c2hDb25maWcgOiB7IHB1c2hUaXRsZSwgcHVzaENvbnRlbnQgfTtcbiAgICBjb25zdCBjb25jbHVzaW9uOiBJVmFsaWRhdGlvblJlc3VsdFtdID0gW3ZhbGlkYXRlVGFyZ2V0SWQodGFyZ2V0SWQpLCB2YWxpZGF0ZVVzZXJJZHModXNlcklkcyksIHZhbGlkYXRlTWVkaWFUeXBlKG1lZGlhVHlwZSksIHZhbGlkYXRlTGlzdGVuZXIobGlzdGVuZXIpLCB2YWxpZGF0ZUV4dHJhKGV4dHJhKV07XG4gICAgY29uc3QgbWVzc2FnZXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgcmVzdWx0ID0gY29uY2x1c2lvbi5ldmVyeSgob2JqOiBJVmFsaWRhdGlvblJlc3VsdCkgPT4ge1xuICAgICAgIW9iai5yZXN1bHQgJiYgbWVzc2FnZXMucHVzaChvYmoubXNnISk7XG4gICAgICByZXR1cm4gb2JqLnJlc3VsdDtcbiAgICB9KTtcblxuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFtSQ0NhbGxDbGllbnQgY2FsbEluR3JvdXBdICR7bWVzc2FnZXMuam9pbignXFxuJyl9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBjb2RlOiB2YWxpZGF0ZVB1c2hDb2RlLCBlcnJvck1zZyB9ID0gdmFsaWRhdGVQdXNoQ29uZmlnKHB1c2hDb25maWcpO1xuICAgIGlmICh2YWxpZGF0ZVB1c2hDb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgdGhpcy5fbG9nZ2VyLmVycm9yKCdfJywgYFtSQ0NhbGxDbGllbnQgY2FsbF0gcGFyYW0gZXJyb3IsIGVycm9yTXNnOiAke2Vycm9yTXNnfWApO1xuICAgICAgcmV0dXJuIHsgY29kZTogdmFsaWRhdGVQdXNoQ29kZSB9O1xuICAgIH1cblxuICAgIGxldCBsb2NhbFRyYWNrczogUkNMb2NhbFRyYWNrW10gPSBbXTtcblxuICAgIGNvbnN0IHsgY29kZTogX2NvZGUsIHRyYWNrcyB9ID0gYXdhaXQgdGhpcy5fZ2V0TG9jYWxUcmFjayhtZWRpYVR5cGUsIGNvbnN0cmFpbnRzKTtcbiAgICBpZiAoX2NvZGUgIT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBfY29kZSB9O1xuICAgIH1cbiAgICBsb2NhbFRyYWNrcyA9IHRyYWNrcyE7XG5cbiAgICBsb2NhbFRyYWNrcy5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgLy8g6K6+572u56CB546HXG4gICAgICBpZiAodHJhY2suaXNBdWRpb1RyYWNrKCkgJiYgYml0cmF0ZT8uYXVkaW8pIHtcbiAgICAgICAgdHJhY2suc2V0Qml0cmF0ZShiaXRyYXRlPy5hdWRpbyk7XG4gICAgICB9XG4gICAgICBpZiAodHJhY2suaXNWaWRlb1RyYWNrKCkgJiYgYml0cmF0ZT8udmlkZW8pIHtcbiAgICAgICAgdHJhY2suc2V0Qml0cmF0ZShiaXRyYXRlPy52aWRlbz8ubWF4LCBiaXRyYXRlPy52aWRlbz8ubWluLCBiaXRyYXRlPy52aWRlbz8uc3RhcnQpO1xuICAgICAgfVxuICAgICAgLy8g5ZCR5aSW5oqb5Ye65pys5Zyw5rWBXG4gICAgICBsaXN0ZW5lci5vblRyYWNrUmVhZHkodHJhY2spO1xuICAgIH0pO1xuXG4gICAgLy8g5b6A57uE6YeM5Y+R5raI5oGvXG4gICAgY29uc3QgeyBjb2RlLCBzdGF0ZU1hY2hpbmUgfSA9IGF3YWl0IHRoaXMuX2NhbGxFbmdpbmUuY2FsbEluR3JvdXAoY2hhbm5lbElkLCB0YXJnZXRJZCwgbWVkaWFUeXBlLCB1c2VySWRzLCBleHRyYSwgcHVzaENvbmZpZyk7XG4gICAgaWYgKGNvZGUgPT09IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTICYmIHN0YXRlTWFjaGluZSkge1xuICAgICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCAnW1JDQ2FsbENsaWVudCBjYWxsSW5Hcm91cF0gc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgc3RhdGUgbWFjaGluZScpO1xuICAgICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBSQ0NhbGxTZXNzaW9uKHN0YXRlTWFjaGluZSwgdGhpcy5fcnRjQ2xpZW50LCB0aGlzLl9sb2dnZXIsIHtcbiAgICAgICAgbG9jYWxUcmFja3MsXG5cbiAgICAgICAgLy8g5piv5ZCm5YWB6K646K6i6ZiF6YeN6K+VXG4gICAgICAgIGlzQWxsb3dTdWJzY3JpYmVSZXRyeTogdGhpcy5fb3B0aW9ucy5pc0FsbG93U3Vic2NyaWJlUmV0cnksXG5cbiAgICAgICAgLy8g5piv5ZCm5YWB6K645Y+R5biD6YeN6K+VXG4gICAgICAgIGlzQWxsb3dQdWJsaXNoUmV0cnk6IHRoaXMuX29wdGlvbnMuaXNBbGxvd1B1Ymxpc2hSZXRyeSxcblxuICAgICAgICAvKipcbiAgICAgICAgICog56aB55So6KeG6aKR5pe25YWz5pGE5YOP5aS0XG4gICAgICAgICAqL1xuICAgICAgICBpc09mZkNhbWVyYVdoZW5WaWRlb0Rpc2FibGU6IHRoaXMuX29wdGlvbnMuaXNPZmZDYW1lcmFXaGVuVmlkZW9EaXNhYmxlLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSVEMg5oi/6Ze05Yqg5YWl57G75Z6LXG4gICAgICAgICAqL1xuICAgICAgICBqb2luVHlwZTogdGhpcy5fb3B0aW9ucy5qb2luVHlwZSxcblxuICAgICAgICAvLyDlhYHorrjpmY3nuqfojrflvpfmtYHvvIzojrflvpfpn7Pop4bpopHkuI3miJDlip8g77yM6ZmN57qn6I635b6X6Z+z6aKRLCDpu5jorqTkuI3lhYHorrhcbiAgICAgICAgaXNBbGxvd0RlbW90aW9uR2V0U3RyZWFtOiB0aGlzLl9vcHRpb25zLmlzQWxsb3dEZW1vdGlvbkdldFN0cmVhbSxcblxuICAgICAgICAvLyDmoIfmmI7mmK/kuLvlj6vkuqfnlJ/nmoRzZXNzaW9uXG4gICAgICAgIHByb2R1Y2VUeXBlOiBQcm9kdWNlVHlwZXMuQ0FMTEVSLFxuXG4gICAgICAgIGNhbGxQdXNoQ29uZmlnOiB0aGlzLl9jYWxsUHVzaENvbmZpZyxcblxuICAgICAgICBodW5ndXBQdXNoQ29uZmlnOiB0aGlzLl9odW5ndXBQdXNoQ29uZmlnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIHNlc3Npb27kuIrms6jlhoznm5HlkKzkuovku7ZcbiAgICAgIHNlc3Npb24ucmVnaXN0ZXJTZXNzaW9uTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgICAgdGhpcy5fc2Vzc2lvbkxpc3QucHVzaChzZXNzaW9uKTtcbiAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgYFtSQ0NhbGxDbGllbnQgY2FsbEluR3JvdXBdIHN1Y2Nlc3NmdWxseSBjcmVhdGVkIHNlc3Npb24gb2JqZWN0LCBzZXNzaW9uSWQ6ICR7c2Vzc2lvbi5nZXRTZXNzaW9uSWQoKX1gKTtcbiAgICAgIHJldHVybiB7IGNvZGUsIHNlc3Npb24gfTtcbiAgICB9XG4gICAgdGhpcy5fbG9nZ2VyLmluZm8oJ18nLCBgW1JDQ2FsbENsaWVudCBjYWxsSW5Hcm91cF0gY2FsbEluR3JvdXAgZmFpbGVkIGNvZGUgLT4gJHtjb2RlfWApO1xuICAgIGxvY2FsVHJhY2tzLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAvLyDnpoHnlKjop4bpopFcbiAgICAgIHRyYWNrLm11dGUoKTtcblxuICAgICAgLy8g5YWz6Zet5pGE5YOP5aS0XG4gICAgICB0cmFjay5kZXN0cm95KCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBjb2RlIH07XG4gIH1cblxuICAvKipcbiAgICog6LCDUlRDIEFQSSDojrflvpfmnKzlnLDmtYFcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2dldExvY2FsVHJhY2tDb3JlKG1lZGlhVHlwZTogUkNDYWxsTWVkaWFUeXBlLCBjb25zdHJhaW50cz86IElNZWRpYVN0cmVhbUNvbnN0cmFpbnRzKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgdHJhY2tzPzogUkNMb2NhbFRyYWNrW10gfT4ge1xuICAgIC8vIOajgOa1i+aYr+WQpuiDveWkn+iOt+W+l+acrOWcsOa1gVxuICAgIGlmIChtZWRpYVR5cGUgPT09IFJDQ2FsbE1lZGlhVHlwZS5BVURJTykge1xuICAgICAgY29uc3QgeyBjb2RlLCB0cmFjayB9ID0gYXdhaXQgdGhpcy5fcnRjQ2xpZW50LmNyZWF0ZU1pY3JvcGhvbmVBdWRpb1RyYWNrKCdSb25nQ2xvdWRSVEMnLCBjb25zdHJhaW50cyAmJiBjb25zdHJhaW50cy5hdWRpbyAmJiB7IC4uLmNvbnN0cmFpbnRzLmF1ZGlvIH0pO1xuICAgICAgaWYgKGNvZGUgIT09IFJDUlRDQ29kZS5TVUNDRVNTKSB7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsQ2xpZW50IF9nZXRUcmFja10gZ2V0IEF1ZGlvIGxvY2FsIHRyYWNrcyBmYWlsZWQgUkNUIGNvZGUgLT4gJHtjb2RlfWApO1xuICAgICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuR0VUX0xPQ0FMX0FVRElPX1RSQUNLX0VSUk9SIH07XG4gICAgICB9XG4gICAgICB0aGlzLl9sb2dnZXIuaW5mbygnXycsICdbUkNDYWxsQ2xpZW50IF9nZXRUcmFja10gc3VjY2Vzc2Z1bGx5IGdldCBBdWRpbyBsb2NhbCB0cmFja3MnKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLCB0cmFja3M6IFt0cmFjayFdIH07XG4gICAgfVxuICAgIGNvbnN0IHsgY29kZSwgdHJhY2tzIH0gPSBhd2FpdCB0aGlzLl9ydGNDbGllbnQuY3JlYXRlTWljcm9waG9uZUFuZENhbWVyYVRyYWNrcygnUm9uZ0Nsb3VkUlRDJywgY29uc3RyYWludHMgJiYgeyAuLi5jb25zdHJhaW50cyB9KTtcbiAgICBpZiAoY29kZSAhPT0gUkNSVENDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBbUkNDYWxsQ2xpZW50IF9nZXRUcmFja10gZ2V0IEF1ZGlvIGFuZCBWaWRlbyBsb2NhbCB0cmFja3MgZmFpbGVkIFJDVCBjb2RlIC0+ICR7Y29kZX1gKTtcbiAgICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5HRVRfTE9DQUxfQVVESU9fQU5EX1ZJREVPX1RSQUNLX0VSUk9SIH07XG4gICAgfVxuICAgIHRoaXMuX2xvZ2dlci5pbmZvKCdfJywgJ1tSQ0NhbGxDbGllbnQgX2dldFRyYWNrXSBzdWNjZXNzZnVsbHkgZ2V0IGF1ZGlvIGFuZCB2aWRlbyBsb2NhbCB0cmFja3MnKTtcbiAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUywgdHJhY2tzIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9nZXRMb2NhbFRyYWNrKG1lZGlhVHlwZTogUkNDYWxsTWVkaWFUeXBlLCBjb25zdHJhaW50cz86IElNZWRpYVN0cmVhbUNvbnN0cmFpbnRzKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgdHJhY2tzPzogUkNMb2NhbFRyYWNrW10gfT4ge1xuICAgIC8vIOWmguaenOaYr+WFgeiuuOmZjee6p+iOt+W+l+a1ge+8jOW5tuS4lOaYr+iOt+W+l+mfs+inhumikVxuICAgIGlmICh0aGlzLl9vcHRpb25zLmlzQWxsb3dEZW1vdGlvbkdldFN0cmVhbSAmJiBtZWRpYVR5cGUgPT09IFJDQ2FsbE1lZGlhVHlwZS5BVURJT19WSURFTykge1xuICAgICAgY29uc3QgeyBjb2RlLCB0cmFja3MgfSA9IGF3YWl0IHRoaXMuX2dldExvY2FsVHJhY2tDb3JlKFJDQ2FsbE1lZGlhVHlwZS5BVURJT19WSURFTywgY29uc3RyYWludHMpO1xuXG4gICAgICAvLyDlpoLmnpzpn7Pop4bpopHkuI3og73ojrflvpfvvIzlsLHpmY3nu4Tojrflvpfpn7PpopFcbiAgICAgIGlmIChjb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgICBjb25zdCB7IGNvZGUsIHRyYWNrcyB9ID0gYXdhaXQgdGhpcy5fZ2V0TG9jYWxUcmFja0NvcmUoUkNDYWxsTWVkaWFUeXBlLkFVRElPLCBjb25zdHJhaW50cyk7XG4gICAgICAgIGlmIChjb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBjb2RlLCB0cmFja3MgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGNvZGUsIHRyYWNrcyB9O1xuICAgIH1cbiAgICBjb25zdCB7IGNvZGU6IF9jb2RlLCB0cmFja3MgfSA9IGF3YWl0IHRoaXMuX2dldExvY2FsVHJhY2tDb3JlKG1lZGlhVHlwZSwgY29uc3RyYWludHMpO1xuICAgIGlmIChfY29kZSAhPT0gUkNDYWxsRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IF9jb2RlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGNvZGU6IF9jb2RlLCB0cmFja3MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDku45zZXNzaW9uTGlzdOWIoOmZpOafkOS4qnNlc3Npb25cbiAgICovXG4gIHByaXZhdGUgX3JlbW92ZVNlc3Npb24oc2Vzc2lvbjogUkNDYWxsU2Vzc2lvbikge1xuICAgIGNvbnN0IGlkID0gc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKTtcbiAgICB0aGlzLl9zZXNzaW9uTGlzdCA9IHRoaXMuX3Nlc3Npb25MaXN0LmZpbHRlcigoc2Vzc2lvbikgPT4gc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKSAhPT0gaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluW3seaWueWFtuS7luerr+WKoOWFpemAmuivne+8iOW3suWKoOWFpSBSVEMg5oi/6Ze077yJ55qE55So5oi35L+h5oGvXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0Sm9pbmVkUm9vbUluZm8oKTogUHJvbWlzZTx7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZSwgZGF0YT86IElSVENKb2luZWRJbmZvW10gfT4ge1xuICAgIGNvbnN0IHsgY29kZSwgZGF0YSB9ID0gYXdhaXQgdGhpcy5fY29udGV4dC5nZXRSVENKb2luZWRVc2VySW5mbyh0aGlzLl9jb250ZXh0LmdldEN1cnJlbnRJZCgpKTtcbiAgICBpZiAoY29kZSAhPT0gRXJyb3JDb2RlLlNVQ0NFU1MpIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5lcnJvcignXycsIGBnZXRKb2luZWRVc2VySW5mbyBlcnJvciBjb2RlOiAke2NvZGV9YCk7XG4gICAgICByZXR1cm4geyBjb2RlOiBSQ0NhbGxFcnJvckNvZGUuUVVFUllfSk9JTkVEX1VTRVJfSU5GT19FUlJPUiB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGU6IFJDQ2FsbEVycm9yQ29kZS5TVUNDRVNTLCBkYXRhIH07XG4gIH1cblxuICAvKipcbiAgICog6K6+572u5ZG85Y+r44CB5oyC5pat5o6o6YCB5pWw5o2uXG4gICAqIEBwYXJhbSBjYWxsUHVzaENvbmZpZyDlkbzlj6vmjqjpgIHphY3nva5cbiAgICogQHBhcmFtIGNhbGxQdXNoQ29uZmlnLnB1c2hUaXRsZSDlkbzlj6vmjqjpgIHmoIfpophcbiAgICogQHBhcmFtIGNhbGxQdXNoQ29uZmlnLnB1c2hDb250ZW50IOWRvOWPq+aOqOmAgeWGheWuuVxuICAgKiBAcGFyYW0gaHVuZ3VwUHVzaENvbmZpZyDmjILmlq3mjqjpgIHphY3nva5cbiAgICogQHBhcmFtIGh1bmd1cFB1c2hDb25maWcucHVzaFRpdGxlIOaMguaWreaOqOmAgeagh+mimFxuICAgKiBAcGFyYW0gaHVuZ3VwUHVzaENvbmZpZy5wdXNoQ29udGVudCDmjILmlq3mjqjpgIHlhoXlrrlcbiAgICovXG4gIHB1YmxpYyBzZXRQdXNoQ29uZmlnKGNhbGxQdXNoQ29uZmlnOiBJUHVzaENvbmZpZywgaHVuZ3VwUHVzaENvbmZpZzogSVB1c2hDb25maWcpIHtcbiAgICBjb25zdCB2YWxpZGF0ZVJlcyA9IFtjYWxsUHVzaENvbmZpZywgaHVuZ3VwUHVzaENvbmZpZ10ubWFwKChpdGVtKSA9PiB2YWxpZGF0ZVB1c2hDb25maWcoaXRlbSkpO1xuXG4gICAgZm9yIChjb25zdCB7IGNvZGUsIGVycm9yTXNnIH0gb2YgdmFsaWRhdGVSZXMpIHtcbiAgICAgIGlmIChjb2RlICE9PSBSQ0NhbGxFcnJvckNvZGUuU1VDQ0VTUykge1xuICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoJ18nLCBgW1JDQ2FsbENsaWVudCBzZXRQdXNoQ29uZmlnXSBwYXJhbSBlcnJvciwgZXJyb3JNc2c6ICR7ZXJyb3JNc2d9YCk7XG4gICAgICAgIHJldHVybiB7IGNvZGUgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9jYWxsUHVzaENvbmZpZyA9IGNhbGxQdXNoQ29uZmlnO1xuICAgIHRoaXMuX2h1bmd1cFB1c2hDb25maWcgPSBodW5ndXBQdXNoQ29uZmlnO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBJUGx1Z2luR2VuZXJhdG9yLCBJUnVudGltZSwgUlRDUGx1Z2luQ29udGV4dCwgVmVyc2lvbk1hbmFnZSxcbn0gZnJvbSAnQHJvbmdjbG91ZC9lbmdpbmUnO1xuaW1wb3J0IHtcbiAgUkNDYWxsRXJyb3JDb2RlLCBSQ0NhbGxMYW5ndWFnZSwgUkNDYWxsRW5kUmVhc29uLCBSQ0NhbGxNZWRpYVR5cGUsIFJDQ2FsbFVzZXJTdGF0ZSwgUkNDYWxsU2Vzc2lvblN0YXRlLCBJRW5kU3VtbWFyeSwgSUludml0ZWRVc2VycywgSVNlbmRlckluZm8sIElPZmZsaW5lUmVjb3JkLFxufSBmcm9tICdAcmMtZW1iZWQvY2FsbC1lbmdpbmUnO1xuaW1wb3J0IHsgSVJDUlRDU3RhdGVSZXBvcnQgfSBmcm9tICdAcm9uZ2Nsb3VkL3BsdWdpbi1ydGMnO1xuaW1wb3J0IHtcbiAgSVJDQ2FsbEluaXRPcHRpb25zLCBJUkNDYWxsUGFyYW1zLCBJUkNDYWxsSW5Hcm91cFBhcmFtcywgSVNlc3Npb25MaXN0ZW5lciwgSU11dGVVc2VyLCBJTWVkaWFTdHJlYW1Db25zdHJhaW50cywgSURldmljZUNoYW5nZVBhcmFtcywgSVZhbGlkYXRpb25SZXN1bHQsIElQdXNoQ29uZmlnLFxufSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgUkNDYWxsQ2xpZW50IGZyb20gJy4vUkNDYWxsQ2xpZW50JztcbmltcG9ydCB7IFJDQ2FsbFNlc3Npb24gfSBmcm9tICcuL1JDQ2FsbFNlc3Npb24nO1xuaW1wb3J0IHsgdmFsaWRhdGVDYWxsSW5pdE9wdGlvbnMgfSBmcm9tICcuL3ZhbGlkYXRpb24nO1xuXG4vLyBwbHVnaW4tY2FsbCDniYjmnKzkuIrmiqVcblZlcnNpb25NYW5hZ2UuYWRkKCdwbHVnaW4tY2FsbCcsIF9fVkVSU0lPTl9fKTtcblxuY29uc3QgaW5zdGFsbGVyOiBJUGx1Z2luR2VuZXJhdG9yPFJDQ2FsbENsaWVudCwgSVJDQ2FsbEluaXRPcHRpb25zPiA9IHtcbiAgdGFnOiAnUkNDYWxsJyxcbiAgdmVyaWZ5KHJ1bnRpbWU6IElSdW50aW1lKSB7XG4gICAgcmV0dXJuIHJ1bnRpbWUudGFnID09PSAnYnJvd3Nlcic7XG4gIH0sXG4gIHNldHVwKGNvbnRleHQ6IFJUQ1BsdWdpbkNvbnRleHQsIHJ1bnRpbWU6IElSdW50aW1lLCBvcHRpb25zOiBJUkNDYWxsSW5pdE9wdGlvbnMpOiBSQ0NhbGxDbGllbnQge1xuICAgIC8vIOWFiOagoemqjOWPguaVsFxuICAgIGNvbnN0IGNvbmNsdXNpb246IElWYWxpZGF0aW9uUmVzdWx0ID0gdmFsaWRhdGVDYWxsSW5pdE9wdGlvbnMob3B0aW9ucyk7XG4gICAgaWYgKCFjb25jbHVzaW9uLnJlc3VsdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBbUkNDYWxsTGliIGluc3RhbGxlciBzdGV1cF0ke2NvbmNsdXNpb24ubXNnfWApO1xuICAgIH1cblxuICAgIC8vIOagoemqjOW9k+WJjeWuieijheeahCBlbmdpbmUg54mI5pys5piv5ZCm5Y+v55SoXG4gICAgaWYgKCFWZXJzaW9uTWFuYWdlLnZhbGlkRW5naW5lKF9fUkVRVUlSRURfRU5HSU5FX1ZFUlNJT05fXykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGN1cnJlbnQgZW5naW5lIHZlcnNpb24gJyR7VmVyc2lvbk1hbmFnZS5nZXRJbmZvKCkuZW5naW5lfScgZXJyb3IsIHBsdWdpbi1jYWxsIHJlcXVpcmVkIGVuZ2luZSB2ZXJzaW9uIGF0IGxlYXN0ICcke19fUkVRVUlSRURfRU5HSU5FX1ZFUlNJT05fX30nLmApO1xuICAgIH1cblxuICAgIGNvbnN0IGxvZ2dlciA9IGNvbnRleHQuY3JlYXRlTG9nZ2VyKCdSQ0NhbGwnLCAnUlRDJyk7XG4gICAgb3B0aW9ucy5sb2dPdXRwdXRMZXZlbCAmJiBsb2dnZXIuc2V0T3V0cHV0TGV2ZWwob3B0aW9ucy5sb2dPdXRwdXRMZXZlbCk7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMubG9nTGV2ZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIud2FybignXycsICdUaGUgXFwnbG9nTGV2ZWxcXCcgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgXFwnbG9nT3V0cHV0TGV2ZWxcXCcgaW5zdGVhZC4nKTtcbiAgICB9XG5cbiAgICBsb2dnZXIud2FybignXycsIGBSQ0NhbGwgVmVyc2lvbjogJHtfX1ZFUlNJT05fX30sIENvbW1pdDogJHtfX0NPTU1JVF9JRF9ffWApO1xuXG4gICAgcmV0dXJuIG5ldyBSQ0NhbGxDbGllbnQoY29udGV4dCwgcnVudGltZSwgbG9nZ2VyLCBvcHRpb25zKTtcbiAgfSxcbn07XG5cbmV4cG9ydCB7XG4gIGluc3RhbGxlcixcbiAgUkNDYWxsQ2xpZW50LFxuICBSQ0NhbGxTZXNzaW9uLFxuICBSQ0NhbGxMYW5ndWFnZSxcbiAgUkNDYWxsRXJyb3JDb2RlLFxuICBSQ0NhbGxFbmRSZWFzb24sXG4gIFJDQ2FsbE1lZGlhVHlwZSxcbiAgUkNDYWxsVXNlclN0YXRlLFxuICBSQ0NhbGxTZXNzaW9uU3RhdGUsXG59O1xuXG5leHBvcnQgdHlwZSB7XG4gIElFbmRTdW1tYXJ5LFxuICBJUkNDYWxsSW5pdE9wdGlvbnMsXG4gIElSQ0NhbGxQYXJhbXMsXG4gIElSQ0NhbGxJbkdyb3VwUGFyYW1zLFxuICBJU2Vzc2lvbkxpc3RlbmVyLFxuICBJU2VuZGVySW5mbyxcbiAgSU11dGVVc2VyLFxuICBJSW52aXRlZFVzZXJzLFxuICBJTWVkaWFTdHJlYW1Db25zdHJhaW50cyxcbiAgSURldmljZUNoYW5nZVBhcmFtcyxcbiAgSU9mZmxpbmVSZWNvcmQsXG4gIElSQ1JUQ1N0YXRlUmVwb3J0LFxuICBJUHVzaENvbmZpZyxcbn07XG4iXSwibmFtZXMiOlsic3RyaW5nMTB0bzY0IiwibnVtYmVyIiwiY2hhcnMiLCJyYWRpeCIsInF1dGllbnQiLCJhcnIiLCJtb2QiLCJnZXRVVUlEIiwiYyIsInIiLCJnZXRVVUlEMjIiLCJ1dWlkIiwiZ2VuZXJhdGVSYW5kb21JZCIsInJhbmRvbSIsInRpbWVyU2V0VGltZW91dCIsImZ1bmMiLCJ0aW1lb3V0IiwiZXZlbnRFbWl0dGVyIiwiRXZlbnRFbWl0dGVyIiwiZ2V0Q2FsbERldmljZUlkIiwicnVudGltZSIsImtleSIsIk1zZ0NhbGxTdGF0dXMiLCJNc2dDYWxsU3RhdHVzMiIsIlJDQ2FsbEVycm9yQ29kZSIsIlJDQ2FsbEVuZFJlYXNvbiIsIkNhbGxSZW1vdGVFbmRSZWFzb24iLCJSQ0NhbGxNZXNzYWdlVHlwZSIsIlJDQ2FsbFNlc3Npb25TdGF0ZSIsIlJDQ2FsbFNlc3Npb25TdGF0ZTIiLCJSQ0NhbGxVc2VyU3RhdGUiLCJSQ0NhbGxVc2VyU3RhdGUyIiwiUkNDcm9zc0NhbGxUeXBlIiwiVGltZXIkMSIsImNhbGxiYWNrIiwiX19wdWJsaWNGaWVsZCIsImVuZFRpbWUiLCJkdXJhdGlvbiIsIlJDQ2FsbFN0YXRlTWFjaGluZSIsIl9jb250ZXh0IiwiX3J1bnRpbWUiLCJfbG9nZ2VyIiwiX2NhbGxNc2dIYW5kbGVyIiwiX2NoYW5uZWxJZCIsIl9jb252ZXJzYXRpb25UeXBlIiwiX3RhcmdldElkIiwiX21lZGlhVHlwZSIsIl9jYWxsSWQiLCJzZW50VGltZSIsImRlbGF5VGltZSIsInVzZXJJZCIsInN0YXRlIiwicmVhc29uIiwiX2EiLCJ1c2VyIiwibWVzc2FnZSIsInNlbmRlclVzZXJJZCIsInVzZXJQcm9maWxlIiwiaHVuZ3VwUmVhc29uIiwibWVzc2FnZVR5cGUiLCJlbmRSZWFzb24iLCJyZW1vdGVVc2VySWQiLCJtc2dEZXZpY2VJZCIsInN1aWQiLCJkZXZpY2VJZCIsInNlbmRlckRldmljZUlkIiwiY3VycmVudFVzZXJJZCIsIkNvbnZlcnNhdGlvblR5cGUiLCJpc0N1cnJlbnRVc2VySWQiLCJtZWRpYVR5cGUiLCJjb250ZW50IiwiaXNMZXNzVGhhblR3byIsImlzSW52aXRlVXNlciIsImlzTm9PbmVBbnN3ZXJlZCIsIndhdGNoZXJzIiwiaW5pZHMiLCJyb29tVHlwZSIsInVzZXJJZExpc3QiLCJpZCIsImludml0ZVVzZXJJZHMiLCJUaW1lciIsImV4aXN0ZWRVc2VyUG9maWxlcyIsImNhbGxlciIsIm5lZWRSaW5naW5nVXNlcklkcyIsInVzZXJJbmZvIiwiY2FsbFN0YXR1cyIsImVycm9yIiwidXNlcklkcyIsImV4dHJhIiwicHVzaENvbmZpZyIsImlzQ3Jvc3NBcHBrZXkiLCJjb2RlIiwiaXNDYWxsZXIiLCJlbmRDb2RlIiwib3B0aW9ucyIsImV4aXN0ZWRVc2VySWRzIiwiaGFuZ3VwUGFyYW1zIiwibXNnQ29kZSIsInJlbW90ZVVzZXJzIiwicmVtb3RlVXNlciIsInVpZCIsImJlZ2luVGltZXN0YW1wIiwiZW5kVGltZXN0YW1wIiwic3VtbWFyeSIsIlJDQ2FsbE1lZGlhVHlwZSIsIlJDQ2FsbE1lZGlhVHlwZTIiLCJNZW1iZXJNb2RpZnlUeXBlIiwiTWVtYmVyTW9kaWZ5VHlwZTIiLCJQbGF0Zm9ybSIsIk9mZmxpbmVSZWNvcmRlciIsIl9vblJlY29yZCIsImNoYW5uZWxJZCIsImNvbnZlcnNhdGlvblR5cGUiLCJ0YXJnZXRJZCIsImNhbGxJZCIsImlzU2VsZlNlbmQiLCJtZXNzYWdlcyIsIm1zZyIsImNhbGxNc2dUeXBlcyIsIkVuZ2luZUVycm9yQ29kZVRvQ2FsbEVycm9yQ29kZSIsIkVycm9yQ29kZSIsIkNhbGxNZXNzYWdlSGFuZGxlciIsIl9vZmZsaW5lTXNnSXR2IiwiX2dldFN0YXRlTWFjaGluZSIsInJlY29yZCIsIm1hcmtUaW1lIiwiY3VycmVudE1zZ1NlbnRUaW1lIiwiaW5zZXJ0SW5kZXgiLCJpbmRleCIsImN1cnJlbnRUaW1lIiwiYnVmZmVycyIsIml0ZW0iLCJtZXNzYWdlVUlkIiwiaXNPZmZMaW5lTWVzc2FnZSIsIm9mZmxpbmVCdWZmZXJzIiwiaW52aXRlQ2FsbElkIiwiaXNJbnZpdGVNc2dUeXBlIiwiaXNMZXNzVGhhbk9mZmxpbmVNc2dJdHYiLCJ0YXNrTXNnTGlzdCIsImkiLCJvdGhlckNhbGxJZCIsImRlbEluZGV4IiwiZGVsT2ZmbGluZUluZGV4IiwiaXNVbmZpbmlzaGVkUHJpdmF0ZUNhbGwiLCJpc09ubHlJbnZpdGUiLCJoYXNJbnZpdGVBbmRSaW5naW5nIiwiaXNVbmZpbmlzaGVkR3JwQ2FsbCIsImlzVW5maW5pc2hlZCIsIm5vT25lQWNjZXB0IiwiYWxsVXNlcklkcyIsImlzQ2FsbGVySHVuZ3VwIiwidGFza01zZ1NlbmRlclVzZXJJZCIsImRlbENvdW50IiwibGlzdGVuZXIiLCJmdW5jTmFtZSIsImV2ZW50IiwiZXZlbnRUeXBlIiwiZGlyZWN0aW9uYWxVc2VySWRMaXN0Iiwic2VuZE9wdHMiLCJuZXdQdXNoQ29uZmlnIiwiY2FsbGVySWQiLCJSQ0NhbGxMYW5ndWFnZSIsIkVOIiwiWkgiLCJMb2NhbCIsImxhbmciLCJSQ0NhbGxFbmdpbmUiLCJfd2F0Y2hlcnMiLCJfb3B0aW9ucyIsImNydFVzZXJJZCIsImluZm8iLCJQcm9kdWNlVHlwZXMiLCJmdW4iLCJvbiIsImRhdGEiLCJmdW5zIiwiY2IiLCJsZW5ndGgiLCJpc0xhbmd1YWdlIiwidmFsIiwiaXNKb2luVHlwZSIsIlJUQ0pvaW5UeXBlIiwiaXNMb2dMZXZlbCIsIkxvZ0wiLCJ2YWxpZGF0ZUNhbGxJbml0T3B0aW9ucyIsImtleU5hbWVzIiwia2V5cyIsIm1pc3NpbmdLZXlzIiwidmFsaWRhdGVMaXN0ZW5lciIsInZhbGlkYXRlVGFyZ2V0SWQiLCJ2YWxpZGF0ZU1lZGlhVHlwZSIsInZhbGlkYXRlRXh0cmEiLCJ2YWxpZGF0ZVB1c2hDb25maWciLCJwdXNoQ29uZmlnS2V5cyIsImlzVW5kZWZpbmVkIiwiaXNCb29sZWFuIiwiaXNTdHJpbmciLCJpT1NDb25maWciLCJhbmRyb2lkQ29uZmlnIiwidmFsaWRhdGVJT1NDb25maWdSZXMiLCJ2YWxpZGF0ZUlPU0NvbmZpZyIsInZhbGlkYXRlQW5kcm9pZENvbmZpZ1JlcyIsInZhbGlkYXRlQW5kcm9pZENvbmZpZyIsInRocmVhZElkIiwicmljaE1lZGlhVXJpIiwiYW5kcm9pZENvbmZpZ0tleXMiLCJ2YWxpZGF0ZVVzZXJJZHMiLCJzdHIiLCJpc1JDRnJhbWVSYXRlIiwiaXNWYWxpZFJlc29sdXRpb24iLCJyZXNvbHV0aW9uIiwiUkNSZXNvbHV0aW9uIiwidmFsaWRhdGVNZWRpYVN0cmVhbUNvbnN0cmFpbnRzIiwiY29uc3RyYWludHMiLCJSQ0NhbGxTZXNzaW9uIiwiX3N0YXRlTWFjaGluZSIsIl9ydGNDbGllbnQiLCJyb29tSWQiLCJzdW1tYXJ5SW5mbyIsInNlbmRlciIsImludml0ZWRVc2VycyIsImNhbGxCYWNrIiwicm9vbSIsIlJDUlRDQ29kZSIsInRyYWNrcyIsImlzQWxsb3dTdWJzY3JpYmVSZXRyeSIsImNvdW50IiwiaXNBbGxvd1B1Ymxpc2hSZXRyeSIsImNvbmNsdXNpb24iLCJ0cmFjayIsIl9jb2RlIiwiYXVkaW9Db25zdHJhaW50cyIsInJlY2VudFRyYWNrcyIsImxvY2FsVHJhY2tzIiwiZXJyb3JNc2ciLCJvYmoiLCJsb2NhbFZpZGVvVHJhY2tzIiwibG9jYWxBdWRpb3RyYWNrcyIsImJ5U2VydmVyIiwiUkNLaWNrUmVhc29uIiwibmFtZSIsImF1ZGlvVHJhY2siLCJtdXRlVXNlciIsInZpZGVvVHJhY2siLCJyZXN1bHQiLCJyZXBvcnQiLCJSQ0NhbGxDbGllbnQiLCJzZXNzaW9uIiwic2VzIiwic3RhdGVNYWNoaW5lIiwicHVzaFRpdGxlIiwicHVzaENvbnRlbnQiLCJiaXRyYXRlIiwidmFsaWRhdGVQdXNoQ29kZSIsIl9iIiwiX2MiLCJjYWxsUHVzaENvbmZpZyIsImh1bmd1cFB1c2hDb25maWciLCJ2YWxpZGF0ZVJlcyIsIlZlcnNpb25NYW5hZ2UiLCJpbnN0YWxsZXIiLCJjb250ZXh0IiwibG9nZ2VyIl0sIm1hcHBpbmdzIjoiOzs7OztBQUVBLE1BQU1BLEtBQWUsQ0FBQ0MsTUFBbUI7QUFDakMsUUFBQUMsSUFBUSxtRUFBbUUsTUFBTSxFQUFFLEdBQ25GQyxJQUFRRCxFQUFNLFNBQVM7QUFDN0IsTUFBSUUsSUFBVSxDQUFDSDtBQUNmLFFBQU1JLElBQU0sQ0FBQTtBQUNULEtBQUE7QUFDRCxVQUFNQyxJQUFNRixJQUFVRDtBQUN0QixJQUFBQyxLQUFXQSxJQUFVRSxLQUFPSCxHQUN4QkUsRUFBQSxRQUFRSCxFQUFNSSxDQUFHLENBQUM7QUFBQSxXQUNmRjtBQUNGLFNBQUFDLEVBQUksS0FBSyxFQUFFO0FBQ3BCLEdBRU1FLEtBQVUsTUFBTSx1Q0FBdUMsUUFBUSxTQUFTLENBQUNDLE1BQU07QUFDbkYsUUFBTUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxLQUFLO0FBRXhCLFVBREdE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SUFBQSxpQkFJQUEsRUFBQUEsRUFBQSw0QkFBNEIsQ0FBNUIsSUFBQSw2QkFJQUEsRUFBQUEsRUFBQSxnQkFBZ0IsQ0FBaEIsSUFBQSxpQkFJQUEsRUFBQUEsRUFBQSxrQkFBa0IsRUFBbEIsSUFBQSxtQkFJQUEsRUFBQUEsRUFBQSxnQkFBZ0IsRUFBaEIsSUFBQSxpQkFJQUEsRUFBQUEsRUFBQSxnQkFBZ0IsRUFBaEIsSUFBQSxpQkFJQUEsRUFBQUEsRUFBQSxnQkFBZ0IsRUFBaEIsSUFBQSxpQkFJQUEsRUFBQUEsRUFBQSxtQkFBbUIsRUFBbkIsSUFBQSxvQkFJQUEsRUFBQUEsRUFBQSxxQkFBcUIsRUFBckIsSUFBQSxzQkFJQUEsRUFBQUEsRUFBQSw0QkFBNEIsRUFBNUIsSUFBQSw2QkFJQUEsRUFBQUEsRUFBQSx1QkFBdUIsRUFBdkIsSUFBQSx3QkFJQUEsRUFBQUEsRUFBQSxrQ0FBa0MsRUFBbEMsSUFBQSxtQ0FJQUEsRUFBQUEsRUFBQSx1QkFBdUIsRUFBdkIsSUFBQSx3QkFJQUEsRUFBQUEsRUFBQSx5QkFBeUIsRUFBekIsSUFBQSwwQkFJQUEsRUFBQUEsRUFBQSwyQkFBMkIsRUFBM0IsSUFBQSw0QkFJQUEsRUFBQUEsRUFBQSx1QkFBdUIsRUFBdkIsSUFBQSx3QkFJQUEsRUFBQUEsRUFBQSxtQkFBbUIsRUFBbkIsSUFBQSxvQkFJQUEsRUFBQUEsRUFBQSxxQkFBcUIsRUFBckIsSUFBQSxzQkFJQUEsRUFBQUEsRUFBQSxrQ0FBa0MsRUFBbEMsSUFBQSxtQ0FJQUEsRUFBQUEsRUFBQSw4QkFBOEIsRUFBOUIsSUFBQSwrQkFJQUEsRUFBQUEsRUFBQSwwQkFBMEIsRUFBMUIsSUFBQSwyQkFJQUEsRUFBQUEsRUFBQSw0QkFBNEIsRUFBNUIsSUFBQSw2QkFJQUEsRUFBQUEsRUFBQSx5QkFBeUIsR0FBekIsSUFBQSwwQkFJQUEsRUFBQUEsRUFBQSx5QkFBeUIsR0FBekIsSUFBQSwwQkFJQUEsRUFBQUEsRUFBQSxxQkFBcUIsR0FBckIsSUFBQSxzQkFJQUEsRUFBQUEsRUFBQSxxQkFBcUIsR0FBckIs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
|
|
1
|
+
import{EventEmitter as e,ConversationType as t,ErrorCode as n,isUndefined as r,isBoolean as i,isString as o,RTCJoinType as s,LogL as a,VersionManage as l}from"@rongcloud/engine";import{RCResolution as c,RCKickReason as u,RCRTCCode as d}from"@rongcloud/plugin-rtc";var _=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},_(e,t)};var h=function(){return h=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},h.apply(this,arguments)};function f(e,t,n,r){return new(n||(n=Promise))((function(i,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function a(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}l((r=r.apply(e,t||[])).next())}))}function g(e,t){var n,r,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,a[0]&&(s=0)),s;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return s.label++,{value:a[1],done:!1};case 5:s.label++,r=a[1],a=[0];continue;case 7:a=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){s=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){s.label=a[1];break}if(6===a[0]&&s.label<i[1]){s.label=i[1],i=a;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(a);break}i[2]&&s.ops.pop(),s.trys.pop();continue}a=t.call(e,s)}catch(e){a=[6,e],r=0}finally{n=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,l])}}}function p(e,t,n){if(n||2===arguments.length)for(var r,i=0,o=t.length;i<o;i++)!r&&i in t||(r||(r=Array.prototype.slice.call(t,0,i)),r[i]=t[i]);return e.concat(r||Array.prototype.slice.call(t))}"function"==typeof SuppressedError&&SuppressedError;var b,C,R,I,m=function(){var e="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}));return e="".concat(e.replace(/-/g,""),"0"),(e=function(e){var t="0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ+/".split(""),n=t.length+1,r=+e,i=[];do{var o=r%n;r=(r-o)/n,i.unshift(t[o])}while(r);return i.join("")}(e=parseInt(e,16))).length>22&&(e=e.slice(0,22)),e},y=function(){var e=Math.floor(1e3*Math.random()),t=m();return[t=t.replace(/\//g,"0"),Date.now(),e].join("_")},E=new e,v=function(e){var t="RCCallDeviceId",n=e.sessionStorage.getItem(t);return n||(n=m(),e.sessionStorage.setItem(t,n)),n};!function(e){e[e.OUTGOING=1]="OUTGOING",e[e.INCOMING=2]="INCOMING",e[e.RINGING=3]="RINGING",e[e.CONNECTED=4]="CONNECTED",e[e.IDLE=5]="IDLE",e[e.ACCEPTED=6]="ACCEPTED"}(b||(b={})),function(e){e[e.SUCCESS=1e4]="SUCCESS",e[e.STATE_MACHINE_EXIT=53200]="STATE_MACHINE_EXIT",e[e.SEND_MSG_ERROR=53201]="SEND_MSG_ERROR",e[e.REJECTED_BY_BLACKLIST=53202]="REJECTED_BY_BLACKLIST",e[e.NOT_IN_GROUP=53203]="NOT_IN_GROUP",e[e.GET_LOCAL_AUDIO_TRACK_ERROR=53301]="GET_LOCAL_AUDIO_TRACK_ERROR",e[e.GET_LOCAL_VIDEO_TRACK_ERROR=53302]="GET_LOCAL_VIDEO_TRACK_ERROR",e[e.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR=53303]="GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR",e[e.JOIN_ROOM_ERROR=53304]="JOIN_ROOM_ERROR",e[e.AUDIO_PUBLISH_ERROR=53305]="AUDIO_PUBLISH_ERROR",e[e.VIDEO_PUBLISH_ERROR=53306]="VIDEO_PUBLISH_ERROR",e[e.AUDIO_AND_VIDEO_PUBLISH_ERROR=53307]="AUDIO_AND_VIDEO_PUBLISH_ERROR",e[e.QUERY_JOINED_USER_INFO_ERROR=53308]="QUERY_JOINED_USER_INFO_ERROR",e[e.MISSING_VIDEO_TRACK_ERROR=53309]="MISSING_VIDEO_TRACK_ERROR",e[e.UNPUBLISH_VIDEO_ERROR=53310]="UNPUBLISH_VIDEO_ERROR",e[e.CONVERSATION_NOT_GROUP_ERROR=53311]="CONVERSATION_NOT_GROUP_ERROR",e[e.NOT_IN_ROOM_ERROR=53312]="NOT_IN_ROOM_ERROR",e[e.PARAM_ERROR=53313]="PARAM_ERROR",e[e.MISSING_AUDIO_TRACK_ERROR=53314]="MISSING_AUDIO_TRACK_ERROR"}(C||(C={})),function(e){e[e.CANCEL=1]="CANCEL",e[e.REJECT=2]="REJECT",e[e.HANGUP=3]="HANGUP",e[e.BUSY_LINE=4]="BUSY_LINE",e[e.NO_RESPONSE=5]="NO_RESPONSE",e[e.ENGINE_UNSUPPORTED=6]="ENGINE_UNSUPPORTED",e[e.NETWORK_ERROR=7]="NETWORK_ERROR",e[e.GET_MEDIA_RESOURCES_ERROR=8]="GET_MEDIA_RESOURCES_ERROR",e[e.PUBLISH_ERROR=9]="PUBLISH_ERROR",e[e.SUBSCRIBE_ERROR=10]="SUBSCRIBE_ERROR",e[e.REMOTE_CANCEL=11]="REMOTE_CANCEL",e[e.REMOTE_REJECT=12]="REMOTE_REJECT",e[e.REMOTE_HANGUP=13]="REMOTE_HANGUP",e[e.REMOTE_BUSY_LINE=14]="REMOTE_BUSY_LINE",e[e.REMOTE_NO_RESPONSE=15]="REMOTE_NO_RESPONSE",e[e.REMOTE_ENGINE_UNSUPPORTED=16]="REMOTE_ENGINE_UNSUPPORTED",e[e.REMOTE_NETWORK_ERROR=17]="REMOTE_NETWORK_ERROR",e[e.REMOTE_GET_MEDIA_RESOURCE_ERROR=18]="REMOTE_GET_MEDIA_RESOURCE_ERROR",e[e.REMOTE_PUBLISH_ERROR=19]="REMOTE_PUBLISH_ERROR",e[e.REMOTE_SUBSCRIBE_ERROR=20]="REMOTE_SUBSCRIBE_ERROR",e[e.OTHER_CLIENT_JOINED_CALL=21]="OTHER_CLIENT_JOINED_CALL",e[e.OTHER_CLIENT_IN_CALL=22]="OTHER_CLIENT_IN_CALL",e[e.KICKED_BY_SERVER=23]="KICKED_BY_SERVER",e[e.ACCEPT_SYSTEM_CALL=24]="ACCEPT_SYSTEM_CALL",e[e.REMOTE_OTHER_CLIENT_JOINED_CALL=31]="REMOTE_OTHER_CLIENT_JOINED_CALL",e[e.REMOTE_OTHER_CLIENT_IN_CALL=32]="REMOTE_OTHER_CLIENT_IN_CALL",e[e.REMOTE_KICKED_BY_SERVER=33]="REMOTE_KICKED_BY_SERVER",e[e.REMOTE_ACCEPT_SYSTEM_CALL=34]="REMOTE_ACCEPT_SYSTEM_CALL",e[e.ACCEPT_BY_OTHER_CLIENT=101]="ACCEPT_BY_OTHER_CLIENT",e[e.HANGUP_BY_OTHER_CLIENT=102]="HANGUP_BY_OTHER_CLIENT",e[e.ADDED_TO_BLACKLIST=103]="ADDED_TO_BLACKLIST",e[e.SERVICE_NOT_OPENED=104]="SERVICE_NOT_OPENED"}(I||(I={}));var O,T,S,M,P=((R={})[I.CANCEL]=I.REMOTE_CANCEL,R[I.REJECT]=I.REMOTE_REJECT,R[I.HANGUP]=I.REMOTE_HANGUP,R[I.BUSY_LINE]=I.REMOTE_BUSY_LINE,R[I.NO_RESPONSE]=I.REMOTE_NO_RESPONSE,R[I.ENGINE_UNSUPPORTED]=I.REMOTE_ENGINE_UNSUPPORTED,R[I.NETWORK_ERROR]=I.REMOTE_NETWORK_ERROR,R[I.GET_MEDIA_RESOURCES_ERROR]=I.REMOTE_GET_MEDIA_RESOURCE_ERROR,R[I.PUBLISH_ERROR]=I.REMOTE_PUBLISH_ERROR,R[I.SUBSCRIBE_ERROR]=I.REMOTE_SUBSCRIBE_ERROR,R[I.OTHER_CLIENT_JOINED_CALL]=I.REMOTE_OTHER_CLIENT_JOINED_CALL,R[I.OTHER_CLIENT_IN_CALL]=I.REMOTE_OTHER_CLIENT_IN_CALL,R[I.KICKED_BY_SERVER]=I.REMOTE_KICKED_BY_SERVER,R[I.REMOTE_NO_RESPONSE]=I.NO_RESPONSE,R[I.ACCEPT_SYSTEM_CALL]=I.REMOTE_ACCEPT_SYSTEM_CALL,R);!function(e){e.VCInvite="RC:VCInvite",e.VCRinging="RC:VCRinging",e.VCAccept="RC:VCAccept",e.VCHangup="RC:VCHangup",e.VCModifyMem="RC:VCModifyMem",e.VCModifyMedia="RC:VCModifyMedia"}(O||(O={})),function(e){e[e.WAITING=0]="WAITING",e[e.KEEPING=1]="KEEPING",e[e.END=2]="END"}(T||(T={})),function(e){e[e.NONE=0]="NONE",e[e.WAITING=1]="WAITING",e[e.KEEPING=2]="KEEPING"}(S||(S={})),function(e){
|
|
2
|
+
/*!
|
|
3
|
+
同App通话
|
|
4
|
+
*/
|
|
5
|
+
e[e.RCCallRoomTypeNormalCall=0]="RCCallRoomTypeNormalCall",
|
|
6
|
+
/*!
|
|
7
|
+
跨App通话
|
|
8
|
+
*/
|
|
9
|
+
e[e.RCCallRoomTypeAcrossCall=7]="RCCallRoomTypeAcrossCall"}(M||(M={}));var w,N,A,U=function(){function e(e,t){Object.defineProperty(this,"_timerId",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_startTime",{enumerable:!0,configurable:!0,writable:!0,value:0}),e&&(this._timerId=function(e,t){return setTimeout(e,t)}((function(){e()}),t)),this._startTime=Date.now()}return Object.defineProperty(e.prototype,"stop",{enumerable:!1,configurable:!0,writable:!0,value:function(){clearTimeout(this._timerId);var e=Date.now(),t=e-this._startTime;return 0===this._startTime&&(t=0),{startTime:this._startTime,endTime:e,duration:t}}}),Object.defineProperty(e.prototype,"reset",{enumerable:!1,configurable:!0,writable:!0,value:function(){this._startTime=0}}),e}(),L=function(){function e(e,t,n,r,i,o,s,a,l){Object.defineProperty(this,"_context",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"_runtime",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(this,"_callMsgHandler",{enumerable:!0,configurable:!0,writable:!0,value:r}),Object.defineProperty(this,"_channelId",{enumerable:!0,configurable:!0,writable:!0,value:i}),Object.defineProperty(this,"_conversationType",{enumerable:!0,configurable:!0,writable:!0,value:o}),Object.defineProperty(this,"_targetId",{enumerable:!0,configurable:!0,writable:!0,value:s}),Object.defineProperty(this,"_mediaType",{enumerable:!0,configurable:!0,writable:!0,value:a}),Object.defineProperty(this,"_callId",{enumerable:!0,configurable:!0,writable:!0,value:l}),Object.defineProperty(this,"_sessionState",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_userInfo",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"_userTimers",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"_watchers",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_callTimeout",{enumerable:!0,configurable:!0,writable:!0,value:6e4}),Object.defineProperty(this,"_beginTimestamp",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_endTimestamp",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_endReason",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_callerId",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_inviterId",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_isCrossAppkey",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"_hungupPushConfig",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._callMsgHandler.registerStateMachineEvent(this._callId,"onRinging",this._onRinging.bind(this)),this._callMsgHandler.registerStateMachineEvent(this._callId,"onAccept",this._onAccept.bind(this)),this._callMsgHandler.registerStateMachineEvent(this._callId,"onMediaModify",this._onMediaModify.bind(this)),this._callMsgHandler.registerStateMachineEvent(this._callId,"onHungup",this._onHungup.bind(this))}return Object.defineProperty(e.prototype,"_getTimeout",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this._context.getServerTime()-e;t<0&&(t=500);var n=this._callTimeout-t;return this._logger.warn("_","_getTimeout -> timeout: ".concat(n)),n}}),Object.defineProperty(e.prototype,"_clearTimerById",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._logger.debug("_","[RCCallStateMachine] before _clearTimerById -> userId: ".concat(e," userTimers: ").concat(JSON.stringify(this._userTimers))),this._userTimers[e]&&(this._userTimers[e].stop(),delete this._userTimers[e]),this._logger.debug("_","[RCCallStateMachine] after _clearTimerById -> userTimers: ".concat(JSON.stringify(this._userTimers)))}}),Object.defineProperty(e.prototype,"_notifyStateChange",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var n;this._logger.warn("_","[RCCallStateMachine] notifyStateChange -> info: ".concat(JSON.stringify({state:e,reason:t}))),this._endReason=t||null,this._sessionState!==e&&(this._sessionState=e,null===(n=this._watchers)||void 0===n||n.onStateChange({state:e,reason:t})),e===T.END&&(E.emit("onStateMachineClose",this._callId),this._callMsgHandler.unregisterStateMachineEvent(this._callId))}}),Object.defineProperty(e.prototype,"_notifyUserStateChange",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var n;this._logger.warn("_","[RCCallStateMachine] notifyUserStateChange -> info: ".concat(JSON.stringify({user:e,reason:t}))),null===(n=this._watchers)||void 0===n||n.onUserStateChange({user:e,reason:t})}}),Object.defineProperty(e.prototype,"_otherClientHandle",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.senderUserId,n=e.content,r=n.user,i=n.reason,o=e.messageType;for(var s in this._userInfo[t]={userId:t,state:S.NONE,isCaller:!1,isRemote:!1},this._userTimers)this._clearTimerById(s);var a=I.ACCEPT_BY_OTHER_CLIENT;o===O.VCHangup&&(a=i===I.BUSY_LINE?I.OTHER_CLIENT_IN_CALL:i===I.NO_RESPONSE?I.NO_RESPONSE:I.HANGUP_BY_OTHER_CLIENT),Object.assign(this._userInfo[t],r),this._notifyUserStateChange(this._userInfo[t],a),this._notifyStateChange(T.END,a)}}),Object.defineProperty(e.prototype,"_isRemoteInvalidMsg",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return!!this._userInfo[e]&&(!(!this._userInfo[e].deviceId||!t)&&(this._userInfo[e].state===S.KEEPING&&this._userInfo[e].deviceId!==t))}}),Object.defineProperty(e.prototype,"_onRinging",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.senderUserId,n=e.content,r=n.user,i=n.deviceId,o=this._isCrossAppkey?t.split("_")[1]:t;this._isRemoteInvalidMsg(o,i)?this._logger.debug("_","[RCCallStateMachine] onRinging -> not the remote device that is currently talking"):this._context.getCurrentId()!==o&&this._watchers.onRinging(h({userId:o},r))}}),Object.defineProperty(e.prototype,"_onAccept",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var n=this,r=e.senderUserId,i=e.content,o=i.user,s=i.deviceId;e.sentTime;var a=this._isCrossAppkey?r.split("_")[1]:r,l=this._context.getCurrentId();this._isRemoteInvalidMsg(a,s)?this._logger.debug("_","[RCCallStateMachine] _onAccept -> not the remote device that is currently talking"):l!==a?(this._userTimers[a]&&this._clearTimerById(a),(this._conversationType===t.PRIVATE?[l,a]:[a]).forEach((function(e){var t=e===l;n._userInfo[e]={userId:e,state:S.KEEPING,isCaller:t,isRemote:t,deviceId:t?v(n._runtime):s},t||(n._beginTimestamp=Date.now(),Object.assign(n._userInfo[a],o)),n._notifyUserStateChange(n._userInfo[e])})),this.getCallerId()===l&&this._notifyStateChange(T.KEEPING),this._watchers.onAccept({userId:a})):this._otherClientHandle(e)}}),Object.defineProperty(e.prototype,"_onMediaModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.senderUserId,n=e.content,r=n.mediaType,i=n.user,o=n.deviceId;this._isRemoteInvalidMsg(t,o)?this._logger.debug("_","[RCCallStateMachine] _onMediaModify -> not the remote device that is currently talking"):this._context.getCurrentId()!==t&&(this._mediaType=r,this._watchers.onMediaModify({sender:h({userId:t},i),mediaType:r}))}}),Object.defineProperty(e.prototype,"_onHungup",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.senderUserId,n=e.content,r=this._isCrossAppkey?t.split("_")[1]:t,i=n,o=i.reason,s=i.user,a=i.deviceId,l=this._context.getCurrentId();if(this._isRemoteInvalidMsg(r,a))this._logger.debug("_","[RCCallStateMachine] _onHungup -> not the remote device that is currently talking");else if(l!==r)if(this._sessionState!==T.END){this._userInfo[r]&&(this._userInfo[r].state=S.NONE,this._endTimestamp=Date.now(),Object.assign(this._userInfo[r],s),this._notifyUserStateChange(this._userInfo[r],P[o]),delete this._userInfo[r]),P[o]===I.REMOTE_CANCEL?this.getRemoteUserIds().length<1&&this._clearTimerById(l):this.getInviterId()===l?this._clearTimerById(r):this.getRemoteUserIds().length<1&&this._clearTimerById(l);var c=Object.keys(this._userInfo).length<2,u=this._inviterId===r,d=Object.values(this._userInfo).every((function(e){return e.state!==S.KEEPING}));(c||u&&d)&&this._notifyStateChange(T.END,P[o]),this._watchers.onHungup(h({userId:r},s),P[o])}else this._logger.info("_","[RCCallStateMachine] Invalid hang up message, current room status has ended -> sessionState: ".concat(this._sessionState));else this._otherClientHandle(e)}}),Object.defineProperty(e.prototype,"registerEventListener",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._watchers=e}}),Object.defineProperty(e.prototype,"__onInvite",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t,n,r=this,i=e.senderUserId,o=e.content,s=e.sentTime,a=o,l=a.inviteUserIds,c=a.user,u=a.deviceId;a.roomType===M.RCCallRoomTypeAcrossCall?(t=i.split("_"),n=t[1],this._watchers.crossAppkey(!0),this._isCrossAppkey=!0):n=i;var d=this._context.getCurrentId();if(this._isRemoteInvalidMsg(n,u))this._logger.debug("_","[RCCallStateMachine] __onInvite -> not the remote device that is currently talking");else if(d!==n){this._callerId=this._inviterId=n;var _=p([i],l,!0);this._callMsgHandler.sendRinging({conversationType:this._conversationType,targetId:this._targetId,channelId:this._channelId,callId:this._callId,userIds:_.filter((function(e){return r._isCrossAppkey?e.split("_")[1]!==d:e!==d}))});var h=this._isCrossAppkey?[l[0].split("_")[1]]:l;p([n],h,!0).forEach((function(e){r._userInfo[e]={userId:e,state:S.WAITING,isCaller:e===n,isRemote:e!==d},e===n&&Object.assign(r._userInfo[e],c,{deviceId:u}),r._notifyUserStateChange(r._userInfo[e]),e!==n&&(r._userTimers[e]=new U((function(){var t=e===d?I.NO_RESPONSE:I.REMOTE_NO_RESPONSE;e===d?r._hungupHandle(t,!1):(r._userInfo[e]&&(r._userInfo[e].state=S.NONE),r._notifyUserStateChange(r._userInfo[e]),r._watchers.onHungup(r._userInfo[e],t),delete r._userInfo[e]),r._clearTimerById(e)}),r._getTimeout(s)))})),this._notifyStateChange(T.WAITING)}}}),Object.defineProperty(e.prototype,"__onMemberModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this,n=e.senderUserId,r=e.content,i=e.sentTime,o=r,s=o.user,a=o.existedUserPofiles,l=o.caller,c=o.deviceId,u=o.inviteUserIds,d=o.mediaType,_=this._context.getCurrentId();if(this._isRemoteInvalidMsg(n,c))this._logger.debug("_","[RCCallStateMachine] __onMemberModify -> not the remote device that is currently talking");else if(_!==n){if(this._callerId=l,this._inviterId=n,u.forEach((function(e){a.push({userId:e,mediaType:d,callStatus:b.INCOMING})})),u.includes(_)){var f=[];a.forEach((function(e){e.userId!==_&&f.push(e.userId)})),this._callMsgHandler.sendRinging({conversationType:this._conversationType,targetId:this._targetId,channelId:this._channelId,callId:this._callId,userIds:f}),this._notifyStateChange(T.WAITING)}else this._watchers.onMemberModify({sender:h({userId:n},s),invitedUsers:u.map((function(e){return{userId:e}}))});a.forEach((function(e){var r=e.userId,o=e.callStatus;if(o!==b.IDLE&&(t._userInfo[r]={userId:r,state:o!==b.CONNECTED?S.WAITING:S.KEEPING,isCaller:n===r,isRemote:_!==r},r===n&&Object.assign(t._userInfo[r],s,{deviceId:c}),t._notifyUserStateChange(t._userInfo[r]),o!==b.CONNECTED&&!t._userTimers[r])){if(!u.includes(r))return;t._userTimers[r]=new U((function(){t._userInfo[r]&&(t._userInfo[r].state=S.NONE);var e=r===_?I.NO_RESPONSE:I.REMOTE_NO_RESPONSE;t._notifyUserStateChange(t._userInfo[r],e);try{t._watchers.onHungup(t._userInfo[r],e)}catch(e){t._logger.error("_","[RCCallStateMachine] call onhungup error -> ".concat(null==e?void 0:e.stack))}delete t._userInfo[r],(Object.keys(t._userInfo).length<2||r===_)&&t._notifyStateChange(T.END,e),t._clearTimerById(r)}),t._getTimeout(i))}}))}}}),Object.defineProperty(e.prototype,"__handleInviteInSession",{enumerable:!1,configurable:!0,writable:!0,value:function(){for(var e in this._logger.info("_","StateMachine -> __handleInviteInSession"),this._userInfo)this._userInfo[e].state&&(this._userInfo[e].state=S.NONE),this._notifyUserStateChange(this._userInfo[e]),this._clearTimerById(e);this._notifyStateChange(T.END,I.BUSY_LINE),this._callMsgHandler.sendHungup({channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,reason:I.BUSY_LINE,userIds:this.getRemoteUserIds()})}}),Object.defineProperty(e.prototype,"__call",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t,n,r){return void 0===t&&(t=""),void 0===r&&(r=!1),f(this,void 0,void 0,(function(){var i,o,s,a,l,c,u=this;return g(this,(function(d){switch(d.label){case 0:return this._logger.debug("_","[RCCallStateMachine] invite -> userIds: ".concat(JSON.stringify(e))),i=this._callerId=this._inviterId=this._context.getCurrentId(),[4,this._callMsgHandler.sendInvite({roomType:r?M.RCCallRoomTypeAcrossCall:M.RCCallRoomTypeNormalCall,channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,extra:t,pushConfig:n,mediaType:this._mediaType,inviteUserIds:e.filter((function(e){return e!==i}))})];case 1:return o=d.sent(),s=o.code,a=o.message,this._isCrossAppkey=r,s===C.SUCCESS?(l=a.sentTime,(r?p([i],[e[0].split("_")[1]],!1):p([i],e,!0)).forEach((function(e){var t=e===i;u._userInfo[e]={userId:e,state:S.WAITING,isCaller:t,isRemote:!t},u._notifyUserStateChange(u._userInfo[e]),t||(u._userTimers[e]=new U((function(){u._userInfo[e]&&(u._userInfo[e].state=S.NONE),u._notifyUserStateChange(u._userInfo[e],I.REMOTE_NO_RESPONSE),u._watchers.onHungup(u._userInfo[e],I.REMOTE_NO_RESPONSE),delete u._userInfo[e],Object.keys(u._userInfo).length<2&&u._notifyStateChange(T.END,I.REMOTE_NO_RESPONSE),0===u.getRemoteUserIds().length&&u._userInfo[i].state!==S.KEEPING&&u._hungupHandle(I.REMOTE_NO_RESPONSE)}),u._getTimeout(l)))})),this._notifyStateChange(T.WAITING)):(c=s===C.REJECTED_BY_BLACKLIST?I.ADDED_TO_BLACKLIST:I.NETWORK_ERROR,this._notifyStateChange(T.END,c)),[2,{code:s}]}}))}))}}),Object.defineProperty(e.prototype,"accept",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,n,r,i;return g(this,(function(o){switch(o.label){case 0:return this._logger.debug("_","[RCCallStateMachine] accept"),e=this._context.getCurrentId(),[4,this._callMsgHandler.sendAccept({channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,mediaType:this._mediaType,userIds:this.getRemoteUserIds()})];case 1:return t=o.sent(),n=t.code,r=t.message,this._clearTimerById(e),n===C.SUCCESS?(r.sentTime,this._userInfo[e]&&(this._userInfo[e].state=S.KEEPING),this._beginTimestamp=Date.now(),this._notifyUserStateChange(this._userInfo[e]),this._notifyStateChange(T.KEEPING)):(this._userInfo[e]&&(this._userInfo[e].state=S.NONE),this._notifyUserStateChange(this._userInfo[e]),i=n===C.REJECTED_BY_BLACKLIST?I.ADDED_TO_BLACKLIST:I.NETWORK_ERROR,this._notifyStateChange(T.END,i)),[2,{code:n}]}}))}))}}),Object.defineProperty(e.prototype,"invite",{enumerable:!1,configurable:!0,writable:!0,value:function(e,n){return void 0===n&&(n={}),f(this,void 0,void 0,(function(){var r,i,o,s,a,l,c,u,d,_,h=this;return g(this,(function(f){switch(f.label){case 0:return this._conversationType!==t.GROUP?[2,{code:C.CONVERSATION_NOT_GROUP_ERROR}]:(this._logger.debug("_","[RCCallStateMachine] invite -> userIds: ".concat(JSON.stringify(e))),r=this._context.getCurrentId(),i=Object.keys(this._userInfo),o=i.map((function(t){var n=b.CONNECTED;return(e.includes(t)||h._userInfo[t].state===S.WAITING)&&(n=b.RINGING),{userId:t,mediaType:h._mediaType,callStatus:n,mediaId:t}})),s=n.extra,a=void 0===s?"":s,l=n.pushConfig,[4,this._callMsgHandler.sendMemeberModify({channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,extra:a,pushConfig:l,mediaType:this._mediaType,inviteUserIds:e.filter((function(e){return e!==r})),callerId:this.getCallerId(),existedUserPofiles:o,directionalUserIdList:p(p([],i,!0),e,!0).filter((function(e){return e!==r}))})]);case 1:return c=f.sent(),u=c.code,d=c.message,u===C.SUCCESS?(_=d.sentTime,e.forEach((function(e){h._userInfo[e]={userId:e,state:S.WAITING,isCaller:!1,isRemote:!0},h._notifyUserStateChange(h._userInfo[e]),h._userTimers[e]=new U((function(){h._userInfo[e]&&(h._userInfo[e].state=S.NONE),h._notifyUserStateChange(h._userInfo[e],I.REMOTE_NO_RESPONSE),h._watchers.onHungup(h._userInfo[e],I.REMOTE_NO_RESPONSE),delete h._userInfo[e],Object.keys(h._userInfo).length<2&&h._notifyStateChange(T.END,I.REMOTE_NO_RESPONSE)}),h._getTimeout(_))}))):e.forEach((function(e){h._userInfo[e]={userId:e,state:S.NONE,isCaller:!1,isRemote:!0};var t=u===C.REJECTED_BY_BLACKLIST?I.ADDED_TO_BLACKLIST:I.NETWORK_ERROR;h._notifyUserStateChange(h._userInfo[e],t)})),[2,{code:u}]}}))}))}}),Object.defineProperty(e.prototype,"_hungupHandle",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return void 0===t&&(t=!0),f(this,void 0,void 0,(function(){var n,r,i,o,s;return g(this,(function(a){switch(a.label){case 0:return n=this._context.getCurrentId(),r=C.SUCCESS,t?(i={channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,reason:e,userIds:this.getRemoteUserIds(),pushConfig:this._hungupPushConfig},e!==I.OTHER_CLIENT_JOINED_CALL?[3,1]:(this._callMsgHandler.sendHungup(i),[3,3])):[3,3];case 1:return[4,this._callMsgHandler.sendHungup(i)];case 2:o=a.sent().code,r=o,a.label=3;case 3:for(s in this._endTimestamp=Date.now(),this._userInfo)this._userInfo[s].state=S.NONE,s===n?this._notifyUserStateChange(this._userInfo[s],e):this._notifyUserStateChange(this._userInfo[s]),delete this._userInfo[s];return Object.keys(this._userInfo).length<2&&this._notifyStateChange(T.END,e),[2,{code:r}]}}))}))}}),Object.defineProperty(e.prototype,"hungup",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,n;return g(this,(function(r){for(n in this._logger.debug("_","[RCCallStateMachine] hungup"),e=this._context.getCurrentId(),t=I.HANGUP,Object.keys(this._userTimers).length>0&&(this._userInfo[e].isCaller?t=I.CANCEL:this._userInfo[e].state===S.WAITING&&(t=I.REJECT)),this._userTimers)this._clearTimerById(n);return[2,this._hungupHandle(t)]}))}))}}),Object.defineProperty(e.prototype,"changeMediaType",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t;return g(this,(function(n){switch(n.label){case 0:return this._logger.debug("_","[RCCallStateMachine] changeMediaType -> mediaType: ".concat(e)),[4,this._callMsgHandler.sendMediaModify({channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,mediaType:e,userIds:this.getRemoteUserIds()})];case 1:return(t=n.sent().code)===C.SUCCESS&&(this._mediaType=e),[2,{code:t}]}}))}))}}),Object.defineProperty(e.prototype,"userJoin",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this;this._logger.debug("_","[RCCallStateMachine] userJoin -> userIds: ".concat(JSON.stringify(e))),setTimeout((function(){e.forEach((function(e){var n=t._userInfo[e];n&&n.state!==S.KEEPING&&(n.state=S.KEEPING,t._notifyUserStateChange(n)),t._sessionState!==T.KEEPING&&t._notifyStateChange(T.KEEPING),t._clearTimerById(e)}))}),300)}}),Object.defineProperty(e.prototype,"userLeave",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this;this._logger.debug("_","[RCCallStateMachine] userLeave -> userIds: ".concat(JSON.stringify(e))),setTimeout((function(){e.forEach((function(e){var n=t._userInfo[e];n&&n.state!==S.NONE&&(n.state=S.NONE,t._notifyUserStateChange(n,I.REMOTE_HANGUP),t._watchers.onHungup(n,I.REMOTE_HANGUP),delete t._userInfo[e]),new U((function(){var e=t.getRemoteUsers();1===e.length&&1===e[0].state&&t._hungupHandle(I.REMOTE_NETWORK_ERROR)}),6e4),Object.keys(t._userInfo).length<2&&t._sessionState!==T.END&&(t._endTimestamp=Date.now(),t._notifyStateChange(T.END,I.REMOTE_HANGUP))}))}),300)}}),Object.defineProperty(e.prototype,"close",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._hungupHandle(e)}}),Object.defineProperty(e.prototype,"setHungupPushConfig",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._hungupPushConfig=e}}),Object.defineProperty(e.prototype,"getCallId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._callId}}),Object.defineProperty(e.prototype,"getChannelId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._channelId}}),Object.defineProperty(e.prototype,"getTargetId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._targetId}}),Object.defineProperty(e.prototype,"getConversationType",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._conversationType}}),Object.defineProperty(e.prototype,"getRemoteUserIds",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;return Object.keys(this._userInfo).filter((function(t){return e._context.getCurrentId()!==t}))}}),Object.defineProperty(e.prototype,"getRemoteUsers",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=[],t=this._context.getCurrentId();for(var n in this._userInfo){this._userInfo[n].userId!==t&&e.push(this._userInfo[n])}return e}}),Object.defineProperty(e.prototype,"getState",{enumerable:!1,configurable:!0,writable:!0,value:function(){return null===this._sessionState?T.END:this._sessionState}}),Object.defineProperty(e.prototype,"getUserState",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t;return null===(t=this._userInfo[e])||void 0===t?void 0:t.state}}),Object.defineProperty(e.prototype,"getCallerId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._callerId}}),Object.defineProperty(e.prototype,"getInviterId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._inviterId}}),Object.defineProperty(e.prototype,"getMediaType",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._mediaType}}),Object.defineProperty(e.prototype,"getSummary",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this._beginTimestamp,t=this._endTimestamp,n=0;t>e&&0!==e&&(n=t-e);var r={conversationType:this._conversationType,channelId:this._channelId,targetId:this._targetId,mediaType:this._mediaType,beginTimestamp:e,endTimestamp:t,duration:n,endReason:this._endReason};return this._logger.debug("_","[RCCallStateMachine] getSummary -> summary: ".concat(JSON.stringify(r))),r}}),e}();!function(e){e[e.AUDIO=1]="AUDIO",e[e.AUDIO_VIDEO=2]="AUDIO_VIDEO"}(w||(w={})),function(e){e[e.ADD=1]="ADD",e[e.REMOVE=2]="REMOVE"}(N||(N={})),function(e){e.WEB="Web",e.IOS="iOS",e.ANDROID="Android"}(A||(A={}));var j,D,k=function(){function e(e,t,n){Object.defineProperty(this,"_context",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"_onRecord",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(this,"_messages",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_channelId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_conversationType",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_targetId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_mediaType",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_callId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_callerId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_inviterId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_endReason",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_beginTimestamp",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_endTimestamp",{enumerable:!0,configurable:!0,writable:!0,value:0})}return Object.defineProperty(e.prototype,"_doInvite",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._context.getCurrentId();var t=e.channelId,n=e.conversationType,r=e.targetId,i=e.senderUserId,o=e.content,s=o.callId,a=o.mediaType;this._channelId=t,this._conversationType=n,this._targetId=r,this._callId=s,this._mediaType=a;this._inviterId=i,this._endReason=I.REMOTE_NO_RESPONSE,this._canGenRecord()}}),Object.defineProperty(e.prototype,"_doMemberModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._doInvite(e)}}),Object.defineProperty(e.prototype,"_doRinging",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._canGenRecord()}}),Object.defineProperty(e.prototype,"_doAccept",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._endReason=I.HANGUP,this._beginTimestamp=e.sentTime,this._canGenRecord()}}),Object.defineProperty(e.prototype,"_doHungup",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.content,n=e.sentTime,r=e.senderUserId,i=t.reason,o=r===this._context.getCurrentId();this._endReason=o?i:P[i],this._endTimestamp=n,this._canGenRecord()}}),Object.defineProperty(e.prototype,"_doMediaModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.content.mediaType;this._mediaType=t,this._canGenRecord()}}),Object.defineProperty(e.prototype,"_canGenRecord",{enumerable:!1,configurable:!0,writable:!0,value:function(){if(0===this._messages.length){var e=0;[I.HANGUP,I.REMOTE_HANGUP,I.OTHER_CLIENT_JOINED_CALL,I.REMOTE_OTHER_CLIENT_JOINED_CALL,I.KICKED_BY_SERVER,I.REMOTE_KICKED_BY_SERVER,I.ACCEPT_SYSTEM_CALL,I.REMOTE_ACCEPT_SYSTEM_CALL].includes(this._endReason)&&(e=this._endTimestamp-this._beginTimestamp),this._onRecord({channelId:this._channelId,conversationType:this._conversationType,targetId:this._targetId,callId:this._callId,inviterId:this._inviterId,mediaType:this._mediaType,endReason:this._endReason,beginTimestamp:this._beginTimestamp,endTimestamp:this._endTimestamp,duration:e})}}}),Object.defineProperty(e.prototype,"onRecvOfflineMsgs",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._messages=e;do{var t=this._messages.shift(),n=t.messageType;switch(t.content.callId,n){case O.VCInvite:this._doInvite(t);break;case O.VCRinging:this._doRinging(t);break;case O.VCAccept:this._doAccept(t);break;case O.VCModifyMem:this._doMemberModify(t);break;case O.VCModifyMedia:this._doMediaModify(t);break;case O.VCHangup:this._doHungup(t);break;default:this._logger.debug("_","[OfflineRecorder] onRecvOfflineMsgs -> unexpected message: ".concat(JSON.stringify(t)))}}while(this._messages.length>0)}}),e}(),H=["RC:VCAccept","RC:VCRinging","RC:VCSummary","RC:VCHangup","RC:VCInvite","RC:VCModifyMedia","RC:VCModifyMem"],V=((j={})[n.REJECTED_BY_BLACKLIST]=C.REJECTED_BY_BLACKLIST,j[n.NOT_IN_GROUP]=C.NOT_IN_GROUP,j),G=function(e){function r(t,n,r,i,o){void 0===i&&(i=6e4);var s=e.call(this)||this;return Object.defineProperty(s,"_context",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(s,"_runtime",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(s,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:r}),Object.defineProperty(s,"_offlineMsgItv",{enumerable:!0,configurable:!0,writable:!0,value:i}),Object.defineProperty(s,"_getStateMachine",{enumerable:!0,configurable:!0,writable:!0,value:o}),Object.defineProperty(s,"_watchers",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(s,"_userInfo",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(s,"_msgBufferList",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(s,"_hadHandleMsgTimer",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(s,"_offlineRecorder",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(s,"_deviceId",{enumerable:!0,configurable:!0,writable:!0,value:""}),s._deviceId=v(n),s._context.onmessage=s._onMessage.bind(s),s._offlineRecorder=new k(s._context,s._logger,(function(e){s._logger.info("_","[CallMessageHandler] offlineRecorder -> ".concat(JSON.stringify(e))),s._watchers.onOfflineRecord&&s._watchers.onOfflineRecord(e)})),s}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}(r,e),Object.defineProperty(r.prototype,"_onMessage",{enumerable:!1,configurable:!0,writable:!0,value:function(e){if(H.includes(e.messageType)){this._logger.debug("_","[CallMessageHandler] _onMessage -> call message: ".concat(JSON.stringify(e)));try{var t=Date.now(),n=e.sentTime,r=0;this._msgBufferList.forEach((function(e,t){var i=e.msg.sentTime;n>=i&&(r=t+1)})),this._msgBufferList.splice(r,0,{markTime:t,msg:e}),this._logger.warn("_","onMessage -> msgBufferList: ".concat(this._msgBufferList.length))}catch(e){this._logger.error("_","[CallMessageHandler] splice buffer msg error -> ".concat(e.message))}return this._handleBufferMsgs(),!0}return!1}}),Object.defineProperty(r.prototype,"_onRecvOnlineCallMsg",{enumerable:!1,configurable:!0,writable:!0,value:function(t){this._logger.info("_","onMessage -> _onRecvOnlineCallMsg: ".concat(t.messageType));var n=t.content.callId;switch(t.messageType){case O.VCInvite:this._watchers.onInvite&&this._watchers.onInvite(t);break;case O.VCRinging:e.prototype.emit.call(this,"".concat(n,"onRinging"),t);break;case O.VCAccept:e.prototype.emit.call(this,"".concat(n,"onAccept"),t);break;case O.VCModifyMem:this._watchers.onInvite&&this._watchers.onInvite(t);break;case O.VCModifyMedia:e.prototype.emit.call(this,"".concat(n,"onMediaModify"),t);break;case O.VCHangup:e.prototype.emit.call(this,"".concat(n,"onHungup"),t);break;default:this._logger.warn("_","[CallMessageHandler] onRecvOnlineCallMsg -> unexpected message: ".concat(JSON.stringify(t)))}}}),Object.defineProperty(r.prototype,"_handleBufferMsgs",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;0===this._msgBufferList.length||this._hadHandleMsgTimer?this._logger.warn("_","_handleBufferMsgs return"):(this._hadHandleMsgTimer=!0,setTimeout((function(){var n=Date.now(),r=e._msgBufferList.filter((function(e){return n-e.markTime>=200}));if(e._logger.debug("_","[CallMessageHandler] handleBufferMsgs -> lists over 200ms : ".concat(JSON.stringify(r.map((function(e){var t=e.msg;return{messageUId:t.messageUId,isOffLineMessage:t.isOffLineMessage,callId:t.content.callId}}))))),0===r.length)return e._hadHandleMsgTimer=!1,void e._handleBufferMsgs();if(r[0].msg.isOffLineMessage){var i=e._msgBufferList.filter((function(e){return e.msg.isOffLineMessage})),o=function(){var n=i[0].msg,r=n.conversationType,o=n.messageType,s=n.sentTime,a=n.senderUserId,l=n.content,c=l.callId,u=l.inviteUserIds,d=[O.VCInvite,O.VCModifyMem].includes(o),_=e._context.getServerTime()-s,h=_<e._offlineMsgItv;if(h||e._logger.warn("_","offline msg delayTime: ".concat(_,"ms")),d){for(var f=[],g=0;g<i.length;g++){var b=i[g].msg;if(c!==b.content.callId)break;f.push(b)}if(e._logger.warn("_","taskMsgList length: ".concat(f.length)),f.length>0){var C=e._msgBufferList.findIndex((function(e){return e.msg.messageUId===f[f.length-1].messageUId}));e._msgBufferList=e._msgBufferList.slice(C+1);var R=i.findIndex((function(e){return e.msg.messageUId===f[f.length-1].messageUId}));i=i.slice(R+1)}var I=function(){if(r!==t.PRIVATE)return!1;var e=1===f.length,n=f.every((function(e){return[O.VCInvite,O.VCModifyMedia,O.VCRinging].includes(e.messageType)}));return e||n}(),m=function(){if(r!==t.GROUP)return!1;for(var n=!1,i=!0,o=p([a],u,!0),s=!1,l=function(t){var n=f[t],r=n.senderUserId,l=n.messageType;if(l===O.VCHangup&&r===e._context.getCurrentId())return"break";l===O.VCHangup&&(s=a===r,o=o.filter((function(e){return r!==e}))),l===O.VCAccept&&(i=!1)},c=0;c<f.length;c++){if("break"===l(c))break}return i&&s||!(o.length>1)||(n=!0),n}();h&&(I||m)&&f.forEach(e._onRecvOnlineCallMsg,e),e._offlineRecorder.onRecvOfflineMsgs(f)}else h&&e._getStateMachine(c)?e._onRecvOnlineCallMsg(i[0].msg):e._logger.debug("_","[CallMessageHandler] unexcepted offline msg -> ".concat(JSON.stringify(i[0].msg))),i.shift(),e._msgBufferList.shift()};do{o()}while(i.length>0)}else{r.forEach((function(t){var n=t.msg;e._onRecvOnlineCallMsg(n)}));var s=r.length;e._msgBufferList.splice(0,s),e._logger.debug("_","timer online msg handle -> delCount: ".concat(s," msgBufferList: ").concat(e._msgBufferList.length))}e._hadHandleMsgTimer=!1,e._handleBufferMsgs()}),20))}}),Object.defineProperty(r.prototype,"registerEventListener",{enumerable:!1,configurable:!0,writable:!0,value:function(e){Object.assign(this._watchers,e)}}),Object.defineProperty(r.prototype,"registerStateMachineEvent",{enumerable:!1,configurable:!0,writable:!0,value:function(t,n,r){var i=t+n;e.prototype.on.call(this,i,r)}}),Object.defineProperty(r.prototype,"unregisterStateMachineEvent",{enumerable:!1,configurable:!0,writable:!0,value:function(t){var n=this;["onRinging","onAccept","onHungup","onMediaModify"].forEach((function(r){var i=t+r;e.prototype.removeAll.call(n,i)}))}}),Object.defineProperty(r.prototype,"registerUserInfo",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._userInfo=e}}),Object.defineProperty(r.prototype,"_sendCallMessage",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t,r,i,o,s,a,l,c,u,d,_,h;return g(this,(function(f){switch(f.label){case 0:return this._logger.debug("_","CallMessageHandler] sendCallMesage -> message: ".concat(JSON.stringify(e))),t=e.channelId,r=e.conversationType,i=e.targetId,o=e.content,s=e.messageType,a=e.directionalUserIdList,l=e.pushConfig,c={channelId:t,messageType:s,content:o,directionalUserIdList:a},[O.VCInvite,O.VCModifyMem,O.VCHangup].includes(s)&&((u=l||{pushTitle:"",pushContent:"",pushData:""}).androidConfig=Object.assign((null==l?void 0:l.androidConfig)||{},{categoryHW:"VOIP",categoryVivo:"IM"}),u.iOSConfig=Object.assign(u.iOSConfig||{},{apnsCollapseId:o.callId}),u.disablePushTitle=!1,u.forceShowDetailContent=!1,c.pushConfig=u),[4,this._context.sendMessage(r,i,c)];case 1:return d=f.sent(),_=d.code,h=d.data,_!==n.SUCCESS?(this._logger.error("_","CallMessageHandler] sendCallMesage error -> code: ".concat(_)),[2,{code:V[_]||C.SEND_MSG_ERROR}]):[2,{code:C.SUCCESS,message:h}]}}))}))}}),Object.defineProperty(r.prototype,"sendInvite",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a,l,c,u,d;return g(this,(function(_){return n=e.roomType,r=e.channelId,i=e.conversationType,o=e.targetId,s=e.callId,a=e.mediaType,l=e.inviteUserIds,c=e.extra,u=e.pushConfig,this._logger.warn("_","CallMessageHandler] sendCallMesage sendInvite",JSON.stringify(e)),this._watchers.sendAccept&&this._watchers.sendAccept({callId:s}),d={platform:A.WEB,deviceId:this._deviceId,callId:s,roomType:n,extra:c,engineType:4,channelInfo:{Id:s,Key:""},mediaType:a,inviteUserIds:l,observerUserIds:[],user:this._userInfo},u&&(u.pushData=JSON.stringify({mediaType:a,userIdList:l,callId:s})),[2,this._sendCallMessage({channelId:r,conversationType:i,targetId:o,content:d,messageType:O.VCInvite,directionalUserIdList:i===t.GROUP?l:void 0,pushConfig:u})]}))}))}}),Object.defineProperty(r.prototype,"sendMemeberModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t,n,r,i,o,s,a,l,c,u,d,_;return g(this,(function(h){return t=e.channelId,n=e.conversationType,r=e.targetId,i=e.callId,o=e.mediaType,s=e.inviteUserIds,a=e.callerId,l=e.existedUserPofiles,c=e.directionalUserIdList,u=e.extra,d=e.pushConfig,_={platform:A.WEB,deviceId:this._deviceId,callId:i,extra:u,engineType:4,channelInfo:{Id:i,Key:""},mediaType:o,inviteUserIds:s,observerUserIds:[],user:this._userInfo,caller:a,modifyMemType:N.ADD,existedUserPofiles:l},d&&(d.pushData=JSON.stringify({mediaType:o,userIdList:s,callId:i})),[2,this._sendCallMessage({channelId:t,conversationType:n,targetId:r,content:_,messageType:O.VCModifyMem,directionalUserIdList:c,pushConfig:d})]}))}))}}),Object.defineProperty(r.prototype,"sendRinging",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var n=e.channelId,r=e.conversationType,i=e.targetId,o=e.callId,s=e.userIds,a={platform:A.WEB,deviceId:this._deviceId,callId:o,user:this._userInfo};return this._sendCallMessage({channelId:n,conversationType:r,targetId:i,content:a,messageType:O.VCRinging,directionalUserIdList:r===t.GROUP?s:void 0})}}),Object.defineProperty(r.prototype,"sendAccept",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var n=e.channelId,r=e.conversationType,i=e.targetId,o=e.callId,s=e.mediaType,a=e.userIds,l={platform:A.WEB,deviceId:this._deviceId,callId:o,mediaType:s,user:this._userInfo};return this._sendCallMessage({channelId:n,conversationType:r,targetId:i,content:l,messageType:O.VCAccept,directionalUserIdList:r===t.GROUP?a:void 0})}}),Object.defineProperty(r.prototype,"sendHungup",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var n=e.channelId,r=e.conversationType,i=e.targetId,o=e.callId,s=e.reason,a=e.userIds,l=e.pushConfig,c={platform:A.WEB,deviceId:this._deviceId,callId:o,reason:s,user:this._userInfo};return l&&(l.pushData=JSON.stringify({callId:o,reason:s})),this._sendCallMessage({channelId:n,conversationType:r,targetId:i,content:c,messageType:O.VCHangup,pushConfig:l,directionalUserIdList:r===t.GROUP?a:void 0})}}),Object.defineProperty(r.prototype,"sendMediaModify",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var n=e.channelId,r=e.conversationType,i=e.targetId,o=e.callId,s=e.mediaType,a=e.userIds,l={platform:A.WEB,deviceId:this._deviceId,callId:o,mediaType:s,user:this._userInfo};return this._sendCallMessage({channelId:n,conversationType:r,targetId:i,content:l,messageType:O.VCModifyMedia,directionalUserIdList:r===t.GROUP?a:void 0})}}),r}(e);!function(e){e.ZH="zh",e.EN="en"}(D||(D={}));var x,B={PushTitle:{AUDIO:"You have a voice call",VIDEO:"You have a video call"}},K={PushTitle:{AUDIO:"您有一条音频通话",VIDEO:"您有一条视频通话"}},J=function(){function e(){}return Object.defineProperty(e,"set",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._lang=e}}),Object.defineProperty(e,"get",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._lang===D.EN?B:K}}),Object.defineProperty(e,"_lang",{enumerable:!0,configurable:!0,writable:!0,value:D.ZH}),e}(),W=function(){function e(e,t,n,r,i){var o=this;Object.defineProperty(this,"_context",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"_runtime",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(this,"_watchers",{enumerable:!0,configurable:!0,writable:!0,value:r}),Object.defineProperty(this,"_options",{enumerable:!0,configurable:!0,writable:!0,value:i}),Object.defineProperty(this,"_stateMachine",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"_callMsgHandler",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._logger.warn("_","RCCallEngine Version: ".concat("5.2.6"," CommitId: ").concat("6761942c405d068867e89ca6c16d888599154bde")),v(t),this._callMsgHandler=new G(this._context,this._runtime,this._logger,this._options.offlineMsgItv,this._getStateMachine.bind(this)),this._callMsgHandler.registerEventListener({onInvite:this._onInvite.bind(this),sendAccept:this._handleSendAccept.bind(this),onOfflineRecord:this._watchers.onOfflineRecord}),E.on("onStateMachineClose",(function(e){delete o._stateMachine[e]})),J.set(i.lang)}return Object.defineProperty(e.prototype,"_onInvite",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.channelId,n=e.conversationType,r=e.targetId,i=e.content,o=e.messageType,s=e.senderUserId;e.pushConfig,this._logger.warn("_","RCCallEngine _onInvite:targetId ".concat(r," senderUserId: ").concat(s));var a,l=i,c=l.mediaType,u=l.callId,d=l.extra;a=l.roomType!==M.RCCallRoomTypeAcrossCall?s:s.split("_")[1];var _=this._context.getCurrentId();if(this._context.getCurrentId()!==a){if(o===O.VCModifyMem)if(i.existedUserPofiles.some((function(e){return e.userId===_}))&&!this._stateMachine[u])return;if(this._stateMachine[u])o===O.VCModifyMem&&this._stateMachine[u].__onMemberModify(e);else this._stateMachine[u]=new L(this._context,this._runtime,this._logger,this._callMsgHandler,t,n,r,c,u),this._logger.info("_","[RCCallEngine] RCCallStateMachine successfully created -> callId: ".concat(u)),o===O.VCInvite?this._stateMachine[u].__onInvite(e):o===O.VCModifyMem&&this._stateMachine[u].__onMemberModify(e),this._watchers.onInvite(this._stateMachine[u],d),Object.keys(this._stateMachine).filter((function(e){return u!==e})).length>0&&!this._options.isAllowAcceptNewCall&&this._stateMachine[u].__handleInviteInSession()}}}),Object.defineProperty(e.prototype,"_handleSendAccept",{enumerable:!1,configurable:!0,writable:!0,value:function(e){if(this._options.isAllowAcceptNewCall){var t=e.callId;for(var n in this._stateMachine)t!==n&&(this._stateMachine[n].hungup(),delete this._stateMachine[n])}}}),Object.defineProperty(e.prototype,"_getStateMachine",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return this._stateMachine[e]}}),Object.defineProperty(e.prototype,"registerUserInfo",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._logger.debug("_","[RCCallEngine] registerUserInfo -> userInfo: ".concat(JSON.stringify(e))),this._callMsgHandler.registerUserInfo(e)}}),Object.defineProperty(e.prototype,"call",{enumerable:!1,configurable:!0,writable:!0,value:function(e,n,r,i,o,s){return void 0===i&&(i=""),void 0===s&&(s=!1),f(this,void 0,void 0,(function(){var a,l;return g(this,(function(c){switch(c.label){case 0:return this._logger.debug("_","[RCCallEngine] call -> args: ".concat(JSON.stringify({channelId:e,targetId:n,mediaType:r,extra:i,pushConfig:o}))),a=y(),Object.keys(this._stateMachine).length>0?[2,{code:C.STATE_MACHINE_EXIT}]:(this._stateMachine[a]=new L(this._context,this._runtime,this._logger,this._callMsgHandler,e,t.PRIVATE,n,r,a),[4,this._stateMachine[a].__call([n],i,o,s)]);case 1:return(l=c.sent().code)===C.SUCCESS?[2,{code:C.SUCCESS,stateMachine:this._stateMachine[a]}]:[2,{code:l}]}}))}))}}),Object.defineProperty(e.prototype,"callInGroup",{enumerable:!1,configurable:!0,writable:!0,value:function(e,n,r,i,o,s){return void 0===o&&(o=""),f(this,void 0,void 0,(function(){var a,l;return g(this,(function(c){switch(c.label){case 0:return this._logger.debug("_","[RCCallEngine] callInGroup -> args: ".concat(JSON.stringify({channelId:e,targetId:n,mediaType:r}))),a=y(),Object.keys(this._stateMachine).length>0?[2,{code:C.STATE_MACHINE_EXIT}]:(this._stateMachine[a]=new L(this._context,this._runtime,this._logger,this._callMsgHandler,e,t.GROUP,n,r,a),[4,this._stateMachine[a].__call(i,o,s)]);case 1:return(l=c.sent().code)===C.SUCCESS?[2,{code:C.SUCCESS,stateMachine:this._stateMachine[a]}]:[2,{code:l}]}}))}))}}),Object.defineProperty(e.prototype,"destroy",{enumerable:!1,configurable:!0,writable:!0,value:function(){this._logger.debug("_","[RCCallEngine] destroy"),this._stateMachine={}}}),e}();!function(e){e[e.CALLER=1]="CALLER",e[e.CALLEE=2]="CALLEE"}(x||(x={}));var Y=new(function(){function e(){Object.defineProperty(this,"list",{enumerable:!0,configurable:!0,writable:!0,value:{}})}return Object.defineProperty(e.prototype,"on",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return(this.list[e]||(this.list[e]=[])).push(t),this}}),Object.defineProperty(e.prototype,"once",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var n=this,r=function(i){n.off(e,r),t.call(n,i)};r.fun=t,this.on(e,r)}}),Object.defineProperty(e.prototype,"off",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var n=this.list[e];if(!n)return!1;if(t){for(var r=void 0,i=0,o=n.length;i<o;i++)if((r=n[i])===t||r.fun===t){n.splice(i,1);break}}else n&&(n.length=0)}}),Object.defineProperty(e.prototype,"emit",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var n=this,r=p([],this.list[e],!0);if(!r||0===r.length)return!1;r.forEach((function(e){e.call(n,t)}))}}),e}());var F=function(e){if(!e)return{result:!1,msg:"Initialization missing parameter -> options"};if("object"!=typeof e)return{result:!1,msg:"Initialization options must be an object"};var t,n=Object.keys(e),r=[];return["rtcClient","onSession","onSessionClose"].forEach((function(e){n.includes(e)||r.push(e)})),r.length?{result:!1,msg:'Initialization missing parameter -> "'.concat(r.join(","),'"')}:"object"!=typeof e.rtcClient?{result:!1,msg:"Initialization 'rtcClient' parameter must be of type 'object'"}:"function"!=typeof e.onSession?{result:!1,msg:"Initialization 'onSession' parameter must be of type 'function'"}:"function"!=typeof e.onSessionClose?{result:!1,msg:"Initialization 'onSessionClose' parameter must be of type 'function'"}:void 0!==e.isAllowSubscribeRetry&&"boolean"!=typeof e.isAllowSubscribeRetry?{result:!1,msg:"Initialization 'isAllowSubscribeRetry' parameter must be of type 'boolean'"}:void 0!==e.isAllowPublishRetry&&"boolean"!=typeof e.isAllowPublishRetry?{result:!1,msg:"Initialization 'isAllowPublishRetry' parameter must be of type 'boolean'"}:void 0!==e.isOffCameraWhenVideoDisable&&"boolean"!=typeof e.isOffCameraWhenVideoDisable?{result:!1,msg:"Initialization 'isOffCameraWhenVideoDisable' parameter must be of type 'boolean'"}:void 0===e.joinType||(t=e.joinType,Object.values(s).includes(t))?void 0!==e.isAllowDemotionGetStream&&"boolean"!=typeof e.isAllowDemotionGetStream?{result:!1,msg:"Initialization 'isAllowDemotionGetStream' parameter must be of type 'boolean'"}:void 0===e.lang||function(e){return Object.values(D).includes(e)}(e.lang)?void 0===e.logOutputLevel||function(e){return[a.DEBUG,a.INFO,a.WARN,a.ERROR].includes(e)}(e.logOutputLevel)?{result:!0}:{result:!1,msg:"Initialization 'logOutputLevel' parameter must be of type correct type"}:{result:!1,msg:"Initialization 'lang' parameter must be of type correct type"}:{result:!1,msg:"Initialization 'joinType' parameter must be of type correct type"}},z=function(e){if(!e)return{result:!1,msg:"missing parameter -> listener"};if("object"!=typeof e)return{result:!1,msg:"listener must be an object"};var t=Object.keys(e),n=[];return["onRinging","onAccept","onHungup","onTrackReady"].forEach((function(e){t.includes(e)||n.push(e)})),n.length?{result:!1,msg:'missing parameter -> "'.concat(n.join(","),'"')}:"function"!=typeof e.onRinging?{result:!1,msg:"'onRinging' parameter must be of type 'function'"}:"function"!=typeof e.onAccept?{result:!1,msg:"'onAccept' parameter must be of type 'function'"}:"function"!=typeof e.onHungup?{result:!1,msg:"'onHungup' parameter must be of type 'function'"}:"function"!=typeof e.onTrackReady?{result:!1,msg:"'onTrackReady' parameter must be of type 'function'"}:{result:!0}},q=function(e){return e&&"string"==typeof e?{result:!0}:{result:!1,msg:"'targetId' parameter is required, must be of type 'string'"}},X=function(e){return e===w.AUDIO||e===w.AUDIO_VIDEO?{result:!0}:{result:!1,msg:"'mediaType' parameter is required, must be of type 'RCCallMediaType'"}},Z=function(e){return"string"==typeof e?{result:!0}:{result:!1,msg:"'extra' parameter must be of type 'string'"}},Q=function(e){var t=["pushTitle","pushContent","pushData","iOSConfig","androidConfig","disablePushTitle","templateId"],n=Object.keys(e).every((function(e){return t.includes(e)}));if(!n)return{code:C.PARAM_ERROR,errorMsg:"right key: ".concat(t.join(","))};for(var s=0;s<t.length;s++){var a=t[s];if("disablePushTitle"===a){if(!r(e[a])&&!i(e[a]))return{code:C.PARAM_ERROR,errorMsg:"".concat(a," type is boolean")}}else if(("pushTitle"===a||"templateId"===a)&&e[a]&&!o(e[a]))return{code:C.PARAM_ERROR,errorMsg:"".concat(a," type is string")}}var l=e.iOSConfig,c=e.androidConfig,u=$(l||{});if(u.code!==C.SUCCESS)return u;var d=ee(c||{});return d.code!==C.SUCCESS?d:{code:C.SUCCESS}},$=function(e){var t=e||{},n=t.threadId,r=t.richMediaUri;return n&&!o(n)?{code:C.PARAM_ERROR,errorMsg:"iOSConfig.threadId type is string"}:r&&!o(r)?{code:C.PARAM_ERROR,errorMsg:"iOSConfig.richMediaUri type is string"}:{code:C.SUCCESS}},ee=function(e){var t=["notificationId","channelIdMi","channelIdHW","categoryHW","importanceHW","imageUrlHW","channelIdOPPO","typeVivo","categoryVivo","fcmChannelId","fcmCollapseKey","fcmImageUrl","importanceHonor","imageUrlHonor"],n=Object.keys(e).every((function(e){return t.includes(e)}));if(!n)return{code:C.PARAM_ERROR,errorMsg:"right key: ".concat(t.join(","))};for(var r=0;r<t.length;r++){var i=t[r];if("importanceHW"===i||"importanceHonor"===i){if(e[i]&&"LOW"!==e[i]&&"NORMAL"!==e[i])return{code:C.PARAM_ERROR,errorMsg:"androidConfig.".concat(i," value is NORMAL|LOW")}}else if(e[i]&&!o(e[i]))return{code:C.PARAM_ERROR,errorMsg:"androidConfig.".concat(i," type is string")}}return{code:C.SUCCESS}},te=function(e){return Array.isArray(e)&&e.length?e.every((function(e){return"string"==typeof e&&e.length>0}))?{result:!0}:{result:!1,msg:"'userIds' parameter is required"}:{result:!1,msg:"'userIds' parameter is required, must be of type 'string[]'"}};var ne=function(e){return e&&e.audio&&void 0!==e.audio.micphoneId&&"string"!=typeof e.audio.micphoneId?{result:!1,msg:"'constraints.audio.micphoneId' must be of type 'string'"}:e&&e.audio&&void 0!==e.audio.sampleRate&&"number"!=typeof e.audio.sampleRate?{result:!1,msg:"'constraints.audio.sampleRate' must be of type 'number'"}:e&&e.video&&void 0!==e.video.cameraId&&"string"!=typeof e.video.cameraId?{result:!1,msg:"'constraints.video.cameraId' must be of type 'string'"}:e&&e.video&&void 0!==e.video.frameRate&&"string"!=typeof e.video.frameRate?{result:!1,msg:"'constraints.video.frameRate' must be of type 'string'"}:e&&e.video&&void 0!==e.video.frameRate&&(t=e.video.frameRate,!["FPS_10","FPS_15","FPS_24","FPS_30"].includes(t))?{result:!1,msg:"'frameRate' value is out of range"}:e&&e.video&&void 0!==e.video.resolution&&"string"!=typeof e.video.resolution?{result:!1,msg:"'constraints.video.frameRate' must be of type 'string'"}:e&&e.video&&void 0!==e.video.resolution&&(n=e.video.resolution,!c[n])?{result:!1,msg:"'resolution' value is out of range"}:!e||!e.video||e.video.frameRate&&e.video.resolution?{result:!0}:{result:!1,msg:"'resolution' and 'resolution' is required"};var t,n},re=function(){function e(e,t){Object.defineProperty(this,"_timerId",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_startTime",{enumerable:!0,configurable:!0,writable:!0,value:0}),e&&(this._timerId=function(e,t){return setTimeout(e,t)}((function(){e()}),t)),this._startTime=Date.now()}return Object.defineProperty(e.prototype,"stop",{enumerable:!1,configurable:!0,writable:!0,value:function(){clearTimeout(this._timerId);var e=Date.now(),t=e-this._startTime;return 0===this._startTime&&(t=0),{startTime:this._startTime,endTime:e,duration:t}}}),Object.defineProperty(e.prototype,"reset",{enumerable:!1,configurable:!0,writable:!0,value:function(){this._startTime=0}}),e}(),ie=function(){function e(e,t,n,r){void 0===r&&(r={});var i=this;Object.defineProperty(this,"_stateMachine",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"_rtcClient",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(this,"_options",{enumerable:!0,configurable:!0,writable:!0,value:r}),Object.defineProperty(this,"_room",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_listener",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_RETRYCOUNT",{enumerable:!0,configurable:!0,writable:!0,value:2}),Object.defineProperty(this,"joinRoomTimer",{enumerable:!0,configurable:!0,writable:!0,value:null}),this._stateMachine.registerEventListener({onUserStateChange:function(e){var t=e.user,n=e.reason;i._logger.info("_","[RCCallSession onUserStateChange] userId->".concat(null==t?void 0:t.userId," state->").concat(null==t?void 0:t.state," reason->").concat(n))},onStateChange:function(e){return f(i,void 0,void 0,(function(){var t,n,r,i,o;return g(this,(function(s){switch(s.label){case 0:if(t=e.state,n=e.reason,this._logger.info("_","[RCCallSession onStateChange] : state->".concat(t," reason->").concat(n)),t!==T.KEEPING)return[3,5];r=this._stateMachine.getCallId(),this._logger.info("_","[RCCallSession onStateChange] roomId: ".concat(r)),s.label=1;case 1:return s.trys.push([1,3,,4]),[4,this._joinRoom(r)];case 2:return s.sent(),[3,4];case 3:return i=s.sent(),this._exceptionClose(I.NETWORK_ERROR),this._logger.error("_","[RCCallSession onStateChange] joinRoom throw exception roomId -> ".concat(r)),console.error(i),[3,4];case 4:return[3,6];case 5:if(t===T.END){if(!this._room)return this._options.localTracks&&this._destroyTracks(this._options.localTracks),o=this._stateMachine.getSummary(),Y.emit("sessionClose",{session:this,summaryInfo:o}),[2];this._options.localTracks&&this._destroyTracks(this._options.localTracks),this._logger.info("_","[RCCallSession onStateChange] localTracks destroyed"),this._leaveRoom(),this._room=null}s.label=6;case 6:return[2]}}))}))},onRinging:function(e){i._logger.info("_","[RCCallSession onRinging]sender: sender.userId -> ".concat(e.userId));try{i._listener.onRinging(e,i)}catch(e){i._logger.error("_","[RCCallSession onRinging] method exception -> onRinging"),console.error(e)}},onAccept:function(e){i._logger.info("_","[RCCallSession onAccept]sender: sender.userId -> ".concat(e.userId));try{i._listener.onAccept(e,i)}catch(e){i._logger.error("_","[RCCallSession onAccept] method exception -> onAccept"),console.error(e)}},onHungup:function(e,t){i._logger.info("_","[RCCallSession onHungup]sender: sender.userId -> ".concat(e.userId," reason->").concat(t));try{i._listener.onHungup(e,t,i)}catch(e){i._logger.error("_","[RCCallSession onHungup] method exception -> onHungup"),console.error(e)}},onMemberModify:function(e){var t=e.sender,n=e.invitedUsers;i._logger.info("_","[RCCallSession onMemberModify] sender.userId -> ".concat(t.userId));try{i._listener.onMemberModify(t,n,i)}catch(e){i._logger.error("_","[RCCallSession onMemberModify] method exception -> onMemberModify"),console.error(e)}},onMediaModify:function(e){var t=e.sender,n=e.mediaType;i._logger.info("_","[RCCallSession onMediaModify]sender: sender.userId -> ".concat(t.userId," mediaType: ").concat(n)),n===w.AUDIO&&i._setMediaTypeToAudio();try{i._listener.onMediaModify(t,n,i)}catch(e){i._logger.error("_","[RCCallSession onMediaModify] method exception -> onMediaModify"),console.error(e)}},crossAppkey:function(e){i._logger.info("_","[RCCallSession crossAppkey] 是否跨 appkey: ".concat(e)),i._options.isCrossAppkey=e}}),this._stateMachine.setHungupPushConfig(this._options.hungupPushConfig||{pushTitle:"",pushContent:""})}return Object.defineProperty(e.prototype,"_joinRoom",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a,l,c=this;return g(this,(function(u){switch(u.label){case 0:return u.trys.push([0,7,,8]),this._options.isCrossAppkey?[4,this._rtcClient.joinCrossRTCRoom(e,this._options.joinType)]:[3,2];case 1:return n=u.sent(),[3,4];case 2:return[4,this._rtcClient.joinRTCRoom(e,this._options.joinType)];case 3:n=u.sent(),u.label=4;case 4:return r=n.code,i=n.userIds,o=n.room,r!==d.SUCCESS?(r===d.NOT_OPEN_VIDEO_AUDIO_SERVER&&this._exceptionClose(I.SERVICE_NOT_OPENED),r===d.SIGNAL_JOIN_RTC_ROOM_REFUSED?this._exceptionClose(I.OTHER_CLIENT_IN_CALL):this._exceptionClose(I.NETWORK_ERROR),this._logger.info("_","[RCCallClient _joinRoom] join room failed: roomId -> ".concat(e," RCRTCCode -> ").concat(r)),[2,{code:C.JOIN_ROOM_ERROR}]):(this._stateMachine.getConversationType()===t.GROUP&&this._stateMachine.userJoin([this._rtcClient.getCurrentId()]),this._stateMachine.getState()!==T.END?[3,6]:[4,this._rtcClient.leaveRoom(o)]);case 5:return u.sent(),this._room=null,[2,{code:C.SUCCESS}];case 6:return i.length<1&&(this.joinRoomTimer=new re((function(){c._exceptionClose(I.REMOTE_NETWORK_ERROR)}),6e4)),this._room=o,[3,8];case 7:return s=u.sent(),this._exceptionClose(I.NETWORK_ERROR),this._logger.error("_","[RCCallSession _joinRoom] _rtcClient.joinRTCRoom throw exception roomId -> ".concat(e)),console.error(s),[2,{code:C.JOIN_ROOM_ERROR}];case 8:this._registerRoomEventListener(),this._registerReportListener(),u.label=9;case 9:return u.trys.push([9,11,,12]),[4,this._subscribeInRoomRemoteTrack()];case 10:return u.sent(),[3,12];case 11:return a=u.sent(),this._exceptionClose(I.SUBSCRIBE_ERROR),this._logger.error("_","[RCCallSession _joinRoom] _subscribeInRoomRemoteTrack Exception roomId -> ".concat(e)),console.error(a),[2,{code:C.JOIN_ROOM_ERROR}];case 12:return u.trys.push([12,14,,15]),[4,this._publish()];case 13:return u.sent(),[3,15];case 14:return l=u.sent(),this._exceptionClose(I.PUBLISH_ERROR),this._logger.error("_","[RCCallSession _joinRoom] _publish Exception roomId -> ".concat(e)),console.error(l),[2,{code:C.JOIN_ROOM_ERROR}];case 15:return[2,{code:C.SUCCESS}]}}))}))}}),Object.defineProperty(e.prototype,"_subscribeInRoomRemoteTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return(e=this._room.getRemoteTracks()).length?[4,this._subscribeRetry(e,this._options.isAllowSubscribeRetry,this._RETRYCOUNT)]:[3,2];case 1:(t=n.sent().code)!==d.SUCCESS&&(this._exceptionClose(I.SUBSCRIBE_ERROR),this._logger.error("_","[RCCallSession _subscribeInRoomRemoteTrack] Resource subscription failed roomId -> ".concat(this._stateMachine.getCallId()," RTC code -> ").concat(t))),n.label=2;case 2:return[2]}}))}))}}),Object.defineProperty(e.prototype,"_subscribeRetry",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t,n){return void 0===t&&(t=!1),void 0===n&&(n=0),f(this,void 0,void 0,(function(){var r;return g(this,(function(i){switch(i.label){case 0:return[4,this._room.subscribe(e)];case 1:if((r=i.sent().code)!==d.SUCCESS){try{this._listener.onTrackSubscribeFail&&this._listener.onTrackSubscribeFail(r,this)}catch(e){this._logger.error("_","[RCCallSession] _listener.onTrackSubscribeFail exception"),console.error(e)}if(!t)return[2,{code:r}];if(n>0)return n--,[2,this._subscribeRetry(e,t,n)]}return[2,{code:r}]}}))}))}}),Object.defineProperty(e.prototype,"_publish",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return e=this._options.localTracks,[4,this._publishRetry(e,this._options.isAllowPublishRetry,this._RETRYCOUNT)];case 1:return(t=n.sent().code)!==d.SUCCESS?(this._exceptionClose(I.PUBLISH_ERROR),this._logger.info("_","[RCCallSession _publist] Resource publishing failed: roomId -> ".concat(this._stateMachine.getCallId()," RCRTCCode -> ").concat(t)),[2]):(this._options.produceType===x.CALLEE&&this._notifyTrackReady(e),[2])}}))}))}}),Object.defineProperty(e.prototype,"_publishRetry",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t,n){return void 0===t&&(t=!1),void 0===n&&(n=0),f(this,void 0,void 0,(function(){var r;return g(this,(function(i){switch(i.label){case 0:return[4,this._room.publish(e)];case 1:if((r=i.sent().code)!==d.SUCCESS){try{this._listener.onTrackPublishFail&&this._listener.onTrackPublishFail(r,this)}catch(e){this._logger.error("_","[RCCallSession] _listener.onTrackPublishFail exception"),console.error(e)}if(!t)return[2,{code:r}];if(n>0)return n--,[2,this._publishRetry(e,t,n)]}return[2,{code:r}]}}))}))}}),Object.defineProperty(e.prototype,"_leaveRoom",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,n;return g(this,(function(r){switch(r.label){case 0:return r.trys.push([0,2,3,4]),[4,this._rtcClient.leaveRoom(this._room)];case 1:return e=r.sent(),this._logger.info("_","[RCCallSession _leaveRoom] Successfully exited the room code: ".concat(e.code)),[3,4];case 2:return t=r.sent(),this._logger.error("_","[RCCallSession _leaveRoom] leaveRoom throw exception"),console.error(t),[3,4];case 3:return n=this._stateMachine.getSummary(),Y.emit("sessionClose",{session:this,summaryInfo:n}),[7];case 4:return[2]}}))}))}}),Object.defineProperty(e.prototype,"_exceptionClose",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._options.localTracks&&this._destroyTracks(this._options.localTracks),this._stateMachine.close(e)}}),Object.defineProperty(e.prototype,"registerSessionListener",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=z(e);if(!t.result)throw new Error("[RCCallSession registerSessionListener] ".concat(t.msg));this._listener=h({},e)}}),Object.defineProperty(e.prototype,"_getLocalTrackCore",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a;return g(this,(function(l){switch(l.label){case 0:return e!==w.AUDIO?[3,2]:[4,this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC",t&&t.audio&&h({},t.audio))];case 1:return n=l.sent(),r=n.code,i=n.track,r!==d.SUCCESS?(this._logger.error("_","[RCCallSession _getLocalTrackCore] get Audio local tracks failed RCT code -> ".concat(r)),[2,{code:C.GET_LOCAL_AUDIO_TRACK_ERROR}]):(this._logger.info("_","[RCCallSession _getLocalTrackCore] successfully get Audio local tracks"),[2,{code:C.SUCCESS,tracks:[i]}]);case 2:return[4,this._rtcClient.createMicrophoneAndCameraTracks("RongCloudRTC",t&&h({},t))];case 3:return o=l.sent(),s=o.code,a=o.tracks,s!==d.SUCCESS?(this._logger.error("_","[RCCallSession _getLocalTrackCore] get Audio and Video local tracks failed RCT code -> ".concat(s)),[2,{code:C.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR}]):(this._logger.info("_","[RCCallSession _getLocalTrackCore] successfully get audio and video local tracks"),[2,{code:C.SUCCESS,tracks:a}])}}))}))}}),Object.defineProperty(e.prototype,"_getLocalTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a,l,c,u;return g(this,(function(d){switch(d.label){case 0:return this._options.isAllowDemotionGetStream&&e===w.AUDIO_VIDEO?[4,this._getLocalTrackCore(w.AUDIO_VIDEO,t)]:[3,4];case 1:return n=d.sent(),r=n.code,i=n.tracks,r===C.SUCCESS?[3,3]:[4,this._getLocalTrackCore(w.AUDIO,t)];case 2:return o=d.sent(),s=o.code,a=o.tracks,s!==C.SUCCESS?(this._exceptionClose(I.GET_MEDIA_RESOURCES_ERROR),[2,{code:s}]):[2,{code:s,tracks:a}];case 3:return[2,{code:r,tracks:i}];case 4:return[4,this._getLocalTrackCore(e,t)];case 5:return l=d.sent(),c=l.code,u=l.tracks,c!==C.SUCCESS?(this._exceptionClose(I.GET_MEDIA_RESOURCES_ERROR),[2,{code:c}]):[2,{code:c,tracks:u}]}}))}))}}),Object.defineProperty(e.prototype,"changeAudioDevice",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t,n,r,i,o;return g(this,(function(s){switch(s.label){case 0:return t=[],n=[],[4,this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC",e)];case 1:return r=s.sent(),i=r.code,o=r.track,i!==d.SUCCESS?(this._logger.error("_","[RCCallSession changeDevice] get local Audio tracks failed RCTLib code -> ".concat(i)),[2,{code:C.GET_LOCAL_AUDIO_TRACK_ERROR}]):(this._options.localTracks&&this._options.localTracks.forEach((function(e){e.isAudioTrack()||n.push(e)})),t.push(o),n.push(o),this._options.localTracks=n,this._notifyTrackReady(t),this._room?[4,this._room.publish(t)]:[3,3]);case 2:if(s.sent().code!==d.SUCCESS)return[2,{code:C.AUDIO_PUBLISH_ERROR}];s.label=3;case 3:return[2,{code:C.SUCCESS}]}}))}))}}),Object.defineProperty(e.prototype,"invite",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return void 0===t&&(t={}),f(this,void 0,void 0,(function(){var n,r,i,o,s,a,l,c;return g(this,(function(u){switch(u.label){case 0:if(n=t.extra,r=void 0===n?"":n,i=this._options.callPushConfig?this._options.callPushConfig:t.pushConfig,o=[te(e),Z(r)],i&&(s=Q(i),a=s.code,l=s.errorMsg,a!==C.SUCCESS))return this._logger.error("_","[RCCallSession invite] param error, errorMsg: ".concat(l)),[2,{code:a}];if(c=[],!o.every((function(e){return!e.result&&c.push(e.msg),e.result})))throw new Error("[RCCallClient invite] ".concat(c.join("\n")));return[4,this._stateMachine.invite(e,{extra:r,pushConfig:i})];case 1:return[2,{code:u.sent().code}]}}))}))}}),Object.defineProperty(e.prototype,"accept",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t,n,r,i,o,s;return g(this,(function(a){switch(a.label){case 0:if(!(t=ne(e)).result)throw new Error("[RCCallSession accept] ".concat(t.msg));return Y.emit("hungupOtherSession",{session:this}),n=this._stateMachine.getMediaType(),[4,this._getLocalTrack(n,e)];case 1:return r=a.sent(),i=r.code,o=r.tracks,i!==C.SUCCESS?[2,{code:i}]:(this._options.localTracks=o,[4,this._stateMachine.accept()]);case 2:return(s=a.sent().code)!==C.SUCCESS?(this._logger.error("_","[RCCallSession accept]Send accept message failed -> code: ".concat(s)),[2,{code:s}]):[2,{code:s}]}}))}))}}),Object.defineProperty(e.prototype,"hungup",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){return g(this,(function(e){return[2,this._stateMachine.hungup()]}))}))}}),Object.defineProperty(e.prototype,"_changeMediaType",{enumerable:!1,configurable:!0,writable:!0,value:function(e){return f(this,void 0,void 0,(function(){var t;return g(this,(function(n){switch(n.label){case 0:return[4,this._stateMachine.changeMediaType(e)];case 1:return(t=n.sent().code)!==C.SUCCESS&&this._logger.error("_","[RCCallSession _changeMediaType] change media type fail code-> ".concat(t)),[2,{code:t}]}}))}))}}),Object.defineProperty(e.prototype,"_getLocalVideoTracks",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=[];return this._room?(this._options.localTracks&&(e=this._options.localTracks.filter((function(e){return e.isVideoTrack()}))),e):e}}),Object.defineProperty(e.prototype,"_getLocalAudioTracks",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=[];return this._room?(this._options.localTracks&&(e=this._options.localTracks.filter((function(e){return e.isAudioTrack()}))),e):e}}),Object.defineProperty(e.prototype,"_setMediaTypeToAudioAndVideo",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,n;return g(this,(function(r){switch(r.label){case 0:return[4,this._rtcClient.createCameraVideoTrack()];case 1:return e=r.sent(),t=e.code,n=e.track,t!==d.SUCCESS?[2,{code:C.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR}]:[4,this._room.publish([n])];case 2:return r.sent().code!==d.SUCCESS?(this._logger.error("_","[RCCallSession _enableVideo] Resource publishing failed: RCRTCCode -> ".concat(t)),[2]):(this._notifyTrackReady([n]),this._changeMediaType(w.AUDIO_VIDEO),[2])}}))}))}}),Object.defineProperty(e.prototype,"_setMediaTypeToAudio",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return(e=this._getLocalVideoTracks()).length?(e.forEach((function(e){e.mute()})),[4,this._room.unpublish(e)]):[3,2];case 1:(t=n.sent().code)!==d.SUCCESS&&this._logger.error("_","[RCCallSession disableVideo] unpublish failed -> ".concat(t)),this._destroyTracks(e),n.label=2;case 2:return[2]}}))}))}}),Object.defineProperty(e.prototype,"descendAbility",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e;return g(this,(function(t){switch(t.label){case 0:return[4,this._changeMediaType(w.AUDIO)];case 1:return(e=t.sent().code)===C.SUCCESS&&this._setMediaTypeToAudio(),[2,{code:e}]}}))}))}}),Object.defineProperty(e.prototype,"disableVideoTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return this._room?(e=this._getLocalVideoTracks()).length?(e.forEach((function(e){e.mute()})),this._options.isOffCameraWhenVideoDisable?[4,this._room.unpublish(e)]:[2,{code:C.SUCCESS}]):(this._logger.error("_","[RCCallSession disableVideoTrack] Room missing video track -> ".concat(C.MISSING_VIDEO_TRACK_ERROR)),[2,{code:C.MISSING_VIDEO_TRACK_ERROR}]):(this._logger.error("_","[RCCallSession disableVideoTrack] Not in room"),[2,{code:C.NOT_IN_ROOM_ERROR}]);case 1:return(t=n.sent().code)!==d.SUCCESS?(this._logger.error("_","[RCCallSession disableVideo] unpublish failed -> ".concat(t)),[2,{code:C.UNPUBLISH_VIDEO_ERROR}]):(e.forEach((function(e){e.destroy()})),[2,{code:C.SUCCESS}])}}))}))}}),Object.defineProperty(e.prototype,"enableVideoTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,n,r,i;return g(this,(function(o){switch(o.label){case 0:return this._room?this._options.isOffCameraWhenVideoDisable?[4,this._rtcClient.createCameraVideoTrack()]:(e=this._getLocalVideoTracks()).length?(e.forEach((function(e){e.unmute()})),[2,{code:C.SUCCESS}]):(this._logger.error("_","[RCCallSession enableVideoTrack] Room missing video track -> ".concat(C.MISSING_VIDEO_TRACK_ERROR)),[2,{code:C.MISSING_VIDEO_TRACK_ERROR}]):(this._logger.error("_","[RCCallSession enableVideoTrack] Not in room -> ".concat(C.NOT_IN_ROOM_ERROR)),[2,{code:C.NOT_IN_ROOM_ERROR}]);case 1:return t=o.sent(),n=t.code,r=t.track,n!==d.SUCCESS?(this._logger.error("_","[RCCallSession EnableVideoTrack] Get Resource failed: RCRTCCode -> ".concat(n)),[2,{code:C.GET_LOCAL_VIDEO_TRACK_ERROR}]):(i=[],this._options.localTracks&&this._options.localTracks.forEach((function(e){e.isVideoTrack()?e.destroy():i.push(e)})),i.push(r),this._options.localTracks=i,r.mute(),[4,this._room.publish([r])]);case 2:return o.sent().code!==d.SUCCESS?(this._logger.error("_","[RCCallSession EnableVideoTrack] Resource publishing failed: RCRTCCode -> ".concat(n)),[2,{code:C.VIDEO_PUBLISH_ERROR}]):(r.unmute(),this._notifyTrackReady([r]),[2,{code:C.SUCCESS}])}}))}))}}),Object.defineProperty(e.prototype,"disableAudioTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return this._room?(e=this._getLocalAudioTracks()[0])?[4,e.mute()]:(this._logger.warn("_","[RCCallSession disableAudioTrack] Room missing audio track -> ".concat(C.MISSING_AUDIO_TRACK_ERROR)),[2,{code:C.MISSING_AUDIO_TRACK_ERROR}]):(this._logger.warn("_","[RCCallSession disableAudioTrack] Not in room -> ".concat(C.NOT_IN_ROOM_ERROR)),[2,{code:C.NOT_IN_ROOM_ERROR}]);case 1:return(t=n.sent())!==d.SUCCESS&&this._logger.warn("_","[RCCallSession disableAudioTrack] mute failed -> ".concat(t)),[2,{code:t}]}}))}))}}),Object.defineProperty(e.prototype,"enableAudioTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t;return g(this,(function(n){switch(n.label){case 0:return this._room?(e=this._getLocalAudioTracks()[0])?[4,e.unmute()]:(this._logger.error("_","[RCCallSession enableAudioTrack] Room missing audio track -> ".concat(C.MISSING_AUDIO_TRACK_ERROR)),[2,{code:C.MISSING_VIDEO_TRACK_ERROR}]):(this._logger.error("_","[RCCallSession enableAudioTrack] Not in room -> ".concat(C.NOT_IN_ROOM_ERROR)),[2,{code:C.NOT_IN_ROOM_ERROR}]);case 1:return(t=n.sent())!==d.SUCCESS&&this._logger.error("_","[RCCallSession enableAudioTrack] unmute failed -> ".concat(t)),[2,{code:t}]}}))}))}}),Object.defineProperty(e.prototype,"_destroyTracks",{enumerable:!1,configurable:!0,writable:!0,value:function(e){e.forEach((function(e){e.destroy()}))}}),Object.defineProperty(e.prototype,"_notifyTrackReady",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this;e.forEach((function(e){try{t._listener.onTrackReady(e,t)}catch(e){t._logger.error("_","[RCCallSession _notifyTrackReady] _listener onTrackReady exception"),console.error(e)}}))}}),Object.defineProperty(e.prototype,"_registerRoomEventListener",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;this._room.registerRoomEventListener({onKickOff:function(t,n){var r=e._rtcClient.getCurrentId();e._stateMachine.userLeave([r]),t?(n===u.SERVER_KICK&&e._exceptionClose(I.KICKED_BY_SERVER),n===u.OTHER_KICK&&e._exceptionClose(I.OTHER_CLIENT_JOINED_CALL)):e._exceptionClose(I.NETWORK_ERROR)},onMessageReceive:function(e,t,n,r){},onRoomAttributeChange:function(e,t){},onAudioMuteChange:function(t){e._logger.info("_","[RCCallSession onAudioMuteChange] userId->".concat(t.getUserId()," muted -> ").concat(t.isOwnerMuted()));var n={userId:t.getUserId(),muted:t.isOwnerMuted(),kind:"audio",trackId:t.getTrackId()};try{e._listener.onAudioMuteChange(n,e)}catch(t){e._logger.error("_","[RCCallSession onAudioMuteChange] Missing listening method -> onAudioMuteChange"),console.error(t)}},onVideoMuteChange:function(t){e._logger.info("_","[RCCallSession onVideoMuteChange]userId->".concat(t.getUserId()," muted -> ").concat(t.isOwnerMuted()));var n={userId:t.getUserId(),muted:t.isOwnerMuted(),kind:"video",trackId:t.getTrackId()};try{e._listener.onVideoMuteChange(n,e)}catch(t){e._logger.error("_","[RCCallSession onVideoMuteChange] Missing listening method -> onVideoMuteChange"),console.error(t)}},onTrackPublish:function(t){return f(e,void 0,void 0,(function(){var e;return g(this,(function(n){switch(n.label){case 0:return this._room?[4,this._room.subscribe(t)]:[3,2];case 1:(e=n.sent().code)!==d.SUCCESS&&this._logger.error("_","[RCCallSession onTrackPublish] subscribe failed RTCCode ->".concat(e)),n.label=2;case 2:return[2]}}))}))},onTrackUnpublish:function(e){},onTrackReady:function(t){e._stateMachine.getMediaType()===w.AUDIO&&t.isVideoTrack()||e._notifyTrackReady([t])},onUserJoin:function(t){e.joinRoomTimer&&e.joinRoomTimer.stop(),e._stateMachine.userJoin(t)},onUserLeave:function(t){e._logger.info("_","[RCCallSession onUserLeave] listening onUserLeave userIds -> ".concat(null==t?void 0:t.join(","))),e._stateMachine.userLeave(t)},onPing:function(t){e._logger.info("_","[RCCallSession onPing]".concat(t));try{e._listener.onPing&&e._listener.onPing(t,e)}catch(t){e._logger.error("_","[RCCallSession onPing] listening onPing exception"),console.error(t)}}})}}),Object.defineProperty(e.prototype,"_registerReportListener",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;this._room.registerReportListener({onStateReport:function(t){try{e._listener.onRTCStateReport&&e._listener.onRTCStateReport(t,e)}catch(t){e._logger.error("_","[RCCallSession onStateReport] listener onStateReport exception"),console.error(t)}},onICEConnectionStateChange:function(t){var n,r;try{null===(r=null===(n=e._listener)||void 0===n?void 0:n.onICEConnectionStateChange)||void 0===r||r.call(n,t,e)}catch(t){e._logger.error("_","[RCCallSession onICEConnectionStateChange] onICEConnectionStateChange exception"),console.error(t)}}})}}),Object.defineProperty(e.prototype,"getSessionId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getCallId()}}),Object.defineProperty(e.prototype,"getRTCSessionId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._room?this._room.getSessionId():null}}),Object.defineProperty(e.prototype,"getTargetId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getTargetId()}}),Object.defineProperty(e.prototype,"getConversationType",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getConversationType()}}),Object.defineProperty(e.prototype,"getChannelId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getChannelId()}}),Object.defineProperty(e.prototype,"getRemoteUsers",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getRemoteUsers()}}),Object.defineProperty(e.prototype,"getUsers",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getRemoteUsers()}}),Object.defineProperty(e.prototype,"getUserState",{enumerable:!1,configurable:!0,writable:!0,value:function(e){if(!e||"string"!=typeof e)throw new Error("userId is required, must be of type 'string'");return this._stateMachine.getUserState(e)}}),Object.defineProperty(e.prototype,"getState",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getState()}}),Object.defineProperty(e.prototype,"getCallerId",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getCallerId()}}),Object.defineProperty(e.prototype,"getMediaType",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._stateMachine.getMediaType()}}),e}(),oe=function(){function e(e,t,n,r){var i=this;Object.defineProperty(this,"_context",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"_runtime",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"_logger",{enumerable:!0,configurable:!0,writable:!0,value:n}),Object.defineProperty(this,"_rtcClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_callEngine",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_options",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_sessionList",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_callPushConfig",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_hungupPushConfig",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._rtcClient=r.rtcClient,this._options=h({isAllowPublishRetry:!1,isAllowSubscribeRetry:!1,isOffCameraWhenVideoDisable:!0,joinType:s.COEXIST,isAllowDemotionGetStream:!1,lang:D.ZH},r),this._callEngine=new W(this._context,t,this._logger,{onInvite:this._onInvite.bind(this),onOfflineRecord:this._onOfflineRecord.bind(this)},{lang:this._options.lang||D.ZH}),Y.on("sessionClose",(function(e){var t=e.session,n=e.summaryInfo;i._removeSession(t);try{i._options.onSessionClose(t,n)}catch(e){i._logger.error("_","[RCCCallClient] options.onSessionClose exception"),console.log(e)}})),Y.on("hungupOtherSession",(function(e){var t=e.session.getSessionId();i._logger.info("_","[RCCallClient hungupOtherSession] sessionId ready to accept -> ".concat(t)),i._logger.info("_","[RCCallClient hungupOtherSession] sessionList ->".concat(i._sessionList.map((function(e){return e.getSessionId()})).join(",")));for(var n=0;i._sessionList.length>1;)i._sessionList[n].getSessionId()!==t?(i._sessionList[n].hungup(),i._sessionList.splice(n,1)):n++;i._logger.info("_","[RCCallClient hungupOtherSession] current sessionList length ->".concat(i._sessionList.length))}))}return Object.defineProperty(e.prototype,"_onInvite",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){this._logger.info("_","[RCCallClient _onInvite] Received invite message");var n=new ie(e,this._rtcClient,this._logger,{isAllowSubscribeRetry:this._options.isAllowSubscribeRetry,isAllowPublishRetry:this._options.isAllowPublishRetry,isOffCameraWhenVideoDisable:this._options.isOffCameraWhenVideoDisable,joinType:this._options.joinType,isAllowDemotionGetStream:this._options.isAllowDemotionGetStream,produceType:x.CALLEE,callPushConfig:this._callPushConfig,hungupPushConfig:this._hungupPushConfig});this._logger.info("_","[RCCallClient _onInvite] Received invite message, successfully created session"),this._sessionList.push(n);try{this._options.onSession(n,t)}catch(e){this._logger.error("_","[RCCallClient _options.onSession] onSession exception"),console.log(e)}if(!n._listener)throw this._logger.error("_","[RCCallClient _options.onSession] session Must Have Listener"),new Error("[RCCallSession _options.onSession] session Must Have Listener");var r=z(n._listener);if(!r.result)throw new Error(r.msg)}}),Object.defineProperty(e.prototype,"_onOfflineRecord",{enumerable:!1,configurable:!0,writable:!0,value:function(e){try{this._options.onOfflineRecord&&this._options.onOfflineRecord(e)}catch(e){this._logger.error("_","[RCCallClient _options.onOfflineRecord] onOfflineRecord exception"),console.log(e)}}}),Object.defineProperty(e.prototype,"registerUserInfo",{enumerable:!1,configurable:!0,writable:!0,value:function(e){void 0===e&&(e={}),this._callEngine.registerUserInfo(e),this._logger.info("_","[RCCallClient registerUserInfo] successfully register user info data")}}),Object.defineProperty(e.prototype,"startCrossCall",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.targetId,n=e.mediaType,r=void 0===n?w.AUDIO:n,i=e.listener,o=e.constraints,s=e.channelId,a=void 0===s?"":s,l=e.extra,c=void 0===l?"":l,u=e.pushTitle,d=void 0===u?"":u,_=e.pushContent,h=void 0===_?"":_,p=e.bitrate;return f(this,void 0,void 0,(function(){return g(this,(function(e){return[2,this.__call({targetId:t,mediaType:r,listener:i,constraints:o,channelId:a,extra:c,pushTitle:d,pushContent:h,bitrate:p,isCrossAppkey:!0})]}))}))}}),Object.defineProperty(e.prototype,"call",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.targetId,n=e.mediaType,r=void 0===n?w.AUDIO:n,i=e.listener,o=e.constraints,s=e.channelId,a=void 0===s?"":s,l=e.extra,c=void 0===l?"":l,u=e.pushTitle,d=void 0===u?"":u,_=e.pushContent,h=void 0===_?"":_,p=e.bitrate;return f(this,void 0,void 0,(function(){return g(this,(function(e){return[2,this.__call({targetId:t,mediaType:r,listener:i,constraints:o,channelId:a,extra:c,pushTitle:d,pushContent:h,bitrate:p})]}))}))}}),Object.defineProperty(e.prototype,"__call",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.targetId,n=e.mediaType,r=void 0===n?w.AUDIO:n,i=e.listener,o=e.constraints,s=e.channelId,a=void 0===s?"":s,l=e.extra,c=void 0===l?"":l,u=e.pushTitle,d=void 0===u?"":u,_=e.pushContent,h=void 0===_?"":_,p=e.bitrate,b=e.isCrossAppkey,R=void 0!==b&&b;return f(this,void 0,void 0,(function(){var e,n,s,l,u,_,f,b,I,m,y,E,v,O;return g(this,(function(g){switch(g.label){case 0:if(e=this._callPushConfig?this._callPushConfig:{pushTitle:d,pushContent:h},this._logger.info("_","[RCCallClient call] extra->".concat(c," pushConfig->").concat(JSON.stringify(e))),n=[q(t),X(r),z(i),Z(c)],s=[],!n.every((function(e){return!e.result&&s.push(e.msg),e.result})))throw new Error("[RCCallClient call] ".concat(s.join("\n")));return l=Q(e),u=l.code,_=l.errorMsg,u!==C.SUCCESS?(this._logger.error("_","[RCCallClient call] param error, errorMsg: ".concat(_)),[2,{code:u}]):(f=[],[4,this._getLocalTrack(r,o)]);case 1:return b=g.sent(),I=b.code,m=b.tracks,I!==C.SUCCESS?[2,{code:I}]:((f=m).forEach((function(e){var t,n,r;e.isAudioTrack()&&(null==p?void 0:p.audio)&&e.setBitrate(null==p?void 0:p.audio),e.isVideoTrack()&&(null==p?void 0:p.video)&&e.setBitrate(null===(t=null==p?void 0:p.video)||void 0===t?void 0:t.max,null===(n=null==p?void 0:p.video)||void 0===n?void 0:n.min,null===(r=null==p?void 0:p.video)||void 0===r?void 0:r.start),i.onTrackReady(e)})),[4,this._callEngine.call(a,t,r,c,e,R)]);case 2:return y=g.sent(),E=y.code,v=y.stateMachine,E===C.SUCCESS&&v?(this._logger.info("_","[RCCallClient call] successfully created state machine"),(O=new ie(v,this._rtcClient,this._logger,{localTracks:f,isAllowSubscribeRetry:this._options.isAllowSubscribeRetry,isAllowPublishRetry:this._options.isAllowPublishRetry,isOffCameraWhenVideoDisable:this._options.isOffCameraWhenVideoDisable,joinType:this._options.joinType,isAllowDemotionGetStream:this._options.isAllowDemotionGetStream,produceType:x.CALLER,isCrossAppkey:R,callPushConfig:this._callPushConfig,hungupPushConfig:this._hungupPushConfig})).registerSessionListener(i),this._sessionList.push(O),this._logger.info("_","[RCCallClient call] successfully created session object, sessionId: ".concat(O.getSessionId())),[2,{code:E,session:O}]):(this._logger.error("_","[RCCallClient call] call failed code ->: ".concat(E)),f.forEach((function(e){e.mute(),e.destroy()})),[2,{code:E}])}}))}))}}),Object.defineProperty(e.prototype,"callInGroup",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.targetId,n=e.userIds,r=e.mediaType,i=void 0===r?w.AUDIO:r,o=e.listener,s=e.constraints,a=e.channelId,l=void 0===a?"":a,c=e.extra,u=void 0===c?"":c,d=e.pushTitle,_=void 0===d?"":d,h=e.pushContent,p=void 0===h?"":h,b=e.bitrate;return f(this,void 0,void 0,(function(){var e,r,a,c,d,h,f,R,I,m,y,E,v,O;return g(this,(function(g){switch(g.label){case 0:if(e=this._callPushConfig?this._callPushConfig:{pushTitle:_,pushContent:p},r=[q(t),te(n),X(i),z(o),Z(u)],a=[],!r.every((function(e){return!e.result&&a.push(e.msg),e.result})))throw new Error("[RCCallClient callInGroup] ".concat(a.join("\n")));return c=Q(e),d=c.code,h=c.errorMsg,d!==C.SUCCESS?(this._logger.error("_","[RCCallClient call] param error, errorMsg: ".concat(h)),[2,{code:d}]):(f=[],[4,this._getLocalTrack(i,s)]);case 1:return R=g.sent(),I=R.code,m=R.tracks,I!==C.SUCCESS?[2,{code:I}]:((f=m).forEach((function(e){var t,n,r;e.isAudioTrack()&&(null==b?void 0:b.audio)&&e.setBitrate(null==b?void 0:b.audio),e.isVideoTrack()&&(null==b?void 0:b.video)&&e.setBitrate(null===(t=null==b?void 0:b.video)||void 0===t?void 0:t.max,null===(n=null==b?void 0:b.video)||void 0===n?void 0:n.min,null===(r=null==b?void 0:b.video)||void 0===r?void 0:r.start),o.onTrackReady(e)})),[4,this._callEngine.callInGroup(l,t,i,n,u,e)]);case 2:return y=g.sent(),E=y.code,v=y.stateMachine,E===C.SUCCESS&&v?(this._logger.info("_","[RCCallClient callInGroup] successfully created state machine"),(O=new ie(v,this._rtcClient,this._logger,{localTracks:f,isAllowSubscribeRetry:this._options.isAllowSubscribeRetry,isAllowPublishRetry:this._options.isAllowPublishRetry,isOffCameraWhenVideoDisable:this._options.isOffCameraWhenVideoDisable,joinType:this._options.joinType,isAllowDemotionGetStream:this._options.isAllowDemotionGetStream,produceType:x.CALLER,callPushConfig:this._callPushConfig,hungupPushConfig:this._hungupPushConfig})).registerSessionListener(o),this._sessionList.push(O),this._logger.info("_","[RCCallClient callInGroup] successfully created session object, sessionId: ".concat(O.getSessionId())),[2,{code:E,session:O}]):(this._logger.info("_","[RCCallClient callInGroup] callInGroup failed code -> ".concat(E)),f.forEach((function(e){e.mute(),e.destroy()})),[2,{code:E}])}}))}))}}),Object.defineProperty(e.prototype,"_getLocalTrackCore",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a;return g(this,(function(l){switch(l.label){case 0:return e!==w.AUDIO?[3,2]:[4,this._rtcClient.createMicrophoneAudioTrack("RongCloudRTC",t&&t.audio&&h({},t.audio))];case 1:return n=l.sent(),r=n.code,i=n.track,r!==d.SUCCESS?(this._logger.error("_","[RCCallClient _getTrack] get Audio local tracks failed RCT code -> ".concat(r)),[2,{code:C.GET_LOCAL_AUDIO_TRACK_ERROR}]):(this._logger.info("_","[RCCallClient _getTrack] successfully get Audio local tracks"),[2,{code:C.SUCCESS,tracks:[i]}]);case 2:return[4,this._rtcClient.createMicrophoneAndCameraTracks("RongCloudRTC",t&&h({},t))];case 3:return o=l.sent(),s=o.code,a=o.tracks,s!==d.SUCCESS?(this._logger.error("_","[RCCallClient _getTrack] get Audio and Video local tracks failed RCT code -> ".concat(s)),[2,{code:C.GET_LOCAL_AUDIO_AND_VIDEO_TRACK_ERROR}]):(this._logger.info("_","[RCCallClient _getTrack] successfully get audio and video local tracks"),[2,{code:C.SUCCESS,tracks:a}])}}))}))}}),Object.defineProperty(e.prototype,"_getLocalTrack",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){return f(this,void 0,void 0,(function(){var n,r,i,o,s,a,l,c,u;return g(this,(function(d){switch(d.label){case 0:return this._options.isAllowDemotionGetStream&&e===w.AUDIO_VIDEO?[4,this._getLocalTrackCore(w.AUDIO_VIDEO,t)]:[3,4];case 1:return n=d.sent(),r=n.code,i=n.tracks,r===C.SUCCESS?[3,3]:[4,this._getLocalTrackCore(w.AUDIO,t)];case 2:return o=d.sent(),s=o.code,a=o.tracks,s!==C.SUCCESS?[2,{code:s}]:[2,{code:s,tracks:a}];case 3:return[2,{code:r,tracks:i}];case 4:return[4,this._getLocalTrackCore(e,t)];case 5:return l=d.sent(),c=l.code,u=l.tracks,c!==C.SUCCESS?[2,{code:c}]:[2,{code:c,tracks:u}]}}))}))}}),Object.defineProperty(e.prototype,"_removeSession",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=e.getSessionId();this._sessionList=this._sessionList.filter((function(e){return e.getSessionId()!==t}))}}),Object.defineProperty(e.prototype,"getJoinedRoomInfo",{enumerable:!1,configurable:!0,writable:!0,value:function(){return f(this,void 0,void 0,(function(){var e,t,r;return g(this,(function(i){switch(i.label){case 0:return[4,this._context.getRTCJoinedUserInfo(this._context.getCurrentId())];case 1:return e=i.sent(),t=e.code,r=e.data,t!==n.SUCCESS?(this._logger.error("_","getJoinedUserInfo error code: ".concat(t)),[2,{code:C.QUERY_JOINED_USER_INFO_ERROR}]):[2,{code:C.SUCCESS,data:r}]}}))}))}}),Object.defineProperty(e.prototype,"setPushConfig",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){for(var n=0,r=[e,t].map((function(e){return Q(e)}));n<r.length;n++){var i=r[n],o=i.code,s=i.errorMsg;if(o!==C.SUCCESS)return this._logger.error("_","[RCCallClient setPushConfig] param error, errorMsg: ".concat(s)),{code:o}}this._callPushConfig=e,this._hungupPushConfig=t}}),e}();l.add("plugin-call","5.2.6");var se={tag:"RCCall",verify:function(e){return"browser"===e.tag},setup:function(e,t,n){var r=F(n);if(!r.result)throw new Error("[RCCallLib installer steup]".concat(r.msg));if(!l.validEngine("5.9.0"))throw new Error("The current engine version '".concat(l.getInfo().engine,"' error, plugin-call required engine version at least '").concat("5.9.0","'."));var i=e.createLogger("RCCall","RTC");return n.logOutputLevel&&i.setOutputLevel(n.logOutputLevel),void 0!==n.logLevel&&i.warn("_","The 'logLevel' parameter is deprecated, please use 'logOutputLevel' instead."),i.warn("_","RCCall Version: ".concat("5.2.6",", Commit: ").concat("6761942c405d068867e89ca6c16d888599154bde")),new oe(e,t,i,n)}};export{oe as RCCallClient,I as RCCallEndReason,C as RCCallErrorCode,D as RCCallLanguage,w as RCCallMediaType,ie as RCCallSession,T as RCCallSessionState,S as RCCallUserState,se as installer};
|