UNPKG

@tripsnek/tmf

Version:

TypeScript Modeling Framework - A TypeScript port of the Eclipse Modeling Framework (EMF)

425 lines 53.8 kB
import { v4 as uuid } from 'uuid'; import { EcorePackage } from './metamodel/ecorepackage.js'; import { TJson } from './json/tjson.js'; import { EEnumImpl } from './metamodel/impl/eenum-impl.js'; import { EDataTypeImpl } from './metamodel/impl/edata-type-impl.js'; import { EClassImpl } from './metamodel/impl/eclass-impl.js'; /** * Various utilities for interacting with TMF-modeled data objects, some * of which are relied upon by core TMF components (e.g. TJson) and generated * source code. */ export class TUtils { //All primitive EDataTypes supported by TMF static PRIMITIVES = [ 'EString', 'EBoolean', 'EDouble', 'EDoubleObject', 'EFloat', 'EFloatObject', 'EInt', 'EIntegerObject', 'EDate', ]; /** * Ensures all objects have IDs. * @param obj */ static generateIdsForAllContained(obj) { for (const e of obj.eAllContents()) this.genIdIfNotExists(e); } /** * Sets an ID for the given object on it's ID EAttribute. If * an ID is already specified, does nothing. * * @param obj */ static genIdIfNotExists(obj) { //TODO: Support IDs other than string uuids if (obj && obj.eClass().getEIDAttribute() && !obj.fullId()) { obj.eSet(obj.eClass().getEIDAttribute(), uuid()); } } /** * If an ID is specified on the object, returns a new TId instance with that ID value. If not, a * new ID is assigned and that TId returned. * * @param obj */ static getOrCreateIdForObject(obj) { this.genIdIfNotExists(obj); return obj.fullId(); } /** * Gets the Typescript name for a given EClassifier, including * translation of primitive EDataType names (e.g. EBoolean -> boolean). * @param type */ static getTypescriptName(type) { if (!type) return 'null'; let typeStr = type.getName(); if (!(type instanceof EEnumImpl) && type instanceof EDataTypeImpl) typeStr = TUtils.toTypeScriptPrimitive(type); return typeStr; } /** * Gets the TypeScript primitive type for a given TMF EClassifier that represents a * primitive type. * @param classifier */ static toTypeScriptPrimitive(classifier) { if (!classifier || !classifier.getName()) return 'any'; switch (classifier.getName().toLowerCase()) { case 'estring': { return 'string'; break; } case 'eboolean': { return 'boolean'; break; } case 'edouble': { return 'number'; break; } case 'edoubleobject': { return 'number'; break; } case 'efloat': { return 'number'; break; } case 'efloatobject': { return 'number'; break; } case 'eint': { return 'number'; break; } case 'eintegerobject': { return 'number'; break; } case 'edate': { return 'Date'; break; } case 'earray': { return '[]'; } default: { return 'any'; } } } static lookupNamedField(object, fieldName) { const curClass = object.eClass(); const field = curClass.getEStructuralFeature(fieldName); if (!field) { console.log(curClass.getName(), ' has no field named', fieldName); return undefined; } return field; } static getNamedFieldValue(object, fieldName) { const field = this.lookupNamedField(object, fieldName); if (field) return object.eGet(field); return undefined; } static setNamedFieldValue(object, fieldName, newValue) { const field = this.lookupNamedField(object, fieldName); if (field) object.eSet(field, newValue); return undefined; } /** * Parses a value for an EAttribute from it's JSON representation. * * @param attr * @param jsonVal */ static parseAttrValFromString(attr, stringVal) { return this.parseValueFromString(attr.getEType(), stringVal + ''); } static parseValueFromString(attrType, stringVal) { let tVal = null; //if an empty string was set for the field, just return null if (!stringVal || (stringVal.toString().trim() === '' && attrType !== EcorePackage.Literals.E_STRING)) { return null; } if (attrType === EcorePackage.Literals.E_STRING) { tVal = stringVal.toString(); } else if (attrType === EcorePackage.Literals.E_DOUBLE || attrType === EcorePackage.Literals.E_DOUBLE_OBJECT) { tVal = Number.parseFloat(stringVal.toString()); } else if (attrType === EcorePackage.Literals.E_FLOAT || attrType === EcorePackage.Literals.E_FLOAT_OBJECT) { tVal = Number.parseFloat(stringVal.toString()); } else if (attrType === EcorePackage.Literals.E_BOOLEAN || attrType === EcorePackage.Literals.E_BOOLEAN_OBJECT) { tVal = stringVal.toString() === 'true'; } else if (attrType === EcorePackage.Literals.E_SHORT || attrType === EcorePackage.Literals.E_SHORT_OBJECT) { tVal = Number.parseInt(stringVal.toString(), 10); } else if (attrType === EcorePackage.Literals.E_INT || attrType === EcorePackage.Literals.E_INTEGER_OBJECT) { tVal = Number.parseInt(stringVal.toString(), 10); } else if (attrType === EcorePackage.Literals.E_LONG || attrType === EcorePackage.Literals.E_LONG_OBJECT) { tVal = Number.parseInt(stringVal.toString(), 10); } else if (attrType === EcorePackage.Literals.E_DATE) { tVal = new Date(Date.parse(stringVal)); } else if (attrType instanceof EEnumImpl) { const eenum = attrType; const literal = eenum.getEEnumLiteral(stringVal.toString()); if (literal != null) { tVal = literal.getLiteral(); } else { console.warn('Could not parse literal value ' + stringVal.toString() + ' for ' + eenum.getName()); } } return tVal; } /** * Creates a deep copy of an Root and it's containment hierarchy, with optional * lists for specifying specific EReferences to traverse or prune during the copy. New * IDs will be assigned to all copied entities. Internal references will be preserved where possible. * * @param toClone - root of container containment hierarchy to copy * @param prune - EReferences not to traverse during copy. If specified, these * references will not be traversed during copy * @param traverse - EReferences to traverse during copy. If specified, no EReference * will be traversed unless it is in this list. * @param target - Allows specification of an entity into which to copy data, which does not have * to be of the same type as the copied entity (non-overlapping structure will be ignored). * @returns the copy */ static clone(toClone, prune, traverse, target, oldToNewEntities) { //create new instance const newContainer = target ? target : (toClone .eClass() .getEPackage() .getEFactoryInstance() .create(toClone.eClass())); //map of old entities to new entities that will be filled in during the duplication const oldToNew = oldToNewEntities ? oldToNewEntities : new Map(); //recursive duplication of containment hierachy this.cloneInto(toClone, newContainer, prune ? prune : [], traverse ? traverse : [], oldToNew); //re-establish container internal references for all entities in the //container, including the container root itself const allOldEntities = toClone.eAllContents(); allOldEntities.push(toClone); for (const oldEntity of allOldEntities) { const newEntity = oldToNew.get(oldEntity); if (newEntity) { for (const eref of newEntity.eClass().getEAllReferences()) { //only look at container internal references if (!eref.isContainment() && !eref.isTransient()) { const oldRefVal = oldEntity.eGet(eref); if (oldRefVal) { //handle many-valued references if (eref.isMany()) { const newRefList = newEntity.eGet(eref); if (newRefList) { for (const oldRef of oldRefVal) { const newRef = oldToNew.get(oldRef); if (newRef) newRefList.add(newRef); else if (oldRef) newRefList.add(oldRef); } } } //handle single-valued references else { const newVal = oldToNew.get(oldRefVal); if (newVal) newEntity.eSet(eref, newVal); else newEntity.eSet(eref, oldRefVal); } } } } } } return newContainer; } static cloneInto(copyFrom, copyInto, pruneOnlyTheseReferences, traverseOnlyTheseReferences, oldToNew) { for (const attr of copyInto.eClass().getEAllAttributes()) { if (!attr.isVolatile()) { copyInto.eSet(attr, copyFrom.eGet(attr)); } } //assign new ID to entity if (copyInto.eClass().getEIDAttribute()) copyInto.eSet(copyInto.eClass().getEIDAttribute(), uuid()); //register old to new entity in Map, if specified if (oldToNew) oldToNew.set(copyFrom, copyInto); //recurse containments for (const ref of copyInto.eClass().getEAllReferences()) { //determine if reference should be traversed let traverse = true; //do not traverse pruned references if (traverse && pruneOnlyTheseReferences) { for (const toPrune of pruneOnlyTheseReferences) { if (toPrune === ref) traverse = false; } } //do not traverse references not in the traverse list (if it is specified) if (traverse && traverseOnlyTheseReferences) { traverse = false; for (const toPrune of traverseOnlyTheseReferences) { if (toPrune === ref) traverse = true; } } //recursively copy the containment if (traverse) { if (ref.isContainment()) { //many-valued containment if (ref.isMany()) { const list = copyInto.eGet(ref); for (const toCopy of copyFrom.eGet(ref)) { list.add(this.clone(toCopy, pruneOnlyTheseReferences, traverseOnlyTheseReferences, null, oldToNew)); } } //single valued containment else { const toCopy = copyFrom.eGet(ref); if (toCopy) { copyInto.eSet(ref, this.clone(toCopy, pruneOnlyTheseReferences, traverseOnlyTheseReferences, null, oldToNew)); } } } //simply assign non-containment references if they have no eopposite else if (!ref.getEOpposite() && !ref.isContainer() && !ref.isVolatile()) { if (ref.isMany()) { const list = copyInto.eGet(ref); for (const member of copyFrom.eGet(ref)) list.add(member); } else copyInto.eSet(ref, copyFrom.eGet(ref)); } } } return copyInto; } static carbonCopy(obj) { return TJson.makeEObject(TJson.makeJson(obj)); } /** * Overwrites all attributes values, and replaces all containments with * carbon copies. Non-containment references are left alone. * * @param currentState * @param newState */ static shallowUpdate(currentState, newState) { //copy all EAttributes at the roote level for (const attr of newState.eClass().getEAllAttributes()) { if (!attr.isVolatile()) { currentState.eSet(attr, newState.eGet(attr)); } } //replace all contained instances for (const ref of newState.eClass().getEAllContainments()) { if (ref.isMany()) { const newContained = newState.eGet(ref); if (newContained) currentState.eSet(ref, this.carbonCopy(newContained)); else currentState.eSet(ref, null); } else { const currentContained = currentState.eGet(ref); currentContained.clear(); const newContainedList = newState.eGet(ref); for (const newContained of newContainedList) { currentContained.add(this.carbonCopy(newContained)); } } } } /** * Returns the package and transitive closure of all contained subpackages. * * @param pkg * @returns */ static allPackagesRecursive(pkg, addTo) { let pkgs = addTo ? addTo : []; pkgs.push(pkg); for (const sp of pkg.getESubPackages()) { this.allPackagesRecursive(sp, pkgs); } return pkgs; } static getRootEClasses(root) { if (!root) return []; const allPkgs = this.allPackagesRecursive(root); const allClasses = []; const containedClasses = new Set(); // First, collect all non-abstract, non-interface classes for (const ePackage of allPkgs) { ePackage.getEClassifiers().forEach((classifier) => { if (classifier instanceof EClassImpl && !classifier.isAbstract() && !classifier.isInterface()) { allClasses.push(classifier); } }); } // Then, find which classes are contained by others allClasses.forEach((eClass) => { eClass.getEAllReferences().forEach((ref) => { if (ref.isContainment()) { const targetType = ref.getEType(); if (targetType instanceof EClassImpl) { containedClasses.add(targetType); // Also add all subtypes allClasses.forEach((otherClass) => { if (otherClass.getEAllSuperTypes().contains(targetType)) { containedClasses.add(otherClass); } }); } } }); }); // Return classes that are not contained by any other class return allClasses.filter((c) => !containedClasses.has(c)).reverse(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi90dXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSTNELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBSXBFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUU3RDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLE1BQU07SUFDakIsMkNBQTJDO0lBQ3BDLE1BQU0sQ0FBQyxVQUFVLEdBQUc7UUFDekIsU0FBUztRQUNULFVBQVU7UUFDVixTQUFTO1FBQ1QsZUFBZTtRQUNmLFFBQVE7UUFDUixjQUFjO1FBQ2QsTUFBTTtRQUNOLGdCQUFnQjtRQUNoQixPQUFPO0tBQ1IsQ0FBQztJQUVGOzs7T0FHRztJQUNILE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxHQUFZO1FBQzVDLEtBQUssTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLFlBQVksRUFBRTtZQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBQ0Q7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsR0FBWTtRQUNsQywyQ0FBMkM7UUFDM0MsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDM0QsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMs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bW9kZWwvYXBpL2VjbGFzc2lmaWVyLmpzJztcbmltcG9ydCB7IEVPYmplY3QgfSBmcm9tICcuL21ldGFtb2RlbC9hcGkvZW9iamVjdC5qcyc7XG5pbXBvcnQgeyBFRW51bSB9IGZyb20gJy4vbWV0YW1vZGVsL2FwaS9lZW51bS5qcyc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBFY29yZVBhY2thZ2UgfSBmcm9tICcuL21ldGFtb2RlbC9lY29yZXBhY2thZ2UuanMnO1xuaW1wb3J0IHsgRUF0dHJpYnV0ZSB9IGZyb20gJy4vbWV0YW1vZGVsL2FwaS9lYXR0cmlidXRlLmpzJztcbmltcG9ydCB7IEVTdHJ1Y3R1cmFsRmVhdHVyZSB9IGZyb20gJy4vbWV0YW1vZGVsL2FwaS9lc3RydWN0dXJhbC1mZWF0dXJlLmpzJztcbmltcG9ydCB7IEVSZWZlcmVuY2UgfSBmcm9tICcuL21ldGFtb2RlbC9hcGkvZXJlZmVyZW5jZS5qcyc7XG5pbXBvcnQgeyBUSnNvbiB9IGZyb20gJy4vanNvbi90anNvbi5qcyc7XG5pbXBvcnQgeyBFRW51bUltcGwgfSBmcm9tICcuL21ldGFtb2RlbC9pbXBsL2VlbnVtLWltcGwuanMnO1xuaW1wb3J0IHsgRURhdGFUeXBlSW1wbCB9IGZyb20gJy4vbWV0YW1vZGVsL2ltcGwvZWRhdGEtdHlwZS1pbXBsLmpzJztcbmltcG9ydCB7IEVMaXN0IH0gZnJvbSAnLi9tZXRhbW9kZWwvYXBpL2VsaXN0LmpzJztcbmltcG9ydCB7IEVDbGFzcyB9IGZyb20gJy4vbWV0YW1vZGVsL2FwaS9lY2xhc3MuanMnO1xuaW1wb3J0IHsgRVBhY2thZ2UgfSBmcm9tICcuL21ldGFtb2RlbC9hcGkvZXBhY2thZ2UuanMnO1xuaW1wb3J0IHsgRUNsYXNzSW1wbCB9IGZyb20gJy4vbWV0YW1vZGVsL2ltcGwvZWNsYXNzLWltcGwuanMnO1xuXG4vKipcbiAqIFZhcmlvdXMgdXRpbGl0aWVzIGZvciBpbnRlcmFjdGluZyB3aXRoIFRNRi1tb2RlbGVkIGRhdGEgb2JqZWN0cywgc29tZVxuICogb2Ygd2hpY2ggYXJlIHJlbGllZCB1cG9uIGJ5IGNvcmUgVE1GIGNvbXBvbmVudHMgKGUuZy4gVEpzb24pIGFuZCBnZW5lcmF0ZWRcbiAqIHNvdXJjZSBjb2RlLlxuICovXG5leHBvcnQgY2xhc3MgVFV0aWxzIHtcbiAgLy9BbGwgcHJpbWl0aXZlIEVEYXRhVHlwZXMgc3VwcG9ydGVkIGJ5IFRNRlxuICBwdWJsaWMgc3RhdGljIFBSSU1JVElWRVMgPSBbXG4gICAgJ0VTdHJpbmcnLFxuICAgICdFQm9vbGVhbicsXG4gICAgJ0VEb3VibGUnLFxuICAgICdFRG91YmxlT2JqZWN0JyxcbiAgICAnRUZsb2F0JyxcbiAgICAnRUZsb2F0T2JqZWN0JyxcbiAgICAnRUludCcsXG4gICAgJ0VJbnRlZ2VyT2JqZWN0JyxcbiAgICAnRURhdGUnLFxuICBdO1xuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGFsbCBvYmplY3RzIGhhdmUgSURzLlxuICAgKiBAcGFyYW0gb2JqXG4gICAqL1xuICBzdGF0aWMgZ2VuZXJhdGVJZHNGb3JBbGxDb250YWluZWQob2JqOiBFT2JqZWN0KSB7XG4gICAgZm9yIChjb25zdCBlIG9mIG9iai5lQWxsQ29udGVudHMoKSkgdGhpcy5nZW5JZElmTm90RXhpc3RzKGUpO1xuICB9XG4gIC8qKlxuICAgKiBTZXRzIGFuIElEIGZvciB0aGUgZ2l2ZW4gb2JqZWN0IG9uIGl0J3MgSUQgRUF0dHJpYnV0ZS4gSWZcbiAgICogYW4gSUQgaXMgYWxyZWFkeSBzcGVjaWZpZWQsIGRvZXMgbm90aGluZy5cbiAgICpcbiAgICogQHBhcmFtIG9ialxuICAgKi9cbiAgc3RhdGljIGdlbklkSWZOb3RFeGlzdHMob2JqOiBFT2JqZWN0KSB7XG4gICAgLy9UT0RPOiBTdXBwb3J0IElEcyBvdGhlciB0aGFuIHN0cmluZyB1dWlkc1xuICAgIGlmIChvYmogJiYgb2JqLmVDbGFzcygpLmdldEVJREF0dHJpYnV0ZSgpICYmICFvYmouZnVsbElkKCkpIHtcbiAgICAgIG9iai5lU2V0KG9iai5lQ2xhc3MoKS5nZXRFSURBdHRyaWJ1dGUoKSBhcyBFQXR0cmlidXRlLCB1dWlkKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBhbiBJRCBpcyBzcGVjaWZpZWQgb24gdGhlIG9iamVjdCwgcmV0dXJucyBhIG5ldyBUSWQgaW5zdGFuY2Ugd2l0aCB0aGF0IElEIHZhbHVlLiBJZiBub3QsIGFcbiAgICogbmV3IElEIGlzIGFzc2lnbmVkIGFuZCB0aGF0IFRJZCByZXR1cm5lZC5cbiAgICpcbiAgICogQHBhcmFtIG9ialxuICAgKi9cbiAgc3RhdGljIGdldE9yQ3JlYXRlSWRGb3JPYmplY3Qob2JqOiBFT2JqZWN0KTogc3RyaW5nIHtcbiAgICB0aGlzLmdlbklkSWZOb3RFeGlzdHMob2JqKTtcbiAgICByZXR1cm4gb2JqLmZ1bGxJZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIFR5cGVzY3JpcHQgbmFtZSBmb3IgYSBnaXZlbiBFQ2xhc3NpZmllciwgaW5jbHVkaW5nXG4gICAqIHRyYW5zbGF0aW9uIG9mIHByaW1pdGl2ZSBFRGF0YVR5cGUgbmFtZXMgKGUuZy4gRUJvb2xlYW4gLT4gYm9vbGVhbikuXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldFR5cGVzY3JpcHROYW1lKHR5cGU6IEVDbGFzc2lmaWVyKSB7XG4gICAgaWYgKCF0eXBlKSByZXR1cm4gJ251bGwnO1xuICAgIGxldCB0eXBlU3RyID0gdHlwZS5nZXROYW1lKCk7XG4gICAgaWYgKCEodHlwZSBpbnN0YW5jZW9mIEVFbnVtSW1wbCkgJiYgdHlwZSBpbnN0YW5jZW9mIEVEYXRhVHlwZUltcGwpXG4gICAgICB0eXBlU3RyID0gVFV0aWxzLnRvVHlwZVNjcmlwdFByaW1pdGl2ZSh0eXBlKTtcbiAgICByZXR1cm4gdHlwZVN0cjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBUeXBlU2NyaXB0IHByaW1pdGl2ZSB0eXBlIGZvciBhIGdpdmVuIFRNRiBFQ2xhc3NpZmllciB0aGF0IHJlcHJlc2VudHMgYVxuICAgKiBwcmltaXRpdmUgdHlwZS5cbiAgICogQHBhcmFtIGNsYXNzaWZpZXJcbiAgICovXG4gIHN0YXRpYyB0b1R5cGVTY3JpcHRQcmltaXRpdmUoY2xhc3NpZmllcjogRUNsYXNzaWZpZXIpOiBzdHJpbmcge1xuICAgIGlmICghY2xhc3NpZmllciB8fCAhY2xhc3NpZmllci5nZXROYW1lKCkpIHJldHVybiAnYW55JztcbiAgICBzd2l0Y2ggKGNsYXNzaWZpZXIuZ2V0TmFtZSgpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgJ2VzdHJpbmcnOiB7XG4gICAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdlYm9vbGVhbic6IHtcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdlZG91YmxlJzoge1xuICAgICAgICByZXR1cm4gJ251bWJlcic7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnZWRvdWJsZW9iamVjdCc6IHtcbiAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2VmbG9hdCc6IHtcbiAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2VmbG9hdG9iamVjdCc6IHtcbiAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2VpbnQnOiB7XG4gICAgICAgIHJldHVybiAnbnVtYmVyJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdlaW50ZWdlcm9iamVjdCc6IHtcbiAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2VkYXRlJzoge1xuICAgICAgICByZXR1cm4gJ0RhdGUnO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2VhcnJheSc6IHtcbiAgICAgICAgcmV0dXJuICdbXSc7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHJldHVybiAnYW55JztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgbG9va3VwTmFtZWRGaWVsZChcbiAgICBvYmplY3Q6IEVPYmplY3QsXG4gICAgZmllbGROYW1lOiBzdHJpbmdcbiAgKTogRVN0cnVjdHVyYWxGZWF0dXJlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjdXJDbGFzcyA9IG9iamVjdC5lQ2xhc3MoKTtcbiAgICBjb25zdCBmaWVsZCA9IGN1ckNsYXNzLmdldEVTdHJ1Y3R1cmFsRmVhdHVyZShmaWVsZE5hbWUpO1xuXG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgY29uc29sZS5sb2coY3VyQ2xhc3MuZ2V0TmFtZSgpLCAnIGhhcyBubyBmaWVsZCBuYW1lZCcsIGZpZWxkTmFtZSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGQ7XG4gIH1cblxuICBzdGF0aWMgZ2V0TmFtZWRGaWVsZFZhbHVlKG9iamVjdDogRU9iamVjdCwgZmllbGROYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5sb29rdXBOYW1lZEZpZWxkKG9iamVjdCwgZmllbGROYW1lKTtcbiAgICBpZiAoZmllbGQpIHJldHVybiBvYmplY3QuZUdldChmaWVsZCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHN0YXRpYyBzZXROYW1lZEZpZWxkVmFsdWUob2JqZWN0OiBFT2JqZWN0LCBmaWVsZE5hbWU6IHN0cmluZywgbmV3VmFsdWU6IGFueSkge1xuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5sb29rdXBOYW1lZEZpZWxkKG9iamVjdCwgZmllbGROYW1lKTtcbiAgICBpZiAoZmllbGQpIG9iamVjdC5lU2V0KGZpZWxkLCBuZXdWYWx1ZSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgYSB2YWx1ZSBmb3IgYW4gRUF0dHJpYnV0ZSBmcm9tIGl0J3MgSlNPTiByZXByZXNlbnRhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIGF0dHJcbiAgICogQHBhcmFtIGpzb25WYWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcGFyc2VBdHRyVmFsRnJvbVN0cmluZyhhdHRyOiBFQXR0cmlidXRlLCBzdHJpbmdWYWw6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VWYWx1ZUZyb21TdHJpbmcoXG4gICAgICBhdHRyLmdldEVUeXBlKCkgYXMgRUNsYXNzaWZpZXIsXG4gICAgICBzdHJpbmdWYWwgKyAnJ1xuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHBhcnNlVmFsdWVGcm9tU3RyaW5nKGF0dHJUeXBlOiBFQ2xhc3NpZmllciwgc3RyaW5nVmFsOiBzdHJpbmcpIHtcbiAgICBsZXQgdFZhbCA9IG51bGw7XG4gICAgLy9pZiBhbiBlbXB0eSBzdHJpbmcgd2FzIHNldCBmb3IgdGhlIGZpZWxkLCBqdXN0IHJldHVybiBudWxsXG4gICAgaWYgKFxuICAgICAgIXN0cmluZ1ZhbCB8fFxuICAgICAgKHN0cmluZ1ZhbC50b1N0cmluZygpLnRyaW0oKSA9PT0gJycgJiZcbiAgICAgICAgYXR0clR5cGUgIT09IEVjb3JlUGFja2FnZS5MaXRlcmFscy5FX1NUUklORylcbiAgICApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChhdHRyVHlwZSA9PT0gRWNvcmVQYWNrYWdlLkxpdGVyYWxzLkVfU1RSSU5HKSB7XG4gICAgICB0VmFsID0gc3RyaW5nVmFsLnRvU3RyaW5nKCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9ET1VCTEUgfHxcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9ET1VCTEVfT0JKRUNUXG4gICAgKSB7XG4gICAgICB0VmFsID0gTnVtYmVyLnBhcnNlRmxvYXQoc3RyaW5nVmFsLnRvU3RyaW5nKCkpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBhdHRyVHlwZSA9PT0gRWNvcmVQYWNrYWdlLkxpdGVyYWxzLkVfRkxPQVQgfHxcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9GTE9BVF9PQkpFQ1RcbiAgICApIHtcbiAgICAgIHRWYWwgPSBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmdWYWwudG9TdHJpbmcoKSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9CT09MRUFOIHx8XG4gICAgICBhdHRyVHlwZSA9PT0gRWNvcmVQYWNrYWdlLkxpdGVyYWxzLkVfQk9PTEVBTl9PQkpFQ1RcbiAgICApIHtcbiAgICAgIHRWYWwgPSBzdHJpbmdWYWwudG9TdHJpbmcoKSA9PT0gJ3RydWUnO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBhdHRyVHlwZSA9PT0gRWNvcmVQYWNrYWdlLkxpdGVyYWxzLkVfU0hPUlQgfHxcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9TSE9SVF9PQkpFQ1RcbiAgICApIHtcbiAgICAgIHRWYWwgPSBOdW1iZXIucGFyc2VJbnQoc3RyaW5nVmFsLnRvU3RyaW5nKCksIDEwKTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYXR0clR5cGUgPT09IEVjb3JlUGFja2FnZS5MaXRlcmFscy5FX0lOVCB8fFxuICAgICAgYXR0clR5cGUgPT09IEVjb3JlUGFja2FnZS5MaXRlcmFscy5FX0lOVEVHRVJfT0JKRUNUXG4gICAgKSB7XG4gICAgICB0VmFsID0gTnVtYmVyLnBhcnNlSW50KHN0cmluZ1ZhbC50b1N0cmluZygpLCAxMCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9MT05HIHx8XG4gICAgICBhdHRyVHlwZSA9PT0gRWNvcmVQYWNrYWdlLkxpdGVyYWxzLkVfTE9OR19PQkpFQ1RcbiAgICApIHtcbiAgICAgIHRWYWwgPSBOdW1iZXIucGFyc2VJbnQoc3RyaW5nVmFsLnRvU3RyaW5nKCksIDEwKTtcbiAgICB9IGVsc2UgaWYgKGF0dHJUeXBlID09PSBFY29yZVBhY2thZ2UuTGl0ZXJhbHMuRV9EQVRFKSB7XG4gICAgICB0VmFsID0gbmV3IERhdGUoRGF0ZS5wYXJzZShzdHJpbmdWYWwpKTtcbiAgICB9IGVsc2UgaWYgKGF0dHJUeXBlIGluc3RhbmNlb2YgRUVudW1JbXBsKSB7XG4gICAgICBjb25zdCBlZW51bSA9IDxFRW51bT5hdHRyVHlwZTtcbiAgICAgIGNvbnN0IGxpdGVyYWwgPSBlZW51bS5nZXRFRW51bUxpdGVyYWwoc3RyaW5nVmFsLnRvU3RyaW5nKCkpO1xuICAgICAgaWYgKGxpdGVyYWwgIT0gbnVsbCkge1xuICAgICAgICB0VmFsID0gbGl0ZXJhbC5nZXRMaXRlcmFsKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ0NvdWxkIG5vdCBwYXJzZSBsaXRlcmFsIHZhbHVlICcgK1xuICAgICAgICAgICAgc3RyaW5nVmFsLnRvU3RyaW5nKCkgK1xuICAgICAgICAgICAgJyBmb3IgJyArXG4gICAgICAgICAgICBlZW51bS5nZXROYW1lKClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRWYWw7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiBhbiBSb290IGFuZCBpdCdzIGNvbnRhaW5tZW50IGhpZXJhcmNoeSwgd2l0aCBvcHRpb25hbFxuICAgKiBsaXN0cyBmb3Igc3BlY2lmeWluZyBzcGVjaWZpYyBFUmVmZXJlbmNlcyB0byB0cmF2ZXJzZSBvciBwcnVuZSBkdXJpbmcgdGhlIGNvcHkuIE5ld1xuICAgKiBJRHMgd2lsbCBiZSBhc3NpZ25lZCB0byBhbGwgY29waWVkIGVudGl0aWVzLiBJbnRlcm5hbCByZWZlcmVuY2VzIHdpbGwgYmUgcHJlc2VydmVkIHdoZXJlIHBvc3NpYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gdG9DbG9uZSAtIHJvb3Qgb2YgY29udGFpbmVyIGNvbnRhaW5tZW50IGhpZXJhcmNoeSB0byBjb3B5XG4gICAqIEBwYXJhbSBwcnVuZSAtICBFUmVmZXJlbmNlcyBub3QgdG8gdHJhdmVyc2UgZHVyaW5nIGNvcHkuIElmIHNwZWNpZmllZCwgdGhlc2VcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VzIHdpbGwgbm90IGJlIHRyYXZlcnNlZCBkdXJpbmcgY29weVxuICAgKiBAcGFyYW0gdHJhdmVyc2UgLSBFUmVmZXJlbmNlcyB0byB0cmF2ZXJzZSBkdXJpbmcgY29weS4gSWYgc3BlY2lmaWVkLCBubyBFUmVmZXJlbmNlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIHRyYXZlcnNlZCB1bmxlc3MgaXQgaXMgaW4gdGhpcyBsaXN0LlxuICAgKiBAcGFyYW0gdGFyZ2V0IC0gQWxsb3dzIHNwZWNpZmljYXRpb24gb2YgYW4gZW50aXR5IGludG8gd2hpY2ggdG8gY29weSBkYXRhLCB3aGljaCBkb2VzIG5vdCBoYXZlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGUgY29waWVkIGVudGl0eSAobm9uLW92ZXJsYXBwaW5nIHN0cnVjdHVyZSB3aWxsIGJlIGlnbm9yZWQpLlxuICAgKiBAcmV0dXJucyB0aGUgY29weVxuICAgKi9cbiAgc3RhdGljIGNsb25lPFQgZXh0ZW5kcyBFT2JqZWN0PihcbiAgICB0b0Nsb25lOiBULFxuICAgIHBydW5lPzogRVJlZmVyZW5jZVtdLFxuICAgIHRyYXZlcnNlPzogRVJlZmVyZW5jZVtdLFxuICAgIHRhcmdldD86IFQsXG4gICAgb2xkVG9OZXdFbnRpdGllcz86IE1hcDxFT2JqZWN0LCBFT2JqZWN0PlxuICApOiBUIHtcbiAgICAvL2NyZWF0ZSBuZXcgaW5zdGFuY2VcbiAgICBjb25zdCBuZXdDb250YWluZXIgPSB0YXJnZXRcbiAgICAgID8gdGFyZ2V0XG4gICAgICA6IDxUPihcbiAgICAgICAgICB0b0Nsb25lXG4gICAgICAgICAgICAuZUNsYXNzKClcbiAgICAgICAgICAgIC5nZXRFUGFja2FnZSgpXG4gICAgICAgICAgICAuZ2V0RUZhY3RvcnlJbnN0YW5jZSgpXG4gICAgICAgICAgICAuY3JlYXRlKHRvQ2xvbmUuZUNsYXNzKCkpXG4gICAgICAgICk7XG5cbiAgICAvL21hcCBvZiBvbGQgZW50aXRpZXMgdG8gbmV3IGVudGl0aWVzIHRoYXQgd2lsbCBiZSBmaWxsZWQgaW4gZHVyaW5nIHRoZSBkdXBsaWNhdGlvblxuICAgIGNvbnN0IG9sZFRvTmV3ID0gb2xkVG9OZXdFbnRpdGllc1xuICAgICAgPyBvbGRUb05ld0VudGl0aWVzXG4gICAgICA6IG5ldyBNYXA8RU9iamVjdCwgRU9iamVjdD4oKTtcblxuICAgIC8vcmVjdXJzaXZlIGR1cGxpY2F0aW9uIG9mIGNvbnRhaW5tZW50IGhpZXJhY2h5XG4gICAgdGhpcy5jbG9uZUludG88VD4oXG4gICAgICB0b0Nsb25lLFxuICAgICAgbmV3Q29udGFpbmVyLFxuICAgICAgcHJ1bmUgPyBwcnVuZSA6IFtdLFxuICAgICAgdHJhdmVyc2UgPyB0cmF2ZXJzZSA6IFtdLFxuICAgICAgb2xkVG9OZXdcbiAgICApO1xuXG4gICAgLy9yZS1lc3RhYmxpc2ggY29udGFpbmVyIGludGVybmFsIHJlZmVyZW5jZXMgZm9yIGFsbCBlbnRpdGllcyBpbiB0aGVcbiAgICAvL2NvbnRhaW5lciwgaW5jbHVkaW5nIHRoZSBjb250YWluZXIgcm9vdCBpdHNlbGZcbiAgICBjb25zdCBhbGxPbGRFbnRpdGllcyA9IHRvQ2xvbmUuZUFsbENvbnRlbnRzKCk7XG4gICAgYWxsT2xkRW50aXRpZXMucHVzaCh0b0Nsb25lKTtcbiAgICBmb3IgKGNvbnN0IG9sZEVudGl0eSBvZiBhbGxPbGRFbnRpdGllcykge1xuICAgICAgY29uc3QgbmV3RW50aXR5ID0gb2xkVG9OZXcuZ2V0KG9sZEVudGl0eSk7XG4gICAgICBpZiAobmV3RW50aXR5KSB7XG4gICAgICAgIGZvciAoY29uc3QgZXJlZiBvZiBuZXdFbnRpdHkuZUNsYXNzKCkuZ2V0RUFsbFJlZmVyZW5jZXMoKSkge1xuICAgICAgICAgIC8vb25seSBsb29rIGF0IGNvbnRhaW5lciBpbnRlcm5hbCByZWZlcmVuY2VzXG4gICAgICAgICAgaWYgKCFlcmVmLmlzQ29udGFpbm1lbnQoKSAmJiAhZXJlZi5pc1RyYW5zaWVudCgpKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRSZWZWYWwgPSBvbGRFbnRpdHkuZUdldChlcmVmKTtcbiAgICAgICAgICAgIGlmIChvbGRSZWZWYWwpIHtcbiAgICAgICAgICAgICAgLy9oYW5kbGUgbWFueS12YWx1ZWQgcmVmZXJlbmNlc1xuICAgICAgICAgICAgICBpZiAoZXJlZi5pc01hbnkoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1JlZkxpc3QgPSBuZXdFbnRpdHkuZUdldChlcmVmKTtcbiAgICAgICAgICAgICAgICBpZiAobmV3UmVmTGlzdCkge1xuICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBvbGRSZWYgb2Ygb2xkUmVmVmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1JlZiA9IG9sZFRvTmV3LmdldChvbGRSZWYpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV3UmVmKSBuZXdSZWZMaXN0LmFkZChuZXdSZWYpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvbGRSZWYpIG5ld1JlZkxpc3QuYWRkKG9sZFJlZik7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vaGFuZGxlIHNpbmdsZS12YWx1ZWQgcmVmZXJlbmNlc1xuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdWYWwgPSBvbGRUb05ldy5nZXQob2xkUmVmVmFsKTtcbiAgICAgICAgICAgICAgICBpZiAobmV3VmFsKSBuZXdFbnRpdHkuZVNldChlcmVmLCBuZXdWYWwpO1xuICAgICAgICAgICAgICAgIGVsc2UgbmV3RW50aXR5LmVTZXQoZXJlZiwgb2xkUmVmVmFsKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3Q29udGFpbmVyO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY2xvbmVJbnRvPFQgZXh0ZW5kcyBFT2JqZWN0PihcbiAgICBjb3B5RnJvbTogVCxcbiAgICBjb3B5SW50bzogVCxcbiAgICBwcnVuZU9ubHlUaGVzZVJlZmVyZW5jZXM6IEVSZWZlcmVuY2VbXSxcbiAgICB0cmF2ZXJzZU9ubHlUaGVzZVJlZmVyZW5jZXM6IEVSZWZlcmVuY2VbXSxcbiAgICBvbGRUb05ldz86IE1hcDxFT2JqZWN0LCBFT2JqZWN0PlxuICApIHtcbiAgICBmb3IgKGNvbnN0IGF0dHIgb2YgY29weUludG8uZUNsYXNzKCkuZ2V0RUFsbEF0dHJpYnV0ZXMoKSkge1xuICAgICAgaWYgKCFhdHRyLmlzVm9sYXRpbGUoKSkge1xuICAgICAgICBjb3B5SW50by5lU2V0KGF0dHIsIGNvcHlGcm9tLmVHZXQoYXR0cikpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vYXNzaWduIG5ldyBJRCB0byBlbnRpdHlcbiAgICBpZiAoY29weUludG8uZUNsYXNzKCkuZ2V0RUlEQXR0cmlidXRlKCkpXG4gICAgICBjb3B5SW50by5lU2V0KGNvcHlJbnRvLmVDbGFzcygpLmdldEVJREF0dHJpYnV0ZSgpIGFzIEVBdHRyaWJ1dGUsIHV1aWQoKSk7XG5cbiAgICAvL3JlZ2lzdGVyIG9sZCB0byBuZXcgZW50aXR5IGluIE1hcCwgaWYgc3BlY2lmaWVkXG4gICAgaWYgKG9sZFRvTmV3KSBvbGRUb05ldy5zZXQoY29weUZyb20sIGNvcHlJbnRvKTtcblxuICAgIC8vcmVjdXJzZSBjb250YWlubWVudHNcbiAgICBmb3IgKGNvbnN0IHJlZiBvZiBjb3B5SW50by5lQ2xhc3MoKS5nZXRFQWxsUmVmZXJlbmNlcygpKSB7XG4gICAgICAvL2RldGVybWluZSBpZiByZWZlcmVuY2Ugc2hvdWxkIGJlIHRyYXZlcnNlZFxuICAgICAgbGV0IHRyYXZlcnNlID0gdHJ1ZTtcblxuICAgICAgLy9kbyBub3QgdHJhdmVyc2UgcHJ1bmVkIHJlZmVyZW5jZXNcbiAgICAgIGlmICh0cmF2ZXJzZSAmJiBwcnVuZU9ubHlUaGVzZVJlZmVyZW5jZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCB0b1BydW5lIG9mIHBydW5lT25seVRoZXNlUmVmZXJlbmNlcykge1xuICAgICAgICAgIGlmICh0b1BydW5lID09PSByZWYpIHRyYXZlcnNlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vZG8gbm90IHRyYXZlcnNlIHJlZmVyZW5jZXMgbm90IGluIHRoZSB0cmF2ZXJzZSBsaXN0IChpZiBpdCBpcyBzcGVjaWZpZWQpXG4gICAgICBpZiAodHJhdmVyc2UgJiYgdHJhdmVyc2VPbmx5VGhlc2VSZWZlcmVuY2VzKSB7XG4gICAgICAgIHRyYXZlcnNlID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgdG9QcnVuZSBvZiB0cmF2ZXJzZU9ubHlUaGVzZVJlZmVyZW5jZXMpIHtcbiAgICAgICAgICBpZiAodG9QcnVuZSA9PT0gcmVmKSB0cmF2ZXJzZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy9yZWN1cnNpdmVseSBjb3B5IHRoZSBjb250YWlubWVudFxuICAgICAgaWYgKHRyYXZlcnNlKSB7XG4gICAgICAgIGlmIChyZWYuaXNDb250YWlubWVudCgpKSB7XG4gICAgICAgICAgLy9tYW55LXZhbHVlZCBjb250YWlubWVudFxuICAgICAgICAgIGlmIChyZWYuaXNNYW55KCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGxpc3QgPSBjb3B5SW50by5lR2V0KHJlZik7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRvQ29weSBvZiBjb3B5RnJvbS5lR2V0KHJlZikpIHtcbiAgICAgICAgICAgICAgbGlzdC5hZGQoXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9uZShcbiAgICAgICAgICAgICAgICAgIHRvQ29weSxcbiAgICAgICAgICAgICAgICAgIHBydW5lT25seVRoZXNlUmVmZXJlbmNlcyxcbiAgICAgICAgICAgICAgICAgIHRyYXZlcnNlT25seVRoZXNlUmVmZXJlbmNlcyxcbiAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICBvbGRUb05ld1xuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvL3NpbmdsZSB2YWx1ZWQgY29udGFpbm1lbnRcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHRvQ29weSA9IGNvcHlGcm9tLmVHZXQocmVmKTtcbiAgICAgICAgICAgIGlmICh0b0NvcHkpIHtcbiAgICAgICAgICAgICAgY29weUludG8uZVNldChcbiAgICAgICAgICAgICAgICByZWYsXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9uZShcbiAgICAgICAgICAgICAgICAgIHRvQ29weSxcbiAgICAgICAgICAgICAgICAgIHBydW5lT25seVRoZXNlUmVmZXJlbmNlcyxcbiAgICAgICAgICAgICAgICAgIHRyYXZlcnNlT25seVRoZXNlUmVmZXJlbmNlcyxcbiAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICBvbGRUb05ld1xuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy9zaW1wbHkgYXNzaWduIG5vbi1jb250YWlubWVudCByZWZlcmVuY2VzIGlmIHRoZXkgaGF2ZSBubyBlb3Bwb3NpdGVcbiAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgIXJlZi5nZXRFT3Bwb3NpdGUoKSAmJlxuICAgICAgICAgICFyZWYuaXNDb250YWluZXIoKSAmJlxuICAgICAgICAgICFyZWYuaXNWb2xhdGlsZSgpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChyZWYuaXNNYW55KCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGxpc3QgPSBjb3B5SW50by5lR2V0KHJlZik7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1lbWJlciBvZiBjb3B5RnJvbS5lR2V0KHJlZikpIGxpc3QuYWRkKG1lbWJlcik7XG4gICAgICAgICAgfSBlbHNlIGNvcHlJbnRvLmVTZXQocmVmLCBjb3B5RnJvbS5lR2V0KHJlZikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb3B5SW50bztcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgY2FyYm9uQ29weTxUIGV4dGVuZHMgRU9iamVjdD4ob2JqOiBUKTogVCB7XG4gICAgcmV0dXJuIFRKc29uLm1ha2VFT2JqZWN0KFRKc29uLm1ha2VKc29uKG9iaikpIGFzIFQ7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcndyaXRlcyBhbGwgYXR0cmlidXRlcyB2YWx1ZXMsIGFuZCByZXBsYWNlcyBhbGwgY29udGFpbm1lbnRzIHdpdGhcbiAgICogY2FyYm9uIGNvcGllcy4gTm9uLWNvbnRhaW5tZW50IHJlZmVyZW5jZXMgYXJlIGxlZn