@aws-cdk/aws-glue-alpha
Version:
The CDK Construct Library for AWS::Glue
340 lines • 45.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartitionProjectionConfiguration = exports.DateIntervalUnit = exports.PartitionProjectionType = void 0;
exports.generatePartitionProjectionParameters = generatePartitionProjectionParameters;
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
/**
* Partition projection type.
*
* Determines how Athena projects partition values.
*
* @see https://docs.aws.amazon.com/athena/latest/ug/partition-projection-supported-types.html
*/
var PartitionProjectionType;
(function (PartitionProjectionType) {
/**
* Project partition values as integers within a range.
*/
PartitionProjectionType["INTEGER"] = "integer";
/**
* Project partition values as dates within a range.
*/
PartitionProjectionType["DATE"] = "date";
/**
* Project partition values from an explicit list of values.
*/
PartitionProjectionType["ENUM"] = "enum";
/**
* Project partition values that are injected at query time.
*/
PartitionProjectionType["INJECTED"] = "injected";
})(PartitionProjectionType || (exports.PartitionProjectionType = PartitionProjectionType = {}));
/**
* Date interval unit for partition projection.
*
* @see https://docs.aws.amazon.com/athena/latest/ug/partition-projection-supported-types.html#partition-projection-date-type
*/
var DateIntervalUnit;
(function (DateIntervalUnit) {
/**
* Year interval.
*/
DateIntervalUnit["YEARS"] = "YEARS";
/**
* Month interval.
*/
DateIntervalUnit["MONTHS"] = "MONTHS";
/**
* Week interval.
*/
DateIntervalUnit["WEEKS"] = "WEEKS";
/**
* Day interval (default).
*/
DateIntervalUnit["DAYS"] = "DAYS";
/**
* Hour interval.
*/
DateIntervalUnit["HOURS"] = "HOURS";
/**
* Minute interval.
*/
DateIntervalUnit["MINUTES"] = "MINUTES";
/**
* Second interval.
*/
DateIntervalUnit["SECONDS"] = "SECONDS";
})(DateIntervalUnit || (exports.DateIntervalUnit = DateIntervalUnit = {}));
/**
* Factory class for creating partition projection configurations.
*/
class PartitionProjectionConfiguration {
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-glue-alpha.PartitionProjectionConfiguration", version: "2.257.0-alpha.0" };
/**
* Create an INTEGER partition projection configuration.
*/
static integer(props) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_IntegerPartitionProjectionConfigurationProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.integer);
}
throw error;
}
// Validate min/max are integers
if (!aws_cdk_lib_1.Token.isUnresolved(props.min) && !aws_cdk_lib_1.Token.isUnresolved(props.max)) {
if (!Number.isInteger(props.min) || !Number.isInteger(props.max)) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `IntegerRangeNotIntegers`, `INTEGER partition projection range must contain integers, but got [${props.min}, ${props.max}]`);
}
// Validate min <= max
if (props.min > props.max) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `IntegerRangeMinGreaterThanMax`, `INTEGER partition projection range must be [min, max] where min <= max, but got [${props.min}, ${props.max}]`);
}
}
// Validate interval
if (props.interval !== undefined &&
!aws_cdk_lib_1.Token.isUnresolved(props.interval) &&
(!Number.isInteger(props.interval) || props.interval <= 0)) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `IntegerIntervalInvalid`, `INTEGER partition projection interval must be a positive integer, but got ${props.interval}`);
}
// Validate digits
if (props.digits !== undefined &&
!aws_cdk_lib_1.Token.isUnresolved(props.digits) &&
(!Number.isInteger(props.digits) || props.digits < 1)) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `IntegerDigitsInvalid`, `INTEGER partition projection digits must be an integer >= 1, but got ${props.digits}`);
}
return new PartitionProjectionConfiguration({
type: PartitionProjectionType.INTEGER,
integerRange: [props.min, props.max],
interval: props.interval,
digits: props.digits,
});
}
/**
* Create a DATE partition projection configuration.
*/
static date(props) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_DatePartitionProjectionConfigurationProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.date);
}
throw error;
}
// Validate min/max are not empty
if (!aws_cdk_lib_1.Token.isUnresolved(props.min) &&
!aws_cdk_lib_1.Token.isUnresolved(props.max) &&
(props.min.trim() === '' || props.max.trim() === '')) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DateRangeEmpty`, 'DATE partition projection range must not contain empty strings');
}
// Validate format
if (!aws_cdk_lib_1.Token.isUnresolved(props.format)) {
// Validate format is not empty
if (props.format.trim() === '') {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DateFormatEmpty`, 'DATE partition projection format must be a non-empty string');
}
// Validate format pattern characters (Java 8 DateTimeFormatter)
const validPatternLetters = 'GyuYDMLdQqwWEecFahKkHmsSAnNVzOXxZp';
const format = props.format;
let inQuote = false;
const invalidChars = [];
for (let i = 0; i < format.length; i++) {
const ch = format[i];
if (ch === "'") {
if (i + 1 < format.length && format[i + 1] === "'") {
// '' is an escaped single quote literal, skip both
i++;
}
else {
inQuote = !inQuote;
}
}
else if (!inQuote && /[a-zA-Z]/.test(ch)) {
if (!validPatternLetters.includes(ch)) {
invalidChars.push(ch);
}
}
}
if (inQuote) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DateFormatUnclosedQuote`, `DATE partition projection format has an unclosed single quote: '${format}'`);
}
if (invalidChars.length > 0) {
const unique = [...new Set(invalidChars)];
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DateFormatInvalidCharacters`, `DATE partition projection format contains invalid pattern characters: ${unique.join(', ')}. Must use Java DateTimeFormatter valid pattern letters.`);
}
}
// Validate interval
if (props.interval !== undefined &&
!aws_cdk_lib_1.Token.isUnresolved(props.interval) &&
(!Number.isInteger(props.interval) || props.interval <= 0)) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DateIntervalInvalid`, `DATE partition projection interval must be a positive integer, but got ${props.interval}`);
}
return new PartitionProjectionConfiguration({
type: PartitionProjectionType.DATE,
dateRange: [props.min, props.max],
interval: props.interval,
format: props.format,
intervalUnit: props.intervalUnit,
});
}
/**
* Create an ENUM partition projection configuration.
*/
static enum(props) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_EnumPartitionProjectionConfigurationProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.enum);
}
throw error;
}
// Validate values is not empty
if (props.values.length === 0) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `EnumValuesEmpty`, 'ENUM partition projection values must be a non-empty array');
}
for (let i = 0; i < props.values.length; i++) {
const value = props.values[i];
if (!aws_cdk_lib_1.Token.isUnresolved(value)) {
if (value.trim() === '') {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `EnumValueEmpty`, 'ENUM partition projection values must not contain empty strings');
}
if (value.includes(',')) {
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `EnumValueContainsComma`, `ENUM partition projection values must not contain commas because the values are serialized as a comma-separated list, got: '${value}'`);
}
}
}
return new PartitionProjectionConfiguration({
type: PartitionProjectionType.ENUM,
values: props.values,
});
}
/**
* Create an INJECTED partition projection configuration.
*
* Partition values are injected at query time through the query statement.
*
* @see https://docs.aws.amazon.com/athena/latest/ug/partition-projection-supported-types.html#partition-projection-injected-type
*/
static injected() {
return new PartitionProjectionConfiguration({
type: PartitionProjectionType.INJECTED,
});
}
/**
* The type of partition projection.
*/
type;
/**
* Range of partition values for INTEGER type.
*
* Array of [min, max] as numbers.
*/
integerRange;
/**
* Range of partition values for DATE type.
*
* Array of [start, end] as date strings.
*/
dateRange;
/**
* Interval between partition values.
*/
interval;
/**
* Number of digits to pad INTEGER partition values.
*/
digits;
/**
* Date format for DATE partition values (Java SimpleDateFormat).
*/
format;
/**
* Unit for DATE partition interval.
*/
intervalUnit;
/**
* Explicit list of values for ENUM partitions.
*/
values;
constructor(props) {
this.type = props.type;
this.integerRange = props.integerRange;
this.dateRange = props.dateRange;
this.interval = props.interval;
this.digits = props.digits;
this.format = props.format;
this.intervalUnit = props.intervalUnit;
this.values = props.values;
}
/**
* Renders CloudFormation parameters for this partition projection configuration.
*
* @param columnName - The partition column name
* @internal
*/
_renderParameters(columnName) {
const params = {
[`projection.${columnName}.type`]: this.type,
};
switch (this.type) {
case PartitionProjectionType.INTEGER: {
const [min, max] = this.integerRange;
params[`projection.${columnName}.range`] = `${min},${max}`;
if (this.interval !== undefined) {
params[`projection.${columnName}.interval`] = this.interval.toString();
}
if (this.digits !== undefined) {
params[`projection.${columnName}.digits`] = this.digits.toString();
}
break;
}
case PartitionProjectionType.DATE: {
const [start, end] = this.dateRange;
params[`projection.${columnName}.range`] = `${start},${end}`;
params[`projection.${columnName}.format`] = this.format;
if (this.interval !== undefined) {
params[`projection.${columnName}.interval`] = this.interval.toString();
}
if (this.intervalUnit !== undefined) {
params[`projection.${columnName}.interval.unit`] = this.intervalUnit;
}
break;
}
case PartitionProjectionType.ENUM: {
params[`projection.${columnName}.values`] = this.values.join(',');
break;
}
case PartitionProjectionType.INJECTED: {
// INJECTED has no additional parameters
break;
}
default: {
// TypeScript exhaustiveness check
const exhaustiveCheck = this.type;
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnknownProjectionType`, `Unknown partition projection type for "${columnName}": ${exhaustiveCheck}`);
}
}
return params;
}
}
exports.PartitionProjectionConfiguration = PartitionProjectionConfiguration;
/**
* Generates CloudFormation parameters for partition projection configuration.
*
* @param columnName - The partition column name
* @param config - The partition configuration
* @returns CloudFormation parameters
*/
function generatePartitionProjectionParameters(columnName, config) {
return config._renderParameters(columnName);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydGl0aW9uLXByb2plY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwYXJ0aXRpb24tcHJvamVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFtaUJBLHNGQUtDOzs7QUF4aUJELDZDQUE2RDtBQUM3RCw0RUFBNEQ7QUFFNUQ7Ozs7OztHQU1HO0FBQ0gsSUFBWSx1QkFvQlg7QUFwQkQsV0FBWSx1QkFBdUI7SUFDakM7O09BRUc7SUFDSCw4Q0FBbUIsQ0FBQTtJQUVuQjs7T0FFRztJQUNILHdDQUFhLENBQUE7SUFFYjs7T0FFRztJQUNILHdDQUFhLENBQUE7SUFFYjs7T0FFRztJQUNILGdEQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFwQlcsdUJBQXVCLHVDQUF2Qix1QkFBdUIsUUFvQmxDO0FBRUQ7Ozs7R0FJRztBQUNILElBQVksZ0JBbUNYO0FBbkNELFdBQVksZ0JBQWdCO0lBQzFCOztPQUVHO0lBQ0gsbUNBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gscUNBQWlCLENBQUE7SUFFakI7O09BRUc7SUFDSCxtQ0FBZSxDQUFBO0lBRWY7O09BRUc7SUFDSCxpQ0FBYSxDQUFBO0lBRWI7O09BRUc7SUFDSCxtQ0FBZSxDQUFBO0lBRWY7O09BRUc7SUFDSCx1Q0FBbUIsQ0FBQTtJQUVuQjs7T0FFRztJQUNILHVDQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFuQ1csZ0JBQWdCLGdDQUFoQixnQkFBZ0IsUUFtQzNCO0FBMEpEOztHQUVHO0FBQ0gsTUFBYSxnQ0FBZ0M7O0lBQzNDOztPQUVHO0lBQ0ksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFtRDs7Ozs7Ozs7OztRQUN2RSxnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JFLElBQUksQ0FBQyxNQUFNLENB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LENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuRSxNQUFNO1lBQ1IsQ0FBQztZQUNELEtBQUssdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDdEMsd0NBQXdDO2dCQUN4QyxNQUFNO1lBQ1IsQ0FBQztZQUNELE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ1Isa0NBQWtDO2dCQUNsQyxNQUFNLGVBQWUsR0FBVSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUN6QyxNQUFNLElBQUkscUNBQXVCLENBQy9CLElBQUEsc0JBQUcsRUFBQSx1QkFBdUIsRUFDMUIsMENBQTBDLFVBQVUsTUFBTSxlQUFlLEVBQUUsQ0FDNUUsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7S0FDZjs7QUExU0gsNEVBMlNDO0FBWUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IscUNBQXFDLENBQ25ELFVBQWtCLEVBQ2xCLE1BQXdDO0lBRXhDLE9BQU8sTUFBTSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUb2tlbiwgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBsaXQgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9oZWxwZXJzLWludGVybmFsJztcblxuLyoqXG4gKiBQYXJ0aXRpb24gcHJvamVjdGlvbiB0eXBlLlxuICpcbiAqIERldGVybWluZXMgaG93IEF0aGVuYSBwcm9qZWN0cyBwYXJ0aXRpb24gdmFsdWVzLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F0aGVuYS9sYXRlc3QvdWcvcGFydGl0aW9uLXByb2plY3Rpb24tc3VwcG9ydGVkLXR5cGVzLmh0bWxcbiAqL1xuZXhwb3J0IGVudW0gUGFydGl0aW9uUHJvamVjdGlvblR5cGUge1xuICAvKipcbiAgICogUHJvamVjdCBwYXJ0aXRpb24gdmFsdWVzIGFzIGludGVnZXJzIHdpdGhpbiBhIHJhbmdlLlxuICAgKi9cbiAgSU5URUdFUiA9ICdpbnRlZ2VyJyxcblxuICAvKipcbiAgICogUHJvamVjdCBwYXJ0aXRpb24gdmFsdWVzIGFzIGRhdGVzIHdpdGhpbiBhIHJhbmdlLlxuICAgKi9cbiAgREFURSA9ICdkYXRlJyxcblxuICAvKipcbiAgICogUHJvamVjdCBwYXJ0aXRpb24gdmFsdWVzIGZyb20gYW4gZXhwbGljaXQgbGlzdCBvZiB2YWx1ZXMuXG4gICAqL1xuICBFTlVNID0gJ2VudW0nLFxuXG4gIC8qKlxuICAgKiBQcm9qZWN0IHBhcnRpdGlvbiB2YWx1ZXMgdGhhdCBhcmUgaW5qZWN0ZWQgYXQgcXVlcnkgdGltZS5cbiAgICovXG4gIElOSkVDVEVEID0gJ2luamVjdGVkJyxcbn1cblxuLyoqXG4gKiBEYXRlIGludGVydmFsIHVuaXQgZm9yIHBhcnRpdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F0aGVuYS9sYXRlc3QvdWcvcGFydGl0aW9uLXByb2plY3Rpb24tc3VwcG9ydGVkLXR5cGVzLmh0bWwjcGFydGl0aW9uLXByb2plY3Rpb24tZGF0ZS10eXBlXG4gKi9cbmV4cG9ydCBlbnVtIERhdGVJbnRlcnZhbFVuaXQge1xuICAvKipcbiAgICogWWVhciBpbnRlcnZhbC5cbiAgICovXG4gIFlFQVJTID0gJ1lFQVJTJyxcblxuICAvKipcbiAgICogTW9udGggaW50ZXJ2YWwuXG4gICAqL1xuICBNT05USFMgPSAnTU9OVEhTJyxcblxuICAvKipcbiAgICogV2VlayBpbnRlcnZhbC5cbiAgICovXG4gIFdFRUtTID0gJ1dFRUtTJyxcblxuICAvKipcbiAgICogRGF5IGludGVydmFsIChkZWZhdWx0KS5cbiAgICovXG4gIERBWVMgPSAnREFZUycsXG5cbiAgLyoqXG4gICAqIEhvdXIgaW50ZXJ2YWwuXG4gICAqL1xuICBIT1VSUyA9ICdIT1VSUycsXG5cbiAgLyoqXG4gICAqIE1pbnV0ZSBpbnRlcnZhbC5cbiAgICovXG4gIE1JTlVURVMgPSAnTUlOVVRFUycsXG5cbiAgLyoqXG4gICAqIFNlY29uZCBpbnRlcnZhbC5cbiAgICovXG4gIFNFQ09ORFMgPSAnU0VDT05EUycsXG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgSU5URUdFUiBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEludGVnZXJQYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIE1pbmltdW0gdmFsdWUgZm9yIHRoZSBpbnRlZ2VyIHBhcnRpdGlvbiByYW5nZSAoaW5jbHVzaXZlKS5cbiAgICovXG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIHZhbHVlIGZvciB0aGUgaW50ZWdlciBwYXJ0aXRpb24gcmFuZ2UgKGluY2x1c2l2ZSkuXG4gICAqL1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcblxuICAvKipcbiAgICogSW50ZXJ2YWwgYmV0d2VlbiBwYXJ0aXRpb24gdmFsdWVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBpbnRlcnZhbD86IG51bWJlcjtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIGRpZ2l0cyB0byBwYWQgdGhlIHBhcnRpdGlvbiB2YWx1ZSB3aXRoIGxlYWRpbmcgemVyb3MuXG4gICAqXG4gICAqIFdpdGggZGlnaXRzOiA0LCBwYXJ0aXRpb24gdmFsdWVzOiAwMDAxLCAwMDAyLCAuLi4sIDAxMDBcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBzdGF0aWMgbnVtYmVyIG9mIGRpZ2l0cyBhbmQgbm8gbGVhZGluZyB6ZXJvZXNcbiAgICovXG4gIHJlYWRvbmx5IGRpZ2l0cz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBEQVRFIHBhcnRpdGlvbiBwcm9qZWN0aW9uIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0ZVBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uUHJvcHMge1xuICAvKipcbiAgICogU3RhcnQgZGF0ZSBmb3IgdGhlIHBhcnRpdGlvbiByYW5nZSAoaW5jbHVzaXZlKS5cbiAgICpcbiAgICogQ2FuIGJlIGVpdGhlcjpcbiAgICogLSBGaXhlZCBkYXRlIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkIGJ5IGBmb3JtYXRgIHByb3BlcnR5XG4gICAqICAgKGUuZy4sICcyMDIwLTAxLTAxJyBmb3IgZm9ybWF0ICd5eXl5LU1NLWRkJylcbiAgICogLSBSZWxhdGl2ZSBkYXRlIHVzaW5nIE5PVyBzeW50YXhcbiAgICogICAoZS5nLiwgJ05PVycsICdOT1ctM1lFQVJTJywgJ05PVysxTU9OVEgnKVxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdGhlbmEvbGF0ZXN0L3VnL3BhcnRpdGlvbi1wcm9qZWN0aW9uLXN1cHBvcnRlZC10eXBlcy5odG1sI3BhcnRpdGlvbi1wcm9qZWN0aW9uLWRhdGUtdHlwZVxuICAgKi9cbiAgcmVhZG9ubHkgbWluOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEVuZCBkYXRlIGZvciB0aGUgcGFydGl0aW9uIHJhbmdlIChpbmNsdXNpdmUpLlxuICAgKlxuICAgKiBDYW4gYmUgZWl0aGVyOlxuICAgKiAtIEZpeGVkIGRhdGUgaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWQgYnkgYGZvcm1hdGAgcHJvcGVydHlcbiAgICogLSBSZWxhdGl2ZSBkYXRlIHVzaW5nIE5PVyBzeW50YXhcbiAgICpcbiAgICogU2FtZSBmb3JtYXQgY29uc3RyYWludHMgYXMgYG1pbmAuXG4gICAqL1xuICByZWFkb25seSBtYXg6IHN0cmluZztcblxuICAvKipcbiAgICogRGF0ZSBmb3JtYXQgZm9yIHBhcnRpdGlvbiB2YWx1ZXMuXG4gICAqXG4gICAqIFVzZXMgSmF2YSBTaW1wbGVEYXRlRm9ybWF0IHBhdHRlcm5zLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5vcmFjbGUuY29tL2phdmFzZS84L2RvY3MvYXBpL2phdmEvdGV4dC9TaW1wbGVEYXRlRm9ybWF0Lmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IGZvcm1hdDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbnRlcnZhbCBiZXR3ZWVuIHBhcnRpdGlvbiB2YWx1ZXMuXG4gICAqXG4gICAqIFdoZW4gdGhlIHByb3ZpZGVkIGRhdGVzIGFyZSBhdCBzaW5nbGUtZGF5IG9yIHNpbmdsZS1tb250aCBwcmVjaXNpb24sXG4gICAqIHRoZSBpbnRlcnZhbCBpcyBvcHRpb25hbCBhbmQgZGVmYXVsdHMgdG8gMSBkYXkgb3IgMSBtb250aCwgcmVzcGVjdGl2ZWx5LlxuICAgKiBPdGhlcndpc2UsIGludGVydmFsIGlzIHJlcXVpcmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIDEgZm9yIHNpbmdsZS1kYXkgb3Igc2luZ2xlLW1vbnRoIHByZWNpc2lvbiwgb3RoZXJ3aXNlIHJlcXVpcmVkXG4gICAqL1xuICByZWFkb25seSBpbnRlcnZhbD86IG51bWJlcjtcblxuICAvKipcbiAgICogVW5pdCBmb3IgdGhlIGludGVydmFsLlxuICAgKlxuICAgKiBXaGVuIHRoZSBwcm92aWRlZCBkYXRlcyBhcmUgYXQgc2luZ2xlLWRheSBvciBzaW5nbGUtbW9udGggcHJlY2lzaW9uLFxuICAgKiB0aGUgaW50ZXJ2YWxVbml0IGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byAxIGRheSBvciAxIG1vbnRoLCByZXNwZWN0aXZlbHkuXG4gICAqIE90aGVyd2lzZSwgdGhlIGludGVydmFsVW5pdCBpcyByZXF1aXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBEQVlTIGZvciBzaW5nbGUtZGF5IHByZWNpc2lvbiwgTU9OVEhTIGZvciBzaW5nbGUtbW9udGggcHJlY2lzaW9uLCBvdGhlcndpc2UgcmVxdWlyZWRcbiAgICovXG4gIHJlYWRvbmx5IGludGVydmFsVW5pdD86IERhdGVJbnRlcnZhbFVuaXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgRU5VTSBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVudW1QYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIEV4cGxpY2l0IGxpc3Qgb2YgcGFydGl0aW9uIHZhbHVlcy5cbiAgICpcbiAgICogQGV4YW1wbGUgWyd1cy1lYXN0LTEnLCAndXMtd2VzdC0yJywgJ2V1LXdlc3QtMSddXG4gICAqL1xuICByZWFkb25seSB2YWx1ZXM6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIEludGVybmFsIHByb3BlcnRpZXMgZm9yIFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uLlxuICovXG5pbnRlcmZhY2UgUGFydGl0aW9uUHJvamVjdGlvbkNvbmZpZ3VyYXRpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBwYXJ0aXRpb24gcHJvamVjdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IFBhcnRpdGlvblByb2plY3Rpb25UeXBlO1xuXG4gIC8qKlxuICAgKiBSYW5nZSBvZiBwYXJ0aXRpb24gdmFsdWVzIGZvciBJTlRFR0VSIHR5cGUuXG4gICAqXG4gICAqIEFycmF5IG9mIFttaW4sIG1heF0gYXMgbnVtYmVycy5cbiAgICovXG4gIHJlYWRvbmx5IGludGVnZXJSYW5nZT86IG51bWJlcltdO1xuXG4gIC8qKlxuICAgKiBSYW5nZSBvZiBwYXJ0aXRpb24gdmFsdWVzIGZvciBEQVRFIHR5cGUuXG4gICAqXG4gICAqIEFycmF5IG9mIFtzdGFydCwgZW5kXSBhcyBkYXRlIHN0cmluZ3MuXG4gICAqL1xuICByZWFkb25seSBkYXRlUmFuZ2U/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogSW50ZXJ2YWwgYmV0d2VlbiBwYXJ0aXRpb24gdmFsdWVzLlxuICAgKi9cbiAgcmVhZG9ubHkgaW50ZXJ2YWw/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBkaWdpdHMgdG8gcGFkIElOVEVHRVIgcGFydGl0aW9uIHZhbHVlcy5cbiAgICovXG4gIHJlYWRvbmx5IGRpZ2l0cz86IG51bWJlcjtcblxuICAvKipcbiAgICogRGF0ZSBmb3JtYXQgZm9yIERBVEUgcGFydGl0aW9uIHZhbHVlcyAoSmF2YSBTaW1wbGVEYXRlRm9ybWF0KS5cbiAgICovXG4gIHJlYWRvbmx5IGZvcm1hdD86IHN0cmluZztcblxuICAvKipcbiAgICogVW5pdCBmb3IgREFURSBwYXJ0aXRpb24gaW50ZXJ2YWwuXG4gICAqL1xuICByZWFkb25seSBpbnRlcnZhbFVuaXQ/OiBEYXRlSW50ZXJ2YWxVbml0O1xuXG4gIC8qKlxuICAgKiBFeHBsaWNpdCBsaXN0IG9mIHZhbHVlcyBmb3IgRU5VTSBwYXJ0aXRpb25zLlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWVzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogRmFjdG9yeSBjbGFzcyBmb3IgY3JlYXRpbmcgcGFydGl0aW9uIHByb2plY3Rpb24gY29uZmlndXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gSU5URUdFUiBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpbnRlZ2VyKHByb3BzOiBJbnRlZ2VyUGFydGl0aW9uUHJvamVjdGlvbkNvbmZpZ3VyYXRpb25Qcm9wcyk6IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uIHtcbiAgICAvLyBWYWxpZGF0ZSBtaW4vbWF4IGFyZSBpbnRlZ2Vyc1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKHByb3BzLm1pbikgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5tYXgpKSB7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIocHJvcHMubWluKSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwcm9wcy5tYXgpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgSW50ZWdlclJhbmdlTm90SW50ZWdlcnNgLFxuICAgICAgICAgIGBJTlRFR0VSIHBhcnRpdGlvbiBwcm9qZWN0aW9uIHJhbmdlIG11c3QgY29udGFpbiBpbnRlZ2VycywgYnV0IGdvdCBbJHtwcm9wcy5taW59LCAke3Byb3BzLm1heH1dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgbWluIDw9IG1heFxuICAgICAgaWYgKHByb3BzLm1pbiA+IHByb3BzLm1heCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YEludGVnZXJSYW5nZU1pbkdyZWF0ZXJUaGFuTWF4YCxcbiAgICAgICAgICBgSU5URUdFUiBwYXJ0aXRpb24gcHJvamVjdGlvbiByYW5nZSBtdXN0IGJlIFttaW4sIG1heF0gd2hlcmUgbWluIDw9IG1heCwgYnV0IGdvdCBbJHtwcm9wcy5taW59LCAke3Byb3BzLm1heH1dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBpbnRlcnZhbFxuICAgIGlmIChcbiAgICAgIHByb3BzLmludGVydmFsICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICFUb2tlbi5pc1VucmVzb2x2ZWQocHJvcHMuaW50ZXJ2YWwpICYmXG4gICAgICAoIU51bWJlci5pc0ludGVnZXIocHJvcHMuaW50ZXJ2YWwpIHx8IHByb3BzLmludGVydmFsIDw9IDApXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBJbnRlZ2VySW50ZXJ2YWxJbnZhbGlkYCxcbiAgICAgICAgYElOVEVHRVIgcGFydGl0aW9uIHByb2plY3Rpb24gaW50ZXJ2YWwgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIsIGJ1dCBnb3QgJHtwcm9wcy5pbnRlcnZhbH1gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBkaWdpdHNcbiAgICBpZiAoXG4gICAgICBwcm9wcy5kaWdpdHMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5kaWdpdHMpICYmXG4gICAgICAoIU51bWJlci5pc0ludGVnZXIocHJvcHMuZGlnaXRzKSB8fCBwcm9wcy5kaWdpdHMgPCAxKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgSW50ZWdlckRpZ2l0c0ludmFsaWRgLFxuICAgICAgICBgSU5URUdFUiBwYXJ0aXRpb24gcHJvamVjdGlvbiBkaWdpdHMgbXVzdCBiZSBhbiBpbnRlZ2VyID49IDEsIGJ1dCBnb3QgJHtwcm9wcy5kaWdpdHN9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvbih7XG4gICAgICB0eXBlOiBQYXJ0aXRpb25Qcm9qZWN0aW9uVHlwZS5JTlRFR0VSLFxuICAgICAgaW50ZWdlclJhbmdlOiBbcHJvcHMubWluLCBwcm9wcy5tYXhdLFxuICAgICAgaW50ZXJ2YWw6IHByb3BzLmludGVydmFsLFxuICAgICAgZGlnaXRzOiBwcm9wcy5kaWdpdHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgREFURSBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkYXRlKHByb3BzOiBEYXRlUGFydGl0aW9uUHJvamVjdGlvbkNvbmZpZ3VyYXRpb25Qcm9wcyk6IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uIHtcbiAgICAvLyBWYWxpZGF0ZSBtaW4vbWF4IGFyZSBub3QgZW1wdHlcbiAgICBpZiAoXG4gICAgICAhVG9rZW4uaXNVbnJlc29sdmVkKHByb3BzLm1pbikgJiZcbiAgICAgICFUb2tlbi5pc1VucmVzb2x2ZWQocHJvcHMubWF4KSAmJlxuICAgICAgKHByb3BzLm1pbi50cmltKCkgPT09ICcnIHx8IHByb3BzLm1heC50cmltKCkgPT09ICcnKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgRGF0ZVJhbmdlRW1wdHlgLFxuICAgICAgICAnREFURSBwYXJ0aXRpb24gcHJvamVjdGlvbiByYW5nZSBtdXN0IG5vdCBjb250YWluIGVtcHR5IHN0cmluZ3MnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBmb3JtYXRcbiAgICBpZiAoIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5mb3JtYXQpKSB7XG4gICAgICAvLyBWYWxpZGF0ZSBmb3JtYXQgaXMgbm90IGVtcHR5XG4gICAgICBpZiAocHJvcHMuZm9ybWF0LnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBEYXRlRm9ybWF0RW1wdHlgLFxuICAgICAgICAgICdEQVRFIHBhcnRpdGlvbiBwcm9qZWN0aW9uIGZvcm1hdCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGZvcm1hdCBwYXR0ZXJuIGNoYXJhY3RlcnMgKEphdmEgOCBEYXRlVGltZUZvcm1hdHRlcilcbiAgICAgIGNvbnN0IHZhbGlkUGF0dGVybkxldHRlcnMgPSAnR3l1WURNTGRRcXdXRWVjRmFoS2tIbXNTQW5OVnpPWHhacCc7XG4gICAgICBjb25zdCBmb3JtYXQgPSBwcm9wcy5mb3JtYXQ7XG4gICAgICBsZXQgaW5RdW90ZSA9IGZhbHNlO1xuICAgICAgY29uc3QgaW52YWxpZENoYXJzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZvcm1hdC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaCA9IGZvcm1hdFtpXTtcbiAgICAgICAgaWYgKGNoID09PSBcIidcIikge1xuICAgICAgICAgIGlmIChpICsgMSA8IGZvcm1hdC5sZW5ndGggJiYgZm9ybWF0W2kgKyAxXSA9PT0gXCInXCIpIHtcbiAgICAgICAgICAgIC8vICcnIGlzIGFuIGVzY2FwZWQgc2luZ2xlIHF1b3RlIGxpdGVyYWwsIHNraXAgYm90aFxuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpblF1b3RlID0gIWluUXVvdGU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFpblF1b3RlICYmIC9bYS16QS1aXS8udGVzdChjaCkpIHtcbiAgICAgICAgICBpZiAoIXZhbGlkUGF0dGVybkxldHRlcnMuaW5jbHVkZXMoY2gpKSB7XG4gICAgICAgICAgICBpbnZhbGlkQ2hhcnMucHVzaChjaCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpblF1b3RlKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgRGF0ZUZvcm1hdFVuY2xvc2VkUXVvdGVgLFxuICAgICAgICAgIGBEQVRFIHBhcnRpdGlvbiBwcm9qZWN0aW9uIGZvcm1hdCBoYXMgYW4gdW5jbG9zZWQgc2luZ2xlIHF1b3RlOiAnJHtmb3JtYXR9J2AsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnZhbGlkQ2hhcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCB1bmlxdWUgPSBbLi4ubmV3IFNldChpbnZhbGlkQ2hhcnMpXTtcbiAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBEYXRlRm9ybWF0SW52YWxpZENoYXJhY3RlcnNgLFxuICAgICAgICAgIGBEQVRFIHBhcnRpdGlvbiBwcm9qZWN0aW9uIGZvcm1hdCBjb250YWlucyBpbnZhbGlkIHBhdHRlcm4gY2hhcmFjdGVyczogJHt1bmlxdWUuam9pbignLCAnKX0uIE11c3QgdXNlIEphdmEgRGF0ZVRpbWVGb3JtYXR0ZXIgdmFsaWQgcGF0dGVybiBsZXR0ZXJzLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgaW50ZXJ2YWxcbiAgICBpZiAoXG4gICAgICBwcm9wcy5pbnRlcnZhbCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhVG9rZW4uaXNVbnJlc29sdmVkKHByb3BzLmludGVydmFsKSAmJlxuICAgICAgKCFOdW1iZXIuaXNJbnRlZ2VyKHByb3BzLmludGVydmFsKSB8fCBwcm9wcy5pbnRlcnZhbCA8PSAwKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgRGF0ZUludGVydmFsSW52YWxpZGAsXG4gICAgICAgIGBEQVRFIHBhcnRpdGlvbiBwcm9qZWN0aW9uIGludGVydmFsIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBidXQgZ290ICR7cHJvcHMuaW50ZXJ2YWx9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvbih7XG4gICAgICB0eXBlOiBQYXJ0aXRpb25Qcm9qZWN0aW9uVHlwZS5EQVRFLFxuICAgICAgZGF0ZVJhbmdlOiBbcHJvcHMubWluLCBwcm9wcy5tYXhdLFxuICAgICAgaW50ZXJ2YWw6IHByb3BzLmludGVydmFsLFxuICAgICAgZm9ybWF0OiBwcm9wcy5mb3JtYXQsXG4gICAgICBpbnRlcnZhbFVuaXQ6IHByb3BzLmludGVydmFsVW5pdCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gRU5VTSBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBlbnVtKHByb3BzOiBFbnVtUGFydGl0aW9uUHJvamVjdGlvbkNvbmZpZ3VyYXRpb25Qcm9wcyk6IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uIHtcbiAgICAvLyBWYWxpZGF0ZSB2YWx1ZXMgaXMgbm90IGVtcHR5XG4gICAgaWYgKHByb3BzLnZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YEVudW1WYWx1ZXNFbXB0eWAsXG4gICAgICAgICdFTlVNIHBhcnRpdGlvbiBwcm9qZWN0aW9uIHZhbHVlcyBtdXN0IGJlIGEgbm9uLWVtcHR5IGFycmF5JyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wcy52YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcHJvcHMudmFsdWVzW2ldO1xuICAgICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQodmFsdWUpKSB7XG4gICAgICAgIGlmICh2YWx1ZS50cmltKCkgPT09ICcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgICAgbGl0YEVudW1WYWx1ZUVtcHR5YCxcbiAgICAgICAgICAgICdFTlVNIHBhcnRpdGlvbiBwcm9qZWN0aW9uIHZhbHVlcyBtdXN0IG5vdCBjb250YWluIGVtcHR5IHN0cmluZ3MnLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlLmluY2x1ZGVzKCcsJykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgICBsaXRgRW51bVZhbHVlQ29udGFpbnNDb21tYWAsXG4gICAgICAgICAgICBgRU5VTSBwYXJ0aXRpb24gcHJvamVjdGlvbiB2YWx1ZXMgbXVzdCBub3QgY29udGFpbiBjb21tYXMgYmVjYXVzZSB0aGUgdmFsdWVzIGFyZSBzZXJpYWxpemVkIGFzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3QsIGdvdDogJyR7dmFsdWV9J2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGFydGl0aW9uUHJvamVjdGlvbkNvbmZpZ3VyYXRpb24oe1xuICAgICAgdHlwZTogUGFydGl0aW9uUHJvamVjdGlvblR5cGUuRU5VTSxcbiAgICAgIHZhbHVlczogcHJvcHMudmFsdWVzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBJTkpFQ1RFRCBwYXJ0aXRpb24gcHJvamVjdGlvbiBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBQYXJ0aXRpb24gdmFsdWVzIGFyZSBpbmplY3RlZCBhdCBxdWVyeSB0aW1lIHRocm91Z2ggdGhlIHF1ZXJ5IHN0YXRlbWVudC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXRoZW5hL2xhdGVzdC91Zy9wYXJ0aXRpb24tcHJvamVjdGlvbi1zdXBwb3J0ZWQtdHlwZXMuaHRtbCNwYXJ0aXRpb24tcHJvamVjdGlvbi1pbmplY3RlZC10eXBlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGluamVjdGVkKCk6IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uKHtcbiAgICAgIHR5cGU6IFBhcnRpdGlvblByb2plY3Rpb25UeXBlLklOSkVDVEVELFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIHBhcnRpdGlvbiBwcm9qZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHR5cGU6IFBhcnRpdGlvblByb2plY3Rpb25UeXBlO1xuXG4gIC8qKlxuICAgKiBSYW5nZSBvZiBwYXJ0aXRpb24gdmFsdWVzIGZvciBJTlRFR0VSIHR5cGUuXG4gICAqXG4gICAqIEFycmF5IG9mIFttaW4sIG1heF0gYXMgbnVtYmVycy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbnRlZ2VyUmFuZ2U/OiBudW1iZXJbXTtcblxuICAvKipcbiAgICogUmFuZ2Ugb2YgcGFydGl0aW9uIHZhbHVlcyBmb3IgREFURSB0eXBlLlxuICAgKlxuICAgKiBBcnJheSBvZiBbc3RhcnQsIGVuZF0gYXMgZGF0ZSBzdHJpbmdzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRhdGVSYW5nZT86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBJbnRlcnZhbCBiZXR3ZWVuIHBhcnRpdGlvbiB2YWx1ZXMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW50ZXJ2YWw/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBkaWdpdHMgdG8gcGFkIElOVEVHRVIgcGFydGl0aW9uIHZhbHVlcy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkaWdpdHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERhdGUgZm9ybWF0IGZvciBEQVRFIHBhcnRpdGlvbiB2YWx1ZXMgKEphdmEgU2ltcGxlRGF0ZUZvcm1hdCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZm9ybWF0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBVbml0IGZvciBEQVRFIHBhcnRpdGlvbiBpbnRlcnZhbC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbnRlcnZhbFVuaXQ/OiBEYXRlSW50ZXJ2YWxVbml0O1xuXG4gIC8qKlxuICAgKiBFeHBsaWNpdCBsaXN0IG9mIHZhbHVlcyBmb3IgRU5VTSBwYXJ0aXRpb25zLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlcz86IHN0cmluZ1tdO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHJvcHM6IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uUHJvcHMpIHtcbiAgICB0aGlzLnR5cGUgPSBwcm9wcy50eXBlO1xuICAgIHRoaXMuaW50ZWdlclJhbmdlID0gcHJvcHMuaW50ZWdlclJhbmdlO1xuICAgIHRoaXMuZGF0ZVJhbmdlID0gcHJvcHMuZGF0ZVJhbmdlO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBwcm9wcy5pbnRlcnZhbDtcbiAgICB0aGlzLmRpZ2l0cyA9IHByb3BzLmRpZ2l0cztcbiAgICB0aGlzLmZvcm1hdCA9IHByb3BzLmZvcm1hdDtcbiAgICB0aGlzLmludGVydmFsVW5pdCA9IHByb3BzLmludGVydmFsVW5pdDtcbiAgICB0aGlzLnZhbHVlcyA9IHByb3BzLnZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIENsb3VkRm9ybWF0aW9uIHBhcmFtZXRlcnMgZm9yIHRoaXMgcGFydGl0aW9uIHByb2plY3Rpb24gY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIGNvbHVtbk5hbWUgLSBUaGUgcGFydGl0aW9uIGNvbHVtbiBuYW1lXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9yZW5kZXJQYXJhbWV0ZXJzKGNvbHVtbk5hbWU6IHN0cmluZyk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIGNvbnN0IHBhcmFtczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgIFtgcHJvamVjdGlvbi4ke2NvbHVtbk5hbWV9LnR5cGVgXTogdGhpcy50eXBlLFxuICAgIH07XG5cbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSBQYXJ0aXRpb25Qcm9qZWN0aW9uVHlwZS5JTlRFR0VSOiB7XG4gICAgICAgIGNvbnN0IFttaW4sIG1heF0gPSB0aGlzLmludGVnZXJSYW5nZSE7XG4gICAgICAgIHBhcmFtc1tgcHJvamVjdGlvbi4ke2NvbHVtbk5hbWV9LnJhbmdlYF0gPSBgJHttaW59LCR7bWF4fWA7XG4gICAgICAgIGlmICh0aGlzLmludGVydmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwYXJhbXNbYHByb2plY3Rpb24uJHtjb2x1bW5OYW1lfS5pbnRlcnZhbGBdID0gdGhpcy5pbnRlcnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRpZ2l0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGFyYW1zW2Bwcm9qZWN0aW9uLiR7Y29sdW1uTmFtZX0uZGlnaXRzYF0gPSB0aGlzLmRpZ2l0cy50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBQYXJ0aXRpb25Qcm9qZWN0aW9uVHlwZS5EQVRFOiB7XG4gICAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IHRoaXMuZGF0ZVJhbmdlITtcbiAgICAgICAgcGFyYW1zW2Bwcm9qZWN0aW9uLiR7Y29sdW1uTmFtZX0ucmFuZ2VgXSA9IGAke3N0YXJ0fSwke2VuZH1gO1xuICAgICAgICBwYXJhbXNbYHByb2plY3Rpb24uJHtjb2x1bW5OYW1lfS5mb3JtYXRgXSA9IHRoaXMuZm9ybWF0ITtcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJ2YWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHBhcmFtc1tgcHJvamVjdGlvbi4ke2NvbHVtbk5hbWV9LmludGVydmFsYF0gPSB0aGlzLmludGVydmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaW50ZXJ2YWxVbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwYXJhbXNbYHByb2plY3Rpb24uJHtjb2x1bW5OYW1lfS5pbnRlcnZhbC51bml0YF0gPSB0aGlzLmludGVydmFsVW5pdDtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgUGFydGl0aW9uUHJvamVjdGlvblR5cGUuRU5VTToge1xuICAgICAgICBwYXJhbXNbYHByb2plY3Rpb24uJHtjb2x1bW5OYW1lfS52YWx1ZXNgXSA9IHRoaXMudmFsdWVzIS5qb2luKCcsJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBQYXJ0aXRpb25Qcm9qZWN0aW9uVHlwZS5JTkpFQ1RFRDoge1xuICAgICAgICAvLyBJTkpFQ1RFRCBoYXMgbm8gYWRkaXRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICAvLyBUeXBlU2NyaXB0IGV4aGF1c3RpdmVuZXNzIGNoZWNrXG4gICAgICAgIGNvbnN0IGV4aGF1c3RpdmVDaGVjazogbmV2ZXIgPSB0aGlzLnR5cGU7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgVW5rbm93blByb2plY3Rpb25UeXBlYCxcbiAgICAgICAgICBgVW5rbm93biBwYXJ0aXRpb24gcHJvamVjdGlvbiB0eXBlIGZvciBcIiR7Y29sdW1uTmFtZX1cIjogJHtleGhhdXN0aXZlQ2hlY2t9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG59XG5cbi8qKlxuICogUGFydGl0aW9uIHByb2plY3Rpb24gY29uZmlndXJhdGlvbiBmb3IgYSB0YWJsZS5cbiAqXG4gKiBNYXBzIHBhcnRpdGlvbiBjb2x1bW4gbmFtZXMgdG8gdGhlaXIgcHJvamVjdGlvbiBjb25maWd1cmF0aW9ucy5cbiAqIFRoZSBrZXkgaXMgdGhlIHBhcnRpdGlvbiBjb2x1bW4gbmFtZSwgdGhlIHZhbHVlIGlzIHRoZSBwYXJ0aXRpb24gY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgUGFydGl0aW9uUHJvamVjdGlvbiA9IHtcbiAgW2NvbHVtbk5hbWU6IHN0cmluZ106IFBhcnRpdGlvblByb2plY3Rpb25Db25maWd1cmF0aW9uO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgQ2xvdWRGb3JtYXRpb24gcGFyYW1ldGVycyBmb3IgcGFydGl0aW9uIHByb2plY3Rpb24gY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAcGFyYW0gY29sdW1uTmFtZSAtIFRoZSBwYXJ0aXRpb24gY29sdW1uIG5hbWVcbiAqIEBwYXJhbSBjb25maWcgLSBUaGUgcGFydGl0aW9uIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIENsb3VkRm9ybWF0aW9uIHBhcmFtZXRlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUGFydGl0aW9uUHJvamVjdGlvblBhcmFtZXRlcnMoXG4gIGNvbHVtbk5hbWU6IHN0cmluZyxcbiAgY29uZmlnOiBQYXJ0aXRpb25Qcm9qZWN0aW9uQ29uZmlndXJhdGlvbixcbik6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICByZXR1cm4gY29uZmlnLl9yZW5kZXJQYXJhbWV0ZXJzKGNvbHVtbk5hbWUpO1xufVxuIl19