UNPKG

18.2 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.isSuperObject = exports.ResourcePart = exports.HaveResourceAssertion = exports.haveResourceLike = exports.haveResource = exports.ABSENT = void 0;
4const assertion_1 = require("../assertion");
5const have_resource_matchers_1 = require("./have-resource-matchers");
6/**
7 * Magic value to signify that a certain key should be absent from the property bag.
8 *
9 * The property is either not present or set to `undefined.
10 *
11 * NOTE: `ABSENT` only works with the `haveResource()` and `haveResourceLike()`
12 * assertions.
13 */
14exports.ABSENT = '{{ABSENT}}';
15/**
16 * An assertion to check whether a resource of a given type and with the given properties exists, disregarding properties
17 *
18 * @param resourceType the type of the resource that is expected to be present.
19 * @param properties the properties that the resource is expected to have. A function may be provided, in which case
20 * it will be called with the properties of candidate resources and an ``InspectionFailure``
21 * instance on which errors should be appended, and should return a truthy value to denote a match.
22 * @param comparison the entity that is being asserted against.
23 * @param allowValueExtension if properties is an object, tells whether values must match exactly, or if they are
24 * allowed to be supersets of the reference values. Meaningless if properties is a function.
25 */
26function haveResource(resourceType, properties, comparison, allowValueExtension = false) {
27 return new HaveResourceAssertion(resourceType, properties, comparison, allowValueExtension);
28}
29exports.haveResource = haveResource;
30/**
31 * Sugar for calling ``haveResource`` with ``allowValueExtension`` set to ``true``.
32 */
33function haveResourceLike(resourceType, properties, comparison) {
34 return haveResource(resourceType, properties, comparison, true);
35}
36exports.haveResourceLike = haveResourceLike;
37class HaveResourceAssertion extends assertion_1.JestFriendlyAssertion {
38 constructor(resourceType, properties, part, allowValueExtension = false) {
39 super();
40 this.resourceType = resourceType;
41 this.inspected = [];
42 this.matcher = isCallable(properties) ? properties :
43 properties === undefined ? have_resource_matchers_1.anything() :
44 allowValueExtension ? have_resource_matchers_1.deepObjectLike(properties) :
45 have_resource_matchers_1.objectLike(properties);
46 this.part = part !== null && part !== void 0 ? part : ResourcePart.Properties;
47 }
48 assertUsing(inspector) {
49 var _a;
50 for (const logicalId of Object.keys(inspector.value.Resources || {})) {
51 const resource = inspector.value.Resources[logicalId];
52 if (resource.Type === this.resourceType) {
53 const propsToCheck = this.part === ResourcePart.Properties ? ((_a = resource.Properties) !== null && _a !== void 0 ? _a : {}) : resource;
54 // Pass inspection object as 2nd argument, initialize failure with default string,
55 // to maintain backwards compatibility with old predicate API.
56 const inspection = { resource, failureReason: 'Object did not match predicate' };
57 if (have_resource_matchers_1.match(propsToCheck, this.matcher, inspection)) {
58 return true;
59 }
60 this.inspected.push(inspection);
61 }
62 }
63 return false;
64 }
65 generateErrorMessage() {
66 const lines = [];
67 lines.push(`None of ${this.inspected.length} resources matches ${this.description}.`);
68 for (const inspected of this.inspected) {
69 lines.push(`- ${inspected.failureReason} in:`);
70 lines.push(indent(4, JSON.stringify(inspected.resource, null, 2)));
71 }
72 return lines.join('\n');
73 }
74 assertOrThrow(inspector) {
75 if (!this.assertUsing(inspector)) {
76 throw new Error(this.generateErrorMessage());
77 }
78 }
79 get description() {
80 // eslint-disable-next-line max-len
81 return `resource '${this.resourceType}' with ${JSON.stringify(this.matcher, undefined, 2)}`;
82 }
83}
84exports.HaveResourceAssertion = HaveResourceAssertion;
85function indent(n, s) {
86 const prefix = ' '.repeat(n);
87 return prefix + s.replace(/\n/g, '\n' + prefix);
88}
89/**
90 * What part of the resource to compare
91 */
92var ResourcePart;
93(function (ResourcePart) {
94 /**
95 * Only compare the resource's properties
96 */
97 ResourcePart[ResourcePart["Properties"] = 0] = "Properties";
98 /**
99 * Check the entire CloudFormation config
100 *
101 * (including UpdateConfig, DependsOn, etc.)
102 */
103 ResourcePart[ResourcePart["CompleteDefinition"] = 1] = "CompleteDefinition";
104})(ResourcePart = exports.ResourcePart || (exports.ResourcePart = {}));
105/**
106 * Whether a value is a callable
107 */
108function isCallable(x) {
109 return x && {}.toString.call(x) === '[object Function]';
110}
111/**
112 * Return whether `superObj` is a super-object of `obj`.
113 *
114 * A super-object has the same or more property values, recursing into sub properties if ``allowValueExtension`` is true.
115 *
116 * At any point in the object, a value may be replaced with a function which will be used to check that particular field.
117 * The type of a matcher function is expected to be of type PropertyMatcher.
118 *
119 * @deprecated - Use `objectLike` or a literal object instead.
120 */
121function isSuperObject(superObj, pattern, errors = [], allowValueExtension = false) {
122 const matcher = allowValueExtension ? have_resource_matchers_1.deepObjectLike(pattern) : have_resource_matchers_1.objectLike(pattern);
123 const inspection = { resource: superObj, failureReason: '' };
124 const ret = have_resource_matchers_1.match(superObj, matcher, inspection);
125 if (!ret) {
126 errors.push(inspection.failureReason);
127 }
128 return ret;
129}
130exports.isSuperObject = isSuperObject;
131//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGF2ZS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhhdmUtcmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNENBQWdFO0FBRWhFLHFFQUF1RjtBQUV2Rjs7Ozs7OztHQU9HO0FBQ1UsUUFBQSxNQUFNLEdBQUcsWUFBWSxDQUFDO0FBRW5DOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixZQUFZLENBQzFCLFlBQW9CLEVBQ3BCLFVBQWdCLEVBQ2hCLFVBQXlCLEVBQ3pCLHNCQUErQixLQUFLO0lBQ3BDLE9BQU8sSUFBSSxxQkFBcUIsQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0FBQzlGLENBQUM7QUFORCxvQ0FNQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQzlCLFlBQW9CLEVBQ3BCLFVBQWdCLEVBQ2hCLFVBQXlCO0lBQ3pCLE9BQU8sWUFBWSxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFMRCw0Q0FLQztBQUlELE1BQWEscUJBQXNCLFNBQVEsaUNBQXFDO0lBSzlFLFlBQ21CLFlBQW9CLEVBQ3JDLFVBQWdCLEVBQ2hCLElBQW1CLEVBQ25CLHNCQUErQixLQUFLO1FBQ3BDLEtBQUssRUFBRSxDQUFDO1FBSlMsaUJBQVksR0FBWixZQUFZLENBQVE7UUFMdEIsY0FBUyxHQUF3QixFQUFFLENBQUM7UUFXbkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlDQUFRLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsdUNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO29CQUNoRCxtQ0FBVSxDQUFDLFVB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WXZCO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxDQUFNO0lBQ3hCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLG1CQUFtQixDQUFDO0FBQzFELENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFnQixhQUFhLENBQUMsUUFBYSxFQUFFLE9BQVksRUFBRSxTQUFtQixFQUFFLEVBQUUsc0JBQStCLEtBQUs7SUFDcEgsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLHVDQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1DQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFcEYsTUFBTSxVQUFVLEdBQXNCLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDaEYsTUFBTSxHQUFHLEdBQUcsOEJBQUssQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDUixNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztLQUN2QztJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQVRELHNDQVNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXNzZXJ0aW9uLCBKZXN0RnJpZW5kbHlBc3NlcnRpb24gfSBmcm9tICcuLi9hc3NlcnRpb24nO1xuaW1wb3J0IHsgU3RhY2tJbnNwZWN0b3IgfSBmcm9tICcuLi9pbnNwZWN0b3InO1xuaW1wb3J0IHsgYW55dGhpbmcsIGRlZXBPYmplY3RMaWtlLCBtYXRjaCwgb2JqZWN0TGlrZSB9IGZyb20gJy4vaGF2ZS1yZXNvdXJjZS1tYXRjaGVycyc7XG5cbi8qKlxuICogTWFnaWMgdmFsdWUgdG8gc2lnbmlmeSB0aGF0IGEgY2VydGFpbiBrZXkgc2hvdWxkIGJlIGFic2VudCBmcm9tIHRoZSBwcm9wZXJ0eSBiYWcuXG4gKlxuICogVGhlIHByb3BlcnR5IGlzIGVpdGhlciBub3QgcHJlc2VudCBvciBzZXQgdG8gYHVuZGVmaW5lZC5cbiAqXG4gKiBOT1RFOiBgQUJTRU5UYCBvbmx5IHdvcmtzIHdpdGggdGhlIGBoYXZlUmVzb3VyY2UoKWAgYW5kIGBoYXZlUmVzb3VyY2VMaWtlKClgXG4gKiBhc3NlcnRpb25zLlxuICovXG5leHBvcnQgY29uc3QgQUJTRU5UID0gJ3t7QUJTRU5UfX0nO1xuXG4vKipcbiAqIEFuIGFzc2VydGlvbiB0byBjaGVjayB3aGV0aGVyIGEgcmVzb3VyY2Ugb2YgYSBnaXZlbiB0eXBlIGFuZCB3aXRoIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIGV4aXN0cywgZGlzcmVnYXJkaW5nIHByb3BlcnRpZXNcbiAqXG4gKiBAcGFyYW0gcmVzb3VyY2VUeXBlIHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSB0aGF0IGlzIGV4cGVjdGVkIHRvIGJlIHByZXNlbnQuXG4gKiBAcGFyYW0gcHJvcGVydGllcyAgIHRoZSBwcm9wZXJ0aWVzIHRoYXQgdGhlIHJlc291cmNlIGlzIGV4cGVjdGVkIHRvIGhhdmUuIEEgZnVuY3Rpb24gbWF5IGJlIHByb3ZpZGVkLCBpbiB3aGljaCBjYXNlXG4gKiAgICAgICAgICAgICAgICAgICAgIGl0IHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIHByb3BlcnRpZXMgb2YgY2FuZGlkYXRlIHJlc291cmNlcyBhbmQgYW4gYGBJbnNwZWN0aW9uRmFpbHVyZWBgXG4gKiAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlIG9uIHdoaWNoIGVycm9ycyBzaG91bGQgYmUgYXBwZW5kZWQsIGFuZCBzaG91bGQgcmV0dXJuIGEgdHJ1dGh5IHZhbHVlIHRvIGRlbm90ZSBhIG1hdGNoLlxuICogQHBhcmFtIGNvbXBhcmlzb24gICB0aGUgZW50aXR5IHRoYXQgaXMgYmVpbmcgYXNzZXJ0ZWQgYWdhaW5zdC5cbiAqIEBwYXJhbSBhbGxvd1ZhbHVlRXh0ZW5zaW9uIGlmIHByb3BlcnRpZXMgaXMgYW4gb2JqZWN0LCB0ZWxscyB3aGV0aGVyIHZhbHVlcyBtdXN0IG1hdGNoIGV4YWN0bHksIG9yIGlmIHRoZXkgYXJlXG4gKiAgICAgICAgICAgICAgICAgICAgIGFsbG93ZWQgdG8gYmUgc3VwZXJzZXRzIG9mIHRoZSByZWZlcmVuY2UgdmFsdWVzLiBNZWFuaW5nbGVzcyBpZiBwcm9wZXJ0aWVzIGlzIGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXZlUmVzb3VyY2UoXG4gIHJlc291cmNlVHlwZTogc3RyaW5nLFxuICBwcm9wZXJ0aWVzPzogYW55LFxuICBjb21wYXJpc29uPzogUmVzb3VyY2VQYXJ0LFxuICBhbGxvd1ZhbHVlRXh0ZW5zaW9uOiBib29sZWFuID0gZmFsc2UpOiBBc3NlcnRpb248U3RhY2tJbnNwZWN0b3I+IHtcbiAgcmV0dXJuIG5ldyBIYXZlUmVzb3VyY2VBc3NlcnRpb24ocmVzb3VyY2VUeXBlLCBwcm9wZXJ0aWVzLCBjb21wYXJpc29uLCBhbGxvd1ZhbHVlRXh0ZW5zaW9uKTtcbn1cblxuLyoqXG4gKiBTdWdhciBmb3IgY2FsbGluZyBgYGhhdmVSZXNvdXJjZWBgIHdpdGggYGBhbGxvd1ZhbHVlRXh0ZW5zaW9uYGAgc2V0IHRvIGBgdHJ1ZWBgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGF2ZVJlc291cmNlTGlrZShcbiAgcmVzb3VyY2VUeXBlOiBzdHJpbmcsXG4gIHByb3BlcnRpZXM/OiBhbnksXG4gIGNvbXBhcmlzb24/OiBSZXNvdXJjZVBhcnQpIHtcbiAgcmV0dXJuIGhhdmVSZXNvdXJjZShyZXNvdXJjZVR5cGUsIHByb3BlcnRpZXMsIGNvbXBhcmlzb24sIHRydWUpO1xufVxuXG5leHBvcnQgdHlwZSBQcm9wZXJ0eU1hdGNoZXIgPSAocHJvcHM6IGFueSwgaW5zcGVjdGlvbjogSW5zcGVjdGlvbkZhaWx1cmUpID0+IGJvb2xlYW47XG5cbmV4cG9ydCBjbGFzcyBIYXZlUmVzb3VyY2VBc3NlcnRpb24gZXh0ZW5kcyBKZXN0RnJpZW5kbHlBc3NlcnRpb248U3RhY2tJbnNwZWN0b3I+IHtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnNwZWN0ZWQ6IEluc3BlY3Rpb25GYWlsdXJlW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBwYXJ0OiBSZXNvdXJjZVBhcnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF0Y2hlcjogYW55O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VUeXBlOiBzdHJpbmcsXG4gICAgcHJvcGVydGllcz86IGFueSxcbiAgICBwYXJ0PzogUmVzb3VyY2VQYXJ0LFxuICAgIGFsbG93VmFsdWVFeHRlbnNpb246IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLm1hdGNoZXIgPSBpc0NhbGxhYmxlKHByb3BlcnRpZXMpID8gcHJvcGVydGllcyA6XG4gICAgICBwcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyBhbnl0aGluZygpIDpcbiAgICAgICAgYWxsb3dWYWx1ZUV4dGVuc2lvbiA/IGRlZXBPYmplY3RMaWtlKHByb3BlcnRpZXMpIDpcbiAgICAgICAgICBvYmplY3RMaWtlKHByb3BlcnRpZXMpO1xuICAgIHRoaXMucGFydCA9IHBhcnQgPz8gUmVzb3VyY2VQYXJ0LlByb3BlcnRpZXM7XG4gIH1cblxuICBwdWJsaWMgYXNzZXJ0VXNpbmcoaW5zcGVjdG9yOiBTdGFja0luc3BlY3Rvcik6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgbG9naWNhbElkIG9mIE9iamVjdC5rZXlzKGluc3BlY3Rvci52YWx1ZS5SZXNvdXJjZXMgfHwge30pKSB7XG4gICAgICBjb25zdCByZXNvdXJjZSA9IGluc3BlY3Rvci52YWx1ZS5SZXNvdXJjZXNbbG9naWNhbElkXTtcbiAgICAgIGlmIChyZXNvdXJjZS5UeXBlID09PSB0aGlzLnJlc291cmNlVHlwZSkge1xuICAgICAgICBjb25zdCBwcm9wc1RvQ2hlY2sgPSB0aGlzLnBhcnQgPT09IFJlc291cmNlUGFydC5Qcm9wZXJ0aWVzID8gKHJlc291cmNlLlByb3BlcnRpZXMgPz8ge30pIDogcmVzb3VyY2U7XG5cbiAgICAgICAgLy8gUGFzcyBpbnNwZWN0aW9uIG9iamVjdCBhcyAybmQgYXJndW1lbnQsIGluaXRpYWxpemUgZmFpbHVyZSB3aXRoIGRlZmF1bHQgc3RyaW5nLFxuICAgICAgICAvLyB0byBtYWludGFpbiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3aXRoIG9sZCBwcmVkaWNhdGUgQVBJLlxuICAgICAgICBjb25zdCBpbnNwZWN0aW9uID0geyByZXNvdXJjZSwgZmFpbHVyZVJlYXNvbjogJ09iamVjdCBkaWQgbm90IG1hdGNoIHByZWRpY2F0ZScgfTtcblxuICAgICAgICBpZiAobWF0Y2gocHJvcHNUb0NoZWNrLCB0aGlzLm1hdGNoZXIsIGluc3BlY3Rpb24pKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmluc3BlY3RlZC5wdXNoKGluc3BlY3Rpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBnZW5lcmF0ZUVycm9yTWVzc2FnZSgpIHtcbiAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBsaW5lcy5wdXNoKGBOb25lIG9mICR7dGhpcy5pbnNwZWN0ZWQubGVuZ3RofSByZXNvdXJjZXMgbWF0Y2hlcyAke3RoaXMuZGVzY3JpcHRpb259LmApO1xuXG4gICAgZm9yIChjb25zdCBpbnNwZWN0ZWQgb2YgdGhpcy5pbnNwZWN0ZWQpIHtcbiAgICAgIGxpbmVzLnB1c2goYC0gJHtpbnNwZWN0ZWQuZmFpbHVyZVJlYXNvbn0gaW46YCk7XG4gICAgICBsaW5lcy5wdXNoKGluZGVudCg0LCBKU09OLnN0cmluZ2lmeShpbnNwZWN0ZWQucmVzb3VyY2UsIG51bGwsIDIpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHVibGljIGFzc2VydE9yVGhyb3coaW5zcGVjdG9yOiBTdGFja0luc3BlY3Rvcikge1xuICAgIGlmICghdGhpcy5hc3NlcnRVc2luZyhpbnNwZWN0b3IpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5nZW5lcmF0ZUVycm9yTWVzc2FnZSgpKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IGRlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICByZXR1cm4gYHJlc291cmNlICcke3RoaXMucmVzb3VyY2VUeXBlfScgd2l0aCAke0pTT04uc3RyaW5naWZ5KHRoaXMubWF0Y2hlciwgdW5kZWZpbmVkLCAyKX1gO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGVudChuOiBudW1iZXIsIHM6IHN0cmluZykge1xuICBjb25zdCBwcmVmaXggPSAnICcucmVwZWF0KG4pO1xuICByZXR1cm4gcHJlZml4ICsgcy5yZXBsYWNlKC9cXG4vZywgJ1xcbicgKyBwcmVmaXgpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluc3BlY3Rpb25GYWlsdXJlIHtcbiAgcmVzb3VyY2U6IGFueTtcbiAgZmFpbHVyZVJlYXNvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIFdoYXQgcGFydCBvZiB0aGUgcmVzb3VyY2UgdG8gY29tcGFyZVxuICovXG5leHBvcnQgZW51bSBSZXNvdXJjZVBhcnQge1xuICAvKipcbiAgICogT25seSBjb21wYXJlIHRoZSByZXNvdXJjZSdzIHByb3BlcnRpZXNcbiAgICovXG4gIFByb3BlcnRpZXMsXG5cbiAgLyoqXG4gICAqIENoZWNrIHRoZSBlbnRpcmUgQ2xvdWRGb3JtYXRpb24gY29uZmlnXG4gICAqXG4gICAqIChpbmNsdWRpbmcgVXBkYXRlQ29uZmlnLCBEZXBlbmRzT24sIGV0Yy4pXG4gICAqL1xuICBDb21wbGV0ZURlZmluaXRpb25cbn1cblxuLyoqXG4gKiBXaGV0aGVyIGEgdmFsdWUgaXMgYSBjYWxsYWJsZVxuICovXG5mdW5jdGlvbiBpc0NhbGxhYmxlKHg6IGFueSk6IHggaXMgKCguLi5hcmdzOiBhbnlbXSkgPT4gYW55KSB7XG4gIHJldHVybiB4ICYmIHt9LnRvU3RyaW5nLmNhbGwoeCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYHN1cGVyT2JqYCBpcyBhIHN1cGVyLW9iamVjdCBvZiBgb2JqYC5cbiAqXG4gKiBBIHN1cGVyLW9iamVjdCBoYXMgdGhlIHNhbWUgb3IgbW9yZSBwcm9wZXJ0eSB2YWx1ZXMsIHJlY3Vyc2luZyBpbnRvIHN1YiBwcm9wZXJ0aWVzIGlmIGBgYWxsb3dWYWx1ZUV4dGVuc2lvbmBgIGlzIHRydWUuXG4gKlxuICogQXQgYW55IHBvaW50IGluIHRoZSBvYmplY3QsIGEgdmFsdWUgbWF5IGJlIHJlcGxhY2VkIHdpdGggYSBmdW5jdGlvbiB3aGljaCB3aWxsIGJlIHVzZWQgdG8gY2hlY2sgdGhhdCBwYXJ0aWN1bGFyIGZpZWxkLlxuICogVGhlIHR5cGUgb2YgYSBtYXRjaGVyIGZ1bmN0aW9uIGlzIGV4cGVjdGVkIHRvIGJlIG9mIHR5cGUgUHJvcGVydHlNYXRjaGVyLlxuICpcbiAqIEBkZXByZWNhdGVkIC0gVXNlIGBvYmplY3RMaWtlYCBvciBhIGxpdGVyYWwgb2JqZWN0IGluc3RlYWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N1cGVyT2JqZWN0KHN1cGVyT2JqOiBhbnksIHBhdHRlcm46IGFueSwgZXJyb3JzOiBzdHJpbmdbXSA9IFtdLCBhbGxvd1ZhbHVlRXh0ZW5zaW9uOiBib29sZWFuID0gZmFsc2UpOiBib29sZWFuIHtcbiAgY29uc3QgbWF0Y2hlciA9IGFsbG93VmFsdWVFeHRlbnNpb24gPyBkZWVwT2JqZWN0TGlrZShwYXR0ZXJuKSA6IG9iamVjdExpa2UocGF0dGVybik7XG5cbiAgY29uc3QgaW5zcGVjdGlvbjogSW5zcGVjdGlvbkZhaWx1cmUgPSB7IHJlc291cmNlOiBzdXBlck9iaiwgZmFpbHVyZVJlYXNvbjogJycgfTtcbiAgY29uc3QgcmV0ID0gbWF0Y2goc3VwZXJPYmosIG1hdGNoZXIsIGluc3BlY3Rpb24pO1xuICBpZiAoIXJldCkge1xuICAgIGVycm9ycy5wdXNoKGluc3BlY3Rpb24uZmFpbHVyZVJlYXNvbik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbiJdfQ==
\No newline at end of file