@aws-amplify/graphql-api-construct 1.16.0 → 1.16.1-ai-next.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.jsii +19 -19
- package/CHANGELOG.md +4 -0
- package/lib/amplify-dynamodb-table-wrapper.js +1 -1
- package/lib/amplify-graphql-api.js +1 -1
- package/lib/amplify-graphql-definition.js +1 -1
- package/lib/sql-model-datasource-strategy.js +1 -1
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/conversation_handler_construct.d.ts +19 -1
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/conversation_handler_construct.js +36 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/index.d.ts +2 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/index.js +1 -1
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/bedrock_converse_adapter.d.ts +11 -4
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/bedrock_converse_adapter.js +279 -67
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/conversation_message_history_retriever.js +34 -8
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/conversation_turn_executor.d.ts +2 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/conversation_turn_executor.js +17 -4
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/conversation_turn_response_sender.d.ts +17 -3
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/conversation_turn_response_sender.js +56 -18
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/default_handler.d.ts +1 -1
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/event-tools-provider/event_tools_provider.js +2 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/event-tools-provider/graphql_tool.d.ts +7 -7
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/event-tools-provider/graphql_tool.js +3 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/executable_tool_factory.d.ts +7 -0
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/executable_tool_factory.js +16 -0
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/graphql_request_executor.d.ts +2 -1
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/graphql_request_executor.js +4 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/index.d.ts +3 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/index.js +4 -2
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/types.d.ts +71 -14
- package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/types.js +1 -1
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/README.md +4 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/ai/conversation/index.d.ts +23 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/ai/conversation/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/ai/conversation/v1.d.ts +22 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/ai/conversation/v1.js +11 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/auth/index.d.ts +118 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/auth/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/auth/v1.d.ts +117 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/auth/v1.js +31 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/custom/index.d.ts +23 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/custom/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/custom/v1.d.ts +22 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/custom/v1.js +11 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/function/index.d.ts +23 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/function/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/function/v1.d.ts +22 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/function/v1.js +11 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/graphql/index.d.ts +59 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/graphql/index.js +12 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/graphql/v1.d.ts +59 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/graphql/v1.js +25 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/index.d.ts +515 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/index.js +112 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/platform/index.d.ts +2 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/platform/index.js +18 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/platform/stack_metadata_schemas.d.ts +42 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/platform/stack_metadata_schemas.js +22 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/stack/index.d.ts +28 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/stack/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/stack/v1.d.ts +27 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/stack/v1.js +12 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/storage/index.d.ts +33 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/storage/index.js +10 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/storage/v1.d.ts +32 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/lib/storage/v1.js +33 -0
- package/node_modules/@aws-amplify/ai-constructs/node_modules/@aws-amplify/backend-output-schemas/package.json +27 -0
- package/node_modules/@aws-amplify/ai-constructs/package.json +9 -2
- package/node_modules/@aws-amplify/graphql-auth-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-auth-transformer/package.json +11 -11
- package/node_modules/@aws-amplify/graphql-conversation-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/conversation-directive-configuration.d.ts +4 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/conversation-directive-configuration.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/message-model.d.ts +5 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/message-model.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/message-model.js +61 -3
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/message-model.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/name-values.d.ts +2 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/name-values.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/name-values.js +4 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/graphql-types/name-values.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/assistant-response-stream-pipeline-definition.d.ts +3 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/assistant-response-stream-pipeline-definition.d.ts.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/assistant-response-stream-pipeline-definition.js +58 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/assistant-response-stream-pipeline-definition.js.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/index.d.ts +5 -2
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/index.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/index.js +9 -3
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/index.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-conversations-init-resolver-definition.d.ts +3 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-conversations-init-resolver-definition.d.ts.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-conversations-init-resolver-definition.js +24 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-conversations-init-resolver-definition.js.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/{list-messages-init-resolver.d.ts → list-messages-init-resolver-definition.d.ts} +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-init-resolver-definition.d.ts.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/{list-messages-init-resolver.js → list-messages-init-resolver-definition.js} +2 -2
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-init-resolver-definition.js.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-post-processing-resolver-definition.d.ts +3 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-post-processing-resolver-definition.d.ts.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-post-processing-resolver-definition.js +10 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-post-processing-resolver-definition.js.map +1 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/send-message-pipeline-definition.js +5 -2
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/send-message-pipeline-definition.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/assistant-streaming-mutation-resolver-fn.template.js +95 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/invoke-lambda-resolver-fn.template.js +6 -4
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/list-conversations-init-set-index-resolver-fn.template.js +12 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/list-messages-init-set-index-resolver-fn.template.js +36 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/list-messages-post-processing-resolver-fn.template.js +12 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/set-updated-at-conversation-table-fn.template.js +31 -0
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-field-handler.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-field-handler.js +8 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-field-handler.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-prepare-handler.d.ts +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-prepare-handler.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-prepare-handler.js +6 -2
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-prepare-handler.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-resolver-generator.d.ts +3 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-resolver-generator.d.ts.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-resolver-generator.js +26 -3
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/transformer-steps/conversation-resolver-generator.js.map +1 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/package.json +9 -9
- package/node_modules/@aws-amplify/graphql-default-value-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-default-value-transformer/package.json +6 -6
- package/node_modules/@aws-amplify/graphql-function-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-function-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-generation-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-generation-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-http-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-http-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-index-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-index-transformer/package.json +6 -6
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/lib/assets/mapping-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-maps-to-transformer/package.json +9 -9
- package/node_modules/@aws-amplify/graphql-model-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-notification-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-patching-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-model-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-predictions-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-predictions-transformer/lib/predictionsLambdaFunction.zip +0 -0
- package/node_modules/@aws-amplify/graphql-predictions-transformer/package.json +5 -5
- package/node_modules/@aws-amplify/graphql-relational-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-relational-transformer/package.json +7 -7
- package/node_modules/@aws-amplify/graphql-searchable-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-searchable-transformer/lib/streaming-lambda.zip +0 -0
- package/node_modules/@aws-amplify/graphql-searchable-transformer/package.json +6 -6
- package/node_modules/@aws-amplify/graphql-sql-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-sql-transformer/package.json +6 -6
- package/node_modules/@aws-amplify/graphql-transformer/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-transformer/package.json +17 -17
- package/node_modules/@aws-amplify/graphql-transformer-core/CHANGELOG.md +4 -0
- package/node_modules/@aws-amplify/graphql-transformer-core/package.json +3 -3
- package/node_modules/graphql-transformer-common/API.md +1 -0
- package/node_modules/graphql-transformer-common/CHANGELOG.md +4 -0
- package/node_modules/graphql-transformer-common/lib/TypescriptSchemaConstants.d.ts +1 -0
- package/node_modules/graphql-transformer-common/lib/TypescriptSchemaConstants.d.ts.map +1 -1
- package/node_modules/graphql-transformer-common/lib/TypescriptSchemaConstants.js +1 -0
- package/node_modules/graphql-transformer-common/lib/TypescriptSchemaConstants.js.map +1 -1
- package/node_modules/graphql-transformer-common/package.json +2 -2
- package/package.json +20 -20
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-init-resolver.d.ts.map +0 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/list-messages-init-resolver.js.map +0 -1
- package/node_modules/@aws-amplify/graphql-conversation-transformer/lib/resolvers/templates/list-messages-init-resolver-fn.template.js +0 -8
package/node_modules/@aws-amplify/ai-constructs/lib/conversation/runtime/bedrock_converse_adapter.js
CHANGED
@@ -12,52 +12,71 @@ class BedrockConverseAdapter {
|
|
12
12
|
/**
|
13
13
|
* Creates Bedrock Converse Adapter.
|
14
14
|
*/
|
15
|
-
constructor(event, additionalTools, bedrockClient = new client_bedrock_runtime_1.BedrockRuntimeClient({ region: event.modelConfiguration.region }), eventToolsProvider = new event_tools_provider_1.ConversationTurnEventToolsProvider(event), messageHistoryRetriever = new conversation_message_history_retriever_1.ConversationMessageHistoryRetriever(event)) {
|
15
|
+
constructor(event, additionalTools, bedrockClient = new client_bedrock_runtime_1.BedrockRuntimeClient({ region: event.modelConfiguration.region }), eventToolsProvider = new event_tools_provider_1.ConversationTurnEventToolsProvider(event), messageHistoryRetriever = new conversation_message_history_retriever_1.ConversationMessageHistoryRetriever(event), logger = console) {
|
16
16
|
var _a, _b;
|
17
17
|
this.event = event;
|
18
18
|
this.bedrockClient = bedrockClient;
|
19
19
|
this.messageHistoryRetriever = messageHistoryRetriever;
|
20
|
+
this.logger = logger;
|
20
21
|
this.executableToolByName = new Map();
|
21
22
|
this.clientToolByName = new Map();
|
22
23
|
this.askBedrock = async () => {
|
23
24
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
var _a, _b;
|
45
|
-
return ((_a = block.toolUse) === null || _a === void 0 ? void 0 : _a.name) &&
|
46
|
-
this.clientToolByName.has((_b = block.toolUse) === null || _b === void 0 ? void 0 : _b.name);
|
47
|
-
});
|
48
|
-
if (clientToolUseBlocks.length > 0) {
|
49
|
-
// For now if any of client tools is used we ignore executable tools
|
50
|
-
// and propagate result back to client.
|
51
|
-
return clientToolUseBlocks;
|
25
|
+
try {
|
26
|
+
const { modelId, systemPrompt, inferenceConfiguration } = this.event.modelConfiguration;
|
27
|
+
const messages = await this.getEventMessagesAsBedrockMessages();
|
28
|
+
let bedrockResponse;
|
29
|
+
do {
|
30
|
+
const toolConfig = this.createToolConfiguration();
|
31
|
+
const converseCommandInput = {
|
32
|
+
modelId,
|
33
|
+
messages: [...messages],
|
34
|
+
system: [{ text: systemPrompt }],
|
35
|
+
inferenceConfig: inferenceConfiguration,
|
36
|
+
toolConfig,
|
37
|
+
};
|
38
|
+
this.logger.info('Sending Bedrock Converse request');
|
39
|
+
this.logger.debug('Bedrock Converse request:', converseCommandInput);
|
40
|
+
bedrockResponse = await this.bedrockClient.send(new client_bedrock_runtime_1.ConverseCommand(converseCommandInput));
|
41
|
+
this.logger.info(`Received Bedrock Converse response, requestId=${bedrockResponse.$metadata.requestId}`, bedrockResponse.usage);
|
42
|
+
this.logger.debug('Bedrock Converse response:', bedrockResponse);
|
43
|
+
if ((_a = bedrockResponse.output) === null || _a === void 0 ? void 0 : _a.message) {
|
44
|
+
messages.push((_b = bedrockResponse.output) === null || _b === void 0 ? void 0 : _b.message);
|
52
45
|
}
|
53
|
-
|
54
|
-
const
|
55
|
-
const
|
56
|
-
|
46
|
+
if (bedrockResponse.stopReason === 'tool_use') {
|
47
|
+
const responseContentBlocks = (_e = (_d = (_c = bedrockResponse.output) === null || _c === void 0 ? void 0 : _c.message) === null || _d === void 0 ? void 0 : _d.content) !== null && _e !== void 0 ? _e : [];
|
48
|
+
const toolUseBlocks = responseContentBlocks.filter((block) => 'toolUse' in block);
|
49
|
+
const clientToolUseBlocks = responseContentBlocks.filter((block) => {
|
50
|
+
var _a, _b;
|
51
|
+
return ((_a = block.toolUse) === null || _a === void 0 ? void 0 : _a.name) &&
|
52
|
+
this.clientToolByName.has((_b = block.toolUse) === null || _b === void 0 ? void 0 : _b.name);
|
53
|
+
});
|
54
|
+
if (clientToolUseBlocks.length > 0) {
|
55
|
+
// For now if any of client tools is used we ignore executable tools
|
56
|
+
// and propagate result back to client.
|
57
|
+
return { content: clientToolUseBlocks };
|
58
|
+
}
|
59
|
+
const toolResponseContentBlocks = [];
|
60
|
+
for (const responseContentBlock of toolUseBlocks) {
|
61
|
+
const toolUseBlock = responseContentBlock;
|
62
|
+
const toolResultContentBlock = await this.executeTool(toolUseBlock);
|
63
|
+
toolResponseContentBlocks.push(toolResultContentBlock);
|
64
|
+
}
|
65
|
+
messages.push({
|
66
|
+
role: 'user',
|
67
|
+
content: toolResponseContentBlocks,
|
68
|
+
});
|
57
69
|
}
|
58
|
-
}
|
59
|
-
|
60
|
-
|
70
|
+
} while (bedrockResponse.stopReason === 'tool_use');
|
71
|
+
return { content: (_h = (_g = (_f = bedrockResponse.output) === null || _f === void 0 ? void 0 : _f.message) === null || _g === void 0 ? void 0 : _g.content) !== null && _h !== void 0 ? _h : [] };
|
72
|
+
}
|
73
|
+
catch (error) {
|
74
|
+
console.error('Conversation with Bedrock failed', error);
|
75
|
+
const conversationTurnError = this.convertErrorToConversationTurnError(error);
|
76
|
+
return {
|
77
|
+
errors: [conversationTurnError],
|
78
|
+
};
|
79
|
+
}
|
61
80
|
};
|
62
81
|
/**
|
63
82
|
* Maps event messages to Bedrock types.
|
@@ -103,6 +122,8 @@ class BedrockConverseAdapter {
|
|
103
122
|
toolSpec: {
|
104
123
|
name: t.name,
|
105
124
|
description: t.description,
|
125
|
+
// We have to cast to bedrock type as we're using different types to describe JSON schema in our API.
|
126
|
+
// These types are runtime compatible.
|
106
127
|
inputSchema: t.inputSchema,
|
107
128
|
},
|
108
129
|
};
|
@@ -118,49 +139,67 @@ class BedrockConverseAdapter {
|
|
118
139
|
throw Error(`Bedrock tool use response contains unknown tool '${toolUseBlock.toolUse.name}'`);
|
119
140
|
}
|
120
141
|
try {
|
142
|
+
this.logger.info(`Invoking tool ${tool.name}`);
|
143
|
+
this.logger.debug('Tool input:', toolUseBlock.toolUse.input);
|
121
144
|
const toolResponse = await tool.execute(toolUseBlock.toolUse.input);
|
145
|
+
this.logger.info(`Received response from ${tool.name} tool`);
|
146
|
+
this.logger.debug(toolResponse);
|
122
147
|
return {
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
content: [toolResponse],
|
129
|
-
status: 'success',
|
130
|
-
},
|
131
|
-
},
|
132
|
-
],
|
148
|
+
toolResult: {
|
149
|
+
toolUseId: toolUseBlock.toolUse.toolUseId,
|
150
|
+
content: [toolResponse],
|
151
|
+
status: 'success',
|
152
|
+
},
|
133
153
|
};
|
134
154
|
}
|
135
155
|
catch (e) {
|
136
156
|
if (e instanceof Error) {
|
137
157
|
return {
|
138
|
-
|
139
|
-
|
140
|
-
{
|
141
|
-
|
142
|
-
|
143
|
-
content: [{ text: e.toString() }],
|
144
|
-
status: 'error',
|
145
|
-
},
|
146
|
-
},
|
147
|
-
],
|
158
|
+
toolResult: {
|
159
|
+
toolUseId: toolUseBlock.toolUse.toolUseId,
|
160
|
+
content: [{ text: e.toString() }],
|
161
|
+
status: 'error',
|
162
|
+
},
|
148
163
|
};
|
149
164
|
}
|
150
165
|
return {
|
151
|
-
|
152
|
-
|
153
|
-
{
|
154
|
-
|
155
|
-
|
156
|
-
content: [{ text: 'unknown error occurred' }],
|
157
|
-
status: 'error',
|
158
|
-
},
|
159
|
-
},
|
160
|
-
],
|
166
|
+
toolResult: {
|
167
|
+
toolUseId: toolUseBlock.toolUse.toolUseId,
|
168
|
+
content: [{ text: 'unknown error occurred' }],
|
169
|
+
status: 'error',
|
170
|
+
},
|
161
171
|
};
|
162
172
|
}
|
163
173
|
};
|
174
|
+
this.convertErrorToConversationTurnError = (error) => {
|
175
|
+
let errorType = 'UnknownError';
|
176
|
+
let message;
|
177
|
+
if (error instanceof Error) {
|
178
|
+
message = error.message;
|
179
|
+
if (error.name) {
|
180
|
+
errorType = error.name;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
message = JSON.stringify(error);
|
185
|
+
}
|
186
|
+
return {
|
187
|
+
errorType,
|
188
|
+
message,
|
189
|
+
};
|
190
|
+
};
|
191
|
+
if (event.request.headers['x-amz-user-agent']) {
|
192
|
+
this.bedrockClient.middlewareStack.add((next) => (args) => {
|
193
|
+
// @ts-expect-error Request is typed as unknown.
|
194
|
+
// But this is recommended way to alter headers per https://github.com/aws/aws-sdk-js-v3/blob/main/README.md.
|
195
|
+
args.request.headers['x-amz-user-agent'] =
|
196
|
+
event.request.headers['x-amz-user-agent'];
|
197
|
+
return next(args);
|
198
|
+
}, {
|
199
|
+
step: 'build',
|
200
|
+
name: 'amplify-user-agent-injector',
|
201
|
+
});
|
202
|
+
}
|
164
203
|
this.executableTools = [
|
165
204
|
...eventToolsProvider.getEventTools(),
|
166
205
|
...additionalTools,
|
@@ -189,6 +228,179 @@ class BedrockConverseAdapter {
|
|
189
228
|
].join(', ')}.`);
|
190
229
|
}
|
191
230
|
}
|
231
|
+
/**
|
232
|
+
* Asks Bedrock for response using streaming version of Converse API.
|
233
|
+
*/
|
234
|
+
async *askBedrockStreaming() {
|
235
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
236
|
+
// keep our own indexing for blocks instead of using Bedrock's indexes
|
237
|
+
// since we stream subset of these upstream.
|
238
|
+
let blockIndex = 0;
|
239
|
+
let lastBlockIndex = 0;
|
240
|
+
let stopReason = '';
|
241
|
+
// Accumulates client facing content per turn.
|
242
|
+
// So that upstream can persist full message at the end of the streaming.
|
243
|
+
const accumulatedTurnContent = [];
|
244
|
+
try {
|
245
|
+
const { modelId, systemPrompt, inferenceConfiguration } = this.event.modelConfiguration;
|
246
|
+
const messages = await this.getEventMessagesAsBedrockMessages();
|
247
|
+
let bedrockResponse;
|
248
|
+
do {
|
249
|
+
const toolConfig = this.createToolConfiguration();
|
250
|
+
const converseCommandInput = {
|
251
|
+
modelId,
|
252
|
+
messages: [...messages],
|
253
|
+
system: [{ text: systemPrompt }],
|
254
|
+
inferenceConfig: inferenceConfiguration,
|
255
|
+
toolConfig,
|
256
|
+
};
|
257
|
+
this.logger.info('Sending Bedrock Converse Stream request');
|
258
|
+
this.logger.debug('Bedrock Converse Stream request:', converseCommandInput);
|
259
|
+
bedrockResponse = await this.bedrockClient.send(new client_bedrock_runtime_1.ConverseStreamCommand(converseCommandInput));
|
260
|
+
this.logger.info(`Received Bedrock Converse Stream response, requestId=${bedrockResponse.$metadata.requestId}`);
|
261
|
+
if (!bedrockResponse.stream) {
|
262
|
+
throw new Error('Bedrock response is missing stream');
|
263
|
+
}
|
264
|
+
let toolUseBlock;
|
265
|
+
let clientToolsRequested = false;
|
266
|
+
let text = '';
|
267
|
+
let toolUseInput = '';
|
268
|
+
let blockDeltaIndex = 0;
|
269
|
+
let lastBlockDeltaIndex = 0;
|
270
|
+
// Accumulate current message for the tool use loop purpose.
|
271
|
+
const accumulatedAssistantMessage = {
|
272
|
+
role: undefined,
|
273
|
+
content: [],
|
274
|
+
};
|
275
|
+
for await (const chunk of bedrockResponse.stream) {
|
276
|
+
this.logger.debug('Bedrock Converse Stream response chunk:', chunk);
|
277
|
+
if (chunk.messageStart) {
|
278
|
+
accumulatedAssistantMessage.role = chunk.messageStart.role;
|
279
|
+
}
|
280
|
+
else if (chunk.contentBlockStart) {
|
281
|
+
blockDeltaIndex = 0;
|
282
|
+
lastBlockDeltaIndex = 0;
|
283
|
+
if ((_a = chunk.contentBlockStart.start) === null || _a === void 0 ? void 0 : _a.toolUse) {
|
284
|
+
toolUseBlock = {
|
285
|
+
toolUse: {
|
286
|
+
...(_b = chunk.contentBlockStart.start) === null || _b === void 0 ? void 0 : _b.toolUse,
|
287
|
+
input: undefined,
|
288
|
+
},
|
289
|
+
};
|
290
|
+
}
|
291
|
+
}
|
292
|
+
else if (chunk.contentBlockDelta) {
|
293
|
+
if ((_c = chunk.contentBlockDelta.delta) === null || _c === void 0 ? void 0 : _c.toolUse) {
|
294
|
+
if (!chunk.contentBlockDelta.delta.toolUse.input) {
|
295
|
+
toolUseInput = '';
|
296
|
+
}
|
297
|
+
toolUseInput += chunk.contentBlockDelta.delta.toolUse.input;
|
298
|
+
}
|
299
|
+
else if ((_d = chunk.contentBlockDelta.delta) === null || _d === void 0 ? void 0 : _d.text) {
|
300
|
+
text += chunk.contentBlockDelta.delta.text;
|
301
|
+
yield {
|
302
|
+
accumulatedTurnContent: [...accumulatedTurnContent, { text }],
|
303
|
+
conversationId: this.event.conversationId,
|
304
|
+
associatedUserMessageId: this.event.currentMessageId,
|
305
|
+
contentBlockText: chunk.contentBlockDelta.delta.text,
|
306
|
+
contentBlockIndex: blockIndex,
|
307
|
+
contentBlockDeltaIndex: blockDeltaIndex,
|
308
|
+
};
|
309
|
+
lastBlockDeltaIndex = blockDeltaIndex;
|
310
|
+
blockDeltaIndex++;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
else if (chunk.contentBlockStop) {
|
314
|
+
if (toolUseBlock) {
|
315
|
+
toolUseBlock.toolUse.input = JSON.parse(toolUseInput);
|
316
|
+
(_e = accumulatedAssistantMessage.content) === null || _e === void 0 ? void 0 : _e.push(toolUseBlock);
|
317
|
+
if (toolUseBlock.toolUse.name &&
|
318
|
+
this.clientToolByName.has(toolUseBlock.toolUse.name)) {
|
319
|
+
clientToolsRequested = true;
|
320
|
+
accumulatedTurnContent.push(toolUseBlock);
|
321
|
+
yield {
|
322
|
+
accumulatedTurnContent: [...accumulatedTurnContent],
|
323
|
+
conversationId: this.event.conversationId,
|
324
|
+
associatedUserMessageId: this.event.currentMessageId,
|
325
|
+
contentBlockIndex: blockIndex,
|
326
|
+
contentBlockToolUse: JSON.stringify(toolUseBlock),
|
327
|
+
};
|
328
|
+
lastBlockIndex = blockIndex;
|
329
|
+
blockIndex++;
|
330
|
+
}
|
331
|
+
toolUseBlock = undefined;
|
332
|
+
toolUseInput = '';
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
(_f = accumulatedAssistantMessage.content) === null || _f === void 0 ? void 0 : _f.push({
|
336
|
+
text,
|
337
|
+
});
|
338
|
+
accumulatedTurnContent.push({ text });
|
339
|
+
yield {
|
340
|
+
accumulatedTurnContent: [...accumulatedTurnContent],
|
341
|
+
conversationId: this.event.conversationId,
|
342
|
+
associatedUserMessageId: this.event.currentMessageId,
|
343
|
+
contentBlockIndex: blockIndex,
|
344
|
+
contentBlockDoneAtIndex: lastBlockDeltaIndex,
|
345
|
+
};
|
346
|
+
text = '';
|
347
|
+
lastBlockIndex = blockIndex;
|
348
|
+
blockIndex++;
|
349
|
+
}
|
350
|
+
}
|
351
|
+
else if (chunk.messageStop) {
|
352
|
+
stopReason = (_g = chunk.messageStop.stopReason) !== null && _g !== void 0 ? _g : '';
|
353
|
+
}
|
354
|
+
}
|
355
|
+
this.logger.debug('Accumulated Bedrock Converse Stream response:', accumulatedAssistantMessage);
|
356
|
+
if (clientToolsRequested) {
|
357
|
+
// For now if any of client tools is used we ignore executable tools
|
358
|
+
// and propagate result back to client.
|
359
|
+
yield {
|
360
|
+
accumulatedTurnContent: [...accumulatedTurnContent],
|
361
|
+
conversationId: this.event.conversationId,
|
362
|
+
associatedUserMessageId: this.event.currentMessageId,
|
363
|
+
contentBlockIndex: lastBlockIndex,
|
364
|
+
stopReason: stopReason,
|
365
|
+
};
|
366
|
+
return;
|
367
|
+
}
|
368
|
+
messages.push(accumulatedAssistantMessage);
|
369
|
+
if (stopReason === 'tool_use') {
|
370
|
+
const responseContentBlocks = (_h = accumulatedAssistantMessage.content) !== null && _h !== void 0 ? _h : [];
|
371
|
+
const toolUseBlocks = responseContentBlocks.filter((block) => 'toolUse' in block);
|
372
|
+
const toolResponseContentBlocks = [];
|
373
|
+
for (const responseContentBlock of toolUseBlocks) {
|
374
|
+
const toolUseBlock = responseContentBlock;
|
375
|
+
const toolResultContentBlock = await this.executeTool(toolUseBlock);
|
376
|
+
toolResponseContentBlocks.push(toolResultContentBlock);
|
377
|
+
}
|
378
|
+
messages.push({
|
379
|
+
role: 'user',
|
380
|
+
content: toolResponseContentBlocks,
|
381
|
+
});
|
382
|
+
}
|
383
|
+
} while (stopReason === 'tool_use');
|
384
|
+
yield {
|
385
|
+
accumulatedTurnContent: [...accumulatedTurnContent],
|
386
|
+
conversationId: this.event.conversationId,
|
387
|
+
associatedUserMessageId: this.event.currentMessageId,
|
388
|
+
contentBlockIndex: lastBlockIndex,
|
389
|
+
stopReason: stopReason,
|
390
|
+
};
|
391
|
+
}
|
392
|
+
catch (error) {
|
393
|
+
console.error('Streaming conversation with Bedrock failed', error);
|
394
|
+
const conversationTurnError = this.convertErrorToConversationTurnError(error);
|
395
|
+
yield {
|
396
|
+
accumulatedTurnContent: [...accumulatedTurnContent],
|
397
|
+
conversationId: this.event.conversationId,
|
398
|
+
associatedUserMessageId: this.event.currentMessageId,
|
399
|
+
contentBlockIndex: blockIndex,
|
400
|
+
errors: [conversationTurnError],
|
401
|
+
};
|
402
|
+
}
|
403
|
+
}
|
192
404
|
}
|
193
405
|
exports.BedrockConverseAdapter = BedrockConverseAdapter;
|
194
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9ja19jb252ZXJzZV9hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbnZlcnNhdGlvbi9ydW50aW1lL2JlZHJvY2tfY29udmVyc2VfYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0RUFTeUM7QUFNekMsaUVBQTRFO0FBQzVFLHFHQUErRjtBQUUvRjs7O0dBR0c7QUFDSCxNQUFhLHNCQUFzQjtJQVFqQzs7T0FFRztJQUNILFlBQ21CLEtBQTRCLEVBQzdDLGVBQXNDLEVBQ3JCLGdCQUFzQyxJQUFJLDZDQUFvQixDQUM3RSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLENBQzVDLEVBQ0Qsa0JBQWtCLEdBQUcsSUFBSSx5REFBa0MsQ0FBQyxLQUFLLENBQUMsRUFDakQsMEJBQTBCLElBQUksNEVBQW1DLENBQ2hGLEtBQUssQ0FDTjs7UUFSZ0IsVUFBSyxHQUFMLEtBQUssQ0FBdUI7UUFFNUIsa0JBQWEsR0FBYixhQUFhLENBRTdCO1FBRWdCLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FFdkM7UUFoQmMseUJBQW9CLEdBQ25DLElBQUksR0FBRyxFQUFFLENBQUM7UUFDSyxxQkFBZ0IsR0FBZ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQStDM0UsZUFBVSxHQUFHLEtBQUssSUFBNkIsRUFBRTs7WUFDL0MsTUFBTSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsR0FDckQsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FDWixNQUFNLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO1lBRWpELElBQUksZUFBc0MsQ0FBQztZQUMzQyxHQUFHO2dCQUNELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUNsRCxNQUFNLG9CQUFvQixHQUF5QjtvQkFDakQsT0FB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LElBQUksR0FBRyxDQUFDLEVBQUU7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FDYixrREFBa0Q7Z0JBQ2hELEdBQUcsY0FBYzthQUNsQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNoQixDQUFDO1NBQ0g7SUFDSCxDQUFDO0NBa0tGO0FBck5ELHdEQXFOQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJlZHJvY2tSdW50aW1lQ2xpZW50LFxuICBDb250ZW50QmxvY2ssXG4gIENvbnZlcnNlQ29tbWFuZCxcbiAgQ29udmVyc2VDb21tYW5kSW5wdXQsXG4gIENvbnZlcnNlQ29tbWFuZE91dHB1dCxcbiAgTWVzc2FnZSxcbiAgVG9vbCxcbiAgVG9vbENvbmZpZ3VyYXRpb24sXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1iZWRyb2NrLXJ1bnRpbWUnO1xuaW1wb3J0IHtcbiAgQ29udmVyc2F0aW9uVHVybkV2ZW50LFxuICBFeGVjdXRhYmxlVG9vbCxcbiAgVG9vbERlZmluaXRpb24sXG59IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgQ29udmVyc2F0aW9uVHVybkV2ZW50VG9vbHNQcm92aWRlciB9IGZyb20gJy4vZXZlbnQtdG9vbHMtcHJvdmlkZXInO1xuaW1wb3J0IHsgQ29udmVyc2F0aW9uTWVzc2FnZUhpc3RvcnlSZXRyaWV2ZXIgfSBmcm9tICcuL2NvbnZlcnNhdGlvbl9tZXNzYWdlX2hpc3RvcnlfcmV0cmlldmVyJztcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBpbnRlcmFjdGluZyB3aXRoIEJlZHJvY2sgQ29udmVyc2UgQVBJXG4gKiBpbiBvcmRlciB0byBwcm9kdWNlIGZpbmFsIHJlc3BvbnNlIHRoYXQgY2FuIGJlIHNlbnQgYmFjayB0byBjYWxsZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBCZWRyb2NrQ29udmVyc2VBZGFwdGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhbGxUb29sczogQXJyYXk8VG9vbERlZmluaXRpb24+O1xuICBwcml2YXRlIHJlYWRvbmx5IGV4ZWN1dGFibGVUb29sczogQXJyYXk8RXhlY3V0YWJsZVRvb2w+O1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRvb2xzOiBBcnJheTxUb29sRGVmaW5pdGlvbj47XG4gIHByaXZhdGUgcmVhZG9ubHkgZXhlY3V0YWJsZVRvb2xCeU5hbWU6IE1hcDxzdHJpbmcsIEV4ZWN1dGFibGVUb29sPiA9XG4gICAgbmV3IE1hcCgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRvb2xCeU5hbWU6IE1hcDxzdHJpbmcsIFRvb2xEZWZpbml0aW9uPiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBCZWRyb2NrIENvbnZlcnNlIEFkYXB0ZXIuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50OiBDb252ZXJzYXRpb25UdXJuRXZlbnQsXG4gICAgYWRkaXRpb25hbFRvb2xzOiBBcnJheTxFeGVjdXRhYmxlVG9vbD4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBiZWRyb2NrQ2xpZW50OiBCZWRyb2NrUnVudGltZUNsaWVudCA9IG5ldyBCZWRyb2NrUnVudGltZUNsaWVudChcbiAgICAgIHsgcmVnaW9uOiBldmVudC5tb2RlbENvbmZpZ3VyYXRpb24ucmVnaW9uIH1cbiAgICApLFxuICAgIGV2ZW50VG9vbHNQcm92aWRlciA9IG5ldyBDb252ZXJzYXRpb25UdXJuRXZlbnRUb29sc1Byb3ZpZGVyKGV2ZW50KSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VIaXN0b3J5UmV0cmlldmVyID0gbmV3IENvbnZlcnNhdGlvbk1lc3NhZ2VIaXN0b3J5UmV0cmlldmVyKFxuICAgICAgZXZlbnRcbiAgICApXG4gICkge1xuICAgIHRoaXMuZXhlY3V0YWJsZVRvb2xzID0gW1xuICAgICAgLi4uZXZlbnRUb29sc1Byb3ZpZGVyLmdldEV2ZW50VG9vbHMoKSxcbiAgICAgIC4uLmFkZGl0aW9uYWxUb29scyxcbiAgICBdO1xuICAgIHRoaXMuY2xpZW50VG9vbHMgPSB0aGlzLmV2ZW50LnRvb2xzQ29uZmlndXJhdGlvbj8uY2xpZW50VG9vbHMgPz8gW107XG4gICAgdGhpcy5hbGxUb29scyA9IFsuLi50aGlzLmV4ZWN1dGFibGVUb29scywgLi4udGhpcy5jbGllbnRUb29sc107XG4gICAgY29uc3QgZHVwbGljYXRlVG9vbHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICB0aGlzLmV4ZWN1dGFibGVUb29scy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICBpZiAodGhpcy5leGVjdXRhYmxlVG9vbEJ5TmFtZS5oYXModC5uYW1lKSkge1xuICAgICAgICBkdXBsaWNhdGVUb29scy5hZGQodC5uYW1lKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZXhlY3V0YWJsZVRvb2xCeU5hbWUuc2V0KHQubmFtZSwgdCk7XG4gICAgfSk7XG4gICAgdGhpcy5jbGllbnRUb29scy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICBpZiAodGhpcy5leGVjdXRhYmxlVG9vbEJ5TmFtZS5oYXModC5uYW1lKSkge1xuICAgICAgICBkdXBsaWNhdGVUb29scy5hZGQodC5uYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmNsaWVudFRvb2xCeU5hbWUuaGFzKHQubmFtZSkpIHtcbiAgICAgICAgZHVwbGljYXRlVG9vbHMuYWRkKHQubmFtZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNsaWVudFRvb2xCeU5hbWUuc2V0KHQubmFtZSwgdCk7XG4gICAgfSk7XG4gICAgaWYgKGR1cGxpY2F0ZVRvb2xzLnNpemUgPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUb29scyBtdXN0IGhhdmUgdW5pcXVlIG5hbWVzLiBEdXBsaWNhdGUgdG9vbHM6ICR7W1xuICAgICAgICAgIC4uLmR1cGxpY2F0ZVRvb2xzLFxuICAgICAgICBdLmpvaW4oJywgJyl9LmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXNrQmVkcm9jayA9IGFzeW5jICgpOiBQcm9taXNlPENvbnRlbnRCbG9ja1tdPiA9PiB7XG4gICAgY29uc3QgeyBtb2RlbElkLCBzeXN0ZW1Qcm9tcHQsIGluZmVyZW5jZUNvbmZpZ3VyYXRpb24gfSA9XG4gICAgICB0aGlzLmV2ZW50Lm1vZGVsQ29uZmlndXJhdGlvbjtcblxuICAgIGNvbnN0IG1lc3NhZ2VzOiBBcnJheTxNZXNzYWdlPiA9XG4gICAgICBhd2FpdCB0aGlzLmdldEV2ZW50TWVzc2FnZXNBc0JlZHJvY2tNZXNzYWdlcygpO1xuXG4gICAgbGV0IGJlZHJvY2tSZXNwb25zZTogQ29udmVyc2VDb21tYW5kT3V0cHV0O1xuICAgIGRvIHtcbiAgICAgIGNvbnN0IHRvb2xDb25maWcgPSB0aGlzLmNyZWF0ZVRvb2xDb25maWd1cmF0aW9uKCk7XG4gICAgICBjb25zdCBjb252ZXJzZUNvbW1hbmRJbnB1dDogQ29udmVyc2VDb21tYW5kSW5wdXQgPSB7XG4gICAgICAgIG1vZGVsSWQsXG4gICAgICAgIG1lc3NhZ2VzOiBbLi4ubWVzc2FnZXNdLFxuICAgICAgICBzeXN0ZW06IFt7IHRleHQ6IHN5c3RlbVByb21wdCB9XSxcbiAgICAgICAgaW5mZXJlbmNlQ29uZmlnOiBpbmZlcmVuY2VDb25maWd1cmF0aW9uLFxuICAgICAgICB0b29sQ29uZmlnLFxuICAgICAgfTtcbiAgICAgIGJlZHJvY2tSZXNwb25zZSA9IGF3YWl0IHRoaXMuYmVkcm9ja0NsaWVudC5zZW5kKFxuICAgICAgICBuZXcgQ29udmVyc2VDb21tYW5kKGNvbnZlcnNlQ29tbWFuZElucHV0KVxuICAgICAgKTtcbiAgICAgIGlmIChiZWRyb2NrUmVzcG9uc2Uub3V0cHV0Py5tZXNzYWdlKSB7XG4gICAgICAgIG1lc3NhZ2VzLnB1c2goYmVkcm9ja1Jlc3BvbnNlLm91dHB1dD8ubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBpZiAoYmVkcm9ja1Jlc3BvbnNlLnN0b3BSZWFzb24gPT09ICd0b29sX3VzZScpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VDb250ZW50QmxvY2tzID1cbiAgICAgICAgICBiZWRyb2NrUmVzcG9uc2Uub3V0cHV0Py5tZXNzYWdlPy5jb250ZW50ID8/IFtdO1xuICAgICAgICBjb25zdCB0b29sVXNlQmxvY2tzID0gcmVzcG9uc2VDb250ZW50QmxvY2tzLmZpbHRlcihcbiAgICAgICAgICAoYmxvY2spID0+ICd0b29sVXNlJyBpbiBibG9ja1xuICAgICAgICApIGFzIEFycmF5PENvbnRlbnRCbG9jay5Ub29sVXNlTWVtYmVyPjtcbiAgICAgICAgY29uc3QgY2xpZW50VG9vbFVzZUJsb2NrcyA9IHJlc3BvbnNlQ29udGVudEJsb2Nrcy5maWx0ZXIoXG4gICAgICAgICAgKGJsb2NrKSA9PlxuICAgICAgICAgICAgYmxvY2sudG9vbFVzZT8ubmFtZSAmJlxuICAgICAgICAgICAgdGhpcy5jbGllbnRUb29sQnlOYW1lLmhhcyhibG9jay50b29sVXNlPy5uYW1lKVxuICAgICAgICApO1xuICAgICAgICBpZiAoY2xpZW50VG9vbFVzZUJsb2Nrcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gRm9yIG5vdyBpZiBhbnkgb2YgY2xpZW50IHRvb2xzIGlzIHVzZWQgd2UgaWdub3JlIGV4ZWN1dGFibGUgdG9vbHNcbiAgICAgICAgICAvLyBhbmQgcHJvcGFnYXRlIHJlc3VsdCBiYWNrIHRvIGNsaWVudC5cbiAgICAgICAgICByZXR1cm4gY2xpZW50VG9vbFVzZUJsb2NrcztcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IHJlc3BvbnNlQ29udGVudEJsb2NrIG9mIHRvb2xVc2VCbG9ja3MpIHtcbiAgICAgICAgICBjb25zdCB0b29sVXNlQmxvY2sgPVxuICAgICAgICAgICAgcmVzcG9uc2VDb250ZW50QmxvY2sgYXMgQ29udGVudEJsb2NrLlRvb2xVc2VNZW1iZXI7XG4gICAgICAgICAgY29uc3QgdG9vbE1lc3NhZ2UgPSBhd2FpdCB0aGlzLmV4ZWN1dGVUb29sKHRvb2xVc2VCbG9jayk7XG4gICAgICAgICAgbWVzc2FnZXMucHVzaCh0b29sTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlIChiZWRyb2NrUmVzcG9uc2Uuc3RvcFJlYXNvbiA9PT0gJ3Rvb2xfdXNlJyk7XG5cbiAgICByZXR1cm4gYmVkcm9ja1Jlc3BvbnNlLm91dHB1dD8ubWVzc2FnZT8uY29udGVudCA/PyBbXTtcbiAgfTtcblxuICAvKipcbiAgICogTWFwcyBldmVudCBtZXNzYWdlcyB0byBCZWRyb2NrIHR5cGVzLlxuICAgKiAxLiBNYWtlcyBhIGNvcHkgc28gdGhhdCB3ZSBkb24ndCBtdXRhdGUgZXZlbnQuXG4gICAqIDIuIERlY29kZXMgQmFzZTY0IGVuY29kZWQgaW1hZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRFdmVudE1lc3NhZ2VzQXNCZWRyb2NrTWVzc2FnZXMgPSBhc3luYyAoKTogUHJvbWlzZTxcbiAgICBBcnJheTxNZXNzYWdlPlxuICA+ID0+IHtcbiAgICBjb25zdCBtZXNzYWdlczogQXJyYXk8TWVzc2FnZT4gPSBbXTtcbiAgICBjb25zdCBldmVudE1lc3NhZ2VzID1cbiAgICAgIGF3YWl0IHRoaXMubWVzc2FnZUhpc3RvcnlSZXRyaWV2ZXIuZ2V0TWVzc2FnZUhpc3RvcnkoKTtcbiAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgZXZlbnRNZXNzYWdlcykge1xuICAgICAgY29uc3QgbWVzc2FnZUNvbnRlbnQ6IEFycmF5PENvbnRlbnRCbG9jaz4gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgY29udGVudEVsZW1lbnQgb2YgbWVzc2FnZS5jb250ZW50KSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29udGVudEVsZW1lbnQuaW1hZ2U/LnNvdXJjZT8uYnl0ZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgbWVzc2FnZUNvbnRlbnQucHVzaCh7XG4gICAgICAgICAgICBpbWFnZToge1xuICAgICAgICAgICAgICBmb3JtYXQ6IGNvbnRlbnRFbGVtZW50LmltYWdlLmZvcm1hdCxcbiAgICAgICAgICAgICAgc291cmNlOiB7XG4gICAgICAgICAgICAgICAgYnl0ZXM6IEJ1ZmZlci5mcm9tKGNvbnRlbnRFbGVtZW50LmltYWdlLnNvdXJjZS5ieXRlcywgJ2Jhc2U2NCcpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgdHlwZSBjb25mb3JtcyB0byBCZWRyb2NrJ3MgdHlwZSBhbmQgaXQncyBzYWZlIHRvIGNhc3QuXG4gICAgICAgICAgbWVzc2FnZUNvbnRlbnQucHVzaChjb250ZW50RWxlbWVudCBhcyBDb250ZW50QmxvY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBtZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgcm9sZTogbWVzc2FnZS5yb2xlLFxuICAgICAgICBjb250ZW50OiBtZXNzYWdlQ29udGVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbWVzc2FnZXM7XG4gIH07XG5cbiAgcHJpdmF0ZSBjcmVhdGVUb29sQ29uZmlndXJhdGlvbiA9ICgpOiBUb29sQ29uZmlndXJhdGlvbiB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKHRoaXMuYWxsVG9vbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0b29sczogdGhpcy5hbGxUb29scy5tYXAoKHQpOiBUb29sID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0b29sU3BlYzoge1xuICAgICAgICAgICAgbmFtZTogdC5uYW1lLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHQuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBpbnB1dFNjaGVtYTogdC5pbnB1dFNjaGVtYSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgfTtcbiAgfTtcblxuICBwcml2YXRlIGV4ZWN1dGVUb29sID0gYXN5bmMgKFxuICAgIHRvb2xVc2VCbG9jazogQ29udGVudEJsb2NrLlRvb2xVc2VNZW1iZXJcbiAgKTogUHJvbWlzZTxNZXNzYWdlPiA9PiB7XG4gICAgaWYgKCF0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lKSB7XG4gICAgICB0aHJvdyBFcnJvcignQmVkcm9jayB0b29sIHVzZSByZXNwb25zZSBpcyBtaXNzaW5nIGEgdG9vbCBuYW1lJyk7XG4gICAgfVxuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmV4ZWN1dGFibGVUb29sQnlOYW1lLmdldCh0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lKTtcbiAgICBpZiAoIXRvb2wpIHtcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgQmVkcm9jayB0b29sIHVzZSByZXNwb25zZSBjb250YWlucyB1bmtub3duIHRvb2wgJyR7dG9vbFVzZUJsb2NrLnRvb2xVc2UubmFtZX0nYFxuICAgICAgKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRvb2xSZXNwb25zZSA9IGF3YWl0IHRvb2wuZXhlY3V0ZSh0b29sVXNlQmxvY2sudG9vbFVzZS5pbnB1dCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0b29sUmVzdWx0OiB7XG4gICAgICAgICAgICAgIHRvb2xVc2VJZDogdG9vbFVzZUJsb2NrLnRvb2xVc2UudG9vbFVzZUlkLFxuICAgICAgICAgICAgICBjb250ZW50OiBbdG9vbFJlc3BvbnNlXSxcbiAgICAgICAgICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByb2xlOiAndXNlcicsXG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0b29sUmVzdWx0OiB7XG4gICAgICAgICAgICAgICAgdG9vbFVzZUlkOiB0b29sVXNlQmxvY2sudG9vbFVzZS50b29sVXNlSWQsXG4gICAgICAgICAgICAgICAgY29udGVudDogW3sgdGV4dDogZS50b1N0cmluZygpIH1dLFxuICAgICAgICAgICAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJvbGU6ICd1c2VyJyxcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRvb2xSZXN1bHQ6IHtcbiAgICAgICAgICAgICAgdG9vbFVzZUlkOiB0b29sVXNlQmxvY2sudG9vbFVzZS50b29sVXNlSWQsXG4gICAgICAgICAgICAgIGNvbnRlbnQ6IFt7IHRleHQ6ICd1bmtub3duIGVycm9yIG9jY3VycmVkJyB9XSxcbiAgICAgICAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH07XG59XG4iXX0=
|
406
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVkcm9ja19jb252ZXJzZV9hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbnZlcnNhdGlvbi9ydW50aW1lL2JlZHJvY2tfY29udmVyc2VfYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0RUFheUM7QUFTekMsaUVBQTRFO0FBQzVFLHFHQUErRjtBQUcvRjs7O0dBR0c7QUFDSCxNQUFhLHNCQUFzQjtJQVFqQzs7T0FFRztJQUNILFlBQ21CLEtBQTRCLEVBQzdDLGVBQXNDLEVBQ3JCLGdCQUFzQyxJQUFJLDZDQUFvQixDQUM3RSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLENBQzVDLEVBQ0Qsa0JBQWtCLEdBQUcsSUFBSSx5REFBa0MsQ0FBQyxLQUFLLENBQUMsRUFDakQsMEJBQTBCLElBQUksNEVBQW1DLENBQ2hGLEtBQUssQ0FDTixFQUNnQixTQUFTLE9BQU87O1FBVGhCLFVBQUssR0FBTCxLQUFLLENBQXVCO1FBRTVCLGtCQUFhLEdBQWIsYUFBYSxDQUU3QjtRQUVnQiw0QkFBdUIsR0FBdkIsdUJBQXVCLENBRXZDO1FBQ2dCLFdBQU0sR0FBTixNQUFNLENBQVU7UUFqQmxCLHlCQUFvQixHQUNuQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ0sscUJBQWdCLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7UUErRDNFLGVBQVUsR0FBRyxLQUFLLElBQXVDLEVBQUU7O1lBQ3pELElBQUk7Z0JBQ0YsTUFBTSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsR0FDckQsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFFaEMsTUFBTSxRQUFRLEdBQ1osTUFBTSxJQUFJLENBQUMsaUNBQWlDLEVBQUUsQ0FBQztnQkFFakQsSUFBSSxlQUFzQyxDQUFDO2dCQUMzQyxHQUFHO29CQUNELE1BQU0sVUFBVSxHQUFHLElBQUks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QkFDRCxRQUFRLENBQUMsSUFBSSxDQUFDO3dCQUNaLElBQUksRUFBRSxNQUFNO3dCQUNaLE9BQU8sRUFBRSx5QkFBeUI7cUJBQ25DLENBQUMsQ0FBQztpQkFDSjthQUNGLFFBQVEsVUFBVSxLQUFLLFVBQVUsRUFBRTtZQUVwQyxNQUFNO2dCQUNKLHNCQUFzQixFQUFFLENBQUMsR0FBRyxzQkFBc0IsQ0FBQztnQkFDbkQsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYztnQkFDekMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0I7Z0JBQ3BELGlCQUFpQixFQUFFLGNBQWM7Z0JBQ2pDLFVBQVUsRUFBRSxVQUFVO2FBQ3ZCLENBQUM7U0FDSDtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuRSxNQUFNLHFCQUFxQixHQUN6QixJQUFJLENBQUMsbUNBQW1DLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEQsTUFBTTtnQkFDSixzQkFBc0IsRUFBRSxDQUFDLEdBQUcsc0JBQXNCLENBQUM7Z0JBQ25ELGNBQWMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWM7Z0JBQ3pDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCO2dCQUNwRCxpQkFBaUIsRUFBRSxVQUFVO2dCQUM3QixNQUFNLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQzthQUNoQyxDQUFDO1NBQ0g7SUFDSCxDQUFDO0NBeUhGO0FBbGNELHdEQWtjQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJlZHJvY2tSdW50aW1lQ2xpZW50LFxuICBDb250ZW50QmxvY2ssXG4gIENvbnZlcnNlQ29tbWFuZCxcbiAgQ29udmVyc2VDb21tYW5kSW5wdXQsXG4gIENvbnZlcnNlQ29tbWFuZE91dHB1dCxcbiAgQ29udmVyc2VTdHJlYW1Db21tYW5kLFxuICBDb252ZXJzZVN0cmVhbUNvbW1hbmRJbnB1dCxcbiAgQ29udmVyc2VTdHJlYW1Db21tYW5kT3V0cHV0LFxuICBNZXNzYWdlLFxuICBUb29sLFxuICBUb29sQ29uZmlndXJhdGlvbixcbiAgVG9vbElucHV0U2NoZW1hLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQtYmVkcm9jay1ydW50aW1lJztcbmltcG9ydCB7XG4gIENvbnZlcnNhdGlvblR1cm5FcnJvcixcbiAgQ29udmVyc2F0aW9uVHVybkV2ZW50LFxuICBDb252ZXJzYXRpb25UdXJuUmVzcG9uc2UsXG4gIEV4ZWN1dGFibGVUb29sLFxuICBTdHJlYW1pbmdSZXNwb25zZUNodW5rLFxuICBUb29sRGVmaW5pdGlvbixcbn0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBDb252ZXJzYXRpb25UdXJuRXZlbnRUb29sc1Byb3ZpZGVyIH0gZnJvbSAnLi9ldmVudC10b29scy1wcm92aWRlcic7XG5pbXBvcnQgeyBDb252ZXJzYXRpb25NZXNzYWdlSGlzdG9yeVJldHJpZXZlciB9IGZyb20gJy4vY29udmVyc2F0aW9uX21lc3NhZ2VfaGlzdG9yeV9yZXRyaWV2ZXInO1xuaW1wb3J0ICogYXMgYmVkcm9jayBmcm9tICdAYXdzLXNkay9jbGllbnQtYmVkcm9jay1ydW50aW1lJztcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBpbnRlcmFjdGluZyB3aXRoIEJlZHJvY2sgQ29udmVyc2UgQVBJXG4gKiBpbiBvcmRlciB0byBwcm9kdWNlIGZpbmFsIHJlc3BvbnNlIHRoYXQgY2FuIGJlIHNlbnQgYmFjayB0byBjYWxsZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBCZWRyb2NrQ29udmVyc2VBZGFwdGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhbGxUb29sczogQXJyYXk8VG9vbERlZmluaXRpb24+O1xuICBwcml2YXRlIHJlYWRvbmx5IGV4ZWN1dGFibGVUb29sczogQXJyYXk8RXhlY3V0YWJsZVRvb2w+O1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRvb2xzOiBBcnJheTxUb29sRGVmaW5pdGlvbj47XG4gIHByaXZhdGUgcmVhZG9ubHkgZXhlY3V0YWJsZVRvb2xCeU5hbWU6IE1hcDxzdHJpbmcsIEV4ZWN1dGFibGVUb29sPiA9XG4gICAgbmV3IE1hcCgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFRvb2xCeU5hbWU6IE1hcDxzdHJpbmcsIFRvb2xEZWZpbml0aW9uPiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBCZWRyb2NrIENvbnZlcnNlIEFkYXB0ZXIuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50OiBDb252ZXJzYXRpb25UdXJuRXZlbnQsXG4gICAgYWRkaXRpb25hbFRvb2xzOiBBcnJheTxFeGVjdXRhYmxlVG9vbD4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBiZWRyb2NrQ2xpZW50OiBCZWRyb2NrUnVudGltZUNsaWVudCA9IG5ldyBCZWRyb2NrUnVudGltZUNsaWVudChcbiAgICAgIHsgcmVnaW9uOiBldmVudC5tb2RlbENvbmZpZ3VyYXRpb24ucmVnaW9uIH1cbiAgICApLFxuICAgIGV2ZW50VG9vbHNQcm92aWRlciA9IG5ldyBDb252ZXJzYXRpb25UdXJuRXZlbnRUb29sc1Byb3ZpZGVyKGV2ZW50KSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VIaXN0b3J5UmV0cmlldmVyID0gbmV3IENvbnZlcnNhdGlvbk1lc3NhZ2VIaXN0b3J5UmV0cmlldmVyKFxuICAgICAgZXZlbnRcbiAgICApLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyID0gY29uc29sZVxuICApIHtcbiAgICBpZiAoZXZlbnQucmVxdWVzdC5oZWFkZXJzWyd4LWFtei11c2VyLWFnZW50J10pIHtcbiAgICAgIHRoaXMuYmVkcm9ja0NsaWVudC5taWRkbGV3YXJlU3RhY2suYWRkKFxuICAgICAgICAobmV4dCkgPT4gKGFyZ3MpID0+IHtcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFJlcXVlc3QgaXMgdHlwZWQgYXMgdW5rbm93bi5cbiAgICAgICAgICAvLyBCdXQgdGhpcyBpcyByZWNvbW1lbmRlZCB3YXkgdG8gYWx0ZXIgaGVhZGVycyBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3Mtc2RrLWpzLXYzL2Jsb2IvbWFpbi9SRUFETUUubWQuXG4gICAgICAgICAgYXJncy5yZXF1ZXN0LmhlYWRlcnNbJ3gtYW16LXVzZXItYWdlbnQnXSA9XG4gICAgICAgICAgICBldmVudC5yZXF1ZXN0LmhlYWRlcnNbJ3gtYW16LXVzZXItYWdlbnQnXTtcbiAgICAgICAgICByZXR1cm4gbmV4dChhcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHN0ZXA6ICdidWlsZCcsXG4gICAgICAgICAgbmFtZTogJ2FtcGxpZnktdXNlci1hZ2VudC1pbmplY3RvcicsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuZXhlY3V0YWJsZVRvb2xzID0gW1xuICAgICAgLi4uZXZlbnRUb29sc1Byb3ZpZGVyLmdldEV2ZW50VG9vbHMoKSxcbiAgICAgIC4uLmFkZGl0aW9uYWxUb29scyxcbiAgICBdO1xuICAgIHRoaXMuY2xpZW50VG9vbHMgPSB0aGlzLmV2ZW50LnRvb2xzQ29uZmlndXJhdGlvbj8uY2xpZW50VG9vbHMgPz8gW107XG4gICAgdGhpcy5hbGxUb29scyA9IFsuLi50aGlzLmV4ZWN1dGFibGVUb29scywgLi4udGhpcy5jbGllbnRUb29sc107XG4gICAgY29uc3QgZHVwbGljYXRlVG9vbHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICB0aGlzLmV4ZWN1dGFibGVUb29scy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICBpZiAodGhpcy5leGVjdXRhYmxlVG9vbEJ5TmFtZS5oYXModC5uYW1lKSkge1xuICAgICAgICBkdXBsaWNhdGVUb29scy5hZGQodC5uYW1lKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZXhlY3V0YWJsZVRvb2xCeU5hbWUuc2V0KHQubmFtZSwgdCk7XG4gICAgfSk7XG4gICAgdGhpcy5jbGllbnRUb29scy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICBpZiAodGhpcy5leGVjdXRhYmxlVG9vbEJ5TmFtZS5oYXModC5uYW1lKSkge1xuICAgICAgICBkdXBsaWNhdGVUb29scy5hZGQodC5uYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmNsaWVudFRvb2xCeU5hbWUuaGFzKHQubmFtZSkpIHtcbiAgICAgICAgZHVwbGljYXRlVG9vbHMuYWRkKHQubmFtZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNsaWVudFRvb2xCeU5hbWUuc2V0KHQubmFtZSwgdCk7XG4gICAgfSk7XG4gICAgaWYgKGR1cGxpY2F0ZVRvb2xzLnNpemUgPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUb29scyBtdXN0IGhhdmUgdW5pcXVlIG5hbWVzLiBEdXBsaWNhdGUgdG9vbHM6ICR7W1xuICAgICAgICAgIC4uLmR1cGxpY2F0ZVRvb2xzLFxuICAgICAgICBdLmpvaW4oJywgJyl9LmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXNrQmVkcm9jayA9IGFzeW5jICgpOiBQcm9taXNlPENvbnZlcnNhdGlvblR1cm5SZXNwb25zZT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IG1vZGVsSWQsIHN5c3RlbVByb21wdCwgaW5mZXJlbmNlQ29uZmlndXJhdGlvbiB9ID1cbiAgICAgICAgdGhpcy5ldmVudC5tb2RlbENvbmZpZ3VyYXRpb247XG5cbiAgICAgIGNvbnN0IG1lc3NhZ2VzOiBBcnJheTxNZXNzYWdlPiA9XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0RXZlbnRNZXNzYWdlc0FzQmVkcm9ja01lc3NhZ2VzKCk7XG5cbiAgICAgIGxldCBiZWRyb2NrUmVzcG9uc2U6IENvbnZlcnNlQ29tbWFuZE91dHB1dDtcbiAgICAgIGRvIHtcbiAgICAgICAgY29uc3QgdG9vbENvbmZpZyA9IHRoaXMuY3JlYXRlVG9vbENvbmZpZ3VyYXRpb24oKTtcbiAgICAgICAgY29uc3QgY29udmVyc2VDb21tYW5kSW5wdXQ6IENvbnZlcnNlQ29tbWFuZElucHV0ID0ge1xuICAgICAgICAgIG1vZGVsSWQsXG4gICAgICAgICAgbWVzc2FnZXM6IFsuLi5tZXNzYWdlc10sXG4gICAgICAgICAgc3lzdGVtOiBbeyB0ZXh0OiBzeXN0ZW1Qcm9tcHQgfV0sXG4gICAgICAgICAgaW5mZXJlbmNlQ29uZmlnOiBpbmZlcmVuY2VDb25maWd1cmF0aW9uLFxuICAgICAgICAgIHRvb2xDb25maWcsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubG9nZ2VyLmluZm8oJ1NlbmRpbmcgQmVkcm9jayBDb252ZXJzZSByZXF1ZXN0Jyk7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdCZWRyb2NrIENvbnZlcnNlIHJlcXVlc3Q6JywgY29udmVyc2VDb21tYW5kSW5wdXQpO1xuICAgICAgICBiZWRyb2NrUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmJlZHJvY2tDbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgQ29udmVyc2VDb21tYW5kKGNvbnZlcnNlQ29tbWFuZElucHV0KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBSZWNlaXZlZCBCZWRyb2NrIENvbnZlcnNlIHJlc3BvbnNlLCByZXF1ZXN0SWQ9JHtiZWRyb2NrUmVzcG9uc2UuJG1ldGFkYXRhLnJlcXVlc3RJZH1gLFxuICAgICAgICAgIGJlZHJvY2tSZXNwb25zZS51c2FnZVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZygnQmVkcm9jayBDb252ZXJzZSByZXNwb25zZTonLCBiZWRyb2NrUmVzcG9uc2UpO1xuICAgICAgICBpZiAoYmVkcm9ja1Jlc3BvbnNlLm91dHB1dD8ubWVzc2FnZSkge1xuICAgICAgICAgIG1lc3NhZ2VzLnB1c2goYmVkcm9ja1Jlc3BvbnNlLm91dHB1dD8ubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJlZHJvY2tSZXNwb25zZS5zdG9wUmVhc29uID09PSAndG9vbF91c2UnKSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2VDb250ZW50QmxvY2tzID1cbiAgICAgICAgICAgIGJlZHJvY2tSZXNwb25zZS5vdXRwdXQ/Lm1lc3NhZ2U/LmNvbnRlbnQgPz8gW107XG4gICAgICAgICAgY29uc3QgdG9vbFVzZUJsb2NrcyA9IHJlc3BvbnNlQ29udGVudEJsb2Nrcy5maWx0ZXIoXG4gICAgICAgICAgICAoYmxvY2spID0+ICd0b29sVXNlJyBpbiBibG9ja1xuICAgICAgICAgICkgYXMgQXJyYXk8Q29udGVudEJsb2NrLlRvb2xVc2VNZW1iZXI+O1xuICAgICAgICAgIGNvbnN0IGNsaWVudFRvb2xVc2VCbG9ja3MgPSByZXNwb25zZUNvbnRlbnRCbG9ja3MuZmlsdGVyKFxuICAgICAgICAgICAgKGJsb2NrKSA9PlxuICAgICAgICAgICAgICBibG9jay50b29sVXNlPy5uYW1lICYmXG4gICAgICAgICAgICAgIHRoaXMuY2xpZW50VG9vbEJ5TmFtZS5oYXMoYmxvY2sudG9vbFVzZT8ubmFtZSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChjbGllbnRUb29sVXNlQmxvY2tzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIEZvciBub3cgaWYgYW55IG9mIGNsaWVudCB0b29scyBpcyB1c2VkIHdlIGlnbm9yZSBleGVjdXRhYmxlIHRvb2xzXG4gICAgICAgICAgICAvLyBhbmQgcHJvcGFnYXRlIHJlc3VsdCBiYWNrIHRvIGNsaWVudC5cbiAgICAgICAgICAgIHJldHVybiB7IGNvbnRlbnQ6IGNsaWVudFRvb2xVc2VCbG9ja3MgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdG9vbFJlc3BvbnNlQ29udGVudEJsb2NrczogQXJyYXk8Q29udGVudEJsb2NrPiA9IFtdO1xuICAgICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2VDb250ZW50QmxvY2sgb2YgdG9vbFVzZUJsb2Nrcykge1xuICAgICAgICAgICAgY29uc3QgdG9vbFVzZUJsb2NrID1cbiAgICAgICAgICAgICAgcmVzcG9uc2VDb250ZW50QmxvY2sgYXMgQ29udGVudEJsb2NrLlRvb2xVc2VNZW1iZXI7XG4gICAgICAgICAgICBjb25zdCB0b29sUmVzdWx0Q29udGVudEJsb2NrID0gYXdhaXQgdGhpcy5leGVjdXRlVG9vbCh0b29sVXNlQmxvY2spO1xuICAgICAgICAgICAgdG9vbFJlc3BvbnNlQ29udGVudEJsb2Nrcy5wdXNoKHRvb2xSZXN1bHRDb250ZW50QmxvY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIHJvbGU6ICd1c2VyJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6IHRvb2xSZXNwb25zZUNvbnRlbnRCbG9ja3MsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKGJlZHJvY2tSZXNwb25zZS5zdG9wUmVhc29uID09PSAndG9vbF91c2UnKTtcblxuICAgICAgcmV0dXJuIHsgY29udGVudDogYmVkcm9ja1Jlc3BvbnNlLm91dHB1dD8ubWVzc2FnZT8uY29udGVudCA/PyBbXSB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdDb252ZXJzYXRpb24gd2l0aCBCZWRyb2NrIGZhaWxlZCcsIGVycm9yKTtcbiAgICAgIGNvbnN0IGNvbnZlcnNhdGlvblR1cm5FcnJvciA9XG4gICAgICAgIHRoaXMuY29udmVydEVycm9yVG9Db252ZXJzYXRpb25UdXJuRXJyb3IoZXJyb3IpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZXJyb3JzOiBbY29udmVyc2F0aW9uVHVybkVycm9yXSxcbiAgICAgIH07XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBc2tzIEJlZHJvY2sgZm9yIHJlc3BvbnNlIHVzaW5nIHN0cmVhbWluZyB2ZXJzaW9uIG9mIENvbnZlcnNlIEFQSS5cbiAgICovXG4gIGFzeW5jICphc2tCZWRyb2NrU3RyZWFtaW5nKCk6IEFzeW5jR2VuZXJhdG9yPFN0cmVhbWluZ1Jlc3BvbnNlQ2h1bms+IHtcbiAgICAvLyBrZWVwIG91ciBvd24gaW5kZXhpbmcgZm9yIGJsb2NrcyBpbnN0ZWFkIG9mIHVzaW5nIEJlZHJvY2sncyBpbmRleGVzXG4gICAgLy8gc2luY2Ugd2Ugc3RyZWFtIHN1YnNldCBvZiB0aGVzZSB1cHN0cmVhbS5cbiAgICBsZXQgYmxvY2tJbmRleCA9IDA7XG4gICAgbGV0IGxhc3RCbG9ja0luZGV4ID0gMDtcbiAgICBsZXQgc3RvcFJlYXNvbiA9ICcnO1xuICAgIC8vIEFjY3VtdWxhdGVzIGNsaWVudCBmYWNpbmcgY29udGVudCBwZXIgdHVybi5cbiAgICAvLyBTbyB0aGF0IHVwc3RyZWFtIGNhbiBwZXJzaXN0IGZ1bGwgbWVzc2FnZSBhdCB0aGUgZW5kIG9mIHRoZSBzdHJlYW1pbmcuXG4gICAgY29uc3QgYWNjdW11bGF0ZWRUdXJuQ29udGVudDogQXJyYXk8YmVkcm9jay5Db250ZW50QmxvY2s+ID0gW107XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBtb2RlbElkLCBzeXN0ZW1Qcm9tcHQsIGluZmVyZW5jZUNvbmZpZ3VyYXRpb24gfSA9XG4gICAgICAgIHRoaXMuZXZlbnQubW9kZWxDb25maWd1cmF0aW9uO1xuXG4gICAgICBjb25zdCBtZXNzYWdlczogQXJyYXk8TWVzc2FnZT4gPVxuICAgICAgICBhd2FpdCB0aGlzLmdldEV2ZW50TWVzc2FnZXNBc0JlZHJvY2tNZXNzYWdlcygpO1xuXG4gICAgICBsZXQgYmVkcm9ja1Jlc3BvbnNlOiBDb252ZXJzZVN0cmVhbUNvbW1hbmRPdXRwdXQ7XG4gICAgICBkbyB7XG4gICAgICAgIGNvbnN0IHRvb2xDb25maWcgPSB0aGlzLmNyZWF0ZVRvb2xDb25maWd1cmF0aW9uKCk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnNlQ29tbWFuZElucHV0OiBDb252ZXJzZVN0cmVhbUNvbW1hbmRJbnB1dCA9IHtcbiAgICAgICAgICBtb2RlbElkLFxuICAgICAgICAgIG1lc3NhZ2VzOiBbLi4ubWVzc2FnZXNdLFxuICAgICAgICAgIHN5c3RlbTogW3sgdGV4dDogc3lzdGVtUHJvbXB0IH1dLFxuICAgICAgICAgIGluZmVyZW5jZUNvbmZpZzogaW5mZXJlbmNlQ29uZmlndXJhdGlvbixcbiAgICAgICAgICB0b29sQ29uZmlnLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKCdTZW5kaW5nIEJlZHJvY2sgQ29udmVyc2UgU3RyZWFtIHJlcXVlc3QnKTtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgJ0JlZHJvY2sgQ29udmVyc2UgU3RyZWFtIHJlcXVlc3Q6JyxcbiAgICAgICAgICBjb252ZXJzZUNvbW1hbmRJbnB1dFxuICAgICAgICApO1xuICAgICAgICBiZWRyb2NrUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmJlZHJvY2tDbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgQ29udmVyc2VTdHJlYW1Db21tYW5kKGNvbnZlcnNlQ29tbWFuZElucHV0KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBSZWNlaXZlZCBCZWRyb2NrIENvbnZlcnNlIFN0cmVhbSByZXNwb25zZSwgcmVxdWVzdElkPSR7YmVkcm9ja1Jlc3BvbnNlLiRtZXRhZGF0YS5yZXF1ZXN0SWR9YFxuICAgICAgICApO1xuICAgICAgICBpZiAoIWJlZHJvY2tSZXNwb25zZS5zdHJlYW0pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JlZHJvY2sgcmVzcG9uc2UgaXMgbWlzc2luZyBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdG9vbFVzZUJsb2NrOiBDb250ZW50QmxvY2suVG9vbFVzZU1lbWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGNsaWVudFRvb2xzUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgICAgIGxldCB0ZXh0OiBzdHJpbmcgPSAnJztcbiAgICAgICAgbGV0IHRvb2xVc2VJbnB1dDogc3RyaW5nID0gJyc7XG4gICAgICAgIGxldCBibG9ja0RlbHRhSW5kZXggPSAwO1xuICAgICAgICBsZXQgbGFzdEJsb2NrRGVsdGFJbmRleCA9IDA7XG4gICAgICAgIC8vIEFjY3VtdWxhdGUgY3VycmVudCBtZXNzYWdlIGZvciB0aGUgdG9vbCB1c2UgbG9vcCBwdXJwb3NlLlxuICAgICAgICBjb25zdCBhY2N1bXVsYXRlZEFzc2lzdGFudE1lc3NhZ2U6IE1lc3NhZ2UgPSB7XG4gICAgICAgICAgcm9sZTogdW5kZWZpbmVkLFxuICAgICAgICAgIGNvbnRlbnQ6IFtdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgYmVkcm9ja1Jlc3BvbnNlLnN0cmVhbSkge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdCZWRyb2NrIENvbnZlcnNlIFN0cmVhbSByZXNwb25zZSBjaHVuazonLCBjaHVuayk7XG4gICAgICAgICAgaWYgKGNodW5rLm1lc3NhZ2VTdGFydCkge1xuICAgICAgICAgICAgYWNjdW11bGF0ZWRBc3Npc3RhbnRNZXNzYWdlLnJvbGUgPSBjaHVuay5tZXNzYWdlU3RhcnQucm9sZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNodW5rLmNvbnRlbnRCbG9ja1N0YXJ0KSB7XG4gICAgICAgICAgICBibG9ja0RlbHRhSW5kZXggPSAwO1xuICAgICAgICAgICAgbGFzdEJsb2NrRGVsdGFJbmRleCA9IDA7XG4gICAgICAgICAgICBpZiAoY2h1bmsuY29udGVudEJsb2NrU3RhcnQuc3RhcnQ/LnRvb2xVc2UpIHtcbiAgICAgICAgICAgICAgdG9vbFVzZUJsb2NrID0ge1xuICAgICAgICAgICAgICAgIHRvb2xVc2U6IHtcbiAgICAgICAgICAgICAgICAgIC4uLmNodW5rLmNvbnRlbnRCbG9ja1N0YXJ0LnN0YXJ0Py50b29sVXNlLFxuICAgICAgICAgICAgICAgICAgaW5wdXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoY2h1bmsuY29udGVudEJsb2NrRGVsdGEpIHtcbiAgICAgICAgICAgIGlmIChjaHVuay5jb250ZW50QmxvY2tEZWx0YS5kZWx0YT8udG9vbFVzZSkge1xuICAgICAgICAgICAgICBpZiAoIWNodW5rLmNvbnRlbnRCbG9ja0RlbHRhLmRlbHRhLnRvb2xVc2UuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICB0b29sVXNlSW5wdXQgPSAnJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0b29sVXNlSW5wdXQgKz0gY2h1bmsuY29udGVudEJsb2NrRGVsdGEuZGVsdGEudG9vbFVzZS5pbnB1dDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2h1bmsuY29udGVudEJsb2NrRGVsdGEuZGVsdGE/LnRleHQpIHtcbiAgICAgICAgICAgICAgdGV4dCArPSBjaHVuay5jb250ZW50QmxvY2tEZWx0YS5kZWx0YS50ZXh0O1xuICAgICAgICAgICAgICB5aWVsZCB7XG4gICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUdXJuQ29udGVudDogWy4uLmFjY3VtdWxhdGVkVHVybkNvbnRlbnQsIHsgdGV4dCB9XSxcbiAgICAgICAgICAgICAgICBjb252ZXJzYXRpb25JZDogdGhpcy5ldmVudC5jb252ZXJzYXRpb25JZCxcbiAgICAgICAgICAgICAgICBhc3NvY2lhdGVkVXNlck1lc3NhZ2VJZDogdGhpcy5ldmVudC5jdXJyZW50TWVzc2FnZUlkLFxuICAgICAgICAgICAgICAgIGNvbnRlbnRCbG9ja1RleHQ6IGNodW5rLmNvbnRlbnRCbG9ja0RlbHRhLmRlbHRhLnRleHQsXG4gICAgICAgICAgICAgICAgY29udGVudEJsb2NrSW5kZXg6IGJsb2NrSW5kZXgsXG4gICAgICAgICAgICAgICAgY29udGVudEJsb2NrRGVsdGFJbmRleDogYmxvY2tEZWx0YUluZGV4LFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBsYXN0QmxvY2tEZWx0YUluZGV4ID0gYmxvY2tEZWx0YUluZGV4O1xuICAgICAgICAgICAgICBibG9ja0RlbHRhSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGNodW5rLmNvbnRlbnRCbG9ja1N0b3ApIHtcbiAgICAgICAgICAgIGlmICh0b29sVXNlQmxvY2spIHtcbiAgICAgICAgICAgICAgdG9vbFVzZUJsb2NrLnRvb2xVc2UuaW5wdXQgPSBKU09OLnBhcnNlKHRvb2xVc2VJbnB1dCk7XG4gICAgICAgICAgICAgIGFjY3VtdWxhdGVkQXNzaXN0YW50TWVzc2FnZS5jb250ZW50Py5wdXNoKHRvb2xVc2VCbG9jayk7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lICYmXG4gICAgICAgICAgICAgICAgdGhpcy5jbGllbnRUb29sQnlOYW1lLmhhcyh0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjbGllbnRUb29sc1JlcXVlc3RlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUdXJuQ29udGVudC5wdXNoKHRvb2xVc2VCbG9jayk7XG4gICAgICAgICAgICAgICAgeWllbGQge1xuICAgICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUdXJuQ29udGVudDogWy4uLmFjY3VtdWxhdGVkVHVybkNvbnRlbnRdLFxuICAgICAgICAgICAgICAgICAgY29udmVyc2F0aW9uSWQ6IHRoaXMuZXZlbnQuY29udmVyc2F0aW9uSWQsXG4gICAgICAgICAgICAgICAgICBhc3NvY2lhdGVkVXNlck1lc3NhZ2VJZDogdGhpcy5ldmVudC5jdXJyZW50TWVzc2FnZUlkLFxuICAgICAgICAgICAgICAgICAgY29udGVudEJsb2NrSW5kZXg6IGJsb2NrSW5kZXgsXG4gICAgICAgICAgICAgICAgICBjb250ZW50QmxvY2tUb29sVXNlOiBKU09OLnN0cmluZ2lmeSh0b29sVXNlQmxvY2spLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbGFzdEJsb2NrSW5kZXggPSBibG9ja0luZGV4O1xuICAgICAgICAgICAgICAgIGJsb2NrSW5kZXgrKztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0b29sVXNlQmxvY2sgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIHRvb2xVc2VJbnB1dCA9ICcnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYWNjdW11bGF0ZWRBc3Npc3RhbnRNZXNzYWdlLmNvbnRlbnQ/LnB1c2goe1xuICAgICAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBhY2N1bXVsYXRlZFR1cm5Db250ZW50LnB1c2goeyB0ZXh0IH0pO1xuICAgICAgICAgICAgICB5aWVsZCB7XG4gICAgICAgICAgICAgICAgYWNjdW11bGF0ZWRUdXJuQ29udGVudDogWy4uLmFjY3VtdWxhdGVkVHVybkNvbnRlbnRdLFxuICAgICAgICAgICAgICAgIGNvbnZlcnNhdGlvbklkOiB0aGlzLmV2ZW50LmNvbnZlcnNhdGlvbklkLFxuICAgICAgICAgICAgICAgIGFzc29jaWF0ZWRVc2VyTWVzc2FnZUlkOiB0aGlzLmV2ZW50LmN1cnJlbnRNZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgY29udGVudEJsb2NrSW5kZXg6IGJsb2NrSW5kZXgsXG4gICAgICAgICAgICAgICAgY29udGVudEJsb2NrRG9uZUF0SW5kZXg6IGxhc3RCbG9ja0RlbHRhSW5kZXgsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHRleHQgPSAnJztcbiAgICAgICAgICAgICAgbGFzdEJsb2NrSW5kZXggPSBibG9ja0luZGV4O1xuICAgICAgICAgICAgICBibG9ja0luZGV4Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChjaHVuay5tZXNzYWdlU3RvcCkge1xuICAgICAgICAgICAgc3RvcFJlYXNvbiA9IGNodW5rLm1lc3NhZ2VTdG9wLnN0b3BSZWFzb24gPz8gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICdBY2N1bXVsYXRlZCBCZWRyb2NrIENvbnZlcnNlIFN0cmVhbSByZXNwb25zZTonLFxuICAgICAgICAgIGFjY3VtdWxhdGVkQXNzaXN0YW50TWVzc2FnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoY2xpZW50VG9vbHNSZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAvLyBGb3Igbm93IGlmIGFueSBvZiBjbGllbnQgdG9vbHMgaXMgdXNlZCB3ZSBpZ25vcmUgZXhlY3V0YWJsZSB0b29sc1xuICAgICAgICAgIC8vIGFuZCBwcm9wYWdhdGUgcmVzdWx0IGJhY2sgdG8gY2xpZW50LlxuICAgICAgICAgIHlpZWxkIHtcbiAgICAgICAgICAgIGFjY3VtdWxhdGVkVHVybkNvbnRlbnQ6IFsuLi5hY2N1bXVsYXRlZFR1cm5Db250ZW50XSxcbiAgICAgICAgICAgIGNvbnZlcnNhdGlvbklkOiB0aGlzLmV2ZW50LmNvbnZlcnNhdGlvbklkLFxuICAgICAgICAgICAgYXNzb2NpYXRlZFVzZXJNZXNzYWdlSWQ6IHRoaXMuZXZlbnQuY3VycmVudE1lc3NhZ2VJZCxcbiAgICAgICAgICAgIGNvbnRlbnRCbG9ja0luZGV4OiBsYXN0QmxvY2tJbmRleCxcbiAgICAgICAgICAgIHN0b3BSZWFzb246IHN0b3BSZWFzb24sXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbWVzc2FnZXMucHVzaChhY2N1bXVsYXRlZEFzc2lzdGFudE1lc3NhZ2UpO1xuICAgICAgICBpZiAoc3RvcFJlYXNvbiA9PT0gJ3Rvb2xfdXNlJykge1xuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlQ29udGVudEJsb2NrcyA9XG4gICAgICAgICAgICBhY2N1bXVsYXRlZEFzc2lzdGFudE1lc3NhZ2UuY29udGVudCA/PyBbXTtcbiAgICAgICAgICBjb25zdCB0b29sVXNlQmxvY2tzID0gcmVzcG9uc2VDb250ZW50QmxvY2tzLmZpbHRlcihcbiAgICAgICAgICAgIChibG9jaykgPT4gJ3Rvb2xVc2UnIGluIGJsb2NrXG4gICAgICAgICAgKSBhcyBBcnJheTxDb250ZW50QmxvY2suVG9vbFVzZU1lbWJlcj47XG4gICAgICAgICAgY29uc3QgdG9vbFJlc3BvbnNlQ29udGVudEJsb2NrczogQXJyYXk8Q29udGVudEJsb2NrPiA9IFtdO1xuICAgICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2VDb250ZW50QmxvY2sgb2YgdG9vbFVzZUJsb2Nrcykge1xuICAgICAgICAgICAgY29uc3QgdG9vbFVzZUJsb2NrID1cbiAgICAgICAgICAgICAgcmVzcG9uc2VDb250ZW50QmxvY2sgYXMgQ29udGVudEJsb2NrLlRvb2xVc2VNZW1iZXI7XG4gICAgICAgICAgICBjb25zdCB0b29sUmVzdWx0Q29udGVudEJsb2NrID0gYXdhaXQgdGhpcy5leGVjdXRlVG9vbCh0b29sVXNlQmxvY2spO1xuICAgICAgICAgICAgdG9vbFJlc3BvbnNlQ29udGVudEJsb2Nrcy5wdXNoKHRvb2xSZXN1bHRDb250ZW50QmxvY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIHJvbGU6ICd1c2VyJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6IHRvb2xSZXNwb25zZUNvbnRlbnRCbG9ja3MsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKHN0b3BSZWFzb24gPT09ICd0b29sX3VzZScpO1xuXG4gICAgICB5aWVsZCB7XG4gICAgICAgIGFjY3VtdWxhdGVkVHVybkNvbnRlbnQ6IFsuLi5hY2N1bXVsYXRlZFR1cm5Db250ZW50XSxcbiAgICAgICAgY29udmVyc2F0aW9uSWQ6IHRoaXMuZXZlbnQuY29udmVyc2F0aW9uSWQsXG4gICAgICAgIGFzc29jaWF0ZWRVc2VyTWVzc2FnZUlkOiB0aGlzLmV2ZW50LmN1cnJlbnRNZXNzYWdlSWQsXG4gICAgICAgIGNvbnRlbnRCbG9ja0luZGV4OiBsYXN0QmxvY2tJbmRleCxcbiAgICAgICAgc3RvcFJlYXNvbjogc3RvcFJlYXNvbixcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1N0cmVhbWluZyBjb252ZXJzYXRpb24gd2l0aCBCZWRyb2NrIGZhaWxlZCcsIGVycm9yKTtcbiAgICAgIGNvbnN0IGNvbnZlcnNhdGlvblR1cm5FcnJvciA9XG4gICAgICAgIHRoaXMuY29udmVydEVycm9yVG9Db252ZXJzYXRpb25UdXJuRXJyb3IoZXJyb3IpO1xuICAgICAgeWllbGQge1xuICAgICAgICBhY2N1bXVsYXRlZFR1cm5Db250ZW50OiBbLi4uYWNjdW11bGF0ZWRUdXJuQ29udGVudF0sXG4gICAgICAgIGNvbnZlcnNhdGlvbklkOiB0aGlzLmV2ZW50LmNvbnZlcnNhdGlvbklkLFxuICAgICAgICBhc3NvY2lhdGVkVXNlck1lc3NhZ2VJZDogdGhpcy5ldmVudC5jdXJyZW50TWVzc2FnZUlkLFxuICAgICAgICBjb250ZW50QmxvY2tJbmRleDogYmxvY2tJbmRleCxcbiAgICAgICAgZXJyb3JzOiBbY29udmVyc2F0aW9uVHVybkVycm9yXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hcHMgZXZlbnQgbWVzc2FnZXMgdG8gQmVkcm9jayB0eXBlcy5cbiAgICogMS4gTWFrZXMgYSBjb3B5IHNvIHRoYXQgd2UgZG9uJ3QgbXV0YXRlIGV2ZW50LlxuICAgKiAyLiBEZWNvZGVzIEJhc2U2NCBlbmNvZGVkIGltYWdlcy5cbiAgICovXG4gIHByaXZhdGUgZ2V0RXZlbnRNZXNzYWdlc0FzQmVkcm9ja01lc3NhZ2VzID0gYXN5bmMgKCk6IFByb21pc2U8XG4gICAgQXJyYXk8TWVzc2FnZT5cbiAgPiA9PiB7XG4gICAgY29uc3QgbWVzc2FnZXM6IEFycmF5PE1lc3NhZ2U+ID0gW107XG4gICAgY29uc3QgZXZlbnRNZXNzYWdlcyA9XG4gICAgICBhd2FpdCB0aGlzLm1lc3NhZ2VIaXN0b3J5UmV0cmlldmVyLmdldE1lc3NhZ2VIaXN0b3J5KCk7XG4gICAgZm9yIChjb25zdCBtZXNzYWdlIG9mIGV2ZW50TWVzc2FnZXMpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2VDb250ZW50OiBBcnJheTxDb250ZW50QmxvY2s+ID0gW107XG4gICAgICBmb3IgKGNvbnN0IGNvbnRlbnRFbGVtZW50IG9mIG1lc3NhZ2UuY29udGVudCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbnRlbnRFbGVtZW50LmltYWdlPy5zb3VyY2U/LmJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIG1lc3NhZ2VDb250ZW50LnB1c2goe1xuICAgICAgICAgICAgaW1hZ2U6IHtcbiAgICAgICAgICAgICAgZm9ybWF0OiBjb250ZW50RWxlbWVudC5pbWFnZS5mb3JtYXQsXG4gICAgICAgICAgICAgIHNvdXJjZToge1xuICAgICAgICAgICAgICAgIGJ5dGVzOiBCdWZmZXIuZnJvbShjb250ZW50RWxlbWVudC5pbWFnZS5zb3VyY2UuYnl0ZXMsICdiYXNlNjQnKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIHR5cGUgY29uZm9ybXMgdG8gQmVkcm9jaydzIHR5cGUgYW5kIGl0J3Mgc2FmZSB0byBjYXN0LlxuICAgICAgICAgIG1lc3NhZ2VDb250ZW50LnB1c2goY29udGVudEVsZW1lbnQgYXMgQ29udGVudEJsb2NrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbWVzc2FnZXMucHVzaCh7XG4gICAgICAgIHJvbGU6IG1lc3NhZ2Uucm9sZSxcbiAgICAgICAgY29udGVudDogbWVzc2FnZUNvbnRlbnQsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2VzO1xuICB9O1xuXG4gIHByaXZhdGUgY3JlYXRlVG9vbENvbmZpZ3VyYXRpb24gPSAoKTogVG9vbENvbmZpZ3VyYXRpb24gfCB1bmRlZmluZWQgPT4ge1xuICAgIGlmICh0aGlzLmFsbFRvb2xzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9vbHM6IHRoaXMuYWxsVG9vbHMubWFwKCh0KTogVG9vbCA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdG9vbFNwZWM6IHtcbiAgICAgICAgICAgIG5hbWU6IHQubmFtZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0LmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBjYXN0IHRvIGJlZHJvY2sgdHlwZSBhcyB3ZSdyZSB1c2luZyBkaWZmZXJlbnQgdHlwZXMgdG8gZGVzY3JpYmUgSlNPTiBzY2hlbWEgaW4gb3VyIEFQSS5cbiAgICAgICAgICAgIC8vIFRoZXNlIHR5cGVzIGFyZSBydW50aW1lIGNvbXBhdGlibGUuXG4gICAgICAgICAgICBpbnB1dFNjaGVtYTogdC5pbnB1dFNjaGVtYSBhcyBUb29sSW5wdXRTY2hlbWEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgIH07XG4gIH07XG5cbiAgcHJpdmF0ZSBleGVjdXRlVG9vbCA9IGFzeW5jIChcbiAgICB0b29sVXNlQmxvY2s6IENvbnRlbnRCbG9jay5Ub29sVXNlTWVtYmVyXG4gICk6IFByb21pc2U8Q29udGVudEJsb2NrPiA9PiB7XG4gICAgaWYgKCF0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lKSB7XG4gICAgICB0aHJvdyBFcnJvcignQmVkcm9jayB0b29sIHVzZSByZXNwb25zZSBpcyBtaXNzaW5nIGEgdG9vbCBuYW1lJyk7XG4gICAgfVxuICAgIGNvbnN0IHRvb2wgPSB0aGlzLmV4ZWN1dGFibGVUb29sQnlOYW1lLmdldCh0b29sVXNlQmxvY2sudG9vbFVzZS5uYW1lKTtcbiAgICBpZiAoIXRvb2wpIHtcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgQmVkcm9jayB0b29sIHVzZSByZXNwb25zZSBjb250YWlucyB1bmtub3duIHRvb2wgJyR7dG9vbFVzZUJsb2NrLnRvb2xVc2UubmFtZX0nYFxuICAgICAgKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9nZ2VyLmluZm8oYEludm9raW5nIHRvb2wgJHt0b29sLm5hbWV9YCk7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZygnVG9vbCBpbnB1dDonLCB0b29sVXNlQmxvY2sudG9vbFVzZS5pbnB1dCk7XG4gICAgICBjb25zdCB0b29sUmVzcG9uc2UgPSBhd2FpdCB0b29sLmV4ZWN1dGUodG9vbFVzZUJsb2NrLnRvb2xVc2UuaW5wdXQpO1xuICAgICAgdGhpcy5sb2dnZXIuaW5mbyhgUmVjZWl2ZWQgcmVzcG9uc2UgZnJvbSAke3Rvb2wubmFtZX0gdG9vbGApO1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcodG9vbFJlc3BvbnNlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvb2xSZXN1bHQ6IHtcbiAgICAgICAgICB0b29sVXNlSWQ6IHRvb2xVc2VCbG9jay50b29sVXNlLnRvb2xVc2VJZCxcbiAgICAgICAgICBjb250ZW50OiBbdG9vbFJlc3BvbnNlXSxcbiAgICAgICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRvb2xSZXN1bHQ6IHtcbiAgICAgICAgICAgIHRvb2xVc2VJZDogdG9vbFVzZUJsb2NrLnRvb2xVc2UudG9vbFVzZUlkLFxuICAgICAgICAgICAgY29udGVudDogW3sgdGV4dDogZS50b1N0cmluZygpIH1dLFxuICAgICAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b29sUmVzdWx0OiB7XG4gICAgICAgICAgdG9vbFVzZUlkOiB0b29sVXNlQmxvY2sudG9vbFVzZS50b29sVXNlSWQsXG4gICAgICAgICAgY29udGVudDogW3sgdGV4dDogJ3Vua25vd24gZXJyb3Igb2NjdXJyZWQnIH1dLFxuICAgICAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgY29udmVydEVycm9yVG9Db252ZXJzYXRpb25UdXJuRXJyb3IgPSAoXG4gICAgZXJyb3I6IHVua25vd25cbiAgKTogQ29udmVyc2F0aW9uVHVybkVycm9yID0+IHtcbiAgICBsZXQgZXJyb3JUeXBlID0gJ1Vua25vd25FcnJvcic7XG4gICAgbGV0IG1lc3NhZ2U6IHN0cmluZztcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICBpZiAoZXJyb3IubmFtZSkge1xuICAgICAgICBlcnJvclR5cGUgPSBlcnJvci5uYW1lO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBtZXNzYWdlID0gSlNPTi5zdHJpbmdpZnkoZXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgZXJyb3JUeXBlLFxuICAgICAgbWVzc2FnZSxcbiAgICB9O1xuICB9O1xufVxuIl19
|