@dbx-tools/appkit-model-gateway 0.9.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +63 -0
  3. package/index.ts +28 -0
  4. package/lib/index.d.ts +24 -0
  5. package/lib/index.js +21 -0
  6. package/lib/scripts/copy-manifest.d.ts +1 -0
  7. package/lib/scripts/copy-manifest.js +14 -0
  8. package/lib/src/gateway.d.ts +29 -0
  9. package/lib/src/gateway.js +127 -0
  10. package/lib/src/manifest.json +13 -0
  11. package/lib/src/models.d.ts +10 -0
  12. package/lib/src/models.js +119 -0
  13. package/lib/src/plugin.d.ts +32 -0
  14. package/lib/src/plugin.js +70 -0
  15. package/lib/src/protocols/decode.d.ts +17 -0
  16. package/lib/src/protocols/decode.js +262 -0
  17. package/lib/src/protocols/encode.d.ts +18 -0
  18. package/lib/src/protocols/encode.js +498 -0
  19. package/lib/src/reasoning-adapt.d.ts +27 -0
  20. package/lib/src/reasoning-adapt.js +61 -0
  21. package/lib/src/registry.d.ts +32 -0
  22. package/lib/src/registry.js +167 -0
  23. package/lib/src/router.d.ts +18 -0
  24. package/lib/src/router.js +139 -0
  25. package/lib/src/routes.d.ts +14 -0
  26. package/lib/src/routes.js +158 -0
  27. package/lib/src/translation.d.ts +8 -0
  28. package/lib/src/translation.js +156 -0
  29. package/lib/src/transport.d.ts +19 -0
  30. package/lib/src/transport.js +168 -0
  31. package/lib/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +150 -0
  33. package/src/gateway.ts +167 -0
  34. package/src/manifest.json +13 -0
  35. package/src/models.ts +152 -0
  36. package/src/plugin.ts +95 -0
  37. package/src/protocols/decode.ts +281 -0
  38. package/src/protocols/encode.ts +515 -0
  39. package/src/reasoning-adapt.ts +87 -0
  40. package/src/registry.ts +225 -0
  41. package/src/router.ts +174 -0
  42. package/src/routes.ts +181 -0
  43. package/src/translation.ts +178 -0
  44. package/src/transport.ts +182 -0
@@ -0,0 +1,498 @@
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
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Reasoning-effort adaptation for gateway round trips.
3
+ *
4
+ * Proactively remaps client efforts onto the known ladder, then on a single
5
+ * unsupported-value 400 learns from the error and retries once with the
6
+ * updated ladder.
7
+ *
8
+ * @module
9
+ */
10
+ /** Result of the first proactive adaptation pass. */
11
+ export interface AdaptedInferenceBody {
12
+ readonly body: Readonly<Record<string, unknown>>;
13
+ readonly wireEffort?: string;
14
+ readonly changed: boolean;
15
+ }
16
+ /** Adapt a request body onto the current known ladder for `model`. */
17
+ export declare function adaptInferenceReasoning(model: string, body: Readonly<Record<string, unknown>>): AdaptedInferenceBody;
18
+ /**
19
+ * On an unsupported-reasoning 400, learn once and optionally produce a
20
+ * remapped retry body. Returns `undefined` when no retry should occur.
21
+ */
22
+ export declare function learnAndAdaptReasoningRetry(input: {
23
+ readonly model: string;
24
+ readonly body: Readonly<Record<string, unknown>>;
25
+ readonly response: Response;
26
+ readonly previousWireEffort?: string;
27
+ }): Promise<Readonly<Record<string, unknown>> | undefined>;