UNPKG

gy-foo

Version:

A library that contains all models for the gy-web-project.

459 lines 54.8 kB
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