UNPKG

@handsontable/angular-wrapper

Version:

Best Data Grid for Angular with Spreadsheet Look and Feel.

133 lines 19 kB
import { createComponent, Injectable } from '@angular/core'; import { BaseEditorAdapter } from '../editor/base-editor-adapter'; import Handsontable from 'handsontable/base'; import * as i0 from "@angular/core"; import * as i1 from "../renderer/hot-dynamic-renderer-component.service"; const AVAILABLE_OPTIONS = Object.keys(Handsontable.DefaultSettings); const AVAILABLE_HOOKS = Handsontable.hooks.getRegistered(); /** * Service to resolve and apply custom settings for Handsontable settings object. */ export class HotSettingsResolver { dynamicComponentService; environmentInjector; constructor(dynamicComponentService, environmentInjector) { this.dynamicComponentService = dynamicComponentService; this.environmentInjector = environmentInjector; } /** * Applies custom settings to the provided GridSettings. * @param settings The original grid settings. * @param ngZone The NgZone instance to run hooks inside the zone context. * @returns The merged grid settings with custom settings applied. */ applyCustomSettings(settings, ngZone) { const mergedSettings = settings; this.updateColumnRendererForGivenCustomRenderer(mergedSettings); this.updateColumnEditorForGivenCustomEditor(mergedSettings); this.updateColumnValidatorForGivenCustomValidator(mergedSettings); this.wrapHooksInNgZone(mergedSettings, ngZone); return mergedSettings ?? {}; } /** * Ensures that hook callbacks in the provided grid settings run inside Angular's zone. * * @param settings The original grid settings. * @param ngZone The NgZone instance to run hooks inside the zone context. */ wrapHooksInNgZone(settings, ngZone) { const options = AVAILABLE_HOOKS.concat(AVAILABLE_OPTIONS); options.forEach(key => { const isHook = AVAILABLE_HOOKS.indexOf(key) > -1; let option; if (isHook) { option = settings[key]; } if (option === void 0) { return; } else if (!!ngZone && (typeof option === 'function' && isHook)) { settings[key] = function (...args) { return ngZone.run(() => option.apply(this, args)); }; } else { settings[key] = option; } }); } /** * Updates the column renderer for columns with a custom renderer. * @param mergedSettings The merged grid settings. */ updateColumnRendererForGivenCustomRenderer(mergedSettings) { if (!Array.isArray(mergedSettings?.columns)) { return; } mergedSettings?.columns ?.filter((settings) => this.isRendererComponentRefType(settings.renderer) || this.isTemplateRef(settings.renderer)) ?.forEach((cellSettings) => { const renderer = this.isTemplateRef(cellSettings.renderer) ? cellSettings.renderer : cellSettings.renderer; const props = cellSettings.rendererProps ?? {}; cellSettings.renderer = this.dynamicComponentService.createRendererFromComponent(renderer, props); }); } /** * Updates the column editor for columns with a custom editor. * @param mergedSettings The merged grid settings. */ updateColumnEditorForGivenCustomEditor(mergedSettings) { if (!Array.isArray(mergedSettings?.columns)) { return; } mergedSettings?.columns ?.filter((settings) => this.isEditorComponentRefType(settings.editor)) ?.forEach((cellSettings) => { const customEditor = cellSettings.editor; cellSettings['_editorComponentReference'] = createComponent(customEditor, { environmentInjector: this.environmentInjector, }); cellSettings['_environmentInjector'] = this.environmentInjector; cellSettings.editor = BaseEditorAdapter; }); } /** * Updates the column validator for columns with a custom validator. * @param mergedSettings The merged grid settings. */ updateColumnValidatorForGivenCustomValidator(mergedSettings) { if (!Array.isArray(mergedSettings?.columns)) { return; } mergedSettings?.columns ?.filter((settings) => this.isCustomValidatorFn(settings.validator)) ?.forEach((cellSettings) => { const customValidatorFn = cellSettings.validator; cellSettings.validator = (value, callback) => { callback(customValidatorFn(value)); }; }); } isCustomValidatorFn(validator) { return typeof validator === 'function' && validator.length === 1; } isEditorComponentRefType(editor) { // ecmp - we need it to check if the editor is a component return typeof editor === 'function' && !!editor?.ɵcmp; } isRendererComponentRefType(renderer) { // ecmp - we need it to check if the renderer is a component return typeof renderer === 'function' && !!renderer?.ɵcmp; } isTemplateRef(renderer) { return renderer && typeof renderer.createEmbeddedView === 'function'; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotSettingsResolver, deps: [{ token: i1.DynamicComponentService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotSettingsResolver }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotSettingsResolver, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.DynamicComponentService }, { type: i0.EnvironmentInjector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90LXNldHRpbmdzLXJlc29sdmVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ob3QtdGFibGUvc3JjL2xpYi9zZXJ2aWNlcy9ob3Qtc2V0dGluZ3MtcmVzb2x2ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsZUFBZSxFQUF1QixVQUFVLEVBQTRCLE1BQU0sZUFBZSxDQUFDO0FBRTFHLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBS2xFLE9BQU8sWUFBWSxNQUFNLG1CQUFtQixDQUFDOzs7QUFFN0MsTUFBTSxpQkFBaUIsR0FBYSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUM5RSxNQUFNLGVBQWUsR0FBYSxZQUFZLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO0FBRXJFOztHQUVHO0FBRUgsTUFBTSxPQUFPLG1CQUFtQjtJQUNWO0lBQW1FO0lBQXZGLFlBQW9CLHVCQUFnRCxFQUFtQixtQkFBd0M7UUFBM0csNEJBQXVCLEdBQXZCLHVCQUF1QixDQUF5QjtRQUFtQix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO0lBQUcsQ0FBQztJQUVuSTs7Ozs7T0FLRztJQUNILG1CQUFtQixDQUFDLFFBQXNCLEVBQUUsTUFBYztRQUN4RCxNQUFNLGNBQWMsR0FBaUIsUUFBUSxDQUFDO1FBRTlDLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsc0NBQXNDLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLDRDQUE0QyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFL0MsT0FBUSxjQUF1QyxJQUFJLEVBQUUsQ0FBQztJQUN4RCxD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SUFDdkUsQ0FBQzt3R0FqSVUsbUJBQW1COzRHQUFuQixtQkFBbUI7OzRGQUFuQixtQkFBbUI7a0JBRC9CLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2NyZWF0ZUNvbXBvbmVudCwgRW52aXJvbm1lbnRJbmplY3RvciwgSW5qZWN0YWJsZSwgTmdab25lLCBUZW1wbGF0ZVJlZiwgVHlwZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEeW5hbWljQ29tcG9uZW50U2VydmljZSB9IGZyb20gJy4uL3JlbmRlcmVyL2hvdC1keW5hbWljLXJlbmRlcmVyLWNvbXBvbmVudC5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VFZGl0b3JBZGFwdGVyIH0gZnJvbSAnLi4vZWRpdG9yL2Jhc2UtZWRpdG9yLWFkYXB0ZXInO1xuaW1wb3J0IHsgR3JpZFNldHRpbmdzLCBHcmlkU2V0dGluZ3NJbnRlcm5hbCB9IGZyb20gJy4uL21vZGVscy9ncmlkLXNldHRpbmdzJztcbmltcG9ydCB7IEN1c3RvbVZhbGlkYXRvckZuLCBDb2x1bW5TZXR0aW5ncyB9IGZyb20gJy4uL21vZGVscy9jb2x1bW4tc2V0dGluZ3MnO1xuaW1wb3J0IHsgSG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vcmVuZGVyZXIvaG90LWNlbGwtcmVuZGVyZXIuY29tcG9uZW50JztcbmltcG9ydCB7IEhvdENlbGxFZGl0b3JDb21wb25lbnQgfSBmcm9tICcuLi9lZGl0b3IvaG90LWNlbGwtZWRpdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQgSGFuZHNvbnRhYmxlIGZyb20gJ2hhbmRzb250YWJsZS9iYXNlJztcblxuY29uc3QgQVZBSUxBQkxFX09QVElPTlM6IHN0cmluZ1tdID0gT2JqZWN0LmtleXMoSGFuZHNvbnRhYmxlLkRlZmF1bHRTZXR0aW5ncyk7XG5jb25zdCBBVkFJTEFCTEVfSE9PS1M6IHN0cmluZ1tdID0gSGFuZHNvbnRhYmxlLmhvb2tzLmdldFJlZ2lzdGVyZWQoKTtcblxuLyoqXG4gKiBTZXJ2aWNlIHRvIHJlc29sdmUgYW5kIGFwcGx5IGN1c3RvbSBzZXR0aW5ncyBmb3IgSGFuZHNvbnRhYmxlIHNldHRpbmdzIG9iamVjdC5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEhvdFNldHRpbmdzUmVzb2x2ZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGR5bmFtaWNDb21wb25lbnRTZXJ2aWNlOiBEeW5hbWljQ29tcG9uZW50U2VydmljZSwgcHJpdmF0ZSByZWFkb25seSBlbnZpcm9ubWVudEluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yKSB7fVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIGN1c3RvbSBzZXR0aW5ncyB0byB0aGUgcHJvdmlkZWQgR3JpZFNldHRpbmdzLlxuICAgKiBAcGFyYW0gc2V0dGluZ3MgVGhlIG9yaWdpbmFsIGdyaWQgc2V0dGluZ3MuXG4gICAqIEBwYXJhbSBuZ1pvbmUgVGhlIE5nWm9uZSBpbnN0YW5jZSB0byBydW4gaG9va3MgaW5zaWRlIHRoZSB6b25lIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIFRoZSBtZXJnZWQgZ3JpZCBzZXR0aW5ncyB3aXRoIGN1c3RvbSBzZXR0aW5ncyBhcHBsaWVkLlxuICAgKi9cbiAgYXBwbHlDdXN0b21TZXR0aW5ncyhzZXR0aW5nczogR3JpZFNldHRpbmdzLCBuZ1pvbmU6IE5nWm9uZSk6IEdyaWRTZXR0aW5nc0ludGVybmFsIHtcbiAgICBjb25zdCBtZXJnZWRTZXR0aW5nczogR3JpZFNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgICB0aGlzLnVwZGF0ZUNvbHVtblJlbmRlcmVyRm9yR2l2ZW5DdXN0b21SZW5kZXJlcihtZXJnZWRTZXR0aW5ncyk7XG4gICAgdGhpcy51cGRhdGVDb2x1bW5FZGl0b3JGb3JHaXZlbkN1c3RvbUVkaXRvcihtZXJnZWRTZXR0aW5ncyk7XG4gICAgdGhpcy51cGRhdGVDb2x1bW5WYWxpZGF0b3JGb3JHaXZlbkN1c3RvbVZhbGlkYXRvcihtZXJnZWRTZXR0aW5ncyk7XG5cbiAgICB0aGlzLndyYXBIb29rc0luTmdab25lKG1lcmdlZFNldHRpbmdzLCBuZ1pvbmUpO1xuXG4gICAgcmV0dXJuIChtZXJnZWRTZXR0aW5ncyBhcyBHcmlkU2V0dGluZ3NJbnRlcm5hbCkgPz8ge307XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGF0IGhvb2sgY2FsbGJhY2tzIGluIHRoZSBwcm92aWRlZCBncmlkIHNldHRpbmdzIHJ1biBpbnNpZGUgQW5ndWxhcidzIHpvbmUuXG4gICAqXG4gICAqIEBwYXJhbSBzZXR0aW5ncyBUaGUgb3JpZ2luYWwgZ3JpZCBzZXR0aW5ncy5cbiAgICogQHBhcmFtIG5nWm9uZSBUaGUgTmdab25lIGluc3RhbmNlIHRvIHJ1biBob29rcyBpbnNpZGUgdGhlIHpvbmUgY29udGV4dC5cbiAgICovXG4gIHByaXZhdGUgd3JhcEhvb2tzSW5OZ1pvbmUoc2V0dGluZ3M6IEdyaWRTZXR0aW5ncywgbmdab25lOiBOZ1pvbmUpIHtcbiAgICBjb25zdCBvcHRpb25zID0gQVZBSUxBQkxFX0hPT0tTLmNvbmNhdChBVkFJTEFCTEVfT1BUSU9OUyk7XG5cbiAgICBvcHRpb25zLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGlzSG9vayA9IEFWQUlMQUJMRV9IT09LUy5pbmRleE9mKGtleSkgPiAtMTtcbiAgICAgIGxldCBvcHRpb247XG5cbiAgICAgIGlmIChpc0hvb2spIHtcbiAgICAgICAgb3B0aW9uID0gc2V0dGluZ3Nba2V5XTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHJldHVybjtcblxuICAgICAgfSBlbHNlIGlmICghIW5nWm9uZSAmJiAodHlwZW9mIG9wdGlvbiA9PT0gJ2Z1bmN0aW9uJyAmJiBpc0hvb2spKSB7XG4gICAgICAgIHNldHRpbmdzW2tleV0gPSBmdW5jdGlvbiguLi5hcmdzOiBhbnkpIHtcbiAgICAgICAgICByZXR1cm4gbmdab25lLnJ1bigoKSA9PiBvcHRpb24uYXBwbHkodGhpcywgYXJncykpO1xuICAgICAgICB9O1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXR0aW5nc1trZXldID0gb3B0aW9uO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNvbHVtbiByZW5kZXJlciBmb3IgY29sdW1ucyB3aXRoIGEgY3VzdG9tIHJlbmRlcmVyLlxuICAgKiBAcGFyYW0gbWVyZ2VkU2V0dGluZ3MgVGhlIG1lcmdlZCBncmlkIHNldHRpbmdzLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVDb2x1bW5SZW5kZXJlckZvckdpdmVuQ3VzdG9tUmVuZGVyZXIobWVyZ2VkU2V0dGluZ3M6IEdyaWRTZXR0aW5ncyk6IHZvaWQge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShtZXJnZWRTZXR0aW5ncz8uY29sdW1ucykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAobWVyZ2VkU2V0dGluZ3M/LmNvbHVtbnMgYXMgQ29sdW1uU2V0dGluZ3NbXSlcbiAgICAgID8uZmlsdGVyKChzZXR0aW5ncykgPT4gdGhpcy5pc1JlbmRlcmVyQ29tcG9uZW50UmVmVHlwZShzZXR0aW5ncy5yZW5kZXJlcikgfHwgdGhpcy5pc1RlbXBsYXRlUmVmKHNldHRpbmdzLnJlbmRlcmVyKSlcbiAgICAgID8uZm9yRWFjaCgoY2VsbFNldHRpbmdzKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5pc1RlbXBsYXRlUmVmKGNlbGxTZXR0aW5ncy5yZW5kZXJlcilcbiAgICAgICAgICA/IChjZWxsU2V0dGluZ3MucmVuZGVyZXIgYXMgVGVtcGxhdGVSZWY8YW55PilcbiAgICAgICAgICA6IChjZWxsU2V0dGluZ3MucmVuZGVyZXIgYXMgVHlwZTxIb3RDZWxsUmVuZGVyZXJDb21wb25lbnQ8YW55LCBhbnk+Pik7XG4gICAgICAgIGNvbnN0IHByb3BzOiBhbnkgPSBjZWxsU2V0dGluZ3MucmVuZGVyZXJQcm9wcyA/PyB7fTtcbiAgICAgICAgY2VsbFNldHRpbmdzLnJlbmRlcmVyID0gdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5jcmVhdGVSZW5kZXJlckZyb21Db21wb25lbnQocmVuZGVyZXIsIHByb3BzKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNvbHVtbiBlZGl0b3IgZm9yIGNvbHVtbnMgd2l0aCBhIGN1c3RvbSBlZGl0b3IuXG4gICAqIEBwYXJhbSBtZXJnZWRTZXR0aW5ncyBUaGUgbWVyZ2VkIGdyaWQgc2V0dGluZ3MuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUNvbHVtbkVkaXRvckZvckdpdmVuQ3VzdG9tRWRpdG9yKG1lcmdlZFNldHRpbmdzOiBHcmlkU2V0dGluZ3MpOiB2b2lkIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVyZ2VkU2V0dGluZ3M/LmNvbHVtbnMpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgKG1lcmdlZFNldHRpbmdzPy5jb2x1bW5zIGFzIENvbHVtblNldHRpbmdzW10pXG4gICAgICA/LmZpbHRlcigoc2V0dGluZ3MpID0+IHRoaXMuaXNFZGl0b3JDb21wb25lbnRSZWZUeXBlKHNldHRpbmdzLmVkaXRvcikpXG4gICAgICA/LmZvckVhY2goKGNlbGxTZXR0aW5ncykgPT4ge1xuICAgICAgICBjb25zdCBjdXN0b21FZGl0b3IgPSBjZWxsU2V0dGluZ3MuZWRpdG9yIGFzIFR5cGU8SG90Q2VsbEVkaXRvckNvbXBvbmVudDxhbnk+PjtcbiAgICAgICAgY2VsbFNldHRpbmdzWydfZWRpdG9yQ29tcG9uZW50UmVmZXJlbmNlJ10gPSBjcmVhdGVDb21wb25lbnQoY3VzdG9tRWRpdG9yLCB7XG4gICAgICAgICAgZW52aXJvbm1lbnRJbmplY3RvcjogdGhpcy5lbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgICB9KTtcbiAgICAgICAgY2VsbFNldHRpbmdzWydfZW52aXJvbm1lbnRJbmplY3RvciddID0gdGhpcy5lbnZpcm9ubWVudEluamVjdG9yO1xuICAgICAgICBjZWxsU2V0dGluZ3MuZWRpdG9yID0gQmFzZUVkaXRvckFkYXB0ZXI7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBjb2x1bW4gdmFsaWRhdG9yIGZvciBjb2x1bW5zIHdpdGggYSBjdXN0b20gdmFsaWRhdG9yLlxuICAgKiBAcGFyYW0gbWVyZ2VkU2V0dGluZ3MgVGhlIG1lcmdlZCBncmlkIHNldHRpbmdzLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVDb2x1bW5WYWxpZGF0b3JGb3JHaXZlbkN1c3RvbVZhbGlkYXRvcihtZXJnZWRTZXR0aW5nczogR3JpZFNldHRpbmdzKTogdm9pZCB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG1lcmdlZFNldHRpbmdzPy5jb2x1bW5zKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIChtZXJnZWRTZXR0aW5ncz8uY29sdW1ucyBhcyBDb2x1bW5TZXR0aW5nc1tdKVxuICAgICAgPy5maWx0ZXIoKHNldHRpbmdzKSA9PiB0aGlzLmlzQ3VzdG9tVmFsaWRhdG9yRm4oc2V0dGluZ3MudmFsaWRhdG9yKSlcbiAgICAgID8uZm9yRWFjaCgoY2VsbFNldHRpbmdzKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1c3RvbVZhbGlkYXRvckZuID0gY2VsbFNldHRpbmdzLnZhbGlkYXRvciBhcyBDdXN0b21WYWxpZGF0b3JGbjxhbnk+O1xuXG4gICAgICAgIGNlbGxTZXR0aW5ncy52YWxpZGF0b3IgPSAodmFsdWU6IGFueSwgY2FsbGJhY2s6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQpID0+IHtcbiAgICAgICAgICBjYWxsYmFjayhjdXN0b21WYWxpZGF0b3JGbih2YWx1ZSkpO1xuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGlzQ3VzdG9tVmFsaWRhdG9yRm4odmFsaWRhdG9yOiB1bmtub3duKTogdmFsaWRhdG9yIGlzIEN1c3RvbVZhbGlkYXRvckZuPGFueT4ge1xuICAgIHJldHVybiB0eXBlb2YgdmFsaWRhdG9yID09PSAnZnVuY3Rpb24nICYmIHZhbGlkYXRvci5sZW5ndGggPT09IDE7XG4gIH1cblxuICBwcml2YXRlIGlzRWRpdG9yQ29tcG9uZW50UmVmVHlwZShlZGl0b3I6IGFueSk6IGVkaXRvciBpcyBUeXBlPEhvdENlbGxFZGl0b3JDb21wb25lbnQ8YW55Pj4ge1xuICAgIC8vIGVjbXAgLSB3ZSBuZWVkIGl0IHRvIGNoZWNrIGlmIHRoZSBlZGl0b3IgaXMgYSBjb21wb25lbnRcbiAgICByZXR1cm4gdHlwZW9mIGVkaXRvciA9PT0gJ2Z1bmN0aW9uJyAmJiAhIShlZGl0b3IgYXMgYW55KT8uybVjbXA7XG4gIH1cblxuICBwcml2YXRlIGlzUmVuZGVyZXJDb21wb25lbnRSZWZUeXBlKHJlbmRlcmVyOiBhbnkpOiByZW5kZXJlciBpcyBUeXBlPEhvdENlbGxSZW5kZXJlckNvbXBvbmVudDxhbnksIGFueT4+IHtcbiAgICAvLyBlY21wIC0gd2UgbmVlZCBpdCB0byBjaGVjayBpZiB0aGUgcmVuZGVyZXIgaXMgYSBjb21wb25lbnRcbiAgICByZXR1cm4gdHlwZW9mIHJlbmRlcmVyID09PSAnZnVuY3Rpb24nICYmICEhKHJlbmRlcmVyIGFzIGFueSk/Lsm1Y21wO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1RlbXBsYXRlUmVmKHJlbmRlcmVyOiBhbnkpOiByZW5kZXJlciBpcyBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICByZXR1cm4gcmVuZGVyZXIgJiYgdHlwZW9mIHJlbmRlcmVyLmNyZWF0ZUVtYmVkZGVkVmlldyA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxufVxuIl19