@fireflysemantics/slice
Version:

222 lines • 25.2 kB
JavaScript
import { AbstractStore } from "./AbstractStore";
const { isArray } = Array;
export class Slice extends AbstractStore {
/**
* perform initial notification to all observers,
* such that operations like {@link combineLatest}{}
* will execute at least once.
*
* @param label The slice label
* @param predicate The slice predicate
* @param eStore The EStore instance containing the elements considered for slicing
*
* @example
* ```
* //Empty slice
* new Slice<Todo>(Todo.COMPLETE, todo=>!todo.complete);
*
* //Initialized slice
* let todos = [new Todo(false, "You complete me!"),
* new Todo(true, "You completed me!")];
* new Slice<Todo>(Todo.COMPLETE, todo=>!todo.complete, todos);
* ```
*/
constructor(label, predicate, eStore) {
super();
this.label = label;
this.predicate = predicate;
this.eStore = eStore;
/* The slice element entries */
this.entries = new Map();
const entities = eStore.allSnapshot();
this.config = eStore.config;
let passed = this.test(predicate, entities);
const delta = { type: "Initialize" /* ActionTypes.INTIALIZE */, entries: passed };
this.post(passed);
this.notifyDelta.next(delta);
}
/**
* Add the element if it satisfies the predicate
* and notify subscribers that an element was added.
*
* @param e The element to be considered for slicing
*/
post(e) {
if (isArray(e)) {
this.postA(e);
}
else {
if (this.predicate(e)) {
const id = e[this.config.guidKey];
this.entries.set(id, e);
const delta = { type: "Post" /* ActionTypes.POST */, entries: [e] };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
}
}
/**
* Add the elements if they satisfy the predicate
* and notify subscribers that elements were added.
*
* @param e The element to be considered for slicing
*/
postN(...e) {
this.postA(e);
}
/**
* Add the elements if they satisfy the predicate
* and notify subscribers that elements were added.
*
* @param e The element to be considered for slicing
*/
postA(e) {
const d = [];
e.forEach(e => {
if (this.predicate(e)) {
const id = e[this.config.guidKey];
this.entries.set(id, e);
d.push(e);
}
});
const delta = { type: "Post" /* ActionTypes.POST */, entries: d };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
/**
* Delete an element from the slice.
*
* @param e The element to be deleted if it satisfies the predicate
*/
delete(e) {
if (isArray(e)) {
this.deleteA(e);
}
else {
if (this.predicate(e)) {
const id = e[this.config.guidKey];
this.entries.delete(id);
const delta = { type: "Delete" /* ActionTypes.DELETE */, entries: [e] };
this.notifyAll(Array.from(this.entries.values()), delta);
}
}
}
/**
* @param e The elements to be deleted if it satisfies the predicate
*/
deleteN(...e) {
this.deleteA(e);
}
/**
* @param e The elements to be deleted if they satisfy the predicate
*/
deleteA(e) {
const d = [];
e.forEach(e => {
if (this.predicate(e)) {
const id = e[this.config.guidKey];
d.push(this.entries.get(id));
this.entries.delete(id);
}
});
const delta = { type: "Delete" /* ActionTypes.DELETE */, entries: d };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
/**
* Update the slice when an Entity instance mutates.
*
* @param e The element to be added or deleted depending on predicate reevaluation
*/
put(e) {
if (isArray(e)) {
this.putA(e);
}
else {
const id = e[this.config.guidKey];
if (this.entries.get(id)) {
if (!this.predicate(e)) {
//Note that this is a ActionTypes.DELETE because we are removing the
//entity from the slice.
const delta = { type: "Delete" /* ActionTypes.DELETE */, entries: [e] };
this.entries.delete(id);
this.notifyAll([...Array.from(this.entries.values())], delta);
}
}
else if (this.predicate(e)) {
this.entries.set(id, e);
const delta = { type: "Put" /* ActionTypes.PUT */, entries: [e] };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
}
}
/**
* Update the slice with mutated Entity instances.
*
* @param e The elements to be deleted if it satisfies the predicate
*/
putN(...e) {
this.putA(e);
}
/**
* @param e The elements to be put
*/
putA(e) {
const d = []; //instances to delete
const u = []; //instances to update
e.forEach(e => {
const id = e[this.config.guidKey];
if (this.entries.get(id)) {
if (!this.predicate(e)) {
d.push(this.entries.get(id));
}
}
else if (this.predicate(e)) {
u.push(e);
}
});
if (d.length > 0) {
d.forEach(e => {
this.entries.delete(e[this.config.guidKey]);
});
const delta = { type: "Delete" /* ActionTypes.DELETE */, entries: d };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
if (u.length > 0) {
u.forEach(e => {
this.entries.set(e[this.config.guidKey], e);
});
const delta = { type: "Put" /* ActionTypes.PUT */, entries: u };
this.notifyAll([...Array.from(this.entries.values())], delta);
}
}
/**
* Resets the slice to empty.
*/
reset() {
let delta = {
type: "Reset" /* ActionTypes.RESET */,
entries: [...Array.from(this.entries.values())]
};
this.notifyAll([], delta);
this.entries = new Map();
}
/**
* Utility method that applies the predicate to an array
* of entities and return the ones that pass the test.
*
* Used to create an initial set of values
* that should be part of the `Slice`.
*
* @param p
* @param e
* @return The the array of entities that pass the predicate test.
*/
test(p, e) {
let v = [];
e.forEach((e) => {
if (p(e)) {
v.push(e);
}
});
return v;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2xpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zbGljZS9zcmMvbGliL1NsaWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUkvQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsS0FBSyxDQUFBO0FBRXpCLE1BQU0sT0FBTyxLQUFTLFNBQVEsYUFBZ0I7SUFNMUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FtQkc7SUFDSCxZQUNXLEtBQWEsRUFDYixTQUF1QixFQUN2QixNQUFpQjtRQUN4QixLQUFLLEVBQUUsQ0FBQztRQUhELFVBQUssR0FBTCxLQUFLLENBQVE7UUFDYixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBQ3ZCLFdBQU0sR0FBTixNQUFNLENBQVc7UUExQjVCLCtCQUErQjtRQUNmLFlBQU8sR0FBbUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQTJCaEQsTUFBTSxRQUFRLEdBQVEsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQTtRQUMzQixJQUFJLE1BQU0sR0FBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNqRCxNQUFNLEtBQUssR0FBYSxFQUFFLElBQUksMENBQXVCLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3pFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsSUFBSSxDQUFDLENBQVU7UUFDWCxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7U0FD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YTtZQUNsQixJQUFJLGlDQUFtQjtZQUN2QixPQUFPLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1NBQ2xELENBQUM7UUFDRixJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxJQUFJLENBQUMsQ0FBZSxFQUFFLENBQU07UUFDL0IsSUFBSSxDQUFDLEdBQVEsRUFBRSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFJLEVBQUUsRUFBRTtZQUNmLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNOLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDYjtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLENBQUM7SUFDYixDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZWx0YSwgQWN0aW9uVHlwZXMsIFByZWRpY2F0ZSB9IGZyb20gXCIuL21vZGVsc1wiXG5pbXBvcnQgeyBBYnN0cmFjdFN0b3JlIH0gZnJvbSBcIi4vQWJzdHJhY3RTdG9yZVwiXG5pbXBvcnQgeyBFU3RvcmUgfSBmcm9tIFwiLi9FU3RvcmVcIjtcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuY29uc3QgeyBpc0FycmF5IH0gPSBBcnJheVxuXG5leHBvcnQgY2xhc3MgU2xpY2U8RT4gZXh0ZW5kcyBBYnN0cmFjdFN0b3JlPEU+IHtcblxuXG4gICAgLyogVGhlIHNsaWNlIGVsZW1lbnQgZW50cmllcyAqL1xuICAgIHB1YmxpYyBvdmVycmlkZSBlbnRyaWVzOiBNYXA8c3RyaW5nLCBFPiA9IG5ldyBNYXAoKTtcblxuICAgIC8qKlxuICAgICAqIHBlcmZvcm0gaW5pdGlhbCBub3RpZmljYXRpb24gdG8gYWxsIG9ic2VydmVycyxcbiAgICAgKiBzdWNoIHRoYXQgb3BlcmF0aW9ucyBsaWtlIHtAbGluayBjb21iaW5lTGF0ZXN0fXt9XG4gICAgICogd2lsbCBleGVjdXRlIGF0IGxlYXN0IG9uY2UuXG4gICAgICogXG4gICAgICogQHBhcmFtIGxhYmVsIFRoZSBzbGljZSBsYWJlbFxuICAgICAqIEBwYXJhbSBwcmVkaWNhdGUgVGhlIHNsaWNlIHByZWRpY2F0ZVxuICAgICAqIEBwYXJhbSBlU3RvcmUgVGhlIEVTdG9yZSBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBlbGVtZW50cyBjb25zaWRlcmVkIGZvciBzbGljaW5nXG4gICAgICogXG4gICAgICogQGV4YW1wbGUgXG4gICAgICogYGBgXG4gICAgICogIC8vRW1wdHkgc2xpY2VcbiAgICAgKiAgbmV3IFNsaWNlPFRvZG8+KFRvZG8uQ09NUExFVEUsIHRvZG89PiF0b2RvLmNvbXBsZXRlKTtcbiAgICAgKlxuICAgICAqICAvL0luaXRpYWxpemVkIHNsaWNlXG4gICAgICogIGxldCB0b2RvcyA9IFtuZXcgVG9kbyhmYWxzZSwgXCJZb3UgY29tcGxldGUgbWUhXCIpLCBcbiAgICAgKiAgICAgICAgICAgICAgIG5ldyBUb2RvKHRydWUsIFwiWW91IGNvbXBsZXRlZCBtZSFcIildO1xuICAgICAqICBuZXcgU2xpY2U8VG9kbz4oVG9kby5DT01QTEVURSwgdG9kbz0+IXRvZG8uY29tcGxldGUsIHRvZG9zKTtcbiAgICAgKiAgYGBgXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBsYWJlbDogc3RyaW5nLFxuICAgICAgICBwdWJsaWMgcHJlZGljYXRlOiBQcmVkaWNhdGU8RT4sXG4gICAgICAgIHB1YmxpYyBlU3RvcmU6IEVTdG9yZTxFPikge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCBlbnRpdGllczogRVtdID0gZVN0b3JlLmFsbFNuYXBzaG90KClcbiAgICAgICAgdGhpcy5jb25maWcgPSBlU3RvcmUuY29uZmlnXG4gICAgICAgIGxldCBwYXNzZWQ6IEVbXSA9IHRoaXMudGVzdChwcmVkaWNhdGUsIGVudGl0aWVzKTtcbiAgICAgICAgY29uc3QgZGVsdGE6IERlbHRhPEU+ID0geyB0eXBlOiBBY3Rpb25UeXBlcy5JTlRJQUxJWkUsIGVudHJpZXM6IHBhc3NlZCB9O1xuICAgICAgICB0aGlzLnBvc3QocGFzc2VkKTtcbiAgICAgICAgdGhpcy5ub3RpZnlEZWx0YS5uZXh0KGRlbHRhKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCB0aGUgZWxlbWVudCBpZiBpdCBzYXRpc2ZpZXMgdGhlIHByZWRpY2F0ZVxuICAgICAqIGFuZCBub3RpZnkgc3Vic2NyaWJlcnMgdGhhdCBhbiBlbGVtZW50IHdhcyBhZGRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIFRoZSBlbGVtZW50IHRvIGJlIGNvbnNpZGVyZWQgZm9yIHNsaWNpbmdcbiAgICAgKi9cbiAgICBwb3N0KGU6IEUgfCBFW10pIHtcbiAgICAgICAgaWYgKGlzQXJyYXkoZSkpIHtcbiAgICAgICAgICAgIHRoaXMucG9zdEEoZSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZWRpY2F0ZShlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gKDxhbnk+ZSlbdGhpcy5jb25maWcuZ3VpZEtleV07XG4gICAgICAgICAgICAgICAgdGhpcy5lbnRyaWVzLnNldChpZCwgZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVsdGE6IERlbHRhPEU+ID0geyB0eXBlOiBBY3Rpb25UeXBlcy5QT1NULCBlbnRyaWVzOiBbZV0gfTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUFsbChbLi4uQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMudmFsdWVzKCkpXSwgZGVsdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIHRoZSBlbGVtZW50cyBpZiB0aGV5IHNhdGlzZnkgdGhlIHByZWRpY2F0ZVxuICAgICAqIGFuZCBub3RpZnkgc3Vic2NyaWJlcnMgdGhhdCBlbGVtZW50cyB3ZXJlIGFkZGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGUgVGhlIGVsZW1lbnQgdG8gYmUgY29uc2lkZXJlZCBmb3Igc2xpY2luZ1xuICAgICAqL1xuICAgIHBvc3ROKC4uLmU6IEVbXSkge1xuICAgICAgICB0aGlzLnBvc3RBKGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCB0aGUgZWxlbWVudHMgaWYgdGhleSBzYXRpc2Z5IHRoZSBwcmVkaWNhdGVcbiAgICAgKiBhbmQgbm90aWZ5IHN1YnNjcmliZXJzIHRoYXQgZWxlbWVudHMgd2VyZSBhZGRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlIFRoZSBlbGVtZW50IHRvIGJlIGNvbnNpZGVyZWQgZm9yIHNsaWNpbmdcbiAgICAgKi9cbiAgICBwb3N0QShlOiBFW10pIHtcbiAgICAgICAgY29uc3QgZDogRVtdID0gW107XG4gICAgICAgIGUuZm9yRWFjaChlID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZWRpY2F0ZShlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gKDxhbnk+ZSlbdGhpcy5jb25maWcuZ3VpZEtleV07XG4gICAgICAgICAgICAgICAgdGhpcy5lbnRyaWVzLnNldChpZCwgZSk7XG4gICAgICAgICAgICAgICAgZC5wdXNoKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZGVsdGE6IERlbHRhPEU+ID0geyB0eXBlOiBBY3Rpb25UeXBlcy5QT1NULCBlbnRyaWVzOiBkIH07XG4gICAgICAgIHRoaXMubm90aWZ5QWxsKFsuLi5BcnJheS5mcm9tKHRoaXMuZW50cmllcy52YWx1ZXMoKSldLCBkZWx0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVsZXRlIGFuIGVsZW1lbnQgZnJvbSB0aGUgc2xpY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZSBUaGUgZWxlbWVudCB0byBiZSBkZWxldGVkIGlmIGl0IHNhdGlzZmllcyB0aGUgcHJlZGljYXRlXG4gICAgICovXG4gICAgZGVsZXRlKGU6IEUgfCBFW10pIHtcbiAgICAgICAgaWYgKGlzQXJyYXkoZSkpIHtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlQShlKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSAoPGFueT5lKVt0aGlzLmNvbmZpZy5ndWlkS2V5XVxuICAgICAgICAgICAgICAgIHRoaXMuZW50cmllcy5kZWxldGUoaWQpXG4gICAgICAgICAgICAgICAgY29uc3QgZGVsdGE6IERlbHRhPEU+ID0geyB0eXBlOiBBY3Rpb25UeXBlcy5ERUxFVEUsIGVudHJpZXM6IFtlXSB9XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlBbGwoQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMudmFsdWVzKCkpLCBkZWx0YSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBlIFRoZSBlbGVtZW50cyB0byBiZSBkZWxldGVkIGlmIGl0IHNhdGlzZmllcyB0aGUgcHJlZGljYXRlXG4gICAgICovXG4gICAgZGVsZXRlTiguLi5lOiBFW10pIHtcbiAgICAgICAgdGhpcy5kZWxldGVBKGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBlIFRoZSBlbGVtZW50cyB0byBiZSBkZWxldGVkIGlmIHRoZXkgc2F0aXNmeSB0aGUgcHJlZGljYXRlXG4gICAgICovXG4gICAgZGVsZXRlQShlOiBFW10pIHtcbiAgICAgICAgY29uc3QgZDogRVtdID0gW11cbiAgICAgICAgZS5mb3JFYWNoKGUgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSAoPGFueT5lKVt0aGlzLmNvbmZpZy5ndWlkS2V5XVxuICAgICAgICAgICAgICAgIGQucHVzaCh0aGlzLmVudHJpZXMuZ2V0KGlkKSEpXG4gICAgICAgICAgICAgICAgdGhpcy5lbnRyaWVzLmRlbGV0ZShpZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGRlbHRhOiBEZWx0YTxFPiA9IHsgdHlwZTogQWN0aW9uVHlwZXMuREVMRVRFLCBlbnRyaWVzOiBkIH07XG4gICAgICAgIHRoaXMubm90aWZ5QWxsKFsuLi5BcnJheS5mcm9tKHRoaXMuZW50cmllcy52YWx1ZXMoKSldLCBkZWx0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBzbGljZSB3aGVuIGFuIEVudGl0eSBpbnN0YW5jZSBtdXRhdGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGUgVGhlIGVsZW1lbnQgdG8gYmUgYWRkZWQgb3IgZGVsZXRlZCBkZXBlbmRpbmcgb24gcHJlZGljYXRlIHJlZXZhbHVhdGlvblxuICAgICAqL1xuICAgIHB1dChlOiBFIHwgRVtdKSB7XG4gICAgICAgIGlmIChpc0FycmF5KGUpKSB7XG4gICAgICAgICAgICB0aGlzLnB1dEEoZSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gKDxhbnk+ZSlbdGhpcy5jb25maWcuZ3VpZEtleV07XG4gICAgICAgICAgICBpZiAodGhpcy5lbnRyaWVzLmdldChpZCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vTm90ZSB0aGF0IHRoaXMgaXMgYSBBY3Rpb25UeXBlcy5ERUxFVEUgYmVjYXVzZSB3ZSBhcmUgcmVtb3ZpbmcgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vZW50aXR5IGZyb20gdGhlIHNsaWNlLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWx0YTogRGVsdGE8RT4gPSB7IHR5cGU6IEFjdGlvblR5cGVzLkRFTEVURSwgZW50cmllczogW2VdIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW50cmllcy5kZWxldGUoaWQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUFsbChbLi4uQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMudmFsdWVzKCkpXSwgZGVsdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcmVkaWNhdGUoZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVudHJpZXMuc2V0KGlkLCBlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWx0YTogRGVsdGE8RT4gPSB7IHR5cGU6IEFjdGlvblR5cGVzLlBVVCwgZW50cmllczogW2VdIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlBbGwoWy4uLkFycmF5LmZyb20odGhpcy5lbnRyaWVzLnZhbHVlcygpKV0sIGRlbHRhKTtcbiAgICAgICAgICAgIH0gICAgXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHNsaWNlIHdpdGggbXV0YXRlZCBFbnRpdHkgaW5zdGFuY2VzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGUgVGhlIGVsZW1lbnRzIHRvIGJlIGRlbGV0ZWQgaWYgaXQgc2F0aXNmaWVzIHRoZSBwcmVkaWNhdGVcbiAgICAgKi9cbiAgICBwdXROKC4uLmU6IEVbXSkge1xuICAgICAgICB0aGlzLnB1dEEoZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGUgVGhlIGVsZW1lbnRzIHRvIGJlIHB1dFxuICAgICAqL1xuICAgIHB1dEEoZTogRVtdKSB7XG4gICAgICAgIGNvbnN0IGQ6IEVbXSA9IFtdOyAvL2luc3RhbmNlcyB0byBkZWxldGVcbiAgICAgICAgY29uc3QgdTogRVtdID0gW107IC8vaW5zdGFuY2VzIHRvIHVwZGF0ZVxuICAgICAgICBlLmZvckVhY2goZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9ICg8YW55PmUpW3RoaXMuY29uZmlnLmd1aWRLZXldO1xuICAgICAgICAgICAgaWYgKHRoaXMuZW50cmllcy5nZXQoaWQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnByZWRpY2F0ZShlKSkge1xuICAgICAgICAgICAgICAgICAgICBkLnB1c2godGhpcy5lbnRyaWVzLmdldChpZCkhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICAgICAgdS5wdXNoKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZC5mb3JFYWNoKGUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZW50cmllcy5kZWxldGUoKDxhbnk+ZSlbdGhpcy5jb25maWcuZ3VpZEtleV0pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhOiBEZWx0YTxFPiA9IHsgdHlwZTogQWN0aW9uVHlwZXMuREVMRVRFLCBlbnRyaWVzOiBkIH07XG4gICAgICAgICAgICB0aGlzLm5vdGlmeUFsbChbLi4uQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMudmFsdWVzKCkpXSwgZGVsdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHUuZm9yRWFjaChlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVudHJpZXMuc2V0KCg8YW55PmUpW3RoaXMuY29uZmlnLmd1aWRLZXldLCBlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgZGVsdGE6IERlbHRhPEU+ID0geyB0eXBlOiBBY3Rpb25UeXBlcy5QVVQsIGVudHJpZXM6IHUgfTtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5QWxsKFsuLi5BcnJheS5mcm9tKHRoaXMuZW50cmllcy52YWx1ZXMoKSldLCBkZWx0YSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldHMgdGhlIHNsaWNlIHRvIGVtcHR5LlxuICAgICAqL1xuICAgIHJlc2V0KCkge1xuICAgICAgICBsZXQgZGVsdGE6IERlbHRhPEU+ID0ge1xuICAgICAgICAgICAgdHlwZTogQWN0aW9uVHlwZXMuUkVTRVQsXG4gICAgICAgICAgICBlbnRyaWVzOiBbLi4uQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMudmFsdWVzKCkpXVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm5vdGlmeUFsbChbXSwgZGVsdGEpO1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBuZXcgTWFwKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXRpbGl0eSBtZXRob2QgdGhhdCBhcHBsaWVzIHRoZSBwcmVkaWNhdGUgdG8gYW4gYXJyYXlcbiAgICAgKiBvZiBlbnRpdGllcyBhbmQgcmV0dXJuIHRoZSBvbmVzIHRoYXQgcGFzcyB0aGUgdGVzdC5cbiAgICAgKlxuICAgICAqIFVzZWQgdG8gY3JlYXRlIGFuIGluaXRpYWwgc2V0IG9mIHZhbHVlc1xuICAgICAqIHRoYXQgc2hvdWxkIGJlIHBhcnQgb2YgdGhlIGBTbGljZWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcFxuICAgICAqIEBwYXJhbSBlXG4gICAgICogQHJldHVybiBUaGUgdGhlIGFycmF5IG9mIGVudGl0aWVzIHRoYXQgcGFzcyB0aGUgcHJlZGljYXRlIHRlc3QuXG4gICAgICovXG4gICAgcHVibGljIHRlc3QocDogUHJlZGljYXRlPEU+LCBlOiBFW10pOiBFW10ge1xuICAgICAgICBsZXQgdjogRVtdID0gW107XG4gICAgICAgIGUuZm9yRWFjaCgoZTogRSkgPT4ge1xuICAgICAgICAgICAgaWYgKHAoZSkpIHtcbiAgICAgICAgICAgICAgICB2LnB1c2goZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdjtcbiAgICB9XG59XG4iXX0=