@acrodata/gradient-picker
Version:
A powerful and beautiful gradient picker.
103 lines • 19.9 kB
JavaScript
import { booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, inject, Input, ViewEncapsulation, } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ConicGradientPicker } from './conic-gradient-picker';
import { GradientFormGroup, GradientInputField } from './form-controls';
import { LinearGradientPicker } from './linear-gradient-picker';
import { RadialGradientPicker } from './radial-gradient-picker';
import { convertAngleToPercentage, parseGradient } from './utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
export class GradientPicker {
cdr = inject(ChangeDetectorRef);
disabled = false;
value = '';
types = [
{ label: 'Linear', value: 'linear' },
{ label: 'Radial', value: 'radial' },
{ label: 'Conic', value: 'conic' },
];
type = 'linear';
onChange = () => { };
onTouched = () => { };
writeValue(value) {
if (!value) {
this.type = 'linear';
}
else if (value.includes('linear')) {
this.type = 'linear';
}
else if (value.includes('radial')) {
this.type = 'radial';
}
else if (value.includes('conic')) {
this.type = 'conic';
}
this.value = value;
this.cdr.markForCheck();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.cdr.markForCheck();
}
onValueChange() {
this.onChange(this.value);
}
onTypeChange() {
const { color, stops } = parseGradient(this.value) || {};
const props = [];
const stopsStr = convertAngleToPercentage(stops || [])
.map(s => s.color + (s.offset ? ` ${s.offset.value}${s.offset.unit}` : ''))
.join(', ') || 'transparent, #000000';
if (color && color.space) {
props.push(`in ${color.space} ${color.method || ''}`.trim());
}
props.push(stopsStr);
if (this.type === 'linear') {
this.value = `linear-gradient(${props.join(', ')})`;
}
else if (this.type === 'radial') {
this.value = `radial-gradient(${props.join(', ')})`;
}
else if (this.type === 'conic') {
this.value = `conic-gradient(${props.join(', ')})`;
}
this.onValueChange();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: GradientPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: GradientPicker, isStandalone: true, selector: "gradient-picker", inputs: { disabled: ["disabled", "disabled", booleanAttribute] }, host: { classAttribute: "gradient-picker" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => GradientPicker),
multi: true,
},
], ngImport: i0, template: "<gradient-form-group label=\"Type\">\n <gradient-input-field>\n <select [(ngModel)]=\"type\" (ngModelChange)=\"onTypeChange()\">\n @for (t of types; track $index) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n </gradient-input-field>\n</gradient-form-group>\n\n@if (type === 'linear') {\n <linear-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n} @else if (type === 'radial') {\n <radial-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n} @else if (type === 'conic') {\n <conic-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n}\n", styles: [".gradient-picker{--gp-container-text-color: light-dark(rgba(0, 0, 0, .9), #fff);--gp-container-background-color: light-dark(#fff, #2c2c2c);--gp-input-background-color: light-dark(#f5f5f5, #383838);--gp-input-outline-color: light-dark(#e6e6e6, #444);--gp-input-hover-outline-color: light-dark(#d6d6d6, #545454);--gp-input-focus-outline-color: light-dark(#0d99ff, #0c8ce9);--gp-unit-select-hover-background-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-icon-button-hover-background-color: light-dark(rgba(0, 0, 0, .06), rgba(255, 255, 255, .06));--gp-icon-button-active-background-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stops-slider-bar-outline-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stops-slider-thumb-background-color: light-dark(#fff, #383838);--gp-stops-slider-thumb-toggle-outline-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stop-item-active-color: light-dark(#e5f4ff, #4a5878);display:block;width:var(--gp-container-width, 240px);padding:var(--gp-container-vertical-padding, 8px) 0;margin:var(--gp-container-margin, 0);box-shadow:var(--gp-container-elevation-shadow, inset 0 0 1px 0 rgba(255, 255, 255, .64), 0 2px 4px 0 rgba(0, 0, 0, .16), 0 8px 16px 0 rgba(0, 0, 0, .12), 0 0 1px 0 rgba(0, 0, 0, .12));background-color:var(--gp-container-background-color);border-radius:var(--gp-container-shape, 8px)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LinearGradientPicker, selector: "linear-gradient-picker", inputs: ["disabled"] }, { kind: "component", type: RadialGradientPicker, selector: "radial-gradient-picker", inputs: ["disabled"] }, { kind: "component", type: ConicGradientPicker, selector: "conic-gradient-picker", inputs: ["disabled"] }, { kind: "component", type: GradientFormGroup, selector: "gradient-form-group", inputs: ["label"] }, { kind: "component", type: GradientInputField, selector: "gradient-input-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: GradientPicker, decorators: [{
type: Component,
args: [{ selector: 'gradient-picker', standalone: true, imports: [
FormsModule,
LinearGradientPicker,
RadialGradientPicker,
ConicGradientPicker,
GradientFormGroup,
GradientInputField,
], host: {
class: 'gradient-picker',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => GradientPicker),
multi: true,
},
], template: "<gradient-form-group label=\"Type\">\n <gradient-input-field>\n <select [(ngModel)]=\"type\" (ngModelChange)=\"onTypeChange()\">\n @for (t of types; track $index) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n </gradient-input-field>\n</gradient-form-group>\n\n@if (type === 'linear') {\n <linear-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n} @else if (type === 'radial') {\n <radial-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n} @else if (type === 'conic') {\n <conic-gradient-picker [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange()\" />\n}\n", styles: [".gradient-picker{--gp-container-text-color: light-dark(rgba(0, 0, 0, .9), #fff);--gp-container-background-color: light-dark(#fff, #2c2c2c);--gp-input-background-color: light-dark(#f5f5f5, #383838);--gp-input-outline-color: light-dark(#e6e6e6, #444);--gp-input-hover-outline-color: light-dark(#d6d6d6, #545454);--gp-input-focus-outline-color: light-dark(#0d99ff, #0c8ce9);--gp-unit-select-hover-background-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-icon-button-hover-background-color: light-dark(rgba(0, 0, 0, .06), rgba(255, 255, 255, .06));--gp-icon-button-active-background-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stops-slider-bar-outline-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stops-slider-thumb-background-color: light-dark(#fff, #383838);--gp-stops-slider-thumb-toggle-outline-color: light-dark(rgba(0, 0, 0, .12), rgba(255, 255, 255, .12));--gp-stop-item-active-color: light-dark(#e5f4ff, #4a5878);display:block;width:var(--gp-container-width, 240px);padding:var(--gp-container-vertical-padding, 8px) 0;margin:var(--gp-container-margin, 0);box-shadow:var(--gp-container-elevation-shadow, inset 0 0 1px 0 rgba(255, 255, 255, .64), 0 2px 4px 0 rgba(0, 0, 0, .16), 0 8px 16px 0 rgba(0, 0, 0, .12), 0 0 1px 0 rgba(0, 0, 0, .12));background-color:var(--gp-container-background-color);border-radius:var(--gp-container-shape, 8px)}\n"] }]
}], propDecorators: { disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhZGllbnQtcGlja2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZ3JhZGllbnQtcGlja2VyL3NyYy9saWIvZ3JhZGllbnQtcGlja2VyLnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvZ3JhZGllbnQtcGlja2VyL3NyYy9saWIvZ3JhZGllbnQtcGlja2VyLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGdCQUFnQixFQUNoQix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFDOzs7QUE0QmxFLE1BQU0sT0FBTyxjQUFjO0lBQ2pCLEdBQUcsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUVBLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFFekQsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUVYLEtBQUssR0FBRztRQUNOLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO1FBQ3BDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO1FBQ3BDLEVBQUUsS0FBSyxF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dGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBpbmplY3QsXG4gIElucHV0LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybXNNb2R1bGUsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQ29uaWNHcmFkaWVudFBpY2tlciB9IGZyb20gJy4vY29uaWMtZ3JhZGllbnQtcGlja2VyJztcbmltcG9ydCB7IEdyYWRpZW50Rm9ybUdyb3VwLCBHcmFkaWVudElucHV0RmllbGQgfSBmcm9tICcuL2Zvcm0tY29udHJvbHMnO1xuaW1wb3J0IHsgTGluZWFyR3JhZGllbnRQaWNrZXIgfSBmcm9tICcuL2xpbmVhci1ncmFkaWVudC1waWNrZXInO1xuaW1wb3J0IHsgUmFkaWFsR3JhZGllbnRQaWNrZXIgfSBmcm9tICcuL3JhZGlhbC1ncmFkaWVudC1waWNrZXInO1xuaW1wb3J0IHsgY29udmVydEFuZ2xlVG9QZXJjZW50YWdlLCBwYXJzZUdyYWRpZW50IH0gZnJvbSAnLi91dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2dyYWRpZW50LXBpY2tlcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBMaW5lYXJHcmFkaWVudFBpY2tlcixcbiAgICBSYWRpYWxHcmFkaWVudFBpY2tlcixcbiAgICBDb25pY0dyYWRpZW50UGlja2VyLFxuICAgIEdyYWRpZW50Rm9ybUdyb3VwLFxuICAgIEdyYWRpZW50SW5wdXRGaWVsZCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2dyYWRpZW50LXBpY2tlci5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2dyYWRpZW50LXBpY2tlci5zY3NzJyxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnZ3JhZGllbnQtcGlja2VyJyxcbiAgfSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gR3JhZGllbnRQaWNrZXIpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgR3JhZGllbnRQaWNrZXIgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gIHByaXZhdGUgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICB2YWx1ZSA9ICcnO1xuXG4gIHR5cGVzID0gW1xuICAgIHsgbGFiZWw6ICdMaW5lYXInLCB2YWx1ZTogJ2xpbmVhcicgfSxcbiAgICB7IGxhYmVsOiAnUmFkaWFsJywgdmFsdWU6ICdyYWRpYWwnIH0sXG4gICAgeyBsYWJlbDogJ0NvbmljJywgdmFsdWU6ICdjb25pYycgfSxcbiAgXTtcblxuICB0eXBlOiAnbGluZWFyJyB8ICdyYWRpYWwnIHwgJ2NvbmljJyA9ICdsaW5lYXInO1xuXG4gIHByaXZhdGUgb25DaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhpcy50eXBlID0gJ2xpbmVhcic7XG4gICAgfSBlbHNlIGlmICh2YWx1ZS5pbmNsdWRlcygnbGluZWFyJykpIHtcbiAgICAgIHRoaXMudHlwZSA9ICdsaW5lYXInO1xuICAgIH0gZWxzZSBpZiAodmFsdWUuaW5jbHVkZXMoJ3JhZGlhbCcpKSB7XG4gICAgICB0aGlzLnR5cGUgPSAncmFkaWFsJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlLmluY2x1ZGVzKCdjb25pYycpKSB7XG4gICAgICB0aGlzLnR5cGUgPSAnY29uaWMnO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25WYWx1ZUNoYW5nZSgpIHtcbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgb25UeXBlQ2hhbmdlKCkge1xuICAgIGNvbnN0IHsgY29sb3IsIHN0b3BzIH0gPSBwYXJzZUdyYWRpZW50KHRoaXMudmFsdWUpIHx8IHt9O1xuXG4gICAgY29uc3QgcHJvcHM6IHN0cmluZ1tdID0gW107XG5cbiAgICBjb25zdCBzdG9wc1N0ciA9XG4gICAgICBjb252ZXJ0QW5nbGVUb1BlcmNlbnRhZ2Uoc3RvcHMgfHwgW10pXG4gICAgICAgIC5tYXAocyA9PiBzLmNvbG9yICsgKHMub2Zmc2V0ID8gYCAke3Mub2Zmc2V0LnZhbHVlfSR7cy5vZmZzZXQudW5pdH1gIDogJycpKVxuICAgICAgICAuam9pbignLCAnKSB8fCAndHJhbnNwYXJlbnQsICMwMDAwMDAnO1xuXG4gICAgaWYgKGNvbG9yICYmIGNvbG9yLnNwYWNlKSB7XG4gICAgICBwcm9wcy5wdXNoKGBpbiAke2NvbG9yLnNwYWNlfSAke2NvbG9yLm1ldGhvZCB8fCAnJ31gLnRyaW0oKSk7XG4gICAgfVxuXG4gICAgcHJvcHMucHVzaChzdG9wc1N0cik7XG5cbiAgICBpZiAodGhpcy50eXBlID09PSAnbGluZWFyJykge1xuICAgICAgdGhpcy52YWx1ZSA9IGBsaW5lYXItZ3JhZGllbnQoJHtwcm9wcy5qb2luKCcsICcpfSlgO1xuICAgIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAncmFkaWFsJykge1xuICAgICAgdGhpcy52YWx1ZSA9IGByYWRpYWwtZ3JhZGllbnQoJHtwcm9wcy5qb2luKCcsICcpfSlgO1xuICAgIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnY29uaWMnKSB7XG4gICAgICB0aGlzLnZhbHVlID0gYGNvbmljLWdyYWRpZW50KCR7cHJvcHMuam9pbignLCAnKX0pYDtcbiAgICB9XG5cbiAgICB0aGlzLm9uVmFsdWVDaGFuZ2UoKTtcbiAgfVxufVxuIiwiPGdyYWRpZW50LWZvcm0tZ3JvdXAgbGFiZWw9XCJUeXBlXCI+XG4gIDxncmFkaWVudC1pbnB1dC1maWVsZD5cbiAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwidHlwZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uVHlwZUNoYW5nZSgpXCI+XG4gICAgICBAZm9yICh0IG9mIHR5cGVzOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwidC52YWx1ZVwiPnt7IHQubGFiZWwgfX08L29wdGlvbj5cbiAgICAgIH1cbiAgICA8L3NlbGVjdD5cbiAgPC9ncmFkaWVudC1pbnB1dC1maWVsZD5cbjwvZ3JhZGllbnQtZm9ybS1ncm91cD5cblxuQGlmICh0eXBlID09PSAnbGluZWFyJykge1xuICA8bGluZWFyLWdyYWRpZW50LXBpY2tlciBbKG5nTW9kZWwpXT1cInZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25WYWx1ZUNoYW5nZSgpXCIgLz5cbn0gQGVsc2UgaWYgKHR5cGUgPT09ICdyYWRpYWwnKSB7XG4gIDxyYWRpYWwtZ3JhZGllbnQtcGlja2VyIFsobmdNb2RlbCldPVwidmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKClcIiAvPlxufSBAZWxzZSBpZiAodHlwZSA9PT0gJ2NvbmljJykge1xuICA8Y29uaWMtZ3JhZGllbnQtcGlja2VyIFsobmdNb2RlbCldPVwidmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKClcIiAvPlxufVxuIl19