UNPKG

@aws-cdk/aws-cloudwatch

Version:

The CDK Construct Library for AWS::CloudWatch

131 lines 14.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dispatchMetric = exports.metricPeriod = exports.metricKey = void 0; const core_1 = require("@aws-cdk/core"); const METRICKEY_SYMBOL = Symbol('@aws-cdk/aws-cloudwatch.MetricKey'); /** * Return a unique string representation for this metric. * * Can be used to determine as a hash key to determine if 2 Metric objects * represent the same metric. Excludes rendering properties. */ function metricKey(metric) { // Cache on the object itself. This is safe because Metric objects are immutable. if (metric.hasOwnProperty(METRICKEY_SYMBOL)) { return metric[METRICKEY_SYMBOL]; } const parts = new Array(); const conf = metric.toMetricConfig(); if (conf.mathExpression) { parts.push(conf.mathExpression.expression); for (const id of Object.keys(conf.mathExpression.usingMetrics).sort()) { parts.push(id); parts.push(metricKey(conf.mathExpression.usingMetrics[id])); } if (conf.mathExpression.searchRegion) { parts.push(conf.mathExpression.searchRegion); } if (conf.mathExpression.searchAccount) { parts.push(conf.mathExpression.searchAccount); } } if (conf.metricStat) { parts.push(conf.metricStat.namespace); parts.push(conf.metricStat.metricName); for (const dim of conf.metricStat.dimensions || []) { parts.push(dim.name); parts.push(dim.value); } if (conf.metricStat.statistic) { parts.push(conf.metricStat.statistic); } if (conf.metricStat.period) { parts.push(`${conf.metricStat.period.toSeconds()}`); } if (conf.metricStat.region) { parts.push(conf.metricStat.region); } if (conf.metricStat.account) { parts.push(conf.metricStat.account); } } const ret = parts.join('|'); Object.defineProperty(metric, METRICKEY_SYMBOL, { value: ret }); return ret; } exports.metricKey = metricKey; /** * Return the period of a metric * * For a stat metric, return the immediate period. * * For an expression metric, all metrics used in it have been made to have the * same period, so we return the period of the first inner metric. */ function metricPeriod(metric) { return dispatchMetric(metric, { withStat(stat) { return stat.period; }, withExpression() { return metric.period || core_1.Duration.minutes(5); }, }); } exports.metricPeriod = metricPeriod; /** * Given a metric object, inspect it and call the correct function for the type of output * * In addition to the metric object itself, takes a callback object with two * methods, to be invoked for the particular type of metric. * * If the metric represent a metric query (nominally generated through an * instantiation of `Metric` but can be generated by any class that implements * `IMetric`) a particular field in its `toMetricConfig()` output will be set * (to wit, `metricStat`) and the `withStat()` callback will be called with * that object. * * If the metric represents an expression (usually by instantiating `MathExpression` * but users can implement `IMetric` arbitrarily) the `mathExpression` field * will be set in the object returned from `toMetricConfig` and the callback * called `withExpression` will be applied to that object. * * Will return the values returned by the callbacks. * * To be used as such: * * ```ts * const ret = dispatchMetric(someMetric, { * withStat(stat) { * // do something with stat * return 1; * }, * withExpression(expr) { * // do something with expr * return 2; * }, * }); * ``` * * This function encapsulates some type analysis that would otherwise have to be * repeated in all places where code needs to make a distinction on the type * of metric object that is being passed. */ // eslint-disable-next-line max-len function dispatchMetric(metric, fns) { const conf = metric.toMetricConfig(); if (conf.metricStat && conf.mathExpression) { throw new Error('Metric object must not produce both \'metricStat\' and \'mathExpression\''); } else if (conf.metricStat) { return fns.withStat(conf.metricStat, conf); } else if (conf.mathExpression) { return fns.withExpression(conf.mathExpression, conf); } else { throw new Error('Metric object must have either \'metricStat\' or \'mathExpression\''); } } exports.dispatchMetric = dispatchMetric; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljLXV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtZXRyaWMtdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3Q0FBeUM7QUFJekMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsbUNBQW1DLENBQUMsQ0FBQztBQUVyRTs7Ozs7R0FLRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxNQUFlO0lBQ3ZDLGlGQUFpRjtJQUNqRixJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtRQUMzQyxPQUFRLE1BQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQzFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUVsQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDckMsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMzQyxLQUFLLE1BQU0sRUFBRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNyRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2YsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzdEO1FBQ0QsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRTtZQUNwQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDOUM7UUFDRCxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFO1lBQ3JDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUMvQztLQUNGO0lBQ0QsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ25CLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0QyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsSUFBSSxFQUFFLEVBQUU7WUFDbEQsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDdkI7UUFDRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFO1lBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUN2QztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFDMUIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUNyRDtRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFDMUIsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRTtZQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDckM7S0FDRjtJQUVELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNoRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUE5Q0QsOEJBOENDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQWdCLFlBQVksQ0FBQyxNQUFlO0lBQzFDLE9BQU8sY0FBYyxDQUFDLE1BQU0sRUFBRTtRQUM1QixRQUFRLENBQUMsSUFBSTtZQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUNwQjtRQUNELGNBQWM7WUFDWixPQUFRLE1BQXlCLENBQUMsTUFBTSxJQUFJLGVBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDakU7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBVEQsb0NBU0M7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDRztBQUNILG1DQUFtQztBQUNuQyxTQUFnQixjQUFjLENBQU8sTUFBZSxFQUFFLEdBQWlJO0lBQ3JMLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNyQyxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtRQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLDJFQUEyRSxDQUFDLENBQUM7S0FDOUY7U0FBTSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7UUFDMUIsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDNUM7U0FBTSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7UUFDOUIsT0FBTyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEQ7U0FBTTtRQUNMLE1BQU0sSUFBSSxLQUFLLENBQUMscUVBQXFFLENBQUMsQ0FBQztLQUN4RjtBQUNILENBQUM7QUFYRCx3Q0FXQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBNYXRoRXhwcmVzc2lvbiB9IGZyb20gJy4uL21ldHJpYyc7XG5pbXBvcnQgeyBJTWV0cmljLCBNZXRyaWNDb25maWcsIE1ldHJpY0V4cHJlc3Npb25Db25maWcsIE1ldHJpY1N0YXRDb25maWcgfSBmcm9tICcuLi9tZXRyaWMtdHlwZXMnO1xuXG5jb25zdCBNRVRSSUNLRVlfU1lNQk9MID0gU3ltYm9sKCdAYXdzLWNkay9hd3MtY2xvdWR3YXRjaC5NZXRyaWNLZXknKTtcblxuLyoqXG4gKiBSZXR1cm4gYSB1bmlxdWUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIG1ldHJpYy5cbiAqXG4gKiBDYW4gYmUgdXNlZCB0byBkZXRlcm1pbmUgYXMgYSBoYXNoIGtleSB0byBkZXRlcm1pbmUgaWYgMiBNZXRyaWMgb2JqZWN0c1xuICogcmVwcmVzZW50IHRoZSBzYW1lIG1ldHJpYy4gRXhjbHVkZXMgcmVuZGVyaW5nIHByb3BlcnRpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXRyaWNLZXkobWV0cmljOiBJTWV0cmljKTogc3RyaW5nIHtcbiAgLy8gQ2FjaGUgb24gdGhlIG9iamVjdCBpdHNlbGYuIFRoaXMgaXMgc2FmZSBiZWNhdXNlIE1ldHJpYyBvYmplY3RzIGFyZSBpbW11dGFibGUuXG4gIGlmIChtZXRyaWMuaGFzT3duUHJvcGVydHkoTUVUUklDS0VZX1NZTUJPTCkpIHtcbiAgICByZXR1cm4gKG1ldHJpYyBhcyBhbnkpW01FVFJJQ0tFWV9TWU1CT0xdO1xuICB9XG5cbiAgY29uc3QgcGFydHMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG4gIGNvbnN0IGNvbmYgPSBtZXRyaWMudG9NZXRyaWNDb25maWcoKTtcbiAgaWYgKGNvbmYubWF0aEV4cHJlc3Npb24pIHtcbiAgICBwYXJ0cy5wdXNoKGNvbmYubWF0aEV4cHJlc3Npb24uZXhwcmVzc2lvbik7XG4gICAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyhjb25mLm1hdGhFeHByZXNzaW9uLnVzaW5nTWV0cmljcykuc29ydCgpKSB7XG4gICAgICBwYXJ0cy5wdXNoKGlkKTtcbiAgICAgIHBhcnRzLnB1c2gobWV0cmljS2V5KGNvbmYubWF0aEV4cHJlc3Npb24udXNpbmdNZXRyaWNzW2lkXSkpO1xuICAgIH1cbiAgICBpZiAoY29uZi5tYXRoRXhwcmVzc2lvbi5zZWFyY2hSZWdpb24pIHtcbiAgICAgIHBhcnRzLnB1c2goY29uZi5tYXRoRXhwcmVzc2lvbi5zZWFyY2hSZWdpb24pO1xuICAgIH1cbiAgICBpZiAoY29uZi5tYXRoRXhwcmVzc2lvbi5zZWFyY2hBY2NvdW50KSB7XG4gICAgICBwYXJ0cy5wdXNoKGNvbmYubWF0aEV4cHJlc3Npb24uc2VhcmNoQWNjb3VudCk7XG4gICAgfVxuICB9XG4gIGlmIChjb25mLm1ldHJpY1N0YXQpIHtcbiAgICBwYXJ0cy5wdXNoKGNvbmYubWV0cmljU3RhdC5uYW1lc3BhY2UpO1xuICAgIHBhcnRzLnB1c2goY29uZi5tZXRyaWNTdGF0Lm1ldHJpY05hbWUpO1xuICAgIGZvciAoY29uc3QgZGltIG9mIGNvbmYubWV0cmljU3RhdC5kaW1lbnNpb25zIHx8IFtdKSB7XG4gICAgICBwYXJ0cy5wdXNoKGRpbS5uYW1lKTtcbiAgICAgIHBhcnRzLnB1c2goZGltLnZhbHVlKTtcbiAgICB9XG4gICAgaWYgKGNvbmYubWV0cmljU3RhdC5zdGF0aXN0aWMpIHtcbiAgICAgIHBhcnRzLnB1c2goY29uZi5tZXRyaWNTdGF0LnN0YXRpc3RpYyk7XG4gICAgfVxuICAgIGlmIChjb25mLm1ldHJpY1N0YXQucGVyaW9kKSB7XG4gICAgICBwYXJ0cy5wdXNoKGAke2NvbmYubWV0cmljU3RhdC5wZXJpb2QudG9TZWNvbmRzKCl9YCk7XG4gICAgfVxuICAgIGlmIChjb25mLm1ldHJpY1N0YXQucmVnaW9uKSB7XG4gICAgICBwYXJ0cy5wdXNoKGNvbmYubWV0cmljU3RhdC5yZWdpb24pO1xuICAgIH1cbiAgICBpZiAoY29uZi5tZXRyaWNTdGF0LmFjY291bnQpIHtcbiAgICAgIHBhcnRzLnB1c2goY29uZi5tZXRyaWNTdGF0LmFjY291bnQpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJldCA9IHBhcnRzLmpvaW4oJ3wnKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1ldHJpYywgTUVUUklDS0VZX1NZTUJPTCwgeyB2YWx1ZTogcmV0IH0pO1xuICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgcGVyaW9kIG9mIGEgbWV0cmljXG4gKlxuICogRm9yIGEgc3RhdCBtZXRyaWMsIHJldHVybiB0aGUgaW1tZWRpYXRlIHBlcmlvZC5cbiAqXG4gKiBGb3IgYW4gZXhwcmVzc2lvbiBtZXRyaWMsIGFsbCBtZXRyaWNzIHVzZWQgaW4gaXQgaGF2ZSBiZWVuIG1hZGUgdG8gaGF2ZSB0aGVcbiAqIHNhbWUgcGVyaW9kLCBzbyB3ZSByZXR1cm4gdGhlIHBlcmlvZCBvZiB0aGUgZmlyc3QgaW5uZXIgbWV0cmljLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWV0cmljUGVyaW9kKG1ldHJpYzogSU1ldHJpYyk6IER1cmF0aW9uIHtcbiAgcmV0dXJuIGRpc3BhdGNoTWV0cmljKG1ldHJpYywge1xuICAgIHdpdGhTdGF0KHN0YXQpIHtcbiAgICAgIHJldHVybiBzdGF0LnBlcmlvZDtcbiAgICB9LFxuICAgIHdpdGhFeHByZXNzaW9uKCkge1xuICAgICAgcmV0dXJuIChtZXRyaWMgYXMgTWF0aEV4cHJlc3Npb24pLnBlcmlvZCB8fCBEdXJhdGlvbi5taW51dGVzKDUpO1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgbWV0cmljIG9iamVjdCwgaW5zcGVjdCBpdCBhbmQgY2FsbCB0aGUgY29ycmVjdCBmdW5jdGlvbiBmb3IgdGhlIHR5cGUgb2Ygb3V0cHV0XG4gKlxuICogSW4gYWRkaXRpb24gdG8gdGhlIG1ldHJpYyBvYmplY3QgaXRzZWxmLCB0YWtlcyBhIGNhbGxiYWNrIG9iamVjdCB3aXRoIHR3b1xuICogbWV0aG9kcywgdG8gYmUgaW52b2tlZCBmb3IgdGhlIHBhcnRpY3VsYXIgdHlwZSBvZiBtZXRyaWMuXG4gKlxuICogSWYgdGhlIG1ldHJpYyByZXByZXNlbnQgYSBtZXRyaWMgcXVlcnkgKG5vbWluYWxseSBnZW5lcmF0ZWQgdGhyb3VnaCBhblxuICogaW5zdGFudGlhdGlvbiBvZiBgTWV0cmljYCBidXQgY2FuIGJlIGdlbmVyYXRlZCBieSBhbnkgY2xhc3MgdGhhdCBpbXBsZW1lbnRzXG4gKiBgSU1ldHJpY2ApIGEgcGFydGljdWxhciBmaWVsZCBpbiBpdHMgYHRvTWV0cmljQ29uZmlnKClgIG91dHB1dCB3aWxsIGJlIHNldFxuICogKHRvIHdpdCwgYG1ldHJpY1N0YXRgKSBhbmQgdGhlIGB3aXRoU3RhdCgpYCBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCB3aXRoXG4gKiB0aGF0IG9iamVjdC5cbiAqXG4gKiBJZiB0aGUgbWV0cmljIHJlcHJlc2VudHMgYW4gZXhwcmVzc2lvbiAodXN1YWxseSBieSBpbnN0YW50aWF0aW5nIGBNYXRoRXhwcmVzc2lvbmBcbiAqIGJ1dCB1c2VycyBjYW4gaW1wbGVtZW50IGBJTWV0cmljYCBhcmJpdHJhcmlseSkgdGhlIGBtYXRoRXhwcmVzc2lvbmAgZmllbGRcbiAqIHdpbGwgYmUgc2V0IGluIHRoZSBvYmplY3QgcmV0dXJuZWQgZnJvbSBgdG9NZXRyaWNDb25maWdgIGFuZCB0aGUgY2FsbGJhY2tcbiAqIGNhbGxlZCBgd2l0aEV4cHJlc3Npb25gIHdpbGwgYmUgYXBwbGllZCB0byB0aGF0IG9iamVjdC5cbiAqXG4gKiBXaWxsIHJldHVybiB0aGUgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsYmFja3MuXG4gKlxuICogVG8gYmUgdXNlZCBhcyBzdWNoOlxuICpcbiAqIGBgYHRzXG4gKiBjb25zdCByZXQgPSBkaXNwYXRjaE1ldHJpYyhzb21lTWV0cmljLCB7XG4gKiAgIHdpdGhTdGF0KHN0YXQpIHtcbiAqICAgICAvLyBkbyBzb21ldGhpbmcgd2l0aCBzdGF0XG4gKiAgICAgcmV0dXJuIDE7XG4gKiAgIH0sXG4gKiAgIHdpdGhFeHByZXNzaW9uKGV4cHIpIHtcbiAqICAgICAvLyBkbyBzb21ldGhpbmcgd2l0aCBleHByXG4gKiAgICAgcmV0dXJuIDI7XG4gKiAgIH0sXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gZW5jYXBzdWxhdGVzIHNvbWUgdHlwZSBhbmFseXNpcyB0aGF0IHdvdWxkIG90aGVyd2lzZSBoYXZlIHRvIGJlXG4gKiByZXBlYXRlZCBpbiBhbGwgcGxhY2VzIHdoZXJlIGNvZGUgbmVlZHMgdG8gbWFrZSBhIGRpc3RpbmN0aW9uIG9uIHRoZSB0eXBlXG4gKiBvZiBtZXRyaWMgb2JqZWN0IHRoYXQgaXMgYmVpbmcgcGFzc2VkLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuZXhwb3J0IGZ1bmN0aW9uIGRpc3BhdGNoTWV0cmljPEEsIEI+KG1ldHJpYzogSU1ldHJpYywgZm5zOiB7IHdpdGhTdGF0OiAoeDogTWV0cmljU3RhdENvbmZpZywgYzogTWV0cmljQ29uZmlnKSA9PiBBLCB3aXRoRXhwcmVzc2lvbjogKHg6IE1ldHJpY0V4cHJlc3Npb25Db25maWcsIGM6IE1ldHJpY0NvbmZpZykgPT4gQiB9KTogQSB8IEIge1xuICBjb25zdCBjb25mID0gbWV0cmljLnRvTWV0cmljQ29uZmlnKCk7XG4gIGlmIChjb25mLm1ldHJpY1N0YXQgJiYgY29uZi5tYXRoRXhwcmVzc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0cmljIG9iamVjdCBtdXN0IG5vdCBwcm9kdWNlIGJvdGggXFwnbWV0cmljU3RhdFxcJyBhbmQgXFwnbWF0aEV4cHJlc3Npb25cXCcnKTtcbiAgfSBlbHNlIGlmIChjb25mLm1ldHJpY1N0YXQpIHtcbiAgICByZXR1cm4gZm5zLndpdGhTdGF0KGNvbmYubWV0cmljU3RhdCwgY29uZik7XG4gIH0gZWxzZSBpZiAoY29uZi5tYXRoRXhwcmVzc2lvbikge1xuICAgIHJldHVybiBmbnMud2l0aEV4cHJlc3Npb24oY29uZi5tYXRoRXhwcmVzc2lvbiwgY29uZik7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRyaWMgb2JqZWN0IG11c3QgaGF2ZSBlaXRoZXIgXFwnbWV0cmljU3RhdFxcJyBvciBcXCdtYXRoRXhwcmVzc2lvblxcJycpO1xuICB9XG59Il19