@dotglitch/ngx-common
Version:
Angular components and utilities that are commonly used.
141 lines • 22.1 kB
JavaScript
import { Component, createComponent } from '@angular/core';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { ulid } from 'ulidx';
import * as i0 from "@angular/core";
import * as i1 from "../../services/theme.service";
/**
* Extend this component to automatically generate
* bindings to a React component.
*
* ! You _must_ override the property `ngReactComponent`
* Failure to do so will result in errors
* `override readonly ngReactComponent = ReactFlowWrappableComponent;`
*/
export class ReactMagicWrapperComponent {
/**
* Wrap an angular component inside of a React memo object.
* Will attempt to bind @Input and @Output properties if provided,
* and will bind the react arguments directly as @Input properties.
*
* @experimental
* @param componentClass Angular component
* @param envInjector An `EnvironmentInjector` instance to be used for the component
* @param injector An `ElementInjector` instance
* @param _inputs
* @param _outputs
* @returns
*/
static { this.WrapAngularComponent = (componentClass, appRef, injector, _inputs = {}, _outputs = {}, additionalChildren = []) => React.memo((args) => {
const id = ulid();
React.useEffect(() => {
const component = createComponent(componentClass, {
environmentInjector: appRef.injector,
elementInjector: injector,
hostElement: document.getElementById(id)
});
appRef.attachView(component.hostView);
// @ts-ignore
// component.hostView = hostView;
Object.assign(_inputs, args);
const { inputs, outputs } = componentClass['ɵcmp'];
// Returns a list of entries that need to be set
// This makes it so that unnecessary setters are not invoked.
const updated = Object.entries(inputs).filter(([parentKey, childKey]) => {
return component.instance[childKey] != _inputs[parentKey];
});
updated.forEach(([parentKey, childKey]) => {
if (_inputs.hasOwnProperty(parentKey))
component.instance[childKey] = _inputs[parentKey];
});
const outputSubscriptions = {};
// Get a list of unregistered outputs
const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]) => {
return !outputSubscriptions[parentKey];
});
// Reverse bind via subscription
newOutputs.forEach(([parentKey, childKey]) => {
if (_outputs.hasOwnProperty(parentKey)) {
const target = component.instance[childKey];
const outputs = _outputs;
const sub = target.subscribe(outputs[parentKey]); // Subscription
outputSubscriptions[parentKey] = sub;
}
});
// Wrap the destroy method to safely release the subscriptions
const originalDestroy = component.onDestroy?.bind(component);
component.onDestroy = (cb) => {
Object.values(outputSubscriptions).forEach(s => s.unsubscribe());
originalDestroy?.(cb);
};
component.changeDetectorRef.detectChanges();
}, []);
// Create a container for the wrapped element and
// all of the siblings we will inject into it's container.
// The double wrapper is necessary for React's mechanisms to properly
// associate things together.
return React.createElement('div', {}, React.createElement("div", { id }), ...additionalChildren);
}); }
constructor(ngContainer, ngTheme, ngZone) {
this.ngContainer = ngContainer;
this.ngTheme = ngTheme;
this.ngZone = ngZone;
this.ngSubscriptions = [
this.ngTheme.subscribe(t => {
this.theme = t;
this.ngOnChanges();
})
];
}
ngOnInit() {
if (!this.ngReactComponent)
throw new Error("ReactMagicWrapperComponent cannot start without a provided ngReactComponent!");
}
ngOnChanges(changes) {
this._render();
}
ngAfterViewInit() {
this._render();
}
ngOnDestroy() {
this._root.unmount();
this.ngSubscriptions.forEach(s => s.unsubscribe());
}
_render() {
if (!this.ngReactComponent)
return;
this.ngZone.runOutsideAngular(() => {
if (!this._root) {
this._root = createRoot(this.ngContainer.element.nativeElement);
}
// List all keys that do not start with `_` nor `ng`
const keys = Object.keys(this).filter(k => !/^(?:_|ng)/.test(k));
// Get all property keys from the class
const propKeys = keys.filter(k => !k.startsWith("on"));
// Get all event handler keys from the class
const evtKeys = keys.filter(k => k.startsWith("on"));
const props = {};
// Project all key properties onto `props`
propKeys.forEach(k => props[k] = this[k]);
// Attempt to ensure no zone is lost during the event emitter fires
this.ngZone.run(() => {
// Bind all event handlers.
// ! important Angular uses EventEmitter, React uses
// a different method of event binding
evtKeys.forEach(k => props[k] = (...args) => this[k].next(args));
});
this._root.render(React.createElement(this.ngReactComponent, { props: props }));
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactMagicWrapperComponent, deps: [{ token: i0.ViewContainerRef }, { token: i1.ThemeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: ReactMagicWrapperComponent, isStandalone: true, selector: "app-react-magic-wrapper", usesOnChanges: true, ngImport: i0, template: ``, isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactMagicWrapperComponent, decorators: [{
type: Component,
args: [{
selector: 'app-react-magic-wrapper',
template: ``,
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i1.ThemeService }, { type: i0.NgZone }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QtbWFnaWMtd3JhcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21tb24vc3JjL2NvbXBvbmVudHMvcmVhY3QtbWFnaWMtd3JhcHBlci9yZWFjdC1tYWdpYy13cmFwcGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlDLFNBQVMsRUFBdUosZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9PLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxVQUFVLEVBQVEsTUFBTSxrQkFBa0IsQ0FBQztBQUdwRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sT0FBTyxDQUFDOzs7QUFHN0I7Ozs7Ozs7R0FPRztBQU1ILE1BQU0sT0FBTywwQkFBMEI7SUFFbkM7Ozs7Ozs7Ozs7OztPQVlHO2FBQ0kseUJBQW9CLEdBQUcsQ0FDMUIsY0FBeUIsRUFDekIsTUFBNEMsRUFDNUMsUUFBa0IsRUFDbEIsVUFBa0MsRUFBRSxFQUNwQyxXQUF3QyxFQUFFLEVBQzFDLHFCQUF3QyxFQUFFLEVBQzVDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFFckIsTUFBTSxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDbEIsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDakIsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLGNBQWMsRUFBRTtnQkFDOUMsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLFFBQVE7Z0JBQ3BDLGVBQWUsRUFBRSxRQUFRO2dCQUN6QixXQUFXLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7YUFDM0MsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdEMsYUFBYTtZQUNi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U0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUseUJBQXlCO29CQUNuQyxRQUFRLEVBQUUsRUFBRTtvQkFDWixVQUFVLEVBQUUsSUFBSTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBBcHBsaWNhdGlvblJlZiwgQ29tcG9uZW50LCBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIEVudmlyb25tZW50SW5qZWN0b3IsIEV2ZW50RW1pdHRlciwgSW5qZWN0b3IsIE5nWm9uZSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMsIFR5cGUsIFZpZXdDb250YWluZXJSZWYsIFZpZXdSZWYsIGNyZWF0ZUNvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgY3JlYXRlUm9vdCwgUm9vdCB9IGZyb20gJ3JlYWN0LWRvbS9jbGllbnQnO1xuXG5pbXBvcnQgeyBUaGVtZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90aGVtZS5zZXJ2aWNlJztcbmltcG9ydCB7IHVsaWQgfSBmcm9tICd1bGlkeCc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuLyoqXG4gKiBFeHRlbmQgdGhpcyBjb21wb25lbnQgdG8gYXV0b21hdGljYWxseSBnZW5lcmF0ZVxuICogYmluZGluZ3MgdG8gYSBSZWFjdCBjb21wb25lbnQuXG4gKlxuICogISBZb3UgX211c3RfIG92ZXJyaWRlIHRoZSBwcm9wZXJ0eSBgbmdSZWFjdENvbXBvbmVudGBcbiAqIEZhaWx1cmUgdG8gZG8gc28gd2lsbCByZXN1bHQgaW4gZXJyb3JzXG4gKiBgb3ZlcnJpZGUgcmVhZG9ubHkgbmdSZWFjdENvbXBvbmVudCA9IFJlYWN0Rmxvd1dyYXBwYWJsZUNvbXBvbmVudDtgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYXBwLXJlYWN0LW1hZ2ljLXdyYXBwZXInLFxuICAgIHRlbXBsYXRlOiBgYCxcbiAgICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIFJlYWN0TWFnaWNXcmFwcGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuXG4gICAgLyoqXG4gICAgICogV3JhcCBhbiBhbmd1bGFyIGNvbXBvbmVudCBpbnNpZGUgb2YgYSBSZWFjdCBtZW1vIG9iamVjdC5cbiAgICAgKiBXaWxsIGF0dGVtcHQgdG8gYmluZCBASW5wdXQgYW5kIEBPdXRwdXQgcHJvcGVydGllcyBpZiBwcm92aWRlZCxcbiAgICAgKiBhbmQgd2lsbCBiaW5kIHRoZSByZWFjdCBhcmd1bWVudHMgZGlyZWN0bHkgYXMgQElucHV0IHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHBhcmFtIGNvbXBvbmVudENsYXNzIEFuZ3VsYXIgY29tcG9uZW50XG4gICAgICogQHBhcmFtIGVudkluamVjdG9yICAgIEFuIGBFbnZpcm9ubWVudEluamVjdG9yYCBpbnN0YW5jZSB0byBiZSB1c2VkIGZvciB0aGUgY29tcG9uZW50XG4gICAgICogQHBhcmFtIGluamVjdG9yICAgICAgIEFuIGBFbGVtZW50SW5qZWN0b3JgIGluc3RhbmNlXG4gICAgICogQHBhcmFtIF9pbnB1dHNcbiAgICAgKiBAcGFyYW0gX291dHB1dHNcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqL1xuICAgIHN0YXRpYyBXcmFwQW5ndWxhckNvbXBvbmVudCA9IChcbiAgICAgICAgY29tcG9uZW50Q2xhc3M6IFR5cGU8YW55PixcbiAgICAgICAgYXBwUmVmOiBPbWl0PEFwcGxpY2F0aW9uUmVmLCAnX3J1bm5pbmdUaWNrJz4sXG4gICAgICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgX2lucHV0czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9LFxuICAgICAgICBfb3V0cHV0czogeyBba2V5OiBzdHJpbmddOiBGdW5jdGlvbiB9ID0ge30sXG4gICAgICAgIGFkZGl0aW9uYWxDaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlW10gPSBbXVxuICAgICkgPT4gUmVhY3QubWVtbygoYXJncykgPT4ge1xuXG4gICAgICAgIGNvbnN0IGlkID0gdWxpZCgpO1xuICAgICAgICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudENsYXNzLCB7XG4gICAgICAgICAgICAgICAgZW52aXJvbm1lbnRJbmplY3RvcjogYXBwUmVmLmluamVjdG9yLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRJbmplY3RvcjogaW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgaG9zdEVsZW1lbnQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGFwcFJlZi5hdHRhY2hWaWV3KGNvbXBvbmVudC5ob3N0Vmlldyk7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAvLyBjb21wb25lbnQuaG9zdFZpZXcgPSBob3N0VmlldztcblxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihfaW5wdXRzLCBhcmdzKTtcblxuICAgICAgICAgICAgY29uc3QgeyBpbnB1dHMsIG91dHB1dHMgfSA9IGNvbXBvbmVudENsYXNzWyfJtWNtcCddO1xuXG4gICAgICAgICAgICAvLyBSZXR1cm5zIGEgbGlzdCBvZiBlbnRyaWVzIHRoYXQgbmVlZCB0byBiZSBzZXRcbiAgICAgICAgICAgIC8vIFRoaXMgbWFrZXMgaXQgc28gdGhhdCB1bm5lY2Vzc2FyeSBzZXR0ZXJzIGFyZSBub3QgaW52b2tlZC5cbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBPYmplY3QuZW50cmllcyhpbnB1dHMpLmZpbHRlcigoW3BhcmVudEtleSwgY2hpbGRLZXldOiBbc3RyaW5nLCBzdHJpbmddKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudC5pbnN0YW5jZVtjaGlsZEtleV0gIT0gX2lucHV0c1twYXJlbnRLZXldO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHVwZGF0ZWQuZm9yRWFjaCgoW3BhcmVudEtleSwgY2hpbGRLZXldOiBbc3RyaW5nLCBzdHJpbmddKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKF9pbnB1dHMuaGFzT3duUHJvcGVydHkocGFyZW50S2V5KSlcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50Lmluc3RhbmNlW2NoaWxkS2V5XSA9IF9pbnB1dHNbcGFyZW50S2V5XTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBvdXRwdXRTdWJzY3JpcHRpb25zOiB7IFtrZXk6IHN0cmluZ106IFN1YnNjcmlwdGlvbiB9ID0ge307XG4gICAgICAgICAgICAvLyBHZXQgYSBsaXN0IG9mIHVucmVnaXN0ZXJlZCBvdXRwdXRzXG4gICAgICAgICAgICBjb25zdCBuZXdPdXRwdXRzID0gT2JqZWN0LmVudHJpZXMob3V0cHV0cykuZmlsdGVyKChbcGFyZW50S2V5LCBjaGlsZEtleV06IFtzdHJpbmcsIHN0cmluZ10pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIW91dHB1dFN1YnNjcmlwdGlvbnNbcGFyZW50S2V5XTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBSZXZlcnNlIGJpbmQgdmlhIHN1YnNjcmlwdGlvblxuICAgICAgICAgICAgbmV3T3V0cHV0cy5mb3JFYWNoKChbcGFyZW50S2V5LCBjaGlsZEtleV06IFtzdHJpbmcsIHN0cmluZ10pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoX291dHB1dHMuaGFzT3duUHJvcGVydHkocGFyZW50S2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQ6IEV2ZW50RW1pdHRlcjx1bmtub3duPiA9IGNvbXBvbmVudC5pbnN0YW5jZVtjaGlsZEtleV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dHMgPSBfb3V0cHV0cztcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdWIgPSB0YXJnZXQuc3Vic2NyaWJlKG91dHB1dHNbcGFyZW50S2V5XSk7IC8vIFN1YnNjcmlwdGlvblxuXG4gICAgICAgICAgICAgICAgICAgIG91dHB1dFN1YnNjcmlwdGlvbnNbcGFyZW50S2V5XSA9IHN1YjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gV3JhcCB0aGUgZGVzdHJveSBtZXRob2QgdG8gc2FmZWx5IHJlbGVhc2UgdGhlIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsRGVzdHJveSA9IGNvbXBvbmVudC5vbkRlc3Ryb3k/LmJpbmQoY29tcG9uZW50KTtcbiAgICAgICAgICAgIGNvbXBvbmVudC5vbkRlc3Ryb3kgPSAoY2IpID0+IHtcbiAgICAgICAgICAgICAgICBPYmplY3QudmFsdWVzKG91dHB1dFN1YnNjcmlwdGlvbnMpLmZvckVhY2gocyA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICAgICAgICAgIG9yaWdpbmFsRGVzdHJveT8uKGNiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29tcG9uZW50LmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSwgW10pO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhIGNvbnRhaW5lciBmb3IgdGhlIHdyYXBwZWQgZWxlbWVudCBhbmRcbiAgICAgICAgLy8gYWxsIG9mIHRoZSBzaWJsaW5ncyB3ZSB3aWxsIGluamVjdCBpbnRvIGl0J3MgY29udGFpbmVyLlxuICAgICAgICAvLyBUaGUgZG91YmxlIHdyYXBwZXIgaXMgbmVjZXNzYXJ5IGZvciBSZWFjdCdzIG1lY2hhbmlzbXMgdG8gcHJvcGVybHlcbiAgICAgICAgLy8gYXNzb2NpYXRlIHRoaW5ncyB0b2dldGhlci5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBpZCB9KSxcbiAgICAgICAgICAgIC4uLmFkZGl0aW9uYWxDaGlsZHJlblxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlYWN0IGNvbXBvbmVudCB0byBiZSB3cmFwcGVkLlxuICAgICAqICEgTXVzdCBiZSBvdmVycmlkZGVuIGZvciB0aGlzIHdyYXBwZXIgdG8gd29ya1xuICAgICAqL1xuICAgIG5nUmVhY3RDb21wb25lbnQ6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PGFueT4gfCBSZWFjdC5Db21wb25lbnRDbGFzczxhbnk+IHwgc3RyaW5nO1xuXG4gICAgcHJpdmF0ZSBfcm9vdDogUm9vdDtcbiAgICBwdWJsaWMgdGhlbWU6IHN0cmluZztcbiAgICBwcml2YXRlIG5nU3Vic2NyaXB0aW9ucyA9IFtcbiAgICAgICAgdGhpcy5uZ1RoZW1lLnN1YnNjcmliZSh0ID0+IHtcbiAgICAgICAgICAgIHRoaXMudGhlbWUgPSB0O1xuICAgICAgICAgICAgdGhpcy5uZ09uQ2hhbmdlcygpO1xuICAgICAgICB9KVxuICAgIF07XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBuZ0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBuZ1RoZW1lOiBUaGVtZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgbmdab25lOiBOZ1pvbmVcbiAgICApIHtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLm5nUmVhY3RDb21wb25lbnQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWFjdE1hZ2ljV3JhcHBlckNvbXBvbmVudCBjYW5ub3Qgc3RhcnQgd2l0aG91dCBhIHByb3ZpZGVkIG5nUmVhY3RDb21wb25lbnQhXCIpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM/OiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3JlbmRlcigpO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5fcmVuZGVyKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuX3Jvb3QudW5tb3VudCgpO1xuICAgICAgICB0aGlzLm5nU3Vic2NyaXB0aW9ucy5mb3JFYWNoKHMgPT4gcy51bnN1YnNjcmliZSgpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5uZ1JlYWN0Q29tcG9uZW50KSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9yb290KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdCA9IGNyZWF0ZVJvb3QodGhpcy5uZ0NvbnRhaW5lci5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBMaXN0IGFsbCBrZXlzIHRoYXQgZG8gbm90IHN0YXJ0IHdpdGggYF9gIG5vciBgbmdgXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXModGhpcykuZmlsdGVyKGsgPT4gIS9eKD86X3xuZykvLnRlc3QoaykpO1xuXG4gICAgICAgICAgICAvLyBHZXQgYWxsIHByb3BlcnR5IGtleXMgZnJvbSB0aGUgY2xhc3NcbiAgICAgICAgICAgIGNvbnN0IHByb3BLZXlzID0ga2V5cy5maWx0ZXIoayA9PiAhay5zdGFydHNXaXRoKFwib25cIikpO1xuICAgICAgICAgICAgLy8gR2V0IGFsbCBldmVudCBoYW5kbGVyIGtleXMgZnJvbSB0aGUgY2xhc3NcbiAgICAgICAgICAgIGNvbnN0IGV2dEtleXMgPSBrZXlzLmZpbHRlcihrID0+IGsuc3RhcnRzV2l0aChcIm9uXCIpKTtcblxuICAgICAgICAgICAgY29uc3QgcHJvcHMgPSB7fTtcbiAgICAgICAgICAgIC8vIFByb2plY3QgYWxsIGtleSBwcm9wZXJ0aWVzIG9udG8gYHByb3BzYFxuICAgICAgICAgICAgcHJvcEtleXMuZm9yRWFjaChrID0+IHByb3BzW2tdID0gdGhpc1trXSk7XG5cbiAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gZW5zdXJlIG5vIHpvbmUgaXMgbG9zdCBkdXJpbmcgdGhlIGV2ZW50IGVtaXR0ZXIgZmlyZXNcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQmluZCBhbGwgZXZlbnQgaGFuZGxlcnMuXG4gICAgICAgICAgICAgICAgLy8gISBpbXBvcnRhbnQgQW5ndWxhciB1c2VzIEV2ZW50RW1pdHRlciwgUmVhY3QgdXNlc1xuICAgICAgICAgICAgICAgIC8vIGEgZGlmZmVyZW50IG1ldGhvZCBvZiBldmVudCBiaW5kaW5nXG4gICAgICAgICAgICAgICAgZXZ0S2V5cy5mb3JFYWNoKGsgPT4gcHJvcHNba10gPSAoLi4uYXJncykgPT4gdGhpc1trXS5uZXh0KGFyZ3MpKTtcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMuX3Jvb3QucmVuZGVyKFJlYWN0LmNyZWF0ZUVsZW1lbnQodGhpcy5uZ1JlYWN0Q29tcG9uZW50LCB7IHByb3BzOiBwcm9wcyBhcyBhbnkgfSkpO1xuICAgICAgICB9KVxuICAgIH1cbn1cbiJdfQ==