@dbx-tools/appkit-model-gateway 0.9.99 → 0.9.105

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.
@@ -1,498 +0,0 @@
1
- /**
2
- * Streaming and buffered protocol encoders for AI SDK fallback results.
3
- *
4
- * @module
5
- */
6
- /** Encode AI SDK events as the requested protocol while preserving backpressure. */
7
- export function encodeGatewayStream(protocol, model, source) {
8
- const encoder = new TextEncoder();
9
- return new ReadableStream({
10
- async start(controller) {
11
- try {
12
- const events = protocol === "openai-responses"
13
- ? responsesEvents(model, source)
14
- : protocol === "anthropic-messages"
15
- ? anthropicEvents(model, source)
16
- : chatEvents(model, source);
17
- for await (const event of events)
18
- controller.enqueue(encoder.encode(event));
19
- controller.close();
20
- }
21
- catch (error) {
22
- controller.error(error);
23
- }
24
- },
25
- });
26
- }
27
- /** Encode a completed AI SDK generation as one protocol-native JSON response. */
28
- export function encodeGatewayResponse(protocol, model, generation) {
29
- if (protocol === "openai-responses")
30
- return responsesObject(model, generation);
31
- if (protocol === "anthropic-messages")
32
- return anthropicObject(model, generation);
33
- return chatObject(model, generation);
34
- }
35
- async function* responsesEvents(model, source) {
36
- const responseId = `resp_${crypto.randomUUID().replaceAll("-", "")}`;
37
- const createdAt = Math.floor(Date.now() / 1000);
38
- const output = [];
39
- const response = {
40
- id: responseId,
41
- object: "response",
42
- created_at: createdAt,
43
- model,
44
- status: "in_progress",
45
- background: false,
46
- completed_at: null,
47
- error: null,
48
- incomplete_details: null,
49
- instructions: null,
50
- max_output_tokens: null,
51
- output,
52
- parallel_tool_calls: true,
53
- previous_response_id: null,
54
- reasoning: null,
55
- store: false,
56
- temperature: null,
57
- text: { format: { type: "text" } },
58
- tool_choice: "auto",
59
- tools: [],
60
- top_p: null,
61
- truncation: "disabled",
62
- usage: null,
63
- metadata: {},
64
- };
65
- let sequenceNumber = 0;
66
- const event = (name, payload) => sse(name, { ...payload, sequence_number: sequenceNumber++ });
67
- yield event("response.created", { type: "response.created", response });
68
- yield event("response.in_progress", { type: "response.in_progress", response });
69
- let outputIndex = 0;
70
- let messageId;
71
- let textValue = "";
72
- const toolIndexes = new Map();
73
- let usage;
74
- for await (const part of source) {
75
- if (part.type === "text-start") {
76
- messageId = `msg_${crypto.randomUUID().replaceAll("-", "")}`;
77
- yield event("response.output_item.added", {
78
- type: "response.output_item.added",
79
- output_index: outputIndex,
80
- item: {
81
- id: messageId,
82
- type: "message",
83
- role: "assistant",
84
- status: "in_progress",
85
- phase: "final_answer",
86
- content: [],
87
- },
88
- });
89
- yield event("response.content_part.added", {
90
- type: "response.content_part.added",
91
- item_id: messageId,
92
- output_index: outputIndex,
93
- content_index: 0,
94
- part: { type: "output_text", text: "", annotations: [], logprobs: [] },
95
- });
96
- }
97
- else if (part.type === "text-delta") {
98
- textValue += part.text;
99
- yield event("response.output_text.delta", {
100
- type: "response.output_text.delta",
101
- item_id: messageId,
102
- output_index: outputIndex,
103
- content_index: 0,
104
- delta: part.text,
105
- logprobs: [],
106
- });
107
- }
108
- else if (part.type === "text-end") {
109
- yield event("response.output_text.done", {
110
- type: "response.output_text.done",
111
- item_id: messageId,
112
- output_index: outputIndex,
113
- content_index: 0,
114
- text: textValue,
115
- logprobs: [],
116
- });
117
- yield event("response.content_part.done", {
118
- type: "response.content_part.done",
119
- item_id: messageId,
120
- output_index: outputIndex,
121
- content_index: 0,
122
- part: { type: "output_text", text: textValue, annotations: [], logprobs: [] },
123
- });
124
- const item = {
125
- id: messageId,
126
- type: "message",
127
- role: "assistant",
128
- status: "completed",
129
- phase: "final_answer",
130
- content: [{ type: "output_text", text: textValue, annotations: [], logprobs: [] }],
131
- };
132
- output.push(item);
133
- yield event("response.output_item.done", {
134
- type: "response.output_item.done",
135
- output_index: outputIndex,
136
- item,
137
- });
138
- outputIndex++;
139
- textValue = "";
140
- }
141
- else if (part.type === "reasoning-delta") {
142
- yield event("response.reasoning_summary_text.delta", {
143
- type: "response.reasoning_summary_text.delta",
144
- output_index: outputIndex,
145
- delta: part.text,
146
- });
147
- }
148
- else if (part.type === "tool-input-start") {
149
- toolIndexes.set(part.id, outputIndex);
150
- yield event("response.output_item.added", {
151
- type: "response.output_item.added",
152
- output_index: outputIndex,
153
- item: {
154
- id: `fc_${part.id}`,
155
- type: "function_call",
156
- call_id: part.id,
157
- name: part.toolName,
158
- arguments: "",
159
- status: "in_progress",
160
- },
161
- });
162
- outputIndex++;
163
- }
164
- else if (part.type === "tool-input-delta") {
165
- yield event("response.function_call_arguments.delta", {
166
- type: "response.function_call_arguments.delta",
167
- item_id: `fc_${part.id}`,
168
- output_index: toolIndexes.get(part.id) ?? outputIndex,
169
- delta: part.delta,
170
- });
171
- }
172
- else if (part.type === "tool-call") {
173
- const index = toolIndexes.get(part.toolCallId) ?? outputIndex++;
174
- const item = {
175
- id: `fc_${part.toolCallId}`,
176
- type: "function_call",
177
- call_id: part.toolCallId,
178
- name: part.toolName,
179
- arguments: JSON.stringify(part.input),
180
- status: "completed",
181
- };
182
- yield event("response.function_call_arguments.done", {
183
- type: "response.function_call_arguments.done",
184
- item_id: `fc_${part.toolCallId}`,
185
- output_index: index,
186
- arguments: JSON.stringify(part.input),
187
- });
188
- yield event("response.output_item.done", {
189
- type: "response.output_item.done",
190
- output_index: index,
191
- item,
192
- });
193
- output.push(item);
194
- }
195
- else if (part.type === "finish") {
196
- usage = part.totalUsage;
197
- }
198
- else if (part.type === "error") {
199
- yield event("error", protocolError(part.error));
200
- }
201
- }
202
- yield event("response.completed", {
203
- type: "response.completed",
204
- response: {
205
- ...response,
206
- status: "completed",
207
- completed_at: Math.floor(Date.now() / 1000),
208
- usage: responsesUsage(usage),
209
- },
210
- });
211
- }
212
- async function* chatEvents(model, source) {
213
- const id = `chatcmpl-${crypto.randomUUID().replaceAll("-", "")}`;
214
- const created = Math.floor(Date.now() / 1000);
215
- yield data({
216
- id,
217
- object: "chat.completion.chunk",
218
- created,
219
- model,
220
- choices: [{ index: 0, delta: { role: "assistant", content: "" }, finish_reason: null }],
221
- });
222
- const toolIndexes = new Map();
223
- let nextToolIndex = 0;
224
- for await (const part of source) {
225
- if (part.type === "text-delta") {
226
- yield data({
227
- id,
228
- object: "chat.completion.chunk",
229
- created,
230
- model,
231
- choices: [{ index: 0, delta: { content: part.text }, finish_reason: null }],
232
- });
233
- }
234
- else if (part.type === "tool-input-start") {
235
- const index = nextToolIndex++;
236
- toolIndexes.set(part.id, index);
237
- yield data({
238
- id,
239
- object: "chat.completion.chunk",
240
- created,
241
- model,
242
- choices: [
243
- {
244
- index: 0,
245
- delta: {
246
- tool_calls: [
247
- {
248
- index,
249
- id: part.id,
250
- type: "function",
251
- function: { name: part.toolName, arguments: "" },
252
- },
253
- ],
254
- },
255
- finish_reason: null,
256
- },
257
- ],
258
- });
259
- }
260
- else if (part.type === "tool-input-delta") {
261
- yield data({
262
- id,
263
- object: "chat.completion.chunk",
264
- created,
265
- model,
266
- choices: [
267
- {
268
- index: 0,
269
- delta: {
270
- tool_calls: [
271
- {
272
- index: toolIndexes.get(part.id) ?? 0,
273
- function: { arguments: part.delta },
274
- },
275
- ],
276
- },
277
- finish_reason: null,
278
- },
279
- ],
280
- });
281
- }
282
- else if (part.type === "finish") {
283
- yield data({
284
- id,
285
- object: "chat.completion.chunk",
286
- created,
287
- model,
288
- choices: [{ index: 0, delta: {}, finish_reason: chatFinishReason(part.finishReason) }],
289
- usage: chatUsage(part.totalUsage),
290
- });
291
- }
292
- else if (part.type === "error") {
293
- yield data(protocolError(part.error));
294
- }
295
- }
296
- yield "data: [DONE]\n\n";
297
- }
298
- async function* anthropicEvents(model, source) {
299
- const id = `msg_${crypto.randomUUID().replaceAll("-", "")}`;
300
- yield sse("message_start", {
301
- type: "message_start",
302
- message: {
303
- id,
304
- type: "message",
305
- role: "assistant",
306
- model,
307
- content: [],
308
- stop_reason: null,
309
- stop_sequence: null,
310
- usage: { input_tokens: 0, output_tokens: 0 },
311
- },
312
- });
313
- let contentIndex = 0;
314
- const toolIndexes = new Map();
315
- for await (const part of source) {
316
- if (part.type === "text-start") {
317
- yield sse("content_block_start", {
318
- type: "content_block_start",
319
- index: contentIndex,
320
- content_block: { type: "text", text: "" },
321
- });
322
- }
323
- else if (part.type === "text-delta") {
324
- yield sse("content_block_delta", {
325
- type: "content_block_delta",
326
- index: contentIndex,
327
- delta: { type: "text_delta", text: part.text },
328
- });
329
- }
330
- else if (part.type === "text-end") {
331
- yield sse("content_block_stop", { type: "content_block_stop", index: contentIndex++ });
332
- }
333
- else if (part.type === "tool-input-start") {
334
- toolIndexes.set(part.id, contentIndex);
335
- yield sse("content_block_start", {
336
- type: "content_block_start",
337
- index: contentIndex++,
338
- content_block: { type: "tool_use", id: part.id, name: part.toolName, input: {} },
339
- });
340
- }
341
- else if (part.type === "tool-input-delta") {
342
- yield sse("content_block_delta", {
343
- type: "content_block_delta",
344
- index: toolIndexes.get(part.id) ?? 0,
345
- delta: { type: "input_json_delta", partial_json: part.delta },
346
- });
347
- }
348
- else if (part.type === "tool-input-end") {
349
- yield sse("content_block_stop", {
350
- type: "content_block_stop",
351
- index: toolIndexes.get(part.id) ?? 0,
352
- });
353
- }
354
- else if (part.type === "finish") {
355
- yield sse("message_delta", {
356
- type: "message_delta",
357
- delta: { stop_reason: anthropicFinishReason(part.finishReason), stop_sequence: null },
358
- usage: { output_tokens: part.totalUsage.outputTokens ?? 0 },
359
- });
360
- }
361
- else if (part.type === "error") {
362
- yield sse("error", protocolError(part.error));
363
- }
364
- }
365
- yield sse("message_stop", { type: "message_stop" });
366
- }
367
- function responsesObject(model, generation) {
368
- const output = [];
369
- if (generation.text) {
370
- output.push({
371
- id: `msg_${crypto.randomUUID().replaceAll("-", "")}`,
372
- type: "message",
373
- role: "assistant",
374
- status: "completed",
375
- content: [{ type: "output_text", text: generation.text, annotations: [] }],
376
- });
377
- }
378
- for (const call of generation.toolCalls) {
379
- output.push({
380
- id: `fc_${call.toolCallId}`,
381
- type: "function_call",
382
- call_id: call.toolCallId,
383
- name: call.toolName,
384
- arguments: JSON.stringify(call.input),
385
- status: "completed",
386
- });
387
- }
388
- return {
389
- id: `resp_${crypto.randomUUID().replaceAll("-", "")}`,
390
- object: "response",
391
- created_at: Math.floor(Date.now() / 1000),
392
- status: "completed",
393
- model,
394
- output,
395
- usage: responsesUsage(generation.usage),
396
- };
397
- }
398
- function chatObject(model, generation) {
399
- return {
400
- id: `chatcmpl-${crypto.randomUUID().replaceAll("-", "")}`,
401
- object: "chat.completion",
402
- created: Math.floor(Date.now() / 1000),
403
- model,
404
- choices: [
405
- {
406
- index: 0,
407
- message: {
408
- role: "assistant",
409
- content: generation.text || null,
410
- ...(generation.toolCalls.length > 0
411
- ? {
412
- tool_calls: generation.toolCalls.map((call) => ({
413
- id: call.toolCallId,
414
- type: "function",
415
- function: { name: call.toolName, arguments: JSON.stringify(call.input) },
416
- })),
417
- }
418
- : {}),
419
- },
420
- finish_reason: chatFinishReason(generation.finishReason),
421
- },
422
- ],
423
- usage: chatUsage(generation.usage),
424
- };
425
- }
426
- function anthropicObject(model, generation) {
427
- return {
428
- id: `msg_${crypto.randomUUID().replaceAll("-", "")}`,
429
- type: "message",
430
- role: "assistant",
431
- model,
432
- content: [
433
- ...(generation.text ? [{ type: "text", text: generation.text }] : []),
434
- ...generation.toolCalls.map((call) => ({
435
- type: "tool_use",
436
- id: call.toolCallId,
437
- name: call.toolName,
438
- input: call.input,
439
- })),
440
- ],
441
- stop_reason: anthropicFinishReason(generation.finishReason),
442
- stop_sequence: null,
443
- usage: {
444
- input_tokens: generation.usage.inputTokens ?? 0,
445
- output_tokens: generation.usage.outputTokens ?? 0,
446
- },
447
- };
448
- }
449
- function responsesUsage(usage) {
450
- const input = usage?.inputTokens ?? 0;
451
- const output = usage?.outputTokens ?? 0;
452
- return {
453
- input_tokens: input,
454
- output_tokens: output,
455
- total_tokens: input + output,
456
- input_tokens_details: { cached_tokens: usage?.inputTokenDetails.cacheReadTokens ?? 0 },
457
- output_tokens_details: {
458
- reasoning_tokens: usage?.outputTokenDetails.reasoningTokens ?? 0,
459
- },
460
- };
461
- }
462
- function chatUsage(usage) {
463
- const input = usage.inputTokens ?? 0;
464
- const output = usage.outputTokens ?? 0;
465
- return { prompt_tokens: input, completion_tokens: output, total_tokens: input + output };
466
- }
467
- function chatFinishReason(reason) {
468
- if (reason === "tool-calls")
469
- return "tool_calls";
470
- if (reason === "length")
471
- return "length";
472
- if (reason === "content-filter")
473
- return "content_filter";
474
- return "stop";
475
- }
476
- function anthropicFinishReason(reason) {
477
- if (reason === "tool-calls")
478
- return "tool_use";
479
- if (reason === "length")
480
- return "max_tokens";
481
- return "end_turn";
482
- }
483
- function protocolError(error) {
484
- return {
485
- type: "error",
486
- error: {
487
- type: "api_error",
488
- message: error instanceof Error ? error.message : String(error),
489
- },
490
- };
491
- }
492
- function sse(event, payload) {
493
- return `event: ${event}\ndata: ${JSON.stringify(payload)}\n\n`;
494
- }
495
- function data(payload) {
496
- return `data: ${JSON.stringify(payload)}\n\n`;
497
- }
498
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Byb3RvY29scy9lbmNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQWFILG9GQUFvRjtBQUNwRixNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLFFBQXdCLEVBQ3hCLEtBQWEsRUFDYixNQUE4QztJQUU5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLE9BQU8sSUFBSSxjQUFjLENBQWE7UUFDcEMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFVO1lBQ3BCLElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sR0FDVixRQUFRLEtBQUssa0JBQWtCO29CQUM3QixDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7b0JBQ2hDLENBQUMsQ0FBQyxRQUFRLEtBQUssb0JBQW9CO3dCQUNqQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7d0JBQ2hDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNsQyxJQUFJLEtBQUssRUFBRSxNQUFNLEtBQUssSUFBSSxNQUFNO29CQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUM1RSxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDckIsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQixDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxpRkFBaUY7QUFDakYsTUFBTSxVQUFVLHFCQUFxQixDQUNuQyxRQUF3QixFQUN4QixLQUFhLEVBQ2IsVUFBK0I7SUFFL0IsSUFBSSxRQUFRLEtBQUssa0JBQWtCO1FBQUUsT0FB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SyxZQUFZO1FBQUUsT0FBTyxVQUFVLENBQUM7SUFDL0MsSUFBSSxNQUFNLEtBQUssUUFBUTtRQUFFLE9BQU8sWUFBWSxDQUFDO0lBQzdDLE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxLQUFjO0lBQ25DLE9BQU87UUFDTCxJQUFJLEVBQUUsT0FBTztRQUNiLEtBQUssRUFBRTtZQUNMLElBQUksRUFBRSxXQUFXO1lBQ2pCLE9BQU8sRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ2hFO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLEdBQUcsQ0FBQyxLQUFhLEVBQUUsT0FBZ0I7SUFDMUMsT0FBTyxVQUFVLEtBQUssV0FBVyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFDakUsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLE9BQWdCO0lBQzVCLE9BQU8sU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFDaEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3RyZWFtaW5nIGFuZCBidWZmZXJlZCBwcm90b2NvbCBlbmNvZGVycyBmb3IgQUkgU0RLIGZhbGxiYWNrIHJlc3VsdHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgQ2xpZW50UHJvdG9jb2wgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuaW1wb3J0IHR5cGUgeyBGaW5pc2hSZWFzb24sIExhbmd1YWdlTW9kZWxVc2FnZSwgVGV4dFN0cmVhbVBhcnQsIFRvb2xTZXQsIFR5cGVkVG9vbENhbGwgfSBmcm9tIFwiYWlcIjtcblxuLyoqIENvbXBsZXRlZCBBSSBTREsgZ2VuZXJhdGlvbiBkYXRhIHVzZWQgYnkgbm9uLXN0cmVhbWluZyBlbmNvZGVycy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGxldGVkR2VuZXJhdGlvbiB7XG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbiAgcmVhZG9ubHkgdG9vbENhbGxzOiByZWFkb25seSBUeXBlZFRvb2xDYWxsPFRvb2xTZXQ+W107XG4gIHJlYWRvbmx5IHVzYWdlOiBMYW5ndWFnZU1vZGVsVXNhZ2U7XG4gIHJlYWRvbmx5IGZpbmlzaFJlYXNvbjogRmluaXNoUmVhc29uO1xufVxuXG4vKiogRW5jb2RlIEFJIFNESyBldmVudHMgYXMgdGhlIHJlcXVlc3RlZCBwcm90b2NvbCB3aGlsZSBwcmVzZXJ2aW5nIGJhY2twcmVzc3VyZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVHYXRld2F5U3RyZWFtKFxuICBwcm90b2NvbDogQ2xpZW50UHJvdG9jb2wsXG4gIG1vZGVsOiBzdHJpbmcsXG4gIHNvdXJjZTogQXN5bmNJdGVyYWJsZTxUZXh0U3RyZWFtUGFydDxUb29sU2V0Pj4sXG4pOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pih7XG4gICAgYXN5bmMgc3RhcnQoY29udHJvbGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZXZlbnRzID1cbiAgICAgICAgICBwcm90b2NvbCA9PT0gXCJvcGVuYWktcmVzcG9uc2VzXCJcbiAgICAgICAgICAgID8gcmVzcG9uc2VzRXZlbnRzKG1vZGVsLCBzb3VyY2UpXG4gICAgICAgICAgICA6IHByb3RvY29sID09PSBcImFudGhyb3BpYy1tZXNzYWdlc1wiXG4gICAgICAgICAgICAgID8gYW50aHJvcGljRXZlbnRzKG1vZGVsLCBzb3VyY2UpXG4gICAgICAgICAgICAgIDogY2hhdEV2ZW50cyhtb2RlbCwgc291cmNlKTtcbiAgICAgICAgZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBldmVudHMpIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVyLmVuY29kZShldmVudCkpO1xuICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIEVuY29kZSBhIGNvbXBsZXRlZCBBSSBTREsgZ2VuZXJhdGlvbiBhcyBvbmUgcHJvdG9jb2wtbmF0aXZlIEpTT04gcmVzcG9uc2UuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlR2F0ZXdheVJlc3BvbnNlKFxuICBwcm90b2NvbDogQ2xpZW50UHJvdG9jb2wsXG4gIG1vZGVsOiBzdHJpbmcsXG4gIGdlbmVyYXRpb246IENvbXBsZXRlZEdlbmVyYXRpb24sXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChwcm90b2NvbCA9PT0gXCJvcGVuYWktcmVzcG9uc2VzXCIpIHJldHVybiByZXNwb25zZXNPYmplY3QobW9kZWwsIGdlbmVyYXRpb24pO1xuICBpZiAocHJvdG9jb2wgPT09IFwiYW50aHJvcGljLW1lc3NhZ2VzXCIpIHJldHVybiBhbnRocm9waWNPYmplY3QobW9kZWwsIGdlbmVyYXRpb24pO1xuICByZXR1cm4gY2hhdE9iamVjdChtb2RlbCwgZ2VuZXJhdGlvbik7XG59XG5cbmFzeW5jIGZ1bmN0aW9uKiByZXNwb25zZXNFdmVudHMoXG4gIG1vZGVsOiBzdHJpbmcsXG4gIHNvdXJjZTogQXN5bmNJdGVyYWJsZTxUZXh0U3RyZWFtUGFydDxUb29sU2V0Pj4sXG4pOiBBc3luY0dlbmVyYXRvcjxzdHJpbmc+IHtcbiAgY29uc3QgcmVzcG9uc2VJZCA9IGByZXNwXyR7Y3J5cHRvLnJhbmRvbVVVSUQoKS5yZXBsYWNlQWxsKFwiLVwiLCBcIlwiKX1gO1xuICBjb25zdCBjcmVhdGVkQXQgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgY29uc3Qgb3V0cHV0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdID0gW107XG4gIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgIGlkOiByZXNwb25zZUlkLFxuICAgIG9iamVjdDogXCJyZXNwb25zZVwiLFxuICAgIGNyZWF0ZWRfYXQ6IGNyZWF0ZWRBdCxcbiAgICBtb2RlbCxcbiAgICBzdGF0dXM6IFwiaW5fcHJvZ3Jlc3NcIixcbiAgICBiYWNrZ3JvdW5kOiBmYWxzZSxcbiAgICBjb21wbGV0ZWRfYXQ6IG51bGwsXG4gICAgZXJyb3I6IG51bGwsXG4gICAgaW5jb21wbGV0ZV9kZXRhaWxzOiBudWxsLFxuICAgIGluc3RydWN0aW9uczogbnVsbCxcbiAgICBtYXhfb3V0cHV0X3Rva2VuczogbnVsbCxcbiAgICBvdXRwdXQsXG4gICAgcGFyYWxsZWxfdG9vbF9jYWxsczogdHJ1ZSxcbiAgICBwcmV2aW91c19yZXNwb25zZV9pZDogbnVsbCxcbiAgICByZWFzb25pbmc6IG51bGwsXG4gICAgc3RvcmU6IGZhbHNlLFxuICAgIHRlbXBlcmF0dXJlOiBudWxsLFxuICAgIHRleHQ6IHsgZm9ybWF0OiB7IHR5cGU6IFwidGV4dFwiIH0gfSxcbiAgICB0b29sX2Nob2ljZTogXCJhdXRvXCIsXG4gICAgdG9vbHM6IFtdLFxuICAgIHRvcF9wOiBudWxsLFxuICAgIHRydW5jYXRpb246IFwiZGlzYWJsZWRcIixcbiAgICB1c2FnZTogbnVsbCxcbiAgICBtZXRhZGF0YToge30sXG4gIH07XG4gIGxldCBzZXF1ZW5jZU51bWJlciA9IDA7XG4gIGNvbnN0IGV2ZW50ID0gKG5hbWU6IHN0cmluZywgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+XG4gICAgc3NlKG5hbWUsIHsgLi4ucGF5bG9hZCwgc2VxdWVuY2VfbnVtYmVyOiBzZXF1ZW5jZU51bWJlcisrIH0pO1xuICB5aWVsZCBldmVudChcInJlc3BvbnNlLmNyZWF0ZWRcIiwgeyB0eXBlOiBcInJlc3BvbnNlLmNyZWF0ZWRcIiwgcmVzcG9uc2UgfSk7XG4gIHlpZWxkIGV2ZW50KFwicmVzcG9uc2UuaW5fcHJvZ3Jlc3NcIiwgeyB0eXBlOiBcInJlc3BvbnNlLmluX3Byb2dyZXNzXCIsIHJlc3BvbnNlIH0pO1xuICBsZXQgb3V0cHV0SW5kZXggPSAwO1xuICBsZXQgbWVzc2FnZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxldCB0ZXh0VmFsdWUgPSBcIlwiO1xuICBjb25zdCB0b29sSW5kZXhlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIGxldCB1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlIHwgdW5kZWZpbmVkO1xuXG4gIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzb3VyY2UpIHtcbiAgICBpZiAocGFydC50eXBlID09PSBcInRleHQtc3RhcnRcIikge1xuICAgICAgbWVzc2FnZUlkID0gYG1zZ18ke2NyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZUFsbChcIi1cIiwgXCJcIil9YDtcbiAgICAgIHlpZWxkIGV2ZW50KFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uYWRkZWRcIiwge1xuICAgICAgICB0eXBlOiBcInJlc3BvbnNlLm91dHB1dF9pdGVtLmFkZGVkXCIsXG4gICAgICAgIG91dHB1dF9pbmRleDogb3V0cHV0SW5kZXgsXG4gICAgICAgIGl0ZW06IHtcbiAgICAgICAgICBpZDogbWVzc2FnZUlkLFxuICAgICAgICAgIHR5cGU6IFwibWVzc2FnZVwiLFxuICAgICAgICAgIHJvbGU6IFwiYXNzaXN0YW50XCIsXG4gICAgICAgICAgc3RhdHVzOiBcImluX3Byb2dyZXNzXCIsXG4gICAgICAgICAgcGhhc2U6IFwiZmluYWxfYW5zd2VyXCIsXG4gICAgICAgICAgY29udGVudDogW10sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHlpZWxkIGV2ZW50KFwicmVzcG9uc2UuY29udGVudF9wYXJ0LmFkZGVkXCIsIHtcbiAgICAgICAgdHlwZTogXCJyZXNwb25zZS5jb250ZW50X3BhcnQuYWRkZWRcIixcbiAgICAgICAgaXRlbV9pZDogbWVzc2FnZUlkLFxuICAgICAgICBvdXRwdXRfaW5kZXg6IG91dHB1dEluZGV4LFxuICAgICAgICBjb250ZW50X2luZGV4OiAwLFxuICAgICAgICBwYXJ0OiB7IHR5cGU6IFwib3V0cHV0X3RleHRcIiwgdGV4dDogXCJcIiwgYW5ub3RhdGlvbnM6IFtdLCBsb2dwcm9iczogW10gfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcInRleHQtZGVsdGFcIikge1xuICAgICAgdGV4dFZhbHVlICs9IHBhcnQudGV4dDtcbiAgICAgIHlpZWxkIGV2ZW50KFwicmVzcG9uc2Uub3V0cHV0X3RleHQuZGVsdGFcIiwge1xuICAgICAgICB0eXBlOiBcInJlc3BvbnNlLm91dHB1dF90ZXh0LmRlbHRhXCIsXG4gICAgICAgIGl0ZW1faWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgb3V0cHV0X2luZGV4OiBvdXRwdXRJbmRleCxcbiAgICAgICAgY29udGVudF9pbmRleDogMCxcbiAgICAgICAgZGVsdGE6IHBhcnQudGV4dCxcbiAgICAgICAgbG9ncHJvYnM6IFtdLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwidGV4dC1lbmRcIikge1xuICAgICAgeWllbGQgZXZlbnQoXCJyZXNwb25zZS5vdXRwdXRfdGV4dC5kb25lXCIsIHtcbiAgICAgICAgdHlwZTogXCJyZXNwb25zZS5vdXRwdXRfdGV4dC5kb25lXCIsXG4gICAgICAgIGl0ZW1faWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgb3V0cHV0X2luZGV4OiBvdXRwdXRJbmRleCxcbiAgICAgICAgY29udGVudF9pbmRleDogMCxcbiAgICAgICAgdGV4dDogdGV4dFZhbHVlLFxuICAgICAgICBsb2dwcm9iczogW10sXG4gICAgICB9KTtcbiAgICAgIHlpZWxkIGV2ZW50KFwicmVzcG9uc2UuY29udGVudF9wYXJ0LmRvbmVcIiwge1xuICAgICAgICB0eXBlOiBcInJlc3BvbnNlLmNvbnRlbnRfcGFydC5kb25lXCIsXG4gICAgICAgIGl0ZW1faWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgb3V0cHV0X2luZGV4OiBvdXRwdXRJbmRleCxcbiAgICAgICAgY29udGVudF9pbmRleDogMCxcbiAgICAgICAgcGFydDogeyB0eXBlOiBcIm91dHB1dF90ZXh0XCIsIHRleHQ6IHRleHRWYWx1ZSwgYW5ub3RhdGlvbnM6IFtdLCBsb2dwcm9iczogW10gfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgaXRlbSA9IHtcbiAgICAgICAgaWQ6IG1lc3NhZ2VJZCxcbiAgICAgICAgdHlwZTogXCJtZXNzYWdlXCIsXG4gICAgICAgIHJvbGU6IFwiYXNzaXN0YW50XCIsXG4gICAgICAgIHN0YXR1czogXCJjb21wbGV0ZWRcIixcbiAgICAgICAgcGhhc2U6IFwiZmluYWxfYW5zd2VyXCIsXG4gICAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwib3V0cHV0X3RleHRcIiwgdGV4dDogdGV4dFZhbHVlLCBhbm5vdGF0aW9uczogW10sIGxvZ3Byb2JzOiBbXSB9XSxcbiAgICAgIH07XG4gICAgICBvdXRwdXQucHVzaChpdGVtKTtcbiAgICAgIHlpZWxkIGV2ZW50KFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uZG9uZVwiLCB7XG4gICAgICAgIHR5cGU6IFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uZG9uZVwiLFxuICAgICAgICBvdXRwdXRfaW5kZXg6IG91dHB1dEluZGV4LFxuICAgICAgICBpdGVtLFxuICAgICAgfSk7XG4gICAgICBvdXRwdXRJbmRleCsrO1xuICAgICAgdGV4dFZhbHVlID0gXCJcIjtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJyZWFzb25pbmctZGVsdGFcIikge1xuICAgICAgeWllbGQgZXZlbnQoXCJyZXNwb25zZS5yZWFzb25pbmdfc3VtbWFyeV90ZXh0LmRlbHRhXCIsIHtcbiAgICAgICAgdHlwZTogXCJyZXNwb25zZS5yZWFzb25pbmdfc3VtbWFyeV90ZXh0LmRlbHRhXCIsXG4gICAgICAgIG91dHB1dF9pbmRleDogb3V0cHV0SW5kZXgsXG4gICAgICAgIGRlbHRhOiBwYXJ0LnRleHQsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWlucHV0LXN0YXJ0XCIpIHtcbiAgICAgIHRvb2xJbmRleGVzLnNldChwYXJ0LmlkLCBvdXRwdXRJbmRleCk7XG4gICAgICB5aWVsZCBldmVudChcInJlc3BvbnNlLm91dHB1dF9pdGVtLmFkZGVkXCIsIHtcbiAgICAgICAgdHlwZTogXCJyZXNwb25zZS5vdXRwdXRfaXRlbS5hZGRlZFwiLFxuICAgICAgICBvdXRwdXRfaW5kZXg6IG91dHB1dEluZGV4LFxuICAgICAgICBpdGVtOiB7XG4gICAgICAgICAgaWQ6IGBmY18ke3BhcnQuaWR9YCxcbiAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uX2NhbGxcIixcbiAgICAgICAgICBjYWxsX2lkOiBwYXJ0LmlkLFxuICAgICAgICAgIG5hbWU6IHBhcnQudG9vbE5hbWUsXG4gICAgICAgICAgYXJndW1lbnRzOiBcIlwiLFxuICAgICAgICAgIHN0YXR1czogXCJpbl9wcm9ncmVzc1wiLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBvdXRwdXRJbmRleCsrO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcInRvb2wtaW5wdXQtZGVsdGFcIikge1xuICAgICAgeWllbGQgZXZlbnQoXCJyZXNwb25zZS5mdW5jdGlvbl9jYWxsX2FyZ3VtZW50cy5kZWx0YVwiLCB7XG4gICAgICAgIHR5cGU6IFwicmVzcG9uc2UuZnVuY3Rpb25fY2FsbF9hcmd1bWVudHMuZGVsdGFcIixcbiAgICAgICAgaXRlbV9pZDogYGZjXyR7cGFydC5pZH1gLFxuICAgICAgICBvdXRwdXRfaW5kZXg6IHRvb2xJbmRleGVzLmdldChwYXJ0LmlkKSA/PyBvdXRwdXRJbmRleCxcbiAgICAgICAgZGVsdGE6IHBhcnQuZGVsdGEsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWNhbGxcIikge1xuICAgICAgY29uc3QgaW5kZXggPSB0b29sSW5kZXhlcy5nZXQocGFydC50b29sQ2FsbElkKSA/PyBvdXRwdXRJbmRleCsrO1xuICAgICAgY29uc3QgaXRlbSA9IHtcbiAgICAgICAgaWQ6IGBmY18ke3BhcnQudG9vbENhbGxJZH1gLFxuICAgICAgICB0eXBlOiBcImZ1bmN0aW9uX2NhbGxcIixcbiAgICAgICAgY2FsbF9pZDogcGFydC50b29sQ2FsbElkLFxuICAgICAgICBuYW1lOiBwYXJ0LnRvb2xOYW1lLFxuICAgICAgICBhcmd1bWVudHM6IEpTT04uc3RyaW5naWZ5KHBhcnQuaW5wdXQpLFxuICAgICAgICBzdGF0dXM6IFwiY29tcGxldGVkXCIsXG4gICAgICB9O1xuICAgICAgeWllbGQgZXZlbnQoXCJyZXNwb25zZS5mdW5jdGlvbl9jYWxsX2FyZ3VtZW50cy5kb25lXCIsIHtcbiAgICAgICAgdHlwZTogXCJyZXNwb25zZS5mdW5jdGlvbl9jYWxsX2FyZ3VtZW50cy5kb25lXCIsXG4gICAgICAgIGl0ZW1faWQ6IGBmY18ke3BhcnQudG9vbENhbGxJZH1gLFxuICAgICAgICBvdXRwdXRfaW5kZXg6IGluZGV4LFxuICAgICAgICBhcmd1bWVudHM6IEpTT04uc3RyaW5naWZ5KHBhcnQuaW5wdXQpLFxuICAgICAgfSk7XG4gICAgICB5aWVsZCBldmVudChcInJlc3BvbnNlLm91dHB1dF9pdGVtLmRvbmVcIiwge1xuICAgICAgICB0eXBlOiBcInJlc3BvbnNlLm91dHB1dF9pdGVtLmRvbmVcIixcbiAgICAgICAgb3V0cHV0X2luZGV4OiBpbmRleCxcbiAgICAgICAgaXRlbSxcbiAgICAgIH0pO1xuICAgICAgb3V0cHV0LnB1c2goaXRlbSk7XG4gICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmluaXNoXCIpIHtcbiAgICAgIHVzYWdlID0gcGFydC50b3RhbFVzYWdlO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgIHlpZWxkIGV2ZW50KFwiZXJyb3JcIiwgcHJvdG9jb2xFcnJvcihwYXJ0LmVycm9yKSk7XG4gICAgfVxuICB9XG4gIHlpZWxkIGV2ZW50KFwicmVzcG9uc2UuY29tcGxldGVkXCIsIHtcbiAgICB0eXBlOiBcInJlc3BvbnNlLmNvbXBsZXRlZFwiLFxuICAgIHJlc3BvbnNlOiB7XG4gICAgICAuLi5yZXNwb25zZSxcbiAgICAgIHN0YXR1czogXCJjb21wbGV0ZWRcIixcbiAgICAgIGNvbXBsZXRlZF9hdDogTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCksXG4gICAgICB1c2FnZTogcmVzcG9uc2VzVXNhZ2UodXNhZ2UpLFxuICAgIH0sXG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiogY2hhdEV2ZW50cyhcbiAgbW9kZWw6IHN0cmluZyxcbiAgc291cmNlOiBBc3luY0l0ZXJhYmxlPFRleHRTdHJlYW1QYXJ0PFRvb2xTZXQ+Pixcbik6IEFzeW5jR2VuZXJhdG9yPHN0cmluZz4ge1xuICBjb25zdCBpZCA9IGBjaGF0Y21wbC0ke2NyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZUFsbChcIi1cIiwgXCJcIil9YDtcbiAgY29uc3QgY3JlYXRlZCA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICB5aWVsZCBkYXRhKHtcbiAgICBpZCxcbiAgICBvYmplY3Q6IFwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXG4gICAgY3JlYXRlZCxcbiAgICBtb2RlbCxcbiAgICBjaG9pY2VzOiBbeyBpbmRleDogMCwgZGVsdGE6IHsgcm9sZTogXCJhc3Npc3RhbnRcIiwgY29udGVudDogXCJcIiB9LCBmaW5pc2hfcmVhc29uOiBudWxsIH1dLFxuICB9KTtcbiAgY29uc3QgdG9vbEluZGV4ZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBsZXQgbmV4dFRvb2xJbmRleCA9IDA7XG4gIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBzb3VyY2UpIHtcbiAgICBpZiAocGFydC50eXBlID09PSBcInRleHQtZGVsdGFcIikge1xuICAgICAgeWllbGQgZGF0YSh7XG4gICAgICAgIGlkLFxuICAgICAgICBvYmplY3Q6IFwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXG4gICAgICAgIGNyZWF0ZWQsXG4gICAgICAgIG1vZGVsLFxuICAgICAgICBjaG9pY2VzOiBbeyBpbmRleDogMCwgZGVsdGE6IHsgY29udGVudDogcGFydC50ZXh0IH0sIGZpbmlzaF9yZWFzb246IG51bGwgfV0sXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWlucHV0LXN0YXJ0XCIpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gbmV4dFRvb2xJbmRleCsrO1xuICAgICAgdG9vbEluZGV4ZXMuc2V0KHBhcnQuaWQsIGluZGV4KTtcbiAgICAgIHlpZWxkIGRhdGEoe1xuICAgICAgICBpZCxcbiAgICAgICAgb2JqZWN0OiBcImNoYXQuY29tcGxldGlvbi5jaHVua1wiLFxuICAgICAgICBjcmVhdGVkLFxuICAgICAgICBtb2RlbCxcbiAgICAgICAgY2hvaWNlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgZGVsdGE6IHtcbiAgICAgICAgICAgICAgdG9vbF9jYWxsczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgaWQ6IHBhcnQuaWQsXG4gICAgICAgICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICAgICAgICBmdW5jdGlvbjogeyBuYW1lOiBwYXJ0LnRvb2xOYW1lLCBhcmd1bWVudHM6IFwiXCIgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZpbmlzaF9yZWFzb246IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcInRvb2wtaW5wdXQtZGVsdGFcIikge1xuICAgICAgeWllbGQgZGF0YSh7XG4gICAgICAgIGlkLFxuICAgICAgICBvYmplY3Q6IFwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXG4gICAgICAgIGNyZWF0ZWQsXG4gICAgICAgIG1vZGVsLFxuICAgICAgICBjaG9pY2VzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICBkZWx0YToge1xuICAgICAgICAgICAgICB0b29sX2NhbGxzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaW5kZXg6IHRvb2xJbmRleGVzLmdldChwYXJ0LmlkKSA/PyAwLFxuICAgICAgICAgICAgICAgICAgZnVuY3Rpb246IHsgYXJndW1lbnRzOiBwYXJ0LmRlbHRhIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaW5pc2hfcmVhc29uOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaW5pc2hcIikge1xuICAgICAgeWllbGQgZGF0YSh7XG4gICAgICAgIGlkLFxuICAgICAgICBvYmplY3Q6IFwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXG4gICAgICAgIGNyZWF0ZWQsXG4gICAgICAgIG1vZGVsLFxuICAgICAgICBjaG9pY2VzOiBbeyBpbmRleDogMCwgZGVsdGE6IHt9LCBmaW5pc2hfcmVhc29uOiBjaGF0RmluaXNoUmVhc29uKHBhcnQuZmluaXNoUmVhc29uKSB9XSxcbiAgICAgICAgdXNhZ2U6IGNoYXRVc2FnZShwYXJ0LnRvdGFsVXNhZ2UpLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgeWllbGQgZGF0YShwcm90b2NvbEVycm9yKHBhcnQuZXJyb3IpKTtcbiAgICB9XG4gIH1cbiAgeWllbGQgXCJkYXRhOiBbRE9ORV1cXG5cXG5cIjtcbn1cblxuYXN5bmMgZnVuY3Rpb24qIGFudGhyb3BpY0V2ZW50cyhcbiAgbW9kZWw6IHN0cmluZyxcbiAgc291cmNlOiBBc3luY0l0ZXJhYmxlPFRleHRTdHJlYW1QYXJ0PFRvb2xTZXQ+Pixcbik6IEFzeW5jR2VuZXJhdG9yPHN0cmluZz4ge1xuICBjb25zdCBpZCA9IGBtc2dfJHtjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2VBbGwoXCItXCIsIFwiXCIpfWA7XG4gIHlpZWxkIHNzZShcIm1lc3NhZ2Vfc3RhcnRcIiwge1xuICAgIHR5cGU6IFwibWVzc2FnZV9zdGFydFwiLFxuICAgIG1lc3NhZ2U6IHtcbiAgICAgIGlkLFxuICAgICAgdHlwZTogXCJtZXNzYWdlXCIsXG4gICAgICByb2xlOiBcImFzc2lzdGFudFwiLFxuICAgICAgbW9kZWwsXG4gICAgICBjb250ZW50OiBbXSxcbiAgICAgIHN0b3BfcmVhc29uOiBudWxsLFxuICAgICAgc3RvcF9zZXF1ZW5jZTogbnVsbCxcbiAgICAgIHVzYWdlOiB7IGlucHV0X3Rva2VuczogMCwgb3V0cHV0X3Rva2VuczogMCB9LFxuICAgIH0sXG4gIH0pO1xuICBsZXQgY29udGVudEluZGV4ID0gMDtcbiAgY29uc3QgdG9vbEluZGV4ZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2Ygc291cmNlKSB7XG4gICAgaWYgKHBhcnQudHlwZSA9PT0gXCJ0ZXh0LXN0YXJ0XCIpIHtcbiAgICAgIHlpZWxkIHNzZShcImNvbnRlbnRfYmxvY2tfc3RhcnRcIiwge1xuICAgICAgICB0eXBlOiBcImNvbnRlbnRfYmxvY2tfc3RhcnRcIixcbiAgICAgICAgaW5kZXg6IGNvbnRlbnRJbmRleCxcbiAgICAgICAgY29udGVudF9ibG9jazogeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCJcIiB9LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwidGV4dC1kZWx0YVwiKSB7XG4gICAgICB5aWVsZCBzc2UoXCJjb250ZW50X2Jsb2NrX2RlbHRhXCIsIHtcbiAgICAgICAgdHlwZTogXCJjb250ZW50X2Jsb2NrX2RlbHRhXCIsXG4gICAgICAgIGluZGV4OiBjb250ZW50SW5kZXgsXG4gICAgICAgIGRlbHRhOiB7IHR5cGU6IFwidGV4dF9kZWx0YVwiLCB0ZXh0OiBwYXJ0LnRleHQgfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcInRleHQtZW5kXCIpIHtcbiAgICAgIHlpZWxkIHNzZShcImNvbnRlbnRfYmxvY2tfc3RvcFwiLCB7IHR5cGU6IFwiY29udGVudF9ibG9ja19zdG9wXCIsIGluZGV4OiBjb250ZW50SW5kZXgrKyB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWlucHV0LXN0YXJ0XCIpIHtcbiAgICAgIHRvb2xJbmRleGVzLnNldChwYXJ0LmlkLCBjb250ZW50SW5kZXgpO1xuICAgICAgeWllbGQgc3NlKFwiY29udGVudF9ibG9ja19zdGFydFwiLCB7XG4gICAgICAgIHR5cGU6IFwiY29udGVudF9ibG9ja19zdGFydFwiLFxuICAgICAgICBpbmRleDogY29udGVudEluZGV4KyssXG4gICAgICAgIGNvbnRlbnRfYmxvY2s6IHsgdHlwZTogXCJ0b29sX3VzZVwiLCBpZDogcGFydC5pZCwgbmFtZTogcGFydC50b29sTmFtZSwgaW5wdXQ6IHt9IH0sXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWlucHV0LWRlbHRhXCIpIHtcbiAgICAgIHlpZWxkIHNzZShcImNvbnRlbnRfYmxvY2tfZGVsdGFcIiwge1xuICAgICAgICB0eXBlOiBcImNvbnRlbnRfYmxvY2tfZGVsdGFcIixcbiAgICAgICAgaW5kZXg6IHRvb2xJbmRleGVzLmdldChwYXJ0LmlkKSA/PyAwLFxuICAgICAgICBkZWx0YTogeyB0eXBlOiBcImlucHV0X2pzb25fZGVsdGFcIiwgcGFydGlhbF9qc29uOiBwYXJ0LmRlbHRhIH0sXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJ0b29sLWlucHV0LWVuZFwiKSB7XG4gICAgICB5aWVsZCBzc2UoXCJjb250ZW50X2Jsb2NrX3N0b3BcIiwge1xuICAgICAgICB0eXBlOiBcImNvbnRlbnRfYmxvY2tfc3RvcFwiLFxuICAgICAgICBpbmRleDogdG9vbEluZGV4ZXMuZ2V0KHBhcnQuaWQpID8/IDAsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaW5pc2hcIikge1xuICAgICAgeWllbGQgc3NlKFwibWVzc2FnZV9kZWx0YVwiLCB7XG4gICAgICAgIHR5cGU6IFwibWVzc2FnZV9kZWx0YVwiLFxuICAgICAgICBkZWx0YTogeyBzdG9wX3JlYXNvbjogYW50aHJvcGljRmluaXNoUmVhc29uKHBhcnQuZmluaXNoUmVhc29uKSwgc3RvcF9zZXF1ZW5jZTogbnVsbCB9LFxuICAgICAgICB1c2FnZTogeyBvdXRwdXRfdG9rZW5zOiBwYXJ0LnRvdGFsVXNhZ2Uub3V0cHV0VG9rZW5zID8/IDAgfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgIHlpZWxkIHNzZShcImVycm9yXCIsIHByb3RvY29sRXJyb3IocGFydC5lcnJvcikpO1xuICAgIH1cbiAgfVxuICB5aWVsZCBzc2UoXCJtZXNzYWdlX3N0b3BcIiwgeyB0eXBlOiBcIm1lc3NhZ2Vfc3RvcFwiIH0pO1xufVxuXG5mdW5jdGlvbiByZXNwb25zZXNPYmplY3QobW9kZWw6IHN0cmluZywgZ2VuZXJhdGlvbjogQ29tcGxldGVkR2VuZXJhdGlvbik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgY29uc3Qgb3V0cHV0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdID0gW107XG4gIGlmIChnZW5lcmF0aW9uLnRleHQpIHtcbiAgICBvdXRwdXQucHVzaCh7XG4gICAgICBpZDogYG1zZ18ke2NyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZUFsbChcIi1cIiwgXCJcIil9YCxcbiAgICAgIHR5cGU6IFwibWVzc2FnZVwiLFxuICAgICAgcm9sZTogXCJhc3Npc3RhbnRcIixcbiAgICAgIHN0YXR1czogXCJjb21wbGV0ZWRcIixcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwib3V0cHV0X3RleHRcIiwgdGV4dDogZ2VuZXJhdGlvbi50ZXh0LCBhbm5vdGF0aW9uczogW10gfV0sXG4gICAgfSk7XG4gIH1cbiAgZm9yIChjb25zdCBjYWxsIG9mIGdlbmVyYXRpb24udG9vbENhbGxzKSB7XG4gICAgb3V0cHV0LnB1c2goe1xuICAgICAgaWQ6IGBmY18ke2NhbGwudG9vbENhbGxJZH1gLFxuICAgICAgdHlwZTogXCJmdW5jdGlvbl9jYWxsXCIsXG4gICAgICBjYWxsX2lkOiBjYWxsLnRvb2xDYWxsSWQsXG4gICAgICBuYW1lOiBjYWxsLnRvb2xOYW1lLFxuICAgICAgYXJndW1lbnRzOiBKU09OLnN0cmluZ2lmeShjYWxsLmlucHV0KSxcbiAgICAgIHN0YXR1czogXCJjb21wbGV0ZWRcIixcbiAgICB9KTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGlkOiBgcmVzcF8ke2NyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZUFsbChcIi1cIiwgXCJcIil9YCxcbiAgICBvYmplY3Q6IFwicmVzcG9uc2VcIixcbiAgICBjcmVhdGVkX2F0OiBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSxcbiAgICBzdGF0dXM6IFwiY29tcGxldGVkXCIsXG4gICAgbW9kZWwsXG4gICAgb3V0cHV0LFxuICAgIHVzYWdlOiByZXNwb25zZXNVc2FnZShnZW5lcmF0aW9uLnVzYWdlKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2hhdE9iamVjdChtb2RlbDogc3RyaW5nLCBnZW5lcmF0aW9uOiBDb21wbGV0ZWRHZW5lcmF0aW9uKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4ge1xuICAgIGlkOiBgY2hhdGNtcGwtJHtjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2VBbGwoXCItXCIsIFwiXCIpfWAsXG4gICAgb2JqZWN0OiBcImNoYXQuY29tcGxldGlvblwiLFxuICAgIGNyZWF0ZWQ6IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApLFxuICAgIG1vZGVsLFxuICAgIGNob2ljZXM6IFtcbiAgICAgIHtcbiAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgICByb2xlOiBcImFzc2lzdGFudFwiLFxuICAgICAgICAgIGNvbnRlbnQ6IGdlbmVyYXRpb24udGV4dCB8fCBudWxsLFxuICAgICAgICAgIC4uLihnZW5lcmF0aW9uLnRvb2xDYWxscy5sZW5ndGggPiAwXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICB0b29sX2NhbGxzOiBnZW5lcmF0aW9uLnRvb2xDYWxscy5tYXAoKGNhbGwpID0+ICh7XG4gICAgICAgICAgICAgICAgICBpZDogY2FsbC50b29sQ2FsbElkLFxuICAgICAgICAgICAgICAgICAgdHlwZTogXCJmdW5jdGlvblwiLFxuICAgICAgICAgICAgICAgICAgZnVuY3Rpb246IHsgbmFtZTogY2FsbC50b29sTmFtZSwgYXJndW1lbnRzOiBKU09OLnN0cmluZ2lmeShjYWxsLmlucHV0KSB9LFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICAgIH0sXG4gICAgICAgIGZpbmlzaF9yZWFzb246IGNoYXRGaW5pc2hSZWFzb24oZ2VuZXJhdGlvbi5maW5pc2hSZWFzb24pLFxuICAgICAgfSxcbiAgICBdLFxuICAgIHVzYWdlOiBjaGF0VXNhZ2UoZ2VuZXJhdGlvbi51c2FnZSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGFudGhyb3BpY09iamVjdChtb2RlbDogc3RyaW5nLCBnZW5lcmF0aW9uOiBDb21wbGV0ZWRHZW5lcmF0aW9uKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4ge1xuICAgIGlkOiBgbXNnXyR7Y3J5cHRvLnJhbmRvbVVVSUQoKS5yZXBsYWNlQWxsKFwiLVwiLCBcIlwiKX1gLFxuICAgIHR5cGU6IFwibWVzc2FnZVwiLFxuICAgIHJvbGU6IFwiYXNzaXN0YW50XCIsXG4gICAgbW9kZWwsXG4gICAgY29udGVudDogW1xuICAgICAgLi4uKGdlbmVyYXRpb24udGV4dCA/IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBnZW5lcmF0aW9uLnRleHQgfV0gOiBbXSksXG4gICAgICAuLi5nZW5lcmF0aW9uLnRvb2xDYWxscy5tYXAoKGNhbGwpID0+ICh7XG4gICAgICAgIHR5cGU6IFwidG9vbF91c2VcIixcbiAgICAgICAgaWQ6IGNhbGwudG9vbENhbGxJZCxcbiAgICAgICAgbmFtZTogY2FsbC50b29sTmFtZSxcbiAgICAgICAgaW5wdXQ6IGNhbGwuaW5wdXQsXG4gICAgICB9KSksXG4gICAgXSxcbiAgICBzdG9wX3JlYXNvbjogYW50aHJvcGljRmluaXNoUmVhc29uKGdlbmVyYXRpb24uZmluaXNoUmVhc29uKSxcbiAgICBzdG9wX3NlcXVlbmNlOiBudWxsLFxuICAgIHVzYWdlOiB7XG4gICAgICBpbnB1dF90b2tlbnM6IGdlbmVyYXRpb24udXNhZ2UuaW5wdXRUb2tlbnMgPz8gMCxcbiAgICAgIG91dHB1dF90b2tlbnM6IGdlbmVyYXRpb24udXNhZ2Uub3V0cHV0VG9rZW5zID8/IDAsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVzcG9uc2VzVXNhZ2UodXNhZ2U6IExhbmd1YWdlTW9kZWxVc2FnZSB8IHVuZGVmaW5lZCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgY29uc3QgaW5wdXQgPSB1c2FnZT8uaW5wdXRUb2tlbnMgPz8gMDtcbiAgY29uc3Qgb3V0cHV0ID0gdXNhZ2U/Lm91dHB1dFRva2VucyA/PyAwO1xuICByZXR1cm4ge1xuICAgIGlucHV0X3Rva2VuczogaW5wdXQsXG4gICAgb3V0cHV0X3Rva2Vuczogb3V0cHV0LFxuICAgIHRvdGFsX3Rva2VuczogaW5wdXQgKyBvdXRwdXQsXG4gICAgaW5wdXRfdG9rZW5zX2RldGFpbHM6IHsgY2FjaGVkX3Rva2VuczogdXNhZ2U/LmlucHV0VG9rZW5EZXRhaWxzLmNhY2hlUmVhZFRva2VucyA/PyAwIH0sXG4gICAgb3V0cHV0X3Rva2Vuc19kZXRhaWxzOiB7XG4gICAgICByZWFzb25pbmdfdG9rZW5zOiB1c2FnZT8ub3V0cHV0VG9rZW5EZXRhaWxzLnJlYXNvbmluZ1Rva2VucyA/PyAwLFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNoYXRVc2FnZSh1c2FnZTogTGFuZ3VhZ2VNb2RlbFVzYWdlKTogUmVjb3JkPHN0cmluZywgbnVtYmVyPiB7XG4gIGNvbnN0IGlucHV0ID0gdXNhZ2UuaW5wdXRUb2tlbnMgPz8gMDtcbiAgY29uc3Qgb3V0cHV0ID0gdXNhZ2Uub3V0cHV0VG9rZW5zID8/IDA7XG4gIHJldHVybiB7IHByb21wdF90b2tlbnM6IGlucHV0LCBjb21wbGV0aW9uX3Rva2Vuczogb3V0cHV0LCB0b3RhbF90b2tlbnM6IGlucHV0ICsgb3V0cHV0IH07XG59XG5cbmZ1bmN0aW9uIGNoYXRGaW5pc2hSZWFzb24ocmVhc29uOiBGaW5pc2hSZWFzb24pOiBzdHJpbmcge1xuICBpZiAocmVhc29uID09PSBcInRvb2wtY2FsbHNcIikgcmV0dXJuIFwidG9vbF9jYWxsc1wiO1xuICBpZiAocmVhc29uID09PSBcImxlbmd0aFwiKSByZXR1cm4gXCJsZW5ndGhcIjtcbiAgaWYgKHJlYXNvbiA9PT0gXCJjb250ZW50LWZpbHRlclwiKSByZXR1cm4gXCJjb250ZW50X2ZpbHRlclwiO1xuICByZXR1cm4gXCJzdG9wXCI7XG59XG5cbmZ1bmN0aW9uIGFudGhyb3BpY0ZpbmlzaFJlYXNvbihyZWFzb246IEZpbmlzaFJlYXNvbik6IHN0cmluZyB7XG4gIGlmIChyZWFzb24gPT09IFwidG9vbC1jYWxsc1wiKSByZXR1cm4gXCJ0b29sX3VzZVwiO1xuICBpZiAocmVhc29uID09PSBcImxlbmd0aFwiKSByZXR1cm4gXCJtYXhfdG9rZW5zXCI7XG4gIHJldHVybiBcImVuZF90dXJuXCI7XG59XG5cbmZ1bmN0aW9uIHByb3RvY29sRXJyb3IoZXJyb3I6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogXCJlcnJvclwiLFxuICAgIGVycm9yOiB7XG4gICAgICB0eXBlOiBcImFwaV9lcnJvclwiLFxuICAgICAgbWVzc2FnZTogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNzZShldmVudDogc3RyaW5nLCBwYXlsb2FkOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBldmVudDogJHtldmVudH1cXG5kYXRhOiAke0pTT04uc3RyaW5naWZ5KHBheWxvYWQpfVxcblxcbmA7XG59XG5cbmZ1bmN0aW9uIGRhdGEocGF5bG9hZDogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiBgZGF0YTogJHtKU09OLnN0cmluZ2lmeShwYXlsb2FkKX1cXG5cXG5gO1xufVxuIl19