UNPKG

kaltura-node-typescript-client

Version:
365 lines 52.2 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.KalturaObjectBase = void 0;
var kaltura_client_utils_1 = require("./kaltura-client-utils");
var kaltura_types_factory_1 = require("./kaltura-types-factory");
var kaltura_logger_1 = require("./kaltura-logger");
;
var KalturaObjectBase = /** @class */ (function () {
    function KalturaObjectBase(data) {
        this._allowedEmptyArray = [];
        this._dependentProperties = {};
        if (data) {
            Object.assign(this, data);
        }
        if (typeof this.relatedObjects === 'undefined')
            this.relatedObjects = {};
    }
    KalturaObjectBase.prototype.allowEmptyArray = function () {
        var properties = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            properties[_i] = arguments[_i];
        }
        var metadata = this._getMetadata().properties;
        for (var _a = 0, properties_1 = properties; _a < properties_1.length; _a++) {
            var property = properties_1[_a];
            var metadataProperty = metadata[property];
            if (!metadataProperty) {
                kaltura_logger_1.Logger.debug("ignore property '" + property + "' flagged to allow empty array as it doesn't not exists on type (did you set the right property in method 'allowEmptyArray'?)");
            }
            else if (metadataProperty.type !== 'a') {
                kaltura_logger_1.Logger.debug("ignore property '" + property + "' flagged to allow empty array as it is not of type array (did you set the right property in method 'allowEmptyArray'?)");
            }
            else {
                this._allowedEmptyArray.push(property);
            }
        }
        return this;
    };
    KalturaObjectBase.prototype.setData = function (handler) {
        if (handler) {
            handler(this);
        }
        return this;
    };
    KalturaObjectBase.prototype.getTypeName = function () {
        return this._getMetadata().properties['objectType'].default;
    };
    KalturaObjectBase.prototype._getMetadata = function () {
        // DEVELOPER NOTICE: according to the server schema, property 'relatedObjects' should have be of type 'KalturaListResponse'.
        // this is not an option as it created circle reference where KalturaListResponse > KalturaObjectBase > KalturaListResponse.
        // Hence, we cannot set the type explicitly and we need to expose the default type 'KalturaObjectBase'
        return {
            properties: {
                relatedObjects: { type: 'm', readOnly: true, subTypeConstructor: null, subType: 'KalturaListResponse' },
            }
        };
    };
    KalturaObjectBase.prototype.hasMetadataProperty = function (propertyName) {
        return !!this._getMetadata().properties[propertyName];
    };
    KalturaObjectBase.prototype.toRequestObject = function () {
        var _this = this;
        var metadata = this._getMetadata();
        var result = {};
        try {
            Object.keys(metadata.properties).forEach(function (propertyName) {
                var propertyData = metadata.properties[propertyName];
                var propertyValue = _this._createRequestPropertyValue(propertyName, propertyData);
                switch (propertyValue.status) {
                    case "exists":
                        result[propertyName] = propertyValue.value;
                        break;
                    case "removed":
                        result[propertyName + "__null"] = ''; // mark property for deletion
                        break;
                    case "missing":
                    default:
                        break;
                }
            });
        }
        catch (err) {
            // TODO [kaltura] should use logHandler
            kaltura_logger_1.Logger.error(err.message);
            throw err;
        }
        return result;
    };
    KalturaObjectBase.prototype.fromResponseObject = function (data) {
        var _this = this;
        var metadata = this._getMetadata();
        var result = {};
        try {
            Object.keys(metadata.properties).forEach(function (propertyName) {
                var propertyData = metadata.properties[propertyName];
                var propertyValue = _this._parseResponseProperty(propertyName, propertyData, data);
                if (propertyValue != null && typeof propertyValue !== 'undefined') {
                    _this[propertyName] = propertyValue;
                }
            });
        }
        catch (err) {
            // TODO [kaltura] should use logHandler
            kaltura_logger_1.Logger.error(err.message);
            throw err;
        }
        return result;
    };
    KalturaObjectBase.prototype._parseResponseProperty = function (propertyName, property, source) {
        var _this = this;
        var result;
        var sourceValue = propertyName ? source[propertyName] : source;
        if (typeof sourceValue !== 'undefined') {
            if (sourceValue === null) {
                result = null;
            }
            else {
                switch (property.type) {
                    case 'b': // boolean
                        if (typeof sourceValue === 'boolean') {
                            result = sourceValue;
                        }
                        else if (sourceValue + '' === '0') {
                            result = false;
                        }
                        else if (sourceValue + '' === '1') {
                            result = true;
                        }
                        break;
                    case 's': // string
                        result = sourceValue + '';
                        break;
                    case 'n': // number
                    case 'en': // enum of type number
                        result = sourceValue * 1;
                        break;
                    case 'es': // enum of type number
                        result = typeof sourceValue !== 'undefined' && sourceValue !== null ? sourceValue.toString() : undefined;
                        break;
                    case 'o': // object
                        var propertyObjectType = sourceValue['objectType'];
                        if (propertyObjectType) {
                            result = this._createKalturaObject(propertyObjectType, property.subType);
                            if (result) {
                                result.fromResponseObject(sourceValue);
                            }
                            else {
                                throw new Error("Failed to create kaltura object of type '" + source['objectType'] + "' (fallback type '" + property.subType + "')");
                            }
                        }
                        else {
                            throw new Error("Failed to create kaltura object for property '" + propertyName + "' (type '" + property.subType + "'). provided response object is missing property 'objectType'.");
                        }
                        break;
                    case 'm': // map
                        var parsedMap_1 = {};
                        if (sourceValue instanceof Object) {
                            Object.keys(sourceValue).forEach(function (itemKey) {
                                var itemValue = sourceValue[itemKey];
                                var newItem = _this._createKalturaObject(itemValue['objectType'], property.subType);
                                if (itemValue && newItem) {
                                    newItem.fromResponseObject(itemValue);
                                    parsedMap_1[itemKey] = newItem;
                                }
                                else {
                                    throw new Error("Failed to create kaltura object for type '" + property.subType + "'");
                                }
                            });
                            result = parsedMap_1;
                        }
                        else {
                            throw new Error("failed to parse property '" + propertyName + ". Expected type object, got type '" + typeof sourceValue);
                        }
                        break;
                    case 'a': // array
                        if (sourceValue instanceof Array) {
                            var parsedArray_1 = [];
                            sourceValue.forEach(function (responseItem) {
                                var newItem = _this._createKalturaObject(responseItem['objectType'], property.subType);
                                if (newItem) {
                                    newItem.fromResponseObject(responseItem);
                                    parsedArray_1.push(newItem);
                                }
                                else {
                                    throw new Error("Failed to create kaltura object for type '" + responseItem['objectType'] + "' and for fallback type '" + property.subType + "'");
                                }
                            });
                            result = parsedArray_1;
                        }
                        else {
                            throw new Error("failed to parse property '" + propertyName + ". Expected type array, got type '" + typeof sourceValue);
                        }
                        break;
                    case 'd': // date
                        if (this._isNumeric(sourceValue)) {
                            result = kaltura_client_utils_1.KalturaClientUtils.fromServerDate(sourceValue * 1);
                        }
                        else {
                            throw new Error("failed to parse property '" + propertyName + ". Expected type date, got type '" + typeof sourceValue);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        return result;
    };
    KalturaObjectBase.prototype._isNumeric = function (n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    };
    KalturaObjectBase.prototype._createKalturaObject = function (objectType, fallbackObjectType) {
        var result = null;
        var usedFallbackType = false;
        if (objectType) {
            result = kaltura_types_factory_1.KalturaTypesFactory.createObject(objectType);
        }
        if (!result && fallbackObjectType) {
            usedFallbackType = true;
            result = kaltura_types_factory_1.KalturaTypesFactory.createObject(fallbackObjectType);
        }
        if (usedFallbackType && result) {
            kaltura_logger_1.Logger.debug("could not find object type '" + objectType + "', Falling back to '" + fallbackObjectType + "' object type. (Did you remember to set your accepted object types in the request \u201Cconfig.acceptedTypes\u201D attribute?)");
        }
        else if (!result) {
            kaltura_logger_1.Logger.debug("could not find object type '" + objectType + "'. (Did you remember to set your accepted object types in the request \u201Cconfig.acceptedTypes\u201D attribute?)");
        }
        return result;
    };
    KalturaObjectBase.prototype._createRequestPropertyValue = function (propertyName, property) {
        var result = { status: 'missing' };
        if (property.type === 'c') {
            // constant string
            if (property.default) {
                result = { status: 'exists', value: property.default };
            }
        }
        else if (this._dependentProperties[propertyName]) {
            var dependentProperty = this._dependentProperties[propertyName];
            var resultValue = "{" + dependentProperty.request + ":result" + (dependentProperty.targetPath ? ':' + dependentProperty.targetPath : '') + "}";
            result = { status: 'exists', value: resultValue };
        }
        else if (!property.readOnly) {
            var value_1 = this[propertyName];
            if (typeof value_1 !== 'undefined') {
                if (value_1 === null) {
                    result = { status: 'removed' };
                }
                else {
                    switch (property.type) {
                        case 'b': // boolean
                            result = { status: 'exists', value: value_1 };
                            break;
                        case 's': // string
                            result = { status: 'exists', value: value_1 + '' };
                            break;
                        case 'n': // number
                        case 'en': // enum of type number
                            result = { status: 'exists', value: value_1 * 1 };
                            break;
                        case 'o': // object
                            if (value_1 instanceof KalturaObjectBase) {
                                result = { status: 'exists', value: value_1.toRequestObject() };
                            }
                            else {
                                throw new Error("failed to parse property. Expected '" + propertyName + " to be kaltura object");
                            }
                            break;
                        case 'a': // array
                            if (value_1 instanceof Array) {
                                var parsedArray_2 = [];
                                value_1.forEach(function (item) {
                                    if (item instanceof KalturaObjectBase) {
                                        parsedArray_2.push(item.toRequestObject());
                                    }
                                });
                                var allowEmptyArrayAsAValue = this._allowedEmptyArray.indexOf(propertyName) !== -1;
                                if (allowEmptyArrayAsAValue || parsedArray_2.length !== 0) {
                                    if (parsedArray_2.length === value_1.length) {
                                        result = { status: 'exists', value: parsedArray_2 };
                                    }
                                    else {
                                        throw new Error("failed to parse array. Expected all '" + propertyName + " items to be kaltura object");
                                    }
                                }
                            }
                            else {
                                throw new Error("failed to parse property. Expected '" + propertyName + " to be Array");
                            }
                            break;
                        case 'm': //map
                            if (value_1 instanceof Object) {
                                var valueKeys = Object.keys(value_1);
                                if (valueKeys.length > 0) {
                                    var parsedObject_1 = {};
                                    valueKeys.forEach(function (itemKey) {
                                        var itemValue = value_1[itemKey];
                                        if (itemValue instanceof KalturaObjectBase) {
                                            parsedObject_1[itemKey] = itemValue.toRequestObject();
                                        }
                                    });
                                    if (valueKeys.length === Object.keys(parsedObject_1).length) {
                                        result = { status: 'exists', value: parsedObject_1 };
                                    }
                                    else {
                                        throw new Error("failed to parse map. Expected all '" + propertyName + " items to be kaltura object");
                                    }
                                }
                            }
                            else {
                                throw new Error("failed to parse property. Expected '" + propertyName + " to be kaltura object");
                            }
                            break;
                        case 'd': // date
                            if (value_1 instanceof Date) {
                                result = { status: 'exists', value: kaltura_client_utils_1.KalturaClientUtils.toServerDate(value_1) };
                            }
                            else {
                                throw new Error("failed to parse property. Expected '" + propertyName + " to be date");
                            }
                            break;
                        case 'es': // enum of type string
                            result = { status: 'exists', value: typeof value_1 === 'string' ? value_1 : undefined };
                            break;
                        case 'f':
                            if (value_1 instanceof FormData) {
                                result = { status: 'exists', value: value_1 };
                            }
                            break;
                        default:
                            // do nothing
                            break;
                    }
                }
            }
        }
        return result;
    };
    KalturaObjectBase.prototype.setDependency = function () {
        var dependency = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            dependency[_i] = arguments[_i];
        }
        for (var i = 0, len = dependency.length; i < len; i++) {
            var item = dependency[i];
            var _a = item, property = _a.property, request = _a.request, targetPath = _a.targetPath;
            if (item instanceof Array) {
                property = item[0];
                request = item[1];
                targetPath = item.length === 3 ? item[2] : null;
            }
            // The server expect one based index (meaning the first item has index 1)
            // since Javascript array are zero based index we expose the api as zero based
            // and transform the index value in the actual request by adding 1
            request = request + 1;
            this._dependentProperties[property] = { property: property, request: request, targetPath: targetPath };
        }
        return this;
    };
    return KalturaObjectBase;
}());
exports.KalturaObjectBase = KalturaObjectBase;

//# sourceMappingURL=data:application/json;charset=utf8;base64,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RUFBRTtZQUNyRCxJQUFNLElBQUksR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkIsSUFBQSxLQUF5QyxJQUFJLEVBQTNDLFFBQVEsY0FBQSxFQUFFLE9BQU8sYUFBQSxFQUFFLFVBQVUsZ0JBQWMsQ0FBQztZQUNsRCxJQUFJLElBQUksWUFBWSxLQUFLLEVBQUU7Z0JBQ3pCLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xCLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7YUFDakQ7WUFFRCx5RUFBeUU7WUFDekUsOEVBQThFO1lBQzlFLGtFQUFrRTtZQUNsRSxPQUFPLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxRQUFRLFVBQUEsRUFBRSxPQUFPLFNBQUEsRUFBRSxVQUFVLFlBQUEsRUFBRSxDQUFDO1NBQ3pFO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0gsd0JBQUM7QUFBRCxDQS9XQSxBQStXQyxJQUFBO0FBL1dxQiw4Q0FBaUIiLCJmaWxlIjoiYXBpL2thbHR1cmEtb2JqZWN0LWJhc2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBLYWx0dXJhQ2xpZW50VXRpbHMgfSBmcm9tIFwiLi9rYWx0dXJhLWNsaWVudC11dGlsc1wiO1xuaW1wb3J0IHsgS2FsdHVyYVR5cGVzRmFjdG9yeSB9IGZyb20gJy4va2FsdHVyYS10eXBlcy1mYWN0b3J5JztcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4va2FsdHVyYS1sb2dnZXInXG5cbmV4cG9ydCB0eXBlIERlcGVuZGVudFByb3BlcnR5ID0geyBwcm9wZXJ0eTogc3RyaW5nLCByZXF1ZXN0OiBudW1iZXIsIHRhcmdldFBhdGg/OiBzdHJpbmdbXSB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIEthbHR1cmFPYmplY3RNZXRhZGF0YSB7XG4gIHByb3BlcnRpZXM6IHsgW2tleTogc3RyaW5nXTogS2FsdHVyYU9iamVjdFByb3BlcnR5TWV0YWRhdGEgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBLYWx0dXJhT2JqZWN0UHJvcGVydHlNZXRhZGF0YSB7XG4gIHJlYWRPbmx5PzogYm9vbGVhbjtcbiAgdHlwZTogc3RyaW5nO1xuICBzdWJUeXBlPzogc3RyaW5nO1xuICBkZWZhdWx0Pzogc3RyaW5nO1xuICBzdWJUeXBlQ29uc3RydWN0b3I/OiB7IG5ldygpOiBLYWx0dXJhT2JqZWN0QmFzZSB9O1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBLYWx0dXJhT2JqZWN0QmFzZUFyZ3Mge1xuICByZWxhdGVkT2JqZWN0cz86IHsgW2tleTogc3RyaW5nXTogS2FsdHVyYU9iamVjdEJhc2UgfTtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEthbHR1cmFPYmplY3RCYXNlIHtcblxuICBwcml2YXRlIF9hbGxvd2VkRW1wdHlBcnJheTogc3RyaW5nW10gPSBbXTtcbiAgcHJpdmF0ZSBfZGVwZW5kZW50UHJvcGVydGllczogeyBba2V5OiBzdHJpbmddOiBEZXBlbmRlbnRQcm9wZXJ0eSB9ID0ge307XG4gIHJlbGF0ZWRPYmplY3RzOiB7IFtrZXk6IHN0cmluZ106IEthbHR1cmFPYmplY3RCYXNlIH07IC8vIHNlZSBkZXZlbG9wZXIgbm90aWNlIGluIG1ldGhvZCAnX2dldE1ldGFkYXRhKCknXG5cblxuICBhbGxvd0VtcHR5QXJyYXkoLi4ucHJvcGVydGllczogc3RyaW5nW10pOiB0aGlzIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuX2dldE1ldGFkYXRhKCkucHJvcGVydGllcztcbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMpIHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhUHJvcGVydHkgPSBtZXRhZGF0YVtwcm9wZXJ0eV07XG4gICAgICBpZiAoIW1ldGFkYXRhUHJvcGVydHkpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKGBpZ25vcmUgcHJvcGVydHkgJyR7cHJvcGVydHl9JyBmbGFnZ2VkIHRvIGFsbG93IGVtcHR5IGFycmF5IGFzIGl0IGRvZXNuJ3Qgbm90IGV4aXN0cyBvbiB0eXBlIChkaWQgeW91IHNldCB0aGUgcmlnaHQgcHJvcGVydHkgaW4gbWV0aG9kICdhbGxvd0VtcHR5QXJyYXknPylgKVxuICAgICAgfSBlbHNlIGlmIChtZXRhZGF0YVByb3BlcnR5LnR5cGUgIT09ICdhJykge1xuICAgICAgICBMb2dnZXIuZGVidWcoYGlnbm9yZSBwcm9wZXJ0eSAnJHtwcm9wZXJ0eX0nIGZsYWdnZWQgdG8gYWxsb3cgZW1wdHkgYXJyYXkgYXMgaXQgaXMgbm90IG9mIHR5cGUgYXJyYXkgKGRpZCB5b3Ugc2V0IHRoZSByaWdodCBwcm9wZXJ0eSBpbiBtZXRob2QgJ2FsbG93RW1wdHlBcnJheSc/KWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9hbGxvd2VkRW1wdHlBcnJheS5wdXNoKHByb3BlcnR5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldERhdGEoaGFuZGxlcjogKHJlcXVlc3Q6IHRoaXMpID0+IHZvaWQpOiB0aGlzIHtcbiAgICBpZiAoaGFuZGxlcikge1xuICAgICAgaGFuZGxlcih0aGlzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihkYXRhPzoge30pIHtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBkYXRhKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRoaXMucmVsYXRlZE9iamVjdHMgPT09ICd1bmRlZmluZWQnKSB0aGlzLnJlbGF0ZWRPYmplY3RzID0ge307XG4gIH1cblxuICBwdWJsaWMgZ2V0VHlwZU5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGEoKS5wcm9wZXJ0aWVzWydvYmplY3RUeXBlJ10uZGVmYXVsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZ2V0TWV0YWRhdGEoKTogS2FsdHVyYU9iamVjdE1ldGFkYXRhIHtcbiAgICAvLyBERVZFTE9QRVIgTk9USUNFOiBhY2NvcmRpbmcgdG8gdGhlIHNlcnZlciBzY2hlbWEsIHByb3BlcnR5ICdyZWxhdGVkT2JqZWN0cycgc2hvdWxkIGhhdmUgYmUgb2YgdHlwZSAnS2FsdHVyYUxpc3RSZXNwb25zZScuXG4gICAgLy8gdGhpcyBpcyBub3QgYW4gb3B0aW9uIGFzIGl0IGNyZWF0ZWQgY2lyY2xlIHJlZmVyZW5jZSB3aGVyZSBLYWx0dXJhTGlzdFJlc3BvbnNlID4gS2FsdHVyYU9iamVjdEJhc2UgPiBLYWx0dXJhTGlzdFJlc3BvbnNlLlxuICAgIC8vIEhlbmNlLCB3ZSBjYW5ub3Qgc2V0IHRoZSB0eXBlIGV4cGxpY2l0bHkgYW5kIHdlIG5lZWQgdG8gZXhwb3NlIHRoZSBkZWZhdWx0IHR5cGUgJ0thbHR1cmFPYmplY3RCYXNlJ1xuICAgIHJldHVybiB7XG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIHJlbGF0ZWRPYmplY3RzOiB7IHR5cGU6ICdtJywgcmVhZE9ubHk6IHRydWUsIHN1YlR5cGVDb25zdHJ1Y3RvcjogbnVsbCwgc3ViVHlwZTogJ0thbHR1cmFMaXN0UmVzcG9uc2UnIH0sXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBoYXNNZXRhZGF0YVByb3BlcnR5KHByb3BlcnR5TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5fZ2V0TWV0YWRhdGEoKS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG4gIH1cblxuICB0b1JlcXVlc3RPYmplY3QoKToge30ge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5fZ2V0TWV0YWRhdGEoKTtcbiAgICBsZXQgcmVzdWx0ID0ge307XG5cbiAgICB0cnkge1xuICAgICAgT2JqZWN0LmtleXMobWV0YWRhdGEucHJvcGVydGllcykuZm9yRWFjaChwcm9wZXJ0eU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBwcm9wZXJ0eURhdGEgPSBtZXRhZGF0YS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG4gICAgICAgIGNvbnN0IHByb3BlcnR5VmFsdWUgPSB0aGlzLl9jcmVhdGVSZXF1ZXN0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eU5hbWUsIHByb3BlcnR5RGF0YSk7XG5cbiAgICAgICAgc3dpdGNoIChwcm9wZXJ0eVZhbHVlLnN0YXR1cykge1xuICAgICAgICAgIGNhc2UgXCJleGlzdHNcIjpcbiAgICAgICAgICAgIHJlc3VsdFtwcm9wZXJ0eU5hbWVdID0gcHJvcGVydHlWYWx1ZS52YWx1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgXCJyZW1vdmVkXCI6XG4gICAgICAgICAgICByZXN1bHRbYCR7cHJvcGVydHlOYW1lfV9fbnVsbGBdID0gJyc7IC8vIG1hcmsgcHJvcGVydHkgZm9yIGRlbGV0aW9uXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIFwibWlzc2luZ1wiOlxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBUT0RPIFtrYWx0dXJhXSBzaG91bGQgdXNlIGxvZ0hhbmRsZXJcbiAgICAgIExvZ2dlci5lcnJvcihlcnIubWVzc2FnZSlcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnJvbVJlc3BvbnNlT2JqZWN0KGRhdGE6IGFueSk6IHt9IHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuX2dldE1ldGFkYXRhKCk7XG4gICAgbGV0IHJlc3VsdCA9IHt9O1xuXG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5rZXlzKG1ldGFkYXRhLnByb3BlcnRpZXMpLmZvckVhY2gocHJvcGVydHlOYW1lID0+IHtcbiAgICAgICAgY29uc3QgcHJvcGVydHlEYXRhID0gbWV0YWRhdGEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgICBjb25zdCBwcm9wZXJ0eVZhbHVlID0gdGhpcy5fcGFyc2VSZXNwb25zZVByb3BlcnR5KHByb3BlcnR5TmFtZSwgcHJvcGVydHlEYXRhLCBkYXRhKTtcblxuICAgICAgICBpZiAocHJvcGVydHlWYWx1ZSAhPSBudWxsICYmIHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnR5VmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gVE9ETyBba2FsdHVyYV0gc2hvdWxkIHVzZSBsb2dIYW5kbGVyXG4gICAgICBMb2dnZXIuZXJyb3IoZXJyLm1lc3NhZ2UpXG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG5cblxuICBwcm90ZWN0ZWQgX3BhcnNlUmVzcG9uc2VQcm9wZXJ0eShwcm9wZXJ0eU5hbWU6IHN0cmluZywgcHJvcGVydHk6IEthbHR1cmFPYmplY3RQcm9wZXJ0eU1ldGFkYXRhLCBzb3VyY2U6IGFueSk6IGFueSB7XG5cbiAgICBsZXQgcmVzdWx0O1xuICAgIGxldCBzb3VyY2VWYWx1ZSA9IHByb3BlcnR5TmFtZSA/IHNvdXJjZVtwcm9wZXJ0eU5hbWVdIDogc291cmNlO1xuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2VWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChzb3VyY2VWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpdGNoIChwcm9wZXJ0eS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnYic6IC8vIGJvb2xlYW5cbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc291cmNlVmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICByZXN1bHQgPSBzb3VyY2VWYWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlVmFsdWUgKyAnJyA9PT0gJzAnKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VWYWx1ZSArICcnID09PSAnMScpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3MnOiAvLyBzdHJpbmdcbiAgICAgICAgICAgIHJlc3VsdCA9IHNvdXJjZVZhbHVlICsgJyc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICduJzogLy8gbnVtYmVyXG4gICAgICAgICAgY2FzZSAnZW4nOiAvLyBlbnVtIG9mIHR5cGUgbnVtYmVyXG4gICAgICAgICAgICByZXN1bHQgPSBzb3VyY2VWYWx1ZSAqIDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdlcyc6IC8vIGVudW0gb2YgdHlwZSBudW1iZXJcbiAgICAgICAgICAgIHJlc3VsdCA9IHR5cGVvZiBzb3VyY2VWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc291cmNlVmFsdWUgIT09IG51bGwgPyBzb3VyY2VWYWx1ZS50b1N0cmluZygpIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnbyc6IC8vIG9iamVjdFxuICAgICAgICAgICAgY29uc3QgcHJvcGVydHlPYmplY3RUeXBlID0gc291cmNlVmFsdWVbJ29iamVjdFR5cGUnXTtcblxuICAgICAgICAgICAgaWYgKHByb3BlcnR5T2JqZWN0VHlwZSkge1xuICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGVLYWx0dXJhT2JqZWN0KHByb3BlcnR5T2JqZWN0VHlwZSwgcHJvcGVydHkuc3ViVHlwZSk7XG5cbiAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5mcm9tUmVzcG9uc2VPYmplY3Qoc291cmNlVmFsdWUpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBrYWx0dXJhIG9iamVjdCBvZiB0eXBlICcke3NvdXJjZVsnb2JqZWN0VHlwZSddfScgKGZhbGxiYWNrIHR5cGUgJyR7cHJvcGVydHkuc3ViVHlwZX0nKWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjcmVhdGUga2FsdHVyYSBvYmplY3QgZm9yIHByb3BlcnR5ICcke3Byb3BlcnR5TmFtZX0nICh0eXBlICcke3Byb3BlcnR5LnN1YlR5cGV9JykuIHByb3ZpZGVkIHJlc3BvbnNlIG9iamVjdCBpcyBtaXNzaW5nIHByb3BlcnR5ICdvYmplY3RUeXBlJy5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnbSc6IC8vIG1hcFxuICAgICAgICAgICAgY29uc3QgcGFyc2VkTWFwID0ge307XG4gICAgICAgICAgICBpZiAoc291cmNlVmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc291cmNlVmFsdWUpLmZvckVhY2goaXRlbUtleSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbVZhbHVlID0gc291cmNlVmFsdWVbaXRlbUtleV07XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3SXRlbSA9IHRoaXMuX2NyZWF0ZUthbHR1cmFPYmplY3QoaXRlbVZhbHVlWydvYmplY3RUeXBlJ10sIHByb3BlcnR5LnN1YlR5cGUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW1WYWx1ZSAmJiBuZXdJdGVtKSB7XG4gICAgICAgICAgICAgICAgICBuZXdJdGVtLmZyb21SZXNwb25zZU9iamVjdChpdGVtVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgcGFyc2VkTWFwW2l0ZW1LZXldID0gbmV3SXRlbTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGthbHR1cmEgb2JqZWN0IGZvciB0eXBlICcke3Byb3BlcnR5LnN1YlR5cGV9J2ApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICByZXN1bHQgPSBwYXJzZWRNYXA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBwYXJzZSBwcm9wZXJ0eSAnJHtwcm9wZXJ0eU5hbWV9LiBFeHBlY3RlZCB0eXBlIG9iamVjdCwgZ290IHR5cGUgJyR7dHlwZW9mIHNvdXJjZVZhbHVlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYSc6IC8vIGFycmF5XG4gICAgICAgICAgICBpZiAoc291cmNlVmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICBjb25zdCBwYXJzZWRBcnJheSA9IFtdO1xuICAgICAgICAgICAgICBzb3VyY2VWYWx1ZS5mb3JFYWNoKHJlc3BvbnNlSXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3SXRlbSA9IHRoaXMuX2NyZWF0ZUthbHR1cmFPYmplY3QocmVzcG9uc2VJdGVtWydvYmplY3RUeXBlJ10sIHByb3BlcnR5LnN1YlR5cGUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKG5ld0l0ZW0pIHtcbiAgICAgICAgICAgICAgICAgIG5ld0l0ZW0uZnJvbVJlc3BvbnNlT2JqZWN0KHJlc3BvbnNlSXRlbSk7XG4gICAgICAgICAgICAgICAgICBwYXJzZWRBcnJheS5wdXNoKG5ld0l0ZW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjcmVhdGUga2FsdHVyYSBvYmplY3QgZm9yIHR5cGUgJyR7cmVzcG9uc2VJdGVtWydvYmplY3RUeXBlJ119JyBhbmQgZm9yIGZhbGxiYWNrIHR5cGUgJyR7cHJvcGVydHkuc3ViVHlwZX0nYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICByZXN1bHQgPSBwYXJzZWRBcnJheTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIHBhcnNlIHByb3BlcnR5ICcke3Byb3BlcnR5TmFtZX0uIEV4cGVjdGVkIHR5cGUgYXJyYXksIGdvdCB0eXBlICcke3R5cGVvZiBzb3VyY2VWYWx1ZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2QnOiAvLyBkYXRlXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOdW1lcmljKHNvdXJjZVZhbHVlKSkge1xuICAgICAgICAgICAgICByZXN1bHQgPSBLYWx0dXJhQ2xpZW50VXRpbHMuZnJvbVNlcnZlckRhdGUoc291cmNlVmFsdWUgKiAxKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmYWlsZWQgdG8gcGFyc2UgcHJvcGVydHkgJyR7cHJvcGVydHlOYW1lfS4gRXhwZWN0ZWQgdHlwZSBkYXRlLCBnb3QgdHlwZSAnJHt0eXBlb2Ygc291cmNlVmFsdWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIF9pc051bWVyaWMobjogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NyZWF0ZUthbHR1cmFPYmplY3Qob2JqZWN0VHlwZTogc3RyaW5nLCBmYWxsYmFja09iamVjdFR5cGU/OiBzdHJpbmcpOiBLYWx0dXJhT2JqZWN0QmFzZSB7XG4gICAgbGV0IHJlc3VsdCA9IG51bGw7XG4gICAgbGV0IHVzZWRGYWxsYmFja1R5cGUgPSBmYWxzZTtcbiAgICBpZiAob2JqZWN0VHlwZSkge1xuICAgICAgcmVzdWx0ID0gS2FsdHVyYVR5cGVzRmFjdG9yeS5jcmVhdGVPYmplY3Qob2JqZWN0VHlwZSk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXN1bHQgJiYgZmFsbGJhY2tPYmplY3RUeXBlKSB7XG4gICAgICB1c2VkRmFsbGJhY2tUeXBlID0gdHJ1ZTtcbiAgICAgIHJlc3VsdCA9IEthbHR1cmFUeXBlc0ZhY3RvcnkuY3JlYXRlT2JqZWN0KGZhbGxiYWNrT2JqZWN0VHlwZSk7XG4gICAgfVxuXG4gICAgaWYgKHVzZWRGYWxsYmFja1R5cGUgJiYgcmVzdWx0KSB7XG4gICAgICBMb2dnZXIuZGVidWcoYGNvdWxkIG5vdCBmaW5kIG9iamVjdCB0eXBlICcke29iamVjdFR5cGV9JywgRmFsbGluZyBiYWNrIHRvICcke2ZhbGxiYWNrT2JqZWN0VHlwZX0nIG9iamVjdCB0eXBlLiAoRGlkIHlvdSByZW1lbWJlciB0byBzZXQgeW91ciBhY2NlcHRlZCBvYmplY3QgdHlwZXMgaW4gdGhlIHJlcXVlc3Qg4oCcY29uZmlnLmFjY2VwdGVkVHlwZXPigJ0gYXR0cmlidXRlPylgKVxuICAgIH0gZWxzZSBpZiAoIXJlc3VsdCkge1xuICAgICAgTG9nZ2VyLmRlYnVnKGBjb3VsZCBub3QgZmluZCBvYmplY3QgdHlwZSAnJHtvYmplY3RUeXBlfScuIChEaWQgeW91IHJlbWVtYmVyIHRvIHNldCB5b3VyIGFjY2VwdGVkIG9iamVjdCB0eXBlcyBpbiB0aGUgcmVxdWVzdCDigJxjb25maWcuYWNjZXB0ZWRUeXBlc+KAnSBhdHRyaWJ1dGU/KWApXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgX2NyZWF0ZVJlcXVlc3RQcm9wZXJ0eVZhbHVlKHByb3BlcnR5TmFtZTogc3RyaW5nLCBwcm9wZXJ0eTogS2FsdHVyYU9iamVjdFByb3BlcnR5TWV0YWRhdGEpOiB7IHN0YXR1czogJ21pc3NpbmcnIHwgJ3JlbW92ZWQnIHwgJ2V4aXN0cycsIHZhbHVlPzogYW55IH0ge1xuXG4gICAgbGV0IHJlc3VsdDogeyBzdGF0dXM6ICdtaXNzaW5nJyB8ICdyZW1vdmVkJyB8ICdleGlzdHMnLCB2YWx1ZT86IGFueSB9ID0geyBzdGF0dXM6ICdtaXNzaW5nJyB9O1xuXG4gICAgaWYgKHByb3BlcnR5LnR5cGUgPT09ICdjJykge1xuICAgICAgLy8gY29uc3RhbnQgc3RyaW5nXG4gICAgICBpZiAocHJvcGVydHkuZGVmYXVsdCkge1xuICAgICAgICByZXN1bHQgPSB7IHN0YXR1czogJ2V4aXN0cycsIHZhbHVlOiBwcm9wZXJ0eS5kZWZhdWx0IH07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLl9kZXBlbmRlbnRQcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0pIHtcbiAgICAgIGNvbnN0IGRlcGVuZGVudFByb3BlcnR5ID0gdGhpcy5fZGVwZW5kZW50UHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgY29uc3QgcmVzdWx0VmFsdWUgPSBgeyR7ZGVwZW5kZW50UHJvcGVydHkucmVxdWVzdH06cmVzdWx0JHtkZXBlbmRlbnRQcm9wZXJ0eS50YXJnZXRQYXRoID8gJzonICsgZGVwZW5kZW50UHJvcGVydHkudGFyZ2V0UGF0aCA6ICcnfX1gO1xuICAgICAgcmVzdWx0ID0geyBzdGF0dXM6ICdleGlzdHMnLCB2YWx1ZTogcmVzdWx0VmFsdWUgfTtcbiAgICB9XG4gICAgZWxzZSBpZiAoIXByb3BlcnR5LnJlYWRPbmx5KSB7XG4gICAgICBsZXQgdmFsdWUgPSB0aGlzW3Byb3BlcnR5TmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJlc3VsdCA9IHsgc3RhdHVzOiAncmVtb3ZlZCcgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzd2l0Y2ggKHByb3BlcnR5LnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2InOiAvLyBib29sZWFuXG4gICAgICAgICAgICAgIHJlc3VsdCA9IHsgc3RhdHVzOiAnZXhpc3RzJywgdmFsdWU6IHZhbHVlIH07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncyc6IC8vIHN0cmluZ1xuICAgICAgICAgICAgICByZXN1bHQgPSB7IHN0YXR1czogJ2V4aXN0cycsIHZhbHVlOiB2YWx1ZSArICcnIH07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbic6IC8vIG51bWJlclxuICAgICAgICAgICAgY2FzZSAnZW4nOiAvLyBlbnVtIG9mIHR5cGUgbnVtYmVyXG4gICAgICAgICAgICAgIHJlc3VsdCA9IHsgc3RhdHVzOiAnZXhpc3RzJywgdmFsdWU6IHZhbHVlICogMSB9O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ28nOiAvLyBvYmplY3RcbiAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgS2FsdHVyYU9iamVjdEJhc2UpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB7IHN0YXR1czogJ2V4aXN0cycsIHZhbHVlOiB2YWx1ZS50b1JlcXVlc3RPYmplY3QoKSB9O1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIHBhcnNlIHByb3BlcnR5LiBFeHBlY3RlZCAnJHtwcm9wZXJ0eU5hbWV9IHRvIGJlIGthbHR1cmEgb2JqZWN0YCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdhJzogLy8gYXJyYXlcbiAgICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRBcnJheSA9IFtdO1xuICAgICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIEthbHR1cmFPYmplY3RCYXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlZEFycmF5LnB1c2goaXRlbS50b1JlcXVlc3RPYmplY3QoKSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBhbGxvd0VtcHR5QXJyYXlBc0FWYWx1ZSA9IHRoaXMuX2FsbG93ZWRFbXB0eUFycmF5LmluZGV4T2YocHJvcGVydHlOYW1lKSAhPT0gLTE7XG4gICAgICAgICAgICAgICAgaWYgKGFsbG93RW1wdHlBcnJheUFzQVZhbHVlIHx8IHBhcnNlZEFycmF5Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlZEFycmF5Lmxlbmd0aCA9PT0gdmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHsgc3RhdHVzOiAnZXhpc3RzJywgdmFsdWU6IHBhcnNlZEFycmF5IH07XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBwYXJzZSBhcnJheS4gRXhwZWN0ZWQgYWxsICcke3Byb3BlcnR5TmFtZX0gaXRlbXMgdG8gYmUga2FsdHVyYSBvYmplY3RgKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmYWlsZWQgdG8gcGFyc2UgcHJvcGVydHkuIEV4cGVjdGVkICcke3Byb3BlcnR5TmFtZX0gdG8gYmUgQXJyYXlgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ20nOiAvL21hcFxuICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZUtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWVLZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZE9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgICAgdmFsdWVLZXlzLmZvckVhY2goaXRlbUtleSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtVmFsdWUgPSB2YWx1ZVtpdGVtS2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1WYWx1ZSBpbnN0YW5jZW9mIEthbHR1cmFPYmplY3RCYXNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgcGFyc2VkT2JqZWN0W2l0ZW1LZXldID0gaXRlbVZhbHVlLnRvUmVxdWVzdE9iamVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBpZiAodmFsdWVLZXlzLmxlbmd0aCA9PT0gT2JqZWN0LmtleXMocGFyc2VkT2JqZWN0KS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0geyBzdGF0dXM6ICdleGlzdHMnLCB2YWx1ZTogcGFyc2VkT2JqZWN0IH07XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBwYXJzZSBtYXAuIEV4cGVjdGVkIGFsbCAnJHtwcm9wZXJ0eU5hbWV9IGl0ZW1zIHRvIGJlIGthbHR1cmEgb2JqZWN0YCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIHBhcnNlIHByb3BlcnR5LiBFeHBlY3RlZCAnJHtwcm9wZXJ0eU5hbWV9IHRvIGJlIGthbHR1cmEgb2JqZWN0YCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkJzogLy8gZGF0ZVxuICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0geyBzdGF0dXM6ICdleGlzdHMnLCB2YWx1ZTogS2FsdHVyYUNsaWVudFV0aWxzLnRvU2VydmVyRGF0ZSh2YWx1ZSkgfTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBwYXJzZSBwcm9wZXJ0eS4gRXhwZWN0ZWQgJyR7cHJvcGVydHlOYW1lfSB0byBiZSBkYXRlYCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdlcyc6IC8vIGVudW0gb2YgdHlwZSBzdHJpbmdcbiAgICAgICAgICAgICAgcmVzdWx0ID0geyBzdGF0dXM6ICdleGlzdHMnLCB2YWx1ZTogdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogdW5kZWZpbmVkIH07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZic6XG4gICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZvcm1EYXRhKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0geyBzdGF0dXM6ICdleGlzdHMnLCB2YWx1ZTogdmFsdWUgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHNldERlcGVuZGVuY3koLi4uZGVwZW5kZW5jeTogKERlcGVuZGVudFByb3BlcnR5IHwgW3N0cmluZywgbnVtYmVyXSB8IFtzdHJpbmcsIG51bWJlciwgc3RyaW5nXSlbXSk6IHRoaXMge1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBkZXBlbmRlbmN5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBpdGVtID0gZGVwZW5kZW5jeVtpXTtcbiAgICAgIGxldCB7IHByb3BlcnR5LCByZXF1ZXN0LCB0YXJnZXRQYXRoIH0gPSA8YW55Pml0ZW07XG4gICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHByb3BlcnR5ID0gaXRlbVswXTtcbiAgICAgICAgcmVxdWVzdCA9IGl0ZW1bMV07XG4gICAgICAgIHRhcmdldFBhdGggPSBpdGVtLmxlbmd0aCA9PT0gMyA/IGl0ZW1bMl0gOiBudWxsO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgc2VydmVyIGV4cGVjdCBvbmUgYmFzZWQgaW5kZXggKG1lYW5pbmcgdGhlIGZpcnN0IGl0ZW0gaGFzIGluZGV4IDEpXG4gICAgICAvLyBzaW5jZSBKYXZhc2NyaXB0IGFycmF5IGFyZSB6ZXJvIGJhc2VkIGluZGV4IHdlIGV4cG9zZSB0aGUgYXBpIGFzIHplcm8gYmFzZWRcbiAgICAgIC8vIGFuZCB0cmFuc2Zvcm0gdGhlIGluZGV4IHZhbHVlIGluIHRoZSBhY3R1YWwgcmVxdWVzdCBieSBhZGRpbmcgMVxuICAgICAgcmVxdWVzdCA9IHJlcXVlc3QgKyAxO1xuICAgICAgdGhpcy5fZGVwZW5kZW50UHJvcGVydGllc1twcm9wZXJ0eV0gPSB7IHByb3BlcnR5LCByZXF1ZXN0LCB0YXJnZXRQYXRoIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cbiJdfQ==