gy-foo
Version:
A library that contains all models for the gy-web-project.
459 lines • 54.8 kB
JavaScript
import { Entity } from './entity.model';
import { ModeFlags } from '../enums/modeFlags.enum';
import { Field } from './field.model';
export class Occurrence {
/**
* Creates a new Occrruence
* @param occ An Occrrence object or an object that looks like an Occurence
*/
constructor(occ, modeFlag) {
if (occ) {
if (occ instanceof Occurrence) {
this.pk = occ.getPk();
this.structure = occ.getStructure();
this.data = occ.getData() ? this.convertValues(occ.getData(), occ.getStructure()) : {};
this.meta = occ.getMeta() || {};
this.modified = occ.isModified();
this.locked = occ.isLocked();
}
else {
this.pk = occ.pk;
this.structure = occ.structure;
this.data = occ.data ? this.convertValues(occ.data, occ.structure) : {};
this.meta = occ.meta || {};
this.modified = occ.modified ? occ.modified : false;
this.locked = occ.locked ? occ.locked : false;
}
}
else {
this.pk = null;
this.data = {};
this.structure = {};
this.meta = {};
this.modified = false;
this.locked = false;
}
this.setMode(modeFlag);
}
/**
* Converts the SubEntities in data to Entities
* @param data data to convert
* @param structure structure of current occ
* @returns new data object
*/
convertValues(data, structure) {
for (const key of Object.keys(structure)) {
const value = data[key.toUpperCase()];
if (value) {
data[key.toUpperCase()] = new Entity(value.occs ? value : { occs: value, structure: structure[key.toUpperCase()] });
}
}
return data;
}
// ------------------------------------------------------------------------------------------------------
// Get Functions
// ------------------------------------------------------------------------------------------------------
/**
* Gets the pk of this Occurrence
*/
getPk() {
return this.pk;
}
/**
* Gets the structure of this Occurrence
*/
getStructure() {
return this.structure;
}
/**
* Gets the value of the given field
* @param field the name of the field
* @returns the value of the field
*/
getValue(field) {
return this.data[field.toUpperCase()];
}
/**
* Returns the Mode of this Occurrence. Possible values are: 'add', 'cpy', 'del' and '';
* @returns returns the mode of the occ (ModeFlags)
*/
getMode() {
return this.data._mode || '';
}
/**
* Gets the data of this Occurence
* @param col get data with or without collections. Default is true (all data).
*/
getData(col) {
return col === false
? Object.keys(this.data)
.filter((field) => !this.structure[field.toUpperCase()])
.reduce((prev, field) => Object.assign(prev, { [field]: this.data[field] }), {})
: this.data;
}
/**
* Gets the Subentity from this Occurrence
* @param name the name of the Subentity
* @returns returns the subEntity
*/
getSubEnt(name) {
if (!this.hasCollection(name)) {
return (this.data[name.toUpperCase()] = new Entity());
}
return this.data[name.toUpperCase()];
}
/**
* Gets the Occurences of the given SubEntity
* @param name the name of the Subentity
* @returns data from SubEntity
*/
getCollection(name) {
return this.data[name.toUpperCase()] ? this.data[name.toUpperCase()].occs : [];
}
/**
* Gets a list of all fields of this Occurrence
* @param col if true all Subentitys will be included in this list, default false
* @returns returns an array of all field Names
*/
getFields(col) {
return Object.keys(this.data).filter((value) => col || !this.structure[value.toUpperCase()]);
}
/**
* Has the Occurrence been modified?
* @param checkSubEnt check Subentities (default: true)
*/
isModified(checkSubEnt = true) {
return this.modified || (!checkSubEnt || !this.hasAnyCollection() ? this.modified : this.checkSubEntityModified());
}
/**
* is this occurence locked and can not be edited?
*/
isLocked() {
return this.locked;
}
/**
* Gets the structure of the given subentity
* @param name the name of the subentity
*/
getSubEntityStructure(name) {
return this.structure[name.toUpperCase()];
}
/**
* Gets the Meta informations of this occurence
* @param entity the name of a subentity, whose meta information should be read
*/
getMeta() {
return this.meta;
}
/**
* Gets the Meta informations of this occurence for the given entityname
* @param entity the name of a subentity, whose meta information should be read
*/
getMetaFieldList(entity) {
return this.meta[entity.toUpperCase()]
? this.meta[entity.toUpperCase()].reduce((acc, val) => Object.assign(acc, val), {}) || {}
: {};
}
/**
* Gets the Meta information for one field, if given
* @param field the name of the field
* @param entity the name of a subentity, where the field should be looked up
*/
getMetaField(field, entity) {
const fieldname = field.startsWith('_') ? field : field.toUpperCase();
const metaList = this.meta[entity.toUpperCase()]
? this.meta[entity.toUpperCase()].find((value) => {
return fieldname in value;
})
: undefined;
return metaList ? metaList[fieldname] : {};
}
// ------------------------------------------------------------------------------------------------------
// Set Functions
// ------------------------------------------------------------------------------------------------------
/**
* Sets the _mode value of this Occurrence
* @param mode boolean, that defines the mode. Add if this Occurrence should be added to the Database,
* cpy if this is a Copy of a Occurrrence and del if this Occurrence should be deleted in the DB.
* If missing, the _mode flag will be deleted.
* @param col set the mode for all subentitys.
*/
setMode(mode, col) {
if (mode) {
if (mode.del) {
this.data._mode = ModeFlags.DEL;
}
else if (mode.cpy) {
this.data._mode = ModeFlags.CPY;
}
else if (mode.add) {
this.data._mode = ModeFlags.ADD;
}
else if (this.data._mode) {
delete this.data._mode;
}
}
else if (this.data._mode) {
delete this.data._mode;
}
if (col) {
Object.keys(this.structure).forEach((subEnt) => {
if (this.data.hasOwnProperty(subEnt)) {
this.getCollection(subEnt).forEach((occ) => occ.setMode(mode, col));
}
});
}
}
/**
* sets the pk property
* @param pk pk that should be set
*/
addPk(pk) {
if (this.pk) {
return;
}
this.pk = pk;
}
/**
* Sets the given field on the given value
* @param field the name of the field
* @param value the new value
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
setValue(field, value, isUserChange = false) {
if (isUserChange && this.isLocked()) {
return;
}
if (!field.startsWith('_')) {
field = field.toUpperCase();
}
const undovalue = this.data[field];
this.data[field] = value;
if (isUserChange && undovalue != value) {
this.modified = true;
}
}
/**
* Sets the given list of fields on the given values
* @param values list of fields and values in the form {fieldname1: value1, fieldname2: value2, ...}
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
setValues(values, isUserChange = false) {
if (!values || (isUserChange && this.isLocked())) {
return;
}
Object.entries(values).forEach(([field, value]) => this.setValue(field, value, isUserChange && !this.modified));
this.data = this.convertValues(this.data, this.structure);
}
/**
* Changes all Occurrences of the given Subentity
* @param name name ot the subentity
* @param occs list of the new Occurences
*/
setCollection(name, occs) {
if (this.hasCollection(name.toUpperCase())) {
this.data[name.toUpperCase()].occs = occs;
}
else if (this.getSubEntityStructure(name)) {
this.data[name.toUpperCase()] = new Entity({ occs, structure: this.getSubEntityStructure(name) });
}
}
/**
* Sets the structure of this Occurrence
* @param value the new value of the structure
*/
setStructure(value) {
this.structure = Object.assign(this.structure, value);
}
/**
* Sets the modified flag
* @param modified occ is modified?
* @param setSubEntites should the modified flag be set also in the subentites?
*/
setModified(modified, setSubEntites = false) {
this.modified = modified;
if (setSubEntites) {
Object.keys(this.structure).forEach((entName) => {
this.getSubEnt(entName).setModified(modified, setSubEntites);
});
}
}
/**
* Sets the Meta information for one field
* @param field the name of the field
* @param entity the name of a subentity, where the field should be looked up
* @param value the new value of the definition
*/
setMetaField(field, entity, value) {
if (value) {
const fldvalue = new Field(value);
const fldname = field.toUpperCase();
const entityname = entity.toUpperCase();
if (!this.meta) {
this.meta = { [entityname]: [{ [fldname]: fldvalue }] };
}
else if (!this.meta[entityname]) {
this.meta[entityname] = [{ [fldname]: fldvalue }];
}
else {
const metaList = this.meta[entityname].find((fldlst) => fldname in fldlst);
if (!metaList) {
this.meta[entityname].push({ [fldname]: fldvalue });
}
else {
Object.assign(metaList[fldname], fldvalue);
}
}
}
}
/**
* Sets the Meta information for one entity
* @param entity the name of a subentity, whose meta information should be set
* @param values the new values of the definition
*/
setMetaFieldList(entity, values) {
if (values) {
const fldlsts = Array.isArray(values) ? values : [values];
const entityname = entity.toUpperCase();
if (!this.meta) {
this.meta = { [entityname]: fldlsts };
}
else if (!this.meta[entityname]) {
this.meta[entityname] = fldlsts;
}
else {
fldlsts.forEach((fldlst) => Object.entries(fldlst).forEach(([field, value]) => this.setMetaField(field, entity, value)));
}
}
}
/**
* Sets the Meta information
* @param metaValue the new values of the definition
*/
setMeta(metaValue) {
if (metaValue) {
if (!this.meta) {
this.meta = metaValue;
}
else {
Object.entries(metaValue).forEach(([entity, fieldlsts]) => {
this.setMetaFieldList(entity, fieldlsts);
});
}
}
}
// ------------------------------------------------------------------------------------------------------
// Copy Functions
// ------------------------------------------------------------------------------------------------------
/**
* Copies the given Occurrence into this Occurrence
* @param occ the Occurrence that should be copied
* @param cpy the Copy mode should be set
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
copy(occ, cpy, isUserChange = false) {
this.pk = occ.pk;
this.data = occ.data;
this.structure = occ.structure;
this.meta = occ.meta;
this.modified = isUserChange;
this.locked = false;
this.setMode({ cpy });
}
/**
* Makes a copy of this Occurrence into a new instance.
* @returns new Occurrence
*/
copyOccFlat() {
return new Occurrence({
pk: this.pk,
structure: this.structure,
meta: this.meta,
data: { _pk: this.data._pk, _hash: this.data._hash },
modified: this.modified,
});
}
// ------------------------------------------------------------------------------------------------------
// SubEntity/Structure Functions
// ------------------------------------------------------------------------------------------------------
/**
* Checks if this Occurrence has the given Subentity
* @param name the name of the Subentity
* @returns true or false
*/
hasCollection(name) {
return this.data[name.toUpperCase()];
}
/**
* Checks if the Occ is type OCC or COL
* @returns true or false
*/
hasAnyCollection() {
for (const subEnt of Object.keys(this.structure)) {
if (this.data.hasOwnProperty(subEnt)) {
return true;
}
}
return false;
}
/**
* Changes the given Subentity
* @param name the name of the Subentity
* @param SubEnt the new Entity
* @param isUserChange is this a users change (should modified flag been set) (default: false)
*/
changeSubEnt(name, SubEnt, isUserChange = false) {
this.data[name.toUpperCase()] = SubEnt;
if (isUserChange) {
this.getSubEnt(name).setModified(true, false);
}
}
// ------------------------------------------------------------------------------------------------------
// Delete Functions
// ------------------------------------------------------------------------------------------------------
/**
* Deletes a Subenetity from this Occurrence
* @param name name of the subentity
*/
deleteSubEnt(name) {
delete this.data[name.toUpperCase()];
}
/**
* Deletes a field from this Occurrence
* @param name name of field
*/
deleteValue(name) {
delete this.data[name.toUpperCase()];
}
// ------------------------------------------------------------------------------------------------------
// Check Functions
// ------------------------------------------------------------------------------------------------------
/**
* checks if some subentity is modified
*/
checkSubEntityModified() {
for (const entName of Object.keys(this.structure)) {
if (this.hasCollection(entName) && this.getSubEnt(entName).isModified()) {
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------------
// Additional
// ------------------------------------------------------------------------------------------------------
/**
* Compares this Occurrence with the given Occ. First the PK will be compared and then the hash value.
* @param occ the second occ
*/
equals(occ) {
return this.getPk() === occ.getPk() && this.getValue('_hash') === occ.getValue('_hash');
}
/**
* Gets a string representation of this Occurrence. This is mainly for debug purpose.
*/
toString() {
return JSON.stringify({ pk: this.pk, _hash: this.data._hash });
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2NjdXJyZW5jZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2d5LWZvby8iLCJzb3VyY2VzIjpbImxpYi9tb2RlbHMvb2NjdXJyZW5jZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxLQUFLLEVBQVksTUFBTSxlQUFlLENBQUM7QUFFaEQsTUFBTSxPQUFPLFVBQVU7SUFRckI7OztPQUdHO0lBQ0gsWUFDRSxHQVNjLEVBQ2QsUUFBMEQ7UUFFMUQsSUFBSSxHQUFHLEVBQUU7WUFDUCxJQUFJLEdBQUcsWUFBWSxVQUFVLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN0QixJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZGLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQzlCO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDakIsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUMsU0FB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LEtBQUssTUFBTSxPQUFPLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDakQsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7Z0JBQ3ZFLE9BQU8sSUFBSSxDQUFDO2FBQ2I7U0FDRjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHlHQUF5RztJQUN6Ryw0Q0FBNEM7SUFDNUMseUdBQXlHO0lBQ3pHOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxHQUFlO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRW50aXR5IH0gZnJvbSAnLi9lbnRpdHkubW9kZWwnO1xuaW1wb3J0IHsgRW50aXR5U3RydWN0dXJlIH0gZnJvbSAnLi9lbnRpdHlTdHJ1Y3R1cmUubW9kZWwnO1xuaW1wb3J0IHsgTW9kZUZsYWdzIH0gZnJvbSAnLi4vZW51bXMvbW9kZUZsYWdzLmVudW0nO1xuaW1wb3J0IHsgRmllbGRMaXN0IH0gZnJvbSAnLi9maWVsZExpc3QubW9kZWwnO1xuaW1wb3J0IHsgRmllbGQsIEZpZWxkRGVmIH0gZnJvbSAnLi9maWVsZC5tb2RlbCc7XG5cbmV4cG9ydCBjbGFzcyBPY2N1cnJlbmNlIHtcbiAgcHJpdmF0ZSBwazogc3RyaW5nO1xuICBwcml2YXRlIGRhdGE6IHsgW2ZpZWxkOiBzdHJpbmddOiBhbnkgfTtcbiAgcHJpdmF0ZSBtZXRhPzogeyBbZW50aXR5OiBzdHJpbmddOiBGaWVsZExpc3RbXSB9O1xuICBwcml2YXRlIHN0cnVjdHVyZTogRW50aXR5U3RydWN0dXJlO1xuICBwcml2YXRlIG1vZGlmaWVkOiBib29sZWFuO1xuICBwcml2YXRlIGxvY2tlZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPY2NycnVlbmNlXG4gICAqIEBwYXJhbSBvY2MgQW4gT2NjcnJlbmNlIG9iamVjdCBvciBhbiBvYmplY3QgdGhhdCBsb29rcyBsaWtlIGFuIE9jY3VyZW5jZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgb2NjPzpcbiAgICAgIHwge1xuICAgICAgICAgIHBrOiBzdHJpbmc7XG4gICAgICAgICAgc3RydWN0dXJlOiBFbnRpdHlTdHJ1Y3R1cmU7XG4gICAgICAgICAgZGF0YT86IHsgW2ZpZWxkOiBzdHJpbmddOiBhbnkgfTtcbiAgICAgICAgICBtZXRhPzogeyBbZW50aXR5OiBzdHJpbmddOiBGaWVsZExpc3RbXSB9O1xuICAgICAgICAgIG1vZGlmaWVkPzogYm9vbGVhbjtcbiAgICAgICAgICBsb2NrZWQ/OiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICB8IE9jY3VycmVuY2UsXG4gICAgbW9kZUZsYWc/OiB7IGFkZD86IGJvb2xlYW47IGNweT86IGJvb2xlYW47IGRlbD86IGJvb2xlYW4gfVxuICApIHtcbiAgICBpZiAob2NjKSB7XG4gICAgICBpZiAob2NjIGluc3RhbmNlb2YgT2NjdXJyZW5jZSkge1xuICAgICAgICB0aGlzLnBrID0gb2NjLmdldFBrKCk7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gb2NjLmdldFN0cnVjdHVyZSgpO1xuICAgICAgICB0aGlzLmRhdGEgPSBvY2MuZ2V0RGF0YSgpID8gdGhpcy5jb252ZXJ0VmFsdWVzKG9jYy5nZXREYXRhKCksIG9jYy5nZXRTdHJ1Y3R1cmUoKSkgOiB7fTtcbiAgICAgICAgdGhpcy5tZXRhID0gb2NjLmdldE1ldGEoKSB8fCB7fTtcbiAgICAgICAgdGhpcy5tb2RpZmllZCA9IG9jYy5pc01vZGlmaWVkKCk7XG4gICAgICAgIHRoaXMubG9ja2VkID0gb2NjLmlzTG9ja2VkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBrID0gb2NjLnBrO1xuICAgICAgICB0aGlzLnN0cnVjdHVyZSA9IG9jYy5zdHJ1Y3R1cmU7XG4gICAgICAgIHRoaXMuZGF0YSA9IG9jYy5kYXRhID8gdGhpcy5jb252ZXJ0VmFsdWVzKG9jYy5kYXRhLCBvY2Muc3RydWN0dXJlKSA6IHt9O1xuICAgICAgICB0aGlzLm1ldGEgPSBvY2MubWV0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5tb2RpZmllZCA9IG9jYy5tb2RpZmllZCA/IG9jYy5tb2RpZmllZCA6IGZhbHNlO1xuICAgICAgICB0aGlzLmxvY2tlZCA9IG9jYy5sb2NrZWQgPyBvY2MubG9ja2VkIDogZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGsgPSBudWxsO1xuICAgICAgdGhpcy5kYXRhID0ge307XG4gICAgICB0aGlzLnN0cnVjdHVyZSA9IHt9O1xuICAgICAgdGhpcy5tZXRhID0ge307XG4gICAgICB0aGlzLm1vZGlmaWVkID0gZmFsc2U7XG4gICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnNldE1vZGUobW9kZUZsYWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBTdWJFbnRpdGllcyBpbiBkYXRhIHRvIEVudGl0aWVzXG4gICAqIEBwYXJhbSBkYXRhIGRhdGEgdG8gY29udmVydFxuICAgKiBAcGFyYW0gc3RydWN0dXJlIHN0cnVjdHVyZSBvZiBjdXJyZW50IG9jY1xuICAgKiBAcmV0dXJucyBuZXcgZGF0YSBvYmplY3RcbiAgICovXG4gIHByaXZhdGUgY29udmVydFZhbHVlcyhkYXRhOiB7IFtmaWVsZDogc3RyaW5nXTogYW55IH0sIHN0cnVjdHVyZTogRW50aXR5U3RydWN0dXJlKTogeyBbZmllbGQ6IHN0cmluZ106IGFueSB9IHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdHJ1Y3R1cmUpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGRhdGFba2V5LnRvVXBwZXJDYXNlKCldO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGRhdGFba2V5LnRvVXBwZXJDYXNlKCldID0gbmV3IEVudGl0eShcbiAgICAgICAgICB2YWx1ZS5vY2NzID8gdmFsdWUgOiB7IG9jY3M6IHZhbHVlLCBzdHJ1Y3R1cmU6IHN0cnVjdHVyZVtrZXkudG9VcHBlckNhc2UoKV0gfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcGsgb2YgdGhpcyBPY2N1cnJlbmNlXG4gICAqL1xuICBnZXRQaygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBrO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHN0cnVjdHVyZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICovXG4gIGdldFN0cnVjdHVyZSgpOiBFbnRpdHlTdHJ1Y3R1cmUge1xuICAgIHJldHVybiB0aGlzLnN0cnVjdHVyZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGRcbiAgICogQHBhcmFtIGZpZWxkIHRoZSBuYW1lIG9mIHRoZSBmaWVsZFxuICAgKiBAcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkXG4gICAqL1xuICBnZXRWYWx1ZShmaWVsZDogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhW2ZpZWxkLnRvVXBwZXJDYXNlKCldO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIE1vZGUgb2YgdGhpcyBPY2N1cnJlbmNlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlOiAnYWRkJywgJ2NweScsICdkZWwnIGFuZCAnJztcbiAgICogQHJldHVybnMgcmV0dXJucyB0aGUgbW9kZSBvZiB0aGUgb2NjIChNb2RlRmxhZ3MpXG4gICAqL1xuICBnZXRNb2RlKCk6IE1vZGVGbGFncyB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5fbW9kZSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoaXMgT2NjdXJlbmNlXG4gICAqIEBwYXJhbSBjb2wgZ2V0IGRhdGEgd2l0aCBvciB3aXRob3V0IGNvbGxlY3Rpb25zLiBEZWZhdWx0IGlzIHRydWUgKGFsbCBkYXRhKS5cbiAgICovXG4gIGdldERhdGEoY29sPzogYm9vbGVhbik6IG9iamVjdCB7XG4gICAgcmV0dXJuIGNvbCA9PT0gZmFsc2VcbiAgICAgID8gT2JqZWN0LmtleXModGhpcy5kYXRhKVxuICAgICAgICAgIC5maWx0ZXIoKGZpZWxkOiBhbnkpID0+ICF0aGlzLnN0cnVjdHVyZVtmaWVsZC50b1VwcGVyQ2FzZSgpXSlcbiAgICAgICAgICAucmVkdWNlKChwcmV2LCBmaWVsZCkgPT4gT2JqZWN0LmFzc2lnbihwcmV2LCB7IFtmaWVsZF06IHRoaXMuZGF0YVtmaWVsZF0gfSksIHt9KVxuICAgICAgOiB0aGlzLmRhdGE7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgU3ViZW50aXR5IGZyb20gdGhpcyBPY2N1cnJlbmNlXG4gICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBTdWJlbnRpdHlcbiAgICogQHJldHVybnMgcmV0dXJucyB0aGUgc3ViRW50aXR5XG4gICAqL1xuICBnZXRTdWJFbnQobmFtZTogc3RyaW5nKTogRW50aXR5IHtcbiAgICBpZiAoIXRoaXMuaGFzQ29sbGVjdGlvbihuYW1lKSkge1xuICAgICAgcmV0dXJuICh0aGlzLmRhdGFbbmFtZS50b1VwcGVyQ2FzZSgpXSA9IG5ldyBFbnRpdHkoKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRhdGFbbmFtZS50b1VwcGVyQ2FzZSgpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBPY2N1cmVuY2VzIG9mIHRoZSBnaXZlbiBTdWJFbnRpdHlcbiAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIFN1YmVudGl0eVxuICAgKiBAcmV0dXJucyBkYXRhIGZyb20gU3ViRW50aXR5XG4gICAqL1xuICBnZXRDb2xsZWN0aW9uKG5hbWU6IHN0cmluZyk6IE9jY3VycmVuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldID8gdGhpcy5kYXRhW25hbWUudG9VcHBlckNhc2UoKV0ub2NjcyA6IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYSBsaXN0IG9mIGFsbCBmaWVsZHMgb2YgdGhpcyBPY2N1cnJlbmNlXG4gICAqIEBwYXJhbSBjb2wgaWYgdHJ1ZSBhbGwgU3ViZW50aXR5cyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoaXMgbGlzdCwgZGVmYXVsdCBmYWxzZVxuICAgKiBAcmV0dXJucyByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBmaWVsZCBOYW1lc1xuICAgKi9cbiAgZ2V0RmllbGRzKGNvbD86IGJvb2xlYW4pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZmlsdGVyKCh2YWx1ZSkgPT4gY29sIHx8ICF0aGlzLnN0cnVjdHVyZVt2YWx1ZS50b1VwcGVyQ2FzZSgpXSk7XG4gIH1cblxuICAvKipcbiAgICogSGFzIHRoZSBPY2N1cnJlbmNlIGJlZW4gbW9kaWZpZWQ/XG4gICAqIEBwYXJhbSBjaGVja1N1YkVudCBjaGVjayBTdWJlbnRpdGllcyAoZGVmYXVsdDogdHJ1ZSlcbiAgICovXG4gIGlzTW9kaWZpZWQoY2hlY2tTdWJFbnQ6IGJvb2xlYW4gPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubW9kaWZpZWQgfHwgKCFjaGVja1N1YkVudCB8fCAhdGhpcy5oYXNBbnlDb2xsZWN0aW9uKCkgPyB0aGlzLm1vZGlmaWVkIDogdGhpcy5jaGVja1N1YkVudGl0eU1vZGlmaWVkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIGlzIHRoaXMgb2NjdXJlbmNlIGxvY2tlZCBhbmQgY2FuIG5vdCBiZSBlZGl0ZWQ/XG4gICAqL1xuICBpc0xvY2tlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2NrZWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgc3RydWN0dXJlIG9mIHRoZSBnaXZlbiBzdWJlbnRpdHlcbiAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIHN1YmVudGl0eVxuICAgKi9cbiAgZ2V0U3ViRW50aXR5U3RydWN0dXJlKG5hbWU6IHN0cmluZyk6IEVudGl0eVN0cnVjdHVyZSB7XG4gICAgcmV0dXJuIHRoaXMuc3RydWN0dXJlW25hbWUudG9VcHBlckNhc2UoKV07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgTWV0YSBpbmZvcm1hdGlvbnMgb2YgdGhpcyBvY2N1cmVuY2VcbiAgICogQHBhcmFtIGVudGl0eSB0aGUgbmFtZSBvZiBhIHN1YmVudGl0eSwgd2hvc2UgbWV0YSBpbmZvcm1hdGlvbiBzaG91bGQgYmUgcmVhZFxuICAgKi9cbiAgZ2V0TWV0YSgpOiB7IFtlbnRpdHk6IHN0cmluZ106IEZpZWxkTGlzdFtdIH0ge1xuICAgIHJldHVybiB0aGlzLm1ldGE7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgTWV0YSBpbmZvcm1hdGlvbnMgb2YgdGhpcyBvY2N1cmVuY2UgZm9yIHRoZSBnaXZlbiBlbnRpdHluYW1lXG4gICAqIEBwYXJhbSBlbnRpdHkgdGhlIG5hbWUgb2YgYSBzdWJlbnRpdHksIHdob3NlIG1ldGEgaW5mb3JtYXRpb24gc2hvdWxkIGJlIHJlYWRcbiAgICovXG4gIGdldE1ldGFGaWVsZExpc3QoZW50aXR5OiBzdHJpbmcpOiBGaWVsZExpc3Qge1xuICAgIHJldHVybiB0aGlzLm1ldGFbZW50aXR5LnRvVXBwZXJDYXNlKCldXG4gICAgICA/IHRoaXMubWV0YVtlbnRpdHkudG9VcHBlckNhc2UoKV0ucmVkdWNlKChhY2MsIHZhbCkgPT4gT2JqZWN0LmFzc2lnbihhY2MsIHZhbCksIHt9KSB8fCB7fVxuICAgICAgOiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBNZXRhIGluZm9ybWF0aW9uIGZvciBvbmUgZmllbGQsIGlmIGdpdmVuXG4gICAqIEBwYXJhbSBmaWVsZCB0aGUgbmFtZSBvZiB0aGUgZmllbGRcbiAgICogQHBhcmFtIGVudGl0eSB0aGUgbmFtZSBvZiBhIHN1YmVudGl0eSwgd2hlcmUgdGhlIGZpZWxkIHNob3VsZCBiZSBsb29rZWQgdXBcbiAgICovXG4gIGdldE1ldGFGaWVsZChmaWVsZDogc3RyaW5nLCBlbnRpdHk6IHN0cmluZyk6IEZpZWxkIHwge30ge1xuICAgIGNvbnN0IGZpZWxkbmFtZSA9IGZpZWxkLnN0YXJ0c1dpdGgoJ18nKSA/IGZpZWxkIDogZmllbGQudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBtZXRhTGlzdCA9IHRoaXMubWV0YVtlbnRpdHkudG9VcHBlckNhc2UoKV1cbiAgICAgID8gdGhpcy5tZXRhW2VudGl0eS50b1VwcGVyQ2FzZSgpXS5maW5kKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHJldHVybiBmaWVsZG5hbWUgaW4gdmFsdWU7XG4gICAgICAgIH0pXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gbWV0YUxpc3QgPyBtZXRhTGlzdFtmaWVsZG5hbWVdIDoge307XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldCBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBfbW9kZSB2YWx1ZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICogQHBhcmFtIG1vZGUgYm9vbGVhbiwgdGhhdCBkZWZpbmVzIHRoZSBtb2RlLiBBZGQgaWYgdGhpcyBPY2N1cnJlbmNlIHNob3VsZCBiZSBhZGRlZCB0byB0aGUgRGF0YWJhc2UsXG4gICAqIGNweSBpZiB0aGlzIGlzIGEgQ29weSBvZiBhIE9jY3VycnJlbmNlIGFuZCBkZWwgaWYgdGhpcyBPY2N1cnJlbmNlIHNob3VsZCBiZSBkZWxldGVkIGluIHRoZSBEQi5cbiAgICogSWYgbWlzc2luZywgdGhlIF9tb2RlIGZsYWcgd2lsbCBiZSBkZWxldGVkLlxuICAgKiBAcGFyYW0gY29sIHNldCB0aGUgbW9kZSBmb3IgYWxsIHN1YmVudGl0eXMuXG4gICAqL1xuICBzZXRNb2RlKG1vZGU/OiB7IGFkZD86IGJvb2xlYW47IGNweT86IGJvb2xlYW47IGRlbD86IGJvb2xlYW4gfSwgY29sPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChtb2RlKSB7XG4gICAgICBpZiAobW9kZS5kZWwpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkRFTDtcbiAgICAgIH0gZWxzZSBpZiAobW9kZS5jcHkpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkNQWTtcbiAgICAgIH0gZWxzZSBpZiAobW9kZS5hZGQpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkFERDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhLl9tb2RlKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuX21vZGU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLmRhdGEuX21vZGUpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuX21vZGU7XG4gICAgfVxuICAgIGlmIChjb2wpIHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuc3RydWN0dXJlKS5mb3JFYWNoKChzdWJFbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5oYXNPd25Qcm9wZXJ0eShzdWJFbnQpKSB7XG4gICAgICAgICAgdGhpcy5nZXRDb2xsZWN0aW9uKHN1YkVudCkuZm9yRWFjaCgob2NjOiBPY2N1cnJlbmNlKSA9PiBvY2Muc2V0TW9kZShtb2RlLCBjb2wpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHNldHMgdGhlIHBrIHByb3BlcnR5XG4gICAqIEBwYXJhbSBwayBwayB0aGF0IHNob3VsZCBiZSBzZXRcbiAgICovXG4gIGFkZFBrKHBrOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5waykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBrID0gcGs7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZ2l2ZW4gZmllbGQgb24gdGhlIGdpdmVuIHZhbHVlXG4gICAqIEBwYXJhbSBmaWVsZCB0aGUgbmFtZSBvZiB0aGUgZmllbGRcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWVcbiAgICogQHBhcmFtIGlzVXNlckNoYW5nZSBpcyB0aGlzIGNoYW5nZSBhIHVzZXJDaGFuZ2UgYW5kIHNob3VsZCBzZXQgdGhlIG1vZGlmaWVkIEZsYWc/IChkZWZhdWx0OiBmYWxzZSlcbiAgICovXG4gIHNldFZhbHVlKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBhbnksIGlzVXNlckNoYW5nZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKGlzVXNlckNoYW5nZSAmJiB0aGlzLmlzTG9ja2VkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFmaWVsZC5zdGFydHNXaXRoKCdfJykpIHtcbiAgICAgIGZpZWxkID0gZmllbGQudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bmRvdmFsdWUgPSB0aGlzLmRhdGFbZmllbGRdO1xuICAgIHRoaXMuZGF0YVtmaWVsZF0gPSB2YWx1ZTtcblxuICAgIGlmIChpc1VzZXJDaGFuZ2UgJiYgdW5kb3ZhbHVlICE9IHZhbHVlKSB7XG4gICAgICB0aGlzLm1vZGlmaWVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZ2l2ZW4gbGlzdCBvZiBmaWVsZHMgb24gdGhlIGdpdmVuIHZhbHVlc1xuICAgKiBAcGFyYW0gdmFsdWVzIGxpc3Qgb2YgZmllbGRzIGFuZCB2YWx1ZXMgaW4gdGhlIGZvcm0ge2ZpZWxkbmFtZTE6IHZhbHVlMSwgZmllbGRuYW1lMjogdmFsdWUyLCAuLi59XG4gICAqIEBwYXJhbSBpc1VzZXJDaGFuZ2UgaXMgdGhpcyBjaGFuZ2UgYSB1c2VyQ2hhbmdlIGFuZCBzaG91bGQgc2V0IHRoZSBtb2RpZmllZCBGbGFnPyAoZGVmYXVsdDogZmFsc2UpXG4gICAqL1xuICBzZXRWYWx1ZXModmFsdWVzOiB7IFtmaWVsZDogc3RyaW5nXTogYW55IH0sIGlzVXNlckNoYW5nZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKCF2YWx1ZXMgfHwgKGlzVXNlckNoYW5nZSAmJiB0aGlzLmlzTG9ja2VkKCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlcykuZm9yRWFjaCgoW2ZpZWxkLCB2YWx1ZV0pID0+IHRoaXMuc2V0VmFsdWUoZmllbGQsIHZhbHVlLCBpc1VzZXJDaGFuZ2UgJiYgIXRoaXMubW9kaWZpZWQpKTtcbiAgICB0aGlzLmRhdGEgPSB0aGlzLmNvbnZlcnRWYWx1ZXModGhpcy5kYXRhLCB0aGlzLnN0cnVjdHVyZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hhbmdlcyBhbGwgT2NjdXJyZW5jZXMgb2YgdGhlIGdpdmVuIFN1YmVudGl0eVxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG90IHRoZSBzdWJlbnRpdHlcbiAgICogQHBhcmFtIG9jY3MgbGlzdCBvZiB0aGUgbmV3IE9jY3VyZW5jZXNcbiAgICovXG4gIHNldENvbGxlY3Rpb24obmFtZTogc3RyaW5nLCBvY2NzOiBPY2N1cnJlbmNlW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYXNDb2xsZWN0aW9uKG5hbWUudG9VcHBlckNhc2UoKSkpIHtcbiAgICAgIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldLm9jY3MgPSBvY2NzO1xuICAgIH0gZWxzZSBpZiAodGhpcy5nZXRTdWJFbnRpdHlTdHJ1Y3R1cmUobmFtZSkpIHtcbiAgICAgIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldID0gbmV3IEVudGl0eSh7IG9jY3MsIHN0cnVjdHVyZTogdGhpcy5nZXRTdWJFbnRpdHlTdHJ1Y3R1cmUobmFtZSkgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHN0cnVjdHVyZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgb2YgdGhlIHN0cnVjdHVyZVxuICAgKi9cbiAgc2V0U3RydWN0dXJlKHZhbHVlOiBFbnRpdHlTdHJ1Y3R1cmUpOiB2b2lkIHtcbiAgICB0aGlzLnN0cnVjdHVyZSA9IE9iamVjdC5hc3NpZ24odGhpcy5zdHJ1Y3R1cmUsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBtb2RpZmllZCBmbGFnXG4gICAqIEBwYXJhbSBtb2RpZmllZCBvY2MgaXMgbW9kaWZpZWQ/XG4gICAqIEBwYXJhbSBzZXRTdWJFbnRpdGVzIHNob3VsZCB0aGUgbW9kaWZpZWQgZmxhZyBiZSBzZXQgYWxzbyBpbiB0aGUgc3ViZW50aXRlcz9cbiAgICovXG4gIHNldE1vZGlmaWVkKG1vZGlmaWVkOiBib29sZWFuLCBzZXRTdWJFbnRpdGVzOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICB0aGlzLm1vZGlmaWVkID0gbW9kaWZpZWQ7XG4gICAgaWYgKHNldFN1YkVudGl0ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuc3RydWN0dXJlKS5mb3JFYWNoKChlbnROYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgdGhpcy5nZXRTdWJFbnQoZW50TmFtZSkuc2V0TW9kaWZpZWQobW9kaWZpZWQsIHNldFN1YkVudGl0ZXMpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIE1ldGEgaW5mb3JtYXRpb24gZm9yIG9uZSBmaWVsZFxuICAgKiBAcGFyYW0gZmllbGQgdGhlIG5hbWUgb2YgdGhlIGZpZWxkXG4gICAqIEBwYXJhbSBlbnRpdHkgdGhlIG5hbWUgb2YgYSBzdWJlbnRpdHksIHdoZXJlIHRoZSBmaWVsZCBzaG91bGQgYmUgbG9va2VkIHVwXG4gICAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHZhbHVlIG9mIHRoZSBkZWZpbml0aW9uXG4gICAqL1xuICBzZXRNZXRhRmllbGQoZmllbGQ6IHN0cmluZywgZW50aXR5OiBzdHJpbmcsIHZhbHVlOiBGaWVsZCB8IEZpZWxkRGVmKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBjb25zdCBmbGR2YWx1ZSA9IG5ldyBGaWVsZCh2YWx1ZSk7XG4gICAgICBjb25zdCBmbGRuYW1lID0gZmllbGQudG9VcHBlckNhc2UoKTtcbiAgICAgIGNvbnN0IGVudGl0eW5hbWUgPSBlbnRpdHkudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmICghdGhpcy5tZXRhKSB7XG4gICAgICAgIHRoaXMubWV0YSA9IHsgW2VudGl0eW5hbWVdOiBbeyBbZmxkbmFtZV06IGZsZHZhbHVlIH1dIH07XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLm1ldGFbZW50aXR5bmFtZV0pIHtcbiAgICAgICAgdGhpcy5tZXRhW2VudGl0eW5hbWVdID0gW3sgW2ZsZG5hbWVdOiBmbGR2YWx1ZSB9XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG1ldGFMaXN0ID0gdGhpcy5tZXRhW2VudGl0eW5hbWVdLmZpbmQoKGZsZGxzdCkgPT4gZmxkbmFtZSBpbiBmbGRsc3QpO1xuICAgICAgICBpZiAoIW1ldGFMaXN0KSB7XG4gICAgICAgICAgdGhpcy5tZXRhW2VudGl0eW5hbWVdLnB1c2goeyBbZmxkbmFtZV06IGZsZHZhbHVlIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24obWV0YUxpc3RbZmxkbmFtZV0sIGZsZHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBNZXRhIGluZm9ybWF0aW9uIGZvciBvbmUgZW50aXR5XG4gICAqIEBwYXJhbSBlbnRpdHkgdGhlIG5hbWUgb2YgYSBzdWJlbnRpdHksIHdob3NlIG1ldGEgaW5mb3JtYXRpb24gc2hvdWxkIGJlIHNldFxuICAgKiBAcGFyYW0gdmFsdWVzIHRoZSBuZXcgdmFsdWVzIG9mIHRoZSBkZWZpbml0aW9uXG4gICAqL1xuICBzZXRNZXRhRmllbGRMaXN0KGVudGl0eTogc3RyaW5nLCB2YWx1ZXM6IEZpZWxkTGlzdCB8IEZpZWxkTGlzdFtdKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlcykge1xuICAgICAgY29uc3QgZmxkbHN0cyA9IEFycmF5LmlzQXJyYXkodmFsdWVzKSA/IHZhbHVlcyA6IFt2YWx1ZXNdO1xuICAgICAgY29uc3QgZW50aXR5bmFtZSA9IGVudGl0eS50b1VwcGVyQ2FzZSgpO1xuICAgICAgaWYgKCF0aGlzLm1ldGEpIHtcbiAgICAgICAgdGhpcy5tZXRhID0geyBbZW50aXR5bmFtZV06IGZsZGxzdHMgfTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMubWV0YVtlbnRpdHluYW1lXSkge1xuICAgICAgICB0aGlzLm1ldGFbZW50aXR5bmFtZV0gPSBmbGRsc3RzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmxkbHN0cy5mb3JFYWNoKChmbGRsc3QpID0+XG4gICAgICAgICAgT2JqZWN0LmVudHJpZXMoZmxkbHN0KS5mb3JFYWNoKChbZmllbGQsIHZhbHVlXSkgPT4gdGhpcy5zZXRNZXRhRmllbGQoZmllbGQsIGVudGl0eSwgdmFsdWUpKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBNZXRhIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSBtZXRhVmFsdWUgdGhlIG5ldyB2YWx1ZXMgb2YgdGhlIGRlZmluaXRpb25cbiAgICovXG4gIHNldE1ldGEobWV0YVZhbHVlOiB7IFtlbnRpdHk6IHN0cmluZ106IEZpZWxkTGlzdFtdIH0pOiB2b2lkIHtcbiAgICBpZiAobWV0YVZhbHVlKSB7XG4gICAgICBpZiAoIXRoaXMubWV0YSkge1xuICAgICAgICB0aGlzLm1ldGEgPSBtZXRhVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QuZW50cmllcyhtZXRhVmFsdWUpLmZvckVhY2goKFtlbnRpdHksIGZpZWxkbHN0c10pID0+IHtcbiAgICAgICAgICB0aGlzLnNldE1ldGFGaWVsZExpc3QoZW50aXR5LCBmaWVsZGxzdHMpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvcHkgRnVuY3Rpb25zXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogQ29waWVzIHRoZSBnaXZlbiBPY2N1cnJlbmNlIGludG8gdGhpcyBPY2N1cnJlbmNlXG4gICAqIEBwYXJhbSBvY2MgdGhlIE9jY3VycmVuY2UgdGhhdCBzaG91bGQgYmUgY29waWVkXG4gICAqIEBwYXJhbSBjcHkgdGhlIENvcHkgbW9kZSBzaG91bGQgYmUgc2V0XG4gICAqIEBwYXJhbSBpc1VzZXJDaGFuZ2UgaXMgdGhpcyBjaGFuZ2UgYSB1c2VyQ2hhbmdlIGFuZCBzaG91bGQgc2V0IHRoZSBtb2RpZmllZCBGbGFnPyAoZGVmYXVsdDogZmFsc2UpXG4gICAqL1xuICBjb3B5KG9jYzogT2NjdXJyZW5jZSwgY3B5PzogYm9vbGVhbiwgaXNVc2VyQ2hhbmdlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICB0aGlzLnBrID0gb2NjLnBrO1xuICAgIHRoaXMuZGF0YSA9IG9jYy5kYXRhO1xuICAgIHRoaXMuc3RydWN0dXJlID0gb2NjLnN0cnVjdHVyZTtcbiAgICB0aGlzLm1ldGEgPSBvY2MubWV0YTtcbiAgICB0aGlzLm1vZGlmaWVkID0gaXNVc2VyQ2hhbmdlO1xuICAgIHRoaXMubG9ja2VkID0gZmFsc2U7XG4gICAgdGhpcy5zZ