@cqa-lib/cqa-ui 1.1.334 → 1.1.335

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,267 @@
1
+ import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core';
2
+ import { CODE_EDITOR_STYLES } from './code-editor.styles';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "ngx-monaco-editor";
5
+ import * as i2 from "@angular/common";
6
+ import * as i3 from "@angular/forms";
7
+ /** Maps custom code step language values to Monaco editor language IDs */
8
+ export const MONACO_LANGUAGE_MAP = {
9
+ javascript: 'javascript',
10
+ typescript: 'typescript',
11
+ python: 'python',
12
+ java: 'java',
13
+ ruby: 'ruby',
14
+ go: 'go',
15
+ rust: 'rust',
16
+ csharp: 'csharp',
17
+ };
18
+ export class CodeEditorComponent {
19
+ constructor() {
20
+ this.value = '';
21
+ this.language = 'javascript';
22
+ this.label = '';
23
+ this.required = false;
24
+ this.placeholder = '// Write your code here...';
25
+ this.fullWidth = true;
26
+ this.ariaLabel = '';
27
+ this.minHeight = '200px';
28
+ this.readOnly = false;
29
+ /** External error messages (e.g. from form validation). Shown alongside syntax errors. */
30
+ this.errors = [];
31
+ /** When true, use a plain textarea instead of Monaco (e.g. for Storybook where Monaco may not load) */
32
+ this.useFallback = false;
33
+ this.valueChange = new EventEmitter();
34
+ this.validationChange = new EventEmitter();
35
+ this.blur = new EventEmitter();
36
+ this.codeValue = '';
37
+ this.validationErrors = [];
38
+ this.editorOptions = {};
39
+ this.editorInstance = null;
40
+ this.markersSubscription = null;
41
+ this.fallbackSyntaxTimer = null;
42
+ this.monacoMarkersTimer = null;
43
+ }
44
+ ngOnInit() {
45
+ this.codeValue = this.value ?? '';
46
+ this.updateEditorOptions();
47
+ if (this.useFallback && ['javascript', 'typescript'].includes(this.language)) {
48
+ this.scheduleFallbackSyntaxCheck(this.codeValue);
49
+ }
50
+ }
51
+ ngOnDestroy() {
52
+ if (this.fallbackSyntaxTimer)
53
+ clearTimeout(this.fallbackSyntaxTimer);
54
+ if (this.monacoMarkersTimer) {
55
+ clearTimeout(this.monacoMarkersTimer);
56
+ this.monacoMarkersTimer = null;
57
+ }
58
+ this.markersSubscription?.();
59
+ }
60
+ ngOnChanges(changes) {
61
+ if (changes['value'] && changes['value'].currentValue !== undefined) {
62
+ const newVal = changes['value'].currentValue ?? '';
63
+ // Only update when value actually changed - avoids overwriting user input during typing
64
+ if (newVal !== this.codeValue) {
65
+ this.codeValue = newVal;
66
+ if (this.useFallback && ['javascript', 'typescript'].includes(this.language)) {
67
+ this.scheduleFallbackSyntaxCheck(newVal);
68
+ }
69
+ }
70
+ }
71
+ // Only update editor options when language or readOnly changes - value changes must NOT
72
+ // recreate editorOptions or ngx-monaco-editor will re-init and dispose the editor,
73
+ // causing "Canceled" errors from Monaco's async operations (word highlighting, etc.)
74
+ if (changes['language'] || changes['readOnly']) {
75
+ this.updateEditorOptions();
76
+ }
77
+ }
78
+ updateEditorOptions() {
79
+ const monacoLang = MONACO_LANGUAGE_MAP[this.language] || this.language || 'plaintext';
80
+ const hasDiagnostics = ['javascript', 'typescript'].includes(monacoLang);
81
+ this.editorOptions = {
82
+ theme: 'vs',
83
+ language: monacoLang,
84
+ minimap: { enabled: false },
85
+ scrollBeyondLastLine: false,
86
+ automaticLayout: true,
87
+ fontSize: 13,
88
+ lineNumbers: 'on',
89
+ roundedSelection: false,
90
+ readOnly: this.readOnly,
91
+ cursorStyle: 'line',
92
+ wordWrap: 'on',
93
+ // useWorker: false - Monaco workers require AMD loader (define) which fails in
94
+ // bundled environments (Storybook, some webpack setups). Running in main thread
95
+ // avoids "define is not defined" and worker creation errors.
96
+ ...(hasDiagnostics ? { quickSuggestions: true } : {}),
97
+ useWorker: false,
98
+ };
99
+ }
100
+ onCodeChange(newValue) {
101
+ this.codeValue = newValue;
102
+ this.valueChange.emit(newValue);
103
+ if (!this.useFallback && ['javascript', 'typescript'].includes(this.language)) {
104
+ this.scheduleFallbackSyntaxCheck(newValue);
105
+ }
106
+ }
107
+ onFallbackInput(event) {
108
+ const target = event.target;
109
+ const newValue = target?.value ?? '';
110
+ this.codeValue = newValue;
111
+ this.valueChange.emit(newValue);
112
+ if (['javascript', 'typescript'].includes(this.language)) {
113
+ this.scheduleFallbackSyntaxCheck(newValue);
114
+ }
115
+ }
116
+ /** Debounced syntax check for fallback mode - avoids running on every keystroke */
117
+ scheduleFallbackSyntaxCheck(code) {
118
+ if (this.fallbackSyntaxTimer)
119
+ clearTimeout(this.fallbackSyntaxTimer);
120
+ this.fallbackSyntaxTimer = setTimeout(() => {
121
+ this.fallbackSyntaxTimer = null;
122
+ this.checkFallbackSyntax(code);
123
+ }, 300);
124
+ }
125
+ /** Syntax validation for fallback (textarea) mode - JS/TS only */
126
+ checkFallbackSyntax(code) {
127
+ if (!['javascript', 'typescript'].includes(this.language)) {
128
+ this.validationErrors = [];
129
+ this.validationChange.emit(this.validationErrors);
130
+ return;
131
+ }
132
+ if (!code || !code.trim()) {
133
+ this.validationErrors = [];
134
+ this.validationChange.emit(this.validationErrors);
135
+ return;
136
+ }
137
+ try {
138
+ new Function(code);
139
+ this.validationErrors = [];
140
+ }
141
+ catch (e) {
142
+ if (e instanceof SyntaxError) {
143
+ const err = e;
144
+ const line = err.lineNumber ?? 1;
145
+ this.validationErrors = [{
146
+ message: err.message || 'Syntax error',
147
+ severity: 'error',
148
+ lineNumber: line,
149
+ column: err.columnNumber,
150
+ }];
151
+ }
152
+ else {
153
+ this.validationErrors = [];
154
+ }
155
+ }
156
+ this.validationChange.emit(this.validationErrors);
157
+ }
158
+ onEditorInit(editor) {
159
+ this.editorInstance = editor;
160
+ this.setupMarkersListener(editor);
161
+ editor.onDidBlurEditorWidget?.(() => this.blur.emit());
162
+ if (['javascript', 'typescript'].includes(this.language)) {
163
+ this.scheduleFallbackSyntaxCheck(this.codeValue);
164
+ }
165
+ }
166
+ setupMarkersListener(editor) {
167
+ this.markersSubscription?.();
168
+ const model = editor.getModel?.();
169
+ if (!model?.uri)
170
+ return;
171
+ const win = window;
172
+ const checkMarkers = () => {
173
+ try {
174
+ if (!win.monaco?.editor?.getModelMarkers)
175
+ return;
176
+ const markers = win.monaco.editor.getModelMarkers({ resource: model.uri }) || [];
177
+ const monacoErrors = markers
178
+ .filter((m) => m.severity === 8) // 8 = Error in Monaco
179
+ .map((m) => ({
180
+ message: m.message || 'Syntax error',
181
+ severity: 'error',
182
+ lineNumber: m.startLineNumber || 1,
183
+ column: m.startColumn,
184
+ }));
185
+ // Only update from Monaco when it has markers - otherwise keep fallback results
186
+ // (Monaco may not produce markers when useWorker: false in bundled environments)
187
+ if (monacoErrors.length > 0) {
188
+ this.validationErrors = monacoErrors;
189
+ this.validationChange.emit(this.validationErrors);
190
+ }
191
+ }
192
+ catch {
193
+ // Monaco may not be loaded yet
194
+ }
195
+ };
196
+ const disposeMarkers = win.monaco?.editor?.onDidChangeMarkers?.(() => {
197
+ checkMarkers();
198
+ });
199
+ const scheduleCheckMarkers = () => {
200
+ if (this.monacoMarkersTimer)
201
+ clearTimeout(this.monacoMarkersTimer);
202
+ this.monacoMarkersTimer = setTimeout(() => {
203
+ this.monacoMarkersTimer = null;
204
+ checkMarkers();
205
+ }, 400);
206
+ };
207
+ editor.onDidChangeModelContent?.(scheduleCheckMarkers);
208
+ setTimeout(checkMarkers, 600);
209
+ this.markersSubscription = () => {
210
+ if (this.monacoMarkersTimer) {
211
+ clearTimeout(this.monacoMarkersTimer);
212
+ this.monacoMarkersTimer = null;
213
+ }
214
+ disposeMarkers?.dispose?.();
215
+ };
216
+ }
217
+ get hasValidationErrors() {
218
+ return this.validationErrors.length > 0;
219
+ }
220
+ get hasErrors() {
221
+ return (this.errors?.length ?? 0) > 0 || this.hasValidationErrors;
222
+ }
223
+ /** All error messages: external errors + syntax errors formatted as strings */
224
+ get allErrorMessages() {
225
+ const external = this.errors ?? [];
226
+ const syntax = this.validationErrors.map((e) => `Line ${e.lineNumber}: ${e.message}`);
227
+ return [...external, ...syntax];
228
+ }
229
+ }
230
+ CodeEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CodeEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
231
+ CodeEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: CodeEditorComponent, selector: "cqa-code-editor", inputs: { value: "value", language: "language", label: "label", required: "required", placeholder: "placeholder", fullWidth: "fullWidth", ariaLabel: "ariaLabel", minHeight: "minHeight", readOnly: "readOnly", errors: "errors", useFallback: "useFallback" }, outputs: { valueChange: "valueChange", validationChange: "validationChange", blur: "blur" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "monacoEditorRef", first: true, predicate: ["monacoEditor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-w-full\" [style.width]=\"fullWidth ? '100%' : 'auto'\">\n <label\n *ngIf=\"label\"\n class=\"cqa-leading-[100%] cqa-block cqa-text-[12px] cqa-font-medium cqa-text-[#161617] cqa-mb-1\">\n {{ label }}\n <span *ngIf=\"required\" class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n\n <!-- Fallback: plain textarea when Monaco is not available (e.g. Storybook) -->\n <div\n *ngIf=\"useFallback\"\n class=\"cqa-code-editor-container cqa-code-editor-fallback cqa-w-full\"\n [class.cqa-has-errors]=\"hasErrors\"\n [style.height]=\"minHeight\"\n [style.min-height]=\"minHeight\">\n <textarea\n class=\"cqa-code-editor-textarea\"\n [value]=\"codeValue\"\n (input)=\"onFallbackInput($event)\"\n (blur)=\"blur.emit()\"\n [placeholder]=\"placeholder\"\n [readonly]=\"readOnly\"\n [attr.aria-label]=\"ariaLabel || label || 'Code editor'\"\n [attr.aria-invalid]=\"hasErrors\"\n [attr.aria-required]=\"required\">\n </textarea>\n </div>\n <!-- Monaco editor (used in main app) -->\n <div\n *ngIf=\"!useFallback\"\n class=\"cqa-code-editor-container cqa-w-full\"\n [class.cqa-has-errors]=\"hasErrors\"\n [style.height]=\"minHeight\"\n [style.min-height]=\"minHeight\">\n <ngx-monaco-editor\n #monacoEditor\n class=\"cqa-monaco-editor\"\n [options]=\"editorOptions\"\n [ngModel]=\"codeValue\"\n (ngModelChange)=\"onCodeChange($event)\"\n (onInit)=\"onEditorInit($event)\">\n </ngx-monaco-editor>\n </div>\n\n <!-- Error messages (same style as custom-textarea) -->\n <div *ngIf=\"hasErrors\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div *ngFor=\"let error of allErrorMessages\" class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n {{ error }}\n </span>\n </div>\n </div>\n</div>\n", styles: [".cqa-code-editor-container{min-height:200px;height:200px;border:1px solid #e5e7eb;border-radius:6px;overflow:hidden;display:flex;flex-direction:column;background:#fff;transition:border-color .2s,box-shadow .2s}.cqa-code-editor-container:focus-within{border-color:#3b82f6;box-shadow:0 0 0 1px #3b82f6}.cqa-code-editor-container.cqa-has-errors{border-color:#ef4444}.cqa-code-editor-container.cqa-has-errors:focus-within{border-color:#ef4444;box-shadow:0 0 0 1px #ef4444}.cqa-code-editor-container .cqa-monaco-editor,.cqa-code-editor-container ngx-monaco-editor{flex:1;min-height:0}.cqa-code-editor-container ::ng-deep .monaco-editor{height:100%!important}.cqa-code-editor-fallback .cqa-code-editor-textarea{width:100%;height:100%;min-height:180px;padding:12px;font-family:Monaco,Menlo,Ubuntu Mono,Consolas,monospace;font-size:13px;line-height:1.5;border:none;resize:none;outline:none;background:#fff;color:#0a0a0a}.cqa-code-editor-fallback .cqa-code-editor-textarea::placeholder{color:#9ca3af}\n"], components: [{ type: i1.EditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "model"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CodeEditorComponent, decorators: [{
233
+ type: Component,
234
+ args: [{ selector: 'cqa-code-editor', styles: [CODE_EDITOR_STYLES], host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-w-full\" [style.width]=\"fullWidth ? '100%' : 'auto'\">\n <label\n *ngIf=\"label\"\n class=\"cqa-leading-[100%] cqa-block cqa-text-[12px] cqa-font-medium cqa-text-[#161617] cqa-mb-1\">\n {{ label }}\n <span *ngIf=\"required\" class=\"cqa-text-[#EF4444] cqa-ml-0.5\">*</span>\n </label>\n\n <!-- Fallback: plain textarea when Monaco is not available (e.g. Storybook) -->\n <div\n *ngIf=\"useFallback\"\n class=\"cqa-code-editor-container cqa-code-editor-fallback cqa-w-full\"\n [class.cqa-has-errors]=\"hasErrors\"\n [style.height]=\"minHeight\"\n [style.min-height]=\"minHeight\">\n <textarea\n class=\"cqa-code-editor-textarea\"\n [value]=\"codeValue\"\n (input)=\"onFallbackInput($event)\"\n (blur)=\"blur.emit()\"\n [placeholder]=\"placeholder\"\n [readonly]=\"readOnly\"\n [attr.aria-label]=\"ariaLabel || label || 'Code editor'\"\n [attr.aria-invalid]=\"hasErrors\"\n [attr.aria-required]=\"required\">\n </textarea>\n </div>\n <!-- Monaco editor (used in main app) -->\n <div\n *ngIf=\"!useFallback\"\n class=\"cqa-code-editor-container cqa-w-full\"\n [class.cqa-has-errors]=\"hasErrors\"\n [style.height]=\"minHeight\"\n [style.min-height]=\"minHeight\">\n <ngx-monaco-editor\n #monacoEditor\n class=\"cqa-monaco-editor\"\n [options]=\"editorOptions\"\n [ngModel]=\"codeValue\"\n (ngModelChange)=\"onCodeChange($event)\"\n (onInit)=\"onEditorInit($event)\">\n </ngx-monaco-editor>\n </div>\n\n <!-- Error messages (same style as custom-textarea) -->\n <div *ngIf=\"hasErrors\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div *ngFor=\"let error of allErrorMessages\" class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n {{ error }}\n </span>\n </div>\n </div>\n</div>\n" }]
235
+ }], propDecorators: { value: [{
236
+ type: Input
237
+ }], language: [{
238
+ type: Input
239
+ }], label: [{
240
+ type: Input
241
+ }], required: [{
242
+ type: Input
243
+ }], placeholder: [{
244
+ type: Input
245
+ }], fullWidth: [{
246
+ type: Input
247
+ }], ariaLabel: [{
248
+ type: Input
249
+ }], minHeight: [{
250
+ type: Input
251
+ }], readOnly: [{
252
+ type: Input
253
+ }], errors: [{
254
+ type: Input
255
+ }], useFallback: [{
256
+ type: Input
257
+ }], valueChange: [{
258
+ type: Output
259
+ }], validationChange: [{
260
+ type: Output
261
+ }], blur: [{
262
+ type: Output
263
+ }], monacoEditorRef: [{
264
+ type: ViewChild,
265
+ args: ['monacoEditor', { static: false }]
266
+ }] } });
267
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvZGUtZWRpdG9yL2NvZGUtZWRpdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBRU4sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7OztBQUUxRCwwRUFBMEU7QUFDMUUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQTJCO0lBQ3pELFVBQVUsRUFBRSxZQUFZO0lBQ3hCLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLElBQUksRUFBRSxNQUFNO0lBQ1osSUFBSSxFQUFFLE1BQU07SUFDWixFQUFFLEVBQUUsSUFBSTtJQUNSLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLFFBQVE7Q0FDakIsQ0FBQztBQWVGLE1BQU0sT0FBTyxtQkFBbUI7SUFOaEM7UUFPVyxVQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ1gsYUFBUSxHQUFHLFlBQVksQ0FBQztRQUN4QixVQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ1gsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixnQkFBVyxHQUFHLDRCQUE0QixDQUFDO1FBQzNDLGNBQVMsR0FBRyxJQUFJLENBQUM7UUFDakIsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNmLGNBQVMsR0FBRyxPQUFPLENBQUM7UUFDcEIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUMxQiwwRkFBMEY7UUFDakYsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUMvQix1R0FBdUc7UUFDOUYsZ0JBQVcs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O2dIQXBQVSxtQkFBbUI7b0dBQW5CLG1CQUFtQixta0JDdENoQyx5K0VBOERBOzJGRHhCYSxtQkFBbUI7a0JBTi9CLFNBQVM7K0JBQ0UsaUJBQWlCLFVBRW5CLENBQUMsa0JBQWtCLENBQUMsUUFDdEIsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFOzhCQUdyQixLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUV1QyxlQUFlO3NCQUE1RCxTQUFTO3VCQUFDLGNBQWMsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENPREVfRURJVE9SX1NUWUxFUyB9IGZyb20gJy4vY29kZS1lZGl0b3Iuc3R5bGVzJztcblxuLyoqIE1hcHMgY3VzdG9tIGNvZGUgc3RlcCBsYW5ndWFnZSB2YWx1ZXMgdG8gTW9uYWNvIGVkaXRvciBsYW5ndWFnZSBJRHMgKi9cbmV4cG9ydCBjb25zdCBNT05BQ09fTEFOR1VBR0VfTUFQOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBqYXZhc2NyaXB0OiAnamF2YXNjcmlwdCcsXG4gIHR5cGVzY3JpcHQ6ICd0eXBlc2NyaXB0JyxcbiAgcHl0aG9uOiAncHl0aG9uJyxcbiAgamF2YTogJ2phdmEnLFxuICBydWJ5OiAncnVieScsXG4gIGdvOiAnZ28nLFxuICBydXN0OiAncnVzdCcsXG4gIGNzaGFycDogJ2NzaGFycCcsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvZGVFZGl0b3JNYXJrZXIge1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHNldmVyaXR5OiAnZXJyb3InIHwgJ3dhcm5pbmcnIHwgJ2luZm8nO1xuICBsaW5lTnVtYmVyOiBudW1iZXI7XG4gIGNvbHVtbj86IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLWNvZGUtZWRpdG9yJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvZGUtZWRpdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVzOiBbQ09ERV9FRElUT1JfU1RZTEVTXSxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9LFxufSlcbmV4cG9ydCBjbGFzcyBDb2RlRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIHZhbHVlID0gJyc7XG4gIEBJbnB1dCgpIGxhbmd1YWdlID0gJ2phdmFzY3JpcHQnO1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICcvLyBXcml0ZSB5b3VyIGNvZGUgaGVyZS4uLic7XG4gIEBJbnB1dCgpIGZ1bGxXaWR0aCA9IHRydWU7XG4gIEBJbnB1dCgpIGFyaWFMYWJlbCA9ICcnO1xuICBASW5wdXQoKSBtaW5IZWlnaHQgPSAnMjAwcHgnO1xuICBASW5wdXQoKSByZWFkT25seSA9IGZhbHNlO1xuICAvKiogRXh0ZXJuYWwgZXJyb3IgbWVzc2FnZXMgKGUuZy4gZnJvbSBmb3JtIHZhbGlkYXRpb24pLiBTaG93biBhbG9uZ3NpZGUgc3ludGF4IGVycm9ycy4gKi9cbiAgQElucHV0KCkgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAvKiogV2hlbiB0cnVlLCB1c2UgYSBwbGFpbiB0ZXh0YXJlYSBpbnN0ZWFkIG9mIE1vbmFjbyAoZS5nLiBmb3IgU3Rvcnlib29rIHdoZXJlIE1vbmFjbyBtYXkgbm90IGxvYWQpICovXG4gIEBJbnB1dCgpIHVzZUZhbGxiYWNrID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIHZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSB2YWxpZGF0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxDb2RlRWRpdG9yTWFya2VyW10+KCk7XG4gIEBPdXRwdXQoKSBibHVyID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ21vbmFjb0VkaXRvcicsIHsgc3RhdGljOiBmYWxzZSB9KSBtb25hY29FZGl0b3JSZWY6IHVua25vd247XG5cbiAgY29kZVZhbHVlID0gJyc7XG4gIHZhbGlkYXRpb25FcnJvcnM6IENvZGVFZGl0b3JNYXJrZXJbXSA9IFtdO1xuICBlZGl0b3JPcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICBwcml2YXRlIGVkaXRvckluc3RhbmNlOiB1bmtub3duID0gbnVsbDtcbiAgcHJpdmF0ZSBtYXJrZXJzU3Vic2NyaXB0aW9uOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBmYWxsYmFja1N5bnRheFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG1vbmFjb01hcmtlcnNUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvZGVWYWx1ZSA9IHRoaXMudmFsdWUgPz8gJyc7XG4gICAgdGhpcy51cGRhdGVFZGl0b3JPcHRpb25zKCk7XG4gICAgaWYgKHRoaXMudXNlRmFsbGJhY2sgJiYgWydqYXZhc2NyaXB0JywgJ3R5cGVzY3JpcHQnXS5pbmNsdWRlcyh0aGlzLmxhbmd1YWdlKSkge1xuICAgICAgdGhpcy5zY2hlZHVsZUZhbGxiYWNrU3ludGF4Q2hlY2sodGhpcy5jb2RlVmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZhbGxiYWNrU3ludGF4VGltZXIpIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrU3ludGF4VGltZXIpO1xuICAgIGlmICh0aGlzLm1vbmFjb01hcmtlcnNUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMubW9uYWNvTWFya2Vyc1RpbWVyKTtcbiAgICAgIHRoaXMubW9uYWNvTWFya2Vyc1RpbWVyID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5tYXJrZXJzU3Vic2NyaXB0aW9uPy4oKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1sndmFsdWUnXSAmJiBjaGFuZ2VzWyd2YWx1ZSddLmN1cnJlbnRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBuZXdWYWwgPSBjaGFuZ2VzWyd2YWx1ZSddLmN1cnJlbnRWYWx1ZSA/PyAnJztcbiAgICAgIC8vIE9ubHkgdXBkYXRlIHdoZW4gdmFsdWUgYWN0dWFsbHkgY2hhbmdlZCAtIGF2b2lkcyBvdmVyd3JpdGluZyB1c2VyIGlucHV0IGR1cmluZyB0eXBpbmdcbiAgICAgIGlmIChuZXdWYWwgIT09IHRoaXMuY29kZVZhbHVlKSB7XG4gICAgICAgIHRoaXMuY29kZVZhbHVlID0gbmV3VmFsO1xuICAgICAgICBpZiAodGhpcy51c2VGYWxsYmFjayAmJiBbJ2phdmFzY3JpcHQnLCAndHlwZXNjcmlwdCddLmluY2x1ZGVzKHRoaXMubGFuZ3VhZ2UpKSB7XG4gICAgICAgICAgdGhpcy5zY2hlZHVsZUZhbGxiYWNrU3ludGF4Q2hlY2sobmV3VmFsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBPbmx5IHVwZGF0ZSBlZGl0b3Igb3B0aW9ucyB3aGVuIGxhbmd1YWdlIG9yIHJlYWRPbmx5IGNoYW5nZXMgLSB2YWx1ZSBjaGFuZ2VzIG11c3QgTk9UXG4gICAgLy8gcmVjcmVhdGUgZWRpdG9yT3B0aW9ucyBvciBuZ3gtbW9uYWNvLWVkaXRvciB3aWxsIHJlLWluaXQgYW5kIGRpc3Bvc2UgdGhlIGVkaXRvcixcbiAgICAvLyBjYXVzaW5nIFwiQ2FuY2VsZWRcIiBlcnJvcnMgZnJvbSBNb25hY28ncyBhc3luYyBvcGVyYXRpb25zICh3b3JkIGhpZ2hsaWdodGluZywgZXRjLilcbiAgICBpZiAoY2hhbmdlc1snbGFuZ3VhZ2UnXSB8fCBjaGFuZ2VzWydyZWFkT25seSddKSB7XG4gICAgICB0aGlzLnVwZGF0ZUVkaXRvck9wdGlvbnMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUVkaXRvck9wdGlvbnMoKTogdm9pZCB7XG4gICAgY29uc3QgbW9uYWNvTGFuZyA9IE1PTkFDT19MQU5HVUFHRV9NQVBbdGhpcy5sYW5ndWFnZV0gfHwgdGhpcy5sYW5ndWFnZSB8fCAncGxhaW50ZXh0JztcbiAgICBjb25zdCBoYXNEaWFnbm9zdGljcyA9IFsnamF2YXNjcmlwdCcsICd0eXBlc2NyaXB0J10uaW5jbHVkZXMobW9uYWNvTGFuZyk7XG5cbiAgICB0aGlzLmVkaXRvck9wdGlvbnMgPSB7XG4gICAgICB0aGVtZTogJ3ZzJyxcbiAgICAgIGxhbmd1YWdlOiBtb25hY29MYW5nLFxuICAgICAgbWluaW1hcDogeyBlbmFibGVkOiBmYWxzZSB9LFxuICAgICAgc2Nyb2xsQmV5b25kTGFzdExpbmU6IGZhbHNlLFxuICAgICAgYXV0b21hdGljTGF5b3V0OiB0cnVlLFxuICAgICAgZm9udFNpemU6IDEzLFxuICAgICAgbGluZU51bWJlcnM6ICdvbicsXG4gICAgICByb3VuZGVkU2VsZWN0aW9uOiBmYWxzZSxcbiAgICAgIHJlYWRPbmx5OiB0aGlzLnJlYWRPbmx5LFxuICAgICAgY3Vyc29yU3R5bGU6ICdsaW5lJyxcbiAgICAgIHdvcmRXcmFwOiAnb24nLFxuICAgICAgLy8gdXNlV29ya2VyOiBmYWxzZSAtIE1vbmFjbyB3b3JrZXJzIHJlcXVpcmUgQU1EIGxvYWRlciAoZGVmaW5lKSB3aGljaCBmYWlscyBpblxuICAgICAgLy8gYnVuZGxlZCBlbnZpcm9ubWVudHMgKFN0b3J5Ym9vaywgc29tZSB3ZWJwYWNrIHNldHVwcykuIFJ1bm5pbmcgaW4gbWFpbiB0aHJlYWRcbiAgICAgIC8vIGF2b2lkcyBcImRlZmluZSBpcyBub3QgZGVmaW5lZFwiIGFuZCB3b3JrZXIgY3JlYXRpb24gZXJyb3JzLlxuICAgICAgLi4uKGhhc0RpYWdub3N0aWNzID8geyBxdWlja1N1Z2dlc3Rpb25zOiB0cnVlIH0gOiB7fSksXG4gICAgICB1c2VXb3JrZXI6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICBvbkNvZGVDaGFuZ2UobmV3VmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29kZVZhbHVlID0gbmV3VmFsdWU7XG4gICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KG5ld1ZhbHVlKTtcbiAgICBpZiAoIXRoaXMudXNlRmFsbGJhY2sgJiYgWydqYXZhc2NyaXB0JywgJ3R5cGVzY3JpcHQnXS5pbmNsdWRlcyh0aGlzLmxhbmd1YWdlKSkge1xuICAgICAgdGhpcy5zY2hlZHVsZUZhbGxiYWNrU3ludGF4Q2hlY2sobmV3VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIG9uRmFsbGJhY2tJbnB1dChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTFRleHRBcmVhRWxlbWVudDtcbiAgICBjb25zdCBuZXdWYWx1ZSA9IHRhcmdldD8udmFsdWUgPz8gJyc7XG4gICAgdGhpcy5jb2RlVmFsdWUgPSBuZXdWYWx1ZTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQobmV3VmFsdWUpO1xuICAgIGlmIChbJ2phdmFzY3JpcHQnLCAndHlwZXNjcmlwdCddLmluY2x1ZGVzKHRoaXMubGFuZ3VhZ2UpKSB7XG4gICAgICB0aGlzLnNjaGVkdWxlRmFsbGJhY2tTeW50YXhDaGVjayhuZXdWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIERlYm91bmNlZCBzeW50YXggY2hlY2sgZm9yIGZhbGxiYWNrIG1vZGUgLSBhdm9pZHMgcnVubmluZyBvbiBldmVyeSBrZXlzdHJva2UgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZUZhbGxiYWNrU3ludGF4Q2hlY2soY29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZmFsbGJhY2tTeW50YXhUaW1lcikgY2xlYXJUaW1lb3V0KHRoaXMuZmFsbGJhY2tTeW50YXhUaW1lcik7XG4gICAgdGhpcy5mYWxsYmFja1N5bnRheFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmZhbGxiYWNrU3ludGF4VGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5jaGVja0ZhbGxiYWNrU3ludGF4KGNvZGUpO1xuICAgIH0sIDMwMCk7XG4gIH1cblxuICAvKiogU3ludGF4IHZhbGlkYXRpb24gZm9yIGZhbGxiYWNrICh0ZXh0YXJlYSkgbW9kZSAtIEpTL1RTIG9ubHkgKi9cbiAgcHJpdmF0ZSBjaGVja0ZhbGxiYWNrU3ludGF4KGNvZGU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghWydqYXZhc2NyaXB0JywgJ3R5cGVzY3JpcHQnXS5pbmNsdWRlcyh0aGlzLmxhbmd1YWdlKSkge1xuICAgICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzID0gW107XG4gICAgICB0aGlzLnZhbGlkYXRpb25DaGFuZ2UuZW1pdCh0aGlzLnZhbGlkYXRpb25FcnJvcnMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWNvZGUgfHwgIWNvZGUudHJpbSgpKSB7XG4gICAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSBbXTtcbiAgICAgIHRoaXMudmFsaWRhdGlvbkNoYW5nZS5lbWl0KHRoaXMudmFsaWRhdGlvbkVycm9ycyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBuZXcgRnVuY3Rpb24oY29kZSk7XG4gICAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSBbXTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFN5bnRheEVycm9yKSB7XG4gICAgICAgIGNvbnN0IGVyciA9IGUgYXMgU3ludGF4RXJyb3IgJiB7IGxpbmVOdW1iZXI/OiBudW1iZXI7IGNvbHVtbk51bWJlcj86IG51bWJlciB9O1xuICAgICAgICBjb25zdCBsaW5lID0gZXJyLmxpbmVOdW1iZXIgPz8gMTtcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzID0gW3tcbiAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSB8fCAnU3ludGF4IGVycm9yJyxcbiAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lLFxuICAgICAgICAgIGNvbHVtbjogZXJyLmNvbHVtbk51bWJlcixcbiAgICAgICAgfV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy52YWxpZGF0aW9uQ2hhbmdlLmVtaXQodGhpcy52YWxpZGF0aW9uRXJyb3JzKTtcbiAgfVxuXG4gIG9uRWRpdG9ySW5pdChlZGl0b3I6IHtcbiAgICBnZXRNb2RlbD86ICgpID0+IHsgdXJpPzogeyB0b1N0cmluZz86ICgpID0+IHN0cmluZyB9IH07XG4gICAgb25EaWRDaGFuZ2VNb2RlbENvbnRlbnQ/OiAoZm46ICgpID0+IHZvaWQpID0+IHsgZGlzcG9zZT86ICgpID0+IHZvaWQgfTtcbiAgICBvbkRpZEJsdXJFZGl0b3JXaWRnZXQ/OiAoZm46ICgpID0+IHZvaWQpID0+IHsgZGlzcG9zZT86ICgpID0+IHZvaWQgfTtcbiAgfSk6IHZvaWQge1xuICAgIHRoaXMuZWRpdG9ySW5zdGFuY2UgPSBlZGl0b3I7XG4gICAgdGhpcy5zZXR1cE1hcmtlcnNMaXN0ZW5lcihlZGl0b3IpO1xuICAgIGVkaXRvci5vbkRpZEJsdXJFZGl0b3JXaWRnZXQ/LigoKSA9PiB0aGlzLmJsdXIuZW1pdCgpKTtcbiAgICBpZiAoWydqYXZhc2NyaXB0JywgJ3R5cGVzY3JpcHQnXS5pbmNsdWRlcyh0aGlzLmxhbmd1YWdlKSkge1xuICAgICAgdGhpcy5zY2hlZHVsZUZhbGxiYWNrU3ludGF4Q2hlY2sodGhpcy5jb2RlVmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBNYXJrZXJzTGlzdGVuZXIoZWRpdG9yOiB7XG4gICAgZ2V0TW9kZWw/OiAoKSA9PiB7IHVyaT86IHVua25vd24gfTtcbiAgICBvbkRpZENoYW5nZU1vZGVsQ29udGVudD86IChmbjogKCkgPT4gdm9pZCkgPT4geyBkaXNwb3NlPzogKCkgPT4gdm9pZCB9O1xuICB9KTogdm9pZCB7XG4gICAgdGhpcy5tYXJrZXJzU3Vic2NyaXB0aW9uPy4oKTtcblxuICAgIGNvbnN0IG1vZGVsID0gZWRpdG9yLmdldE1vZGVsPy4oKTtcbiAgICBpZiAoIW1vZGVsPy51cmkpIHJldHVybjtcblxuICAgIGNvbnN0IHdpbiA9IHdpbmRvdyBhcyB1bmtub3duIGFzIHtcbiAgICAgIG1vbmFjbz86IHtcbiAgICAgICAgZWRpdG9yPzoge1xuICAgICAgICAgIGdldE1vZGVsTWFya2Vycz86IChmaWx0ZXI6IHsgcmVzb3VyY2U/OiB1bmtub3duIH0pID0+IEFycmF5PHtcbiAgICAgICAgICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgICAgICAgICBzZXZlcml0eT86IG51bWJlcjtcbiAgICAgICAgICAgIHN0YXJ0TGluZU51bWJlcj86IG51bWJlcjtcbiAgICAgICAgICAgIHN0YXJ0Q29sdW1uPzogbnVtYmVyO1xuICAgICAgICAgIH0+O1xuICAgICAgICAgIG9uRGlkQ2hhbmdlTWFya2Vycz86IChmbjogKHVyaXM6IHVua25vd25bXSkgPT4gdm9pZCkgPT4geyBkaXNwb3NlPzogKCkgPT4gdm9pZCB9O1xuICAgICAgICB9O1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgY29uc3QgY2hlY2tNYXJrZXJzID0gKCk6IHZvaWQgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCF3aW4ubW9uYWNvPy5lZGl0b3I/LmdldE1vZGVsTWFya2VycykgcmV0dXJuO1xuICAgICAgICBjb25zdCBtYXJrZXJzID0gd2luLm1vbmFjby5lZGl0b3IuZ2V0TW9kZWxNYXJrZXJzKHsgcmVzb3VyY2U6IG1vZGVsLnVyaSB9KSB8fCBbXTtcbiAgICAgICAgY29uc3QgbW9uYWNvRXJyb3JzID0gbWFya2Vyc1xuICAgICAgICAgIC5maWx0ZXIoKG0pID0+IG0uc2V2ZXJpdHkgPT09IDgpIC8vIDggPSBFcnJvciBpbiBNb25hY29cbiAgICAgICAgICAubWFwKChtKSA9PiAoe1xuICAgICAgICAgICAgbWVzc2FnZTogbS5tZXNzYWdlIHx8ICdTeW50YXggZXJyb3InLFxuICAgICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicgYXMgY29uc3QsXG4gICAgICAgICAgICBsaW5lTnVtYmVyOiBtLnN0YXJ0TGluZU51bWJlciB8fCAxLFxuICAgICAgICAgICAgY29sdW1uOiBtLnN0YXJ0Q29sdW1uLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgLy8gT25seSB1cGRhdGUgZnJvbSBNb25hY28gd2hlbiBpdCBoYXMgbWFya2VycyAtIG90aGVyd2lzZSBrZWVwIGZhbGxiYWNrIHJlc3VsdHNcbiAgICAgICAgLy8gKE1vbmFjbyBtYXkgbm90IHByb2R1Y2UgbWFya2VycyB3aGVuIHVzZVdvcmtlcjogZmFsc2UgaW4gYnVuZGxlZCBlbnZpcm9ubWVudHMpXG4gICAgICAgIGlmIChtb25hY29FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMudmFsaWRhdGlvbkVycm9ycyA9IG1vbmFjb0Vycm9ycztcbiAgICAgICAgICB0aGlzLnZhbGlkYXRpb25DaGFuZ2UuZW1pdCh0aGlzLnZhbGlkYXRpb25FcnJvcnMpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTW9uYWNvIG1heSBub3QgYmUgbG9hZGVkIHlldFxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBkaXNwb3NlTWFya2VycyA9IHdpbi5tb25hY28/LmVkaXRvcj8ub25EaWRDaGFuZ2VNYXJrZXJzPy4oKCkgPT4ge1xuICAgICAgY2hlY2tNYXJrZXJzKCk7XG4gICAgfSk7XG4gICAgY29uc3Qgc2NoZWR1bGVDaGVja01hcmtlcnMgPSAoKTogdm9pZCA9PiB7XG4gICAgICBpZiAodGhpcy5tb25hY29NYXJrZXJzVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLm1vbmFjb01hcmtlcnNUaW1lcik7XG4gICAgICB0aGlzLm1vbmFjb01hcmtlcnNUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLm1vbmFjb01hcmtlcnNUaW1lciA9IG51bGw7XG4gICAgICAgIGNoZWNrTWFya2VycygpO1xuICAgICAgfSwgNDAwKTtcbiAgICB9O1xuICAgIGVkaXRvci5vbkRpZENoYW5nZU1vZGVsQ29udGVudD8uKHNjaGVkdWxlQ2hlY2tNYXJrZXJzKTtcbiAgICBzZXRUaW1lb3V0KGNoZWNrTWFya2VycywgNjAwKTtcblxuICAgIHRoaXMubWFya2Vyc1N1YnNjcmlwdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGlmICh0aGlzLm1vbmFjb01hcmtlcnNUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5tb25hY29NYXJrZXJzVGltZXIpO1xuICAgICAgICB0aGlzLm1vbmFjb01hcmtlcnNUaW1lciA9IG51bGw7XG4gICAgICB9XG4gICAgICBkaXNwb3NlTWFya2Vycz8uZGlzcG9zZT8uKCk7XG4gICAgfTtcbiAgfVxuXG4gIGdldCBoYXNWYWxpZGF0aW9uRXJyb3JzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldCBoYXNFcnJvcnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmVycm9ycz8ubGVuZ3RoID8/IDApID4gMCB8fCB0aGlzLmhhc1ZhbGlkYXRpb25FcnJvcnM7XG4gIH1cblxuICAvKiogQWxsIGVycm9yIG1lc3NhZ2VzOiBleHRlcm5hbCBlcnJvcnMgKyBzeW50YXggZXJyb3JzIGZvcm1hdHRlZCBhcyBzdHJpbmdzICovXG4gIGdldCBhbGxFcnJvck1lc3NhZ2VzKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBleHRlcm5hbCA9IHRoaXMuZXJyb3JzID8/IFtdO1xuICAgIGNvbnN0IHN5bnRheCA9IHRoaXMudmFsaWRhdGlvbkVycm9ycy5tYXAoXG4gICAgICAoZSkgPT4gYExpbmUgJHtlLmxpbmVOdW1iZXJ9OiAke2UubWVzc2FnZX1gXG4gICAgKTtcbiAgICByZXR1cm4gWy4uLmV4dGVybmFsLCAuLi5zeW50YXhdO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS13LWZ1bGxcIiBbc3R5bGUud2lkdGhdPVwiZnVsbFdpZHRoID8gJzEwMCUnIDogJ2F1dG8nXCI+XG4gIDxsYWJlbFxuICAgICpuZ0lmPVwibGFiZWxcIlxuICAgIGNsYXNzPVwiY3FhLWxlYWRpbmctWzEwMCVdIGNxYS1ibG9jayBjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMTYxNjE3XSBjcWEtbWItMVwiPlxuICAgIHt7IGxhYmVsIH19XG4gICAgPHNwYW4gKm5nSWY9XCJyZXF1aXJlZFwiIGNsYXNzPVwiY3FhLXRleHQtWyNFRjQ0NDRdIGNxYS1tbC0wLjVcIj4qPC9zcGFuPlxuICA8L2xhYmVsPlxuXG4gIDwhLS0gRmFsbGJhY2s6IHBsYWluIHRleHRhcmVhIHdoZW4gTW9uYWNvIGlzIG5vdCBhdmFpbGFibGUgKGUuZy4gU3Rvcnlib29rKSAtLT5cbiAgPGRpdlxuICAgICpuZ0lmPVwidXNlRmFsbGJhY2tcIlxuICAgIGNsYXNzPVwiY3FhLWNvZGUtZWRpdG9yLWNvbnRhaW5lciBjcWEtY29kZS1lZGl0b3ItZmFsbGJhY2sgY3FhLXctZnVsbFwiXG4gICAgW2NsYXNzLmNxYS1oYXMtZXJyb3JzXT1cImhhc0Vycm9yc1wiXG4gICAgW3N0eWxlLmhlaWdodF09XCJtaW5IZWlnaHRcIlxuICAgIFtzdHlsZS5taW4taGVpZ2h0XT1cIm1pbkhlaWdodFwiPlxuICAgIDx0ZXh0YXJlYVxuICAgICAgY2xhc3M9XCJjcWEtY29kZS1lZGl0b3ItdGV4dGFyZWFcIlxuICAgICAgW3ZhbHVlXT1cImNvZGVWYWx1ZVwiXG4gICAgICAoaW5wdXQpPVwib25GYWxsYmFja0lucHV0KCRldmVudClcIlxuICAgICAgKGJsdXIpPVwiYmx1ci5lbWl0KClcIlxuICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgIFtyZWFkb25seV09XCJyZWFkT25seVwiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbCB8fCBsYWJlbCB8fCAnQ29kZSBlZGl0b3InXCJcbiAgICAgIFthdHRyLmFyaWEtaW52YWxpZF09XCJoYXNFcnJvcnNcIlxuICAgICAgW2F0dHIuYXJpYS1yZXF1aXJlZF09XCJyZXF1aXJlZFwiPlxuICAgIDwvdGV4dGFyZWE+XG4gIDwvZGl2PlxuICA8IS0tIE1vbmFjbyBlZGl0b3IgKHVzZWQgaW4gbWFpbiBhcHApIC0tPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhdXNlRmFsbGJhY2tcIlxuICAgIGNsYXNzPVwiY3FhLWNvZGUtZWRpdG9yLWNvbnRhaW5lciBjcWEtdy1mdWxsXCJcbiAgICBbY2xhc3MuY3FhLWhhcy1lcnJvcnNdPVwiaGFzRXJyb3JzXCJcbiAgICBbc3R5bGUuaGVpZ2h0XT1cIm1pbkhlaWdodFwiXG4gICAgW3N0eWxlLm1pbi1oZWlnaHRdPVwibWluSGVpZ2h0XCI+XG4gICAgPG5neC1tb25hY28tZWRpdG9yXG4gICAgICAjbW9uYWNvRWRpdG9yXG4gICAgICBjbGFzcz1cImNxYS1tb25hY28tZWRpdG9yXCJcbiAgICAgIFtvcHRpb25zXT1cImVkaXRvck9wdGlvbnNcIlxuICAgICAgW25nTW9kZWxdPVwiY29kZVZhbHVlXCJcbiAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uQ29kZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgIChvbkluaXQpPVwib25FZGl0b3JJbml0KCRldmVudClcIj5cbiAgICA8L25neC1tb25hY28tZWRpdG9yPlxuICA8L2Rpdj5cblxuICA8IS0tIEVycm9yIG1lc3NhZ2VzIChzYW1lIHN0eWxlIGFzIGN1c3RvbS10ZXh0YXJlYSkgLS0+XG4gIDxkaXYgKm5nSWY9XCJoYXNFcnJvcnNcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEgY3FhLW10LTEuNVwiPlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IGVycm9yIG9mIGFsbEVycm9yTWVzc2FnZXNcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1zdGFydCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgPHN2Z1xuICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbiAgICAgICAgd2lkdGg9XCIxNFwiXG4gICAgICAgIGhlaWdodD1cIjE0XCJcbiAgICAgICAgdmlld0JveD1cIjAgMCAxNCAxNFwiXG4gICAgICAgIGZpbGw9XCJub25lXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtZmxleC1zaHJpbmstMCBjcWEtbXQtMC41XCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNNyAxLjc1QzQuMSAxLjc1IDEuNzUgNC4xIDEuNzUgN0MxLjc1IDkuOSA0LjEgMTIuMjUgNyAxMi4yNUM5LjkgMTIuMjUgMTIuMjUgOS45IDEyLjI1IDdDMTIuMjUgNC4xIDkuOSAxLjc1IDcgMS43NVpNNyA5LjYyNUM2LjY1NjI1IDkuNjI1IDYuMzc1IDkuMzQzNzUgNi4zNzUgOVY3QzYuMzc1IDYuNjU2MjUgNi42NTYyNSA2LjM3NSA3IDYuMzc1QzcuMzQzNzUgNi4zNzUgNy42MjUgNi42NTYyNSA3LjYyNSA3VjlDNy42MjUgOS4zNDM3NSA3LjM0Mzc1IDkuNjI1IDcgOS42MjVaTTcuNjI1IDUuMjVINi4zNzVWNEg3LjYyNVY1LjI1WlwiIGZpbGw9XCIjRUY0NDQ0XCIvPlxuICAgICAgPC9zdmc+XG4gICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LVsjRUY0NDQ0XSBjcWEtZm9udC1tZWRpdW0gY3FhLWxlYWRpbmctWzE4cHhdXCI+XG4gICAgICAgIHt7IGVycm9yIH19XG4gICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Code editor styles as a string for use in component `styles` arrays.
3
+ * Matches step-builder-custom-code form styling (custom-input, custom-textarea).
4
+ * Using a string constant avoids Angular's style compiler receiving non-string values
5
+ * (e.g. from styleUrls resolution in Storybook), which causes "input.match is not a function".
6
+ */
7
+ export const CODE_EDITOR_STYLES = `
8
+ .cqa-code-editor-container {
9
+ min-height: 200px;
10
+ height: 200px;
11
+ border: 1px solid #e5e7eb;
12
+ border-radius: 6px;
13
+ overflow: hidden;
14
+ display: flex;
15
+ flex-direction: column;
16
+ background: #fff;
17
+ transition: border-color 0.2s, box-shadow 0.2s;
18
+ }
19
+ .cqa-code-editor-container:focus-within {
20
+ border-color: #3b82f6;
21
+ box-shadow: 0 0 0 1px #3b82f6;
22
+ }
23
+ .cqa-code-editor-container.cqa-has-errors {
24
+ border-color: #ef4444;
25
+ }
26
+ .cqa-code-editor-container.cqa-has-errors:focus-within {
27
+ border-color: #ef4444;
28
+ box-shadow: 0 0 0 1px #ef4444;
29
+ }
30
+ .cqa-code-editor-container .cqa-monaco-editor,
31
+ .cqa-code-editor-container ngx-monaco-editor {
32
+ flex: 1;
33
+ min-height: 0;
34
+ }
35
+ .cqa-code-editor-container ::ng-deep .monaco-editor {
36
+ height: 100% !important;
37
+ }
38
+ .cqa-code-editor-fallback .cqa-code-editor-textarea {
39
+ width: 100%;
40
+ height: 100%;
41
+ min-height: 180px;
42
+ padding: 12px;
43
+ font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, monospace;
44
+ font-size: 13px;
45
+ line-height: 1.5;
46
+ border: none;
47
+ resize: none;
48
+ outline: none;
49
+ background: #fff;
50
+ color: #0a0a0a;
51
+ }
52
+ .cqa-code-editor-fallback .cqa-code-editor-textarea::placeholder {
53
+ color: #9ca3af;
54
+ }
55
+ `;
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3Iuc3R5bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci5zdHlsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBZ0RqQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb2RlIGVkaXRvciBzdHlsZXMgYXMgYSBzdHJpbmcgZm9yIHVzZSBpbiBjb21wb25lbnQgYHN0eWxlc2AgYXJyYXlzLlxuICogTWF0Y2hlcyBzdGVwLWJ1aWxkZXItY3VzdG9tLWNvZGUgZm9ybSBzdHlsaW5nIChjdXN0b20taW5wdXQsIGN1c3RvbS10ZXh0YXJlYSkuXG4gKiBVc2luZyBhIHN0cmluZyBjb25zdGFudCBhdm9pZHMgQW5ndWxhcidzIHN0eWxlIGNvbXBpbGVyIHJlY2VpdmluZyBub24tc3RyaW5nIHZhbHVlc1xuICogKGUuZy4gZnJvbSBzdHlsZVVybHMgcmVzb2x1dGlvbiBpbiBTdG9yeWJvb2spLCB3aGljaCBjYXVzZXMgXCJpbnB1dC5tYXRjaCBpcyBub3QgYSBmdW5jdGlvblwiLlxuICovXG5leHBvcnQgY29uc3QgQ09ERV9FRElUT1JfU1RZTEVTID0gYFxuLmNxYS1jb2RlLWVkaXRvci1jb250YWluZXIge1xuICBtaW4taGVpZ2h0OiAyMDBweDtcbiAgaGVpZ2h0OiAyMDBweDtcbiAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTdlYjtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgMC4ycywgYm94LXNoYWRvdyAwLjJzO1xufVxuLmNxYS1jb2RlLWVkaXRvci1jb250YWluZXI6Zm9jdXMtd2l0aGluIHtcbiAgYm9yZGVyLWNvbG9yOiAjM2I4MmY2O1xuICBib3gtc2hhZG93OiAwIDAgMCAxcHggIzNiODJmNjtcbn1cbi5jcWEtY29kZS1lZGl0b3ItY29udGFpbmVyLmNxYS1oYXMtZXJyb3JzIHtcbiAgYm9yZGVyLWNvbG9yOiAjZWY0NDQ0O1xufVxuLmNxYS1jb2RlLWVkaXRvci1jb250YWluZXIuY3FhLWhhcy1lcnJvcnM6Zm9jdXMtd2l0aGluIHtcbiAgYm9yZGVyLWNvbG9yOiAjZWY0NDQ0O1xuICBib3gtc2hhZG93OiAwIDAgMCAxcHggI2VmNDQ0NDtcbn1cbi5jcWEtY29kZS1lZGl0b3ItY29udGFpbmVyIC5jcWEtbW9uYWNvLWVkaXRvcixcbi5jcWEtY29kZS1lZGl0b3ItY29udGFpbmVyIG5neC1tb25hY28tZWRpdG9yIHtcbiAgZmxleDogMTtcbiAgbWluLWhlaWdodDogMDtcbn1cbi5jcWEtY29kZS1lZGl0b3ItY29udGFpbmVyIDo6bmctZGVlcCAubW9uYWNvLWVkaXRvciB7XG4gIGhlaWdodDogMTAwJSAhaW1wb3J0YW50O1xufVxuLmNxYS1jb2RlLWVkaXRvci1mYWxsYmFjayAuY3FhLWNvZGUtZWRpdG9yLXRleHRhcmVhIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgbWluLWhlaWdodDogMTgwcHg7XG4gIHBhZGRpbmc6IDEycHg7XG4gIGZvbnQtZmFtaWx5OiBNb25hY28sIE1lbmxvLCBcIlVidW50dSBNb25vXCIsIENvbnNvbGFzLCBtb25vc3BhY2U7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgYm9yZGVyOiBub25lO1xuICByZXNpemU6IG5vbmU7XG4gIG91dGxpbmU6IG5vbmU7XG4gIGJhY2tncm91bmQ6ICNmZmY7XG4gIGNvbG9yOiAjMGEwYTBhO1xufVxuLmNxYS1jb2RlLWVkaXRvci1mYWxsYmFjayAuY3FhLWNvZGUtZWRpdG9yLXRleHRhcmVhOjpwbGFjZWhvbGRlciB7XG4gIGNvbG9yOiAjOWNhM2FmO1xufVxuYDtcbiJdfQ==