@handsontable/angular-wrapper
Version:
Best Data Grid for Angular with Spreadsheet Look and Feel.
147 lines • 20.2 kB
JavaScript
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import Handsontable from 'handsontable/base';
import { HotSettingsResolver } from './services/hot-settings-resolver.service';
import * as i0 from "@angular/core";
import * as i1 from "./services/hot-settings-resolver.service";
import * as i2 from "./services/hot-global-config.service";
export const HOT_DESTROYED_WARNING = 'The Handsontable instance bound to this component was destroyed and cannot be' + ' used properly.';
export class HotTableComponent {
_hotSettingsResolver;
_hotConfig;
ngZone;
// component inputs
/** The data for the Handsontable instance. */
data = null;
/** The settings for the Handsontable instance. */
settings = {};
/** The container element for the Handsontable instance. */
container;
/** The Handsontable instance. */
__hotInstance = null;
configSubscription;
constructor(_hotSettingsResolver, _hotConfig, ngZone) {
this._hotSettingsResolver = _hotSettingsResolver;
this._hotConfig = _hotConfig;
this.ngZone = ngZone;
}
/**
* Gets the Handsontable instance.
* @returns The Handsontable instance or `null` if it's not yet been created or has been destroyed.
*/
get hotInstance() {
if (!this.__hotInstance || (this.__hotInstance && !this.__hotInstance.isDestroyed)) {
// Will return the Handsontable instance or `null` if it's not yet been created.
return this.__hotInstance;
}
else {
console.warn(HOT_DESTROYED_WARNING);
return null;
}
}
/**
* Sets the Handsontable instance.
* @param hotInstance The Handsontable instance to set.
*/
set hotInstance(hotInstance) {
this.__hotInstance = hotInstance;
}
/**
* Initializes the Handsontable instance after the view has been initialized.
* The initial settings of the table are also prepared here
*/
ngAfterViewInit() {
let options = this._hotSettingsResolver.applyCustomSettings(this.settings, this.ngZone);
const negotiatedSettings = this.getNegotiatedSettings(options);
options = { ...options, ...negotiatedSettings, data: this.data };
this.ngZone.runOutsideAngular(() => {
this.hotInstance = new Handsontable.Core(this.container.nativeElement, options);
this.hotInstance.init();
});
this.configSubscription = this._hotConfig.config$.subscribe((config) => {
if (this.hotInstance) {
const negotiatedSettings = this.getNegotiatedSettings(this.settings);
this.updateHotTable(negotiatedSettings);
}
});
}
ngOnChanges(changes) {
if (this.hotInstance === null) {
return;
}
if (changes.settings && !changes.settings.firstChange) {
const newOptions = this._hotSettingsResolver.applyCustomSettings(changes.settings.currentValue, this.ngZone);
this.updateHotTable(newOptions);
}
if (changes.data && !changes.data.firstChange) {
this.hotInstance?.updateData(changes.data.currentValue);
}
}
/**
* Destroys the Handsontable instance and clears the columns from custom editors.
*/
ngOnDestroy() {
this.ngZone.runOutsideAngular(() => {
if (!this.hotInstance) {
return;
}
const columns = this.hotInstance.getSettings().columns;
if (columns && Array.isArray(columns)) {
columns.forEach((column) => {
if (column._editorComponentReference) {
column._editorComponentReference.destroy();
}
});
}
this.hotInstance.destroy();
});
this.configSubscription.unsubscribe();
}
/**
* Updates the Handsontable instance with new settings.
* @param newSettings The new settings to apply to the Handsontable instance.
*/
updateHotTable(newSettings) {
if (!this.hotInstance) {
return;
}
this.ngZone.runOutsideAngular(() => {
this.hotInstance?.updateSettings(newSettings, false);
});
}
/**
* Merges the provided Handsontable grid settings with the global configuration.
*
* This method retrieves the global configuration from the HotGlobalConfigService and negotiates the final
* Handsontable settings by giving precedence to the provided settings.
* Additionally, the `layoutDirection` is only merged if the Handsontable instance has not yet been initialized.
*
* @param settings - The grid settings provided by the user or component.
* @returns The final negotiated grid settings after merging with global defaults.
*/
getNegotiatedSettings(settings) {
const hotConfig = this._hotConfig.getConfig();
const negotiatedSettings = {};
negotiatedSettings.licenseKey = settings.licenseKey ?? hotConfig.license;
negotiatedSettings.themeName = settings.themeName ?? hotConfig.themeName;
negotiatedSettings.language = settings.language ?? hotConfig.language;
// settings that can be set only before the Handsontable instance is initialized
if (!this.__hotInstance) {
negotiatedSettings.layoutDirection = settings.layoutDirection ?? hotConfig.layoutDirection;
}
return negotiatedSettings;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotTableComponent, deps: [{ token: i1.HotSettingsResolver }, { token: i2.HotGlobalConfigService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HotTableComponent, selector: "hot-table", inputs: { data: "data", settings: "settings" }, providers: [HotSettingsResolver], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: '<div #container></div>', isInline: true, styles: [":host{display:block}\n"], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotTableComponent, decorators: [{
type: Component,
args: [{ selector: 'hot-table', template: '<div #container></div>', encapsulation: ViewEncapsulation.None, providers: [HotSettingsResolver], styles: [":host{display:block}\n"] }]
}], ctorParameters: function () { return [{ type: i1.HotSettingsResolver }, { type: i2.HotGlobalConfigService }, { type: i0.NgZone }]; }, propDecorators: { data: [{
type: Input
}], settings: [{
type: Input
}], container: [{
type: ViewChild,
args: ['container', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90LXRhYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2hvdC10YWJsZS9zcmMvbGliL2hvdC10YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFFVCxLQUFLLEVBS0wsU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLFlBQVksTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7OztBQUsvRSxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRywrRUFBK0UsR0FBRyxpQkFBaUIsQ0FBQztBQWV6SSxNQUFNLE9BQU8saUJBQWlCO0lBZVI7SUFBbUQ7SUFBMkM7SUFkbEgsbUJBQW1CO0lBQ25CLDhDQUE4QztJQUNyQyxJQUFJLEdBQTZDLElBQUksQ0FBQztJQUMvRCxrREFBa0Q7SUFDekMsUUFBUSxHQUFpQixFQUFFLENBQUM7SUFFckMsMkRBQTJEO0lBRXBELFNBQVMsQ0FBNkI7SUFFN0MsaUNBQWlDO0lBQ3pCLGFBQWEsR0FBd0IsSUFBSSxDQUFDO0lBQzFDLGtCQUFrQixDQUFlO0lBRXpDLFlBQW9CLG9CQUF5QyxFQUFVLFVBQWtDLEVBQVMsTUFBYztRQUE1Ryx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXFCO1FBQVUsZUFBVSxHQUFWLFVBQVUsQ0FBd0I7UUFBUyxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUVwSTs7O09BR0c7SUFDSCxJQUFXLFdBQVc7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUNsRixnRkFBZ0Y7WUFDaEYsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO1NB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QVcsWUFDWCx3QkFBd0IsaUJBQ25CLGlCQUFpQixDQUFDLElBQUksYUFDMUIsQ0FBQyxtQkFBbUIsQ0FBQztvS0FZdkIsSUFBSTtzQkFBWixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBSUMsU0FBUztzQkFEZixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IEhhbmRzb250YWJsZSBmcm9tICdoYW5kc29udGFibGUvYmFzZSc7XG5pbXBvcnQgeyBIb3RTZXR0aW5nc1Jlc29sdmVyIH0gZnJvbSAnLi9zZXJ2aWNlcy9ob3Qtc2V0dGluZ3MtcmVzb2x2ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBIb3RHbG9iYWxDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9ob3QtZ2xvYmFsLWNvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7IEdyaWRTZXR0aW5ncyB9IGZyb20gJy4vbW9kZWxzL2dyaWQtc2V0dGluZ3MnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBjb25zdCBIT1RfREVTVFJPWUVEX1dBUk5JTkcgPSAnVGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBib3VuZCB0byB0aGlzIGNvbXBvbmVudCB3YXMgZGVzdHJveWVkIGFuZCBjYW5ub3QgYmUnICsgJyB1c2VkIHByb3Blcmx5Lic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hvdC10YWJsZScsXG4gIHRlbXBsYXRlOiAnPGRpdiAjY29udGFpbmVyPjwvZGl2PicsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHByb3ZpZGVyczogW0hvdFNldHRpbmdzUmVzb2x2ZXJdLFxuICBzdHlsZXM6IFtcbiAgICBgXG4gICAgICA6aG9zdCB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgfVxuICAgIGAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEhvdFRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvLyBjb21wb25lbnQgaW5wdXRzXG4gIC8qKiBUaGUgZGF0YSBmb3IgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS4gKi9cbiAgQElucHV0KCkgZGF0YTogSGFuZHNvbnRhYmxlLkdyaWRTZXR0aW5nc1snZGF0YSddIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgc2V0dGluZ3MgZm9yIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UuICovXG4gIEBJbnB1dCgpIHNldHRpbmdzOiBHcmlkU2V0dGluZ3MgPSB7fTtcblxuICAvKiogVGhlIGNvbnRhaW5lciBlbGVtZW50IGZvciB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlLiAqL1xuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7IHN0YXRpYzogZmFsc2UgfSlcbiAgcHVibGljIGNvbnRhaW5lcjogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgLyoqIFRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UuICovXG4gIHByaXZhdGUgX19ob3RJbnN0YW5jZTogSGFuZHNvbnRhYmxlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY29uZmlnU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfaG90U2V0dGluZ3NSZXNvbHZlcjogSG90U2V0dGluZ3NSZXNvbHZlciwgcHJpdmF0ZSBfaG90Q29uZmlnOiBIb3RHbG9iYWxDb25maWdTZXJ2aWNlLCBwdWJsaWMgbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMgVGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBvciBgbnVsbGAgaWYgaXQncyBub3QgeWV0IGJlZW4gY3JlYXRlZCBvciBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGhvdEluc3RhbmNlKCk6IEhhbmRzb250YWJsZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5fX2hvdEluc3RhbmNlIHx8ICh0aGlzLl9faG90SW5zdGFuY2UgJiYgIXRoaXMuX19ob3RJbnN0YW5jZS5pc0Rlc3Ryb3llZCkpIHtcbiAgICAgIC8vIFdpbGwgcmV0dXJuIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2Ugb3IgYG51bGxgIGlmIGl0J3Mgbm90IHlldCBiZWVuIGNyZWF0ZWQuXG4gICAgICByZXR1cm4gdGhpcy5fX2hvdEluc3RhbmNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oSE9UX0RFU1RST1lFRF9XQVJOSU5HKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSBob3RJbnN0YW5jZSBUaGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlIHRvIHNldC5cbiAgICovXG4gIHByaXZhdGUgc2V0IGhvdEluc3RhbmNlKGhvdEluc3RhbmNlKSB7XG4gICAgdGhpcy5fX2hvdEluc3RhbmNlID0gaG90SW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBpbml0aWFsaXplZC5cbiAgICogVGhlIGluaXRpYWwgc2V0dGluZ3Mgb2YgdGhlIHRhYmxlIGFyZSBhbHNvIHByZXBhcmVkIGhlcmVcbiAgICovXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBsZXQgb3B0aW9uczogSGFuZHNvbnRhYmxlLkdyaWRTZXR0aW5ncyA9IHRoaXMuX2hvdFNldHRpbmdzUmVzb2x2ZXIuYXBwbHlDdXN0b21TZXR0aW5ncyh0aGlzLnNldHRpbmdzLCB0aGlzLm5nWm9uZSk7XG5cbiAgICBjb25zdCBuZWdvdGlhdGVkU2V0dGluZ3MgPSB0aGlzLmdldE5lZ290aWF0ZWRTZXR0aW5ncyhvcHRpb25zKTtcbiAgICBvcHRpb25zID0geyAuLi5vcHRpb25zLCAuLi5uZWdvdGlhdGVkU2V0dGluZ3MsIGRhdGE6IHRoaXMuZGF0YSB9O1xuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgdGhpcy5ob3RJbnN0YW5jZSA9IG5ldyBIYW5kc29udGFibGUuQ29yZSh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCBvcHRpb25zKTtcblxuICAgICAgdGhpcy5ob3RJbnN0YW5jZS5pbml0KCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbmZpZ1N1YnNjcmlwdGlvbiA9IHRoaXMuX2hvdENvbmZpZy5jb25maWckLnN1YnNjcmliZSgoY29uZmlnKSA9PiB7XG4gICAgICBpZiAodGhpcy5ob3RJbnN0YW5jZSkge1xuICAgICAgICBjb25zdCBuZWdvdGlhdGVkU2V0dGluZ3MgPSB0aGlzLmdldE5lZ290aWF0ZWRTZXR0aW5ncyh0aGlzLnNldHRpbmdzKTtcbiAgICAgICAgdGhpcy51cGRhdGVIb3RUYWJsZShuZWdvdGlhdGVkU2V0dGluZ3MpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhvdEluc3RhbmNlID09PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMuc2V0dGluZ3MgJiYgIWNoYW5nZXMuc2V0dGluZ3MuZmlyc3RDaGFuZ2UpIHtcbiAgICAgIGNvbnN0IG5ld09wdGlvbnM6IEhhbmRzb250YWJsZS5HcmlkU2V0dGluZ3MgPSB0aGlzLl9ob3RTZXR0aW5nc1Jlc29sdmVyLmFwcGx5Q3VzdG9tU2V0dGluZ3MoXG4gICAgICAgIGNoYW5nZXMuc2V0dGluZ3MuY3VycmVudFZhbHVlLFxuICAgICAgICB0aGlzLm5nWm9uZVxuICAgICAgKTtcblxuICAgICAgdGhpcy51cGRhdGVIb3RUYWJsZShuZXdPcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlcy5kYXRhICYmICFjaGFuZ2VzLmRhdGEuZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMuaG90SW5zdGFuY2U/LnVwZGF0ZURhdGEoY2hhbmdlcy5kYXRhLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UgYW5kIGNsZWFycyB0aGUgY29sdW1ucyBmcm9tIGN1c3RvbSBlZGl0b3JzLlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmhvdEluc3RhbmNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29sdW1ucyA9IHRoaXMuaG90SW5zdGFuY2UuZ2V0U2V0dGluZ3MoKS5jb2x1bW5zO1xuXG4gICAgICBpZiAoY29sdW1ucyAmJiBBcnJheS5pc0FycmF5KGNvbHVtbnMpKSB7XG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sdW1uKSA9PiB7XG4gICAgICAgICAgaWYgKGNvbHVtbi5fZWRpdG9yQ29tcG9uZW50UmVmZXJlbmNlKSB7XG4gICAgICAgICAgICBjb2x1bW4uX2VkaXRvckNvbXBvbmVudFJlZmVyZW5jZS5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5ob3RJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbmZpZ1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSB3aXRoIG5ldyBzZXR0aW5ncy5cbiAgICogQHBhcmFtIG5ld1NldHRpbmdzIFRoZSBuZXcgc2V0dGluZ3MgdG8gYXBwbHkgdG8gdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlSG90VGFibGUobmV3U2V0dGluZ3M6IEhhbmRzb250YWJsZS5HcmlkU2V0dGluZ3MpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG90SW5zdGFuY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB0aGlzLmhvdEluc3RhbmNlPy51cGRhdGVTZXR0aW5ncyhuZXdTZXR0aW5ncywgZmFsc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlcyB0aGUgcHJvdmlkZWQgSGFuZHNvbnRhYmxlIGdyaWQgc2V0dGluZ3Mgd2l0aCB0aGUgZ2xvYmFsIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgSG90R2xvYmFsQ29uZmlnU2VydmljZSBhbmQgbmVnb3RpYXRlcyB0aGUgZmluYWxcbiAgICogSGFuZHNvbnRhYmxlIHNldHRpbmdzIGJ5IGdpdmluZyBwcmVjZWRlbmNlIHRvIHRoZSBwcm92aWRlZCBzZXR0aW5ncy5cbiAgICogQWRkaXRpb25hbGx5LCB0aGUgYGxheW91dERpcmVjdGlvbmAgaXMgb25seSBtZXJnZWQgaWYgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkLlxuICAgKlxuICAgKiBAcGFyYW0gc2V0dGluZ3MgLSBUaGUgZ3JpZCBzZXR0aW5ncyBwcm92aWRlZCBieSB0aGUgdXNlciBvciBjb21wb25lbnQuXG4gICAqIEByZXR1cm5zIFRoZSBmaW5hbCBuZWdvdGlhdGVkIGdyaWQgc2V0dGluZ3MgYWZ0ZXIgbWVyZ2luZyB3aXRoIGdsb2JhbCBkZWZhdWx0cy5cbiAgICovXG4gIHByaXZhdGUgZ2V0TmVnb3RpYXRlZFNldHRpbmdzKHNldHRpbmdzOiBHcmlkU2V0dGluZ3MpOiBIYW5kc29udGFibGUuR3JpZFNldHRpbmdzIHtcbiAgICBjb25zdCBob3RDb25maWcgPSB0aGlzLl9ob3RDb25maWcuZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgbmVnb3RpYXRlZFNldHRpbmdzOiBIYW5kc29udGFibGUuR3JpZFNldHRpbmdzID0ge307XG5cbiAgICBuZWdvdGlhdGVkU2V0dGluZ3MubGljZW5zZUtleSA9IHNldHRpbmdzLmxpY2Vuc2VLZXkgPz8gaG90Q29uZmlnLmxpY2Vuc2U7XG4gICAgbmVnb3RpYXRlZFNldHRpbmdzLnRoZW1lTmFtZSA9IHNldHRpbmdzLnRoZW1lTmFtZSA/PyBob3RDb25maWcudGhlbWVOYW1lO1xuICAgIG5lZ290aWF0ZWRTZXR0aW5ncy5sYW5ndWFnZSA9IHNldHRpbmdzLmxhbmd1YWdlID8/IGhvdENvbmZpZy5sYW5ndWFnZTtcblxuICAgIC8vIHNldHRpbmdzIHRoYXQgY2FuIGJlIHNldCBvbmx5IGJlZm9yZSB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlIGlzIGluaXRpYWxpemVkXG4gICAgaWYgKCF0aGlzLl9faG90SW5zdGFuY2UpIHtcbiAgICAgIG5lZ290aWF0ZWRTZXR0aW5ncy5sYXlvdXREaXJlY3Rpb24gPSBzZXR0aW5ncy5sYXlvdXREaXJlY3Rpb24gPz8gaG90Q29uZmlnLmxheW91dERpcmVjdGlvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmVnb3RpYXRlZFNldHRpbmdzO1xuICB9XG59XG4iXX0=