@unifylib/ui-lib 1.0.64 → 1.0.66

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,181 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @param {{
5
+ * kebab: string,
6
+ * pascal: string,
7
+ * labelsSection: string,
8
+ * apiUri: string,
9
+ * importPath: string,
10
+ * }} ctx
11
+ */
12
+ function generate(ctx) {
13
+ const fileBase = ctx.kebab;
14
+
15
+ const settings = `import { Validators } from "@angular/forms";
16
+ import {
17
+ ButtonActionSettings,
18
+ FieldInfo,
19
+ FilterRequest,
20
+ PageInfo,
21
+ ReportRequest,
22
+ TableColumn,
23
+ } from "${ctx.importPath}";
24
+
25
+ export const PAGE_INFO: PageInfo = {
26
+ id: "${ctx.kebab}",
27
+ labelsSection: "${ctx.labelsSection}",
28
+ hasAddButton: true,
29
+ apiUri: "${ctx.apiUri}",
30
+ selfRouting: true,
31
+ listRoutePath: "/${ctx.kebab}",
32
+ draftSupported: true,
33
+ pageSize: 10,
34
+ };
35
+
36
+ export const COLUMNS: TableColumn<Record<string, unknown>>[] = [
37
+ { property: "id", type: "text", enableSorting: true, visible: true, label: "id" },
38
+ { property: "name", type: "text", enableSorting: true, visible: true, label: "name" },
39
+ ];
40
+
41
+ export const FILTER_FIELDS: FieldInfo[] = [
42
+ new FieldInfo({
43
+ property: "name",
44
+ row: 1,
45
+ type: "text",
46
+ label: "name",
47
+ advancedFilter: true,
48
+ filterOperator: "LIKE",
49
+ validators: [Validators.maxLength(30)],
50
+ maxLength: 30,
51
+ } as FieldInfo),
52
+ ];
53
+
54
+ function buildReportRequest(): ReportRequest {
55
+ const filterRequest = new FilterRequest(PAGE_INFO.pageSize ?? 10);
56
+ filterRequest.columns = COLUMNS.filter((c) => c.visible !== false).map((c) => c.property);
57
+ return new ReportRequest({ filterRequest });
58
+ }
59
+
60
+ export const REPORT_REQUEST: ReportRequest = buildReportRequest();
61
+
62
+ export const LIST_ACTIONS: ButtonActionSettings[] = [
63
+ new ButtonActionSettings({
64
+ key: 1,
65
+ id: "view",
66
+ label: "VIEW",
67
+ linkHref: (row: unknown) => {
68
+ const id = (row as { id?: number }).id;
69
+ return id != null ? \`/${ctx.kebab}/view/\${id}\` : undefined;
70
+ },
71
+ } as ButtonActionSettings),
72
+ ];
73
+
74
+ export const TOOLBAR_ACTIONS: ButtonActionSettings[] = [
75
+ new ButtonActionSettings({
76
+ key: 1,
77
+ id: "create",
78
+ label: "ADD_NEW",
79
+ linkHref: "/${ctx.kebab}/new",
80
+ } as ButtonActionSettings),
81
+ ];
82
+ `;
83
+
84
+ const componentTs = `import { ChangeDetectionStrategy, Component, inject } from "@angular/core";
85
+ import { Router } from "@angular/router";
86
+ import { TranslateModule } from "@ngx-translate/core";
87
+ import {
88
+ BaseTableComponent,
89
+ ButtonActionSettings,
90
+ Filter,
91
+ } from "${ctx.importPath}";
92
+ import {
93
+ COLUMNS,
94
+ FILTER_FIELDS,
95
+ LIST_ACTIONS,
96
+ PAGE_INFO,
97
+ REPORT_REQUEST,
98
+ TOOLBAR_ACTIONS,
99
+ } from "./${fileBase}.settings";
100
+
101
+ @Component({
102
+ selector: "app-${fileBase}",
103
+ standalone: true,
104
+ imports: [BaseTableComponent, TranslateModule],
105
+ templateUrl: "./${fileBase}.component.html",
106
+ styleUrls: ["./${fileBase}.component.scss"],
107
+ changeDetection: ChangeDetectionStrategy.OnPush,
108
+ })
109
+ export class ${ctx.pascal}Component {
110
+ private readonly router = inject(Router);
111
+
112
+ readonly pageInfo = PAGE_INFO;
113
+ readonly columnsDefinition = COLUMNS;
114
+ readonly filterFieldDefinitions = FILTER_FIELDS;
115
+ readonly reportRequest = REPORT_REQUEST;
116
+ readonly filters: Filter[] = [];
117
+ readonly listActions = LIST_ACTIONS;
118
+ readonly toolbarActions = TOOLBAR_ACTIONS;
119
+ readonly isPending = false;
120
+
121
+ onListActionClicked(event: {
122
+ action: ButtonActionSettings;
123
+ row: unknown;
124
+ isPending: boolean;
125
+ }): void {
126
+ const href =
127
+ typeof event.action.linkHref === "function"
128
+ ? event.action.linkHref(event.row)
129
+ : event.action.linkHref;
130
+ if (href) {
131
+ void this.router.navigateByUrl(href);
132
+ }
133
+ }
134
+
135
+ onToolbarButton(action: ButtonActionSettings): void {
136
+ if (typeof action.linkHref === "string") {
137
+ void this.router.navigateByUrl(action.linkHref);
138
+ }
139
+ }
140
+ }
141
+ `;
142
+
143
+ const componentHtml = `<app-base-table
144
+ [pageInfo]="pageInfo"
145
+ [columns]="columnsDefinition"
146
+ [reportRequest]="reportRequest"
147
+ [filterFields]="filterFieldDefinitions"
148
+ [isPending]="isPending"
149
+ [filters]="filters"
150
+ [listAction]="listActions"
151
+ [extraActions]="toolbarActions"
152
+ [buttonsDisplayMode]="'list'"
153
+ (listActionClicked)="onListActionClicked($event)"
154
+ (buttonClicked)="onToolbarButton($event)">
155
+ </app-base-table>
156
+ `;
157
+
158
+ const componentScss = `:host {
159
+ display: block;
160
+ }
161
+ `;
162
+
163
+ return [
164
+ { relative: `${fileBase}.settings.ts`, content: settings },
165
+ { relative: `${fileBase}.component.ts`, content: componentTs },
166
+ { relative: `${fileBase}.component.html`, content: componentHtml },
167
+ { relative: `${fileBase}.component.scss`, content: componentScss },
168
+ ];
169
+ }
170
+
171
+ function getTranslations(ctx) {
172
+ return {
173
+ [`${ctx.labelsSection}.list_title`]: `${ctx.pascal} List`,
174
+ [`${ctx.labelsSection}.id`]: "ID",
175
+ [`${ctx.labelsSection}.name`]: "Name",
176
+ VIEW: "View",
177
+ ADD_NEW: "Add new",
178
+ };
179
+ }
180
+
181
+ module.exports = { generate, getTranslations };
package/cli/index.js ADDED
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const path = require("path");
5
+ const {
6
+ kebabCase,
7
+ pascalCase,
8
+ upperSnakeFromKebab,
9
+ lastPathSegment,
10
+ writeFiles,
11
+ upsertI18nEntries,
12
+ } = require("./utils");
13
+
14
+ const GENERATORS = {
15
+ "form-screen": require("./generators/form-screen.js"),
16
+ "table-screen": require("./generators/table-screen.js"),
17
+ "section-form": require("./generators/section-form.js"),
18
+ "line-editor": require("./generators/line-editor.js"),
19
+ dashboard: require("./generators/dashboard.js"),
20
+ "permission-matrix": require("./generators/permission-matrix.js"),
21
+ };
22
+
23
+ function printHelp() {
24
+ console.log(`
25
+ iq-ui — scaffold Angular screens that use @unifylib/ui-lib
26
+
27
+ Usage:
28
+ iq-ui -g <type> <destination> [options]
29
+
30
+ Types:
31
+ form-screen app-base-form-canvas + settings
32
+ table-screen app-base-table + settings
33
+ section-form lib-section-form-canvas + settings
34
+ line-editor app-item-line-editor + settings
35
+ dashboard lib-action-card grid (no settings file)
36
+ permission-matrix lib-permission-matrix + settings
37
+
38
+ Options:
39
+ --name <n> File/class base name (default: last segment of destination)
40
+ --labels-section <s> i18n labelsSection (default: UPPER_SNAKE from name)
41
+ --api-uri <u> API path for PageInfo.apiUri (default: /<name>)
42
+ --fields-count <n> Placeholder fields (default: 6; form-screen, section-form, line-editor)
43
+ --import-path <p> Library import (default: @iq/ui-lib)
44
+ --i18n-path <p> Optional translation file/folder (example: src/assets/en.json or src/assets)
45
+ --dry-run Print files that would be written
46
+ -h, --help Show this help
47
+
48
+ Examples (after npm install @unifylib/ui-lib, use the package binary; do not run \`npx iq-ui\`, which looks up a wrong package on npm):
49
+ npx -p @unifylib/ui-lib iq-ui -g form-screen src/app/registration --i18n-path src/assets/en.json
50
+ npx -p @unifylib/ui-lib iq-ui -g table-screen src/app/devices --labels-section DEVICE --api-uri /devices/list
51
+ npx -p @unifylib/ui-lib iq-ui -g dashboard src/app/home --import-path @unifylib/ui-lib
52
+
53
+ Local dev / linked build:
54
+ node node_modules/@unifylib/ui-lib/cli/index.js -g form-screen src/app/registration
55
+ `);
56
+ }
57
+
58
+ /**
59
+ * @returns {{
60
+ * type?: string,
61
+ * destination?: string,
62
+ * name?: string,
63
+ * labelsSection?: string,
64
+ * apiUri?: string,
65
+ * fieldsCount: number,
66
+ * importPath: string,
67
+ * i18nPath?: string,
68
+ * dryRun: boolean,
69
+ * help: boolean,
70
+ * }}
71
+ */
72
+ function parseArgs(argv) {
73
+ const out = {
74
+ fieldsCount: 6,
75
+ importPath: "@iq/ui-lib",
76
+ dryRun: false,
77
+ help: false,
78
+ };
79
+
80
+ for (let i = 2; i < argv.length; i++) {
81
+ const a = argv[i];
82
+ if (a === "-h" || a === "--help") {
83
+ out.help = true;
84
+ continue;
85
+ }
86
+ if (a === "--dry-run") {
87
+ out.dryRun = true;
88
+ continue;
89
+ }
90
+ if (a === "-g" || a === "--generate") {
91
+ out.type = argv[++i];
92
+ continue;
93
+ }
94
+ if (a === "--name") {
95
+ out.name = argv[++i];
96
+ continue;
97
+ }
98
+ if (a === "--labels-section") {
99
+ out.labelsSection = argv[++i];
100
+ continue;
101
+ }
102
+ if (a === "--api-uri") {
103
+ out.apiUri = argv[++i];
104
+ continue;
105
+ }
106
+ if (a === "--fields-count") {
107
+ out.fieldsCount = parseInt(argv[++i], 10) || 6;
108
+ continue;
109
+ }
110
+ if (a === "--import-path") {
111
+ out.importPath = argv[++i];
112
+ continue;
113
+ }
114
+ if (a === "--i18n-path") {
115
+ out.i18nPath = argv[++i];
116
+ continue;
117
+ }
118
+ if (a.startsWith("-")) {
119
+ console.error("Unknown option:", a);
120
+ process.exitCode = 1;
121
+ out.help = true;
122
+ return out;
123
+ }
124
+ if (!out.destination) {
125
+ out.destination = a;
126
+ } else {
127
+ console.error("Unexpected argument:", a);
128
+ process.exitCode = 1;
129
+ out.help = true;
130
+ return out;
131
+ }
132
+ }
133
+ return out;
134
+ }
135
+
136
+ function main() {
137
+ const args = parseArgs(process.argv);
138
+ if (args.help) {
139
+ printHelp();
140
+ process.exit(process.exitCode || 0);
141
+ }
142
+ if (!args.type || !args.destination) {
143
+ console.error("Missing required: -g <type> and <destination>\n");
144
+ printHelp();
145
+ process.exit(1);
146
+ }
147
+
148
+ const gen = GENERATORS[args.type];
149
+ if (!gen || typeof gen.generate !== "function") {
150
+ console.error("Unknown generator type:", args.type);
151
+ printHelp();
152
+ process.exit(1);
153
+ }
154
+
155
+ const rawName = args.name || lastPathSegment(args.destination);
156
+ const kebab = kebabCase(rawName);
157
+ const pascal = pascalCase(rawName);
158
+ const labelsSection = args.labelsSection || upperSnakeFromKebab(kebab);
159
+ const apiUri = args.apiUri != null ? args.apiUri : `/${kebab}`;
160
+
161
+ const destDir = path.isAbsolute(args.destination)
162
+ ? args.destination
163
+ : path.join(process.cwd(), args.destination);
164
+
165
+ const ctx = {
166
+ kebab,
167
+ pascal,
168
+ labelsSection,
169
+ apiUri,
170
+ importPath: args.importPath,
171
+ fieldsCount: args.fieldsCount,
172
+ };
173
+
174
+ const files = gen.generate(ctx);
175
+ writeFiles({ destDir, dryRun: args.dryRun }, files);
176
+
177
+ if (args.i18nPath && typeof gen.getTranslations === "function") {
178
+ const translations = gen.getTranslations(ctx);
179
+ if (translations && Object.keys(translations).length > 0) {
180
+ upsertI18nEntries(args.i18nPath, translations, args.dryRun);
181
+ }
182
+ }
183
+ }
184
+
185
+ main();
package/cli/utils.js ADDED
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ /**
7
+ * @param {string} destPath
8
+ * @returns {string}
9
+ */
10
+ function lastPathSegment(destPath) {
11
+ const normalized = destPath.replace(/\\/g, "/").replace(/\/+$/, "");
12
+ const parts = normalized.split("/").filter(Boolean);
13
+ return parts[parts.length - 1] || "feature";
14
+ }
15
+
16
+ /**
17
+ * @param {string} str
18
+ * @returns {string}
19
+ */
20
+ function kebabCase(str) {
21
+ return String(str)
22
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
23
+ .replace(/[\s_]+/g, "-")
24
+ .toLowerCase()
25
+ .replace(/[^a-z0-9-]/g, "")
26
+ .replace(/-+/g, "-")
27
+ .replace(/^-|-$/g, "") || "feature";
28
+ }
29
+
30
+ /**
31
+ * @param {string} str
32
+ * @returns {string}
33
+ */
34
+ function pascalCase(str) {
35
+ return kebabCase(str)
36
+ .split("-")
37
+ .filter(Boolean)
38
+ .map((s) => s[0].toUpperCase() + s.slice(1))
39
+ .join("");
40
+ }
41
+
42
+ /**
43
+ * @param {string} kebab
44
+ * @returns {string}
45
+ */
46
+ function upperSnakeFromKebab(kebab) {
47
+ return kebabCase(kebab)
48
+ .split("-")
49
+ .filter(Boolean)
50
+ .map((s) => s.toUpperCase())
51
+ .join("_");
52
+ }
53
+
54
+ /**
55
+ * @param {string} destDir
56
+ * @param {boolean} dryRun
57
+ */
58
+ function ensureDir(destDir, dryRun) {
59
+ if (dryRun) return;
60
+ fs.mkdirSync(destDir, { recursive: true });
61
+ }
62
+
63
+ /**
64
+ * @param {string} filePath
65
+ * @param {string} content
66
+ * @param {boolean} dryRun
67
+ */
68
+ function writeFile(filePath, content, dryRun) {
69
+ if (dryRun) {
70
+ console.log(`[dry-run] would write ${filePath} (${content.length} bytes)`);
71
+ return;
72
+ }
73
+ fs.writeFileSync(filePath, content, "utf8");
74
+ console.log(`Wrote ${filePath}`);
75
+ }
76
+
77
+ /**
78
+ * @param {{ destDir: string, dryRun: boolean }} opts
79
+ * @param {Array<{ relative: string, content: string }>} files
80
+ */
81
+ function writeFiles(opts, files) {
82
+ ensureDir(opts.destDir, opts.dryRun);
83
+ for (const f of files) {
84
+ const filePath = path.join(opts.destDir, f.relative);
85
+ writeFile(filePath, f.content, opts.dryRun);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @param {Record<string, unknown>} target
91
+ * @param {string[]} pathParts
92
+ * @param {string} value
93
+ */
94
+ function setNested(target, pathParts, value) {
95
+ let cursor = target;
96
+ for (let i = 0; i < pathParts.length; i++) {
97
+ const part = pathParts[i];
98
+ const isLeaf = i === pathParts.length - 1;
99
+ if (isLeaf) {
100
+ cursor[part] = value;
101
+ return;
102
+ }
103
+ if (typeof cursor[part] !== "object" || cursor[part] === null || Array.isArray(cursor[part])) {
104
+ cursor[part] = {};
105
+ }
106
+ cursor = /** @type {Record<string, unknown>} */ (cursor[part]);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * @param {string} targetPath
112
+ * @returns {string[]}
113
+ */
114
+ function resolveJsonTargets(targetPath) {
115
+ const fullPath = path.isAbsolute(targetPath) ? targetPath : path.join(process.cwd(), targetPath);
116
+ if (!fs.existsSync(fullPath)) {
117
+ return [fullPath];
118
+ }
119
+
120
+ const stat = fs.statSync(fullPath);
121
+ if (stat.isFile()) {
122
+ return [fullPath];
123
+ }
124
+
125
+ if (!stat.isDirectory()) {
126
+ return [fullPath];
127
+ }
128
+
129
+ /** @type {string[]} */
130
+ const out = [];
131
+ /** @param {string} fileName */
132
+ function isTranslationFileName(fileName) {
133
+ const lower = fileName.toLowerCase();
134
+ // Common translation file patterns
135
+ // - en.json / ar.json
136
+ // - en-us.json / ar-QA.json
137
+ // - messages.en.json / messages-ar.json
138
+ return (
139
+ /^(en|ar)([-_][a-z0-9]+)*\.json$/i.test(lower) ||
140
+ /\.((en|ar)([-_][a-z0-9]+)*)\.json$/i.test(lower) ||
141
+ lower.includes("i18n")
142
+ );
143
+ }
144
+ /** @param {string} dir */
145
+ function walk(dir) {
146
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
147
+ for (const entry of entries) {
148
+ const entryPath = path.join(dir, entry.name);
149
+ if (entry.isDirectory()) {
150
+ walk(entryPath);
151
+ } else if (entry.isFile() && isTranslationFileName(entry.name)) {
152
+ out.push(entryPath);
153
+ }
154
+ }
155
+ }
156
+
157
+ walk(fullPath);
158
+ return out;
159
+ }
160
+
161
+ /**
162
+ * @param {string} i18nPath
163
+ * @param {Record<string, string>} entries
164
+ * @param {boolean} dryRun
165
+ */
166
+ function upsertI18nEntries(i18nPath, entries, dryRun) {
167
+ const targets = resolveJsonTargets(i18nPath);
168
+ if (targets.length === 0) {
169
+ console.log(`No JSON files found in i18n target: ${i18nPath}`);
170
+ return;
171
+ }
172
+
173
+ for (const fullPath of targets) {
174
+ if (dryRun) {
175
+ console.log(`[dry-run] would update i18n file ${fullPath} with ${Object.keys(entries).length} keys`);
176
+ continue;
177
+ }
178
+
179
+ let data = {};
180
+ if (fs.existsSync(fullPath)) {
181
+ const raw = fs.readFileSync(fullPath, "utf8").trim();
182
+ data = raw ? JSON.parse(raw) : {};
183
+ } else {
184
+ const parent = path.dirname(fullPath);
185
+ fs.mkdirSync(parent, { recursive: true });
186
+ }
187
+
188
+ for (const [key, value] of Object.entries(entries)) {
189
+ const parts = key.split(".").filter(Boolean);
190
+ if (parts.length === 0) continue;
191
+ setNested(data, parts, value);
192
+ }
193
+
194
+ fs.writeFileSync(fullPath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
195
+ console.log(`Updated i18n ${fullPath}`);
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Generate placeholder FieldInfo rows (2 per row by default).
201
+ * @param {number} count
202
+ * @param {number} perRow
203
+ * @param {string} indent
204
+ * @returns {string}
205
+ */
206
+ function buildFieldInfoLines(count, perRow, indent) {
207
+ const lines = [];
208
+ for (let i = 1; i <= count; i++) {
209
+ const row = Math.ceil(i / perRow);
210
+ lines.push(
211
+ `${indent}new FieldInfo({ row: ${row}, property: "field${i}", label: "field${i}", required: false, type: "text", validators: [Validators.maxLength(100)], validationMessages: { maxlength: "VALIDATION_MAX_100" } })`
212
+ );
213
+ }
214
+ return lines.join(",\n");
215
+ }
216
+
217
+ module.exports = {
218
+ lastPathSegment,
219
+ kebabCase,
220
+ pascalCase,
221
+ upperSnakeFromKebab,
222
+ ensureDir,
223
+ writeFile,
224
+ writeFiles,
225
+ buildFieldInfoLines,
226
+ resolveJsonTargets,
227
+ upsertI18nEntries,
228
+ };
@@ -49,7 +49,7 @@ export class ActionCommentComponent {
49
49
  this.signingRequired = this.data.signingRequired;
50
50
  this.tokenReference = this.data.tokenReference;
51
51
  this.warningMsg = this.data.warningMsg || false;
52
- this.itemName = this.data.deviceName;
52
+ this.itemName = this.data.itemName;
53
53
  this.titleKey = this.data.titleKey;
54
54
  this.subtitleKey = this.data.subtitleKey;
55
55
  this.reasonLabelKey = this.data.reasonLabelKey;
@@ -108,4 +108,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
108
108
  type: HostListener,
109
109
  args: ['window:keyup.esc']
110
110
  }] } });
111
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWNvbW1lbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52b2ljZXEvdWktbGliL3NyYy9saWIvY29tcG9uZW50cy9hY3Rpb24tY29tbWVudC9hY3Rpb24tY29tbWVudC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZvaWNlcS91aS1saWIvc3JjL2xpYi9jb21wb25lbnRzL2FjdGlvbi1jb21tZW50L2FjdGlvbi1jb21tZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFFaEIsY0FBYyxFQUNmLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxFQUFDLGVBQWUsRUFBbUIsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1B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d0JBQ1QsT0FBTzt3QkFDUCxJQUFJO3FCQUNMOzswQkEyQlksTUFBTTsyQkFBQyxlQUFlO3dFQUlELE9BQU87c0JBQXhDLFlBQVk7dUJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIEluamVjdCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgTUFUX0RJQUxPR19EQVRBLFxyXG4gIE1hdERpYWxvZ0FjdGlvbnMsXHJcbiAgTWF0RGlhbG9nQ29udGVudCxcclxuICBNYXREaWFsb2dSZWYsXHJcbiAgTWF0RGlhbG9nVGl0bGVcclxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGQsIE1hdExhYmVsIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XHJcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBDZGtUZXh0YXJlYUF1dG9zaXplIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3RleHQtZmllbGQnO1xyXG5pbXBvcnQge1RyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IE1hdE9wdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xyXG5pbXBvcnQgeyBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyBOZ0Zvck9mLCBOZ0lmIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXBwLWFjdGlvbi1jb21tZW50JyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIE1hdERpYWxvZ1RpdGxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkLFxyXG4gICAgTWF0TGFiZWwsXHJcbiAgICBNYXREaWFsb2dDb250ZW50LFxyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBDZGtUZXh0YXJlYUF1dG9zaXplLFxyXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxyXG4gICAgTWF0RGlhbG9nQWN0aW9ucyxcclxuICAgIE1hdEJ1dHRvbixcclxuICAgIE1hdElucHV0LFxyXG4gICAgTWF0SWNvbixcclxuICAgIE1hdE9wdGlvbixcclxuICAgIE1hdFNlbGVjdCxcclxuICAgIE5nRm9yT2YsXHJcbiAgICBOZ0lmXHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vYWN0aW9uLWNvbW1lbnQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9hY3Rpb24tY29tbWVudC5jb21wb25lbnQuY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQWN0aW9uQ29tbWVudENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgaXRlbU5hbWU6IHN0cmluZyA9ICcnO1xyXG4gIHRpdGxlS2V5OiBzdHJpbmcgPSAnJztcclxuICBzdWJ0aXRsZUtleTogc3RyaW5nID0gJyc7XHJcbiAgcmVhc29uTGFiZWxLZXk6IHN0cmluZyA9ICcnO1xyXG4gIHBsYWNlaG9sZGVyS2V5OiBzdHJpbmcgPSAnJztcclxuICB3YXJuaW5nS2V5OiBzdHJpbmcgPSAnJztcclxuICBjYW5jZWxLZXk6IHN0cmluZyA9ICcnO1xyXG4gIGFjdGlvbktleTogc3RyaW5nID0gJyc7XHJcbiAgY3VycmVudERpcmVjdGlvbjogJ2x0cicgfCAncnRsJyA9ICdsdHInO1xyXG5cclxuICBhY3Rpb25MYWJlbCA6IHN0cmluZyA9JydcclxuICBpc1Rlcm1pbmF0aW9uIDogYm9vbGVhbj1mYWxzZTtcclxuICBjb21tZW50OiBzdHJpbmcgPSAnJztcclxuICBvdGhlckNvbW1lbnQ6IHN0cmluZyA9ICcnO1xyXG4gIGV4dGVybmFsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2lnbmluZ1JlcXVpcmVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgdG9rZW5SZWZlcmVuY2U6IHN0cmluZyA9IFwiXCI7XHJcbiAgb3RwOiBzdHJpbmcgPSBcIlwiO1xyXG4gIGlzU3VibWl0dGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgd2FybmluZ01zZyA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8QWN0aW9uQ29tbWVudENvbXBvbmVudD4sXHJcbiAgICAgICAgICAgICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHB1YmxpYyBkYXRhOiBhbnksXHJcbiAgICAgICAgICAgICAgcHVibGljIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSkge1xyXG4gICAgZGlhbG9nUmVmLmRpc2FibGVDbG9zZSA9IHRydWU7XHJcbiAgfVxyXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXl1cC5lc2MnKSBvbktleVVwKCkge1xyXG4gICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UoKTtcclxuICB9XHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmFjdGlvbkxhYmVsID0gdGhpcy5kYXRhLmxhYmVsO1xyXG4gICAgdGhpcy5pc1Rlcm1pbmF0aW9uID0gdGhpcy5kYXRhLmlzVGVybWluYXRpb24gO1xyXG4gICAgdGhpcy5zaWduaW5nUmVxdWlyZWQgPSB0aGlzLmRhdGEuc2lnbmluZ1JlcXVpcmVkO1xyXG4gICAgdGhpcy50b2tlblJlZmVyZW5jZSA9IHRoaXMuZGF0YS50b2tlblJlZmVyZW5jZTtcclxuICAgIHRoaXMud2FybmluZ01zZyA9IHRoaXMuZGF0YS53YXJuaW5nTXNnIHx8IGZhbHNlO1xyXG5cclxuICAgIHRoaXMuaXRlbU5hbWUgPSB0aGlzLmRhdGEuZGV2aWNlTmFtZTtcclxuICAgIHRoaXMudGl0bGVLZXkgPSB0aGlzLmRhdGEudGl0bGVLZXk7XHJcbiAgICB0aGlzLnN1YnRpdGxlS2V5ID0gdGhpcy5kYXRhLnN1YnRpdGxlS2V5O1xyXG4gICAgdGhpcy5yZWFzb25MYWJlbEtleSA9IHRoaXMuZGF0YS5yZWFzb25MYWJlbEtleTtcclxuICAgIHRoaXMucGxhY2Vob2xkZXJLZXkgPSB0aGlzLmRhdGEucGxhY2Vob2xkZXJLZXk7XHJcbiAgICB0aGlzLndhcm5pbmdLZXkgPSB0aGlzLmRhdGEud2FybmluZ0tleTtcclxuICAgIHRoaXMuY2FuY2VsS2V5ID0gdGhpcy5kYXRhLmNhbmNlbEtleTtcclxuICAgIHRoaXMuYWN0aW9uS2V5ID0gdGhpcy5kYXRhLmFjdGlvbktleTtcclxuICAgIHRoaXMuY3VycmVudERpcmVjdGlvbiAgPSB0aGlzLmRhdGEuZGlyZWN0aW9uO1xyXG4gIH1cclxuXHJcblxyXG4gIGNvbW1lbnRBbmRDbG9zZSgpIHtcclxuICAgIHRoaXMuaXNTdWJtaXR0ZWQgPSB0cnVlO1xyXG5cclxuICAgIGlmICh0aGlzLnNpZ25pbmdSZXF1aXJlZCAmJiAhdGhpcy5vdHApIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZpbmFsQ29tbWVudCA9XHJcbiAgICAgIHRoaXMuY29tbWVudCA9PT0gJ09USEVSJyA/IHRoaXMub3RoZXJDb21tZW50IDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCh0aGlzLmNvbW1lbnQpO1xyXG5cclxuICAgIGNvbnN0IG9iajogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHtcclxuICAgICAgY29tbWVudDogZmluYWxDb21tZW50LFxyXG4gICAgICBzaGFyZUV4dGVybmFsOiB0aGlzLmV4dGVybmFsXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLnNpZ25pbmdSZXF1aXJlZCkge1xyXG4gICAgICBvYmpbJ3Rva2VuJ10gPSB0aGlzLm90cDtcclxuICAgICAgb2JqWyd0b2tlblJlZmVyZW5jZSddID0gdGhpcy50b2tlblJlZmVyZW5jZTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZShvYmopO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBjYW5jZWwoKSB7XHJcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgpO1xyXG4gIH1cclxuXHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImRpYWxvZy1jb250YWluZXJcIiBbZGlyXT1cImN1cnJlbnREaXJlY3Rpb25cIj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cImRlc2t0b3Atdmlld1wiPlxyXG4gICAgPGgyIG1hdC1kaWFsb2ctdGl0bGUgY2xhc3M9XCJkaWFsb2ctdGl0bGVcIj5cclxuICAgICAge3sgdGl0bGVLZXkgfCB0cmFuc2xhdGV9fSB7e2l0ZW1OYW1lfX1cclxuICAgIDwvaDI+XHJcblxyXG4gICAgPHAgY2xhc3M9XCJkaWFsb2ctc3VidGl0bGVcIj5cclxuICAgICAge3sgc3VidGl0bGVLZXkgfCB0cmFuc2xhdGUgfX1cclxuICAgIDwvcD5cclxuXHJcbiAgICA8bWF0LWRpYWxvZy1jb250ZW50IGNsYXNzPVwiY29udGVudC1zZWN0aW9uXCI+XHJcblxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGF0YT8ub3B0aW9ucz8ubGVuZ3RoOyBlbHNlIHRleHRNb2RlXCI+XHJcblxyXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwidy0xMDBcIj5cclxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgcmVhc29uTGFiZWxLZXkgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgIDxtYXQtc2VsZWN0XHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29tbWVudFwiXHJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlcktleSB8IHRyYW5zbGF0ZVwiPlxyXG5cclxuICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgZGF0YS5vcHRpb25zXCIgW3ZhbHVlXT1cIml0ZW1cIj5cclxuICAgICAgICAgICAgICB7eyBkYXRhLnRyYW5zbGF0ZSA/IChpdGVtIHwgdHJhbnNsYXRlKSA6IGl0ZW0gfX1cclxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG5cclxuICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICAgICpuZ0lmPVwiY29tbWVudCA9PT0gJ09USEVSJ1wiXHJcbiAgICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICBjbGFzcz1cInctMTAwXCI+XHJcbiAgICAgICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyS2V5IHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8dGV4dGFyZWFcclxuICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJvdGhlckNvbW1lbnRcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJLZXkgfCB0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICBjZGtUZXh0YXJlYUF1dG9zaXplXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWluUm93cz1cIjRcIlxyXG4gICAgICAgICAgICBtYXhsZW5ndGg9XCIxMDAwXCJcclxuICAgICAgICAgICAgY2RrQXV0b3NpemVNYXhSb3dzPVwiNVwiPlxyXG4gICAgICAgICAgPC90ZXh0YXJlYT5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICA8bmctdGVtcGxhdGUgI3RleHRNb2RlPlxyXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwidy0xMDBcIj5cclxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgcmVhc29uTGFiZWxLZXkgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNvbW1lbnRcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJLZXkgfCB0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICBjZGtUZXh0YXJlYUF1dG9zaXplXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWluUm93cz1cIjRcIlxyXG4gICAgICAgICAgICBtYXhsZW5ndGg9XCIxMDAwXCJcclxuICAgICAgICAgICAgY2RrQXV0b3NpemVNYXhSb3dzPVwiNVwiPlxyXG4gICAgICAgICAgPC90ZXh0YXJlYT5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICA8L25nLXRlbXBsYXRlPlxyXG5cclxuICAgICAgPGRpdiBjbGFzcz1cImluZm8tYm94XCI+XHJcbiAgICAgICAgPG1hdC1pY29uPmluZm88L21hdC1pY29uPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby10ZXh0XCI+XHJcbiAgICAgICAgICB7eyB3YXJuaW5nS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgICAgPC9zcGFuPlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICA8L21hdC1kaWFsb2ctY29udGVudD5cclxuXHJcbiAgICA8bWF0LWRpYWxvZy1hY3Rpb25zIGFsaWduPVwiZW5kXCIgY2xhc3M9XCJmb290ZXItYWN0aW9uc1wiPlxyXG4gICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjbGFzcz1cImJ0bi1ub25lLWJhY2tncm91bmQtcHJpbWFyeSBjYW5jZWwtYnRuXCIgKGNsaWNrKT1cImNhbmNlbCgpXCI+XHJcbiAgICAgICAge3sgY2FuY2VsS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgIDwvYnV0dG9uPlxyXG5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIG1hdC1mbGF0LWJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuLWJhY2tncm91bmQtcHJpbWFyeSB3YXJuLWJ0blwiXHJcbiAgICAgICAgKGNsaWNrKT1cImNvbW1lbnRBbmRDbG9zZSgpXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWNvbW1lbnQgfHwgKGNvbW1lbnQgPT09ICdPVEhFUicgJiYgIW90aGVyQ29tbWVudClcIj5cclxuICAgICAgICB7eyBhY3Rpb25LZXkgfCB0cmFuc2xhdGUgfX1cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cIm1vYmlsZS12aWV3XCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJoYW5kbGVcIj48L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1jb250ZW50XCI+XHJcbiAgICAgICAgPHAgY2xhc3M9XCJtb2RhbC10aXRsZVwiPnt7IHRpdGxlS2V5IHwgdHJhbnNsYXRlIH19PC9wPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJjbG9zZS1idXR0b25cIiAoY2xpY2spPVwiY2FuY2VsKClcIj5cclxuICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIj5cclxuXHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkYXRhPy5vcHRpb25zPy5sZW5ndGg7IGVsc2UgbW9iaWxlVGV4dFwiPlxyXG5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInRleHRhcmVhLWZpZWxkLW1vYmlsZVwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyByZWFzb25MYWJlbEtleSB8IHRyYW5zbGF0ZSB9fSB7eyBpdGVtTmFtZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJjb21tZW50XCJcclxuICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0YXJlYS1tb2JpbGVcIj5cclxuXHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIGRhdGEub3B0aW9uc1wiIFt2YWx1ZV09XCJpdGVtXCI+XHJcbiAgICAgICAgICAgICAge3sgZGF0YS50cmFuc2xhdGUgPyAoIGl0ZW0gfCB0cmFuc2xhdGUpIDogaXRlbSB9fVxyXG4gICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcblxyXG4gICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgICAgKm5nSWY9XCJjb21tZW50ID09PSAnT1RIRVInXCJcclxuICAgICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgIGNsYXNzPVwidGV4dGFyZWEtZmllbGQtbW9iaWxlXCI+XHJcbiAgICAgICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyS2V5IHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8dGV4dGFyZWFcclxuICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJvdGhlckNvbW1lbnRcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJLZXkgfCB0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICBjZGtUZXh0YXJlYUF1dG9zaXplXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWluUm93cz1cIjRcIlxyXG4gICAgICAgICAgICBjZGtBdXRvc2l6ZU1heFJvd3M9XCI1XCJcclxuICAgICAgICAgICAgbWF4bGVuZ3RoPVwiMTAwMFwiXHJcbiAgICAgICAgICAgIGNsYXNzPVwidGV4dGFyZWEtbW9iaWxlXCI+XHJcbiAgICAgICAgICA8L3RleHRhcmVhPlxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgIDxuZy10ZW1wbGF0ZSAjbW9iaWxlVGV4dD5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInRleHRhcmVhLWZpZWxkLW1vYmlsZVwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyByZWFzb25MYWJlbEtleSB8IHRyYW5zbGF0ZSB9fSB7eyBpdGVtTmFtZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgPHRleHRhcmVhXHJcbiAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29tbWVudFwiXHJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlcktleSB8IHRyYW5zbGF0ZVwiXHJcbiAgICAgICAgICAgIGNka1RleHRhcmVhQXV0b3NpemVcclxuICAgICAgICAgICAgY2RrQXV0b3NpemVNaW5Sb3dzPVwiNFwiXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWF4Um93cz1cIjVcIlxyXG4gICAgICAgICAgICBtYXhsZW5ndGg9XCIxMDAwXCJcclxuICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0YXJlYS1tb2JpbGVcIj5cclxuICAgICAgICAgIDwvdGV4dGFyZWE+XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJpbmZvLWJveC1tb2JpbGVcIj5cclxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJpbmZvLWljb24tbW9iaWxlXCI+aW5mbzwvbWF0LWljb24+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLXRleHQtbW9iaWxlXCI+XHJcbiAgICAgICAgICB7eyB3YXJuaW5nS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgICAgPC9zcGFuPlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYWN0aW9ucy1tb2JpbGVcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnMtYnV0dG9ucy1jb250YWluZXJcIj5cclxuICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiBjbGFzcz1cImJ0bi1jYW5jZWwtbW9iaWxlXCIgKGNsaWNrKT1cImNhbmNlbCgpXCI+XHJcbiAgICAgICAgICB7eyBjYW5jZWxLZXkgfCB0cmFuc2xhdGUgfX1cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICBtYXQtZmxhdC1idXR0b25cclxuICAgICAgICAgIGNsYXNzPVwiYnRuLWFjdGlvbi1tb2JpbGVcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImNvbW1lbnRBbmRDbG9zZSgpXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhY29tbWVudCB8fCAoY29tbWVudCA9PT0gJ09USEVSJyAmJiAhb3RoZXJDb21tZW50KVwiPlxyXG4gICAgICAgICAge3sgYWN0aW9uS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiaG9tZS1pbmRpY2F0b3JcIj48L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuPC9kaXY+XHJcbiJdfQ==
111
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWNvbW1lbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52b2ljZXEvdWktbGliL3NyYy9saWIvY29tcG9uZW50cy9hY3Rpb24tY29tbWVudC9hY3Rpb24tY29tbWVudC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZvaWNlcS91aS1saWIvc3JjL2xpYi9jb21wb25lbnRzL2FjdGlvbi1jb21tZW50L2FjdGlvbi1jb21tZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFFaEIsY0FBYyxFQUNmLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxFQUFDLGVBQWUsRUFBbUIsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1B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d0JBQ1QsT0FBTzt3QkFDUCxJQUFJO3FCQUNMOzswQkEyQlksTUFBTTsyQkFBQyxlQUFlO3dFQUlELE9BQU87c0JBQXhDLFlBQVk7dUJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIEluamVjdCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgTUFUX0RJQUxPR19EQVRBLFxyXG4gIE1hdERpYWxvZ0FjdGlvbnMsXHJcbiAgTWF0RGlhbG9nQ29udGVudCxcclxuICBNYXREaWFsb2dSZWYsXHJcbiAgTWF0RGlhbG9nVGl0bGVcclxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGQsIE1hdExhYmVsIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XHJcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBDZGtUZXh0YXJlYUF1dG9zaXplIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3RleHQtZmllbGQnO1xyXG5pbXBvcnQge1RyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IE1hdE9wdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xyXG5pbXBvcnQgeyBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyBOZ0Zvck9mLCBOZ0lmIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXBwLWFjdGlvbi1jb21tZW50JyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIE1hdERpYWxvZ1RpdGxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkLFxyXG4gICAgTWF0TGFiZWwsXHJcbiAgICBNYXREaWFsb2dDb250ZW50LFxyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBDZGtUZXh0YXJlYUF1dG9zaXplLFxyXG4gICAgVHJhbnNsYXRlTW9kdWxlLFxyXG4gICAgTWF0RGlhbG9nQWN0aW9ucyxcclxuICAgIE1hdEJ1dHRvbixcclxuICAgIE1hdElucHV0LFxyXG4gICAgTWF0SWNvbixcclxuICAgIE1hdE9wdGlvbixcclxuICAgIE1hdFNlbGVjdCxcclxuICAgIE5nRm9yT2YsXHJcbiAgICBOZ0lmXHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vYWN0aW9uLWNvbW1lbnQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9hY3Rpb24tY29tbWVudC5jb21wb25lbnQuY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQWN0aW9uQ29tbWVudENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgaXRlbU5hbWU6IHN0cmluZyA9ICcnO1xyXG4gIHRpdGxlS2V5OiBzdHJpbmcgPSAnJztcclxuICBzdWJ0aXRsZUtleTogc3RyaW5nID0gJyc7XHJcbiAgcmVhc29uTGFiZWxLZXk6IHN0cmluZyA9ICcnO1xyXG4gIHBsYWNlaG9sZGVyS2V5OiBzdHJpbmcgPSAnJztcclxuICB3YXJuaW5nS2V5OiBzdHJpbmcgPSAnJztcclxuICBjYW5jZWxLZXk6IHN0cmluZyA9ICcnO1xyXG4gIGFjdGlvbktleTogc3RyaW5nID0gJyc7XHJcbiAgY3VycmVudERpcmVjdGlvbjogJ2x0cicgfCAncnRsJyA9ICdsdHInO1xyXG5cclxuICBhY3Rpb25MYWJlbCA6IHN0cmluZyA9JydcclxuICBpc1Rlcm1pbmF0aW9uIDogYm9vbGVhbj1mYWxzZTtcclxuICBjb21tZW50OiBzdHJpbmcgPSAnJztcclxuICBvdGhlckNvbW1lbnQ6IHN0cmluZyA9ICcnO1xyXG4gIGV4dGVybmFsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2lnbmluZ1JlcXVpcmVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgdG9rZW5SZWZlcmVuY2U6IHN0cmluZyA9IFwiXCI7XHJcbiAgb3RwOiBzdHJpbmcgPSBcIlwiO1xyXG4gIGlzU3VibWl0dGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgd2FybmluZ01zZyA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8QWN0aW9uQ29tbWVudENvbXBvbmVudD4sXHJcbiAgICAgICAgICAgICAgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHB1YmxpYyBkYXRhOiBhbnksXHJcbiAgICAgICAgICAgICAgcHVibGljIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSkge1xyXG4gICAgZGlhbG9nUmVmLmRpc2FibGVDbG9zZSA9IHRydWU7XHJcbiAgfVxyXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXl1cC5lc2MnKSBvbktleVVwKCkge1xyXG4gICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UoKTtcclxuICB9XHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmFjdGlvbkxhYmVsID0gdGhpcy5kYXRhLmxhYmVsO1xyXG4gICAgdGhpcy5pc1Rlcm1pbmF0aW9uID0gdGhpcy5kYXRhLmlzVGVybWluYXRpb24gO1xyXG4gICAgdGhpcy5zaWduaW5nUmVxdWlyZWQgPSB0aGlzLmRhdGEuc2lnbmluZ1JlcXVpcmVkO1xyXG4gICAgdGhpcy50b2tlblJlZmVyZW5jZSA9IHRoaXMuZGF0YS50b2tlblJlZmVyZW5jZTtcclxuICAgIHRoaXMud2FybmluZ01zZyA9IHRoaXMuZGF0YS53YXJuaW5nTXNnIHx8IGZhbHNlO1xyXG5cclxuICAgIHRoaXMuaXRlbU5hbWUgPSB0aGlzLmRhdGEuaXRlbU5hbWU7XHJcbiAgICB0aGlzLnRpdGxlS2V5ID0gdGhpcy5kYXRhLnRpdGxlS2V5O1xyXG4gICAgdGhpcy5zdWJ0aXRsZUtleSA9IHRoaXMuZGF0YS5zdWJ0aXRsZUtleTtcclxuICAgIHRoaXMucmVhc29uTGFiZWxLZXkgPSB0aGlzLmRhdGEucmVhc29uTGFiZWxLZXk7XHJcbiAgICB0aGlzLnBsYWNlaG9sZGVyS2V5ID0gdGhpcy5kYXRhLnBsYWNlaG9sZGVyS2V5O1xyXG4gICAgdGhpcy53YXJuaW5nS2V5ID0gdGhpcy5kYXRhLndhcm5pbmdLZXk7XHJcbiAgICB0aGlzLmNhbmNlbEtleSA9IHRoaXMuZGF0YS5jYW5jZWxLZXk7XHJcbiAgICB0aGlzLmFjdGlvbktleSA9IHRoaXMuZGF0YS5hY3Rpb25LZXk7XHJcbiAgICB0aGlzLmN1cnJlbnREaXJlY3Rpb24gID0gdGhpcy5kYXRhLmRpcmVjdGlvbjtcclxuICB9XHJcblxyXG5cclxuICBjb21tZW50QW5kQ2xvc2UoKSB7XHJcbiAgICB0aGlzLmlzU3VibWl0dGVkID0gdHJ1ZTtcclxuXHJcbiAgICBpZiAodGhpcy5zaWduaW5nUmVxdWlyZWQgJiYgIXRoaXMub3RwKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBmaW5hbENvbW1lbnQgPVxyXG4gICAgICB0aGlzLmNvbW1lbnQgPT09ICdPVEhFUicgPyB0aGlzLm90aGVyQ29tbWVudCA6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQodGhpcy5jb21tZW50KTtcclxuXHJcbiAgICBjb25zdCBvYmo6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7XHJcbiAgICAgIGNvbW1lbnQ6IGZpbmFsQ29tbWVudCxcclxuICAgICAgc2hhcmVFeHRlcm5hbDogdGhpcy5leHRlcm5hbFxyXG4gICAgfTtcclxuXHJcbiAgICBpZiAodGhpcy5zaWduaW5nUmVxdWlyZWQpIHtcclxuICAgICAgb2JqWyd0b2tlbiddID0gdGhpcy5vdHA7XHJcbiAgICAgIG9ialsndG9rZW5SZWZlcmVuY2UnXSA9IHRoaXMudG9rZW5SZWZlcmVuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5kaWFsb2dSZWYuY2xvc2Uob2JqKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgY2FuY2VsKCkge1xyXG4gICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UoKTtcclxuICB9XHJcblxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJkaWFsb2ctY29udGFpbmVyXCIgW2Rpcl09XCJjdXJyZW50RGlyZWN0aW9uXCI+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJkZXNrdG9wLXZpZXdcIj5cclxuICAgIDxoMiBtYXQtZGlhbG9nLXRpdGxlIGNsYXNzPVwiZGlhbG9nLXRpdGxlXCI+XHJcbiAgICAgIHt7IHRpdGxlS2V5IHwgdHJhbnNsYXRlfX0ge3tpdGVtTmFtZX19XHJcbiAgICA8L2gyPlxyXG5cclxuICAgIDxwIGNsYXNzPVwiZGlhbG9nLXN1YnRpdGxlXCI+XHJcbiAgICAgIHt7IHN1YnRpdGxlS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICA8L3A+XHJcblxyXG4gICAgPG1hdC1kaWFsb2ctY29udGVudCBjbGFzcz1cImNvbnRlbnQtc2VjdGlvblwiPlxyXG5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGE/Lm9wdGlvbnM/Lmxlbmd0aDsgZWxzZSB0ZXh0TW9kZVwiPlxyXG5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInctMTAwXCI+XHJcbiAgICAgICAgICA8bWF0LWxhYmVsPnt7IHJlYXNvbkxhYmVsS2V5IHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNvbW1lbnRcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJLZXkgfCB0cmFuc2xhdGVcIj5cclxuXHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIGRhdGEub3B0aW9uc1wiIFt2YWx1ZV09XCJpdGVtXCI+XHJcbiAgICAgICAgICAgICAge3sgZGF0YS50cmFuc2xhdGUgPyAoaXRlbSB8IHRyYW5zbGF0ZSkgOiBpdGVtIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuXHJcbiAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgICAqbmdJZj1cImNvbW1lbnQgPT09ICdPVEhFUidcIlxyXG4gICAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgY2xhc3M9XCJ3LTEwMFwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyBwbGFjZWhvbGRlcktleSB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgPHRleHRhcmVhXHJcbiAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwib3RoZXJDb21tZW50XCJcclxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyS2V5IHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgY2RrVGV4dGFyZWFBdXRvc2l6ZVxyXG4gICAgICAgICAgICBjZGtBdXRvc2l6ZU1pblJvd3M9XCI0XCJcclxuICAgICAgICAgICAgbWF4bGVuZ3RoPVwiMTAwMFwiXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWF4Um93cz1cIjVcIj5cclxuICAgICAgICAgIDwvdGV4dGFyZWE+XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgPG5nLXRlbXBsYXRlICN0ZXh0TW9kZT5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInctMTAwXCI+XHJcbiAgICAgICAgICA8bWF0LWxhYmVsPnt7IHJlYXNvbkxhYmVsS2V5IHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICA8dGV4dGFyZWFcclxuICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJjb21tZW50XCJcclxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyS2V5IHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgY2RrVGV4dGFyZWFBdXRvc2l6ZVxyXG4gICAgICAgICAgICBjZGtBdXRvc2l6ZU1pblJvd3M9XCI0XCJcclxuICAgICAgICAgICAgbWF4bGVuZ3RoPVwiMTAwMFwiXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWF4Um93cz1cIjVcIj5cclxuICAgICAgICAgIDwvdGV4dGFyZWE+XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJpbmZvLWJveFwiPlxyXG4gICAgICAgIDxtYXQtaWNvbj5pbmZvPC9tYXQtaWNvbj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tdGV4dFwiPlxyXG4gICAgICAgICAge3sgd2FybmluZ0tleSB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICAgIDwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XHJcblxyXG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucyBhbGlnbj1cImVuZFwiIGNsYXNzPVwiZm9vdGVyLWFjdGlvbnNcIj5cclxuICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gY2xhc3M9XCJidG4tbm9uZS1iYWNrZ3JvdW5kLXByaW1hcnkgY2FuY2VsLWJ0blwiIChjbGljayk9XCJjYW5jZWwoKVwiPlxyXG4gICAgICAgIHt7IGNhbmNlbEtleSB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICA8L2J1dHRvbj5cclxuXHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBtYXQtZmxhdC1idXR0b25cclxuICAgICAgICBjbGFzcz1cImJ0bi1iYWNrZ3JvdW5kLXByaW1hcnkgd2Fybi1idG5cIlxyXG4gICAgICAgIChjbGljayk9XCJjb21tZW50QW5kQ2xvc2UoKVwiXHJcbiAgICAgICAgW2Rpc2FibGVkXT1cIiFjb21tZW50IHx8IChjb21tZW50ID09PSAnT1RIRVInICYmICFvdGhlckNvbW1lbnQpXCI+XHJcbiAgICAgICAge3sgYWN0aW9uS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJtb2JpbGUtdmlld1wiPlxyXG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udGVudFwiPlxyXG4gICAgICAgIDxwIGNsYXNzPVwibW9kYWwtdGl0bGVcIj57eyB0aXRsZUtleSB8IHRyYW5zbGF0ZSB9fTwvcD5cclxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY2xvc2UtYnV0dG9uXCIgKGNsaWNrKT1cImNhbmNlbCgpXCI+XHJcbiAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XHJcblxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGF0YT8ub3B0aW9ucz8ubGVuZ3RoOyBlbHNlIG1vYmlsZVRleHRcIj5cclxuXHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ0ZXh0YXJlYS1maWVsZC1tb2JpbGVcIj5cclxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgcmVhc29uTGFiZWxLZXkgfCB0cmFuc2xhdGUgfX0ge3sgaXRlbU5hbWUgfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgIDxtYXQtc2VsZWN0XHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29tbWVudFwiXHJcbiAgICAgICAgICAgIGNsYXNzPVwidGV4dGFyZWEtbW9iaWxlXCI+XHJcblxyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkYXRhLm9wdGlvbnNcIiBbdmFsdWVdPVwiaXRlbVwiPlxyXG4gICAgICAgICAgICAgIHt7IGRhdGEudHJhbnNsYXRlID8gKCBpdGVtIHwgdHJhbnNsYXRlKSA6IGl0ZW0gfX1cclxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG5cclxuICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICAgICpuZ0lmPVwiY29tbWVudCA9PT0gJ09USEVSJ1wiXHJcbiAgICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICBjbGFzcz1cInRleHRhcmVhLWZpZWxkLW1vYmlsZVwiPlxyXG4gICAgICAgICAgPG1hdC1sYWJlbD57eyBwbGFjZWhvbGRlcktleSB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgPHRleHRhcmVhXHJcbiAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwib3RoZXJDb21tZW50XCJcclxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyS2V5IHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgY2RrVGV4dGFyZWFBdXRvc2l6ZVxyXG4gICAgICAgICAgICBjZGtBdXRvc2l6ZU1pblJvd3M9XCI0XCJcclxuICAgICAgICAgICAgY2RrQXV0b3NpemVNYXhSb3dzPVwiNVwiXHJcbiAgICAgICAgICAgIG1heGxlbmd0aD1cIjEwMDBcIlxyXG4gICAgICAgICAgICBjbGFzcz1cInRleHRhcmVhLW1vYmlsZVwiPlxyXG4gICAgICAgICAgPC90ZXh0YXJlYT5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICA8bmctdGVtcGxhdGUgI21vYmlsZVRleHQ+XHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ0ZXh0YXJlYS1maWVsZC1tb2JpbGVcIj5cclxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgcmVhc29uTGFiZWxLZXkgfCB0cmFuc2xhdGUgfX0ge3sgaXRlbU5hbWUgfX08L21hdC1sYWJlbD5cclxuICAgICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cImNvbW1lbnRcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJLZXkgfCB0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICBjZGtUZXh0YXJlYUF1dG9zaXplXHJcbiAgICAgICAgICAgIGNka0F1dG9zaXplTWluUm93cz1cIjRcIlxyXG4gICAgICAgICAgICBjZGtBdXRvc2l6ZU1heFJvd3M9XCI1XCJcclxuICAgICAgICAgICAgbWF4bGVuZ3RoPVwiMTAwMFwiXHJcbiAgICAgICAgICAgIGNsYXNzPVwidGV4dGFyZWEtbW9iaWxlXCI+XHJcbiAgICAgICAgICA8L3RleHRhcmVhPlxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICA8ZGl2IGNsYXNzPVwiaW5mby1ib3gtbW9iaWxlXCI+XHJcbiAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiaW5mby1pY29uLW1vYmlsZVwiPmluZm88L21hdC1pY29uPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby10ZXh0LW1vYmlsZVwiPlxyXG4gICAgICAgICAge3sgd2FybmluZ0tleSB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICAgIDwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWFjdGlvbnMtbW9iaWxlXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLWJ1dHRvbnMtY29udGFpbmVyXCI+XHJcbiAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gY2xhc3M9XCJidG4tY2FuY2VsLW1vYmlsZVwiIChjbGljayk9XCJjYW5jZWwoKVwiPlxyXG4gICAgICAgICAge3sgY2FuY2VsS2V5IHwgdHJhbnNsYXRlIH19XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgbWF0LWZsYXQtYnV0dG9uXHJcbiAgICAgICAgICBjbGFzcz1cImJ0bi1hY3Rpb24tbW9iaWxlXCJcclxuICAgICAgICAgIChjbGljayk9XCJjb21tZW50QW5kQ2xvc2UoKVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiIWNvbW1lbnQgfHwgKGNvbW1lbnQgPT09ICdPVEhFUicgJiYgIW90aGVyQ29tbWVudClcIj5cclxuICAgICAgICAgIHt7IGFjdGlvbktleSB8IHRyYW5zbGF0ZSB9fVxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cImhvbWUtaW5kaWNhdG9yXCI+PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbjwvZGl2PlxyXG4iXX0=