@aws-cdk/integ-tests-alpha
Version:
CDK Integration Testing Constructs
170 lines • 20.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = handler;
exports.onTimeout = onTimeout;
exports.isComplete = isComplete;
/* eslint-disable no-console */
const assertion_1 = require("./assertion");
const http_1 = require("./http");
const sdk_1 = require("./sdk");
const types = require("./types");
async function handler(event, context) {
console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`);
const provider = createResourceHandler(event, context);
try {
// if we are deleting the custom resource, just respond
// with 'SUCCESS' since there is nothing to do.
if (event.RequestType === 'Delete') {
await provider.respond({
status: 'SUCCESS',
reason: 'OK',
});
return;
}
const result = await provider.handle();
// if there is a `stateMachineArn` then we have already started a state machine
// execution and the rest will be handled there
if ('stateMachineArn' in event.ResourceProperties) {
console.info('Found "stateMachineArn", waiter statemachine started');
return;
}
else if ('expected' in event.ResourceProperties) {
console.info('Found "expected", testing assertions');
const actualPath = event.ResourceProperties.actualPath;
// if we are providing a path to make the assertion at, that means that we have
// flattened the response, otherwise the path to assert against in the entire response
const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
const assertion = new assertion_1.AssertionHandler({
...event,
ResourceProperties: {
ServiceToken: event.ServiceToken,
actual,
expected: event.ResourceProperties.expected,
},
}, context);
try {
const assertionResult = await assertion.handle();
await provider.respond({
status: 'SUCCESS',
reason: 'OK',
// return both the result of the API call _and_ the assertion results
data: {
...assertionResult,
...result,
},
});
return;
}
catch (e) {
await provider.respond({
status: 'FAILED',
reason: e.message ?? 'Internal Error',
});
return;
}
}
await provider.respond({
status: 'SUCCESS',
reason: 'OK',
data: result,
});
}
catch (e) {
await provider.respond({
status: 'FAILED',
reason: e.message ?? 'Internal Error',
});
return;
}
return;
}
/**
* Invoked by the waiter statemachine when the retry
* attempts are exhausted
*/
async function onTimeout(timeoutEvent) {
// the event payload is passed through the `errorMessage` in the state machine
// timeout event
const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage);
const provider = createResourceHandler(isCompleteRequest, standardContext);
await provider.respond({
status: 'FAILED',
reason: 'Operation timed out: ' + JSON.stringify(isCompleteRequest),
});
}
/**
* Invoked by the waiter statemachine when the user is waiting for a specific
* result.
*
* If the result of the assertion is not successful then it will throw an error
* which will cause the state machine to try again
*/
async function isComplete(event, context) {
console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`);
const provider = createResourceHandler(event, context);
try {
const result = await provider.handleIsComplete();
const actualPath = event.ResourceProperties.actualPath;
if (result) {
const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse;
if ('expected' in event.ResourceProperties) {
const assertion = new assertion_1.AssertionHandler({
...event,
ResourceProperties: {
ServiceToken: event.ServiceToken,
actual,
expected: event.ResourceProperties.expected,
},
}, context);
const assertionResult = await assertion.handleIsComplete();
if (!(assertionResult?.failed)) {
await provider.respond({
status: 'SUCCESS',
reason: 'OK',
data: {
...assertionResult,
...result,
},
});
return;
}
else {
console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`);
throw new Error(JSON.stringify(event));
}
}
await provider.respond({
status: 'SUCCESS',
reason: 'OK',
data: result,
});
}
else {
console.log('No result');
throw new Error(JSON.stringify(event));
}
return;
}
catch (e) {
console.log(e);
throw new Error(JSON.stringify(event));
}
}
function createResourceHandler(event, context) {
if (event.ResourceType.startsWith(types.SDK_RESOURCE_TYPE_PREFIX)) {
return new sdk_1.AwsApiCallHandler(event, context);
}
else if (event.ResourceType.startsWith(types.ASSERT_RESOURCE_TYPE)) {
return new assertion_1.AssertionHandler(event, context);
}
else if (event.ResourceType.startsWith(types.HTTP_RESOURCE_TYPE)) {
return new http_1.HttpHandler(event, context);
}
else {
throw new Error(`Unsupported resource type "${event.ResourceType}`);
}
}
const standardContext = {
getRemainingTimeInMillis: () => 90000,
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLDBCQWtFQztBQU1ELDhCQVNDO0FBU0QsZ0NBK0NDO0FBL0lELCtCQUErQjtBQUMvQiwyQ0FBK0M7QUFDL0MsaUNBQXFDO0FBQ3JDLCtCQUEwQztBQUMxQyxpQ0FBaUM7QUFFMUIsS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRCxFQUFFLE9BQTBCO0lBQzFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxJQUFJLENBQUM7UUFDSCx1REFBdUQ7UUFDdkQsK0NBQStDO1FBQy9DLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3JCLE1BQU0sRUFBRSxTQUFTO2dCQUNqQixNQUFNLEVBQUUsSUFBSTthQUNiLENBQUMsQ0FBQztZQUNILE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdkMsK0VBQStFO1FBQy9FLCtDQUErQztRQUMvQyxJQUFJLGlCQUFpQixJQUFJLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQ2xELE9BQU8sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUNyRSxPQUFPO1FBQ1QsQ0FBQzthQUFNLElBQUksVUFBVSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQ2xELE9BQU8sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLENBQUMsQ0FBQztZQUNyRCxNQUFNLFVBQVUs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O0lBQzNCLHdCQUF3QixFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUs7Q0FDdEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCB7IEFzc2VydGlvbkhhbmRsZXIgfSBmcm9tICcuL2Fzc2VydGlvbic7XG5pbXBvcnQgeyBIdHRwSGFuZGxlciB9IGZyb20gJy4vaHR0cCc7XG5pbXBvcnQgeyBBd3NBcGlDYWxsSGFuZGxlciB9IGZyb20gJy4vc2RrJztcbmltcG9ydCAqIGFzIHR5cGVzIGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgY29uc29sZS5sb2coYEV2ZW50OiAke0pTT04uc3RyaW5naWZ5KHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9KX1gKTtcbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVSZXNvdXJjZUhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB0cnkge1xuICAgIC8vIGlmIHdlIGFyZSBkZWxldGluZyB0aGUgY3VzdG9tIHJlc291cmNlLCBqdXN0IHJlc3BvbmRcbiAgICAvLyB3aXRoICdTVUNDRVNTJyBzaW5jZSB0aGVyZSBpcyBub3RoaW5nIHRvIGRvLlxuICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICBzdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmhhbmRsZSgpO1xuICAgIC8vIGlmIHRoZXJlIGlzIGEgYHN0YXRlTWFjaGluZUFybmAgdGhlbiB3ZSBoYXZlIGFscmVhZHkgc3RhcnRlZCBhIHN0YXRlIG1hY2hpbmVcbiAgICAvLyBleGVjdXRpb24gYW5kIHRoZSByZXN0IHdpbGwgYmUgaGFuZGxlZCB0aGVyZVxuICAgIGlmICgnc3RhdGVNYWNoaW5lQXJuJyBpbiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpIHtcbiAgICAgIGNvbnNvbGUuaW5mbygnRm91bmQgXCJzdGF0ZU1hY2hpbmVBcm5cIiwgd2FpdGVyIHN0YXRlbWFjaGluZSBzdGFydGVkJyk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmICgnZXhwZWN0ZWQnIGluIGV2ZW50LlJlc291cmNlUHJvcGVydGllcykge1xuICAgICAgY29uc29sZS5pbmZvKCdGb3VuZCBcImV4cGVjdGVkXCIsIHRlc3RpbmcgYXNzZXJ0aW9ucycpO1xuICAgICAgY29uc3QgYWN0dWFsUGF0aCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5hY3R1YWxQYXRoO1xuICAgICAgLy8gaWYgd2UgYXJlIHByb3ZpZGluZyBhIHBhdGggdG8gbWFrZSB0aGUgYXNzZXJ0aW9uIGF0LCB0aGF0IG1lYW5zIHRoYXQgd2UgaGF2ZVxuICAgICAgLy8gZmxhdHRlbmVkIHRoZSByZXNwb25zZSwgb3RoZXJ3aXNlIHRoZSBwYXRoIHRvIGFzc2VydCBhZ2FpbnN0IGluIHRoZSBlbnRpcmUgcmVzcG9uc2VcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGFjdHVhbFBhdGggPyAocmVzdWx0IGFzIHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pW2BhcGlDYWxsUmVzcG9uc2UuJHthY3R1YWxQYXRofWBdIDogKHJlc3VsdCBhcyB0eXBlcy5Bd3NBcGlDYWxsUmVzdWx0KS5hcGlDYWxsUmVzcG9uc2U7XG4gICAgICBjb25zdCBhc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uSGFuZGxlcih7XG4gICAgICAgIC4uLmV2ZW50LFxuICAgICAgICBSZXNvdXJjZVByb3BlcnRpZXM6IHtcbiAgICAgICAgICBTZXJ2aWNlVG9rZW46IGV2ZW50LlNlcnZpY2VUb2tlbixcbiAgICAgICAgICBhY3R1YWwsXG4gICAgICAgICAgZXhwZWN0ZWQ6IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5leHBlY3RlZCxcbiAgICAgICAgfSxcbiAgICAgIH0sIGNvbnRleHQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXNzZXJ0aW9uUmVzdWx0ID0gYXdhaXQgYXNzZXJ0aW9uLmhhbmRsZSgpO1xuICAgICAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgICAgICBzdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgICAgICByZWFzb246ICdPSycsXG4gICAgICAgICAgLy8gcmV0dXJuIGJvdGggdGhlIHJlc3VsdCBvZiB0aGUgQVBJIGNhbGwgX2FuZF8gdGhlIGFzc2VydGlvbiByZXN1bHRzXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgLi4uYXNzZXJ0aW9uUmVzdWx0LFxuICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICAgICAgc3RhdHVzOiAnRkFJTEVEJyxcbiAgICAgICAgICByZWFzb246IGUubWVzc2FnZSA/PyAnSW50ZXJuYWwgRXJyb3InLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgZGF0YTogcmVzdWx0LFxuICAgIH0pO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgIHN0YXR1czogJ0ZBSUxFRCcsXG4gICAgICByZWFzb246IGUubWVzc2FnZSA/PyAnSW50ZXJuYWwgRXJyb3InLFxuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm47XG59XG5cbi8qKlxuICogSW52b2tlZCBieSB0aGUgd2FpdGVyIHN0YXRlbWFjaGluZSB3aGVuIHRoZSByZXRyeVxuICogYXR0ZW1wdHMgYXJlIGV4aGF1c3RlZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25UaW1lb3V0KHRpbWVvdXRFdmVudDogYW55KSB7XG4gIC8vIHRoZSBldmVudCBwYXlsb2FkIGlzIHBhc3NlZCB0aHJvdWdoIHRoZSBgZXJyb3JNZXNzYWdlYCBpbiB0aGUgc3RhdGUgbWFjaGluZVxuICAvLyB0aW1lb3V0IGV2ZW50XG4gIGNvbnN0IGlzQ29tcGxldGVSZXF1ZXN0ID0gSlNPTi5wYXJzZShKU09OLnBhcnNlKHRpbWVvdXRFdmVudC5DYXVzZSkuZXJyb3JNZXNzYWdlKTtcbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVSZXNvdXJjZUhhbmRsZXIoaXNDb21wbGV0ZVJlcXVlc3QsIHN0YW5kYXJkQ29udGV4dCk7XG4gIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgIHN0YXR1czogJ0ZBSUxFRCcsXG4gICAgcmVhc29uOiAnT3BlcmF0aW9uIHRpbWVkIG91dDogJyArIEpTT04uc3RyaW5naWZ5KGlzQ29tcGxldGVSZXF1ZXN0KSxcbiAgfSk7XG59XG5cbi8qKlxuICogSW52b2tlZCBieSB0aGUgd2FpdGVyIHN0YXRlbWFjaGluZSB3aGVuIHRoZSB1c2VyIGlzIHdhaXRpbmcgZm9yIGEgc3BlY2lmaWNcbiAqIHJlc3VsdC5cbiAqXG4gKiBJZiB0aGUgcmVzdWx0IG9mIHRoZSBhc3NlcnRpb24gaXMgbm90IHN1Y2Nlc3NmdWwgdGhlbiBpdCB3aWxsIHRocm93IGFuIGVycm9yXG4gKiB3aGljaCB3aWxsIGNhdXNlIHRoZSBzdGF0ZSBtYWNoaW5lIHRvIHRyeSBhZ2FpblxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNDb21wbGV0ZShldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgY29uc29sZS5sb2coYEV2ZW50OiAke0pTT04uc3RyaW5naWZ5KHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9KX1gKTtcbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVSZXNvdXJjZUhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmhhbmRsZUlzQ29tcGxldGUoKTtcbiAgICBjb25zdCBhY3R1YWxQYXRoID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmFjdHVhbFBhdGg7XG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgY29uc3QgYWN0dWFsID0gYWN0dWFsUGF0aCA/IChyZXN1bHQgYXMgeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSlbYGFwaUNhbGxSZXNwb25zZS4ke2FjdHVhbFBhdGh9YF0gOiAocmVzdWx0IGFzIHR5cGVzLkF3c0FwaUNhbGxSZXN1bHQpLmFwaUNhbGxSZXNwb25zZTtcbiAgICAgIGlmICgnZXhwZWN0ZWQnIGluIGV2ZW50LlJlc291cmNlUHJvcGVydGllcykge1xuICAgICAgICBjb25zdCBhc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uSGFuZGxlcih7XG4gICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgUmVzb3VyY2VQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBTZXJ2aWNlVG9rZW46IGV2ZW50LlNlcnZpY2VUb2tlbixcbiAgICAgICAgICAgIGFjdHVhbCxcbiAgICAgICAgICAgIGV4cGVjdGVkOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuZXhwZWN0ZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSwgY29udGV4dCk7XG4gICAgICAgIGNvbnN0IGFzc2VydGlvblJlc3VsdCA9IGF3YWl0IGFzc2VydGlvbi5oYW5kbGVJc0NvbXBsZXRlKCk7XG4gICAgICAgIGlmICghKGFzc2VydGlvblJlc3VsdD8uZmFpbGVkKSkge1xuICAgICAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICAgICAgc3RhdHVzOiAnU1VDQ0VTUycsXG4gICAgICAgICAgICByZWFzb246ICdPSycsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIC4uLmFzc2VydGlvblJlc3VsdCxcbiAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYEFzc2VydGlvbiBGYWlsZWQ6ICR7SlNPTi5zdHJpbmdpZnkoYXNzZXJ0aW9uUmVzdWx0KX1gKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgICByZWFzb246ICdPSycsXG4gICAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZygnTm8gcmVzdWx0Jyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBpZiAoZXZlbnQuUmVzb3VyY2VUeXBlLnN0YXJ0c1dpdGgodHlwZXMuU0RLX1JFU09VUkNFX1RZUEVfUFJFRklYKSkge1xuICAgIHJldHVybiBuZXcgQXdzQXBpQ2FsbEhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlc291cmNlVHlwZS5zdGFydHNXaXRoKHR5cGVzLkFTU0VSVF9SRVNPVVJDRV9UWVBFKSkge1xuICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uSGFuZGxlcihldmVudCwgY29udGV4dCk7XG4gIH0gZWxzZSBpZiAoZXZlbnQuUmVzb3VyY2VUeXBlLnN0YXJ0c1dpdGgodHlwZXMuSFRUUF9SRVNPVVJDRV9UWVBFKSkge1xuICAgIHJldHVybiBuZXcgSHR0cEhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcmVzb3VyY2UgdHlwZSBcIiR7ZXZlbnQuUmVzb3VyY2VUeXBlfWApO1xuICB9XG59XG5cbmNvbnN0IHN0YW5kYXJkQ29udGV4dDogYW55ID0ge1xuICBnZXRSZW1haW5pbmdUaW1lSW5NaWxsaXM6ICgpID0+IDkwMDAwLFxufTtcbiJdfQ==