"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SetPropertyTool = void 0; const decorators_1 = require("../decorators"); const tools_utils_1 = require("../utils/tools-utils"); const asset_importers_1 = require("../utils/asset-importers"); const schemas_1 = require("../schemas"); class SetPropertyTool { async setCurrentSceneProperties(params) { return await this.setInstanceProperties({ reference: { id: params.settingsType }, propertyPaths: params.propertyPaths, values: params.values }); } async setInstanceProperties(params) { let { reference: { id: uuid }, propertyPaths, values } = params; let info = await tools_utils_1.ToolsUtils.inspectInstance(uuid, false); if (!info) { throw new Error(`Target ${uuid} not found or not supported.`); } uuid = info.uuid; const { type, props, assetInfo } = info; if (!props) { throw new Error(`Could not retrieve properties for ${type} of instance ${uuid}.`); } for (let i = 0; i < propertyPaths.length; i++) { await this.setProperty(info, propertyPaths[i], values[i]); } return { success: true }; } async setProperty({ uuid, type, props, assetInfo }, propertyPath, value) { var _a; // Find property definition in the dump let targetProp = null; try { targetProp = this.findPropertyInDump(props, propertyPath); } catch (e) { throw new Error(`Property '${propertyPath}' resolution failed: ${e.message}. Please recheck TypescriptDefinition of ${uuid}. Arrays are reached by indexes.`); } if (!targetProp) { throw new Error(`Property '${propertyPath}' not found on ${type} of instance ${uuid}.`); } // Normalize value based on property definition value = this.normalizeValue(value, targetProp); if (assetInfo) { try { const success = await ((_a = asset_importers_1.ImporterManager.getInstance().getImporter(assetInfo.importer)) === null || _a === void 0 ? void 0 : _a.setProperty(assetInfo, propertyPath, value)); if (!success) { throw new Error(`Importer failed to set property.`); } } catch (e) { throw new Error(`Failed to set property on Asset ${uuid}: ${e}`); } return; } if (type === 'cc.SceneGlobals') { // Scene Globals are part of the scene node but under _globals propertyPath = `_globals.${propertyPath}`; // uuid is already set to the Scene UUID from inspectInstance } else if (type !== 'cc.Node') { const nodeUuid = props.node.value.uuid; const nodeInfo = await Editor.Message.request('scene', 'query-node', nodeUuid); if (!nodeInfo) { throw new Error(`Parent Node ${nodeUuid} for Component ${uuid} not found.`); } const componentIndex = nodeInfo.__comps__.findIndex((comp) => comp.value.uuid.value === uuid); propertyPath = `__comps__.${componentIndex}.${propertyPath}`; uuid = nodeUuid; } await this.applyValue(uuid, propertyPath, targetProp, value); } normalizeValue(value, prop) { // Try to parse string values into proper types if (typeof value === 'string') { const isStringProp = prop.type === 'String'; if (!isStringProp) { const t = value.trim(); if (t === 'true') return true; if (t === 'false') return false; if (!isNaN(Number(t)) && t !== '') { return Number(t); } if ((t.startsWith('{') || t.startsWith('[')) && (t.endsWith('}') || t.endsWith(']'))) { try { return JSON.parse(t); } catch (e) { } } } } return value; } findPropertyInDump(root, path) { if (!path) return null; if (!root) return null; const parts = path.split('.'); let current = { value: root }; // Wrap to unify traversal // Helper to check if object looks like a property definition const isProperty = (obj) => obj && typeof obj === 'object' && ('type' in obj || 'extends' in obj); for (let i = 0; i < parts.length; i++) { const part = parts[i]; // Current is expected to be an IProperty or object containing IProperty data let val = current.value; // If current is just the dictionary (root), use it directly if (current === root || (typeof current === 'object' && !('value' in current))) { val = current; } if (val === undefined || val === null) return null; // 1. Array Index if (Array.isArray(val)) { const idx = parseInt(part); if (!isNaN(idx)) { // Existing index if (val[idx] !== undefined) { const elem = val[idx]; if (isProperty(elem)) { current = elem; } else if (current.elementTypeData) { // Hydrate from schema current = Object.assign(Object.assign({}, current.elementTypeData), { value: elem }); } else { // Fallback for primitive arrays without schema current = { value: elem, type: 'Unknown' }; } continue; } // Extending array support: Allow index == length if schema exists. // Don't allow gaps (idx > length). if (idx === val.length) { if (current.elementTypeData) { current = current.elementTypeData; continue; } else { throw new Error(`Array extension at '${part}' failed: No elementTypeData.`); } } throw new Error(`Array index '${idx}' out of bounds (length: ${val.length}) at '${part}'.`); } throw new Error(`Invalid array index '${part}' at '${path}'.`); } // 2. Object Key if (typeof val === 'object') { if (part in val) { const propCandidate = val[part]; if (isProperty(propCandidate)) { current = propCandidate; } else { // Not a property, probably a raw value in a struct (like position.x = 0) // Try to find schema in default value if available let schema = null; if (current.default && current.default.value && typeof current.default.value === 'object' && part in current.default.value) { schema = current.default.value[part]; } if (schema) { current = Object.assign(Object.assign({}, schema), { value: propCandidate }); } else { // No schema found, treat as untyped value current = { value: propCandidate, type: 'Unknown' }; } } continue; } throw new Error(`Key '${part}' not found ${i == 0 ? '' : 'in ' + parts.slice(0, i).join('.')}.`); } throw new Error(`Path segment '${part}' '${i == 0 ? '' : 'at ' + parts.slice(0, i).join('.')}' failed resolution.`); } return current; } async applyValue(uuid, path, prop, value) { var _a, _b, _c; // Handle direct references if ((_a = prop.extends) === null || _a === void 0 ? void 0 : _a.includes('cc.Object')) { value = await this.convertObjectReferenceToCocos(value, prop); } // Handle array of references if (Array.isArray(value) && ((_c = (_b = prop.elementTypeData) === null || _b === void 0 ? void 0 : _b.extends) === null || _c === void 0 ? void 0 : _c.includes('cc.Object'))) { const convertedArray = []; value.forEach(async (item, index) => { convertedArray[index] = await this.convertObjectReferenceToCocos(item, prop.elementTypeData); }); value = convertedArray; } const dump = { value, type: prop.type }; await Editor.Message.request('scene', 'set-property', { uuid, path, dump }); await Editor.Message.request('scene', 'snapshot'); } async convertObjectReferenceToCocos(value, prop) { const extendsInfo = prop.extends || []; // Accept plain UUID string or { uuid: string } structure if (typeof value === 'string') { value = { uuid: value }; } // Reference object with id is sent if (typeof value === 'object' && value !== null && 'id' in value) { value = { uuid: value.id }; } // Special case for asset subtype check if (extendsInfo.includes('cc.Asset')) { const assetInfo = await Editor.Message.request('asset-db', 'query-asset-info', value.uuid); if (!assetInfo) { throw new Error(`Asset with id ${value.uuid} not found.`); } let foundSubAsset = false; if (assetInfo.type !== prop.type) { Object.values(assetInfo.subAssets || {}).forEach(subAsset => { if (subAsset.type === prop.type) { value = { uuid: subAsset.uuid }; foundSubAsset = true; } }); } else { foundSubAsset = true; } if (!foundSubAsset && assetInfo.type !== prop.type) { throw new Error(`Reference type mismatch: expected ${prop.type}, got ${assetInfo.type}.`); } } return value; } } exports.SetPropertyTool = SetPropertyTool; __decorate([ (0, decorators_1.utcpTool)("inspectorSetSettingsProperties", "Sets a property on the specific settings. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter.", { type: 'object', properties: { settingsType: { type: 'string', enum: ['CurrentSceneGlobals', 'ProjectSettings'] }, propertyPath: { type: 'string', description: "Plain path to the property (e.g., 'ambient.skyLightingColor.r'). Don't support code execution." }, value: { type: ['array', 'object', 'string', 'number', 'boolean', 'null'], additionalProperties: true } }, required: ['settingsType', 'propertyPath', 'value'] }, schemas_1.SuccessIndicatorSchema, "POST", ['property', 'set', 'scene', 'settings', 'project', 'modify', 'config']) ], SetPropertyTool.prototype, "setCurrentSceneProperties", null); __decorate([ (0, decorators_1.utcpTool)("inspectorSetInstanceProperties", "Sets a property on instance of Node, Component or Asset. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter.", { type: 'object', properties: { reference: schemas_1.InstanceReferenceSchema, propertyPaths: { type: 'array', items: { type: 'string' }, description: "Plain paths to the properties (e.g., ['position.x', 'rotation.y']). Don't support code execution. Arrays are reached by indexes. (e.g. 'sharedMaterials.0')" }, values: { type: 'array', items: { type: ['array', 'object', 'string', 'number', 'boolean', 'null'], additionalProperties: true } } }, required: ['reference', 'propertyPaths', 'values'] }, schemas_1.SuccessIndicatorSchema, "POST", ['property', 'set', 'instance', 'node', 'component', 'asset', 'modify', 'meta']) ], SetPropertyTool.prototype, "setInstanceProperties", null); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0LXByb3BlcnR5LXRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvdXRjcC90b29scy9zZXQtcHJvcGVydHktdG9vbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSw4Q0FBeUM7QUFFekMsc0RBQWtEO0FBQ2xELDhEQUEyRDtBQUUzRCx3Q0FBb0g7QUFJcEgsTUFBYSxlQUFlO0lBY2xCLEFBQU4sS0FBSyxDQUFDLHlCQUF5QixDQUFDLE1BQXdFO1FBQ3BHLE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUM7WUFDcEMsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxZQUFZLEVBQUUsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07U0FDckcsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQWlCSyxBQUFOLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxNQUFpRjtRQUN6RyxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFFaEUsSUFBSSxJQUFJLEdBQUcsTUFBTSx3QkFBVSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1IsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLElBQUksOEJBQThCLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFFakIsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBRXhDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLElBQUksZ0JBQWdCLElBQUksR0FBRyxDQUFDLENBQUM7UUFDdEYsQ0FBQztRQUVELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDNUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUVELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQW9ILEVBQUUsWUFBb0IsRUFBRSxLQUFVOztRQUMxTSx1Q0FBdUM7UUFDdkMsSUFBSSxVQUFVLEdBQXFCLElBQUksQ0FBQztRQUN4QyxJQUFJLENBQUM7WUFDRCxVQUFVLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsYUFBYSxZQUFZLHdCQUF3QixDQUFDLENBQUMsT0FBTyw0Q0FBNEMsSUFBSSxrQ0FBa0MsQ0FBQyxDQUFDO1FBQ2xLLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLGFBQWEsWUFBWSxrQkFBa0IsSUFBSSxnQkFBZ0IsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUM1RixDQUFDO1FBRUQsK0NBQStDO1FBQy9DLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztRQUUvQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDO2dCQUNELE1BQU0sT0FBTyxHQUF3QixNQUFNLENBQUEsTUFBQSxpQ0FBZSxDQUFDLFdBQVcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLDBDQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFBLENBQUM7Z0JBQ3RKLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDWCxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7Z0JBQ3hELENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBQ0QsT0FBTztRQUNYLENBQUM7UUFFRCxJQUFJLElBQUksS0FBSyxpQkFBaUIsRUFBRSxDQUFDO1lBQzdCLDhEQUE4RDtZQUM5RCxZQUFZLEdBQUcsWUFBWSxZQUFZLEVBQUUsQ0FBQztZQUMxQyw2REFBNkQ7UUFDakUsQ0FBQzthQUFNLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sUUFBUSxHQUFJLEtBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztZQUNoRCxNQUFNLFFBQVEsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDL0UsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxRQUFRLGtCQUFrQixJQUFJLGFBQWEsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7WUFDRCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDO1lBQ25HLFlBQVksR0FBRyxhQUFhLGNBQWMsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUM3RCxJQUFJLEdBQUcsUUFBUSxDQUFDO1FBQ3BCLENBQUM7UUFFRCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFVLEVBQUUsSUFBZTtRQUM5QywrQ0FBK0M7UUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM1QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztZQUM1QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLEtBQUssTUFBTTtvQkFBRSxPQUFPLElBQUksQ0FBQztnQkFDOUIsSUFBSSxDQUFDLEtBQUssT0FBTztvQkFBRSxPQUFPLEtBQUssQ0FBQztnQkFFaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUM7b0JBQ2hDLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyQixDQUFDO2dCQUVELElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ25GLElBQUksQ0FBQzt3QkFBQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQUMsQ0FBQztvQkFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDL0MsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVPLGtCQUFrQixDQUFDLElBQThELEVBQUUsSUFBWTtRQUNuRyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFdkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUU5QixJQUFJLE9BQU8sR0FBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLDBCQUEwQjtRQUU5RCw2REFBNkQ7UUFDN0QsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUV2RyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV0Qiw2RUFBNkU7WUFDN0UsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztZQUN4Qiw0REFBNEQ7WUFDNUQsSUFBSSxPQUFPLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM3RSxHQUFHLEdBQUcsT0FBTyxDQUFDO1lBQ2xCLENBQUM7WUFFRCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLElBQUk7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFFbkQsaUJBQWlCO1lBQ2pCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNyQixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDZCxpQkFBaUI7b0JBQ2pCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsRUFBRSxDQUFDO3dCQUN6QixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQ3RCLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7NEJBQ25CLE9BQU8sR0FBRyxJQUFJLENBQUM7d0JBQ25CLENBQUM7NkJBQU0sSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7NEJBQ2pDLHNCQUFzQjs0QkFDdEIsT0FBTyxtQ0FBUSxPQUFPLENBQUMsZUFBZSxLQUFFLEtBQUssRUFBRSxJQUFJLEdBQUUsQ0FBQzt3QkFDMUQsQ0FBQzs2QkFBTSxDQUFDOzRCQUNKLCtDQUErQzs0QkFDL0MsT0FBTyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUM7d0JBQy9DLENBQUM7d0JBQ0QsU0FBUztvQkFDYixDQUFDO29CQUNELG1FQUFtRTtvQkFDbkUsbUNBQW1DO29CQUNuQyxJQUFJLEdBQUcsS0FBSyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7d0JBQ3JCLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDOzRCQUMxQixPQUFPLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQzs0QkFDbEMsU0FBUzt3QkFDYixDQUFDOzZCQUFNLENBQUM7NEJBQ0osTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsSUFBSSwrQkFBK0IsQ0FBQyxDQUFDO3dCQUNoRixDQUFDO29CQUNMLENBQUM7b0JBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyw0QkFBNEIsR0FBRyxDQUFDLE1BQU0sU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDO2dCQUNoRyxDQUFDO2dCQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLElBQUksU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFFRCxnQkFBZ0I7WUFDaEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7b0JBQ2QsTUFBTSxhQUFhLEdBQUcsR0FBRyxDQUFDLElBQXdCLENBQUMsQ0FBQztvQkFDcEQsSUFBSSxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzt3QkFDNUIsT0FBTyxHQUFHLGFBQWEsQ0FBQztvQkFDNUIsQ0FBQzt5QkFBTSxDQUFDO3dCQUNKLHlFQUF5RTt3QkFDekUsbURBQW1EO3dCQUNuRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUM7d0JBQ2xCLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxJQUFJLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFDekgsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN6QyxDQUFDO3dCQUVELElBQUksTUFBTSxFQUFFLENBQUM7NEJBQ1QsT0FBTyxtQ0FBUSxNQUFNLEtBQUUsS0FBSyxFQUFFLGFBQWEsR0FBRSxDQUFDO3dCQUNsRCxDQUFDOzZCQUFNLENBQUM7NEJBQ0osMENBQTBDOzRCQUMxQyxPQUFPLEdBQUcsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQzt3QkFDeEQsQ0FBQztvQkFDTCxDQUFDO29CQUNELFNBQVM7Z0JBQ2IsQ0FBQztnQkFDRCxNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckcsQ0FBQztZQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDeEgsQ0FBQztRQUVELE9BQU8sT0FBb0IsQ0FBQztJQUNoQyxDQUFDO0lBRU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFFLElBQWUsRUFBRSxLQUFVOztRQUM1RSwyQkFBMkI7UUFDM0IsSUFBSSxNQUFBLElBQUksQ0FBQyxPQUFPLDBDQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3RDLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUVELDZCQUE2QjtRQUM3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUksTUFBQSxNQUFBLElBQUksQ0FBQyxlQUFlLDBDQUFFLE9BQU8sMENBQUUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFBLEVBQUUsQ0FBQztZQUMvRSxNQUFNLGNBQWMsR0FBVSxFQUFFLENBQUM7WUFDakMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUNoQyxjQUFjLENBQUMsS0FBSyxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsNkJBQTZCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFnQixDQUFDLENBQUM7WUFDbEcsQ0FBQyxDQUFDLENBQUM7WUFDSCxLQUFLLEdBQUcsY0FBYyxDQUFDO1FBQzNCLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBRXhDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLGNBQWMsRUFBRTtZQUNsRCxJQUFJO1lBQ0osSUFBSTtZQUNKLElBQUk7U0FDUCxDQUFDLENBQUM7UUFFSCxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU8sS0FBSyxDQUFDLDZCQUE2QixDQUFDLEtBQVUsRUFBRSxJQUFlO1FBQ25FLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO1FBRXZDLHlEQUF5RDtRQUN6RCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzVCLEtBQUssR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM1QixDQUFDO1FBRUQsbUNBQW1DO1FBQ25DLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQy9ELEtBQUssR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDL0IsQ0FBQztRQUVELHVDQUF1QztRQUN2QyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFNBQVMsR0FBcUIsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDYixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixLQUFLLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQztZQUM5RCxDQUFDO1lBQ0QsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzFCLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQy9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7b0JBQ3hELElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7d0JBQzlCLEtBQUssR0FBRyxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7d0JBQ2hDLGFBQWEsR0FBRyxJQUFJLENBQUM7b0JBQ3pCLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osYUFBYSxHQUFHLElBQUksQ0FBQztZQUN6QixDQUFDO1lBRUQsSUFBSSxDQUFDLGFBQWEsSUFBSSxTQUFTLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDakQsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsSUFBSSxDQUFDLElBQUksU0FBUyxTQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztZQUM5RixDQUFDO1FBQ0wsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7Q0FDSjtBQXBSRCwwQ0FvUkM7QUF0UVM7SUFiTCxJQUFBLHFCQUFRLEVBQ0wsZ0NBQWdDLEVBQ2hDLDhJQUE4SSxFQUM5SSxFQUFFLElBQUksRUFBRSxRQUFRO1FBQ1osVUFBVSxFQUFFO1lBQ1IsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFO1lBQ2xGLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLGdHQUFnRyxFQUFFO1lBQy9JLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFO1NBQzFHO1FBQ0QsUUFBUSxFQUFFLENBQUMsY0FBYyxFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUM7S0FDdEQsRUFDRCxnQ0FBc0IsRUFBRSxNQUFNLEVBQUUsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FDMUc7Z0VBS0E7QUFpQks7SUFkTCxJQUFBLHFCQUFRLEVBQ0wsZ0NBQWdDLEVBQ2hDLDZKQUE2SixFQUM3SjtRQUNJLElBQUksRUFBRSxRQUFRO1FBQ2QsVUFBVSxFQUFFO1lBQ1IsU0FBUyxFQUFFLGlDQUF1QjtZQUNsQyxhQUFhLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxXQUFXLEVBQUUsNkpBQTZKLEVBQUU7WUFDdk8sTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxFQUFFO1NBQ3JJO1FBQ0QsUUFBUSxFQUFFLENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxRQUFRLENBQUM7S0FDckQsRUFDRCxnQ0FBc0IsRUFBRSxNQUFNLEVBQUUsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQ2xIOzREQXNCQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHV0Y3BUb29sIH0gZnJvbSAnLi4vZGVjb3JhdG9ycyc7XG5pbXBvcnQgeyBJUHJvcGVydHksIElQcm9wZXJ0eVZhbHVlVHlwZSB9IGZyb20gJ0Bjb2Nvcy9jcmVhdG9yLXR5cGVzL2VkaXRvci9wYWNrYWdlcy9zY2VuZS9AdHlwZXMvcHVibGljJztcbmltcG9ydCB7IFRvb2xzVXRpbHMgfSBmcm9tICcuLi91dGlscy90b29scy11dGlscyc7XG5pbXBvcnQgeyBJbXBvcnRlck1hbmFnZXIgfSBmcm9tICcuLi91dGlscy9hc3NldC1pbXBvcnRlcnMnO1xuaW1wb3J0IHsgQXNzZXRJbmZvIH0gZnJvbSAnQGNvY29zL2NyZWF0b3ItdHlwZXMvZWRpdG9yL3BhY2thZ2VzL2Fzc2V0LWRiL0B0eXBlcy9wdWJsaWMnO1xuaW1wb3J0IHsgSUluc3RhbmNlUmVmZXJlbmNlLCBJbnN0YW5jZVJlZmVyZW5jZVNjaGVtYSwgSVN1Y2Nlc3NJbmRpY2F0b3IsIFN1Y2Nlc3NJbmRpY2F0b3JTY2hlbWEgfSBmcm9tICcuLi9zY2hlbWFzJztcblxuZGVjbGFyZSBjb25zdCBFZGl0b3I6IGFueTtcblxuZXhwb3J0IGNsYXNzIFNldFByb3BlcnR5VG9vbCB7XG4gICAgQHV0Y3BUb29sKFxuICAgICAgICBcImluc3BlY3RvclNldFNldHRpbmdzUHJvcGVydGllc1wiLFxuICAgICAgICBcIlNldHMgYSBwcm9wZXJ0eSBvbiB0aGUgc3BlY2lmaWMgc2V0dGluZ3MuIElmIGEgcHJvcGVydHkgcGF0aCBvciB0eXBlIGlzIG5vdCBjb25maXJtZWQgdmlhIGluc3BlY3RvckdldCogdG9vbHMsIHlvdSBNVVNUIE5PVCBjYWxsIGFueSBzZXR0ZXIuXCIsXG4gICAgICAgIHsgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgc2V0dGluZ3NUeXBlOiB7IHR5cGU6ICdzdHJpbmcnLCBlbnVtOiBbJ0N1cnJlbnRTY2VuZUdsb2JhbHMnLCAnUHJvamVjdFNldHRpbmdzJ10gfSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eVBhdGg6IHsgdHlwZTogJ3N0cmluZycsIGRlc2NyaXB0aW9uOiBcIlBsYWluIHBhdGggdG8gdGhlIHByb3BlcnR5IChlLmcuLCAnYW1iaWVudC5za3lMaWdodGluZ0NvbG9yLnInKS4gRG9uJ3Qgc3VwcG9ydCBjb2RlIGV4ZWN1dGlvbi5cIiB9LFxuICAgICAgICAgICAgICAgIHZhbHVlOiB7IHR5cGU6IFsnYXJyYXknLCAnb2JqZWN0JywgJ3N0cmluZycsICdudW1iZXInLCAnYm9vbGVhbicsICdudWxsJ10sIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB0cnVlIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXF1aXJlZDogWydzZXR0aW5nc1R5cGUnLCAncHJvcGVydHlQYXRoJywgJ3ZhbHVlJ11cbiAgICAgICAgfSxcbiAgICAgICAgU3VjY2Vzc0luZGljYXRvclNjaGVtYSwgXCJQT1NUXCIsIFsncHJvcGVydHknLCAnc2V0JywgJ3NjZW5lJywgJ3NldHRpbmdzJywgJ3Byb2plY3QnLCAnbW9kaWZ5JywgJ2NvbmZpZyddXG4gICAgKVxuICAgIGFzeW5jIHNldEN1cnJlbnRTY2VuZVByb3BlcnRpZXMocGFyYW1zOiB7IHNldHRpbmdzVHlwZTogc3RyaW5nLCBwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXSwgdmFsdWVzOiBhbnlbXSB9KTogUHJvbWlzZTxJU3VjY2Vzc0luZGljYXRvcj4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZXRJbnN0YW5jZVByb3BlcnRpZXMoe1xuICAgICAgICAgICAgcmVmZXJlbmNlOiB7IGlkOiBwYXJhbXMuc2V0dGluZ3NUeXBlIH0sIHByb3BlcnR5UGF0aHM6IHBhcmFtcy5wcm9wZXJ0eVBhdGhzLCB2YWx1ZXM6IHBhcmFtcy52YWx1ZXNcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICBAdXRjcFRvb2woXG4gICAgICAgIFwiaW5zcGVjdG9yU2V0SW5zdGFuY2VQcm9wZXJ0aWVzXCIsXG4gICAgICAgIFwiU2V0cyBhIHByb3BlcnR5IG9uIGluc3RhbmNlIG9mIE5vZGUsIENvbXBvbmVudCBvciBBc3NldC4gSWYgYSBwcm9wZXJ0eSBwYXRoIG9yIHR5cGUgaXMgbm90IGNvbmZpcm1lZCB2aWEgaW5zcGVjdG9yR2V0KiB0b29scywgeW91IE1VU1QgTk9UIGNhbGwgYW55IHNldHRlci5cIixcbiAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgcmVmZXJlbmNlOiBJbnN0YW5jZVJlZmVyZW5jZVNjaGVtYSxcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eVBhdGhzOiB7IHR5cGU6ICdhcnJheScsIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0sIGRlc2NyaXB0aW9uOiBcIlBsYWluIHBhdGhzIHRvIHRoZSBwcm9wZXJ0aWVzIChlLmcuLCBbJ3Bvc2l0aW9uLngnLCAncm90YXRpb24ueSddKS4gRG9uJ3Qgc3VwcG9ydCBjb2RlIGV4ZWN1dGlvbi4gQXJyYXlzIGFyZSByZWFjaGVkIGJ5IGluZGV4ZXMuIChlLmcuICdzaGFyZWRNYXRlcmlhbHMuMCcpXCIgfSxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IHsgdHlwZTogJ2FycmF5JywgaXRlbXM6IHsgdHlwZTogWydhcnJheScsICdvYmplY3QnLCAnc3RyaW5nJywgJ251bWJlcicsICdib29sZWFuJywgJ251bGwnXSwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHRydWUgfSB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWlyZWQ6IFsncmVmZXJlbmNlJywgJ3Byb3BlcnR5UGF0aHMnLCAndmFsdWVzJ11cbiAgICAgICAgfSxcbiAgICAgICAgU3VjY2Vzc0luZGljYXRvclNjaGVtYSwgXCJQT1NUXCIsIFsncHJvcGVydHknLCAnc2V0JywgJ2luc3RhbmNlJywgJ25vZGUnLCAnY29tcG9uZW50JywgJ2Fzc2V0JywgJ21vZGlmeScsICdtZXRhJ11cbiAgICApXG4gICAgYXN5bmMgc2V0SW5zdGFuY2VQcm9wZXJ0aWVzKHBhcmFtczogeyByZWZlcmVuY2U6IElJbnN0YW5jZVJlZmVyZW5jZSwgcHJvcGVydHlQYXRoczogc3RyaW5nW10sIHZhbHVlczogYW55W10gfSk6IFByb21pc2U8SVN1Y2Nlc3NJbmRpY2F0b3I+IHtcbiAgICAgICAgbGV0IHsgcmVmZXJlbmNlOiB7IGlkOiB1dWlkIH0sIHByb3BlcnR5UGF0aHMsIHZhbHVlcyB9ID0gcGFyYW1zO1xuXG4gICAgICAgIGxldCBpbmZvID0gYXdhaXQgVG9vbHNVdGlscy5pbnNwZWN0SW5zdGFuY2UodXVpZCwgZmFsc2UpO1xuICAgICAgICBpZiAoIWluZm8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGFyZ2V0ICR7dXVpZH0gbm90IGZvdW5kIG9yIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgICAgIH1cblxuICAgICAgICB1dWlkID0gaW5mby51dWlkO1xuXG4gICAgICAgIGNvbnN0IHsgdHlwZSwgcHJvcHMsIGFzc2V0SW5mbyB9ID0gaW5mbztcblxuICAgICAgICBpZiAoIXByb3BzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCByZXRyaWV2ZSBwcm9wZXJ0aWVzIGZvciAke3R5cGV9IG9mIGluc3RhbmNlICR7dXVpZH0uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3BlcnR5UGF0aHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2V0UHJvcGVydHkoaW5mbywgcHJvcGVydHlQYXRoc1tpXSwgdmFsdWVzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNldFByb3BlcnR5KHsgdXVpZCwgdHlwZSwgcHJvcHMsIGFzc2V0SW5mbyB9OiB7IHV1aWQ6IHN0cmluZywgdHlwZTogc3RyaW5nLCBwcm9wczogeyBba2V5OiBzdHJpbmddOiBJUHJvcGVydHlWYWx1ZVR5cGUgfSB8IG51bGwsIGFzc2V0SW5mbzogQXNzZXRJbmZvIHwgbnVsbCB9LCBwcm9wZXJ0eVBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAvLyBGaW5kIHByb3BlcnR5IGRlZmluaXRpb24gaW4gdGhlIGR1bXBcbiAgICAgICAgbGV0IHRhcmdldFByb3A6IElQcm9wZXJ0eSB8IG51bGwgPSBudWxsO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGFyZ2V0UHJvcCA9IHRoaXMuZmluZFByb3BlcnR5SW5EdW1wKHByb3BzLCBwcm9wZXJ0eVBhdGgpO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvcGVydHkgJyR7cHJvcGVydHlQYXRofScgcmVzb2x1dGlvbiBmYWlsZWQ6ICR7ZS5tZXNzYWdlfS4gUGxlYXNlIHJlY2hlY2sgVHlwZXNjcmlwdERlZmluaXRpb24gb2YgJHt1dWlkfS4gQXJyYXlzIGFyZSByZWFjaGVkIGJ5IGluZGV4ZXMuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRhcmdldFByb3ApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvcGVydHkgJyR7cHJvcGVydHlQYXRofScgbm90IGZvdW5kIG9uICR7dHlwZX0gb2YgaW5zdGFuY2UgJHt1dWlkfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSB2YWx1ZSBiYXNlZCBvbiBwcm9wZXJ0eSBkZWZpbml0aW9uXG4gICAgICAgIHZhbHVlID0gdGhpcy5ub3JtYWxpemVWYWx1ZSh2YWx1ZSwgdGFyZ2V0UHJvcCk7XG5cbiAgICAgICAgaWYgKGFzc2V0SW5mbykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdWNjZXNzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gYXdhaXQgSW1wb3J0ZXJNYW5hZ2VyLmdldEluc3RhbmNlKCkuZ2V0SW1wb3J0ZXIoYXNzZXRJbmZvLmltcG9ydGVyKT8uc2V0UHJvcGVydHkoYXNzZXRJbmZvLCBwcm9wZXJ0eVBhdGgsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBpZiAoIXN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbXBvcnRlciBmYWlsZWQgdG8gc2V0IHByb3BlcnR5LmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBzZXQgcHJvcGVydHkgb24gQXNzZXQgJHt1dWlkfTogJHtlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdjYy5TY2VuZUdsb2JhbHMnKSB7XG4gICAgICAgICAgICAvLyBTY2VuZSBHbG9iYWxzIGFyZSBwYXJ0IG9mIHRoZSBzY2VuZSBub2RlIGJ1dCB1bmRlciBfZ2xvYmFsc1xuICAgICAgICAgICAgcHJvcGVydHlQYXRoID0gYF9nbG9iYWxzLiR7cHJvcGVydHlQYXRofWA7XG4gICAgICAgICAgICAvLyB1dWlkIGlzIGFscmVhZHkgc2V0IHRvIHRoZSBTY2VuZSBVVUlEIGZyb20gaW5zcGVjdEluc3RhbmNlXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSAhPT0gJ2NjLk5vZGUnKSB7XG4gICAgICAgICAgICBjb25zdCBub2RlVXVpZCA9IChwcm9wcyBhcyBhbnkpLm5vZGUudmFsdWUudXVpZDtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVJbmZvID0gYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdCgnc2NlbmUnLCAncXVlcnktbm9kZScsIG5vZGVVdWlkKTtcbiAgICAgICAgICAgIGlmICghbm9kZUluZm8pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhcmVudCBOb2RlICR7bm9kZVV1aWR9IGZvciBDb21wb25lbnQgJHt1dWlkfSBub3QgZm91bmQuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnRJbmRleCA9IG5vZGVJbmZvLl9fY29tcHNfXy5maW5kSW5kZXgoKGNvbXA6IGFueSkgPT4gY29tcC52YWx1ZS51dWlkLnZhbHVlID09PSB1dWlkKTtcbiAgICAgICAgICAgIHByb3BlcnR5UGF0aCA9IGBfX2NvbXBzX18uJHtjb21wb25lbnRJbmRleH0uJHtwcm9wZXJ0eVBhdGh9YDtcbiAgICAgICAgICAgIHV1aWQgPSBub2RlVXVpZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlWYWx1ZSh1dWlkLCBwcm9wZXJ0eVBhdGgsIHRhcmdldFByb3AsIHZhbHVlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG5vcm1hbGl6ZVZhbHVlKHZhbHVlOiBhbnksIHByb3A6IElQcm9wZXJ0eSk6IGFueSB7XG4gICAgICAgIC8vIFRyeSB0byBwYXJzZSBzdHJpbmcgdmFsdWVzIGludG8gcHJvcGVyIHR5cGVzXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBpc1N0cmluZ1Byb3AgPSBwcm9wLnR5cGUgPT09ICdTdHJpbmcnO1xuICAgICAgICAgICAgaWYgKCFpc1N0cmluZ1Byb3ApIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ID0gdmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgICAgIGlmICh0ID09PSAndHJ1ZScpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICh0ID09PSAnZmFsc2UnKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKE51bWJlcih0KSkgJiYgdCAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoKHQuc3RhcnRzV2l0aCgneycpIHx8IHQuc3RhcnRzV2l0aCgnWycpKSAmJiAodC5lbmRzV2l0aCgnfScpIHx8IHQuZW5kc1dpdGgoJ10nKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgcmV0dXJuIEpTT04ucGFyc2UodCk7IH0gY2F0Y2ggKGUpIHsgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaW5kUHJvcGVydHlJbkR1bXAocm9vdDogeyBba2V5OiBzdHJpbmddOiBJUHJvcGVydHlWYWx1ZVR5cGUgfSB8IEFzc2V0SW5mbyB8IG51bGwsIHBhdGg6IHN0cmluZyk6IElQcm9wZXJ0eSB8IG51bGwge1xuICAgICAgICBpZiAoIXBhdGgpIHJldHVybiBudWxsO1xuICAgICAgICBpZiAoIXJvb3QpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdCgnLicpO1xuXG4gICAgICAgIGxldCBjdXJyZW50OiBhbnkgPSB7IHZhbHVlOiByb290IH07IC8vIFdyYXAgdG8gdW5pZnkgdHJhdmVyc2FsXG5cbiAgICAgICAgLy8gSGVscGVyIHRvIGNoZWNrIGlmIG9iamVjdCBsb29rcyBsaWtlIGEgcHJvcGVydHkgZGVmaW5pdGlvblxuICAgICAgICBjb25zdCBpc1Byb3BlcnR5ID0gKG9iajogYW55KSA9PiBvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgKCd0eXBlJyBpbiBvYmogfHwgJ2V4dGVuZHMnIGluIG9iaik7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgcGFydCA9IHBhcnRzW2ldO1xuXG4gICAgICAgICAgICAvLyBDdXJyZW50IGlzIGV4cGVjdGVkIHRvIGJlIGFuIElQcm9wZXJ0eSBvciBvYmplY3QgY29udGFpbmluZyBJUHJvcGVydHkgZGF0YVxuICAgICAgICAgICAgbGV0IHZhbCA9IGN1cnJlbnQudmFsdWU7XG4gICAgICAgICAgICAvLyBJZiBjdXJyZW50IGlzIGp1c3QgdGhlIGRpY3Rpb25hcnkgKHJvb3QpLCB1c2UgaXQgZGlyZWN0bHlcbiAgICAgICAgICAgIGlmIChjdXJyZW50ID09PSByb290IHx8ICh0eXBlb2YgY3VycmVudCA9PT0gJ29iamVjdCcgJiYgISgndmFsdWUnIGluIGN1cnJlbnQpKSkge1xuICAgICAgICAgICAgICAgIHZhbCA9IGN1cnJlbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPT09IG51bGwpIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAvLyAxLiBBcnJheSBJbmRleFxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9IHBhcnNlSW50KHBhcnQpO1xuICAgICAgICAgICAgICAgIGlmICghaXNOYU4oaWR4KSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBFeGlzdGluZyBpbmRleFxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsW2lkeF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbSA9IHZhbFtpZHhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzUHJvcGVydHkoZWxlbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gZWxlbTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5lbGVtZW50VHlwZURhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIeWRyYXRlIGZyb20gc2NoZW1hXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHsgLi4uY3VycmVudC5lbGVtZW50VHlwZURhdGEsIHZhbHVlOiBlbGVtIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZhbGxiYWNrIGZvciBwcmltaXRpdmUgYXJyYXlzIHdpdGhvdXQgc2NoZW1hXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHsgdmFsdWU6IGVsZW0sIHR5cGU6ICdVbmtub3duJyB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gRXh0ZW5kaW5nIGFycmF5IHN1cHBvcnQ6IEFsbG93IGluZGV4ID09IGxlbmd0aCBpZiBzY2hlbWEgZXhpc3RzLlxuICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBhbGxvdyBnYXBzIChpZHggPiBsZW5ndGgpLlxuICAgICAgICAgICAgICAgICAgICBpZiAoaWR4ID09PSB2YWwubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudC5lbGVtZW50VHlwZURhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5lbGVtZW50VHlwZURhdGE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQXJyYXkgZXh0ZW5zaW9uIGF0ICcke3BhcnR9JyBmYWlsZWQ6IE5vIGVsZW1lbnRUeXBlRGF0YS5gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFycmF5IGluZGV4ICcke2lkeH0nIG91dCBvZiBib3VuZHMgKGxlbmd0aDogJHt2YWwubGVuZ3RofSkgYXQgJyR7cGFydH0nLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJyYXkgaW5kZXggJyR7cGFydH0nIGF0ICcke3BhdGh9Jy5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gMi4gT2JqZWN0IEtleVxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnQgaW4gdmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb3BDYW5kaWRhdGUgPSB2YWxbcGFydCBhcyBrZXlvZiB0eXBlb2YgdmFsXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUHJvcGVydHkocHJvcENhbmRpZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBwcm9wQ2FuZGlkYXRlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90IGEgcHJvcGVydHksIHByb2JhYmx5IGEgcmF3IHZhbHVlIGluIGEgc3RydWN0IChsaWtlIHBvc2l0aW9uLnggPSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgc2NoZW1hIGluIGRlZmF1bHQgdmFsdWUgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc2NoZW1hID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LmRlZmF1bHQgJiYgY3VycmVudC5kZWZhdWx0LnZhbHVlICYmIHR5cGVvZiBjdXJyZW50LmRlZmF1bHQudmFsdWUgPT09ICdvYmplY3QnICYmIHBhcnQgaW4gY3VycmVudC5kZWZhdWx0LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hID0gY3VycmVudC5kZWZhdWx0LnZhbHVlW3BhcnRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHsgLi4uc2NoZW1hLCB2YWx1ZTogcHJvcENhbmRpZGF0ZSB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBObyBzY2hlbWEgZm91bmQsIHRyZWF0IGFzIHVudHlwZWQgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0geyB2YWx1ZTogcHJvcENhbmRpZGF0ZSwgdHlwZTogJ1Vua25vd24nIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgS2V5ICcke3BhcnR9JyBub3QgZm91bmQgJHtpID09IDAgPyAnJyA6ICdpbiAnICsgcGFydHMuc2xpY2UoMCwgaSkuam9pbignLicpfS5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYXRoIHNlZ21lbnQgJyR7cGFydH0nICcke2kgPT0gMCA/ICcnIDogJ2F0ICcgKyBwYXJ0cy5zbGljZSgwLCBpKS5qb2luKCcuJyl9JyBmYWlsZWQgcmVzb2x1dGlvbi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjdXJyZW50IGFzIElQcm9wZXJ0eTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFwcGx5VmFsdWUodXVpZDogc3RyaW5nLCBwYXRoOiBzdHJpbmcsIHByb3A6IElQcm9wZXJ0eSwgdmFsdWU6IGFueSkge1xuICAgICAgICAvLyBIYW5kbGUgZGlyZWN0IHJlZmVyZW5jZXNcbiAgICAgICAgaWYgKHByb3AuZXh0ZW5kcz8uaW5jbHVkZXMoJ2NjLk9iamVjdCcpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGF3YWl0IHRoaXMuY29udmVydE9iamVjdFJlZmVyZW5jZVRvQ29jb3ModmFsdWUsIHByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGFycmF5IG9mIHJlZmVyZW5jZXNcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHByb3AuZWxlbWVudFR5cGVEYXRhPy5leHRlbmRzPy5pbmNsdWRlcygnY2MuT2JqZWN0JykpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlZEFycmF5OiBhbnlbXSA9IFtdO1xuICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChhc3luYyAoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRBcnJheVtpbmRleF0gPSBhd2FpdCB0aGlzLmNvbnZlcnRPYmplY3RSZWZlcmVuY2VUb0NvY29zKGl0ZW0sIHByb3AuZWxlbWVudFR5cGVEYXRhISk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhbHVlID0gY29udmVydGVkQXJyYXk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkdW1wID0geyB2YWx1ZSwgdHlwZTogcHJvcC50eXBlIH07XG5cbiAgICAgICAgYXdhaXQgRWRpdG9yLk1lc3NhZ2UucmVxdWVzdCgnc2NlbmUnLCAnc2V0LXByb3BlcnR5Jywge1xuICAgICAgICAgICAgdXVpZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBkdW1wXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IEVkaXRvci5NZXNzYWdlLnJlcXVlc3QoJ3NjZW5lJywgJ3NuYXBzaG90Jyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjb252ZXJ0T2JqZWN0UmVmZXJlbmNlVG9Db2Nvcyh2YWx1ZTogYW55LCBwcm9wOiBJUHJvcGVydHkpOiBQcm9taXNlPHsgdXVpZDogc3RyaW5nIH0+IHtcbiAgICAgICAgY29uc3QgZXh0ZW5kc0luZm8gPSBwcm9wLmV4dGVuZHMgfHwgW107XG5cbiAgICAgICAgLy8gQWNjZXB0IHBsYWluIFVVSUQgc3RyaW5nIG9yIHsgdXVpZDogc3RyaW5nIH0gc3RydWN0dXJlXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHsgdXVpZDogdmFsdWUgfTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gUmVmZXJlbmNlIG9iamVjdCB3aXRoIGlkIGlzIHNlbnRcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgJ2lkJyBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgdmFsdWUgPSB7IHV1aWQ6IHZhbHVlLmlkIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIGFzc2V0IHN1YnR5cGUgY2hlY2tcbiAgICAgICAgaWYgKGV4dGVuZHNJbmZvLmluY2x1ZGVzKCdjYy5Bc3NldCcpKSB7XG4gICAgICAgICAgICBjb25zdCBhc3NldEluZm86IEFzc2V0SW5mbyB8IG51bGwgPSBhd2FpdCBFZGl0b3IuTWVzc2FnZS5yZXF1ZXN0KCdhc3NldC1kYicsICdxdWVyeS1hc3NldC1pbmZvJywgdmFsdWUudXVpZCk7XG4gICAgICAgICAgICBpZiAoIWFzc2V0SW5mbykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQXNzZXQgd2l0aCBpZCAke3ZhbHVlLnV1aWR9IG5vdCBmb3VuZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBmb3VuZFN1YkFzc2V0ID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoYXNzZXRJbmZvLnR5cGUgIT09IHByb3AudHlwZSkge1xuICAgICAgICAgICAgICAgIE9iamVjdC52YWx1ZXMoYXNzZXRJbmZvLnN1YkFzc2V0cyB8fCB7fSkuZm9yRWFjaChzdWJBc3NldCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdWJBc3NldC50eXBlID09PSBwcm9wLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0geyB1dWlkOiBzdWJBc3NldC51dWlkIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZFN1YkFzc2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3VuZFN1YkFzc2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFmb3VuZFN1YkFzc2V0ICYmIGFzc2V0SW5mby50eXBlICE9PSBwcm9wLnR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlZmVyZW5jZSB0eXBlIG1pc21hdGNoOiBleHBlY3RlZCAke3Byb3AudHlwZX0sIGdvdCAke2Fzc2V0SW5mby50eXBlfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuIl19