ng-hub-ui-portal
Version:
A flexible Angular portal library for dynamic content rendering with advanced positioning and interaction control
180 lines • 19.5 kB
JavaScript
import { isDefined, isPromise } from 'ng-hub-ui-utils';
import { Subject, zip } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
/**
* A reference to the currently opened (active) portal.
*
* Instances of this class can be injected into your component passed as portal content.
* So you can `.update()`, `.close()` or `.dismiss()` the portal window from your component.
*/
export class HubActivePortal {
/**
* Updates options of an opened portal.
*
* @since 14.2.0
*/
update(options) { }
/**
* Closes the portal with an optional `result` value.
*
* The `HubPortalRef.result` promise will be resolved with the provided value.
*/
close(result) { }
/**
* Dismisses the portal with an optional `reason` value.
*
* The `HubPortalRef.result` promise will be rejected with the provided value.
*/
dismiss(reason) { }
}
const WINDOW_ATTRIBUTES = [
'animation',
'ariaLabelledBy',
'ariaDescribedBy',
'scrollable',
'windowClass',
'portalDialogClass',
'portalContentClass'
];
const BACKDROP_ATTRIBUTES = ['animation', 'backdropClass'];
/**
* A reference to the newly opened portal returned by the `HubPortal.open()` method.
*/
export class HubPortalRef {
_applyWindowOptions(windowInstance, options) {
WINDOW_ATTRIBUTES.forEach((optionName) => {
if (isDefined(options[optionName])) {
windowInstance[optionName] = options[optionName];
}
});
}
/**
* Updates options of an opened portal.
*
* @since 14.2.0
*/
update(options) {
this._applyWindowOptions(this._windowCmptRef.instance, options);
}
/**
* The instance of a component used for the portal content.
*
* When a `TemplateRef` is used as the content or when the portal is closed, will return `undefined`.
*/
get componentInstance() {
if (this._contentRef && this._contentRef.componentRef) {
return this._contentRef.componentRef.instance;
}
}
/**
* The observable that emits when the portal is closed via the `.close()` method.
*
* It will emit the result passed to the `.close()` method.
*/
get closed() {
return this._closed.asObservable().pipe(takeUntil(this._hidden));
}
/**
* The observable that emits when the portal is dismissed via the `.dismiss()` method.
*
* It will emit the reason passed to the `.dismissed()` method by the user.
*/
get dismissed() {
return this._dismissed.asObservable().pipe(takeUntil(this._hidden));
}
/**
* The observable that emits when portal window is closed and animations were finished.
* At this point portal element will be removed from the DOM tree.
*
* This observable will be completed after emitting.
*/
get hidden() {
return this._hidden.asObservable();
}
/**
* The observable that emits when portal is fully visible and animation was finished.
* Portal DOM element is always available synchronously after calling 'portal.open()' service.
*
* This observable will be completed after emitting.
* It will not emit, if portal is closed before open animation is finished.
*/
get shown() {
return this._windowCmptRef.instance.shown.asObservable();
}
constructor(_windowCmptRef, _contentRef, _beforeDismiss) {
this._windowCmptRef = _windowCmptRef;
this._contentRef = _contentRef;
this._beforeDismiss = _beforeDismiss;
this._closed = new Subject();
this._dismissed = new Subject();
this._hidden = new Subject();
_windowCmptRef.instance.dismissEvent.subscribe((reason) => {
this.dismiss(reason);
});
this.result = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
this.result.then(null, () => { });
}
/**
* Closes the portal with an optional `result` value.
*
* The `HubMobalRef.result` promise will be resolved with the provided value.
*/
close(result) {
if (this._windowCmptRef) {
this._closed.next(result);
this._resolve(result);
this._removePortalElements();
}
}
_dismiss(reason) {
this._dismissed.next(reason);
this._reject(reason);
this._removePortalElements();
}
/**
* Dismisses the portal with an optional `reason` value.
*
* The `HubPortalRef.result` promise will be rejected with the provided value.
*/
dismiss(reason) {
if (this._windowCmptRef) {
if (!this._beforeDismiss) {
this._dismiss(reason);
}
else {
const dismiss = this._beforeDismiss();
if (isPromise(dismiss)) {
dismiss.then((result) => {
if (result !== false) {
this._dismiss(reason);
}
}, () => { });
}
else if (dismiss !== false) {
this._dismiss(reason);
}
}
}
}
_removePortalElements() {
const windowTransition$ = this._windowCmptRef.instance.hide();
// hiding window
windowTransition$.subscribe(() => {
const { nativeElement } = this._windowCmptRef.location;
nativeElement.parentNode.removeChild(nativeElement);
this._windowCmptRef.destroy();
this._contentRef?.viewRef?.destroy();
this._windowCmptRef = null;
this._contentRef = null;
});
// all done
zip(windowTransition$).subscribe(() => {
this._hidden.next();
this._hidden.complete();
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydGFsLXJlZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3BvcnRhbC9zcmMvbGliL3BvcnRhbC1yZWYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFjLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRSxPQUFPLEVBQWMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJM0M7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUMzQjs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLE9BQWtDLElBQVMsQ0FBQztJQUNuRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE1BQVksSUFBUyxDQUFDO0lBRTVCOzs7O09BSUc7SUFDSCxPQUFPLENBQUMsTUFBWSxJQUFTLENBQUM7Q0FDOUI7QUFFRCxNQUFNLGlCQUFpQixHQUFhO0lBQ25DLFdBQVc7SUFDWCxnQkFBZ0I7SUFDaEIsaUJBQWlCO0lBQ2pCLFlBQVk7SUFDWixhQUFhO0lBQ2IsbUJBQW1CO0lBQ25CLG9CQUFvQjtDQUNwQixDQUFDO0FBQ0YsTUFBTSxtQkFBbUIsR0FBYSxDQUFDLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUVyRTs7R0FFRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBT2hCLG1CQUFtQixDQUMxQixjQUErQixFQUMvQixPQUF5QjtRQUV6QixpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFrQixFQUFFLEVBQUU7WUFDaEQsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUU7Z0JBQ25DLGNBQWMsQ0FBQyxVQUFVLENBQUMsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDakQ7UUFDRixDQUFDLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRDs7OztPQUlH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WUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250ZW50UmVmLCBpc0RlZmluZWQsIGlzUHJvbWlzZSB9IGZyb20gJ25nLWh1Yi11aS11dGlscyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCB6aXAgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEh1YlBvcnRhbE9wdGlvbnMsIEh1YlBvcnRhbFVwZGF0YWJsZU9wdGlvbnMgfSBmcm9tICcuL3BvcnRhbC1jb25maWcnO1xuaW1wb3J0IHsgSHViUG9ydGFsV2luZG93IH0gZnJvbSAnLi9wb3J0YWwtd2luZG93JztcblxuLyoqXG4gKiBBIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudGx5IG9wZW5lZCAoYWN0aXZlKSBwb3J0YWwuXG4gKlxuICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgY2FuIGJlIGluamVjdGVkIGludG8geW91ciBjb21wb25lbnQgcGFzc2VkIGFzIHBvcnRhbCBjb250ZW50LlxuICogU28geW91IGNhbiBgLnVwZGF0ZSgpYCwgYC5jbG9zZSgpYCBvciBgLmRpc21pc3MoKWAgdGhlIHBvcnRhbCB3aW5kb3cgZnJvbSB5b3VyIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIEh1YkFjdGl2ZVBvcnRhbCB7XG5cdC8qKlxuXHQgKiBVcGRhdGVzIG9wdGlvbnMgb2YgYW4gb3BlbmVkIHBvcnRhbC5cblx0ICpcblx0ICogQHNpbmNlIDE0LjIuMFxuXHQgKi9cblx0dXBkYXRlKG9wdGlvbnM6IEh1YlBvcnRhbFVwZGF0YWJsZU9wdGlvbnMpOiB2b2lkIHt9XG5cdC8qKlxuXHQgKiBDbG9zZXMgdGhlIHBvcnRhbCB3aXRoIGFuIG9wdGlvbmFsIGByZXN1bHRgIHZhbHVlLlxuXHQgKlxuXHQgKiBUaGUgYEh1YlBvcnRhbFJlZi5yZXN1bHRgIHByb21pc2Ugd2lsbCBiZSByZXNvbHZlZCB3aXRoIHRoZSBwcm92aWRlZCB2YWx1ZS5cblx0ICovXG5cdGNsb3NlKHJlc3VsdD86IGFueSk6IHZvaWQge31cblxuXHQvKipcblx0ICogRGlzbWlzc2VzIHRoZSBwb3J0YWwgd2l0aCBhbiBvcHRpb25hbCBgcmVhc29uYCB2YWx1ZS5cblx0ICpcblx0ICogVGhlIGBIdWJQb3J0YWxSZWYucmVzdWx0YCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgcHJvdmlkZWQgdmFsdWUuXG5cdCAqL1xuXHRkaXNtaXNzKHJlYXNvbj86IGFueSk6IHZvaWQge31cbn1cblxuY29uc3QgV0lORE9XX0FUVFJJQlVURVM6IHN0cmluZ1tdID0gW1xuXHQnYW5pbWF0aW9uJyxcblx0J2FyaWFMYWJlbGxlZEJ5Jyxcblx0J2FyaWFEZXNjcmliZWRCeScsXG5cdCdzY3JvbGxhYmxlJyxcblx0J3dpbmRvd0NsYXNzJyxcblx0J3BvcnRhbERpYWxvZ0NsYXNzJyxcblx0J3BvcnRhbENvbnRlbnRDbGFzcydcbl07XG5jb25zdCBCQUNLRFJPUF9BVFRSSUJVVEVTOiBzdHJpbmdbXSA9IFsnYW5pbWF0aW9uJywgJ2JhY2tkcm9wQ2xhc3MnXTtcblxuLyoqXG4gKiBBIHJlZmVyZW5jZSB0byB0aGUgbmV3bHkgb3BlbmVkIHBvcnRhbCByZXR1cm5lZCBieSB0aGUgYEh1YlBvcnRhbC5vcGVuKClgIG1ldGhvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEh1YlBvcnRhbFJlZiB7XG5cdHByaXZhdGUgX2Nsb3NlZCA9IG5ldyBTdWJqZWN0PGFueT4oKTtcblx0cHJpdmF0ZSBfZGlzbWlzc2VkID0gbmV3IFN1YmplY3Q8YW55PigpO1xuXHRwcml2YXRlIF9oaWRkZW4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXHRwcml2YXRlIF9yZXNvbHZlITogKHJlc3VsdD86IGFueSkgPT4gdm9pZDtcblx0cHJpdmF0ZSBfcmVqZWN0ITogKHJlYXNvbj86IGFueSkgPT4gdm9pZDtcblxuXHRwcml2YXRlIF9hcHBseVdpbmRvd09wdGlvbnMoXG5cdFx0d2luZG93SW5zdGFuY2U6IEh1YlBvcnRhbFdpbmRvdyxcblx0XHRvcHRpb25zOiBIdWJQb3J0YWxPcHRpb25zXG5cdCk6IHZvaWQge1xuXHRcdFdJTkRPV19BVFRSSUJVVEVTLmZvckVhY2goKG9wdGlvbk5hbWU6IHN0cmluZykgPT4ge1xuXHRcdFx0aWYgKGlzRGVmaW5lZChvcHRpb25zW29wdGlvbk5hbWVdKSkge1xuXHRcdFx0XHR3aW5kb3dJbnN0YW5jZVtvcHRpb25OYW1lXSA9IG9wdGlvbnNbb3B0aW9uTmFtZV07XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyBvcHRpb25zIG9mIGFuIG9wZW5lZCBwb3J0YWwuXG5cdCAqXG5cdCAqIEBzaW5jZSAxNC4yLjBcblx0ICovXG5cdHVwZGF0ZShvcHRpb25zOiBIdWJQb3J0YWxVcGRhdGFibGVPcHRpb25zKTogdm9pZCB7XG5cdFx0dGhpcy5fYXBwbHlXaW5kb3dPcHRpb25zKHRoaXMuX3dpbmRvd0NtcHRSZWYuaW5zdGFuY2UsIG9wdGlvbnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBpbnN0YW5jZSBvZiBhIGNvbXBvbmVudCB1c2VkIGZvciB0aGUgcG9ydGFsIGNvbnRlbnQuXG5cdCAqXG5cdCAqIFdoZW4gYSBgVGVtcGxhdGVSZWZgIGlzIHVzZWQgYXMgdGhlIGNvbnRlbnQgb3Igd2hlbiB0aGUgcG9ydGFsIGlzIGNsb3NlZCwgd2lsbCByZXR1cm4gYHVuZGVmaW5lZGAuXG5cdCAqL1xuXHRnZXQgY29tcG9uZW50SW5zdGFuY2UoKTogYW55IHtcblx0XHRpZiAodGhpcy5fY29udGVudFJlZiAmJiB0aGlzLl9jb250ZW50UmVmLmNvbXBvbmVudFJlZikge1xuXHRcdFx0cmV0dXJuIHRoaXMuX2NvbnRlbnRSZWYuY29tcG9uZW50UmVmLmluc3RhbmNlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgcHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdoZW4gdGhlIHBvcnRhbCBpcyBjbG9zZWQgYW5kIHJlamVjdGVkIHdoZW4gdGhlIHBvcnRhbCBpcyBkaXNtaXNzZWQuXG5cdCAqL1xuXHRyZXN1bHQ6IFByb21pc2U8YW55PjtcblxuXHQvKipcblx0ICogVGhlIG9ic2VydmFibGUgdGhhdCBlbWl0cyB3aGVuIHRoZSBwb3J0YWwgaXMgY2xvc2VkIHZpYSB0aGUgYC5jbG9zZSgpYCBtZXRob2QuXG5cdCAqXG5cdCAqIEl0IHdpbGwgZW1pdCB0aGUgcmVzdWx0IHBhc3NlZCB0byB0aGUgYC5jbG9zZSgpYCBtZXRob2QuXG5cdCAqL1xuXHRnZXQgY2xvc2VkKCk6IE9ic2VydmFibGU8YW55PiB7XG5cdFx0cmV0dXJuIHRoaXMuX2Nsb3NlZC5hc09ic2VydmFibGUoKS5waXBlKHRha2VVbnRpbCh0aGlzLl9oaWRkZW4pKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHdoZW4gdGhlIHBvcnRhbCBpcyBkaXNtaXNzZWQgdmlhIHRoZSBgLmRpc21pc3MoKWAgbWV0aG9kLlxuXHQgKlxuXHQgKiBJdCB3aWxsIGVtaXQgdGhlIHJlYXNvbiBwYXNzZWQgdG8gdGhlIGAuZGlzbWlzc2VkKClgIG1ldGhvZCBieSB0aGUgdXNlci5cblx0ICovXG5cdGdldCBkaXNtaXNzZWQoKTogT2JzZXJ2YWJsZTxhbnk+IHtcblx0XHRyZXR1cm4gdGhpcy5fZGlzbWlzc2VkLmFzT2JzZXJ2YWJsZSgpLnBpcGUodGFrZVVudGlsKHRoaXMuX2hpZGRlbikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBwb3J0YWwgd2luZG93IGlzIGNsb3NlZCBhbmQgYW5pbWF0aW9ucyB3ZXJlIGZpbmlzaGVkLlxuXHQgKiBBdCB0aGlzIHBvaW50IHBvcnRhbCBlbGVtZW50IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBET00gdHJlZS5cblx0ICpcblx0ICogVGhpcyBvYnNlcnZhYmxlIHdpbGwgYmUgY29tcGxldGVkIGFmdGVyIGVtaXR0aW5nLlxuXHQgKi9cblx0Z2V0IGhpZGRlbigpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcblx0XHRyZXR1cm4gdGhpcy5faGlkZGVuLmFzT2JzZXJ2YWJsZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBwb3J0YWwgaXMgZnVsbHkgdmlzaWJsZSBhbmQgYW5pbWF0aW9uIHdhcyBmaW5pc2hlZC5cblx0ICogUG9ydGFsIERPTSBlbGVtZW50IGlzIGFsd2F5cyBhdmFpbGFibGUgc3luY2hyb25vdXNseSBhZnRlciBjYWxsaW5nICdwb3J0YWwub3BlbigpJyBzZXJ2aWNlLlxuXHQgKlxuXHQgKiBUaGlzIG9ic2VydmFibGUgd2lsbCBiZSBjb21wbGV0ZWQgYWZ0ZXIgZW1pdHRpbmcuXG5cdCAqIEl0IHdpbGwgbm90IGVtaXQsIGlmIHBvcnRhbCBpcyBjbG9zZWQgYmVmb3JlIG9wZW4gYW5pbWF0aW9uIGlzIGZpbmlzaGVkLlxuXHQgKi9cblx0Z2V0IHNob3duKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuXHRcdHJldHVybiB0aGlzLl93aW5kb3dDbXB0UmVmLmluc3RhbmNlLnNob3duLmFzT2JzZXJ2YWJsZSgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBfd2luZG93Q21wdFJlZjogQ29tcG9uZW50UmVmPEh1YlBvcnRhbFdpbmRvdz4sXG5cdFx0cHJpdmF0ZSBfY29udGVudFJlZjogQ29udGVudFJlZixcblx0XHRwcml2YXRlIF9iZWZvcmVEaXNtaXNzPzogKCkgPT4gYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj5cblx0KSB7XG5cdFx0X3dpbmRvd0NtcHRSZWYuaW5zdGFuY2UuZGlzbWlzc0V2ZW50LnN1YnNjcmliZSgocmVhc29uOiBhbnkpID0+IHtcblx0XHRcdHRoaXMuZGlzbWlzcyhyZWFzb24pO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy5yZXN1bHQgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0XHR0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcblx0XHRcdHRoaXMuX3JlamVjdCA9IHJlamVjdDtcblx0XHR9KTtcblx0XHR0aGlzLnJlc3VsdC50aGVuKG51bGwsICgpID0+IHt9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9zZXMgdGhlIHBvcnRhbCB3aXRoIGFuIG9wdGlvbmFsIGByZXN1bHRgIHZhbHVlLlxuXHQgKlxuXHQgKiBUaGUgYEh1Yk1vYmFsUmVmLnJlc3VsdGAgcHJvbWlzZSB3aWxsIGJlIHJlc29sdmVkIHdpdGggdGhlIHByb3ZpZGVkIHZhbHVlLlxuXHQgKi9cblx0Y2xvc2UocmVzdWx0PzogYW55KTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuX3dpbmRvd0NtcHRSZWYpIHtcblx0XHRcdHRoaXMuX2Nsb3NlZC5uZXh0KHJlc3VsdCk7XG5cdFx0XHR0aGlzLl9yZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHR0aGlzLl9yZW1vdmVQb3J0YWxFbGVtZW50cygpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgX2Rpc21pc3MocmVhc29uPzogYW55KSB7XG5cdFx0dGhpcy5fZGlzbWlzc2VkLm5leHQocmVhc29uKTtcblx0XHR0aGlzLl9yZWplY3QocmVhc29uKTtcblx0XHR0aGlzLl9yZW1vdmVQb3J0YWxFbGVtZW50cygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc21pc3NlcyB0aGUgcG9ydGFsIHdpdGggYW4gb3B0aW9uYWwgYHJlYXNvbmAgdmFsdWUuXG5cdCAqXG5cdCAqIFRoZSBgSHViUG9ydGFsUmVmLnJlc3VsdGAgcHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHByb3ZpZGVkIHZhbHVlLlxuXHQgKi9cblx0ZGlzbWlzcyhyZWFzb24/OiBhbnkpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5fd2luZG93Q21wdFJlZikge1xuXHRcdFx0aWYgKCF0aGlzLl9iZWZvcmVEaXNtaXNzKSB7XG5cdFx0XHRcdHRoaXMuX2Rpc21pc3MocmVhc29uKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IGRpc21pc3MgPSB0aGlzLl9iZWZvcmVEaXNtaXNzKCk7XG5cdFx0XHRcdGlmIChpc1Byb21pc2UoZGlzbWlzcykpIHtcblx0XHRcdFx0XHRkaXNtaXNzLnRoZW4oXG5cdFx0XHRcdFx0XHQocmVzdWx0KSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmIChyZXN1bHQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGlzbWlzcyhyZWFzb24pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0KCkgPT4ge31cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRpc21pc3MgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0dGhpcy5fZGlzbWlzcyhyZWFzb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfcmVtb3ZlUG9ydGFsRWxlbWVudHMoKSB7XG5cdFx0Y29uc3Qgd2luZG93VHJhbnNpdGlvbiQgPSB0aGlzLl93aW5kb3dDbXB0UmVmLmluc3RhbmNlLmhpZGUoKTtcblxuXHRcdC8vIGhpZGluZyB3aW5kb3dcblx0XHR3aW5kb3dUcmFuc2l0aW9uJC5zdWJzY3JpYmUoKCkgPT4ge1xuXHRcdFx0Y29uc3QgeyBuYXRpdmVFbGVtZW50IH0gPSB0aGlzLl93aW5kb3dDbXB0UmVmLmxvY2F0aW9uO1xuXHRcdFx0bmF0aXZlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5hdGl2ZUVsZW1lbnQpO1xuXHRcdFx0dGhpcy5fd2luZG93Q21wdFJlZi5kZXN0cm95KCk7XG5cdFx0XHR0aGlzLl9jb250ZW50UmVmPy52aWV3UmVmPy5kZXN0cm95KCk7XG5cblx0XHRcdHRoaXMuX3dpbmRvd0NtcHRSZWYgPSA8YW55Pm51bGw7XG5cdFx0XHR0aGlzLl9jb250ZW50UmVmID0gPGFueT5udWxsO1xuXHRcdH0pO1xuXG5cdFx0Ly8gYWxsIGRvbmVcblx0XHR6aXAod2luZG93VHJhbnNpdGlvbiQpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHR0aGlzLl9oaWRkZW4ubmV4dCgpO1xuXHRcdFx0dGhpcy5faGlkZGVuLmNvbXBsZXRlKCk7XG5cdFx0fSk7XG5cdH1cbn1cbiJdfQ==