@cqa-lib/cqa-ui 1.1.549-delta.1 → 1.1.549-delta.2
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.
- package/esm2020/lib/test-case-details/api-edit-step/api-edit-step.component.mjs +298 -19
- package/esm2020/lib/test-case-details/api-edit-step/graphql-operation-picker/graphql-operation-picker.component.mjs +121 -0
- package/esm2020/lib/ui-kit.module.mjs +6 -1
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +413 -30
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +408 -11
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/test-case-details/api-edit-step/api-edit-step.component.d.ts +108 -5
- package/lib/test-case-details/api-edit-step/graphql-operation-picker/graphql-operation-picker.component.d.ts +83 -0
- package/lib/ui-kit.module.d.ts +60 -59
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/styles.css +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/material/icon";
|
|
4
|
+
import * as i2 from "../../../button/button.component";
|
|
5
|
+
import * as i3 from "../../../custom-input/custom-input.component";
|
|
6
|
+
import * as i4 from "@angular/common";
|
|
7
|
+
export class GraphQLOperationPickerComponent {
|
|
8
|
+
constructor() {
|
|
9
|
+
/** Flat operations list. Picker partitions by `kind` for the section headers. */
|
|
10
|
+
this.operations = [];
|
|
11
|
+
/** Display state for the "Introspected" / "Pending" badge in the title row. */
|
|
12
|
+
this.introspected = false;
|
|
13
|
+
/** True while the parent is fetching/introspecting a schema. Renders a spinner instead of the empty state. */
|
|
14
|
+
this.isLoading = false;
|
|
15
|
+
/** Emitted when the user clicks the back arrow above the title (returns to the main step 1 view). */
|
|
16
|
+
this.back = new EventEmitter();
|
|
17
|
+
/** Emitted when the user clicks an operation row. Parent patches graphQLForm and pops the picker. */
|
|
18
|
+
this.operationSelected = new EventEmitter();
|
|
19
|
+
/** Emitted when the user clicks Re-introspect — parent re-fetches the schema. */
|
|
20
|
+
this.reIntrospect = new EventEmitter();
|
|
21
|
+
/** Emitted when the user clicks Change — parent shows a URL/auth picker (deferred for now). */
|
|
22
|
+
this.change = new EventEmitter();
|
|
23
|
+
/** Emitted when the user clicks Preview on a row — parent shows a preview popover (deferred). */
|
|
24
|
+
this.preview = new EventEmitter();
|
|
25
|
+
/** Filter input value. Plain substring match across name / description / returnType. */
|
|
26
|
+
this.filterTerm = '';
|
|
27
|
+
}
|
|
28
|
+
/** Operations currently shown after applying `filterTerm`. */
|
|
29
|
+
get filteredOperations() {
|
|
30
|
+
const term = this.filterTerm.trim().toLowerCase();
|
|
31
|
+
if (!term)
|
|
32
|
+
return this.operations || [];
|
|
33
|
+
return (this.operations || []).filter((o) => o.name.toLowerCase().includes(term) ||
|
|
34
|
+
(o.description ?? '').toLowerCase().includes(term) ||
|
|
35
|
+
(o.returnType ?? '').toLowerCase().includes(term));
|
|
36
|
+
}
|
|
37
|
+
get queryOperations() {
|
|
38
|
+
return this.filteredOperations.filter((o) => o.kind === 'query');
|
|
39
|
+
}
|
|
40
|
+
get mutationOperations() {
|
|
41
|
+
return this.filteredOperations.filter((o) => o.kind === 'mutation');
|
|
42
|
+
}
|
|
43
|
+
get subscriptionOperations() {
|
|
44
|
+
return this.filteredOperations.filter((o) => o.kind === 'subscription');
|
|
45
|
+
}
|
|
46
|
+
/** Convenience: total schema-source count line, e.g. "38 types · 4 queries · 3 mutations". */
|
|
47
|
+
get headerCounts() {
|
|
48
|
+
const parts = [];
|
|
49
|
+
const s = this.schemaSource;
|
|
50
|
+
if (!s)
|
|
51
|
+
return '';
|
|
52
|
+
if (s.typeCount != null)
|
|
53
|
+
parts.push(`${s.typeCount} types`);
|
|
54
|
+
if (s.queryCount != null)
|
|
55
|
+
parts.push(`${s.queryCount} ${s.queryCount === 1 ? 'query' : 'queries'}`);
|
|
56
|
+
if (s.mutationCount != null)
|
|
57
|
+
parts.push(`${s.mutationCount} ${s.mutationCount === 1 ? 'mutation' : 'mutations'}`);
|
|
58
|
+
if (s.subscriptionCount != null && s.subscriptionCount > 0) {
|
|
59
|
+
parts.push(`${s.subscriptionCount} ${s.subscriptionCount === 1 ? 'subscription' : 'subscriptions'}`);
|
|
60
|
+
}
|
|
61
|
+
return parts.join(' · ');
|
|
62
|
+
}
|
|
63
|
+
onBack() {
|
|
64
|
+
this.back.emit();
|
|
65
|
+
}
|
|
66
|
+
onSelect(op) {
|
|
67
|
+
this.operationSelected.emit(op);
|
|
68
|
+
}
|
|
69
|
+
onPreview(op, event) {
|
|
70
|
+
// Stop the click from also bubbling to the row's select handler — Preview is a peek,
|
|
71
|
+
// not a commit.
|
|
72
|
+
event.stopPropagation();
|
|
73
|
+
this.preview.emit(op);
|
|
74
|
+
}
|
|
75
|
+
onReIntrospect() {
|
|
76
|
+
this.reIntrospect.emit(this.schemaSource);
|
|
77
|
+
}
|
|
78
|
+
onChange() {
|
|
79
|
+
this.change.emit();
|
|
80
|
+
}
|
|
81
|
+
onFilterChange(value) {
|
|
82
|
+
this.filterTerm = value ?? '';
|
|
83
|
+
}
|
|
84
|
+
trackByOperation(_index, op) {
|
|
85
|
+
return op.id;
|
|
86
|
+
}
|
|
87
|
+
/** Tailwind text colour for the return-type pill, keyed by operation kind. */
|
|
88
|
+
returnTypeColorClass(kind) {
|
|
89
|
+
switch (kind) {
|
|
90
|
+
case 'mutation': return 'cqa-text-[#D97706]'; // amber-600
|
|
91
|
+
case 'subscription': return 'cqa-text-[#7C3AED]'; // violet-600
|
|
92
|
+
case 'query':
|
|
93
|
+
default: return 'cqa-text-[#059669]'; // emerald-600
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
GraphQLOperationPickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GraphQLOperationPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
+
GraphQLOperationPickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: GraphQLOperationPickerComponent, selector: "cqa-graphql-operation-picker", inputs: { schemaSource: "schemaSource", operations: "operations", introspected: "introspected", isLoading: "isLoading" }, outputs: { back: "back", operationSelected: "operationSelected", reIntrospect: "reIntrospect", change: "change", preview: "preview" }, host: { classAttribute: "cqa-ui-root" }, ngImport: i0, template: "<div class=\"cqa-graphql-operation-picker cqa-flex cqa-flex-col cqa-gap-4 cqa-bg-white cqa-w-full\">\n\n <!-- Title row: back arrow + heading + Introspected badge -->\n <div class=\"cqa-graphql-operation-picker-header cqa-flex cqa-items-center cqa-gap-3\">\n <div class=\"cqa-cursor-pointer cqa-text-[#6B7280] cqa-text-[14px] cqa-font-semibold\" (click)=\"onBack()\">\n <mat-icon class=\"cqa-flex cqa-items-center cqa-justify-center cqa-text-[18px] cqa-text-[#6B7280] cqa-font-semibold\" style=\"display:flex;font-size:18px;font-weight: 600;\">arrow_back</mat-icon>\n </div>\n <h3 class=\"cqa-graphql-operation-picker-title cqa-m-0 cqa-text-[18px] cqa-font-semibold cqa-text-[#111827] cqa-leading-[1.25]\">\n Pick a GraphQL operation\n </h3>\n <span *ngIf=\"introspected\"\n class=\"cqa-graphql-operation-picker-badge cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-[2px] cqa-rounded-full cqa-bg-[#EDE9FE] cqa-text-[#7C3AED] cqa-text-[11px] cqa-font-medium cqa-leading-[1.4]\">\n <span aria-hidden=\"true\">\u25C6</span> Introspected\n </span>\n </div>\n\n <!-- Subheading -->\n <p class=\"cqa-graphql-operation-picker-subheading cqa-m-0 cqa-text-[12px] cqa-text-[#6B7280] cqa-leading-[1.5]\">\n Phase 1 supports one operation per test step. Select one to auto-fill the request.\n </p>\n\n <!-- Schema source bar: URL + counts + Re-introspect / Change buttons -->\n <div class=\"cqa-graphql-operation-picker-source cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-bg-[#EEF2FF] cqa-rounded-lg cqa-px-4 cqa-py-3 cqa-border cqa-border-solid cqa-border-[#E0E7FF]\">\n <div class=\"cqa-graphql-operation-picker-source-info cqa-flex cqa-flex-col cqa-gap-0.5 cqa-min-w-0\">\n <div class=\"cqa-graphql-operation-picker-source-label cqa-text-[10px] cqa-uppercase cqa-tracking-wide cqa-text-[#6B7280] cqa-font-semibold\">\n Schema source\n </div>\n <div *ngIf=\"schemaSource?.url\"\n class=\"cqa-graphql-operation-picker-source-url cqa-text-[13px] cqa-font-mono cqa-text-[#1F2937] cqa-truncate cqa-min-w-0\"\n [title]=\"schemaSource?.url\">\n {{ schemaSource?.url }}\n </div>\n <div *ngIf=\"!schemaSource?.url\"\n class=\"cqa-graphql-operation-picker-source-url cqa-text-[13px] cqa-italic cqa-text-[#6B7280]\">\n No schema loaded yet.\n </div>\n </div>\n <div class=\"cqa-graphql-operation-picker-source-meta cqa-flex cqa-items-center cqa-gap-3 cqa-shrink-0\">\n <span *ngIf=\"headerCounts\" class=\"cqa-graphql-operation-picker-source-counts cqa-text-[12px] cqa-text-[#4B5563]\">\n {{ headerCounts }}\n </span>\n <cqa-button type=\"button\" variant=\"outlined\" [icon]=\"'refresh'\" btnSize=\"md\" text=\"Re-introspect\"\n customClass=\"!cqa-bg-white !cqa-text-[#374151] !cqa-border !cqa-border-solid !cqa-border-[#D1D5DB] cqa-text-[12px] cqa-font-medium hover:!cqa-bg-[#F9FAFB]\"\n (clicked)=\"onReIntrospect()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\" btnSize=\"md\" text=\"Change\"\n customClass=\"!cqa-text-[#4F46E5] cqa-text-[12px] cqa-font-medium hover:!cqa-bg-[#EEF2FF]\"\n (clicked)=\"onChange()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Filter -->\n <cqa-custom-input\n [(value)]=\"filterTerm\"\n [label]=\"''\"\n placeholder=\"Filter operations...\"\n [fullWidth]=\"true\"\n size=\"md\"\n ariaLabel=\"Filter GraphQL operations\">\n </cqa-custom-input>\n\n <!-- Loading spinner shown while the parent is introspecting. Replaces the empty state. -->\n <div *ngIf=\"isLoading\"\n class=\"cqa-graphql-operation-picker-loading cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-12 cqa-text-center cqa-bg-[#F9FAFB] cqa-rounded-md cqa-border cqa-border-dashed cqa-border-[#E5E7EB]\">\n <span class=\"cqa-graphql-operation-picker-spinner cqa-inline-block cqa-w-7 cqa-h-7 cqa-rounded-full cqa-border-2 cqa-border-solid cqa-border-[#E5E7EB] cqa-border-t-[#4F46E5] cqa-animate-spin\" aria-hidden=\"true\"></span>\n <span class=\"cqa-text-[13px] cqa-font-medium cqa-text-[#374151]\">Loading schema\u2026</span>\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Introspecting GraphQL endpoint, this may take a moment.</span>\n </div>\n\n <!-- Empty state when no operations are loaded yet (or filter rules everything out). -->\n <div *ngIf=\"!isLoading && !filteredOperations.length\"\n class=\"cqa-graphql-operation-picker-empty cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-2 cqa-py-10 cqa-text-center cqa-bg-[#F9FAFB] cqa-rounded-md cqa-border cqa-border-dashed cqa-border-[#E5E7EB]\">\n <span class=\"cqa-text-[13px] cqa-font-medium cqa-text-[#374151]\">\n {{ filterTerm ? 'No operations match your filter.' : 'No operations available.' }}\n </span>\n <span *ngIf=\"!filterTerm\" class=\"cqa-text-[12px] cqa-text-[#6B7280]\">\n Click <strong>Re-introspect</strong> above to load the schema.\n </span>\n </div>\n\n <!-- Operation sections (Queries / Mutations / Subscriptions) -->\n <ng-container *ngIf=\"!isLoading && filteredOperations.length\">\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: queryOperations, label: 'Queries', accent: 'cqa-text-[#059669]' }\"></ng-container>\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: mutationOperations, label: 'Mutations', accent: 'cqa-text-[#D97706]' }\"></ng-container>\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: subscriptionOperations, label: 'Subscriptions', accent: 'cqa-text-[#7C3AED]' }\"></ng-container>\n </ng-container>\n\n <!-- Footer: selection summary. No Back / Use buttons \u2014 clicking a row commits + returns. -->\n <div *ngIf=\"!isLoading && filteredOperations.length\" class=\"cqa-graphql-operation-picker-footer cqa-flex cqa-items-center cqa-pt-2 cqa-text-[12px] cqa-text-[#6B7280]\">\n <span>Click an operation to use it \u2014 the picker closes and the request is auto-filled.</span>\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Section template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #opSection let-ops let-label=\"label\" let-accent=\"accent\">\n <div *ngIf=\"ops?.length\" class=\"cqa-graphql-operation-picker-section cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-graphql-operation-picker-section-head cqa-flex cqa-items-center cqa-gap-2 cqa-bg-[#F9FAFB] cqa-px-3 cqa-py-1.5 cqa-rounded-md cqa-border cqa-border-solid cqa-border-[#F3F4F6]\">\n <span class=\"cqa-graphql-operation-picker-section-label cqa-text-[12px] cqa-font-semibold\" [ngClass]=\"accent\">{{ label }}</span>\n <span class=\"cqa-graphql-operation-picker-section-count cqa-text-[11px] cqa-text-[#6B7280]\">\n {{ ops.length }} {{ ops.length === 1 ? 'operation' : 'operations' }}\n </span>\n </div>\n <div *ngFor=\"let op of ops; trackBy: trackByOperation\"\n class=\"cqa-graphql-operation-picker-row cqa-flex cqa-items-start cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2.5 cqa-rounded-md cqa-cursor-pointer cqa-border cqa-border-solid cqa-border-transparent hover:cqa-bg-[#F9FAFB] hover:cqa-border-[#E5E7EB] focus-within:cqa-bg-[#F5F3FF]\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Use operation ' + op.name\"\n (click)=\"onSelect(op)\"\n (keydown.enter)=\"onSelect(op)\"\n (keydown.space)=\"onSelect(op); $event.preventDefault()\">\n <span class=\"cqa-graphql-operation-picker-row-radio cqa-mt-1 cqa-shrink-0\">\n <span class=\"cqa-inline-block cqa-w-4 cqa-h-4 cqa-rounded-full cqa-border cqa-border-solid cqa-border-[#9CA3AF] cqa-bg-white\" aria-hidden=\"true\"></span>\n </span>\n <div class=\"cqa-graphql-operation-picker-row-body cqa-flex cqa-flex-col cqa-gap-0.5 cqa-flex-1 cqa-min-w-0\">\n <div class=\"cqa-graphql-operation-picker-row-signature cqa-flex cqa-flex-wrap cqa-items-baseline cqa-gap-x-1 cqa-text-[13px] cqa-font-mono cqa-leading-[1.4] cqa-min-w-0\">\n <span class=\"cqa-text-[#111827] cqa-font-semibold\">{{ op.name }}</span>\n <span class=\"cqa-text-[#6B7280]\">(</span>\n <ng-container *ngFor=\"let arg of op.args ?? []; let last = last\">\n <span class=\"cqa-text-[#374151]\">{{ arg.name }}</span>\n <span class=\"cqa-text-[#6B7280]\">: </span>\n <span [ngClass]=\"returnTypeColorClass(op.kind)\">{{ arg.type }}</span>\n <span *ngIf=\"!last\" class=\"cqa-text-[#6B7280]\">, </span>\n </ng-container>\n <span class=\"cqa-text-[#6B7280]\">)</span>\n \n </div>\n <div *ngIf=\"op.description\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-graphql-operation-picker-row-description cqa-text-[12px] cqa-text-[#6B7280] cqa-leading-[1.5]\">\n <span>{{ op.description }}</span>\n <mat-icon *ngIf=\"op.returnType\" style=\"display:flex;font-size:14px;font-weight: 600;\" class=\"cqa-flex cqa-items-center cqa-justify-center cqa-text-[#6B7280] cqa-mx-1\">arrow_forward</mat-icon>\n <span *ngIf=\"op.returnType\" [ngClass]=\"returnTypeColorClass(op.kind)\" class=\"cqa-font-semibold\">{{ op.returnType }}</span>\n </div>\n </div>\n <!-- <button type=\"button\"\n class=\"cqa-graphql-operation-picker-row-preview cqa-shrink-0 cqa-inline-flex cqa-items-center cqa-gap-1 cqa-bg-transparent cqa-border-0 cqa-cursor-pointer cqa-text-[#4F46E5] cqa-text-[12px] cqa-font-medium hover:cqa-underline focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#A5B4FC] cqa-rounded-md cqa-px-2 cqa-py-1\"\n [attr.aria-label]=\"'Preview operation ' + op.name\"\n (click)=\"onPreview(op, $event)\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n <span>Preview</span>\n </button> -->\n </div>\n </div>\n </ng-template>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i3.CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
99
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: GraphQLOperationPickerComponent, decorators: [{
|
|
100
|
+
type: Component,
|
|
101
|
+
args: [{ selector: 'cqa-graphql-operation-picker', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.Default, template: "<div class=\"cqa-graphql-operation-picker cqa-flex cqa-flex-col cqa-gap-4 cqa-bg-white cqa-w-full\">\n\n <!-- Title row: back arrow + heading + Introspected badge -->\n <div class=\"cqa-graphql-operation-picker-header cqa-flex cqa-items-center cqa-gap-3\">\n <div class=\"cqa-cursor-pointer cqa-text-[#6B7280] cqa-text-[14px] cqa-font-semibold\" (click)=\"onBack()\">\n <mat-icon class=\"cqa-flex cqa-items-center cqa-justify-center cqa-text-[18px] cqa-text-[#6B7280] cqa-font-semibold\" style=\"display:flex;font-size:18px;font-weight: 600;\">arrow_back</mat-icon>\n </div>\n <h3 class=\"cqa-graphql-operation-picker-title cqa-m-0 cqa-text-[18px] cqa-font-semibold cqa-text-[#111827] cqa-leading-[1.25]\">\n Pick a GraphQL operation\n </h3>\n <span *ngIf=\"introspected\"\n class=\"cqa-graphql-operation-picker-badge cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-[2px] cqa-rounded-full cqa-bg-[#EDE9FE] cqa-text-[#7C3AED] cqa-text-[11px] cqa-font-medium cqa-leading-[1.4]\">\n <span aria-hidden=\"true\">\u25C6</span> Introspected\n </span>\n </div>\n\n <!-- Subheading -->\n <p class=\"cqa-graphql-operation-picker-subheading cqa-m-0 cqa-text-[12px] cqa-text-[#6B7280] cqa-leading-[1.5]\">\n Phase 1 supports one operation per test step. Select one to auto-fill the request.\n </p>\n\n <!-- Schema source bar: URL + counts + Re-introspect / Change buttons -->\n <div class=\"cqa-graphql-operation-picker-source cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-bg-[#EEF2FF] cqa-rounded-lg cqa-px-4 cqa-py-3 cqa-border cqa-border-solid cqa-border-[#E0E7FF]\">\n <div class=\"cqa-graphql-operation-picker-source-info cqa-flex cqa-flex-col cqa-gap-0.5 cqa-min-w-0\">\n <div class=\"cqa-graphql-operation-picker-source-label cqa-text-[10px] cqa-uppercase cqa-tracking-wide cqa-text-[#6B7280] cqa-font-semibold\">\n Schema source\n </div>\n <div *ngIf=\"schemaSource?.url\"\n class=\"cqa-graphql-operation-picker-source-url cqa-text-[13px] cqa-font-mono cqa-text-[#1F2937] cqa-truncate cqa-min-w-0\"\n [title]=\"schemaSource?.url\">\n {{ schemaSource?.url }}\n </div>\n <div *ngIf=\"!schemaSource?.url\"\n class=\"cqa-graphql-operation-picker-source-url cqa-text-[13px] cqa-italic cqa-text-[#6B7280]\">\n No schema loaded yet.\n </div>\n </div>\n <div class=\"cqa-graphql-operation-picker-source-meta cqa-flex cqa-items-center cqa-gap-3 cqa-shrink-0\">\n <span *ngIf=\"headerCounts\" class=\"cqa-graphql-operation-picker-source-counts cqa-text-[12px] cqa-text-[#4B5563]\">\n {{ headerCounts }}\n </span>\n <cqa-button type=\"button\" variant=\"outlined\" [icon]=\"'refresh'\" btnSize=\"md\" text=\"Re-introspect\"\n customClass=\"!cqa-bg-white !cqa-text-[#374151] !cqa-border !cqa-border-solid !cqa-border-[#D1D5DB] cqa-text-[12px] cqa-font-medium hover:!cqa-bg-[#F9FAFB]\"\n (clicked)=\"onReIntrospect()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"text\" btnSize=\"md\" text=\"Change\"\n customClass=\"!cqa-text-[#4F46E5] cqa-text-[12px] cqa-font-medium hover:!cqa-bg-[#EEF2FF]\"\n (clicked)=\"onChange()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Filter -->\n <cqa-custom-input\n [(value)]=\"filterTerm\"\n [label]=\"''\"\n placeholder=\"Filter operations...\"\n [fullWidth]=\"true\"\n size=\"md\"\n ariaLabel=\"Filter GraphQL operations\">\n </cqa-custom-input>\n\n <!-- Loading spinner shown while the parent is introspecting. Replaces the empty state. -->\n <div *ngIf=\"isLoading\"\n class=\"cqa-graphql-operation-picker-loading cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-12 cqa-text-center cqa-bg-[#F9FAFB] cqa-rounded-md cqa-border cqa-border-dashed cqa-border-[#E5E7EB]\">\n <span class=\"cqa-graphql-operation-picker-spinner cqa-inline-block cqa-w-7 cqa-h-7 cqa-rounded-full cqa-border-2 cqa-border-solid cqa-border-[#E5E7EB] cqa-border-t-[#4F46E5] cqa-animate-spin\" aria-hidden=\"true\"></span>\n <span class=\"cqa-text-[13px] cqa-font-medium cqa-text-[#374151]\">Loading schema\u2026</span>\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Introspecting GraphQL endpoint, this may take a moment.</span>\n </div>\n\n <!-- Empty state when no operations are loaded yet (or filter rules everything out). -->\n <div *ngIf=\"!isLoading && !filteredOperations.length\"\n class=\"cqa-graphql-operation-picker-empty cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-2 cqa-py-10 cqa-text-center cqa-bg-[#F9FAFB] cqa-rounded-md cqa-border cqa-border-dashed cqa-border-[#E5E7EB]\">\n <span class=\"cqa-text-[13px] cqa-font-medium cqa-text-[#374151]\">\n {{ filterTerm ? 'No operations match your filter.' : 'No operations available.' }}\n </span>\n <span *ngIf=\"!filterTerm\" class=\"cqa-text-[12px] cqa-text-[#6B7280]\">\n Click <strong>Re-introspect</strong> above to load the schema.\n </span>\n </div>\n\n <!-- Operation sections (Queries / Mutations / Subscriptions) -->\n <ng-container *ngIf=\"!isLoading && filteredOperations.length\">\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: queryOperations, label: 'Queries', accent: 'cqa-text-[#059669]' }\"></ng-container>\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: mutationOperations, label: 'Mutations', accent: 'cqa-text-[#D97706]' }\"></ng-container>\n <ng-container *ngTemplateOutlet=\"opSection; context: { $implicit: subscriptionOperations, label: 'Subscriptions', accent: 'cqa-text-[#7C3AED]' }\"></ng-container>\n </ng-container>\n\n <!-- Footer: selection summary. No Back / Use buttons \u2014 clicking a row commits + returns. -->\n <div *ngIf=\"!isLoading && filteredOperations.length\" class=\"cqa-graphql-operation-picker-footer cqa-flex cqa-items-center cqa-pt-2 cqa-text-[12px] cqa-text-[#6B7280]\">\n <span>Click an operation to use it \u2014 the picker closes and the request is auto-filled.</span>\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Section template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <ng-template #opSection let-ops let-label=\"label\" let-accent=\"accent\">\n <div *ngIf=\"ops?.length\" class=\"cqa-graphql-operation-picker-section cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-graphql-operation-picker-section-head cqa-flex cqa-items-center cqa-gap-2 cqa-bg-[#F9FAFB] cqa-px-3 cqa-py-1.5 cqa-rounded-md cqa-border cqa-border-solid cqa-border-[#F3F4F6]\">\n <span class=\"cqa-graphql-operation-picker-section-label cqa-text-[12px] cqa-font-semibold\" [ngClass]=\"accent\">{{ label }}</span>\n <span class=\"cqa-graphql-operation-picker-section-count cqa-text-[11px] cqa-text-[#6B7280]\">\n {{ ops.length }} {{ ops.length === 1 ? 'operation' : 'operations' }}\n </span>\n </div>\n <div *ngFor=\"let op of ops; trackBy: trackByOperation\"\n class=\"cqa-graphql-operation-picker-row cqa-flex cqa-items-start cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2.5 cqa-rounded-md cqa-cursor-pointer cqa-border cqa-border-solid cqa-border-transparent hover:cqa-bg-[#F9FAFB] hover:cqa-border-[#E5E7EB] focus-within:cqa-bg-[#F5F3FF]\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Use operation ' + op.name\"\n (click)=\"onSelect(op)\"\n (keydown.enter)=\"onSelect(op)\"\n (keydown.space)=\"onSelect(op); $event.preventDefault()\">\n <span class=\"cqa-graphql-operation-picker-row-radio cqa-mt-1 cqa-shrink-0\">\n <span class=\"cqa-inline-block cqa-w-4 cqa-h-4 cqa-rounded-full cqa-border cqa-border-solid cqa-border-[#9CA3AF] cqa-bg-white\" aria-hidden=\"true\"></span>\n </span>\n <div class=\"cqa-graphql-operation-picker-row-body cqa-flex cqa-flex-col cqa-gap-0.5 cqa-flex-1 cqa-min-w-0\">\n <div class=\"cqa-graphql-operation-picker-row-signature cqa-flex cqa-flex-wrap cqa-items-baseline cqa-gap-x-1 cqa-text-[13px] cqa-font-mono cqa-leading-[1.4] cqa-min-w-0\">\n <span class=\"cqa-text-[#111827] cqa-font-semibold\">{{ op.name }}</span>\n <span class=\"cqa-text-[#6B7280]\">(</span>\n <ng-container *ngFor=\"let arg of op.args ?? []; let last = last\">\n <span class=\"cqa-text-[#374151]\">{{ arg.name }}</span>\n <span class=\"cqa-text-[#6B7280]\">: </span>\n <span [ngClass]=\"returnTypeColorClass(op.kind)\">{{ arg.type }}</span>\n <span *ngIf=\"!last\" class=\"cqa-text-[#6B7280]\">, </span>\n </ng-container>\n <span class=\"cqa-text-[#6B7280]\">)</span>\n \n </div>\n <div *ngIf=\"op.description\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-graphql-operation-picker-row-description cqa-text-[12px] cqa-text-[#6B7280] cqa-leading-[1.5]\">\n <span>{{ op.description }}</span>\n <mat-icon *ngIf=\"op.returnType\" style=\"display:flex;font-size:14px;font-weight: 600;\" class=\"cqa-flex cqa-items-center cqa-justify-center cqa-text-[#6B7280] cqa-mx-1\">arrow_forward</mat-icon>\n <span *ngIf=\"op.returnType\" [ngClass]=\"returnTypeColorClass(op.kind)\" class=\"cqa-font-semibold\">{{ op.returnType }}</span>\n </div>\n </div>\n <!-- <button type=\"button\"\n class=\"cqa-graphql-operation-picker-row-preview cqa-shrink-0 cqa-inline-flex cqa-items-center cqa-gap-1 cqa-bg-transparent cqa-border-0 cqa-cursor-pointer cqa-text-[#4F46E5] cqa-text-[12px] cqa-font-medium hover:cqa-underline focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#A5B4FC] cqa-rounded-md cqa-px-2 cqa-py-1\"\n [attr.aria-label]=\"'Preview operation ' + op.name\"\n (click)=\"onPreview(op, $event)\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n <span>Preview</span>\n </button> -->\n </div>\n </div>\n </ng-template>\n</div>\n" }]
|
|
102
|
+
}], propDecorators: { schemaSource: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], operations: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], introspected: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], isLoading: [{
|
|
109
|
+
type: Input
|
|
110
|
+
}], back: [{
|
|
111
|
+
type: Output
|
|
112
|
+
}], operationSelected: [{
|
|
113
|
+
type: Output
|
|
114
|
+
}], reIntrospect: [{
|
|
115
|
+
type: Output
|
|
116
|
+
}], change: [{
|
|
117
|
+
type: Output
|
|
118
|
+
}], preview: [{
|
|
119
|
+
type: Output
|
|
120
|
+
}] } });
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvYXBpLWVkaXQtc3RlcC9ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXIvZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvYXBpLWVkaXQtc3RlcC9ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXIvZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7OztBQWdEaEcsTUFBTSxPQUFPLCtCQUErQjtJQU41QztRQVNFLGlGQUFpRjtRQUN4RSxlQUFVLEdBQTZCLEVBQUUsQ0FBQztRQUNuRCwrRUFBK0U7UUFDdEUsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDOUIsOEdBQThHO1FBQ3JHLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFM0IscUdBQXFHO1FBQzNGLFNBQUksR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzFDLHFHQUFxRztRQUMzRixzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBMEIsQ0FBQztRQUN6RSxpRkFBaUY7UUFDdkUsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBbUMsQ0FBQztRQUM3RSwrRkFBK0Y7UUFDckYsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDNUMsaUdBQWlHO1FBQ3ZGLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBMEIsQ0FBQztRQUUvRCx3RkFBd0Y7UUFDeEYsZUFBVSxHQUFHLEVBQUUsQ0FBQztLQTZFakI7SUEz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O3NCQUFwQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdJLElBQUk7c0JBQWIsTUFBTTtnQkFFRyxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBRUcsWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxNQUFNO3NCQUFmLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqIFdoZXJlIHRoZSBvcGVyYXRpb25zIGxpc3QgY2FtZSBmcm9tLiBUaGUgaGVhZGVyIGJhciByZW5kZXJzIHRoZSBVUkwgcGx1c1xuICogdHlwZSAvIHF1ZXJ5IC8gbXV0YXRpb24gY291bnRzIHNvIHRoZSB1c2VyIGNhbiBzYW5pdHktY2hlY2sgdGhlIHNjaGVtYVxuICogc291cmNlIGJlZm9yZSBwaWNraW5nIGFuIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcmFwaFFMU2NoZW1hU291cmNlIHtcbiAgdXJsOiBzdHJpbmc7XG4gIHR5cGVDb3VudD86IG51bWJlcjtcbiAgcXVlcnlDb3VudD86IG51bWJlcjtcbiAgbXV0YXRpb25Db3VudD86IG51bWJlcjtcbiAgc3Vic2NyaXB0aW9uQ291bnQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogT25lIHJvdyBpbiB0aGUgcGlja2VyLiBUaGUgcGFyZW50IChhcGktZWRpdC1zdGVwKSBidWlsZHMgdGhpcyBsaXN0IGZyb21cbiAqIHRoZSBpbnRyb3NwZWN0ZWQgc2NoZW1hIGFuZCBwYXNzZXMgaXQgdmlhIGBbb3BlcmF0aW9uc11gLiBPbiBzZWxlY3QsIHRoZVxuICogcGlja2VyIGVtaXRzIHRoZSB3aG9sZSBvcHRpb24gb2JqZWN0IHNvIHRoZSBjYWxsZXIgY2FuIHBhdGNoIHRoZSBHcmFwaFFMXG4gKiBlZGl0b3Igd2l0aCBgcXVlcnlgLCBgdmFyaWFibGVzYCwgYW5kIGBvcGVyYXRpb25OYW1lYCBpbiBvbmUgc2hvdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcmFwaFFMT3BlcmF0aW9uT3B0aW9uIHtcbiAgLyoqIFN0YWJsZSBpZGVudGlmaWVyIHVzZWQgYXMgKm5nRm9yIHRyYWNrQnkgYW5kIHRoZSByYWRpbydzIFt2YWx1ZV0uIFR5cGljYWxseSB0aGUgb3BlcmF0aW9uIG5hbWUuICovXG4gIGlkOiBzdHJpbmc7XG4gIC8qKiBEaXNwbGF5IG5hbWUgKGUuZy4gJ2dldEJvb2tpbmcnKS4gKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogU2VjdGlvbiBncm91cGluZyArIGNvbG91ci1jb2Rpbmcgb2YgdGhlIHJldHVybiB0eXBlIHBpbGwuICovXG4gIGtpbmQ6ICdxdWVyeScgfCAnbXV0YXRpb24nIHwgJ3N1YnNjcmlwdGlvbic7XG4gIC8qKiBJbmxpbmUgYXJndW1lbnQgbGlzdCwgZS5nLiBgW3sgbmFtZTogJ2lkJywgdHlwZTogJ0lEIScgfV1gLiBVc2VkIGZvciB0aGUgc2lnbmF0dXJlIGxpbmUuICovXG4gIGFyZ3M/OiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdHlwZTogc3RyaW5nIH0+O1xuICAvKiogUmV0dXJuIHR5cGUgZGlzcGxheWVkIGFmdGVyIHRoZSBhcnJvdy4gQ29sb3VyZWQgYnkgYGtpbmRgLiAqL1xuICByZXR1cm5UeXBlPzogc3RyaW5nO1xuICAvKiogT3B0aW9uYWwgaHVtYW4gZGVzY3JpcHRpb24gcmVuZGVyZWQgYmVsb3cgdGhlIHNpZ25hdHVyZSBsaW5lLiAqL1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqIFByZS1idWlsdCBvcGVyYXRpb24gdGV4dCB0aGUgcGFyZW50IGRyb3BzIGludG8gdGhlIEdyYXBoUUwgUXVlcnkgZWRpdG9yLiAqL1xuICBxdWVyeTogc3RyaW5nO1xuICAvKiogSW5pdGlhbCB2YXJpYWJsZXM7IHBhcmVudCBKU09OLXN0cmluZ2lmaWVzIGludG8gdGhlIFZhcmlhYmxlcyBlZGl0b3IuICovXG4gIHZhcmlhYmxlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAvKiogT3BlcmF0aW9uIG5hbWUgd3JpdHRlbiBpbnRvIHRoZSBPcGVyYXRpb24gTmFtZSBmaWVsZCAodHlwaWNhbGx5IHNhbWUgYXMgYG5hbWVgKS4gKi9cbiAgb3BlcmF0aW9uTmFtZTogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dyYXBocWwtb3BlcmF0aW9uLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5EZWZhdWx0LFxufSlcbmV4cG9ydCBjbGFzcyBHcmFwaFFMT3BlcmF0aW9uUGlja2VyQ29tcG9uZW50IHtcbiAgLyoqIFNjaGVtYSBzb3VyY2UgZGVzY3JpcHRvciAoVVJMICsgY291bnRzKS4gV2hlbiBvbWl0dGVkIHRoZSBoZWFkZXIgc2hvd3MgYW4gZW1wdHkgcGxhY2Vob2xkZXIuICovXG4gIEBJbnB1dCgpIHNjaGVtYVNvdXJjZT86IEdyYXBoUUxTY2hlbWFTb3VyY2U7XG4gIC8qKiBGbGF0IG9wZXJhdGlvbnMgbGlzdC4gUGlja2VyIHBhcnRpdGlvbnMgYnkgYGtpbmRgIGZvciB0aGUgc2VjdGlvbiBoZWFkZXJzLiAqL1xuICBASW5wdXQoKSBvcGVyYXRpb25zOiBHcmFwaFFMT3BlcmF0aW9uT3B0aW9uW10gPSBbXTtcbiAgLyoqIERpc3BsYXkgc3RhdGUgZm9yIHRoZSBcIkludHJvc3BlY3RlZFwiIC8gXCJQZW5kaW5nXCIgYmFkZ2UgaW4gdGhlIHRpdGxlIHJvdy4gKi9cbiAgQElucHV0KCkgaW50cm9zcGVjdGVkID0gZmFsc2U7XG4gIC8qKiBUcnVlIHdoaWxlIHRoZSBwYXJlbnQgaXMgZmV0Y2hpbmcvaW50cm9zcGVjdGluZyBhIHNjaGVtYS4gUmVuZGVycyBhIHNwaW5uZXIgaW5zdGVhZCBvZiB0aGUgZW1wdHkgc3RhdGUuICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZyA9IGZhbHNlO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIHRoZSBiYWNrIGFycm93IGFib3ZlIHRoZSB0aXRsZSAocmV0dXJucyB0byB0aGUgbWFpbiBzdGVwIDEgdmlldykuICovXG4gIEBPdXRwdXQoKSBiYWNrID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyBhbiBvcGVyYXRpb24gcm93LiBQYXJlbnQgcGF0Y2hlcyBncmFwaFFMRm9ybSBhbmQgcG9wcyB0aGUgcGlja2VyLiAqL1xuICBAT3V0cHV0KCkgb3BlcmF0aW9uU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEdyYXBoUUxPcGVyYXRpb25PcHRpb24+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIFJlLWludHJvc3BlY3Qg4oCUIHBhcmVudCByZS1mZXRjaGVzIHRoZSBzY2hlbWEuICovXG4gIEBPdXRwdXQoKSByZUludHJvc3BlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPEdyYXBoUUxTY2hlbWFTb3VyY2UgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIENoYW5nZSDigJQgcGFyZW50IHNob3dzIGEgVVJML2F1dGggcGlja2VyIChkZWZlcnJlZCBmb3Igbm93KS4gKi9cbiAgQE91dHB1dCgpIGNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEVtaXR0ZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgUHJldmlldyBvbiBhIHJvdyDigJQgcGFyZW50IHNob3dzIGEgcHJldmlldyBwb3BvdmVyIChkZWZlcnJlZCkuICovXG4gIEBPdXRwdXQoKSBwcmV2aWV3ID0gbmV3IEV2ZW50RW1pdHRlcjxHcmFwaFFMT3BlcmF0aW9uT3B0aW9uPigpO1xuXG4gIC8qKiBGaWx0ZXIgaW5wdXQgdmFsdWUuIFBsYWluIHN1YnN0cmluZyBtYXRjaCBhY3Jvc3MgbmFtZSAvIGRlc2NyaXB0aW9uIC8gcmV0dXJuVHlwZS4gKi9cbiAgZmlsdGVyVGVybSA9ICcnO1xuXG4gIC8qKiBPcGVyYXRpb25zIGN1cnJlbnRseSBzaG93biBhZnRlciBhcHBseWluZyBgZmlsdGVyVGVybWAuICovXG4gIGdldCBmaWx0ZXJlZE9wZXJhdGlvbnMoKTogR3JhcGhRTE9wZXJhdGlvbk9wdGlvbltdIHtcbiAgICBjb25zdCB0ZXJtID0gdGhpcy5maWx0ZXJUZXJtLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghdGVybSkgcmV0dXJuIHRoaXMub3BlcmF0aW9ucyB8fCBbXTtcbiAgICByZXR1cm4gKHRoaXMub3BlcmF0aW9ucyB8fCBbXSkuZmlsdGVyKChvKSA9PlxuICAgICAgby5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSkgfHxcbiAgICAgIChvLmRlc2NyaXB0aW9uID8/ICcnKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pIHx8XG4gICAgICAoby5yZXR1cm5UeXBlID8/ICcnKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pLFxuICAgICk7XG4gIH1cblxuICBnZXQgcXVlcnlPcGVyYXRpb25zKCk6IEdyYXBoUUxPcGVyYXRpb25PcHRpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyZWRPcGVyYXRpb25zLmZpbHRlcigobykgPT4gby5raW5kID09PSAncXVlcnknKTtcbiAgfVxuICBnZXQgbXV0YXRpb25PcGVyYXRpb25zKCk6IEdyYXBoUUxPcGVyYXRpb25PcHRpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyZWRPcGVyYXRpb25zLmZpbHRlcigobykgPT4gby5raW5kID09PSAnbXV0YXRpb24nKTtcbiAgfVxuICBnZXQgc3Vic2NyaXB0aW9uT3BlcmF0aW9ucygpOiBHcmFwaFFMT3BlcmF0aW9uT3B0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLmZpbHRlcmVkT3BlcmF0aW9ucy5maWx0ZXIoKG8pID0+IG8ua2luZCA9PT0gJ3N1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqIENvbnZlbmllbmNlOiB0b3RhbCBzY2hlbWEtc291cmNlIGNvdW50IGxpbmUsIGUuZy4gXCIzOCB0eXBlcyDCtyA0IHF1ZXJpZXMgwrcgMyBtdXRhdGlvbnNcIi4gKi9cbiAgZ2V0IGhlYWRlckNvdW50cygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHMgPSB0aGlzLnNjaGVtYVNvdXJjZTtcbiAgICBpZiAoIXMpIHJldHVybiAnJztcbiAgICBpZiAocy50eXBlQ291bnQgIT0gbnVsbCkgcGFydHMucHVzaChgJHtzLnR5cGVDb3VudH0gdHlwZXNgKTtcbiAgICBpZiAocy5xdWVyeUNvdW50ICE9IG51bGwpIHBhcnRzLnB1c2goYCR7cy5xdWVyeUNvdW50fSAke3MucXVlcnlDb3VudCA9PT0gMSA/ICdxdWVyeScgOiAncXVlcmllcyd9YCk7XG4gICAgaWYgKHMubXV0YXRpb25Db3VudCAhPSBudWxsKSBwYXJ0cy5wdXNoKGAke3MubXV0YXRpb25Db3VudH0gJHtzLm11dGF0aW9uQ291bnQgPT09IDEgPyAnbXV0YXRpb24nIDogJ211dGF0aW9ucyd9YCk7XG4gICAgaWYgKHMuc3Vic2NyaXB0aW9uQ291bnQgIT0gbnVsbCAmJiBzLnN1YnNjcmlwdGlvbkNvdW50ID4gMCkge1xuICAgICAgcGFydHMucHVzaChgJHtzLnN1YnNjcmlwdGlvbkNvdW50fSAke3Muc3Vic2NyaXB0aW9uQ291bnQgPT09IDEgPyAnc3Vic2NyaXB0aW9uJyA6ICdzdWJzY3JpcHRpb25zJ31gKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oJyDCtyAnKTtcbiAgfVxuXG4gIG9uQmFjaygpOiB2b2lkIHtcbiAgICB0aGlzLmJhY2suZW1pdCgpO1xuICB9XG5cbiAgb25TZWxlY3Qob3A6IEdyYXBoUUxPcGVyYXRpb25PcHRpb24pOiB2b2lkIHtcbiAgICB0aGlzLm9wZXJhdGlvblNlbGVjdGVkLmVtaXQob3ApO1xuICB9XG5cbiAgb25QcmV2aWV3KG9wOiBHcmFwaFFMT3BlcmF0aW9uT3B0aW9uLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBTdG9wIHRoZSBjbGljayBmcm9tIGFsc28gYnViYmxpbmcgdG8gdGhlIHJvdydzIHNlbGVjdCBoYW5kbGVyIOKAlCBQcmV2aWV3IGlzIGEgcGVlayxcbiAgICAvLyBub3QgYSBjb21taXQuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5wcmV2aWV3LmVtaXQob3ApO1xuICB9XG5cbiAgb25SZUludHJvc3BlY3QoKTogdm9pZCB7XG4gICAgdGhpcy5yZUludHJvc3BlY3QuZW1pdCh0aGlzLnNjaGVtYVNvdXJjZSk7XG4gIH1cblxuICBvbkNoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYW5nZS5lbWl0KCk7XG4gIH1cblxuICBvbkZpbHRlckNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXJUZXJtID0gdmFsdWUgPz8gJyc7XG4gIH1cblxuICB0cmFja0J5T3BlcmF0aW9uKF9pbmRleDogbnVtYmVyLCBvcDogR3JhcGhRTE9wZXJhdGlvbk9wdGlvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9wLmlkO1xuICB9XG5cbiAgLyoqIFRhaWx3aW5kIHRleHQgY29sb3VyIGZvciB0aGUgcmV0dXJuLXR5cGUgcGlsbCwga2V5ZWQgYnkgb3BlcmF0aW9uIGtpbmQuICovXG4gIHJldHVyblR5cGVDb2xvckNsYXNzKGtpbmQ6IEdyYXBoUUxPcGVyYXRpb25PcHRpb25bJ2tpbmQnXSk6IHN0cmluZyB7XG4gICAgc3dpdGNoIChraW5kKSB7XG4gICAgICBjYXNlICdtdXRhdGlvbic6ICAgICAgcmV0dXJuICdjcWEtdGV4dC1bI0Q5NzcwNl0nOyAvLyBhbWJlci02MDBcbiAgICAgIGNhc2UgJ3N1YnNjcmlwdGlvbic6ICByZXR1cm4gJ2NxYS10ZXh0LVsjN0MzQUVEXSc7IC8vIHZpb2xldC02MDBcbiAgICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICByZXR1cm4gJ2NxYS10ZXh0LVsjMDU5NjY5XSc7IC8vIGVtZXJhbGQtNjAwXG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlciBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC00IGNxYS1iZy13aGl0ZSBjcWEtdy1mdWxsXCI+XG5cbiAgPCEtLSBUaXRsZSByb3c6IGJhY2sgYXJyb3cgKyBoZWFkaW5nICsgSW50cm9zcGVjdGVkIGJhZGdlIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1oZWFkZXIgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWN1cnNvci1wb2ludGVyIGNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtdGV4dC1bMTRweF0gY3FhLWZvbnQtc2VtaWJvbGRcIiAoY2xpY2spPVwib25CYWNrKClcIj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS10ZXh0LVsxOHB4XSBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLWZvbnQtc2VtaWJvbGRcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDtmb250LXNpemU6MThweDtmb250LXdlaWdodDogNjAwO1wiPmFycm93X2JhY2s8L21hdC1pY29uPlxuICAgIDwvZGl2PlxuICAgIDxoMyBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItdGl0bGUgY3FhLW0tMCBjcWEtdGV4dC1bMThweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtWyMxMTE4MjddIGNxYS1sZWFkaW5nLVsxLjI1XVwiPlxuICAgICAgUGljayBhIEdyYXBoUUwgb3BlcmF0aW9uXG4gICAgPC9oMz5cbiAgICA8c3BhbiAqbmdJZj1cImludHJvc3BlY3RlZFwiXG4gICAgICBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItYmFkZ2UgY3FhLWlubGluZS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xIGNxYS1weC0yIGNxYS1weS1bMnB4XSBjcWEtcm91bmRlZC1mdWxsIGNxYS1iZy1bI0VERTlGRV0gY3FhLXRleHQtWyM3QzNBRURdIGNxYS10ZXh0LVsxMXB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLWxlYWRpbmctWzEuNF1cIj5cbiAgICAgIDxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKXhjwvc3Bhbj4gSW50cm9zcGVjdGVkXG4gICAgPC9zcGFuPlxuICA8L2Rpdj5cblxuICA8IS0tIFN1YmhlYWRpbmcgLS0+XG4gIDxwIGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1zdWJoZWFkaW5nIGNxYS1tLTAgY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtbGVhZGluZy1bMS41XVwiPlxuICAgIFBoYXNlIDEgc3VwcG9ydHMgb25lIG9wZXJhdGlvbiBwZXIgdGVzdCBzdGVwLiBTZWxlY3Qgb25lIHRvIGF1dG8tZmlsbCB0aGUgcmVxdWVzdC5cbiAgPC9wPlxuXG4gIDwhLS0gU2NoZW1hIHNvdXJjZSBiYXI6IFVSTCArIGNvdW50cyArIFJlLWludHJvc3BlY3QgLyBDaGFuZ2UgYnV0dG9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItc291cmNlIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktYmV0d2VlbiBjcWEtZ2FwLTMgY3FhLWJnLVsjRUVGMkZGXSBjcWEtcm91bmRlZC1sZyBjcWEtcHgtNCBjcWEtcHktMyBjcWEtYm9yZGVyIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci1bI0UwRTdGRl1cIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1zb3VyY2UtaW5mbyBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0wLjUgY3FhLW1pbi13LTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLXNvdXJjZS1sYWJlbCBjcWEtdGV4dC1bMTBweF0gY3FhLXVwcGVyY2FzZSBjcWEtdHJhY2tpbmctd2lkZSBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLWZvbnQtc2VtaWJvbGRcIj5cbiAgICAgICAgU2NoZW1hIHNvdXJjZVxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2NoZW1hU291cmNlPy51cmxcIlxuICAgICAgICBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItc291cmNlLXVybCBjcWEtdGV4dC1bMTNweF0gY3FhLWZvbnQtbW9ubyBjcWEtdGV4dC1bIzFGMjkzN10gY3FhLXRydW5jYXRlIGNxYS1taW4tdy0wXCJcbiAgICAgICAgW3RpdGxlXT1cInNjaGVtYVNvdXJjZT8udXJsXCI+XG4gICAgICAgIHt7IHNjaGVtYVNvdXJjZT8udXJsIH19XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhc2NoZW1hU291cmNlPy51cmxcIlxuICAgICAgICBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItc291cmNlLXVybCBjcWEtdGV4dC1bMTNweF0gY3FhLWl0YWxpYyBjcWEtdGV4dC1bIzZCNzI4MF1cIj5cbiAgICAgICAgTm8gc2NoZW1hIGxvYWRlZCB5ZXQuXG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1zb3VyY2UtbWV0YSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtc2hyaW5rLTBcIj5cbiAgICAgIDxzcGFuICpuZ0lmPVwiaGVhZGVyQ291bnRzXCIgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLXNvdXJjZS1jb3VudHMgY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjNEI1NTYzXVwiPlxuICAgICAgICB7eyBoZWFkZXJDb3VudHMgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxjcWEtYnV0dG9uIHR5cGU9XCJidXR0b25cIiB2YXJpYW50PVwib3V0bGluZWRcIiBbaWNvbl09XCIncmVmcmVzaCdcIiBidG5TaXplPVwibWRcIiB0ZXh0PVwiUmUtaW50cm9zcGVjdFwiXG4gICAgICAgIGN1c3RvbUNsYXNzPVwiIWNxYS1iZy13aGl0ZSAhY3FhLXRleHQtWyMzNzQxNTFdICFjcWEtYm9yZGVyICFjcWEtYm9yZGVyLXNvbGlkICFjcWEtYm9yZGVyLVsjRDFENURCXSBjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGhvdmVyOiFjcWEtYmctWyNGOUZBRkJdXCJcbiAgICAgICAgKGNsaWNrZWQpPVwib25SZUludHJvc3BlY3QoKVwiPlxuICAgICAgPC9jcWEtYnV0dG9uPlxuICAgICAgPGNxYS1idXR0b24gdHlwZT1cImJ1dHRvblwiIHZhcmlhbnQ9XCJ0ZXh0XCIgYnRuU2l6ZT1cIm1kXCIgdGV4dD1cIkNoYW5nZVwiXG4gICAgICAgIGN1c3RvbUNsYXNzPVwiIWNxYS10ZXh0LVsjNEY0NkU1XSBjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGhvdmVyOiFjcWEtYmctWyNFRUYyRkZdXCJcbiAgICAgICAgKGNsaWNrZWQpPVwib25DaGFuZ2UoKVwiPlxuICAgICAgPC9jcWEtYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIEZpbHRlciAtLT5cbiAgPGNxYS1jdXN0b20taW5wdXRcbiAgICBbKHZhbHVlKV09XCJmaWx0ZXJUZXJtXCJcbiAgICBbbGFiZWxdPVwiJydcIlxuICAgIHBsYWNlaG9sZGVyPVwiRmlsdGVyIG9wZXJhdGlvbnMuLi5cIlxuICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgc2l6ZT1cIm1kXCJcbiAgICBhcmlhTGFiZWw9XCJGaWx0ZXIgR3JhcGhRTCBvcGVyYXRpb25zXCI+XG4gIDwvY3FhLWN1c3RvbS1pbnB1dD5cblxuICA8IS0tIExvYWRpbmcgc3Bpbm5lciBzaG93biB3aGlsZSB0aGUgcGFyZW50IGlzIGludHJvc3BlY3RpbmcuIFJlcGxhY2VzIHRoZSBlbXB0eSBzdGF0ZS4gLS0+XG4gIDxkaXYgKm5nSWY9XCJpc0xvYWRpbmdcIlxuICAgIGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1sb2FkaW5nIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtZ2FwLTMgY3FhLXB5LTEyIGNxYS10ZXh0LWNlbnRlciBjcWEtYmctWyNGOUZBRkJdIGNxYS1yb3VuZGVkLW1kIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1kYXNoZWQgY3FhLWJvcmRlci1bI0U1RTdFQl1cIj5cbiAgICA8c3BhbiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItc3Bpbm5lciBjcWEtaW5saW5lLWJsb2NrIGNxYS13LTcgY3FhLWgtNyBjcWEtcm91bmRlZC1mdWxsIGNxYS1ib3JkZXItMiBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNFNUU3RUJdIGNxYS1ib3JkZXItdC1bIzRGNDZFNV0gY3FhLWFuaW1hdGUtc3BpblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsxM3B4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+TG9hZGluZyBzY2hlbWHigKY8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLXRleHQtWyM2QjcyODBdXCI+SW50cm9zcGVjdGluZyBHcmFwaFFMIGVuZHBvaW50LCB0aGlzIG1heSB0YWtlIGEgbW9tZW50Ljwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBFbXB0eSBzdGF0ZSB3aGVuIG5vIG9wZXJhdGlvbnMgYXJlIGxvYWRlZCB5ZXQgKG9yIGZpbHRlciBydWxlcyBldmVyeXRoaW5nIG91dCkuIC0tPlxuICA8ZGl2ICpuZ0lmPVwiIWlzTG9hZGluZyAmJiAhZmlsdGVyZWRPcGVyYXRpb25zLmxlbmd0aFwiXG4gICAgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLWVtcHR5IGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtZ2FwLTIgY3FhLXB5LTEwIGNxYS10ZXh0LWNlbnRlciBjcWEtYmctWyNGOUZBRkJdIGNxYS1yb3VuZGVkLW1kIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1kYXNoZWQgY3FhLWJvcmRlci1bI0U1RTdFQl1cIj5cbiAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsxM3B4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+XG4gICAgICB7eyBmaWx0ZXJUZXJtID8gJ05vIG9wZXJhdGlvbnMgbWF0Y2ggeW91ciBmaWx0ZXIuJyA6ICdObyBvcGVyYXRpb25zIGF2YWlsYWJsZS4nIH19XG4gICAgPC9zcGFuPlxuICAgIDxzcGFuICpuZ0lmPVwiIWZpbHRlclRlcm1cIiBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtdGV4dC1bIzZCNzI4MF1cIj5cbiAgICAgIENsaWNrIDxzdHJvbmc+UmUtaW50cm9zcGVjdDwvc3Ryb25nPiBhYm92ZSB0byBsb2FkIHRoZSBzY2hlbWEuXG4gICAgPC9zcGFuPlxuICA8L2Rpdj5cblxuICA8IS0tIE9wZXJhdGlvbiBzZWN0aW9ucyAoUXVlcmllcyAvIE11dGF0aW9ucyAvIFN1YnNjcmlwdGlvbnMpIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTG9hZGluZyAmJiBmaWx0ZXJlZE9wZXJhdGlvbnMubGVuZ3RoXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm9wU2VjdGlvbjsgY29udGV4dDogeyAkaW1wbGljaXQ6IHF1ZXJ5T3BlcmF0aW9ucywgbGFiZWw6ICdRdWVyaWVzJywgYWNjZW50OiAnY3FhLXRleHQtWyMwNTk2NjldJyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm9wU2VjdGlvbjsgY29udGV4dDogeyAkaW1wbGljaXQ6IG11dGF0aW9uT3BlcmF0aW9ucywgbGFiZWw6ICdNdXRhdGlvbnMnLCBhY2NlbnQ6ICdjcWEtdGV4dC1bI0Q5NzcwNl0nIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwib3BTZWN0aW9uOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogc3Vic2NyaXB0aW9uT3BlcmF0aW9ucywgbGFiZWw6ICdTdWJzY3JpcHRpb25zJywgYWNjZW50OiAnY3FhLXRleHQtWyM3QzNBRURdJyB9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDwhLS0gRm9vdGVyOiBzZWxlY3Rpb24gc3VtbWFyeS4gTm8gQmFjayAvIFVzZSBidXR0b25zIOKAlCBjbGlja2luZyBhIHJvdyBjb21taXRzICsgcmV0dXJucy4gLS0+XG4gIDxkaXYgKm5nSWY9XCIhaXNMb2FkaW5nICYmIGZpbHRlcmVkT3BlcmF0aW9ucy5sZW5ndGhcIiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItZm9vdGVyIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLXB0LTIgY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjNkI3MjgwXVwiPlxuICAgIDxzcGFuPkNsaWNrIGFuIG9wZXJhdGlvbiB0byB1c2UgaXQg4oCUIHRoZSBwaWNrZXIgY2xvc2VzIGFuZCB0aGUgcmVxdWVzdCBpcyBhdXRvLWZpbGxlZC48L3NwYW4+XG4gIDwvZGl2PlxuXG4gIDwhLS0g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAIFNlY3Rpb24gdGVtcGxhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAIC0tPlxuICA8bmctdGVtcGxhdGUgI29wU2VjdGlvbiBsZXQtb3BzIGxldC1sYWJlbD1cImxhYmVsXCIgbGV0LWFjY2VudD1cImFjY2VudFwiPlxuICAgIDxkaXYgKm5nSWY9XCJvcHM/Lmxlbmd0aFwiIGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1zZWN0aW9uIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLXNlY3Rpb24taGVhZCBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtYmctWyNGOUZBRkJdIGNxYS1weC0zIGNxYS1weS0xLjUgY3FhLXJvdW5kZWQtbWQgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNGM0Y0RjZdXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLWdyYXBocWwtb3BlcmF0aW9uLXBpY2tlci1zZWN0aW9uLWxhYmVsIGNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZFwiIFtuZ0NsYXNzXT1cImFjY2VudFwiPnt7IGxhYmVsIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItc2VjdGlvbi1jb3VudCBjcWEtdGV4dC1bMTFweF0gY3FhLXRleHQtWyM2QjcyODBdXCI+XG4gICAgICAgICAge3sgb3BzLmxlbmd0aCB9fSB7eyBvcHMubGVuZ3RoID09PSAxID8gJ29wZXJhdGlvbicgOiAnb3BlcmF0aW9ucycgfX1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBvcCBvZiBvcHM7IHRyYWNrQnk6IHRyYWNrQnlPcGVyYXRpb25cIlxuICAgICAgICBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItcm93IGNxYS1mbGV4IGNxYS1pdGVtcy1zdGFydCBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtMyBjcWEtcHgtMyBjcWEtcHktMi41IGNxYS1yb3VuZGVkLW1kIGNxYS1jdXJzb3ItcG9pbnRlciBjcWEtYm9yZGVyIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci10cmFuc3BhcmVudCBob3ZlcjpjcWEtYmctWyNGOUZBRkJdIGhvdmVyOmNxYS1ib3JkZXItWyNFNUU3RUJdIGZvY3VzLXdpdGhpbjpjcWEtYmctWyNGNUYzRkZdXCJcbiAgICAgICAgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1VzZSBvcGVyYXRpb24gJyArIG9wLm5hbWVcIlxuICAgICAgICAoY2xpY2spPVwib25TZWxlY3Qob3ApXCJcbiAgICAgICAgKGtleWRvd24uZW50ZXIpPVwib25TZWxlY3Qob3ApXCJcbiAgICAgICAgKGtleWRvd24uc3BhY2UpPVwib25TZWxlY3Qob3ApOyAkZXZlbnQucHJldmVudERlZmF1bHQoKVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItcm93LXJhZGlvIGNxYS1tdC0xIGNxYS1zaHJpbmstMFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLWlubGluZS1ibG9jayBjcWEtdy00IGNxYS1oLTQgY3FhLXJvdW5kZWQtZnVsbCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci1bIzlDQTNBRl0gY3FhLWJnLXdoaXRlXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLXJvdy1ib2R5IGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTAuNSBjcWEtZmxleC0xIGNxYS1taW4tdy0wXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItcm93LXNpZ25hdHVyZSBjcWEtZmxleCBjcWEtZmxleC13cmFwIGNxYS1pdGVtcy1iYXNlbGluZSBjcWEtZ2FwLXgtMSBjcWEtdGV4dC1bMTNweF0gY3FhLWZvbnQtbW9ubyBjcWEtbGVhZGluZy1bMS40XSBjcWEtbWluLXctMFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bIzExMTgyN10gY3FhLWZvbnQtc2VtaWJvbGRcIj57eyBvcC5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bIzZCNzI4MF1cIj4oPC9zcGFuPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYXJnIG9mIG9wLmFyZ3MgPz8gW107IGxldCBsYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsjMzc0MTUxXVwiPnt7IGFyZy5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsjNkI3MjgwXVwiPjombmJzcDs8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIFtuZ0NsYXNzXT1cInJldHVyblR5cGVDb2xvckNsYXNzKG9wLmtpbmQpXCI+e3sgYXJnLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIWxhc3RcIiBjbGFzcz1cImNxYS10ZXh0LVsjNkI3MjgwXVwiPiwmbmJzcDs8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWyM2QjcyODBdXCI+KTwvc3Bhbj5cbiAgICAgICAgICAgIFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJvcC5kZXNjcmlwdGlvblwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xIGNxYS1ncmFwaHFsLW9wZXJhdGlvbi1waWNrZXItcm93LWRlc2NyaXB0aW9uIGNxYS10ZXh0LVsxMnB4XSBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLWxlYWRpbmctWzEuNV1cIj5cbiAgICAgICAgICAgIDxzcGFuPnt7IG9wLmRlc2NyaXB0aW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwib3AucmV0dXJuVHlwZVwiIHN0eWxlPVwiZGlzcGxheTpmbGV4O2ZvbnQtc2l6ZToxNHB4O2ZvbnQtd2VpZ2h0OiA2MDA7XCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLW14LTFcIj5hcnJvd19mb3J3YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwib3AucmV0dXJuVHlwZVwiIFtuZ0NsYXNzXT1cInJldHVyblR5cGVDb2xvckNsYXNzKG9wLmtpbmQpXCIgY2xhc3M9XCJjcWEtZm9udC1zZW1pYm9sZFwiPnt7IG9wLnJldHVyblR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZ3JhcGhxbC1vcGVyYXRpb24tcGlja2VyLXJvdy1wcmV2aWV3IGNxYS1zaHJpbmstMCBjcWEtaW5saW5lLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgY3FhLWJnLXRyYW5zcGFyZW50IGNxYS1ib3JkZXItMCBjcWEtY3Vyc29yLXBvaW50ZXIgY3FhLXRleHQtWyM0RjQ2RTVdIGNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gaG92ZXI6Y3FhLXVuZGVybGluZSBmb2N1czpjcWEtb3V0bGluZS1ub25lIGZvY3VzLXZpc2libGU6Y3FhLXJpbmctMiBmb2N1cy12aXNpYmxlOmNxYS1yaW5nLVsjQTVCNEZDXSBjcWEtcm91bmRlZC1tZCBjcWEtcHgtMiBjcWEtcHktMVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInUHJldmlldyBvcGVyYXRpb24gJyArIG9wLm5hbWVcIlxuICAgICAgICAgIChjbGljayk9XCJvblByZXZpZXcob3AsICRldmVudClcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgIDxwYXRoIGQ9XCJNMiAxMnMzLjUtNyAxMC03IDEwIDcgMTAgNy0zLjUgNy0xMCA3LTEwLTctMTAtN3pcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjEyXCIgY3k9XCIxMlwiIHI9XCIzXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8c3Bhbj5QcmV2aWV3PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj4gLS0+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PlxuIl19
|