@cartanova/qgrid-cli 2.3.1 → 2.3.3
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/bundle/dist/application/qgrid/qgrid.dispatcher.js +94 -277
- package/bundle/dist/application/qgrid/qgrid.frame.js +15 -5
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +33 -12
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +39 -96
- package/bundle/dist/utils/providers/anthropic/claude-session.js +47 -32
- package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +3 -36
- package/bundle/dist/utils/providers/common/model-cost.js +3 -2
- package/bundle/dist/utils/providers/openai/codex-worker.js +1 -2
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +19 -12
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +262 -2
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +142 -373
- package/bundle/src/application/qgrid/qgrid.frame.ts +38 -23
- package/bundle/src/utils/providers/anthropic/anthropic-constants.test.ts +60 -0
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +57 -16
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.test.ts +92 -340
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +50 -185
- package/bundle/src/utils/providers/anthropic/claude-session.test.ts +71 -62
- package/bundle/src/utils/providers/anthropic/claude-session.ts +56 -46
- package/bundle/src/utils/providers/anthropic/stream-json-adapter.test.ts +19 -30
- package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +24 -101
- package/bundle/src/utils/providers/common/model-cost.test.ts +19 -1
- package/bundle/src/utils/providers/common/model-cost.ts +2 -1
- package/bundle/src/utils/providers/common/provider-dispatcher.ts +7 -4
- package/bundle/src/utils/providers/openai/codex-worker.ts +2 -8
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +18 -11
- package/package.json +1 -1
|
@@ -1,58 +1,42 @@
|
|
|
1
1
|
import "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { canonicalAnthropicModel } from "./anthropic-constants.js";
|
|
3
2
|
import { getExpiresAt, getRefreshToken } from "../common/credentials.js";
|
|
4
3
|
import { TokenModel } from "../../../application/token/token.model.js";
|
|
5
|
-
import {
|
|
4
|
+
import { assertSupportedOneMillionSuffix, canonicalAnthropicModel } from "./anthropic-constants.js";
|
|
5
|
+
import { makeAnthropicWorkerId, runClaudeSession } from "./claude-session.js";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
//#region src/utils/providers/anthropic/anthropic-dispatcher.ts
|
|
8
8
|
/**
|
|
9
|
-
* AnthropicDispatcher
|
|
9
|
+
* AnthropicDispatcher
|
|
10
10
|
*
|
|
11
|
-
* OpenAIDispatcher
|
|
12
|
-
*
|
|
11
|
+
* OpenAIDispatcher와 달리, worker pool을 두는 대신 요청별 fresh spawn
|
|
12
|
+
* 토큰은 인메모리(MAP)으로 관리하고 least-used, round-robin 으로 고른다
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* - **compat 는 threadCoord 로 왕복하지 않는다.** sessionCompat 는 이 dispatcher 인스턴스 메모리에만
|
|
20
|
-
* 산다(TTL sweep + 토큰 제거 시 정리). threadCoord.systemHash 는 상위 issueConvContext 가 따로
|
|
21
|
-
* 채우지만 Anthropic resume eligibility 판정에는 쓰이지 않는다.
|
|
22
|
-
* - **락 소유권**: claude session-id 직렬화는 U4 `runClaudeSession` 이 단독 소유한다.
|
|
23
|
-
* dispatcher 는 resume eligibility / token ownership 만 판정하고 `withSessionLock` 으로 감싸지 않는다.
|
|
24
|
-
* 여기서 다시 감싸면 U4 내부 락과 같은 session-id 로 재진입해 deadlock 이 난다.
|
|
25
|
-
* cold 첫 호출 경쟁을 따로 막지 않는 근거는 run() 의 락 주석 참조(IF/owner scope 의 순차 호출 전제).
|
|
26
|
-
* - 발급한 session-id 와 호환키를 GenerateResult.threadCoord(threadId=session-id, workerId=tokenId,
|
|
27
|
-
* epoch=0)로 올려, 상위(issueConvContext)가 클라에 회송할 좌표를 만든다.
|
|
14
|
+
* - 모든 요청은 fresh `--session-id` 로 실행
|
|
15
|
+
* - 멀티턴 문맥은 클라이언트가 매 호출 보내는 full history 를 평탄화해 전달한다.
|
|
16
|
+
* - 발급한 session-id 를 GenerateResult.threadCoord(threadId=session-id, workerId=tokenId,
|
|
17
|
+
* epoch=0)로 올려, 상위(issueConvContext)가 클라에 회송할 좌표를 만든다. 다음 turn 이 좌표를
|
|
18
|
+
* 회송해도 Anthropic 라우팅에는 쓰지 않는다.
|
|
28
19
|
*/
|
|
29
20
|
const logger = getLogger(["qgrid", "anthropic-dispatcher"]);
|
|
30
|
-
const DEFAULT_TIMEOUT_MS =
|
|
21
|
+
const DEFAULT_TIMEOUT_MS = 24e4;
|
|
31
22
|
const REFRESH_SAFETY_MS = 6e4;
|
|
32
|
-
const ANTHROPIC_PROVIDER = "anthropic";
|
|
33
|
-
const SESSION_COMPAT_TTL_MS = 600 * 1e3;
|
|
34
|
-
function isRetryableResumeFailure(error) {
|
|
35
|
-
const lower = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
36
|
-
if (lower.includes("timeout") || lower.includes("aborted") || lower.includes("spawn error") || lower.includes("quota") || lower.includes("you've hit") || lower.includes("unauthorized") || lower.includes("authentication") || lower.includes("invalid oauth") || lower.includes("permission denied") || lower.includes("max_turns") || lower.includes("max-turns") || lower.includes("schema") || lower.includes("model_error") || lower.includes("model error")) return false;
|
|
37
|
-
return lower.includes("closed without result") || /\b(resume|transcript)\b/.test(lower);
|
|
38
|
-
}
|
|
39
23
|
var AnthropicDispatcher = class {
|
|
40
24
|
tokenPool = /* @__PURE__ */ new Map();
|
|
41
25
|
requestCounts = /* @__PURE__ */ new Map();
|
|
42
26
|
rrIndex = 0;
|
|
43
|
-
sessionCompat = /* @__PURE__ */ new Map();
|
|
44
27
|
async start() {
|
|
45
28
|
const tokens = await TokenModel.findActiveByProvider("A", "anthropic");
|
|
46
|
-
for (const t of tokens)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
29
|
+
for (const t of tokens) {
|
|
30
|
+
this.tokenPool.set(t.id, {
|
|
31
|
+
id: t.id,
|
|
32
|
+
name: t.name,
|
|
33
|
+
credentials: t.credentials
|
|
34
|
+
});
|
|
35
|
+
logger.info(`worker spawned: ${t.name}`);
|
|
36
|
+
}
|
|
52
37
|
}
|
|
53
38
|
async stop() {
|
|
54
39
|
this.tokenPool.clear();
|
|
55
|
-
this.sessionCompat.clear();
|
|
56
40
|
this.requestCounts.clear();
|
|
57
41
|
this.rrIndex = 0;
|
|
58
42
|
}
|
|
@@ -74,8 +58,6 @@ var AnthropicDispatcher = class {
|
|
|
74
58
|
});
|
|
75
59
|
}
|
|
76
60
|
onTokenUpdated(id, name, credentials) {
|
|
77
|
-
const existing = this.tokenPool.get(id);
|
|
78
|
-
if (existing !== void 0 && existing.credentials.accountUuid !== credentials.accountUuid) this.clearSessionCompatFor(id);
|
|
79
61
|
this.tokenPool.set(id, {
|
|
80
62
|
id,
|
|
81
63
|
name,
|
|
@@ -85,10 +67,6 @@ var AnthropicDispatcher = class {
|
|
|
85
67
|
onTokenRemoved(id) {
|
|
86
68
|
this.tokenPool.delete(id);
|
|
87
69
|
this.requestCounts.delete(id);
|
|
88
|
-
this.clearSessionCompatFor(id);
|
|
89
|
-
}
|
|
90
|
-
clearSessionCompatFor(tokenId) {
|
|
91
|
-
for (const [sid, e] of this.sessionCompat) if (e.tokenId === tokenId) this.sessionCompat.delete(sid);
|
|
92
70
|
}
|
|
93
71
|
countOf(id) {
|
|
94
72
|
return this.requestCounts.get(id) ?? 0;
|
|
@@ -102,46 +80,27 @@ var AnthropicDispatcher = class {
|
|
|
102
80
|
this.rrIndex++;
|
|
103
81
|
return this.charge(picked);
|
|
104
82
|
}
|
|
105
|
-
pickToken(id) {
|
|
106
|
-
const token = this.tokenPool.get(id);
|
|
107
|
-
return token ? this.charge(token) : null;
|
|
108
|
-
}
|
|
109
83
|
charge(token) {
|
|
110
84
|
this.requestCounts.set(token.id, this.countOf(token.id) + 1);
|
|
111
85
|
return token;
|
|
112
86
|
}
|
|
113
|
-
sweepSessionCompat() {
|
|
114
|
-
const now = Date.now();
|
|
115
|
-
for (const [sid, e] of this.sessionCompat) if (now - e.lastUsedAt > SESSION_COMPAT_TTL_MS) this.sessionCompat.delete(sid);
|
|
116
|
-
}
|
|
117
87
|
async generate(req) {
|
|
118
88
|
return this.run(req, () => {});
|
|
119
89
|
}
|
|
120
90
|
async generateStream(req, cb) {
|
|
121
91
|
try {
|
|
122
|
-
const result = await this.run(req, cb.onDelta);
|
|
92
|
+
const result = await this.run(req, cb.onDelta, { includePartialMessages: true });
|
|
123
93
|
cb.onThreadId?.(result.threadCoord.threadId);
|
|
124
94
|
cb.onComplete(result);
|
|
125
95
|
} catch (e) {
|
|
126
96
|
cb.onError(e);
|
|
127
97
|
}
|
|
128
98
|
}
|
|
129
|
-
async run(req, onDelta) {
|
|
130
|
-
|
|
99
|
+
async run(req, onDelta, opts) {
|
|
100
|
+
assertSupportedOneMillionSuffix(req.model);
|
|
131
101
|
const model = canonicalAnthropicModel(req.model);
|
|
132
102
|
const jsonSchema = req.outputSchema !== void 0 ? JSON.stringify(req.outputSchema) : void 0;
|
|
133
|
-
const
|
|
134
|
-
system: req.systemPrompt,
|
|
135
|
-
model,
|
|
136
|
-
outputSchema: jsonSchema
|
|
137
|
-
});
|
|
138
|
-
const candidate = req.reuse?.threadId;
|
|
139
|
-
const stored = candidate !== void 0 ? this.sessionCompat.get(candidate) : void 0;
|
|
140
|
-
const ownerMatches = stored !== void 0 && stored.tokenId === req.reuse?.workerId;
|
|
141
|
-
const resumeToken = stored?.compat === compat && ownerMatches ? this.pickToken(stored.tokenId) : null;
|
|
142
|
-
const isResume = resumeToken !== null;
|
|
143
|
-
const resumeSessionId = isResume ? candidate : void 0;
|
|
144
|
-
const token = resumeToken ?? this.selectToken();
|
|
103
|
+
const token = this.selectToken();
|
|
145
104
|
if (!token) throw new Error("No anthropic tokens available");
|
|
146
105
|
const exec = async () => {
|
|
147
106
|
let accessToken = token.credentials.accessToken;
|
|
@@ -150,48 +109,32 @@ var AnthropicDispatcher = class {
|
|
|
150
109
|
const { QgridFrame } = await import("../../../application/qgrid/qgrid.frame.js");
|
|
151
110
|
accessToken = await QgridFrame.refreshToken({
|
|
152
111
|
id: token.id,
|
|
153
|
-
provider:
|
|
112
|
+
provider: "anthropic",
|
|
154
113
|
name: token.name,
|
|
155
114
|
credentials: token.credentials
|
|
156
115
|
});
|
|
157
116
|
} catch (e) {
|
|
158
117
|
logger.warn(`refresh failed for ${token.name}: ${e.message}`);
|
|
159
118
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}, onDelta);
|
|
175
|
-
};
|
|
176
|
-
let session;
|
|
177
|
-
try {
|
|
178
|
-
session = await runSession(isResume);
|
|
179
|
-
} catch (e) {
|
|
180
|
-
if (!isResume || !isRetryableResumeFailure(e)) throw e;
|
|
181
|
-
if (candidate) this.sessionCompat.delete(candidate);
|
|
182
|
-
logger.warn(`resume failed for ${token.name}; retrying cold once: ${e.message}`);
|
|
183
|
-
session = await runSession(false);
|
|
184
|
-
}
|
|
119
|
+
logger.info(`→ ${token.name} (model: ${model})`);
|
|
120
|
+
const session = await runClaudeSession({
|
|
121
|
+
tokenId: token.id,
|
|
122
|
+
token: accessToken,
|
|
123
|
+
model,
|
|
124
|
+
system: req.systemPrompt,
|
|
125
|
+
jsonSchema,
|
|
126
|
+
effort: req.effort,
|
|
127
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
128
|
+
coldHistory: req.coldHistory,
|
|
129
|
+
input: req.coldInput,
|
|
130
|
+
abortSignal: req.abortSignal,
|
|
131
|
+
includePartialMessages: opts?.includePartialMessages
|
|
132
|
+
}, onDelta);
|
|
185
133
|
if (session.quotaExhausted) throw new Error(`quota exhausted (${token.name})`);
|
|
186
134
|
if (session.isError) {
|
|
187
135
|
const detail = session.text || `empty text, outputTokens=${session.usage.outputTokens}`;
|
|
188
136
|
throw new Error(`claude error (${token.name}): ${detail}`);
|
|
189
137
|
}
|
|
190
|
-
this.sessionCompat.set(session.sessionId, {
|
|
191
|
-
compat,
|
|
192
|
-
tokenId: token.id,
|
|
193
|
-
lastUsedAt: Date.now()
|
|
194
|
-
});
|
|
195
138
|
return {
|
|
196
139
|
text: session.text,
|
|
197
140
|
tokenName: token.name,
|
|
@@ -212,4 +155,4 @@ var AnthropicDispatcher = class {
|
|
|
212
155
|
//#endregion
|
|
213
156
|
export { AnthropicDispatcher };
|
|
214
157
|
|
|
215
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW50aHJvcGljLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvYW50aHJvcGljLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBbnRocm9waWNEaXNwYXRjaGVyIOKAlCBDbGF1ZGUoQW50aHJvcGljKSBwcm92aWRlciDsnZggUHJvdmlkZXJEaXNwYXRjaGVyIOq1rO2YhC5cbiAqXG4gKiBPcGVuQUlEaXNwYXRjaGVyIO2MqO2EtOydhCDrr7jrn6zrp4HtlZjrkJgsIHdvcmtlciBwb29sIOuMgOyLoCDsmpTssq3rs4QgZnJlc2ggc3Bhd24oVTQgcnVuQ2xhdWRlU2Vzc2lvbinsnYRcbiAqIOyTtOuLpC4g7Yag7YGw7J2AIOyekOyytCDtkoAoTWFwKeuhnCDqtIDrpqztlZjqs6AgbGVhc3QtdXNlZCByb3VuZC1yb2JpbiDsnLzroZwg6rOg66W464ukLlxuICpcbiAqIOupgO2LsO2EtCAvIOuPmeyLnOyEsSDqs4Tslb06XG4gKiAgLSAqKmVsaWdpYmlsaXR5IOuKlCBjb21wYXRpYmlsaXR5S2V5KHN5c3RlbSttb2RlbCtzY2hlbWEpKiog66GcIO2MkOygle2VnOuLpC4gc3lzdGVtSGFzaCDqsIAg7JWE64uI64ukLlxuICogICAgR2VuZXJhdGVSZXF1ZXN0LnJldXNlIOqwgCDrk6TslrTsmKTrqbQg6re4IHRocmVhZElkKD1jbGF1ZGUgc2Vzc2lvbi1pZCnsl5Ag64yA7ZW0IGRpc3BhdGNoZXItbG9jYWxcbiAqICAgIGBzZXNzaW9uQ29tcGF0YCDsl5Ag7KCA7J6l7ZW0IOuRlCDtmLjtmZjtgqTsmYAg7J2067KIIOyalOyyrSDtmLjtmZjtgqTrpbwg67mE6rWQIOKAlCDsnbzsuZgg7IucIHJlc3VtZSwg67aI7J287LmYL+yXhuydjCDsi5xcbiAqICAgIGNvbGQo7IOIIHNlc3Npb24taWQpLlxuICogIC0gKipjb21wYXQg64qUIHRocmVhZENvb3JkIOuhnCDsmZXrs7XtlZjsp4Ag7JWK64qU64ukLioqIHNlc3Npb25Db21wYXQg64qUIOydtCBkaXNwYXRjaGVyIOyduOyKpO2EtOyKpCDrqZTrqqjrpqzsl5Drp4xcbiAqICAgIOyCsOuLpChUVEwgc3dlZXAgKyDthqDtgbAg7KCc6rGwIOyLnCDsoJXrpqwpLiB0aHJlYWRDb29yZC5zeXN0ZW1IYXNoIOuKlCDsg4HsnIQgaXNzdWVDb252Q29udGV4dCDqsIAg65Sw66GcXG4gKiAgICDssYTsmrDsp4Drp4wgQW50aHJvcGljIHJlc3VtZSBlbGlnaWJpbGl0eSDtjJDsoJXsl5DripQg7JOw7J207KeAIOyViuuKlOuLpC5cbiAqICAtICoq6529IOyGjOycoOq2jCoqOiBjbGF1ZGUgc2Vzc2lvbi1pZCDsp4HroKztmZTripQgVTQgYHJ1bkNsYXVkZVNlc3Npb25gIOydtCDri6jrj4Ug7IaM7Jyg7ZWc64ukLlxuICogICAgZGlzcGF0Y2hlciDripQgcmVzdW1lIGVsaWdpYmlsaXR5IC8gdG9rZW4gb3duZXJzaGlwIOunjCDtjJDsoJXtlZjqs6AgYHdpdGhTZXNzaW9uTG9ja2Ag7Jy866GcIOqwkOyLuOyngCDslYrripTri6QuXG4gKiAgICDsl6zquLDshJwg64uk7IucIOqwkOyLuOuptCBVNCDrgrTrtoAg65296rO8IOqwmeydgCBzZXNzaW9uLWlkIOuhnCDsnqzsp4TsnoXtlbQgZGVhZGxvY2sg7J20IOuCnOuLpC5cbiAqICAgIGNvbGQg7LKrIO2YuOy2nCDqsr3sn4HsnYQg65Sw66GcIOunieyngCDslYrripQg6re86rGw64qUIHJ1bigpIOydmCDrnb0g7KO87ISdIOywuOyhsChJRi9vd25lciBzY29wZSDsnZgg7Iic7LCoIO2YuOy2nCDsoITsoJwpLlxuICogIC0g67Cc6riJ7ZWcIHNlc3Npb24taWQg7JmAIO2YuO2ZmO2CpOulvCBHZW5lcmF0ZVJlc3VsdC50aHJlYWRDb29yZCh0aHJlYWRJZD1zZXNzaW9uLWlkLCB3b3JrZXJJZD10b2tlbklkLFxuICogICAgZXBvY2g9MCnroZwg7Jis66CkLCDsg4HsnIQoaXNzdWVDb252Q29udGV4dCnqsIAg7YG065287JeQIO2ajOyGoe2VoCDsooztkZzrpbwg66eM65Og64ukLlxuICovXG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5cbmltcG9ydCB7IFRva2VuTW9kZWwgfSBmcm9tIFwiLi4vLi4vLi4vYXBwbGljYXRpb24vdG9rZW4vdG9rZW4ubW9kZWxcIjtcbmltcG9ydCB7IHR5cGUgQW50aHJvcGljQ3JlZGVudGlhbHMgfSBmcm9tIFwiLi4vLi4vLi4vYXBwbGljYXRpb24vdG9rZW4vdG9rZW4udHlwZXNcIjtcbmltcG9ydCB7IGdldEV4cGlyZXNBdCwgZ2V0UmVmcmVzaFRva2VuIH0gZnJvbSBcIi4uL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBHZW5lcmF0ZVJlcXVlc3QsXG4gIHR5cGUgR2VuZXJhdGVSZXN1bHQsXG4gIHR5cGUgR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MsXG4gIHR5cGUgUHJvdmlkZXJEaXNwYXRjaGVyLFxufSBmcm9tIFwiLi4vY29tbW9uL3Byb3ZpZGVyLWRpc3BhdGNoZXJcIjtcbmltcG9ydCB7IGNhbm9uaWNhbEFudGhyb3BpY01vZGVsIH0gZnJvbSBcIi4vYW50aHJvcGljLWNvbnN0YW50c1wiO1xuaW1wb3J0IHsgY29tcGF0aWJpbGl0eUtleSwgbWFrZUFudGhyb3BpY1dvcmtlcklkLCBydW5DbGF1ZGVTZXNzaW9uIH0gZnJvbSBcIi4vY2xhdWRlLXNlc3Npb25cIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwiYW50aHJvcGljLWRpc3BhdGNoZXJcIl0pO1xuXG5jb25zdCBERUZBVUxUX1RJTUVPVVRfTVMgPSAxMjBfMDAwO1xuLy8gYWNjZXNzIHRva2VuIOunjOujjCDsnoTrsJUg7J6E6rOEIOKAlCDquLDsobQgc3RhbmRhbG9uZSDqsr3roZwocWdyaWQuZGlzcGF0Y2hlci50cynsmYAg64+Z7J28KDYwcykuXG5jb25zdCBSRUZSRVNIX1NBRkVUWV9NUyA9IDYwXzAwMDtcblxuaW50ZXJmYWNlIFBvb2xlZFRva2VuIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBjcmVkZW50aWFsczogQW50aHJvcGljQ3JlZGVudGlhbHM7XG59XG5cbi8vIFFncmlkRnJhbWUucmVmcmVzaFRva2VuIOydgCBUb2tlblN1YnNldEEo7Yq57Z6IIHByb3ZpZGVyKeulvCDrsJvslYQgVG9rZW5Nb2RlbC5zYXZlIOyXkCDrhJjquLTri6QuXG4vLyBhbnRocm9waWMg7ZKA7J2YIO2GoO2BsOydgCDtla3sg4EgcHJvdmlkZXI9XCJhbnRocm9waWNcIiDsnbTrr4DroZwgcmVmcmVzaCDsi5wg7J20IOqwkuydhCDqs6DsoJXsnLzroZwg7LGE7Jq064ukLlxuLy8gKHByb3ZpZGVyIOuIhOudvSDsi5wgc2F2ZSDsi6TtjKgg4oaSIOunjOujjOuQnCBhY2Nlc3MgdG9rZW4g7Jy866GcIOynhO2Wie2VmOuKlCDrsoTqt7jqsIAg64Kc64ukLilcbmNvbnN0IEFOVEhST1BJQ19QUk9WSURFUiA9IFwiYW50aHJvcGljXCIgYXMgY29uc3Q7XG5cbi8vIHNlc3Npb24taWQg4oaSIGNvbXBhdCDrp6TtlZEgVFRMLiDshJzrsoQgdGhyZWFkIGlkbGUgVFRMKDEw67aEKeqzvCDsoJXtlakg4oCUIOq3uOuztOuLpCDsmKTrnpjrkJwg7IS47IWY7J2AXG4vLyDslrTssKjtlLwgcmVzdW1lIOu2iOqwgO2VmOuvgOuhnCDtj5DquLDtlbTrj4Qg7JWI7KCEKHNlc3Npb25Db21wYXQg66y07ZWcIOymneqwgCDrsKnsp4ApLlxuY29uc3QgU0VTU0lPTl9DT01QQVRfVFRMX01TID0gMTAgKiA2MCAqIDEwMDA7XG5cbmludGVyZmFjZSBDb21wYXRFbnRyeSB7XG4gIGNvbXBhdDogc3RyaW5nO1xuICB0b2tlbklkOiBudW1iZXI7XG4gIGxhc3RVc2VkQXQ6IG51bWJlcjtcbn1cblxuZnVuY3Rpb24gaXNSZXRyeWFibGVSZXN1bWVGYWlsdXJlKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gIGNvbnN0IGxvd2VyID0gbWVzc2FnZS50b0xvd2VyQ2FzZSgpO1xuICBpZiAoXG4gICAgbG93ZXIuaW5jbHVkZXMoXCJ0aW1lb3V0XCIpIHx8XG4gICAgbG93ZXIuaW5jbHVkZXMoXCJhYm9ydGVkXCIpIHx8XG4gICAgbG93ZXIuaW5jbHVkZXMoXCJzcGF3biBlcnJvclwiKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKFwicXVvdGFcIikgfHxcbiAgICBsb3dlci5pbmNsdWRlcyhcInlvdSd2ZSBoaXRcIikgfHxcbiAgICBsb3dlci5pbmNsdWRlcyhcInVuYXV0aG9yaXplZFwiKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKFwiYXV0aGVudGljYXRpb25cIikgfHxcbiAgICBsb3dlci5pbmNsdWRlcyhcImludmFsaWQgb2F1dGhcIikgfHxcbiAgICBsb3dlci5pbmNsdWRlcyhcInBlcm1pc3Npb24gZGVuaWVkXCIpIHx8XG4gICAgbG93ZXIuaW5jbHVkZXMoXCJtYXhfdHVybnNcIikgfHxcbiAgICBsb3dlci5pbmNsdWRlcyhcIm1heC10dXJuc1wiKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKFwic2NoZW1hXCIpIHx8XG4gICAgbG93ZXIuaW5jbHVkZXMoXCJtb2RlbF9lcnJvclwiKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKFwibW9kZWwgZXJyb3JcIilcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBsb3dlci5pbmNsdWRlcyhcImNsb3NlZCB3aXRob3V0IHJlc3VsdFwiKSB8fCAvXFxiKHJlc3VtZXx0cmFuc2NyaXB0KVxcYi8udGVzdChsb3dlcik7XG59XG5cbmV4cG9ydCBjbGFzcyBBbnRocm9waWNEaXNwYXRjaGVyIGltcGxlbWVudHMgUHJvdmlkZXJEaXNwYXRjaGVyIHtcbiAgLy8gdG9rZW5JZCDihpIg7ZKAIO2VreuqqS4gc3RhcnQoKS90b2tlbiDsnbTrsqTtirjroZwg7LGE7Jq064ukLlxuICBwcml2YXRlIHRva2VuUG9vbCA9IG5ldyBNYXA8bnVtYmVyLCBQb29sZWRUb2tlbj4oKTtcbiAgLy8gdG9rZW5JZCDrs4Qg7IKs7JqpIOy5tOyatO2EsChsZWFzdC11c2VkIFJSKS4gbmFtZSDsnbQg7JWE64uI6528IGlkIOq4sOykgCDigJQg7J2066aEIOy2qeuPjCDslYjsoIQuXG4gIHByaXZhdGUgcmVxdWVzdENvdW50cyA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcnJJbmRleCA9IDA7XG4gIC8vIGNsYXVkZSBzZXNzaW9uLWlkIOKGkiDqt7gg7IS47IWY7J2EIOunjOuToCDsmpTssq3snZgg7Zi47ZmY7YKkKCt0b2tlbklkL2xhc3RVc2VkQXQpLiByZXN1bWUgZWxpZ2liaWxpdHkg7YyQ7KCVLlxuICAvLyBUVEwgc3dlZXAgKyDthqDtgbAg7KCc6rGwIOyLnCDsoJXrpqzroZwg66y07ZWcIOymneqwgCDrsKnsp4AuXG4gIHByaXZhdGUgc2Vzc2lvbkNvbXBhdCA9IG5ldyBNYXA8c3RyaW5nLCBDb21wYXRFbnRyeT4oKTtcblxuICAvLyDilIDilIAgbGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIE9wZW5BSURpc3BhdGNoZXIuc3RhcnQoKSDsmYAg64+Z7J287ZWY6rKMIERCIOyXkOyEnCDquLDsobQgYW50aHJvcGljIO2GoO2BsOydhCBzZWxmLWJvb3RzdHJhcCDtlZzri6QuXG4gICAgLy8gKOyEnOuyhCDsnqzsi5zsnpEg7IucIE5PVElGWSDqsIAg7JWIIOyYpOuvgOuhnCDrtoDtirjsiqTtirjrnqnsnbQg7JeG7Jy866m0IO2SgOydtCDruYgg7LGE66GcIOuCqOuKlOuLpC4pXG4gICAgLy8g7J207ZuEIOuzgOqyveu2hOydgCB0b2tlbi1zdWJzY3JpYmVyIOqwgCBvblRva2VuQWRkZWQvVXBkYXRlZC9SZW1vdmVkIOuhnCDsoITri6ztlZzri6QuXG4gICAgLy8gZmluZEFjdGl2ZUJ5UHJvdmlkZXIg6rCAIGFjdGl2ZT10cnVlICsgcHJvdmlkZXIg7ZWE7YSw66W8IERCIOyXkOyEnCDsspjrpqwg4oaSIGluYWN0aXZlIOuKlCDslaDstIjsl5Ag7JWIIOyYqOuLpC5cbiAgICBjb25zdCB0b2tlbnMgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRBY3RpdmVCeVByb3ZpZGVyKFwiQVwiLCBcImFudGhyb3BpY1wiKTtcbiAgICBmb3IgKGNvbnN0IHQgb2YgdG9rZW5zKSB7XG4gICAgICB0aGlzLnRva2VuUG9vbC5zZXQodC5pZCwge1xuICAgICAgICBpZDogdC5pZCxcbiAgICAgICAgbmFtZTogdC5uYW1lLFxuICAgICAgICBjcmVkZW50aWFsczogdC5jcmVkZW50aWFscyBhcyBBbnRocm9waWNDcmVkZW50aWFscyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbyhgYW50aHJvcGljIGRpc3BhdGNoZXIgc3RhcnRlZCAoJHt0aGlzLnRva2VuUG9vbC5zaXplfSB0b2tlbnMpYCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMudG9rZW5Qb29sLmNsZWFyKCk7XG4gICAgdGhpcy5zZXNzaW9uQ29tcGF0LmNsZWFyKCk7XG4gICAgLy8gbGlmZWN5Y2xlIOygle2VqTogUlIg7Lm07Jq07YSwL+yduOuNseyKpOuPhCDruYTsm4wgc3RvcOKGknN0YXJ0IOyerOuTseuhnSDsi5wg7J207KCEIOy5tOyatO2KuOqwgCDslYgg64Ko6rKMIO2VnOuLpC5cbiAgICB0aGlzLnJlcXVlc3RDb3VudHMuY2xlYXIoKTtcbiAgICB0aGlzLnJySW5kZXggPSAwO1xuICB9XG5cbiAgLy8g7ZiE7J6sIO2SgOydmCDthqDtgbAg7IiYKHN0YXJ0dXAg66Gc6re4L2hlYWx0aCDsmqkpLlxuICBnZXQgdG9rZW5Db3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRva2VuUG9vbC5zaXplO1xuICB9XG5cbiAgLy8gREIgYWN0aXZlIGFudGhyb3BpYyDthqDtgbAg66qp66Gd7Jy866GcIO2SgOydhCDsnqzrj5nquLDtmZTtlZzri6QocGVyaW9kaWMgcmVjb25jaWxlL+yerOyXsOqysOyaqSkuXG4gIC8vIExJU1RFTi9OT1RJRlkg6rCAIOuBiuq4tCDrj5nslYgg7Jyg7Iuk65CcIOy2lOqwgC/sgq3soJwv67mE7Zmc7ISx7ZmU66W8IERCIOq4sOykgOycvOuhnCDri6Tsi5wg66ee7LaY64ukLlxuICAvLyDsnbTrsqTtirgg7ZW465Ok65+s66W8IOyerOyCrOyaqe2VtCBpZGVudGl0eS1jaGFuZ2UgLyBzZXNzaW9uQ29tcGF0IOygleumrOqwgCDsnbzqtIDrkJjqsowg7KCB7Jqp65CY64+E66GdIO2VnOuLpDpcbiAgLy8gIC0gREIg7JeQIOyXhuuKlOuNsCDtkoDsl5Ag7J6I64qUIO2GoO2BsCDihpIgb25Ub2tlblJlbW92ZWQgKGNvbXBhdCDsoJXrpqwg7Y+s7ZWoKVxuICAvLyAgLSBEQiDsl5Ag7J6I64qUIO2GoO2BsCDihpIg7Iug6rec66m0IG9uVG9rZW5BZGRlZCwg6riw7KG07J2066m0IG9uVG9rZW5VcGRhdGVkKGlkZW50aXR5IOuzgOqyvSDqsJDsp4ApXG4gIHJlcGxhY2VUb2tlbnMoXG4gICAgcm93czogQXJyYXk8eyBpZDogbnVtYmVyOyBuYW1lOiBzdHJpbmc7IGNyZWRlbnRpYWxzOiBBbnRocm9waWNDcmVkZW50aWFscyB9PixcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICAvLyBvblRva2VuUmVtb3ZlZCDqsIAgdG9rZW5Qb29sIOydhCBkZWxldGUg7ZWY66+A66GcIOyInO2ajCDspJEg7IiY7KCV7J2EIO2UvO2VmOugpCDtgqTrpbwg66i87KCAIOyKpOuDheyDt+2VnOuLpC5cbiAgICBjb25zdCBjdXJyZW50SWRzID0gQXJyYXkuZnJvbSh0aGlzLnRva2VuUG9vbC5rZXlzKCkpO1xuICAgIGZvciAoY29uc3QgaWQgb2YgY3VycmVudElkcykge1xuICAgICAgaWYgKCFuZXh0LmhhcyhpZCkpIHRoaXMub25Ub2tlblJlbW92ZWQoaWQpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHIgb2Ygcm93cykge1xuICAgICAgaWYgKHRoaXMudG9rZW5Qb29sLmhhcyhyLmlkKSkgdGhpcy5vblRva2VuVXBkYXRlZChyLmlkLCByLm5hbWUsIHIuY3JlZGVudGlhbHMpO1xuICAgICAgZWxzZSB0aGlzLm9uVG9rZW5BZGRlZChyLmlkLCByLm5hbWUsIHIuY3JlZGVudGlhbHMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCB0b2tlbiBldmVudHMgKHRva2VuLXN1YnNjcmliZXIg6rCAIO2YuOy2nCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgb25Ub2tlbkFkZGVkKGlkOiBudW1iZXIsIG5hbWU6IHN0cmluZywgY3JlZGVudGlhbHM6IEFudGhyb3BpY0NyZWRlbnRpYWxzKTogdm9pZCB7XG4gICAgdGhpcy50b2tlblBvb2wuc2V0KGlkLCB7IGlkLCBuYW1lLCBjcmVkZW50aWFscyB9KTtcbiAgfVxuICBvblRva2VuVXBkYXRlZChpZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGNyZWRlbnRpYWxzOiBBbnRocm9waWNDcmVkZW50aWFscyk6IHZvaWQge1xuICAgIC8vIGFjY2Vzcy9yZWZyZXNoIHRva2VuIHJvdGF0aW9uKOqwmeydgCDqs4TsoJUp7J2066m0IGluLXBsYWNlIOqwseyLoOycvOuhnCDshLjshZjsnYQg7Jyg7KeA7ZWc64ukLlxuICAgIC8vIO2VmOyngOunjCBhY2NvdW50VXVpZCDqsIAg67CU64CQIOyerOuhnOq3uOyduC/qs4TsoJUg6rWQ7LK066m0LCDqsJnsnYAgdG9rZW5JZCDslYTrnpgg7IK07JWE64Ko7J2AIHNlc3Npb25Db21wYXQg6rCAXG4gICAgLy8g7J207KCEIOqzhOygleycvOuhnCDrp4zrk6Agc2Vzc2lvbi1pZCDrpbwg7IOIIOqzhOyglSBjcmVkZW50aWFscyDroZwgcmVzdW1lIOyLnO2CpOuKlCDqsqnrpqwg7JyE67CY7J20IOuQnOuLpC5cbiAgICAvLyBPcGVuQUkgZGlzcGF0Y2hlciDqsIAgbG9naW4gaWRlbnRpdHkg67OA6rK97J2EIHdvcmtlciByZXN0YXJ0IOuhnCDqtazrtoTtlZjripQg6rKD6rO8IOuPmeydvO2VnCDsspjrpqw6XG4gICAgLy8gaWRlbnRpdHkg6rCAIOuwlOuAjOuptCDqt7ggdG9rZW5JZCDsnZgg7IS47IWYIGNvbXBhdCDsnYQg7Y+Q6riw7ZW0IOydtO2bhCDtmLjstpzsnbQgY29sZCDroZwg65ao7Ja07KeA6rKMIO2VnOuLpC5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMudG9rZW5Qb29sLmdldChpZCk7XG4gICAgY29uc3QgaWRlbnRpdHlDaGFuZ2VkID1cbiAgICAgIGV4aXN0aW5nICE9PSB1bmRlZmluZWQgJiYgZXhpc3RpbmcuY3JlZGVudGlhbHMuYWNjb3VudFV1aWQgIT09IGNyZWRlbnRpYWxzLmFjY291bnRVdWlkO1xuICAgIGlmIChpZGVudGl0eUNoYW5nZWQpIHRoaXMuY2xlYXJTZXNzaW9uQ29tcGF0Rm9yKGlkKTtcbiAgICB0aGlzLnRva2VuUG9vbC5zZXQoaWQsIHsgaWQsIG5hbWUsIGNyZWRlbnRpYWxzIH0pO1xuICB9XG4gIG9uVG9rZW5SZW1vdmVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnRva2VuUG9vbC5kZWxldGUoaWQpO1xuICAgIHRoaXMucmVxdWVzdENvdW50cy5kZWxldGUoaWQpO1xuICAgIC8vIOydtCDthqDtgbDsnLzroZwg66eM65OgIOyEuOyFmOydmCBjb21wYXQg7JeU7Yq466as64+EIOygleumrC5cbiAgICB0aGlzLmNsZWFyU2Vzc2lvbkNvbXBhdEZvcihpZCk7XG4gIH1cblxuICAvLyDtirnsoJUgdG9rZW5JZCDroZwg66eM65OgIOuqqOuToCBzZXNzaW9uQ29tcGF0IOyXlO2KuOumrCDtj5DquLAo7Yag7YGwIOygnOqxsCAvIGlkZW50aXR5IOuzgOqyvSDsi5wg6rO17Ya1KS5cbiAgcHJpdmF0ZSBjbGVhclNlc3Npb25Db21wYXRGb3IodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBbc2lkLCBlXSBvZiB0aGlzLnNlc3Npb25Db21wYXQpIHtcbiAgICAgIGlmIChlLnRva2VuSWQgPT09IHRva2VuSWQpIHRoaXMuc2Vzc2lvbkNvbXBhdC5kZWxldGUoc2lkKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgdG9rZW4gc2VsZWN0aW9uIChsZWFzdC11c2VkIFJSLCB0b2tlbklkIOq4sOykgCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcHJpdmF0ZSBjb3VudE9mKGlkOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RDb3VudHMuZ2V0KGlkKSA/PyAwO1xuICB9XG5cbiAgLy8gY29sZCDqsr3roZw6IGxlYXN0LXVzZWQgUlIg66GcIO2GoO2BsOydhCDqs6Drpbjri6Qo64+Z7KCQ7J2066m0IHJySW5kZXgg66GcIO2ajOyghCkuXG4gIHByaXZhdGUgc2VsZWN0VG9rZW4oKTogUG9vbGVkVG9rZW4gfCBudWxsIHtcbiAgICBjb25zdCByb3dzID0gWy4uLnRoaXMudG9rZW5Qb29sLnZhbHVlcygpXTtcbiAgICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIGNvbnN0IG1pbkNvdW50ID0gTWF0aC5taW4oLi4ucm93cy5tYXAoKHIpID0+IHRoaXMuY291bnRPZihyLmlkKSkpO1xuICAgIGNvbnN0IGlkbGUgPSByb3dzLmZpbHRlcigocikgPT4gdGhpcy5jb3VudE9mKHIuaWQpID09PSBtaW5Db3VudCk7XG4gICAgY29uc3QgcGlja2VkID0gaWRsZVt0aGlzLnJySW5kZXggJSBpZGxlLmxlbmd0aF0hO1xuICAgIHRoaXMucnJJbmRleCsrO1xuICAgIHJldHVybiB0aGlzLmNoYXJnZShwaWNrZWQpO1xuICB9XG5cbiAgLy8gcmVzdW1lIOqyveuhnDog7IS47IWY7J2EIOunjOuToCDthqDtgbDsnYQgaWQg66GcIOqzoOyglSDshKDtg53tlZzri6QuIO2SgOyXkCDsl4bsnLzrqbQgbnVsbCjihpIgY29sZCBmYWxsYmFjaykuXG4gIC8vIHJlc3VtZSDshLjshZjsnYAg6re4IO2GoO2BsOydmCBDTEFVREVfQ09ORklHX0RJUiDsl5AgdHJhbnNjcmlwdCDqsIAg66y27JesIOyeiOyWtCwg64uk66W4IO2GoO2BsOycvOuhnCByZXN1bWUg7ZWY66m0XG4gIC8vIHRyYW5zY3JpcHQg6rCAIOyXhuyWtCDquajsp4Tri6QuIOq3uOuemOyEnCBSUiDsnYQg7JOw7KeAIOyViuqzoCDshozsnKAg7Yag7YGw7J2EIOq3uOuMgOuhnCDsnqHslYTslbwg7ZWc64ukLlxuICBwcml2YXRlIHBpY2tUb2tlbihpZDogbnVtYmVyKTogUG9vbGVkVG9rZW4gfCBudWxsIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5Qb29sLmdldChpZCk7XG4gICAgcmV0dXJuIHRva2VuID8gdGhpcy5jaGFyZ2UodG9rZW4pIDogbnVsbDtcbiAgfVxuXG4gIC8vIOyEoO2DneuQnCDthqDtgbDsnZgg7IKs7JqpIOy5tOyatO2KuOulvCBhd2FpdCDsoITsl5Ag7ISg67CY7JiBKOuPmeyLnCDsmpTssq3snbQg64uk66W4IO2GoO2BsOydhCDqs6DrpbTrj4TroZ0pLlxuICBwcml2YXRlIGNoYXJnZSh0b2tlbjogUG9vbGVkVG9rZW4pOiBQb29sZWRUb2tlbiB7XG4gICAgdGhpcy5yZXF1ZXN0Q291bnRzLnNldCh0b2tlbi5pZCwgdGhpcy5jb3VudE9mKHRva2VuLmlkKSArIDEpO1xuICAgIHJldHVybiB0b2tlbjtcbiAgfVxuXG4gIC8vIOunjOujjOuQnCBjb21wYXQg7JeU7Yq466asIOygleumrChsYXp5IHN3ZWVwIOKAlCBnZW5lcmF0ZSDsp4TsnoUg7IucIO2YuOy2nCkuXG4gIHByaXZhdGUgc3dlZXBTZXNzaW9uQ29tcGF0KCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgZm9yIChjb25zdCBbc2lkLCBlXSBvZiB0aGlzLnNlc3Npb25Db21wYXQpIHtcbiAgICAgIGlmIChub3cgLSBlLmxhc3RVc2VkQXQgPiBTRVNTSU9OX0NPTVBBVF9UVExfTVMpIHRoaXMuc2Vzc2lvbkNvbXBhdC5kZWxldGUoc2lkKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgZ2VuZXJhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgYXN5bmMgZ2VuZXJhdGUocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucnVuKHJlcSwgKCkgPT4ge30pO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVTdHJlYW0ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJ1bihyZXEsIGNiLm9uRGVsdGEpO1xuICAgICAgY2Iub25UaHJlYWRJZD8uKHJlc3VsdC50aHJlYWRDb29yZC50aHJlYWRJZCk7XG4gICAgICBjYi5vbkNvbXBsZXRlKHJlc3VsdCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2Iub25FcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvLyBnZW5lcmF0ZS9nZW5lcmF0ZVN0cmVhbSDqs7XthrUg7Iuk7ZaJLiBvbkRlbHRhIOuKlCDsiqTtirjrprzsnbTrqbQg7KCQ7KeEIOuwqey2nCwg67mE7Iqk7Yq466a87J2066m0IG5vLW9wLlxuICBwcml2YXRlIGFzeW5jIHJ1bihyZXE6IEdlbmVyYXRlUmVxdWVzdCwgb25EZWx0YTogKHQ6IHN0cmluZykgPT4gdm9pZCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICB0aGlzLnN3ZWVwU2Vzc2lvbkNvbXBhdCgpO1xuXG4gICAgLy8gbW9kZWwg7KCV6rec7ZmU66W8IGRpc3BhdGNoZXIg7KeE7J6F7KCQ7JeQ7IScIO2VnCDrsogg7ZWc64ukOiBjb21wYXQgLyByZXN1bHQubW9kZWwgLyBydW5DbGF1ZGVTZXNzaW9uIOyghOu2gFxuICAgIC8vIGNhbm9uaWNhbChwcmVmaXgg7JeG64qUIGNvc3Qg7YKkKSDsnYQg7JOw6rKMIO2GteydvC4g66+47KeA7KCV7J2066m0IEFOVEhST1BJQ19ERUZBVUxUX01PREVMIOKAlCBxZ3JpZC5kaXNwYXRjaGVyXG4gICAgLy8g7J2YIFwic29ubmV0XCIg67OE7LmtIOyasO2ajCDssKjri6guIOygleq3nO2ZlCDqt5zsuZnsnYAgZmFsbGJhY2sg6rK966Gc7JmAIOqzteycoChjYW5vbmljYWxBbnRocm9waWNNb2RlbCkuXG4gICAgY29uc3QgbW9kZWwgPSBjYW5vbmljYWxBbnRocm9waWNNb2RlbChyZXEubW9kZWwpO1xuICAgIGNvbnN0IGpzb25TY2hlbWEgPVxuICAgICAgcmVxLm91dHB1dFNjaGVtYSAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkocmVxLm91dHB1dFNjaGVtYSkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgY29tcGF0ID0gY29tcGF0aWJpbGl0eUtleSh7IHN5c3RlbTogcmVxLnN5c3RlbVByb21wdCwgbW9kZWwsIG91dHB1dFNjaGVtYToganNvblNjaGVtYSB9KTtcblxuICAgIC8vIOKUgOKUgCByZXN1bWUgZWxpZ2liaWxpdHkgKyDthqDtgbAg7ISg7YOdIChyZXN1bWUg64qUIOyEuOyFmCDshozsnKAg7Yag7YGw7Jy866Gc66eMKSDilIDilIBcbiAgICAvLyAgcmVzdW1lIOqwgCDshLHrpr3tlZjroKTrqbQg7IS4IOyhsOqxtOydtCDrqqjrkZAg7LC47J207Ja07JW8IO2VnOuLpDpcbiAgICAvLyAgIChhKSByZXVzZS50aHJlYWRJZCDsnZgg7KCA7J6l65CcIO2YuO2ZmO2CpCA9PSDsnbTrsogg7JqU7LKtIO2YuO2ZmO2CpCAo66qo6424L3N5c3RlbS9zY2hlbWEg67OA6rK9IOyYpOyXvCDrsKnsp4ApXG4gICAgLy8gICAoYikg7KCA7J6l65CcIHRva2VuSWQgPT0gcmV1c2Uud29ya2VySWQgKGNvb3JkIOyZleuztSDrrLTqsrDshLEpIOydtOqzoFxuICAgIC8vICAgKGMpIOq3uCDthqDtgbDsnbQg7JWE7KeBIO2SgOyXkCDsgrTslYTsnojsnYwuXG4gICAgLy8gIO2VmOuCmOudvOuPhCDslrTquIvrgpjrqbQgcmVzdW1lIOu2iOqwgCDihpIgY29sZCDroZwg65ao7Ja07KeA6rOgIFJSIOuhnCDsg4gg7Yag7YGw7J2EIOqzoOuluOuLpC5cbiAgICAvLyAgcmVzdW1lIOydvCDrlYzripQg67CY65Oc7IucIOyEuOyFmOydhCDrp4zrk6Ag6re4IO2GoO2BsChzdG9yZWQudG9rZW5JZCnsnYQg6rOg7KCVIOyEoO2Dne2VnOuLpCDigJQgUlIg66GcIOuLpOuluCDthqDtgbDsnYQg7J6h7Jy866m0XG4gICAgLy8gIOq3uCDthqDtgbDsnZggQ0xBVURFX0NPTkZJR19ESVIg7JeQIHRyYW5zY3JpcHQg6rCAIOyXhuyWtCByZXN1bWUg7J20IOq5qOynhOuLpC5cbiAgICBjb25zdCBjYW5kaWRhdGUgPSByZXEucmV1c2U/LnRocmVhZElkO1xuICAgIGNvbnN0IHN0b3JlZCA9IGNhbmRpZGF0ZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5zZXNzaW9uQ29tcGF0LmdldChjYW5kaWRhdGUpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IG93bmVyTWF0Y2hlcyA9IHN0b3JlZCAhPT0gdW5kZWZpbmVkICYmIHN0b3JlZC50b2tlbklkID09PSByZXEucmV1c2U/LndvcmtlcklkO1xuICAgIGNvbnN0IHJlc3VtZVRva2VuID1cbiAgICAgIHN0b3JlZD8uY29tcGF0ID09PSBjb21wYXQgJiYgb3duZXJNYXRjaGVzID8gdGhpcy5waWNrVG9rZW4oc3RvcmVkLnRva2VuSWQpIDogbnVsbDtcblxuICAgIGNvbnN0IGlzUmVzdW1lID0gcmVzdW1lVG9rZW4gIT09IG51bGw7XG4gICAgY29uc3QgcmVzdW1lU2Vzc2lvbklkID0gaXNSZXN1bWUgPyBjYW5kaWRhdGUgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyByZXN1bWUg66m0IOyGjOycoCDthqDtgbAg6rOg7KCVLCDslYTri4jrqbQgY29sZCBSUiDshKDtg50uXG4gICAgY29uc3QgdG9rZW4gPSByZXN1bWVUb2tlbiA/PyB0aGlzLnNlbGVjdFRva2VuKCk7XG4gICAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKFwiTm8gYW50aHJvcGljIHRva2VucyBhdmFpbGFibGVcIik7XG5cbiAgICAvLyDrnb0g7IaM7Jyg6raMOlxuICAgIC8vICBzZXNzaW9uLWlkIOuLqOychCDsp4HroKztmZQg65297J2AICoqVTQgcnVuQ2xhdWRlU2Vzc2lvbiDsnbQg64uo64+FIOyGjOycoCoq7ZWc64ukLiBkaXNwYXRjaGVyIOqwgCDsl6zquLDshJxcbiAgICAvLyAgd2l0aFNlc3Npb25Mb2NrKHJlc3VtZVNlc3Npb25JZCkg7Jy866GcIO2VnCDrsogg642UIOqwkOyLuOuptCwgZXhlYygpIOyViOydmCBydW5DbGF1ZGVTZXNzaW9uIOydtCDqsJnsnYBcbiAgICAvLyAgc2Vzc2lvbi1pZCDroZwg65297JeQIOyerOynhOyehe2VmOuKlOuNsCB3aXRoU2Vzc2lvbkxvY2sg7J2AIHJlZW50cmFudCDqsIAg7JWE64uI6528IOyekOq4sCDsnpDsi6DsnYQg6riw64uk66as64qUXG4gICAgLy8gIGRlYWRsb2NrIOydtCDrgpzri6Qo7LKrIHJlc3VtZSDtmLjstpzsnbQg7JiB6rWsIOygleyngCkuIFUxL1U1IGRpc3BhdGNoZXIg64qUIHRva2VuIG93bmVyc2hpcCAvIGNvbXBhdCDrp4xcbiAgICAvLyAg7YyQ7KCV7ZWY6rOgLCB0cmFuc2NyaXB0IOyngeugrO2ZlOuKlCBVNCDrnb3sl5Ag7JyE7J6E7ZWc64ukLlxuICAgIC8vICBjb2xkIOyyqy3tmLjstpwg64+Z7Iuc7ISx7J2EIGRpc3BhdGNoZXIg6rCAIOuUsOuhnCDrp4nsp4Ag7JWK64qUIOq3vOqxsDogc2Vzc2lvbktleSDripQg7ISc67KE66GcIOyYpOyngCDslYrslYQo7YG06528XG4gICAgLy8gIHN0b3JlIOq0gOumrCwg7KKM7ZGc66eMIO2ajOyGoSkgY29sZCDrs4Qg65297J2YIOyeheugpSDsnpDssrTqsIAg7JeG6rOgLCDtmITsnqwgSUYvb3duZXIg64qUIExMTSDtmLjstpzsnYQg7KCE67aAIOyInOywqOuhnFxuICAgIC8vICDrj4zroKQg64+Z7IucIOyyqyDtmLjstpzsnbQg64KY7KeAIOyViuuKlOuLpCgyMDI2LTA2LTA2IEwyMS9MMjQ4KS4g67OR66Cs7ZmUL+yEnOuyhOyghOuLrOuhnCDrsJTrgIzrqbQg7J6s6rKA7YagLlxuICAgIGNvbnN0IGV4ZWMgPSBhc3luYyAoKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4gPT4ge1xuICAgICAgLy8g66eM66OMIOyehOuwlSDthqDtgbAgcHJlZW1wdGl2ZSByZWZyZXNoKOq4sOyhtCBzdGFuZGFsb25lIOqyveuhnOyZgCDrj5nsnbwpLiDsi6TtjKjtlbTrj4Qg7KeE7ZaJLlxuICAgICAgbGV0IGFjY2Vzc1Rva2VuID0gdG9rZW4uY3JlZGVudGlhbHMuYWNjZXNzVG9rZW47XG4gICAgICBjb25zdCBleHBpcmVzQXQgPSBnZXRFeHBpcmVzQXQodG9rZW4uY3JlZGVudGlhbHMpO1xuICAgICAgaWYgKFxuICAgICAgICBleHBpcmVzQXQgJiZcbiAgICAgICAgZXhwaXJlc0F0IC0gRGF0ZS5ub3coKSA8IFJFRlJFU0hfU0FGRVRZX01TICYmXG4gICAgICAgIGdldFJlZnJlc2hUb2tlbih0b2tlbi5jcmVkZW50aWFscylcbiAgICAgICkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgUWdyaWRGcmFtZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vLi4vLi4vYXBwbGljYXRpb24vcWdyaWQvcWdyaWQuZnJhbWVcIik7XG4gICAgICAgICAgLy8gcHJvdmlkZXIg66W8IOuwmOuTnOyLnCDssYTsm4zslbwgcmVmcmVzaFRva2VuIOuCtOu2gCBUb2tlbk1vZGVsLnNhdmUg6rCAIOyEseqzte2VnOuLpC5cbiAgICAgICAgICAvLyByZWZyZXNoVG9rZW4oVG9rZW5TdWJzZXRBKSDripQgaWQvcHJvdmlkZXIvY3JlZGVudGlhbHMvbmFtZSDrp4wg7IKs7Jqp7ZWY66+A66GcIOq3uCA06rCc66eMIOuEmOq4tOuLpC5cbiAgICAgICAgICBhY2Nlc3NUb2tlbiA9IGF3YWl0IFFncmlkRnJhbWUucmVmcmVzaFRva2VuKHtcbiAgICAgICAgICAgIGlkOiB0b2tlbi5pZCxcbiAgICAgICAgICAgIHByb3ZpZGVyOiBBTlRIUk9QSUNfUFJPVklERVIsXG4gICAgICAgICAgICBuYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHRva2VuLmNyZWRlbnRpYWxzLFxuICAgICAgICAgIH0gYXMgUGFyYW1ldGVyczx0eXBlb2YgUWdyaWRGcmFtZS5yZWZyZXNoVG9rZW4+WzBdKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZ2dlci53YXJuKGByZWZyZXNoIGZhaWxlZCBmb3IgJHt0b2tlbi5uYW1lfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBydW5TZXNzaW9uID0gKHJlc3VtZTogYm9vbGVhbikgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbyhg4oaSICR7dG9rZW4ubmFtZX0gKG1vZGVsOiAke21vZGVsfSwgJHtyZXN1bWUgPyBcInJlc3VtZVwiIDogXCJjb2xkXCJ9KWApO1xuICAgICAgICByZXR1cm4gcnVuQ2xhdWRlU2Vzc2lvbihcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0b2tlbklkOiB0b2tlbi5pZCxcbiAgICAgICAgICAgIHRva2VuOiBhY2Nlc3NUb2tlbixcbiAgICAgICAgICAgIG1vZGVsLFxuICAgICAgICAgICAgc3lzdGVtOiByZXEuc3lzdGVtUHJvbXB0LFxuICAgICAgICAgICAganNvblNjaGVtYSxcbiAgICAgICAgICAgIGVmZm9ydDogcmVxLmVmZm9ydCxcbiAgICAgICAgICAgIHRpbWVvdXRNczogREVGQVVMVF9USU1FT1VUX01TLFxuICAgICAgICAgICAgY29sZEhpc3Rvcnk6IHJlc3VtZSA/IHVuZGVmaW5lZCA6IHJlcS5jb2xkSGlzdG9yeSxcbiAgICAgICAgICAgIGlucHV0OiByZXN1bWUgJiYgcmVxLnJldXNlSW5wdXQgPyByZXEucmV1c2VJbnB1dCA6IHJlcS5jb2xkSW5wdXQsXG4gICAgICAgICAgICByZXN1bWVTZXNzaW9uSWQ6IHJlc3VtZSA/IHJlc3VtZVNlc3Npb25JZCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGFib3J0U2lnbmFsOiByZXEuYWJvcnRTaWduYWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvbkRlbHRhLFxuICAgICAgICApO1xuICAgICAgfTtcblxuICAgICAgbGV0IHNlc3Npb247XG4gICAgICB0cnkge1xuICAgICAgICBzZXNzaW9uID0gYXdhaXQgcnVuU2Vzc2lvbihpc1Jlc3VtZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghaXNSZXN1bWUgfHwgIWlzUmV0cnlhYmxlUmVzdW1lRmFpbHVyZShlKSkgdGhyb3cgZTtcbiAgICAgICAgaWYgKGNhbmRpZGF0ZSkgdGhpcy5zZXNzaW9uQ29tcGF0LmRlbGV0ZShjYW5kaWRhdGUpO1xuICAgICAgICBsb2dnZXIud2FybihgcmVzdW1lIGZhaWxlZCBmb3IgJHt0b2tlbi5uYW1lfTsgcmV0cnlpbmcgY29sZCBvbmNlOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICBzZXNzaW9uID0gYXdhaXQgcnVuU2Vzc2lvbihmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzZXNzaW9uLnF1b3RhRXhoYXVzdGVkKSB0aHJvdyBuZXcgRXJyb3IoYHF1b3RhIGV4aGF1c3RlZCAoJHt0b2tlbi5uYW1lfSlgKTtcbiAgICAgIGlmIChzZXNzaW9uLmlzRXJyb3IpIHtcbiAgICAgICAgLy8gdGV4dCDqsIAg67mE7Ja0IOyeiOydhCDsiJgg7J6I7Jy866+A66GcIOynhOuLqCDqsIDriqXtlZwg7ZiV7YOc66GcIOuplOyLnOyngOulvCDrp4zrk6Dri6Qoc3VidHlwZSDrk7HsnYAgcmF3IOuhnOq3uCDssLjsobApLlxuICAgICAgICBjb25zdCBkZXRhaWwgPSBzZXNzaW9uLnRleHQgfHwgYGVtcHR5IHRleHQsIG91dHB1dFRva2Vucz0ke3Nlc3Npb24udXNhZ2Uub3V0cHV0VG9rZW5zfWA7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY2xhdWRlIGVycm9yICgke3Rva2VuLm5hbWV9KTogJHtkZXRhaWx9YCk7XG4gICAgICB9XG5cbiAgICAgIC8vIOuwnOq4ie2VnCBzZXNzaW9uLWlkIOydmCDtmLjtmZjtgqQg7KCA7J6lKOuLpOydjCByZXN1bWUg7YyQ7KCV7JqpKS4gY29tcGF0IOuKlCDsl6zquLAgZGlzcGF0Y2hlci1sb2NhbCDsl5Drp4xcbiAgICAgIC8vIOuztOyhtO2VnOuLpCDigJQgdGhyZWFkQ29vcmQuc3lzdGVtSGFzaCDroZwg7JmV67O17ZWY7KeAIOyViuuKlOuLpC4g7IOB7JyEIGlzc3VlQ29udkNvbnRleHQg6rCAIHN5c3RlbUhhc2gg66W8XG4gICAgICAvLyDrlLDroZwg7LGE7Jqw7KeA66eMIEFudGhyb3BpYyByZXN1bWUgZWxpZ2liaWxpdHkg64qUIOydtCBzZXNzaW9uQ29tcGF0IOqwgCDri6jrj4Ug7YyQ7KCVLlxuICAgICAgdGhpcy5zZXNzaW9uQ29tcGF0LnNldChzZXNzaW9uLnNlc3Npb25JZCwge1xuICAgICAgICBjb21wYXQsXG4gICAgICAgIHRva2VuSWQ6IHRva2VuLmlkLFxuICAgICAgICBsYXN0VXNlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHNlc3Npb24udGV4dCxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICB1c2FnZTogc2Vzc2lvbi51c2FnZSxcbiAgICAgICAgZHVyYXRpb25Nczogc2Vzc2lvbi5kdXJhdGlvbk1zLFxuICAgICAgICBjb3N0VXNkOiBzZXNzaW9uLmNvc3RVc2QsXG4gICAgICAgIG1vZGVsLFxuICAgICAgICAvLyBzeXN0ZW1IYXNoIOuKlCDsg4HsnIQgaXNzdWVDb252Q29udGV4dCDqsIAg7LGE7Jq064ukKOyXrOq4sOyEoCDruYTsmrTri6QpLlxuICAgICAgICB0aHJlYWRDb29yZDoge1xuICAgICAgICAgIHdvcmtlcklkOiBtYWtlQW50aHJvcGljV29ya2VySWQodG9rZW4uaWQpLFxuICAgICAgICAgIHRocmVhZElkOiBzZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICBlcG9jaDogMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfTtcblxuICAgIHJldHVybiBleGVjKCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9DQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsdUJBQXVCLENBQUM7QUFFM0QsTUFBTSxxQkFBcUI7QUFFM0IsTUFBTSxvQkFBb0I7QUFXMUIsTUFBTSxxQkFBcUI7QUFJM0IsTUFBTSx3QkFBd0IsTUFBVTtBQVF4QyxTQUFTLHlCQUF5QixPQUF5QjtDQUV6RCxNQUFNLFNBRFUsaUJBQWlCLFFBQVEsTUFBTSxVQUFVLE9BQU8sTUFBTSxFQUNoRCxhQUFhO0FBQ25DLEtB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
|
|
158
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW50aHJvcGljLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvYW50aHJvcGljLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBbnRocm9waWNEaXNwYXRjaGVyXG4gKlxuICogT3BlbkFJRGlzcGF0Y2hlcuyZgCDri6zrpqwsIHdvcmtlciBwb29s7J2EIOuRkOuKlCDrjIDsi6Ag7JqU7LKt67OEIGZyZXNoIHNwYXduXG4gKiDthqDtgbDsnYAg7J2466mU66qo66asKE1BUCnsnLzroZwg6rSA66as7ZWY6rOgIGxlYXN0LXVzZWQsIHJvdW5kLXJvYmluIOycvOuhnCDqs6Drpbjri6RcbiAqXG4gKiAtIOuqqOuToCDsmpTssq3snYAgZnJlc2ggYC0tc2Vzc2lvbi1pZGAg66GcIOyLpO2WiVxuICogLSDrqYDti7DthLQg66y466el7J2AIO2BtOudvOydtOyWuO2KuOqwgCDrp6Qg7Zi47LacIOuztOuCtOuKlCBmdWxsIGhpc3Rvcnkg66W8IO2Pie2DhO2ZlO2VtCDsoITri6ztlZzri6QuXG4gKiAtIOuwnOq4ie2VnCBzZXNzaW9uLWlkIOulvCBHZW5lcmF0ZVJlc3VsdC50aHJlYWRDb29yZCh0aHJlYWRJZD1zZXNzaW9uLWlkLCB3b3JrZXJJZD10b2tlbklkLFxuICogICBlcG9jaD0wKeuhnCDsmKzroKQsIOyDgeychChpc3N1ZUNvbnZDb250ZXh0KeqwgCDtgbTrnbzsl5Ag7ZqM7Iah7ZWgIOyijO2RnOulvCDrp4zrk6Dri6QuIOuLpOydjCB0dXJuIOydtCDsooztkZzrpbxcbiAqICAg7ZqM7Iah7ZW064+EIEFudGhyb3BpYyDrnbzsmrDtjIXsl5DripQg7JOw7KeAIOyViuuKlOuLpC5cbiAqL1xuXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIEFudGhyb3BpY0NyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyBnZXRFeHBpcmVzQXQsIGdldFJlZnJlc2hUb2tlbiB9IGZyb20gXCIuLi9jb21tb24vY3JlZGVudGlhbHNcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBhc3NlcnRTdXBwb3J0ZWRPbmVNaWxsaW9uU3VmZml4LCBjYW5vbmljYWxBbnRocm9waWNNb2RlbCB9IGZyb20gXCIuL2FudGhyb3BpYy1jb25zdGFudHNcIjtcbmltcG9ydCB7IG1ha2VBbnRocm9waWNXb3JrZXJJZCwgcnVuQ2xhdWRlU2Vzc2lvbiB9IGZyb20gXCIuL2NsYXVkZS1zZXNzaW9uXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcImFudGhyb3BpYy1kaXNwYXRjaGVyXCJdKTtcblxuLy8gMU0gY29udGV4dCDsoJXsg4Eg7IOd7ISx7J2AIOyLpOy4oeyDgSAxMDBzK+q5jOyngCDqsITri6QuIDI0MHPripQg7JmE7LapIOyepey5mOydvCDrv5AsXG4vLyDqsbDrtoAr6rGw64yAIHN5c3RlbSDsnqzsg53shLEg7KeA7Jew7J2EIOyZhOyghO2eiCDtlbTqsrDtlZjripQg6rCS7J2AIOyVhOuLiOuLpC5cbmNvbnN0IERFRkFVTFRfVElNRU9VVF9NUyA9IDI0MF8wMDA7XG4vLyBhY2Nlc3MgdG9rZW4g66eM66OMIOyehOuwlSDsnoTqs4Qg4oCUIOq4sOyhtCBzdGFuZGFsb25lIOqyveuhnChxZ3JpZC5kaXNwYXRjaGVyLnRzKeyZgCDrj5nsnbwoNjBzKS5cbmNvbnN0IFJFRlJFU0hfU0FGRVRZX01TID0gNjBfMDAwO1xuXG5pbnRlcmZhY2UgUG9vbGVkVG9rZW4ge1xuICBpZDogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxzOiBBbnRocm9waWNDcmVkZW50aWFscztcbn1cblxuZXhwb3J0IGNsYXNzIEFudGhyb3BpY0Rpc3BhdGNoZXIgaW1wbGVtZW50cyBQcm92aWRlckRpc3BhdGNoZXIge1xuICAvLyB0b2tlbklkIOKGkiDtkoAg7ZWt66qpLiBzdGFydCgpL3Rva2VuIOydtOuypO2KuOuhnCDssYTsm4BcbiAgcHJpdmF0ZSB0b2tlblBvb2wgPSBuZXcgTWFwPG51bWJlciwgUG9vbGVkVG9rZW4+KCk7XG4gIC8vIHRva2VuSWQg67OEIOyCrOyaqSDsubTsmrTthLAobGVhc3QtdXNlZCBSUikuIG5hbWUg7J20IOyVhOuLiOudvCBpZCDquLDspIAg4oCUIOydtOumhCDstqnrj4wg7JWI7KCEXG4gIHByaXZhdGUgcmVxdWVzdENvdW50cyA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcnJJbmRleCA9IDA7XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gT3BlbkFJRGlzcGF0Y2hlci5zdGFydCgpIOyZgCDrj5nsnbztlZjqsowgREIg7JeQ7IScIOq4sOyhtCBhbnRocm9waWMg7Yag7YGw7J2EIHNlbGYtYm9vdHN0cmFwIO2VnOuLpC5cbiAgICAvLyAo7ISc67KEIOyerOyLnOyekSDsi5wgTk9USUZZIOqwgCDslYgg7Jik66+A66GcIOu2gO2KuOyKpO2KuOueqeydtCDsl4bsnLzrqbQg7ZKA7J20IOu5iCDssYTroZwg64Ko64qU64ukLilcbiAgICAvLyDsnbTtm4Qg67OA6rK967aE7J2AIHRva2VuLXN1YnNjcmliZXIg6rCAIG9uVG9rZW5BZGRlZC9VcGRhdGVkL1JlbW92ZWQg66GcIOyghOuLrO2VnOuLpC5cbiAgICAvLyBmaW5kQWN0aXZlQnlQcm92aWRlciDqsIAgYWN0aXZlPXRydWUgKyBwcm92aWRlciDtlYTthLDrpbwgREIg7JeQ7IScIOyymOumrCDihpIgaW5hY3RpdmUg64qUIOyVoOy0iOyXkCDslYgg7Jio64ukLlxuICAgIGNvbnN0IHRva2VucyA9IGF3YWl0IFRva2VuTW9kZWwuZmluZEFjdGl2ZUJ5UHJvdmlkZXIoXCJBXCIsIFwiYW50aHJvcGljXCIpO1xuICAgIGZvciAoY29uc3QgdCBvZiB0b2tlbnMpIHtcbiAgICAgIHRoaXMudG9rZW5Qb29sLnNldCh0LmlkLCB7XG4gICAgICAgIGlkOiB0LmlkLFxuICAgICAgICBuYW1lOiB0Lm5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzOiB0LmNyZWRlbnRpYWxzIGFzIEFudGhyb3BpY0NyZWRlbnRpYWxzLFxuICAgICAgfSk7XG4gICAgICBsb2dnZXIuaW5mbyhgd29ya2VyIHNwYXduZWQ6ICR7dC5uYW1lfWApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy50b2tlblBvb2wuY2xlYXIoKTtcbiAgICAvLyBsaWZlY3ljbGUg7KCV7ZWpOiBSUiDsubTsmrTthLAv7J24642x7Iqk64+EIOu5hOybjCBzdG9w4oaSc3RhcnQg7J6s65Ox66GdIOyLnCDsnbTsoIQg7Lm07Jq07Yq46rCAIOyViCDrgqjqsowg7ZWc64ukLlxuICAgIHRoaXMucmVxdWVzdENvdW50cy5jbGVhcigpO1xuICAgIHRoaXMucnJJbmRleCA9IDA7XG4gIH1cblxuICAvLyDtmITsnqwg7ZKA7J2YIO2GoO2BsCDsiJgoc3RhcnR1cCDroZzqt7gvaGVhbHRoIOyaqSkuXG4gIGdldCB0b2tlbkNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5Qb29sLnNpemU7XG4gIH1cblxuICAvLyBEQiBhY3RpdmUgYW50aHJvcGljIO2GoO2BsCDrqqnroZ3snLzroZwg7ZKA7J2EIOyerOuPmeq4sO2ZlO2VnOuLpChwZXJpb2RpYyByZWNvbmNpbGUv7J6s7Jew6rKw7JqpKS5cbiAgLy8gTElTVEVOL05PVElGWSDqsIAg64GK6ri0IOuPmeyViCDsnKDsi6TrkJwg7LaU6rCAL+yCreygnC/ruYTtmZzshLHtmZTrpbwgREIg6riw7KSA7Jy866GcIOuLpOyLnCDrp57stpjri6QuXG4gIC8vIOydtOuypO2KuCDtlbjrk6Trn6zrpbwg7J6s7IKs7Jqp7ZW0IO2SgCDqsLHsi6DsnbQg7J286rSA65CY6rKMIOyggeyaqeuQmOuPhOuhnSDtlZzri6Q6XG4gIC8vICAtIERCIOyXkCDsl4bripTrjbAg7ZKA7JeQIOyeiOuKlCDthqDtgbAg4oaSIG9uVG9rZW5SZW1vdmVkXG4gIC8vICAtIERCIOyXkCDsnojripQg7Yag7YGwIOKGkiDsi6Dqt5zrqbQgb25Ub2tlbkFkZGVkLCDquLDsobTsnbTrqbQgb25Ub2tlblVwZGF0ZWRcbiAgcmVwbGFjZVRva2VucyhcbiAgICByb3dzOiBBcnJheTx7IGlkOiBudW1iZXI7IG5hbWU6IHN0cmluZzsgY3JlZGVudGlhbHM6IEFudGhyb3BpY0NyZWRlbnRpYWxzIH0+LFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gbmV3IFNldChyb3dzLm1hcCgocikgPT4gci5pZCkpO1xuICAgIC8vIG9uVG9rZW5SZW1vdmVkIOqwgCB0b2tlblBvb2wg7J2EIGRlbGV0ZSDtlZjrr4DroZwg7Iic7ZqMIOykkSDsiJjsoJXsnYQg7ZS87ZWY66CkIO2CpOulvCDrqLzsoIAg7Iqk64OF7IO37ZWc64ukLlxuICAgIGNvbnN0IGN1cnJlbnRJZHMgPSBBcnJheS5mcm9tKHRoaXMudG9rZW5Qb29sLmtleXMoKSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiBjdXJyZW50SWRzKSB7XG4gICAgICBpZiAoIW5leHQuaGFzKGlkKSkgdGhpcy5vblRva2VuUmVtb3ZlZChpZCk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgciBvZiByb3dzKSB7XG4gICAgICBpZiAodGhpcy50b2tlblBvb2wuaGFzKHIuaWQpKSB0aGlzLm9uVG9rZW5VcGRhdGVkKHIuaWQsIHIubmFtZSwgci5jcmVkZW50aWFscyk7XG4gICAgICBlbHNlIHRoaXMub25Ub2tlbkFkZGVkKHIuaWQsIHIubmFtZSwgci5jcmVkZW50aWFscyk7XG4gICAgfVxuICB9XG5cbiAgLy8gdG9rZW4gZXZlbnRzICh0b2tlbi1zdWJzY3JpYmVyIOqwgCDtmLjstpwpXG4gIG9uVG9rZW5BZGRlZChpZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGNyZWRlbnRpYWxzOiBBbnRocm9waWNDcmVkZW50aWFscyk6IHZvaWQge1xuICAgIHRoaXMudG9rZW5Qb29sLnNldChpZCwgeyBpZCwgbmFtZSwgY3JlZGVudGlhbHMgfSk7XG4gIH1cblxuICBvblRva2VuVXBkYXRlZChpZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGNyZWRlbnRpYWxzOiBBbnRocm9waWNDcmVkZW50aWFscyk6IHZvaWQge1xuICAgIHRoaXMudG9rZW5Qb29sLnNldChpZCwgeyBpZCwgbmFtZSwgY3JlZGVudGlhbHMgfSk7XG4gIH1cblxuICBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy50b2tlblBvb2wuZGVsZXRlKGlkKTtcbiAgICB0aGlzLnJlcXVlc3RDb3VudHMuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIHByaXZhdGUgY291bnRPZihpZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0Q291bnRzLmdldChpZCkgPz8gMDtcbiAgfVxuXG4gIC8vIOyalOyyreuniOuLpCBsZWFzdC11c2VkIFJSIOuhnCDthqDtgbDsnYQg6rOg66W464ukKOuPmeygkOydtOuptCByckluZGV4IOuhnCDtmozsoIQpLlxuICBwcml2YXRlIHNlbGVjdFRva2VuKCk6IFBvb2xlZFRva2VuIHwgbnVsbCB7XG4gICAgY29uc3Qgcm93cyA9IFsuLi50aGlzLnRva2VuUG9vbC52YWx1ZXMoKV07XG4gICAgaWYgKHJvd3MubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBtaW5Db3VudCA9IE1hdGgubWluKC4uLnJvd3MubWFwKChyKSA9PiB0aGlzLmNvdW50T2Yoci5pZCkpKTtcbiAgICBjb25zdCBpZGxlID0gcm93cy5maWx0ZXIoKHIpID0+IHRoaXMuY291bnRPZihyLmlkKSA9PT0gbWluQ291bnQpO1xuICAgIGNvbnN0IHBpY2tlZCA9IGlkbGVbdGhpcy5yckluZGV4ICUgaWRsZS5sZW5ndGhdITtcbiAgICB0aGlzLnJySW5kZXgrKztcbiAgICByZXR1cm4gdGhpcy5jaGFyZ2UocGlja2VkKTtcbiAgfVxuXG4gIC8vIOyEoO2DneuQnCDthqDtgbDsnZgg7IKs7JqpIOy5tOyatO2KuOulvCBhd2FpdCDsoITsl5Ag7ISg67CY7JiBKOuPmeyLnCDsmpTssq3snbQg64uk66W4IO2GoO2BsOydhCDqs6DrpbTrj4TroZ0pLlxuICBwcml2YXRlIGNoYXJnZSh0b2tlbjogUG9vbGVkVG9rZW4pOiBQb29sZWRUb2tlbiB7XG4gICAgdGhpcy5yZXF1ZXN0Q291bnRzLnNldCh0b2tlbi5pZCwgdGhpcy5jb3VudE9mKHRva2VuLmlkKSArIDEpO1xuICAgIHJldHVybiB0b2tlbjtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJ1bihyZXEsICgpID0+IHt9KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ydW4ocmVxLCBjYi5vbkRlbHRhLCB7IGluY2x1ZGVQYXJ0aWFsTWVzc2FnZXM6IHRydWUgfSk7XG4gICAgICBjYi5vblRocmVhZElkPy4ocmVzdWx0LnRocmVhZENvb3JkLnRocmVhZElkKTtcbiAgICAgIGNiLm9uQ29tcGxldGUocmVzdWx0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYi5vbkVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdlbmVyYXRlL2dlbmVyYXRlU3RyZWFtIOqzte2GtSDsi6TtlokuIG9uRGVsdGEg64qUIOyKpO2KuOumvOydtOuptCDsoJDsp4Qg67Cp7LacLCDruYTsiqTtirjrprzsnbTrqbQgbm8tb3AuXG4gIHByaXZhdGUgYXN5bmMgcnVuKFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIG9uRGVsdGE6ICh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICAgb3B0cz86IHsgaW5jbHVkZVBhcnRpYWxNZXNzYWdlcz86IGJvb2xlYW4gfSxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIC8vIG1vZGVsIOygleq3nO2ZlOulvCBkaXNwYXRjaGVyIOynhOyeheygkOyXkOyEnCDtlZwg67KIIO2VnOuLpDogcmVzdWx0Lm1vZGVsIC8gcnVuQ2xhdWRlU2Vzc2lvbiDsoITrtoBcbiAgICAvLyBjYW5vbmljYWwocHJlZml4IOyXhuuKlCBjb3N0IO2CpCkg7J2EIOyTsOqyjCDthrXsnbwuIOuvuOyngOygleydtOuptCBBTlRIUk9QSUNfREVGQVVMVF9NT0RFTCDigJQgcWdyaWQuZGlzcGF0Y2hlclxuICAgIC8vIOydmCBcInNvbm5ldFwiIOuzhOy5rSDsmrDtmowg7LCo64uoLiDsoJXqt5ztmZQg6rec7LmZ7J2AIGZhbGxiYWNrIOqyveuhnOyZgCDqs7XsnKAoY2Fub25pY2FsQW50aHJvcGljTW9kZWwpLlxuICAgIGFzc2VydFN1cHBvcnRlZE9uZU1pbGxpb25TdWZmaXgocmVxLm1vZGVsKTtcbiAgICBjb25zdCBtb2RlbCA9IGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKHJlcS5tb2RlbCk7XG4gICAgY29uc3QganNvblNjaGVtYSA9XG4gICAgICByZXEub3V0cHV0U2NoZW1hICE9PSB1bmRlZmluZWQgPyBKU09OLnN0cmluZ2lmeShyZXEub3V0cHV0U2NoZW1hKSA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHRva2VuID0gdGhpcy5zZWxlY3RUb2tlbigpO1xuICAgIGlmICghdG9rZW4pIHRocm93IG5ldyBFcnJvcihcIk5vIGFudGhyb3BpYyB0b2tlbnMgYXZhaWxhYmxlXCIpO1xuXG4gICAgY29uc3QgZXhlYyA9IGFzeW5jICgpOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiA9PiB7XG4gICAgICAvLyDrp4zro4wg7J6E67CVIO2GoO2BsCBwcmVlbXB0aXZlIHJlZnJlc2go6riw7KG0IHN0YW5kYWxvbmUg6rK966Gc7JmAIOuPmeydvCkuIOyLpO2MqO2VtOuPhCDsp4TtlokuXG4gICAgICBsZXQgYWNjZXNzVG9rZW4gPSB0b2tlbi5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbjtcbiAgICAgIGNvbnN0IGV4cGlyZXNBdCA9IGdldEV4cGlyZXNBdCh0b2tlbi5jcmVkZW50aWFscyk7XG4gICAgICBpZiAoXG4gICAgICAgIGV4cGlyZXNBdCAmJlxuICAgICAgICBleHBpcmVzQXQgLSBEYXRlLm5vdygpIDwgUkVGUkVTSF9TQUZFVFlfTVMgJiZcbiAgICAgICAgZ2V0UmVmcmVzaFRva2VuKHRva2VuLmNyZWRlbnRpYWxzKVxuICAgICAgKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBRZ3JpZEZyYW1lIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC5mcmFtZVwiKTtcbiAgICAgICAgICAvLyBwcm92aWRlciDrpbwg67CY65Oc7IucIOyxhOybjOyVvCByZWZyZXNoVG9rZW4g64K067aAIFRva2VuTW9kZWwuc2F2ZSDqsIAg7ISx6rO17ZWc64ukLlxuICAgICAgICAgIC8vIHJlZnJlc2hUb2tlbihUb2tlblN1YnNldEEpIOuKlCBpZC9wcm92aWRlci9jcmVkZW50aWFscy9uYW1lIOunjCDsgqzsmqntlZjrr4DroZwg6re4IDTqsJzrp4wg64SY6ri064ukLlxuICAgICAgICAgIGFjY2Vzc1Rva2VuID0gYXdhaXQgUWdyaWRGcmFtZS5yZWZyZXNoVG9rZW4oe1xuICAgICAgICAgICAgaWQ6IHRva2VuLmlkLFxuICAgICAgICAgICAgcHJvdmlkZXI6IFwiYW50aHJvcGljXCIsXG4gICAgICAgICAgICBuYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHRva2VuLmNyZWRlbnRpYWxzLFxuICAgICAgICAgIH0gYXMgUGFyYW1ldGVyczx0eXBlb2YgUWdyaWRGcmFtZS5yZWZyZXNoVG9rZW4+WzBdKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZ2dlci53YXJuKGByZWZyZXNoIGZhaWxlZCBmb3IgJHt0b2tlbi5uYW1lfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2dnZXIuaW5mbyhg4oaSICR7dG9rZW4ubmFtZX0gKG1vZGVsOiAke21vZGVsfSlgKTtcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCBydW5DbGF1ZGVTZXNzaW9uKFxuICAgICAgICB7XG4gICAgICAgICAgdG9rZW5JZDogdG9rZW4uaWQsXG4gICAgICAgICAgdG9rZW46IGFjY2Vzc1Rva2VuLFxuICAgICAgICAgIG1vZGVsLFxuICAgICAgICAgIHN5c3RlbTogcmVxLnN5c3RlbVByb21wdCxcbiAgICAgICAgICBqc29uU2NoZW1hLFxuICAgICAgICAgIGVmZm9ydDogcmVxLmVmZm9ydCxcbiAgICAgICAgICB0aW1lb3V0TXM6IERFRkFVTFRfVElNRU9VVF9NUyxcbiAgICAgICAgICBjb2xkSGlzdG9yeTogcmVxLmNvbGRIaXN0b3J5LFxuICAgICAgICAgIGlucHV0OiByZXEuY29sZElucHV0LFxuICAgICAgICAgIGFib3J0U2lnbmFsOiByZXEuYWJvcnRTaWduYWwsXG4gICAgICAgICAgaW5jbHVkZVBhcnRpYWxNZXNzYWdlczogb3B0cz8uaW5jbHVkZVBhcnRpYWxNZXNzYWdlcyxcbiAgICAgICAgfSxcbiAgICAgICAgb25EZWx0YSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChzZXNzaW9uLnF1b3RhRXhoYXVzdGVkKSB0aHJvdyBuZXcgRXJyb3IoYHF1b3RhIGV4aGF1c3RlZCAoJHt0b2tlbi5uYW1lfSlgKTtcbiAgICAgIGlmIChzZXNzaW9uLmlzRXJyb3IpIHtcbiAgICAgICAgLy8gdGV4dCDqsIAg67mE7Ja0IOyeiOydhCDsiJgg7J6I7Jy866+A66GcIOynhOuLqCDqsIDriqXtlZwg7ZiV7YOc66GcIOuplOyLnOyngOulvCDrp4zrk6Dri6Qoc3VidHlwZSDrk7HsnYAgcmF3IOuhnOq3uCDssLjsobApLlxuICAgICAgICBjb25zdCBkZXRhaWwgPSBzZXNzaW9uLnRleHQgfHwgYGVtcHR5IHRleHQsIG91dHB1dFRva2Vucz0ke3Nlc3Npb24udXNhZ2Uub3V0cHV0VG9rZW5zfWA7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY2xhdWRlIGVycm9yICgke3Rva2VuLm5hbWV9KTogJHtkZXRhaWx9YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHNlc3Npb24udGV4dCxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICB1c2FnZTogc2Vzc2lvbi51c2FnZSxcbiAgICAgICAgZHVyYXRpb25Nczogc2Vzc2lvbi5kdXJhdGlvbk1zLFxuICAgICAgICBjb3N0VXNkOiBzZXNzaW9uLmNvc3RVc2QsXG4gICAgICAgIG1vZGVsLFxuICAgICAgICAvLyBzeXN0ZW1IYXNoIOuKlCDsg4HsnIQgaXNzdWVDb252Q29udGV4dCDqsIAg7LGE7Jq064ukKOyXrOq4sOyEoCDruYTsmrTri6QpLlxuICAgICAgICB0aHJlYWRDb29yZDoge1xuICAgICAgICAgIHdvcmtlcklkOiBtYWtlQW50aHJvcGljV29ya2VySWQodG9rZW4uaWQpLFxuICAgICAgICAgIHRocmVhZElkOiBzZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICBlcG9jaDogMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfTtcblxu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
|
|
@@ -1,35 +1,25 @@
|
|
|
1
1
|
import "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { ANTHROPIC_CLAUDE_CWD, ANTHROPIC_DISALLOWED_TOOLS, anthropicConfigDir, canonicalAnthropicModel } from "./anthropic-constants.js";
|
|
2
|
+
import { ANTHROPIC_CLAUDE_CWD, ANTHROPIC_DISALLOWED_TOOLS, anthropicConfigDir, assertSupportedOneMillionSuffix, canonicalAnthropicModel, needsCli1mSuffix, supports1MContext } from "./anthropic-constants.js";
|
|
3
3
|
import { buildStreamJsonInput, handleStreamJsonLine } from "./stream-json-adapter.js";
|
|
4
|
-
import {
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
7
7
|
//#region src/utils/providers/anthropic/claude-session.ts
|
|
8
8
|
/**
|
|
9
9
|
* claude-session — Claude CLI 세션 spawn + QgridThreadCoord 매핑 + per-session 락.
|
|
10
10
|
*
|
|
11
|
-
* 멀티턴:
|
|
12
|
-
*
|
|
11
|
+
* 멀티턴: 매 호출 fresh `--session-id <uuid>`로 실행한다. 입력은 어댑터가 만든 JSONL 을
|
|
12
|
+
* stdin 으로 흘리고(`--input-format stream-json`), 출력은 파서로 처리한다.
|
|
13
13
|
*
|
|
14
14
|
* 핵심 계약:
|
|
15
15
|
* - coord 는 임의 저장이 아니라 기존 QgridThreadCoord{workerId,threadId,epoch,systemHash} 에
|
|
16
16
|
* 매핑한다. threadId=세션 uuid, epoch=0 고정(worker restart 개념 없음), workerId=token 기반
|
|
17
17
|
* 안정 합성, systemHash=요청 system 해시. issueConvContext/decideConvRouting 과 round-trip.
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
20
|
-
* - 같은 세션의 동시 turn 은 per-session 락(session-id 단위 직렬화)으로 transcript 오염 방지.
|
|
18
|
+
* - withSessionLock 은 exported primitive 로 유지한다. 기본 경로에서는 매 호출 새 session-id 라
|
|
19
|
+
* 사실상 no-contention 이지만, 직접 호출자/테스트의 직렬화 보장은 보존한다.
|
|
21
20
|
* - stream-json 직렬화 시 SDK envelope(uuid/session_id/parent_tool_use_id) decorate.
|
|
22
21
|
* - structured output 일 때 출력 파서에 { structuredOutput: true } 전달(없으면 streamObject 깨짐).
|
|
23
|
-
*
|
|
24
|
-
* ⚠️ 첫 호출 동시성: resume 가 아닌 "첫 호출"은 여기서 새 랜덤 session-id 를 발급하므로, 같은
|
|
25
|
-
* qgrid sessionKey 에 대한 두 동시 첫 호출은 서로 다른 id 로 둘 다 실행된다. 현재 IF/owner scope 는
|
|
26
|
-
* LLM 호출을 순차 실행하고 sessionKey 를 서버로 보내지 않으므로, dispatcher 는 cold 락을 두지 않는다.
|
|
27
|
-
* 병렬 첫 호출을 서버가 지원하게 되면 sessionKey 전달/락 설계부터 다시 잡아야 한다.
|
|
28
22
|
*/
|
|
29
|
-
function compatibilityKey(opts) {
|
|
30
|
-
const schemaPart = opts.outputSchema && opts.outputSchema.length > 0 ? opts.outputSchema : "text";
|
|
31
|
-
return createHash("sha256").update(`${opts.system ?? ""}\0${opts.model}\0${schemaPart}`).digest("hex").slice(0, 16);
|
|
32
|
-
}
|
|
33
23
|
const sessionChains = /* @__PURE__ */ new Map();
|
|
34
24
|
async function withSessionLock(sessionId, fn) {
|
|
35
25
|
const next = (sessionChains.get(sessionId) ?? Promise.resolve()).then(fn, fn);
|
|
@@ -66,6 +56,13 @@ function ensureCwd() {
|
|
|
66
56
|
writeFileSync(`${ANTHROPIC_CLAUDE_CWD}/.claude/settings.json`, "{}");
|
|
67
57
|
cwdEnsured = true;
|
|
68
58
|
}
|
|
59
|
+
function applyOneMillionSuffix(model, needsSuffix) {
|
|
60
|
+
const base = canonicalAnthropicModel(model);
|
|
61
|
+
return needsSuffix ? `${base}[1m]` : base;
|
|
62
|
+
}
|
|
63
|
+
function oneMillionEnv(supported) {
|
|
64
|
+
return supported ? {} : { CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" };
|
|
65
|
+
}
|
|
69
66
|
function buildClaudeArgs(opts) {
|
|
70
67
|
const useStructured = Boolean(opts.jsonSchema && opts.jsonSchema.length > 0);
|
|
71
68
|
const args = [
|
|
@@ -83,22 +80,22 @@ function buildClaudeArgs(opts) {
|
|
|
83
80
|
"--output-format",
|
|
84
81
|
"stream-json",
|
|
85
82
|
"--verbose",
|
|
86
|
-
"--
|
|
87
|
-
useStructured ? "2" : "1",
|
|
83
|
+
...opts.includePartialMessages ? ["--include-partial-messages"] : [],
|
|
88
84
|
"--permission-mode",
|
|
89
85
|
"bypassPermissions",
|
|
90
86
|
"--setting-sources",
|
|
91
87
|
"project",
|
|
92
88
|
"--model",
|
|
93
|
-
opts.model,
|
|
89
|
+
applyOneMillionSuffix(opts.model, opts.needsOneMillionSuffix ?? false),
|
|
94
90
|
"--system-prompt",
|
|
95
91
|
opts.system ?? "",
|
|
96
92
|
"--thinking",
|
|
97
93
|
"disabled",
|
|
98
94
|
"--effort",
|
|
99
|
-
opts.effort ?? "
|
|
95
|
+
opts.effort ?? "low",
|
|
100
96
|
"--disable-slash-commands",
|
|
101
|
-
|
|
97
|
+
"--session-id",
|
|
98
|
+
opts.sessionId
|
|
102
99
|
];
|
|
103
100
|
if (useStructured) args.push("--json-schema", opts.jsonSchema);
|
|
104
101
|
return args;
|
|
@@ -108,9 +105,11 @@ function buildClaudeArgs(opts) {
|
|
|
108
105
|
* @param onDelta 점진 텍스트 delta(streamText) 또는 structured 부분 JSON(streamObject).
|
|
109
106
|
*/
|
|
110
107
|
function runClaudeSession(req, onDelta) {
|
|
108
|
+
assertSupportedOneMillionSuffix(req.model);
|
|
111
109
|
const model = canonicalAnthropicModel(req.model);
|
|
112
|
-
const
|
|
113
|
-
const
|
|
110
|
+
const supportsOneMillion = supports1MContext(model);
|
|
111
|
+
const needsOneMillionSuffix = needsCli1mSuffix(model);
|
|
112
|
+
const sessionId = randomUUID();
|
|
114
113
|
const useStructured = Boolean(req.jsonSchema && req.jsonSchema.length > 0);
|
|
115
114
|
const workerId = makeAnthropicWorkerId(req.tokenId);
|
|
116
115
|
return withSessionLock(sessionId, () => {
|
|
@@ -122,14 +121,18 @@ function runClaudeSession(req, onDelta) {
|
|
|
122
121
|
effort: req.effort,
|
|
123
122
|
jsonSchema: req.jsonSchema,
|
|
124
123
|
sessionId,
|
|
125
|
-
|
|
124
|
+
needsOneMillionSuffix,
|
|
125
|
+
includePartialMessages: req.includePartialMessages
|
|
126
126
|
});
|
|
127
127
|
const stdinPayload = decorateAndSerialize(buildStreamJsonInput({
|
|
128
128
|
coldHistory: req.coldHistory,
|
|
129
|
-
input: req.input
|
|
130
|
-
isResume
|
|
129
|
+
input: req.input
|
|
131
130
|
}), sessionId);
|
|
132
131
|
return new Promise((resolve, reject) => {
|
|
132
|
+
if (req.abortSignal?.aborted) {
|
|
133
|
+
reject(/* @__PURE__ */ new Error("aborted"));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
133
136
|
const child = spawn("claude", args, {
|
|
134
137
|
stdio: [
|
|
135
138
|
"pipe",
|
|
@@ -144,9 +147,13 @@ function runClaudeSession(req, onDelta) {
|
|
|
144
147
|
CLAUDE_CONFIG_DIR: configDir,
|
|
145
148
|
CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1",
|
|
146
149
|
CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING: "1",
|
|
147
|
-
|
|
150
|
+
...oneMillionEnv(supportsOneMillion),
|
|
148
151
|
CLAUDE_CODE_DISABLE_CLAUDE_MDS: "1",
|
|
149
|
-
|
|
152
|
+
CLAUDE_CODE_DISABLE_TERMINAL_TITLE: "1",
|
|
153
|
+
CLAUDE_CODE_DISABLE_BUNDLED_SKILLS: "1",
|
|
154
|
+
CLAUDE_CODE_DISABLE_WORKFLOWS: "1",
|
|
155
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: "0",
|
|
156
|
+
MAX_THINKING_TOKENS: "0"
|
|
150
157
|
}
|
|
151
158
|
});
|
|
152
159
|
let settled = false;
|
|
@@ -158,9 +165,11 @@ function runClaudeSession(req, onDelta) {
|
|
|
158
165
|
stderrBuf = (stderrBuf + d.toString()).slice(-STDERR_CAP);
|
|
159
166
|
});
|
|
160
167
|
const stderrSuffix = () => stderrBuf.trim() ? ` — stderr: ${stderrBuf.trim()}` : "";
|
|
168
|
+
let cleanupAbort;
|
|
161
169
|
const timer = setTimeout(() => {
|
|
162
170
|
if (settled) return;
|
|
163
171
|
settled = true;
|
|
172
|
+
cleanupAbort?.();
|
|
164
173
|
child.kill();
|
|
165
174
|
reject(/* @__PURE__ */ new Error(`Claude session timeout after ${req.timeoutMs / 1e3}s`));
|
|
166
175
|
}, req.timeoutMs);
|
|
@@ -168,19 +177,23 @@ function runClaudeSession(req, onDelta) {
|
|
|
168
177
|
if (settled) return;
|
|
169
178
|
settled = true;
|
|
170
179
|
clearTimeout(timer);
|
|
180
|
+
cleanupAbort?.();
|
|
171
181
|
resolve({
|
|
172
182
|
...result,
|
|
173
183
|
sessionId,
|
|
174
184
|
workerId
|
|
175
185
|
});
|
|
176
186
|
};
|
|
177
|
-
|
|
187
|
+
const onAbort = () => {
|
|
178
188
|
if (settled) return;
|
|
179
189
|
settled = true;
|
|
180
190
|
clearTimeout(timer);
|
|
191
|
+
cleanupAbort?.();
|
|
181
192
|
child.kill();
|
|
182
193
|
reject(/* @__PURE__ */ new Error("aborted"));
|
|
183
|
-
}
|
|
194
|
+
};
|
|
195
|
+
cleanupAbort = () => req.abortSignal?.removeEventListener("abort", onAbort);
|
|
196
|
+
req.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
184
197
|
child.stdout?.on("data", (d) => {
|
|
185
198
|
if (settled) return;
|
|
186
199
|
buffer += d.toString();
|
|
@@ -201,12 +214,14 @@ function runClaudeSession(req, onDelta) {
|
|
|
201
214
|
if (settled) return;
|
|
202
215
|
settled = true;
|
|
203
216
|
clearTimeout(timer);
|
|
217
|
+
cleanupAbort?.();
|
|
204
218
|
reject(/* @__PURE__ */ new Error(`Claude session closed without result${stderrSuffix()}`));
|
|
205
219
|
});
|
|
206
220
|
child.on("error", (err) => {
|
|
207
221
|
if (settled) return;
|
|
208
222
|
settled = true;
|
|
209
223
|
clearTimeout(timer);
|
|
224
|
+
cleanupAbort?.();
|
|
210
225
|
reject(/* @__PURE__ */ new Error(`Claude session spawn error: ${err.message}`));
|
|
211
226
|
});
|
|
212
227
|
child.stdin?.write(stdinPayload);
|
|
@@ -215,6 +230,6 @@ function runClaudeSession(req, onDelta) {
|
|
|
215
230
|
});
|
|
216
231
|
}
|
|
217
232
|
//#endregion
|
|
218
|
-
export {
|
|
233
|
+
export { applyOneMillionSuffix, buildClaudeArgs, decorateAndSerialize, ensureConfigDir, makeAnthropicWorkerId, oneMillionEnv, runClaudeSession, withSessionLock };
|
|
219
234
|
|
|
220
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhdWRlLXNlc3Npb24uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvY2xhdWRlLXNlc3Npb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBjbGF1ZGUtc2Vzc2lvbiDigJQgQ2xhdWRlIENMSSDshLjshZggc3Bhd24gKyBRZ3JpZFRocmVhZENvb3JkIOunpO2VkSArIHBlci1zZXNzaW9uIOudvS5cbiAqXG4gKiDrqYDti7DthLQ6IOyyqyDtmLjstpwgYC0tc2Vzc2lvbi1pZCA8dXVpZD5gLCDtm4Tsho0gYC0tcmVzdW1lIDx1dWlkPmAuIOyeheugpeydgCBVMiDslrTrjJHthLDqsIAg66eM65OgXG4gKiBKU09OTCDsnYQgc3RkaW4g7Jy866GcIO2dmOumrOqzoChgLS1pbnB1dC1mb3JtYXQgc3RyZWFtLWpzb25gKSwg7Lac66Cl7J2AIFUzIO2MjOyEnOuhnCDsspjrpqztlZzri6QuXG4gKlxuICog7ZW17IusIOqzhOyVvTpcbiAqICAtIGNvb3JkIOuKlCDsnoTsnZgg7KCA7J6l7J20IOyVhOuLiOudvCDquLDsobQgUWdyaWRUaHJlYWRDb29yZHt3b3JrZXJJZCx0aHJlYWRJZCxlcG9jaCxzeXN0ZW1IYXNofSDsl5BcbiAqICAgIOunpO2Vke2VnOuLpC4gdGhyZWFkSWQ97IS47IWYIHV1aWQsIGVwb2NoPTAg6rOg7KCVKHdvcmtlciByZXN0YXJ0IOqwnOuFkCDsl4bsnYwpLCB3b3JrZXJJZD10b2tlbiDquLDrsJhcbiAqICAgIOyViOyglSDtlanshLEsIHN5c3RlbUhhc2g97JqU7LKtIHN5c3RlbSDtlbTsi5wuIGlzc3VlQ29udkNvbnRleHQvZGVjaWRlQ29udlJvdXRpbmcg6rO8IHJvdW5kLXRyaXAuXG4gKiAgLSByZXN1bWUgZWxpZ2liaWxpdHkg64qUIHN5c3RlbUhhc2gg66eM7Jy866GcIOu2gOyhsSDihpIg7ZmV7J6lIO2YuO2ZmO2CpChzeXN0ZW0rbW9kZWwrc3RydWN0dXJlZCDrqqjrk5wp66GcXG4gKiAgICDtjJDsoJUuIOu2iOydvOy5mOuptCBjb2xkIGZhbGxiYWNrLlxuICogIC0g6rCZ7J2AIOyEuOyFmOydmCDrj5nsi5wgdHVybiDsnYAgcGVyLXNlc3Npb24g6529KHNlc3Npb24taWQg64uo7JyEIOyngeugrO2ZlCnsnLzroZwgdHJhbnNjcmlwdCDsmKTsl7wg67Cp7KeALlxuICogIC0gc3RyZWFtLWpzb24g7KeB66Cs7ZmUIOyLnCBTREsgZW52ZWxvcGUodXVpZC9zZXNzaW9uX2lkL3BhcmVudF90b29sX3VzZV9pZCkgZGVjb3JhdGUuXG4gKiAgLSBzdHJ1Y3R1cmVkIG91dHB1dCDsnbwg65WMIOy2nOugpSDtjIzshJzsl5AgeyBzdHJ1Y3R1cmVkT3V0cHV0OiB0cnVlIH0g7KCE64usKOyXhuycvOuptCBzdHJlYW1PYmplY3Qg6rmo7KeQKS5cbiAqXG4gKiDimqDvuI8g7LKrIO2YuOy2nCDrj5nsi5zshLE6IHJlc3VtZSDqsIAg7JWE64uMIFwi7LKrIO2YuOy2nFwi7J2AIOyXrOq4sOyEnCDsg4gg656c642kIHNlc3Npb24taWQg66W8IOuwnOq4ie2VmOuvgOuhnCwg6rCZ7J2AXG4gKiAgICBxZ3JpZCBzZXNzaW9uS2V5IOyXkCDrjIDtlZwg65GQIOuPmeyLnCDssqsg7Zi47Lac7J2AIOyEnOuhnCDri6TrpbggaWQg66GcIOuRmCDri6Qg7Iuk7ZaJ65Cc64ukLiDtmITsnqwgSUYvb3duZXIgc2NvcGUg64qUXG4gKiAgICBMTE0g7Zi47Lac7J2EIOyInOywqCDsi6TtlontlZjqs6Agc2Vzc2lvbktleSDrpbwg7ISc67KE66GcIOuztOuCtOyngCDslYrsnLzrr4DroZwsIGRpc3BhdGNoZXIg64qUIGNvbGQg65297J2EIOuRkOyngCDslYrripTri6QuXG4gKiAgICDrs5HroKwg7LKrIO2YuOy2nOydhCDshJzrsoTqsIAg7KeA7JuQ7ZWY6rKMIOuQmOuptCBzZXNzaW9uS2V5IOyghOuLrC/rnb0g7ISk6rOE67aA7YSwIOuLpOyLnCDsnqHslYTslbwg7ZWc64ukLlxuICovXG5cbmltcG9ydCB7IHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tVVVJRCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgbWtkaXJTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcblxuaW1wb3J0IHsgdHlwZSBKc29uVmFsdWUgfSBmcm9tIFwiLi4vLi4vLi4vY29kZXgtcHJvdG9jb2wvc2VyZGVfanNvbi9Kc29uVmFsdWVcIjtcbmltcG9ydCB7IHR5cGUgVG9rZW5Vc2FnZUJyZWFrZG93biB9IGZyb20gXCIuLi8uLi8uLi9jb2RleC1wcm90b2NvbC92Mi9Ub2tlblVzYWdlQnJlYWtkb3duXCI7XG5pbXBvcnQgeyB0eXBlIFVzZXJJbnB1dCB9IGZyb20gXCIuLi8uLi8uLi9jb2RleC1wcm90b2NvbC92Mi9Vc2VySW5wdXRcIjtcbmltcG9ydCB7XG4gIEFOVEhST1BJQ19DTEFVREVfQ1dELFxuICBhbnRocm9waWNDb25maWdEaXIsXG4gIEFOVEhST1BJQ19ERUZBVUxUX0VGRk9SVCxcbiAgQU5USFJPUElDX0RJU0FMTE9XRURfVE9PTFMsXG4gIGNhbm9uaWNhbEFudGhyb3BpY01vZGVsLFxufSBmcm9tIFwiLi9hbnRocm9waWMtY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBidWlsZFN0cmVhbUpzb25JbnB1dCxcbiAgdHlwZSBDbGF1ZGVTdHJlYW1Kc29uU3RhdGUsXG4gIHR5cGUgQ2xhdWRlU3RyZWFtSnNvbkxpbmUsXG4gIHR5cGUgQ2xhdWRlU3RyZWFtUmVzdWx0LFxuICBoYW5kbGVTdHJlYW1Kc29uTGluZSxcbn0gZnJvbSBcIi4vc3RyZWFtLWpzb24tYWRhcHRlclwiO1xuXG4vLyDilIDilIAg7Zi47ZmY7YKkIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vLyByZXN1bWUg6rCA64qlIOyXrOu2gOulvCDqsIDrpbTripQg7YKkLiBzeXN0ZW1IYXNoIOunjOycvOuhnOuKlCDqsJnsnYAgc2Vzc2lvbktleSDrpbwg64uk66W4IG1vZGVsL3NjaGVtYSDroZxcbi8vIOyerOyCrOyaqe2VoCDrlYwgY29udGV4dCDsmKTsl7wg4oaSIHN5c3RlbSArIG1vZGVsICsgc3RydWN0dXJlZCDrqqjrk5zquYzsp4Ag66y264qU64ukLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhdGliaWxpdHlLZXkob3B0czoge1xuICBzeXN0ZW0/OiBzdHJpbmc7XG4gIG1vZGVsOiBzdHJpbmc7XG4gIC8vIHN0cnVjdHVyZWQgb3V0cHV0IHNjaGVtYSDrrLjsnpDsl7QuIOyXhuycvOuptCB0ZXh0IOuqqOuTnC4g64K07Jqp7J20IOuLpOultOuptCDri6Trpbgg7YKkLlxuICBvdXRwdXRTY2hlbWE/OiBzdHJpbmc7XG59KTogc3RyaW5nIHtcbiAgY29uc3Qgc2NoZW1hUGFydCA9IG9wdHMub3V0cHV0U2NoZW1hICYmIG9wdHMub3V0cHV0U2NoZW1hLmxlbmd0aCA+IDAgPyBvcHRzLm91dHB1dFNjaGVtYSA6IFwidGV4dFwiO1xuICByZXR1cm4gY3JlYXRlSGFzaChcInNoYTI1NlwiKVxuICAgIC51cGRhdGUoYCR7b3B0cy5zeXN0ZW0gPz8gXCJcIn1cXDAke29wdHMubW9kZWx9XFwwJHtzY2hlbWFQYXJ0fWApXG4gICAgLmRpZ2VzdChcImhleFwiKVxuICAgIC5zbGljZSgwLCAxNik7XG59XG5cbi8vIOKUgOKUgCBwZXItc2Vzc2lvbiDrnb0g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8vIHNlc3Npb24taWQg64uo7JyEIOyngeugrO2ZlC4g6rCZ7J2AIOyEuOyFmOydmCDrj5nsi5wgdHVybiDsnbQg6rCZ7J2AIHRyYW5zY3JpcHQg7JeQIOuPmeyLnCByZXN1bWXCt2FwcGVuZCDtlZjripQg6rKDIOuwqeyngC5cbmNvbnN0IHNlc3Npb25DaGFpbnMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx1bmtub3duPj4oKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhTZXNzaW9uTG9jazxUPihzZXNzaW9uSWQ6IHN0cmluZywgZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgcHJldiA9IHNlc3Npb25DaGFpbnMuZ2V0KHNlc3Npb25JZCkgPz8gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIC8vIOydtOyghCB0dXJuIOydmCDshLHtjKjsmYAg66y06rSA7ZWY6rKMIOyngeugrCDssrTsnbjsnYQg7J6H64qU64ukLlxuICBjb25zdCBuZXh0ID0gcHJldi50aGVuKGZuLCBmbik7XG4gIC8vIHRhaWw6IOyEse2MqCDrrLTqtIAgc2V0dGxlIOuQmOuKlCDtlbjrk6QuIOydtOqxuCDrp7Xsl5Ag65GQ6rOgLCBmaW5hbGx5IOyXkOyEnCBcIuyXrOyghO2eiCDrgrTqsIAg64GdXCLsnbwg65WM66eMIOyCreygnC5cbiAgLy8gKHNldCDsp4Htm4QgdW5kZWZpbmVkIOqygOyCrOuhnCDtlZjrqbQg7KCI64yAIOyCreygnCDslYgg64+8IOyEuOyFmCBpZCDqsIAg64iE7IiY65CoIOKAlCB0YWlsIOydvOy5mCDqsoDsgqzroZwg7ZqM7ZS8LilcbiAgY29uc3QgdGFpbCA9IG5leHQudGhlbihcbiAgICAoKSA9PiB7fSxcbiAgICAoKSA9PiB7fSxcbiAgKTtcbiAgc2Vzc2lvbkNoYWlucy5zZXQoc2Vzc2lvbklkLCB0YWlsKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgbmV4dDtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyDqt7gg7IKs7J20IOuLpOuluCB0dXJuIOydtCDssrTsnbjsnYQg7J207Ja067Cb7JWY7Jy866m0IHRhaWwg7J20IOq1kOyytOuPvCDsnojri6Qg4oCUIOq3uOuVjOuKlCDsgq3soJztlZjsp4Ag7JWK64qU64ukLlxuICAgIGlmIChzZXNzaW9uQ2hhaW5zLmdldChzZXNzaW9uSWQpID09PSB0YWlsKSBzZXNzaW9uQ2hhaW5zLmRlbGV0ZShzZXNzaW9uSWQpO1xuICB9XG59XG5cbi8vIOKUgOKUgCBjb29yZCDrp6TtlZEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8vIHRva2VuIOq4sOuwmCDslYjsoJUgd29ya2VySWQg7ZWp7ISxLiBBbnRocm9waWMg7J2AIHdvcmtlciBwb29sIOydtCDsl4bsnLzrr4DroZwgdG9rZW5JZCDrpbwg6re464yA66GcIOyTtOuLpC5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlQW50aHJvcGljV29ya2VySWQodG9rZW5JZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHRva2VuSWQ7XG59XG5cbi8vIOKUgOKUgCBlbnZlbG9wZSBkZWNvcmF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLy8gc3RyZWFtLWpzb24g7J6F66ClIOudvOyduOyXkCBTREsgZW52ZWxvcGUg67aA7LCpIO2bhCDsp4HroKztmZQuIHNlc3Npb24g7IaM7Jyg7J6Q7J24IOyXrOq4sOyEnCDtlZzri6QuXG5leHBvcnQgZnVuY3Rpb24gZGVjb3JhdGVBbmRTZXJpYWxpemUobGluZXM6IEFycmF5PENsYXVkZVN0cmVhbUpzb25MaW5lPiwgc2Vzc2lvbklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gKFxuICAgIGxpbmVzXG4gICAgICAubWFwKChsaW5lKSA9PlxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgLi4ubGluZSxcbiAgICAgICAgICBzZXNzaW9uX2lkOiBzZXNzaW9uSWQsXG4gICAgICAgICAgdXVpZDogcmFuZG9tVVVJRCgpLFxuICAgICAgICAgIHBhcmVudF90b29sX3VzZV9pZDogbnVsbCxcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuam9pbihcIlxcblwiKSArIFwiXFxuXCJcbiAgKTtcbn1cblxuLy8g4pSA4pSAIHNwYXduICsgY29uc3VtZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZXhwb3J0IGludGVyZmFjZSBDbGF1ZGVTZXNzaW9uUmVxdWVzdCB7XG4gIHRva2VuSWQ6IG51bWJlcjtcbiAgdG9rZW46IHN0cmluZzsgLy8gT0F1dGggYWNjZXNzIHRva2VuXG4gIG1vZGVsOiBzdHJpbmc7XG4gIHN5c3RlbT86IHN0cmluZztcbiAganNvblNjaGVtYT86IHN0cmluZzsgLy8g7J6I7Jy866m0IHN0cnVjdHVyZWQgb3V0cHV0XG4gIGVmZm9ydD86IHN0cmluZztcbiAgdGltZW91dE1zOiBudW1iZXI7XG4gIC8vIOyeheugpTogY29sZChjb2xkSGlzdG9yeStjb2xkSW5wdXQpIOuYkOuKlCByZXN1bWUocmV1c2VJbnB1dCkuXG4gIGNvbGRIaXN0b3J5PzogQXJyYXk8SnNvblZhbHVlPjtcbiAgaW5wdXQ6IEFycmF5PFVzZXJJbnB1dD47XG4gIC8vIHJlc3VtZSDqsr3roZzrqbQg6riw7KG0IHNlc3Npb24taWQsIGNvbGQg66m0IHVuZGVmaW5lZCjsg4jroZwg67Cc6riJKS5cbiAgcmVzdW1lU2Vzc2lvbklkPzogc3RyaW5nO1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENsYXVkZVNlc3Npb25SZXN1bHQgZXh0ZW5kcyBDbGF1ZGVTdHJlYW1SZXN1bHQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgd29ya2VySWQ6IG51bWJlcjtcbn1cblxuLy8gcGVyLXRva2VuIENMQVVERV9DT05GSUdfRElSIOuztOyepSjqsqnrpqwpLiDqsr3roZwg6rec7LmZ7J2AIGFudGhyb3BpY0NvbmZpZ0RpcijsiJzsiJgg7ZWo7IiYKeydtCDshozsnKAg4oCUXG4vLyDsl6zquLDshKAg6re4IOqyveuhnOyXkCDruYggc2V0dGluZ3Mg66W8IOq5lOyVhCBjbGF1ZGUtbWVtIGhvb2sg65Ox7J2EIOywqOuLqO2VnOuLpC4gKFIxMCDqsqnrpqwpXG4vLyDsnbQgc2VlZCDtjIzsnbzsnYAgY2xhdWRlLW1lbSBob29rIC8g7IKs7Jqp7J6QIOyEpOyglSDsmKTsl7wg7LCo64uo7J2EIOychO2VnCDqsqnrpqwg6rK96rOE64ukLiDrp6Qg7Zi47Lac66eI64ukIOuLpOyLnCDsjajshJxcbi8vIOyZuOu2gCDrs4DsobDCt+yCreygnCDtm4Tsl5Drj4Qg64uk7J2MIOyLpO2WieyXkOyEnCBzZWxmLWhlYWxpbmcg65CY64+E66GdIOq4sOyhtCBzZW1hbnRpY3Mg66W8IOycoOyngO2VnOuLpC5cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVDb25maWdEaXIodG9rZW5JZDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZGlyID0gYW50aHJvcGljQ29uZmlnRGlyKHRva2VuSWQpO1xuICBta2RpclN5bmMoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgd3JpdGVGaWxlU3luYyhgJHtkaXJ9Ly5jbGF1ZGUuanNvbmAsIFwie31cIik7XG4gIHdyaXRlRmlsZVN5bmMoYCR7ZGlyfS9zZXR0aW5ncy5qc29uYCwgXCJ7fVwiKTtcbiAgcmV0dXJuIGRpcjtcbn1cblxubGV0IGN3ZEVuc3VyZWQgPSBmYWxzZTtcbmZ1bmN0aW9uIGVuc3VyZUN3ZCgpOiB2b2lkIHtcbiAgaWYgKGN3ZEVuc3VyZWQpIHJldHVybjtcbiAgbWtkaXJTeW5jKGAke0FOVEhST1BJQ19DTEFVREVfQ1dEfS8uY2xhdWRlYCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHdyaXRlRmlsZVN5bmMoYCR7QU5USFJPUElDX0NMQVVERV9DV0R9Ly5jbGF1ZGUvc2V0dGluZ3MuanNvbmAsIFwie31cIik7XG4gIGN3ZEVuc3VyZWQgPSB0cnVlO1xufVxuXG4vLyBzcGF3biBhcmdzIOq1rOyEsS4g66mA7Yuw7YS0L+qyqeumrC9zdHJ1Y3R1cmVkIOuqqOuTnCDrsJjsmIEuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDbGF1ZGVBcmdzKG9wdHM6IHtcbiAgbW9kZWw6IHN0cmluZztcbiAgc3lzdGVtPzogc3RyaW5nO1xuICBlZmZvcnQ/OiBzdHJpbmc7XG4gIGpzb25TY2hlbWE/OiBzdHJpbmc7XG4gIHNlc3Npb25JZDogc3RyaW5nO1xuICBpc1Jlc3VtZTogYm9vbGVhbjtcbn0pOiBBcnJheTxzdHJpbmc+IHtcbiAgY29uc3QgdXNlU3RydWN0dXJlZCA9IEJvb2xlYW4ob3B0cy5qc29uU2NoZW1hICYmIG9wdHMuanNvblNjaGVtYS5sZW5ndGggPiAwKTtcbiAgLy8gLS10b29scyBcIlwiIOuhnCDsoITssrQg7LCo64uoLCBzdHJ1Y3R1cmVkKGpzb25TY2hlbWEg7J6I7J2MKSDrqbQgU3RydWN0dXJlZE91dHB1dCDrp4wg7ZeI7JqpLlxuICBjb25zdCB0b29sQXJncyA9IHVzZVN0cnVjdHVyZWRcbiAgICA/IFtcIi0tdG9vbHNcIiwgXCJcIiwgXCItLWFsbG93ZWQtdG9vbHNcIiwgXCJTdHJ1Y3R1cmVkT3V0cHV0XCJdXG4gICAgOiBbXCItLXRvb2xzXCIsIFwiXCJdO1xuXG4gIGNvbnN0IGFyZ3M6IEFycmF5PHN0cmluZz4gPSBbXG4gICAgXCItcFwiLFxuICAgIC4uLnRvb2xBcmdzLFxuICAgIFwiLS1kaXNhbGxvd2VkVG9vbHNcIixcbiAgICAuLi5BTlRIUk9QSUNfRElTQUxMT1dFRF9UT09MUyxcbiAgICBcIi0taW5wdXQtZm9ybWF0XCIsXG4gICAgXCJzdHJlYW0tanNvblwiLFxuICAgIFwiLS1vdXRwdXQtZm9ybWF0XCIsXG4gICAgXCJzdHJlYW0tanNvblwiLFxuICAgIFwiLS12ZXJib3NlXCIsXG4gICAgXCItLW1heC10dXJuc1wiLFxuICAgIHVzZVN0cnVjdHVyZWQgPyBcIjJcIiA6IFwiMVwiLFxuICAgIFwiLS1wZXJtaXNzaW9uLW1vZGVcIixcbiAgICBcImJ5cGFzc1Blcm1pc3Npb25zXCIsXG4gICAgXCItLXNldHRpbmctc291cmNlc1wiLFxuICAgIFwicHJvamVjdFwiLFxuICAgIFwiLS1tb2RlbFwiLFxuICAgIG9wdHMubW9kZWwsXG4gICAgLy8gaW5saW5lIFtTeXN0ZW1dIOq4iOyngCDigJQg7KCV7IudIOyxhOuEkOunjChSNykuIOyDneuetSDsi5wgQ0MgZGVmYXVsdCgyM2spIOyjvOyeheuQmOuvgOuhnCDrsJjrk5zsi5wg66qF7IucLlxuICAgIFwiLS1zeXN0ZW0tcHJvbXB0XCIsXG4gICAgb3B0cy5zeXN0ZW0gPz8gXCJcIixcbiAgICBcIi0tdGhpbmtpbmdcIixcbiAgICBcImRpc2FibGVkXCIsXG4gICAgXCItLWVmZm9ydFwiLFxuICAgIG9wdHMuZWZmb3J0ID8/IEFOVEhST1BJQ19ERUZBVUxUX0VGRk9SVCxcbiAgICBcIi0tZGlzYWJsZS1zbGFzaC1jb21tYW5kc1wiLFxuICAgIC8vIOupgO2LsO2EtDog7LKrIO2YuOy2nOydgCBzZXNzaW9uLWlkIOuwnOq4iSwg7ZuE7IaN7J2AIHJlc3VtZS4gLS1uby1zZXNzaW9uLXBlcnNpc3RlbmNlIOuKlCDsk7Dsp4Ag7JWK64qU64ukLlxuICAgIC4uLihvcHRzLmlzUmVzdW1lID8gW1wiLS1yZXN1bWVcIiwgb3B0cy5zZXNzaW9uSWRdIDogW1wiLS1zZXNzaW9uLWlkXCIsIG9wdHMuc2Vzc2lvbklkXSksXG4gIF07XG4gIGlmICh1c2VTdHJ1Y3R1cmVkKSBhcmdzLnB1c2goXCItLWpzb24tc2NoZW1hXCIsIG9wdHMuanNvblNjaGVtYSEpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBDbGF1ZGUg7IS47IWY7J2EIHNwYXduIO2VtCDtlZwgdHVybiDsnYQg7Iuk7ZaJ7ZWc64ukLiBwZXItc2Vzc2lvbiDrnb3snLzroZwg7KeB66Cs7ZmU65Cc64ukLlxuICogQHBhcmFtIG9uRGVsdGEg7KCQ7KeEIO2FjeyKpO2KuCBkZWx0YShzdHJlYW1UZXh0KSDrmJDripQgc3RydWN0dXJlZCDrtoDrtoQgSlNPTihzdHJlYW1PYmplY3QpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuQ2xhdWRlU2Vzc2lvbihcbiAgcmVxOiBDbGF1ZGVTZXNzaW9uUmVxdWVzdCxcbiAgb25EZWx0YTogKHRleHQ6IHN0cmluZykgPT4gdm9pZCxcbik6IFByb21pc2U8Q2xhdWRlU2Vzc2lvblJlc3VsdD4ge1xuICAvLyDsoJXqt5ztmZQg6rec7LmZ7J2AIGNhbm9uaWNhbEFudGhyb3BpY01vZGVsIOydtCDri6jrj4Ug7IaM7JygIOKAlCBkaXNwYXRjaGVyIOqwgCDsnbTrr7ggY2Fub25pY2FsIOydhCDrhJjquLDsp4Drp4wsXG4gIC8vIOyngeygkSDtmLjstpwo7YWM7Iqk7Yq4L+uvuOuemCBjYWxsZXIpIOuMgOu5hCDrsKnslrTsoIHsnLzroZwg7ZWcIOuyiCDrjZQg7Ya16rO87Iuc7YKo64ukKOydtOuvuCBjYW5vbmljYWwg7J2066m0IG5vLW9wKS5cbiAgY29uc3QgbW9kZWwgPSBjYW5vbmljYWxBbnRocm9waWNNb2RlbChyZXEubW9kZWwpO1xuICBjb25zdCBpc1Jlc3VtZSA9IEJvb2xlYW4ocmVxLnJlc3VtZVNlc3Npb25JZCk7XG4gIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5yZXN1bWVTZXNzaW9uSWQgPz8gcmFuZG9tVVVJRCgpO1xuICBjb25zdCB1c2VTdHJ1Y3R1cmVkID0gQm9vbGVhbihyZXEuanNvblNjaGVtYSAmJiByZXEuanNvblNjaGVtYS5sZW5ndGggPiAwKTtcbiAgY29uc3Qgd29ya2VySWQgPSBtYWtlQW50aHJvcGljV29ya2VySWQocmVxLnRva2VuSWQpO1xuXG4gIHJldHVybiB3aXRoU2Vzc2lvbkxvY2soc2Vzc2lvbklkLCAoKSA9PiB7XG4gICAgZW5zdXJlQ3dkKCk7XG4gICAgY29uc3QgY29uZmlnRGlyID0gZW5zdXJlQ29uZmlnRGlyKHJlcS50b2tlbklkKTtcblxuICAgIGNvbnN0IGFyZ3MgPSBidWlsZENsYXVkZUFyZ3Moe1xuICAgICAgbW9kZWwsXG4gICAgICBzeXN0ZW06IHJlcS5zeXN0ZW0sXG4gICAgICBlZmZvcnQ6IHJlcS5lZmZvcnQsXG4gICAgICBqc29uU2NoZW1hOiByZXEuanNvblNjaGVtYSxcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIGlzUmVzdW1lLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5wdXRMaW5lcyA9IGJ1aWxkU3RyZWFtSnNvbklucHV0KHtcbiAgICAgIGNvbGRIaXN0b3J5OiByZXEuY29sZEhpc3RvcnksXG4gICAgICBpbnB1dDogcmVxLmlucHV0LFxuICAgICAgaXNSZXN1bWUsXG4gICAgfSk7XG4gICAgY29uc3Qgc3RkaW5QYXlsb2FkID0gZGVjb3JhdGVBbmRTZXJpYWxpemUoaW5wdXRMaW5lcywgc2Vzc2lvbklkKTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxDbGF1ZGVTZXNzaW9uUmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaGlsZCA9IHNwYXduKFwiY2xhdWRlXCIsIGFyZ3MsIHtcbiAgICAgICAgLy8gc3RkZXJyIOuPhCDsuqHsspg6IGludmFsaWQgT0F1dGggLyDsnpjrqrvrkJwg7ZSM656Y6re4IC8gQ0xJIOqygOymnSDsi6TtjKjqsIBcbiAgICAgICAgLy8gXCJjbG9zZWQgd2l0aG91dCByZXN1bHRcIiDroZwg662J6rCc7KeA7KeAIOyViuqyjCBjbG9zZS9lcnJvciDsl5Agc3RkZXJyIOulvCDsi6TslrQg67O064K464ukLlxuICAgICAgICBzdGRpbzogW1wicGlwZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICAgICAgICBjd2Q6IEFOVEhST1BJQ19DTEFVREVfQ1dELFxuICAgICAgICBlbnY6IHtcbiAgICAgICAgICBQQVRIOiBwcm9jZXNzLmVudi5QQVRILFxuICAgICAgICAgIFRNUERJUjogcHJvY2Vzcy5lbnYuVE1QRElSLFxuICAgICAgICAgIENMQVVERV9DT0RFX09BVVRIX1RPS0VOOiByZXEudG9rZW4sXG4gICAgICAgICAgQ0xBVURFX0NPTkZJR19ESVI6IGNvbmZpZ0RpcixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX0FVVE9fTUVNT1JZOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX0FEQVBUSVZFX1RISU5LSU5HOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFXzFNX0NPTlRFWFQ6IFwiMVwiLFxuICAgICAgICAgIENMQVVERV9DT0RFX0RJU0FCTEVfQ0xBVURFX01EUzogXCIxXCIsXG4gICAgICAgICAgQ0xBVURFX0NPREVfQVRUUklCVVRJT05fSEVBREVSOiBcIjBcIixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBsZXQgc2V0dGxlZCA9IGZhbHNlO1xuICAgICAgbGV0IGJ1ZmZlciA9IFwiXCI7XG4gICAgICBjb25zdCBzdHJlYW1TdGF0ZTogQ2xhdWRlU3RyZWFtSnNvblN0YXRlID0ge307XG4gICAgICAvLyBib3VuZGVkIHN0ZGVyciDrsoTtjbwo7LWc6re8IH40S0Lrp4wg7Jyg7KeAIOKAlCDrrLTtlZwg64iE7KCBIOuwqeyngCkuXG4gICAgICBsZXQgc3RkZXJyQnVmID0gXCJcIjtcbiAgICAgIGNvbnN0IFNUREVSUl9DQVAgPSA0MDk2O1xuICAgICAgY2hpbGQuc3RkZXJyPy5vbihcImRhdGFcIiwgKGQ6IEJ1ZmZlcikgPT4ge1xuICAgICAgICBzdGRlcnJCdWYgPSAoc3RkZXJyQnVmICsgZC50b1N0cmluZygpKS5zbGljZSgtU1RERVJSX0NBUCk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHN0ZGVyclN1ZmZpeCA9ICgpID0+IChzdGRlcnJCdWYudHJpbSgpID8gYCDigJQgc3RkZXJyOiAke3N0ZGVyckJ1Zi50cmltKCl9YCA6IFwiXCIpO1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGNoaWxkLmtpbGwoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2xhdWRlIHNlc3Npb24gdGltZW91dCBhZnRlciAke3JlcS50aW1lb3V0TXMgLyAxMDAwfXNgKSk7XG4gICAgICB9LCByZXEudGltZW91dE1zKTtcblxuICAgICAgY29uc3QgZmluaXNoID0gKHJlc3VsdDogQ2xhdWRlU3RyZWFtUmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChzZXR0bGVkKSByZXR1cm47XG4gICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICByZXNvbHZlKHsgLi4ucmVzdWx0LCBzZXNzaW9uSWQsIHdvcmtlcklkIH0pO1xuICAgICAgfTtcblxuICAgICAgcmVxLmFib3J0U2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgKCkgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgY2hpbGQua2lsbCgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiYWJvcnRlZFwiKSk7XG4gICAgICB9KTtcblxuICAgICAgY2hpbGQuc3Rkb3V0Py5vbihcImRhdGFcIiwgKGQ6IEJ1ZmZlcikgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgICBidWZmZXIgKz0gZC50b1N0cmluZygpO1xuICAgICAgICBjb25zdCBsaW5lcyA9IGJ1ZmZlci5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgYnVmZmVyID0gbGluZXMucG9wKCkgPz8gXCJcIjtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gaGFuZGxlU3RyZWFtSnNvbkxpbmUobGluZSwgb25EZWx0YSwge1xuICAgICAgICAgICAgc3RydWN0dXJlZE91dHB1dDogdXNlU3RydWN0dXJlZCxcbiAgICAgICAgICAgIHN0YXRlOiBzdHJlYW1TdGF0ZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICBmaW5pc2gocmVzdWx0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjaGlsZC5vbihcImNsb3NlXCIsICgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYENsYXVkZSBzZXNzaW9uIGNsb3NlZCB3aXRob3V0IHJlc3VsdCR7c3RkZXJyU3VmZml4KCl9YCkpO1xuICAgICAgfSk7XG4gICAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYENsYXVkZSBzZXNzaW9uIHNwYXduIGVycm9yOiAke2Vyci5tZXNzYWdlfWApKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBzdGRpbiDsnLzroZwg7J6F66ClIEpTT05MIO2dmOumrOqzoCDri6vripTri6QuXG4gICAgICBjaGlsZC5zdGRpbj8ud3JpdGUoc3RkaW5QYXlsb2FkKTtcbiAgICAgIGNoaWxkLnN0ZGluPy5lbmQoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8vIHVzYWdlIOyerOuFuOy2nCjthYzsiqTtirgg7Y647J2YKS5cbmV4cG9ydCB0eXBlIHsgVG9rZW5Vc2FnZUJyZWFrZG93biB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0RBLFNBQWdCLGlCQUFpQixNQUt0QjtDQUNULE1BQU0sYUFBYSxLQUFLLGdCQUFnQixLQUFLLGFBQWEsU0FBUyxJQUFJLEtBQUssZUFBZTtBQUMzRixRQUFPLFdBQVcsU0FBUyxDQUN4QixPQUFPLEdBQUcsS0FBSyxVQUFVLEdBQUcsSUFBSSxLQUFLLE1BQU0sSUFBSSxhQUFhLENBQzVELE9BQU8sTUFBTSxDQUNiLE1BQU0sR0FBRyxHQUFHOztBQU1qQixNQUFNLGdDQUFnQixJQUFJLEtBQStCO0FBRXpELGVBQXNCLGdCQUFtQixXQUFtQixJQUFrQztDQUc1RixNQUFNLFFBRk8sY0FBYyxJQUFJLFVBQVUsSUFBSSxRQUFRLFNBQVMsRUFFNUMsS0FBSyxJQUFJLEdBQUc7Q0FHOUIsTUFBTSxPQUFPLEtBQUssV0FDVixVQUNBLEdBQ1A7QUFDRCxlQUFjLElBQUksV0FBVyxLQUFLO0FBQ2xDLEtBQUk7QUFDRixTQUFPLE1BQU07V0FDTDtBQUVSLE1BQUksY0FBYyxJQUFJLFVBQVUsS0FBSyxLQUFNLGVBQWMsT0FBTyxVQUFVOzs7QUFPOUUsU0FBZ0Isc0JBQXNCLFNBQXlCO0FBQzdELFFBQU87O0FBTVQsU0FBZ0IscUJBQXFCLE9BQW9DLFdBQTJCO0FBQ2xHLFFBQ0UsTUFDRyxLQUFLLFNBQ0osS0FBSyxVQUFVO0VBQ2IsR0FBRztFQUNILFlBQVk7RUFDWixNQUFNLFlBQVk7RUFDbEIsb0JBQW9CO0VBQ3JCLENBQUMsQ0FDSCxDQUNBLEtBQUssS0FB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
|
|
235
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhdWRlLXNlc3Npb24uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvY2xhdWRlLXNlc3Npb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBjbGF1ZGUtc2Vzc2lvbiDigJQgQ2xhdWRlIENMSSDshLjshZggc3Bhd24gKyBRZ3JpZFRocmVhZENvb3JkIOunpO2VkSArIHBlci1zZXNzaW9uIOudvS5cbiAqXG4gKiDrqYDti7DthLQ6IOunpCDtmLjstpwgZnJlc2ggYC0tc2Vzc2lvbi1pZCA8dXVpZD5g66GcIOyLpO2Wie2VnOuLpC4g7J6F66Cl7J2AIOyWtOuMke2EsOqwgCDrp4zrk6AgSlNPTkwg7J2EXG4gKiBzdGRpbiDsnLzroZwg7Z2Y66as6rOgKGAtLWlucHV0LWZvcm1hdCBzdHJlYW0tanNvbmApLCDstpzroKXsnYAg7YyM7ISc66GcIOyymOumrO2VnOuLpC5cbiAqXG4gKiDtlbXsi6wg6rOE7JW9OlxuICogIC0gY29vcmQg64qUIOyehOydmCDsoIDsnqXsnbQg7JWE64uI6528IOq4sOyhtCBRZ3JpZFRocmVhZENvb3Jke3dvcmtlcklkLHRocmVhZElkLGVwb2NoLHN5c3RlbUhhc2h9IOyXkFxuICogICAg66ek7ZWR7ZWc64ukLiB0aHJlYWRJZD3shLjshZggdXVpZCwgZXBvY2g9MCDqs6DsoJUod29ya2VyIHJlc3RhcnQg6rCc64WQIOyXhuydjCksIHdvcmtlcklkPXRva2VuIOq4sOuwmFxuICogICAg7JWI7KCVIO2VqeyEsSwgc3lzdGVtSGFzaD3smpTssq0gc3lzdGVtIO2VtOyLnC4gaXNzdWVDb252Q29udGV4dC9kZWNpZGVDb252Um91dGluZyDqs7wgcm91bmQtdHJpcC5cbiAqICAtIHdpdGhTZXNzaW9uTG9jayDsnYAgZXhwb3J0ZWQgcHJpbWl0aXZlIOuhnCDsnKDsp4DtlZzri6QuIOq4sOuzuCDqsr3roZzsl5DshJzripQg66ekIO2YuOy2nCDsg4ggc2Vzc2lvbi1pZCDrnbxcbiAqICAgIOyCrOyLpOyDgSBuby1jb250ZW50aW9uIOydtOyngOunjCwg7KeB7KCRIO2YuOy2nOyekC/thYzsiqTtirjsnZgg7KeB66Cs7ZmUIOuztOyepeydgCDrs7TsobTtlZzri6QuXG4gKiAgLSBzdHJlYW0tanNvbiDsp4HroKztmZQg7IucIFNESyBlbnZlbG9wZSh1dWlkL3Nlc3Npb25faWQvcGFyZW50X3Rvb2xfdXNlX2lkKSBkZWNvcmF0ZS5cbiAqICAtIHN0cnVjdHVyZWQgb3V0cHV0IOydvCDrlYwg7Lac66ClIO2MjOyEnOyXkCB7IHN0cnVjdHVyZWRPdXRwdXQ6IHRydWUgfSDsoITri6wo7JeG7Jy866m0IHN0cmVhbU9iamVjdCDquajsp5ApLlxuICovXG5cbmltcG9ydCB7IHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgbWtkaXJTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcblxuaW1wb3J0IHsgdHlwZSBKc29uVmFsdWUgfSBmcm9tIFwiLi4vLi4vLi4vY29kZXgtcHJvdG9jb2wvc2VyZGVfanNvbi9Kc29uVmFsdWVcIjtcbmltcG9ydCB7IHR5cGUgVG9rZW5Vc2FnZUJyZWFrZG93biB9IGZyb20gXCIuLi8uLi8uLi9jb2RleC1wcm90b2NvbC92Mi9Ub2tlblVzYWdlQnJlYWtkb3duXCI7XG5pbXBvcnQgeyB0eXBlIFVzZXJJbnB1dCB9IGZyb20gXCIuLi8uLi8uLi9jb2RleC1wcm90b2NvbC92Mi9Vc2VySW5wdXRcIjtcbmltcG9ydCB7XG4gIEFOVEhST1BJQ19DTEFVREVfQ1dELFxuICBhbnRocm9waWNDb25maWdEaXIsXG4gIEFOVEhST1BJQ19ERUZBVUxUX0VGRk9SVCxcbiAgQU5USFJPUElDX0RJU0FMTE9XRURfVE9PTFMsXG4gIGFzc2VydFN1cHBvcnRlZE9uZU1pbGxpb25TdWZmaXgsXG4gIGNhbm9uaWNhbEFudGhyb3BpY01vZGVsLFxuICBuZWVkc0NsaTFtU3VmZml4LFxuICBzdXBwb3J0czFNQ29udGV4dCxcbn0gZnJvbSBcIi4vYW50aHJvcGljLWNvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgYnVpbGRTdHJlYW1Kc29uSW5wdXQsXG4gIHR5cGUgQ2xhdWRlU3RyZWFtSnNvblN0YXRlLFxuICB0eXBlIENsYXVkZVN0cmVhbUpzb25MaW5lLFxuICB0eXBlIENsYXVkZVN0cmVhbVJlc3VsdCxcbiAgaGFuZGxlU3RyZWFtSnNvbkxpbmUsXG59IGZyb20gXCIuL3N0cmVhbS1qc29uLWFkYXB0ZXJcIjtcblxuLy8g4pSA4pSAIHBlci1zZXNzaW9uIOudvSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLy8gc2Vzc2lvbi1pZCDri6jsnIQg7KeB66Cs7ZmUIHByaW1pdGl2ZS4g6riw67O4IOqyveuhnOyXkOyEnOuKlCDrp6Qg7Zi47LacIOyDiCB1dWlkIOudvCDsgqzsi6Tsg4Egbm8tb3Ag7J207KeA66eMLFxuLy8g6rCZ7J2AIHNlc3Npb24taWQg66W8IOyngeygkSDsk7DripQg7Zi47Lac7J6Q64qUIOyXrOyghO2eiCDsp4HroKztmZQg67O07J6l7J2EIOuwm+uKlOuLpC5cbmNvbnN0IHNlc3Npb25DaGFpbnMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx1bmtub3duPj4oKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhTZXNzaW9uTG9jazxUPihzZXNzaW9uSWQ6IHN0cmluZywgZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgcHJldiA9IHNlc3Npb25DaGFpbnMuZ2V0KHNlc3Npb25JZCkgPz8gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIC8vIOydtOyghCB0dXJuIOydmCDshLHtjKjsmYAg66y06rSA7ZWY6rKMIOyngeugrCDssrTsnbjsnYQg7J6H64qU64ukLlxuICBjb25zdCBuZXh0ID0gcHJldi50aGVuKGZuLCBmbik7XG4gIC8vIHRhaWw6IOyEse2MqCDrrLTqtIAgc2V0dGxlIOuQmOuKlCDtlbjrk6QuIOydtOqxuCDrp7Xsl5Ag65GQ6rOgLCBmaW5hbGx5IOyXkOyEnCBcIuyXrOyghO2eiCDrgrTqsIAg64GdXCLsnbwg65WM66eMIOyCreygnC5cbiAgLy8gKHNldCDsp4Htm4QgdW5kZWZpbmVkIOqygOyCrOuhnCDtlZjrqbQg7KCI64yAIOyCreygnCDslYgg64+8IOyEuOyFmCBpZCDqsIAg64iE7IiY65CoIOKAlCB0YWlsIOydvOy5mCDqsoDsgqzroZwg7ZqM7ZS8LilcbiAgY29uc3QgdGFpbCA9IG5leHQudGhlbihcbiAgICAoKSA9PiB7fSxcbiAgICAoKSA9PiB7fSxcbiAgKTtcbiAgc2Vzc2lvbkNoYWlucy5zZXQoc2Vzc2lvbklkLCB0YWlsKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgbmV4dDtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyDqt7gg7IKs7J20IOuLpOuluCB0dXJuIOydtCDssrTsnbjsnYQg7J207Ja067Cb7JWY7Jy866m0IHRhaWwg7J20IOq1kOyytOuPvCDsnojri6Qg4oCUIOq3uOuVjOuKlCDsgq3soJztlZjsp4Ag7JWK64qU64ukLlxuICAgIGlmIChzZXNzaW9uQ2hhaW5zLmdldChzZXNzaW9uSWQpID09PSB0YWlsKSBzZXNzaW9uQ2hhaW5zLmRlbGV0ZShzZXNzaW9uSWQpO1xuICB9XG59XG5cbi8vIOKUgOKUgCBjb29yZCDrp6TtlZEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8vIHRva2VuIOq4sOuwmCDslYjsoJUgd29ya2VySWQg7ZWp7ISxLiBBbnRocm9waWMg7J2AIHdvcmtlciBwb29sIOydtCDsl4bsnLzrr4DroZwgdG9rZW5JZCDrpbwg6re464yA66GcIOyTtOuLpC5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlQW50aHJvcGljV29ya2VySWQodG9rZW5JZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHRva2VuSWQ7XG59XG5cbi8vIOKUgOKUgCBlbnZlbG9wZSBkZWNvcmF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLy8gc3RyZWFtLWpzb24g7J6F66ClIOudvOyduOyXkCBTREsgZW52ZWxvcGUg67aA7LCpIO2bhCDsp4HroKztmZQuIHNlc3Npb24g7IaM7Jyg7J6Q7J24IOyXrOq4sOyEnCDtlZzri6QuXG5leHBvcnQgZnVuY3Rpb24gZGVjb3JhdGVBbmRTZXJpYWxpemUoXG4gIGxpbmVzOiBBcnJheTxDbGF1ZGVTdHJlYW1Kc29uTGluZT4sXG4gIHNlc3Npb25JZDogc3RyaW5nLFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIChcbiAgICBsaW5lc1xuICAgICAgLm1hcCgobGluZSkgPT5cbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIC4uLmxpbmUsXG4gICAgICAgICAgc2Vzc2lvbl9pZDogc2Vzc2lvbklkLFxuICAgICAgICAgIHV1aWQ6IHJhbmRvbVVVSUQoKSxcbiAgICAgICAgICBwYXJlbnRfdG9vbF91c2VfaWQ6IG51bGwsXG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgLmpvaW4oXCJcXG5cIikgKyBcIlxcblwiXG4gICk7XG59XG5cbi8vIOKUgOKUgCBzcGF3biArIGNvbnN1bWUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xhdWRlU2Vzc2lvblJlcXVlc3Qge1xuICB0b2tlbklkOiBudW1iZXI7XG4gIHRva2VuOiBzdHJpbmc7IC8vIE9BdXRoIGFjY2VzcyB0b2tlblxuICBtb2RlbDogc3RyaW5nO1xuICBzeXN0ZW0/OiBzdHJpbmc7XG4gIGpzb25TY2hlbWE/OiBzdHJpbmc7IC8vIOyeiOycvOuptCBzdHJ1Y3R1cmVkIG91dHB1dFxuICBlZmZvcnQ/OiBzdHJpbmc7XG4gIHRpbWVvdXRNczogbnVtYmVyO1xuICBjb2xkSGlzdG9yeT86IEFycmF5PEpzb25WYWx1ZT47XG4gIGlucHV0OiBBcnJheTxVc2VySW5wdXQ+O1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBpbmNsdWRlUGFydGlhbE1lc3NhZ2VzPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGF1ZGVTZXNzaW9uUmVzdWx0IGV4dGVuZHMgQ2xhdWRlU3RyZWFtUmVzdWx0IHtcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIHdvcmtlcklkOiBudW1iZXI7XG59XG5cbi8vIHBlci10b2tlbiBDTEFVREVfQ09ORklHX0RJUiDrs7TsnqUo6rKp66asKS4g6rK966GcIOq3nOy5meydgCBhbnRocm9waWNDb25maWdEaXIo7Iic7IiYIO2VqOyImCnsnbQg7IaM7JygIOKAlFxuLy8g7Jes6riw7ISgIOq3uCDqsr3roZzsl5Ag67mIIHNldHRpbmdzIOulvCDquZTslYQgY2xhdWRlLW1lbSBob29rIOuTseydhCDssKjri6jtlZzri6QuIChSMTAg6rKp66asKVxuLy8g7J20IHNlZWQg7YyM7J287J2AIGNsYXVkZS1tZW0gaG9vayAvIOyCrOyaqeyekCDshKTsoJUg7Jik7Je8IOywqOuLqOydhCDsnITtlZwg6rKp66asIOqyveqzhOuLpC4g66ekIO2YuOy2nOuniOuLpCDri6Tsi5wg7I2o7IScXG4vLyDsmbjrtoAg67OA7KGwwrfsgq3soJwg7ZuE7JeQ64+EIOuLpOydjCDsi6Ttlonsl5DshJwgc2VsZi1oZWFsaW5nIOuQmOuPhOuhnSDquLDsobQgc2VtYW50aWNzIOulvCDsnKDsp4DtlZzri6QuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlQ29uZmlnRGlyKHRva2VuSWQ6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGRpciA9IGFudGhyb3BpY0NvbmZpZ0Rpcih0b2tlbklkKTtcbiAgbWtkaXJTeW5jKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHdyaXRlRmlsZVN5bmMoYCR7ZGlyfS8uY2xhdWRlLmpzb25gLCBcInt9XCIpO1xuICB3cml0ZUZpbGVTeW5jKGAke2Rpcn0vc2V0dGluZ3MuanNvbmAsIFwie31cIik7XG4gIHJldHVybiBkaXI7XG59XG5cbmxldCBjd2RFbnN1cmVkID0gZmFsc2U7XG5mdW5jdGlvbiBlbnN1cmVDd2QoKTogdm9pZCB7XG4gIGlmIChjd2RFbnN1cmVkKSByZXR1cm47XG4gIG1rZGlyU3luYyhgJHtBTlRIUk9QSUNfQ0xBVURFX0NXRH0vLmNsYXVkZWAsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICB3cml0ZUZpbGVTeW5jKGAke0FOVEhST1BJQ19DTEFVREVfQ1dEfS8uY2xhdWRlL3NldHRpbmdzLmpzb25gLCBcInt9XCIpO1xuICBjd2RFbnN1cmVkID0gdHJ1ZTtcbn1cblxuLy8gc3Bhd24gYXJncyDqtazshLEuIOupgO2LsO2EtC/qsqnrpqwvc3RydWN0dXJlZCDrqqjrk5wg67CY7JiBLlxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5T25lTWlsbGlvblN1ZmZpeChtb2RlbDogc3RyaW5nLCBuZWVkc1N1ZmZpeDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGNvbnN0IGJhc2UgPSBjYW5vbmljYWxBbnRocm9waWNNb2RlbChtb2RlbCk7XG4gIHJldHVybiBuZWVkc1N1ZmZpeCA/IGAke2Jhc2V9WzFtXWAgOiBiYXNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb25lTWlsbGlvbkVudihzdXBwb3J0ZWQ6IGJvb2xlYW4pOiB7IENMQVVERV9DT0RFX0RJU0FCTEVfMU1fQ09OVEVYVD86IFwiMVwiIH0ge1xuICByZXR1cm4gc3VwcG9ydGVkID8ge30gOiB7IENMQVVERV9DT0RFX0RJU0FCTEVfMU1fQ09OVEVYVDogXCIxXCIgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ2xhdWRlQXJncyhvcHRzOiB7XG4gIG1vZGVsOiBzdHJpbmc7XG4gIHN5c3RlbT86IHN0cmluZztcbiAgZWZmb3J0Pzogc3RyaW5nO1xuICBqc29uU2NoZW1hPzogc3RyaW5nO1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgbmVlZHNPbmVNaWxsaW9uU3VmZml4PzogYm9vbGVhbjtcbiAgaW5jbHVkZVBhcnRpYWxNZXNzYWdlcz86IGJvb2xlYW47XG59KTogQXJyYXk8c3RyaW5nPiB7XG4gIGNvbnN0IHVzZVN0cnVjdHVyZWQgPSBCb29sZWFuKG9wdHMuanNvblNjaGVtYSAmJiBvcHRzLmpzb25TY2hlbWEubGVuZ3RoID4gMCk7XG4gIC8vIC0tdG9vbHMgXCJcIiDroZwg7KCE7LK0IOywqOuLqCwgc3RydWN0dXJlZChqc29uU2NoZW1hIOyeiOydjCkg66m0IFN0cnVjdHVyZWRPdXRwdXQg66eMIO2XiOyaqS5cbiAgY29uc3QgdG9vbEFyZ3MgPSB1c2VTdHJ1Y3R1cmVkXG4gICAgPyBbXCItLXRvb2xzXCIsIFwiXCIsIFwiLS1hbGxvd2VkLXRvb2xzXCIsIFwiU3RydWN0dXJlZE91dHB1dFwiXVxuICAgIDogW1wiLS10b29sc1wiLCBcIlwiXTtcblxuICBjb25zdCBhcmdzOiBBcnJheTxzdHJpbmc+ID0gW1xuICAgIFwiLXBcIixcbiAgICAuLi50b29sQXJncyxcbiAgICBcIi0tZGlzYWxsb3dlZFRvb2xzXCIsXG4gICAgLi4uQU5USFJPUElDX0RJU0FMTE9XRURfVE9PTFMsXG4gICAgXCItLWlucHV0LWZvcm1hdFwiLFxuICAgIFwic3RyZWFtLWpzb25cIixcbiAgICBcIi0tb3V0cHV0LWZvcm1hdFwiLFxuICAgIFwic3RyZWFtLWpzb25cIixcbiAgICBcIi0tdmVyYm9zZVwiLFxuICAgIC4uLihvcHRzLmluY2x1ZGVQYXJ0aWFsTWVzc2FnZXMgPyBbXCItLWluY2x1ZGUtcGFydGlhbC1tZXNzYWdlc1wiXSA6IFtdKSxcbiAgICBcIi0tcGVybWlzc2lvbi1tb2RlXCIsXG4gICAgXCJieXBhc3NQZXJtaXNzaW9uc1wiLFxuICAgIFwiLS1zZXR0aW5nLXNvdXJjZXNcIixcbiAgICBcInByb2plY3RcIixcbiAgICBcIi0tbW9kZWxcIixcbiAgICBhcHBseU9uZU1pbGxpb25TdWZmaXgob3B0cy5tb2RlbCwgb3B0cy5uZWVkc09uZU1pbGxpb25TdWZmaXggPz8gZmFsc2UpLFxuICAgIC8vIGlubGluZSBbU3lzdGVtXSDquIjsp4Ag4oCUIOygleyLnSDssYTrhJDrp4woUjcpLiDsg53rnrUg7IucIENDIGRlZmF1bHQoMjNrKSDso7zsnoXrkJjrr4DroZwg67CY65Oc7IucIOuqheyLnC5cbiAgICBcIi0tc3lzdGVtLXByb21wdFwiLFxuICAgIG9wdHMuc3lzdGVtID8/IFwiXCIsXG4gICAgXCItLXRoaW5raW5nXCIsXG4gICAgXCJkaXNhYmxlZFwiLFxuICAgIFwiLS1lZmZvcnRcIixcbiAgICBvcHRzLmVmZm9ydCA/PyBBTlRIUk9QSUNfREVGQVVMVF9FRkZPUlQsXG4gICAgXCItLWRpc2FibGUtc2xhc2gtY29tbWFuZHNcIixcbiAgICBcIi0tc2Vzc2lvbi1pZFwiLFxuICAgIG9wdHMuc2Vzc2lvbklkLFxuICBdO1xuICBpZiAodXNlU3RydWN0dXJlZCkgYXJncy5wdXNoKFwiLS1qc29uLXNjaGVtYVwiLCBvcHRzLmpzb25TY2hlbWEhKTtcbiAgcmV0dXJuIGFyZ3M7XG59XG5cbi8qKlxuICogQ2xhdWRlIOyEuOyFmOydhCBzcGF3biDtlbQg7ZWcIHR1cm4g7J2EIOyLpO2Wie2VnOuLpC4gcGVyLXNlc3Npb24g65297Jy866GcIOyngeugrO2ZlOuQnOuLpC5cbiAqIEBwYXJhbSBvbkRlbHRhIOygkOynhCDthY3siqTtirggZGVsdGEoc3RyZWFtVGV4dCkg65iQ64qUIHN0cnVjdHVyZWQg67aA67aEIEpTT04oc3RyZWFtT2JqZWN0KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ1bkNsYXVkZVNlc3Npb24oXG4gIHJlcTogQ2xhdWRlU2Vzc2lvblJlcXVlc3QsXG4gIG9uRGVsdGE6ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4pOiBQcm9taXNlPENsYXVkZVNlc3Npb25SZXN1bHQ+IHtcbiAgLy8g7KCV6rec7ZmUIOq3nOy5meydgCBjYW5vbmljYWxBbnRocm9waWNNb2RlbCDsnbQg64uo64+FIOyGjOycoCDigJQgZGlzcGF0Y2hlciDqsIAg7J2066+4IGNhbm9uaWNhbCDsnYQg64SY6riw7KeA66eMLFxuICAvLyDsp4HsoJEg7Zi47LacKO2FjOyKpO2KuC/rr7jrnpggY2FsbGVyKSDrjIDruYQg67Cp7Ja07KCB7Jy866GcIO2VnCDrsogg642UIO2GteqzvOyLnO2CqOuLpCjsnbTrr7ggY2Fub25pY2FsIOydtOuptCBuby1vcCkuXG4gIGFzc2VydFN1cHBvcnRlZE9uZU1pbGxpb25TdWZmaXgocmVxLm1vZGVsKTtcbiAgY29uc3QgbW9kZWwgPSBjYW5vbmljYWxBbnRocm9waWNNb2RlbChyZXEubW9kZWwpO1xuICBjb25zdCBzdXBwb3J0c09uZU1pbGxpb24gPSBzdXBwb3J0czFNQ29udGV4dChtb2RlbCk7XG4gIGNvbnN0IG5lZWRzT25lTWlsbGlvblN1ZmZpeCA9IG5lZWRzQ2xpMW1TdWZmaXgobW9kZWwpO1xuICBjb25zdCBzZXNzaW9uSWQgPSByYW5kb21VVUlEKCk7XG4gIGNvbnN0IHVzZVN0cnVjdHVyZWQgPSBCb29sZWFuKHJlcS5qc29uU2NoZW1hICYmIHJlcS5qc29uU2NoZW1hLmxlbmd0aCA+IDApO1xuICBjb25zdCB3b3JrZXJJZCA9IG1ha2VBbnRocm9waWNXb3JrZXJJZChyZXEudG9rZW5JZCk7XG5cbiAgcmV0dXJuIHdpdGhTZXNzaW9uTG9jayhzZXNzaW9uSWQsICgpID0+IHtcbiAgICBlbnN1cmVDd2QoKTtcbiAgICBjb25zdCBjb25maWdEaXIgPSBlbnN1cmVDb25maWdEaXIocmVxLnRva2VuSWQpO1xuXG4gICAgY29uc3QgYXJncyA9IGJ1aWxkQ2xhdWRlQXJncyh7XG4gICAgICBtb2RlbCxcbiAgICAgIHN5c3RlbTogcmVxLnN5c3RlbSxcbiAgICAgIGVmZm9ydDogcmVxLmVmZm9ydCxcbiAgICAgIGpzb25TY2hlbWE6IHJlcS5qc29uU2NoZW1hLFxuICAgICAgc2Vzc2lvbklkLFxuICAgICAgbmVlZHNPbmVNaWxsaW9uU3VmZml4LFxuICAgICAgaW5jbHVkZVBhcnRpYWxNZXNzYWdlczogcmVxLmluY2x1ZGVQYXJ0aWFsTWVzc2FnZXMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBpbnB1dExpbmVzID0gYnVpbGRTdHJlYW1Kc29uSW5wdXQoe1xuICAgICAgY29sZEhpc3Rvcnk6IHJlcS5jb2xkSGlzdG9yeSxcbiAgICAgIGlucHV0OiByZXEuaW5wdXQsXG4gICAgfSk7XG4gICAgY29uc3Qgc3RkaW5QYXlsb2FkID0gZGVjb3JhdGVBbmRTZXJpYWxpemUoaW5wdXRMaW5lcywgc2Vzc2lvbklkKTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxDbGF1ZGVTZXNzaW9uUmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAocmVxLmFib3J0U2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJhYm9ydGVkXCIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjaGlsZCA9IHNwYXduKFwiY2xhdWRlXCIsIGFyZ3MsIHtcbiAgICAgICAgLy8gc3RkZXJyIOuPhCDsuqHsspg6IGludmFsaWQgT0F1dGggLyDsnpjrqrvrkJwg7ZSM656Y6re4IC8gQ0xJIOqygOymnSDsi6TtjKjqsIBcbiAgICAgICAgLy8gXCJjbG9zZWQgd2l0aG91dCByZXN1bHRcIiDroZwg662J6rCc7KeA7KeAIOyViuqyjCBjbG9zZS9lcnJvciDsl5Agc3RkZXJyIOulvCDsi6TslrQg67O064K464ukLlxuICAgICAgICBzdGRpbzogW1wicGlwZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICAgICAgICBjd2Q6IEFOVEhST1BJQ19DTEFVREVfQ1dELFxuICAgICAgICBlbnY6IHtcbiAgICAgICAgICBQQVRIOiBwcm9jZXNzLmVudi5QQVRILFxuICAgICAgICAgIFRNUERJUjogcHJvY2Vzcy5lbnYuVE1QRElSLFxuICAgICAgICAgIENMQVVERV9DT0RFX09BVVRIX1RPS0VOOiByZXEudG9rZW4sXG4gICAgICAgICAgQ0xBVURFX0NPTkZJR19ESVI6IGNvbmZpZ0RpcixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX0FVVE9fTUVNT1JZOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX0FEQVBUSVZFX1RISU5LSU5HOiBcIjFcIixcbiAgICAgICAgICAuLi5vbmVNaWxsaW9uRW52KHN1cHBvcnRzT25lTWlsbGlvbiksXG4gICAgICAgICAgQ0xBVURFX0NPREVfRElTQUJMRV9DTEFVREVfTURTOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX1RFUk1JTkFMX1RJVExFOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX0JVTkRMRURfU0tJTExTOiBcIjFcIixcbiAgICAgICAgICBDTEFVREVfQ09ERV9ESVNBQkxFX1dPUktGTE9XUzogXCIxXCIsXG4gICAgICAgICAgQ0xBVURFX0NPREVfQVRUUklCVVRJT05fSEVBREVSOiBcIjBcIixcbiAgICAgICAgICBNQVhfVEhJTktJTkdfVE9LRU5TOiBcIjBcIixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBsZXQgc2V0dGxlZCA9IGZhbHNlO1xuICAgICAgbGV0IGJ1ZmZlciA9IFwiXCI7XG4gICAgICBjb25zdCBzdHJlYW1TdGF0ZTogQ2xhdWRlU3RyZWFtSnNvblN0YXRlID0ge307XG4gICAgICAvLyBib3VuZGVkIHN0ZGVyciDrsoTtjbwo7LWc6re8IH40S0Lrp4wg7Jyg7KeAIOKAlCDrrLTtlZwg64iE7KCBIOuwqeyngCkuXG4gICAgICBsZXQgc3RkZXJyQnVmID0gXCJcIjtcbiAgICAgIGNvbnN0IFNUREVSUl9DQVAgPSA0MDk2O1xuICAgICAgY2hpbGQuc3RkZXJyPy5vbihcImRhdGFcIiwgKGQ6IEJ1ZmZlcikgPT4ge1xuICAgICAgICBzdGRlcnJCdWYgPSAoc3RkZXJyQnVmICsgZC50b1N0cmluZygpKS5zbGljZSgtU1RERVJSX0NBUCk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHN0ZGVyclN1ZmZpeCA9ICgpID0+IChzdGRlcnJCdWYudHJpbSgpID8gYCDigJQgc3RkZXJyOiAke3N0ZGVyckJ1Zi50cmltKCl9YCA6IFwiXCIpO1xuICAgICAgbGV0IGNsZWFudXBBYm9ydDogKCgpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGNsZWFudXBBYm9ydD8uKCk7XG4gICAgICAgIGNoaWxkLmtpbGwoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2xhdWRlIHNlc3Npb24gdGltZW91dCBhZnRlciAke3JlcS50aW1lb3V0TXMgLyAxMDAwfXNgKSk7XG4gICAgICB9LCByZXEudGltZW91dE1zKTtcblxuICAgICAgY29uc3QgZmluaXNoID0gKHJlc3VsdDogQ2xhdWRlU3RyZWFtUmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChzZXR0bGVkKSByZXR1cm47XG4gICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICBjbGVhbnVwQWJvcnQ/LigpO1xuICAgICAgICByZXNvbHZlKHsgLi4ucmVzdWx0LCBzZXNzaW9uSWQsIHdvcmtlcklkIH0pO1xuICAgICAgfTtcblxuICAgICAgY29uc3Qgb25BYm9ydCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIGNsZWFudXBBYm9ydD8uKCk7XG4gICAgICAgIGNoaWxkLmtpbGwoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcImFib3J0ZWRcIikpO1xuICAgICAgfTtcbiAgICAgIGNsZWFudXBBYm9ydCA9ICgpID0+IHJlcS5hYm9ydFNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgICAgcmVxLmFib3J0U2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25BYm9ydCwgeyBvbmNlOiB0cnVlIH0pO1xuXG4gICAgICBjaGlsZC5zdGRvdXQ/Lm9uKFwiZGF0YVwiLCAoZDogQnVmZmVyKSA9PiB7XG4gICAgICAgIGlmIChzZXR0bGVkKSByZXR1cm47XG4gICAgICAgIGJ1ZmZlciArPSBkLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGxpbmVzID0gYnVmZmVyLnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICBidWZmZXIgPSBsaW5lcy5wb3AoKSA/PyBcIlwiO1xuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBoYW5kbGVTdHJlYW1Kc29uTGluZShsaW5lLCBvbkRlbHRhLCB7XG4gICAgICAgICAgICBzdHJ1Y3R1cmVkT3V0cHV0OiB1c2VTdHJ1Y3R1cmVkLFxuICAgICAgICAgICAgc3RhdGU6IHN0cmVhbVN0YXRlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIGZpbmlzaChyZXN1bHQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKCkgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgY2xlYW51cEFib3J0Py4oKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2xhdWRlIHNlc3Npb24gY2xvc2VkIHdpdGhvdXQgcmVzdWx0JHtzdGRlcnJTdWZmaXgoKX1gKSk7XG4gICAgICB9KTtcbiAgICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgY2xlYW51cEFib3J0Py4oKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2xhdWRlIHNlc3Npb24gc3Bhd24gZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCkpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIHN0ZGluIOycvOuhnCDsnoXroKUgSlNPTkwg7Z2Y66as6rOgIOuLq+uKlOuLpC5cbiAgICAgIGNoaWxkLnN0ZGluPy53cml0ZShzdGRpblBheWxvYWQpO1xuICAgICAgY2hpbGQuc3RkaW4/LmVuZCgpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLy8gdXNhZ2Ug7J6s64W47LacKO2FjOyKpO2KuCDtjrjsnZgpLlxuZXhwb3J0IHR5cGUgeyBUb2tlblVzYWdlQnJlYWtkb3duIH07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE2Q0EsTUFBTSxnQ0FBZ0IsSUFBSSxLQUErQjtBQUV6RCxlQUFzQixnQkFBbUIsV0FBbUIsSUFBa0M7Q0FHNUYsTUFBTSxRQUZPLGNBQWMsSUFBSSxVQUFVLElBQUks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
|