@hestia-earth/ui-components 0.22.2 → 0.23.1

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.
@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2
2
  import { parse } from 'papaparse';
3
3
  import { SchemaType, NodeType, UploadLimit, isExpandable, typeToSchemaType } from '@hestia-earth/schema';
4
4
  import { maxFileSizeMb, SupportedExtensions } from '@hestia-earth/api';
5
- import { toCsv } from '@hestia-earth/schema-convert';
5
+ import { toCsv, ErrorKeys as SchemaErrorKeys } from '@hestia-earth/schema-convert';
6
6
  import { baseUrl } from '../../common';
7
7
  import { schemaBaseUrl } from '../../schema/schema.service';
8
8
  import * as i0 from "@angular/core";
@@ -24,16 +24,11 @@ export var ErrorKeys;
24
24
  ErrorKeys["InvalidFirstColumn"] = "invalid-first-column";
25
25
  ErrorKeys["DuplicatedHeaders"] = "duplicated-headers";
26
26
  ErrorKeys["DuplicatedIds"] = "duplicated-ids";
27
- ErrorKeys["DuplicatedIdFields"] = "duplicated-id-fields";
28
- ErrorKeys["PropertyInvalidFormat"] = "property-invalid-format";
29
- ErrorKeys["PropertyNotFound"] = "property-not-found";
30
27
  ErrorKeys["PropertyRequired"] = "property-required";
31
28
  ErrorKeys["PropertyInternal"] = "property-internal";
32
- ErrorKeys["SchemaNotFound"] = "schema-not-found";
33
29
  ErrorKeys["UploadsLimit"] = "upload-limit";
34
30
  ErrorKeys["NestedHeaders"] = "nested-headers";
35
31
  ErrorKeys["ReferenceExistingHeaders"] = "reference-existing-headers";
36
- ErrorKeys["ObjectArrayInvalid"] = "object-array-invalid";
37
32
  ErrorKeys["MaxSize"] = "max-size";
38
33
  ErrorKeys["MaxRows"] = "max-rows";
39
34
  })(ErrorKeys || (ErrorKeys = {}));
@@ -76,6 +71,7 @@ export class FilesUploadErrorsComponent {
76
71
  constructor() {
77
72
  this.baseUrl = baseUrl();
78
73
  this.nodeTypes = acceptedTypes;
74
+ this.SchemaErrorKeys = SchemaErrorKeys;
79
75
  this.ErrorKeys = ErrorKeys;
80
76
  this.UploadLimit = UploadLimit;
81
77
  this.maxFileSizeMb = maxFileSizeMb;
@@ -119,7 +115,7 @@ export class FilesUploadErrorsComponent {
119
115
  return [this.schemaUrl, this.error?.schemaKey || this.error?.key].filter(Boolean).join('#');
120
116
  }
121
117
  get isSchemaError() {
122
- return [ErrorKeys.PropertyNotFound, ErrorKeys.SchemaNotFound].includes(this.error?.message);
118
+ return [SchemaErrorKeys.PropertyNotFound, SchemaErrorKeys.SchemaNotFound].includes(this.error?.message);
123
119
  }
124
120
  get showCsvPreview() {
125
121
  return this.headers?.length && this.rows?.length && !this.isSchemaError && !this.isJSONFile;
@@ -128,14 +124,14 @@ export class FilesUploadErrorsComponent {
128
124
  return this.error?.node && this.isJSONFile;
129
125
  }
130
126
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: FilesUploadErrorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
131
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: FilesUploadErrorsComponent, selector: "he-files-upload-errors", inputs: { file: "file", error: "error" }, ngImport: i0, template: "<ng-container *ngIf=\"!!error\">\n <div class=\"has-text-danger\" [ngSwitch]=\"error?.message\">\n <div *ngSwitchCase=\"ErrorKeys.InvalidJSON\">\n <p>The uploaded content does not appear to contain valid JSON data:</p>\n\n <div class=\"is-mt-2\">\n <pre><code>{{error.error}}</code></pre>\n </div>\n\n <p>\n Please validate your JSON content before uploading it using an\n <a href=\"https://jsoneditoronline.org\" target=\"_blank\">online tool</a>\n for example.\n </p>\n </div>\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoData\">\n <p>No Nodes could be found in your Upload. Please verify the column headers match the Hestia schema.</p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyNotFound\">\n <div class=\"notification is-danger\" role=\"alert\">\n <p>\n <fa-icon class=\"pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>You have column headers that do not match the Hestia schema.</span>\n <span class=\"px-1\">Please refer to the</span>\n <a [href]=\"schemaUrl\" target=\"_blank\">schema</a>\n <span class=\"pl-1\">and then correct the column headers indicated below.</span>\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\">\n <pre><code>{{error.key}}</code></pre>\n </div>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInvalidFormat\">\n <div class=\"is-mb-2\">\n <span>\n The following value in the column\n <i>{{ error.key }}</i>\n is not in the correct format:\n </span>\n <br />\n <pre class=\"is-mt-2\"><code>{{stringify(error.value)}}</code></pre>\n </div>\n <ng-container [ngSwitch]=\"hasNumberWithCommasError\">\n <ng-container *ngSwitchCase=\"true\">\n <p class=\"is-mt-2\">\n Please format your numbers to remove commas and use a decimal point to separate the whole part of the number\n from the fractional part of the number.\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>3,510.1</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>3510.1</code></pre>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"false\">\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>The error could either be a value in the column, or an error with the column header.</p>\n <p>\n If you are trying to set no data, we accept either\n <code>-</code>\n or an empty cell.\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyRequired\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The following field is required in the</span>\n <a class=\"pr-1\" *ngIf=\"error.schema\" [href]=\"schemaUrl\" target=\"_blank\">{{ error.schema }}</a>\n <span>schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.property}}</code></pre>\n </div>\n <p [ngSwitch]=\"error.property\">\n <span *ngSwitchCase=\"'id'\">\n You must assign a unique\n <code>id</code>\n for every record in your data.\n </span>\n <span *ngSwitchCase=\"'type'\">\n Every record in your data must contain a\n <code>type</code>\n .\n </span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInternal\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">\n The following field is\n <code>internal</code>\n in the\n </span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schema }} schema</a>\n <span>:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.schemaKey || error.key}}</code></pre>\n </div>\n <p>\n You cannot upload\n <code>internal</code>\n fields to Hestia.\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.SchemaNotFound\">\n <div class=\"is-mb-2\">\n <span>The following Node does not exist in the schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.key}}</code></pre>\n </div>\n <p>\n <span>The list of accepted values is:</span>\n </p>\n <div class=\"content\">\n <ul>\n <li *ngFor=\"let type of nodeTypes\">\n <i>{{ type }}</i>\n </li>\n </ul>\n </div>\n </div>\n\n <ng-container *ngSwitchCase=\"ErrorKeys.UploadsLimit\">\n <div class=\"is-mb-2\">\n <span>You have reached the upload limit of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>\n {{ error.schema }} in a single file (\n <b>{{ error.value }}</b>\n have been found).\n </span>\n </div>\n\n <p>\n <span>Please re-upload these data in multiple files with a maximum of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>{{ error.schema }} in each file.</span>\n </p>\n </ng-container>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidFirstColumn\">\n <span>\n No data in the Hestia format was detected on the first sheet. Either try selecting a different sheet in the\n upload screen, or check the sheet to ensure the headers follow the schema - see examples\n </span>\n <a class=\"pl-1\" routerLink=\"/upload\" fragment=\"example\">here</a>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoHeaders\">\n <p>\n No headers matching the Hestia schema were found on the first row. Please remove all empty rows at the begining\n of the file and try uploading again.\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidSheetName\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The Excel sheet</span>\n <code>{{ error.value }}</code>\n <span class=\"pl-1\">does not exist.</span>\n <span class=\"pl-1\">Your Excel file contains the following sheets:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let e of error.error.split(';')\">\n <code>{{ e }}</code>\n </li>\n </ul>\n </div>\n\n <p>\n <span>Please re-upload selecting one of the sheets above.</span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedHeaders\">\n <span>Your upload contains duplicated column headers.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIds\">\n <span class=\"pr-1\">You have multiple</span>\n <code>{{ error.schema | pluralize }}</code>\n <span class=\"px-1\">with the same</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"px-1\">but different data. The</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"pl-1\">is:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.value}}</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIdFields\">\n <span class=\"is-pr-1\">You have used both the</span>\n <code>@id</code>\n <span class=\"is-px-1\">and</span>\n <code>id</code>\n <span class=\"is-px-1\">fields in the same data. Please use</span>\n <code>@id</code>\n <span class=\"is-px-1\">when linking to existing nodes on the Platform, and</span>\n <code>id</code>\n <span class=\"is-px-1\">when linking to nodes you are uploading in this file using the same</span>\n <code>id</code>\n <span class=\"is-px-1\">field.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NestedHeaders\">\n <p>\n To link nodes together, you first need to define the node (e.g.,\n <code>source.id</code>\n ,\n <code>source.bibliography.title</code>\n ) and then create the link (e.g.,\n <code>cycle.defaultSource.id</code>\n ). We do not allow nesting (e.g.,\n <code>cycle.defaultSource.bibliography.title</code>\n ).\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ReferenceExistingHeaders\">\n <p>\n You have used the internal\n <code>@id</code>\n field to upload a new Node.\n </p>\n <p>\n The\n <code>@id</code>\n field should only be used to reference existing Node or Terms. Example:\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>cycle.@id,cycle.inputs.0.term.@id,source.id</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>cycle.id,cycle.inputs.0.term.@id,source.id</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ObjectArrayInvalid\">\n <p>The values in the column {{ error.key }} must be represented as arrays.</p>\n\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>Examples:</p>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.value</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.value</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxSize\">\n <span>The maximum file size limit is {{ maxFileSizeMb }}Mb (current file size: {{ error.value }}Mb).</span>\n <span class=\"pl-1\">Please re-upload these data in multiple files.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxRows\">\n <span>\n Your file has {{ error.value | number }} rows. This might be an error caused by adding some data at the bottom\n of a spreadsheet by accident: delete any unused rows and resubmit the file.\n </span>\n </div>\n\n <div class=\"is-mb-2\" *ngIf=\"hasGeoJSONError\">\n <p>If the GeoJSON is too large, please try to simplify it following these steps:</p>\n <ul class=\"is-my-1 content is-list-style-decimal pl-5\">\n <li>\n <span class=\"is-pr-1\">Go to</span>\n <a href=\"https://mapshaper.org/\" target=\"_blank\">https://mapshaper.org/</a>\n </li>\n <li>\n <span>\n Save the boundary in a valid\n <code>.geojson</code>\n file.\n </span>\n </li>\n <li>\n <span>Import it on mapshaper.</span>\n </li>\n <li>\n <span>Click \"Simplify\" in the top right corner in the menu bar.</span>\n </li>\n <li>\n <span>Adjust the percentage to a lower value, like 50% to start with.</span>\n </li>\n <li>\n <span>\n Export to\n <code>GeoJson</code>\n or\n <code>CSV</code>\n .\n </span>\n </li>\n <li>\n <span>Copy the resulting content into your upload file.</span>\n </li>\n </ul>\n <p>If you encounter the error again, try again using a lower percentage at step 5.</p>\n </div>\n\n <div class=\"my-3\" *ngIf=\"columns.length || (error.index && !isSchemaError)\">\n <b>Hint:</b>\n <span class=\"pl-1\">the error might be located</span>\n <span class=\"pl-1\" *ngIf=\"error.index && !isSchemaError\">on row {{ error.index }}</span>\n <ng-container *ngIf=\"columns.length\">\n <span class=\"pl-1\">in {{ 'column' | pluralize: columns.length }}:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let column of columns\">\n <b class=\"pr-2\">{{ column.column }}</b>\n <code>{{ column.name }}</code>\n </li>\n </ul>\n </ng-container>\n </div>\n\n <div class=\"my-3\" *ngIf=\"error.suggestions?.length\">\n <b>Suggestions:</b>\n <span class=\"pl-1\">did you mean instead:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let suggestion of error.suggestions\">\n <code>{{ suggestion }}</code>\n </li>\n </ul>\n </div>\n\n <div *ngIf=\"showCsvPreview\" class=\"is-my-2\">\n <b>\n Preview\n <sup>1</sup>\n :\n </b>\n <div class=\"table-container is-mt-2\">\n <table class=\"table is-bordered is-fullwidth is-hoverable is-narrow mb-0\">\n <thead>\n <th *ngIf=\"error.index\"></th>\n <th *ngFor=\"let header of headers\">{{ header }}</th>\n </thead>\n <tbody>\n <ng-container *bindOnce=\"rows\">\n <tr *ngFor=\"let row of rows\">\n <td class=\"has-text-danger\" *ngIf=\"error.index\">\n <span class=\"is-nowrap\">Row {{ error.index }}</span>\n </td>\n <td *ngFor=\"let col of row; let colIndex = index\">\n <span\n [class.has-text-danger]=\"\n error?.message === ErrorKeys.DuplicatedIds && hasDuplicatedError(col, colIndex)\n \">\n {{ col | ellipsis: 50 }}\n </span>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n <p class=\"is-size-7\">\n <i>1. The preview does not necessarily reflect the original Upload's order or content.</i>\n </p>\n </div>\n\n <div *ngIf=\"showJsonPreview\" class=\"is-my-2\">\n <b>Preview:</b>\n <pre class=\"is-mt-2\"><code>{{stringify(error.node)}}</code></pre>\n </div>\n </div>\n</ng-container>\n\n<ng-template #defaultError>\n <p class=\"is-mt-2 has-text-black\">\n <span class=\"is-pr-1\">If you are still stuck, please see</span>\n <a [href]=\"baseUrl + '/upload#example'\" target=\"_blank\">the example uploads and videos</a>\n <span class=\"is-px-1\">\n or try using the Wizard to get the first few rows of data formatted correctly, or use the chat to ask for help.\n </span>\n </p>\n</ng-template>\n\n<ng-template #schemaError>\n <p>\n <span class=\"pr-1\">You can see the accepted field type and some examples</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">here</a>\n <span>.</span>\n </p>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i3.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i4.EllipsisPipe, name: "ellipsis" }, { kind: "pipe", type: i5.PluralizePipe, name: "pluralize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
127
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: FilesUploadErrorsComponent, selector: "he-files-upload-errors", inputs: { file: "file", error: "error" }, ngImport: i0, template: "<ng-container *ngIf=\"!!error\">\n <div class=\"has-text-danger\" [ngSwitch]=\"error?.message\">\n <div *ngSwitchCase=\"ErrorKeys.InvalidJSON\">\n <p>The uploaded content does not appear to contain valid JSON data:</p>\n\n <div class=\"is-mt-2\">\n <pre><code>{{error.error}}</code></pre>\n </div>\n\n <p>\n Please validate your JSON content before uploading it using an\n <a href=\"https://jsoneditoronline.org\" target=\"_blank\">online tool</a>\n for example.\n </p>\n </div>\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoData\">\n <p>No Nodes could be found in your Upload. Please verify the column headers match the Hestia schema.</p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.PropertyNotFound\">\n <div class=\"notification is-danger\" role=\"alert\">\n <p>\n <fa-icon class=\"pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>You have column headers that do not match the Hestia schema.</span>\n <span class=\"px-1\">Please refer to the</span>\n <a [href]=\"schemaUrl\" target=\"_blank\">schema</a>\n <span class=\"pl-1\">and then correct the column headers indicated below.</span>\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\">\n <pre><code>{{error.key}}</code></pre>\n </div>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.PropertyInvalidFormat\">\n <div class=\"is-mb-2\">\n <span>\n The following value in the column\n <i>{{ error.key }}</i>\n is not in the correct format:\n </span>\n <br />\n <pre class=\"is-mt-2\"><code>{{stringify(error.value)}}</code></pre>\n </div>\n <ng-container [ngSwitch]=\"hasNumberWithCommasError\">\n <ng-container *ngSwitchCase=\"true\">\n <p class=\"is-mt-2\">\n Please format your numbers to remove commas and use a decimal point to separate the whole part of the number\n from the fractional part of the number.\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>3,510.1</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>3510.1</code></pre>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"false\">\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>The error could either be a value in the column, or an error with the column header.</p>\n <p>\n If you are trying to set no data, we accept either\n <code>-</code>\n or an empty cell.\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyRequired\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The following field is required in the</span>\n <a class=\"pr-1\" *ngIf=\"error.schema\" [href]=\"schemaUrl\" target=\"_blank\">{{ error.schema }}</a>\n <span>schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.property}}</code></pre>\n </div>\n <p [ngSwitch]=\"error.property\">\n <span *ngSwitchCase=\"'id'\">\n You must assign a unique\n <code>id</code>\n for every record in your data.\n </span>\n <span *ngSwitchCase=\"'type'\">\n Every record in your data must contain a\n <code>type</code>\n .\n </span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInternal\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">\n The following field is\n <code>internal</code>\n in the\n </span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schema }} schema</a>\n <span>:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.schemaKey || error.key}}</code></pre>\n </div>\n <p>\n You cannot upload\n <code>internal</code>\n fields to Hestia.\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.SchemaNotFound\">\n <div class=\"is-mb-2\">\n <span>The following Node does not exist in the schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.key}}</code></pre>\n </div>\n <p>\n <span>The list of accepted values is:</span>\n </p>\n <div class=\"content\">\n <ul>\n <li *ngFor=\"let type of nodeTypes\">\n <i>{{ type }}</i>\n </li>\n </ul>\n </div>\n </div>\n\n <ng-container *ngSwitchCase=\"ErrorKeys.UploadsLimit\">\n <div class=\"is-mb-2\">\n <span>You have reached the upload limit of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>\n {{ error.schema }} in a single file (\n <b>{{ error.value }}</b>\n have been found).\n </span>\n </div>\n\n <p>\n <span>Please re-upload these data in multiple files with a maximum of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>{{ error.schema }} in each file.</span>\n </p>\n </ng-container>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidFirstColumn\">\n <span>\n No data in the Hestia format was detected on the first sheet. Either try selecting a different sheet in the\n upload screen, or check the sheet to ensure the headers follow the schema - see examples\n </span>\n <a class=\"pl-1\" routerLink=\"/upload\" fragment=\"example\">here</a>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoHeaders\">\n <p>\n No headers matching the Hestia schema were found on the first row. Please remove all empty rows at the begining\n of the file and try uploading again.\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidSheetName\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The Excel sheet</span>\n <code>{{ error.value }}</code>\n <span class=\"pl-1\">does not exist.</span>\n <span class=\"pl-1\">Your Excel file contains the following sheets:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let e of error.error.split(';')\">\n <code>{{ e }}</code>\n </li>\n </ul>\n </div>\n\n <p>\n <span>Please re-upload selecting one of the sheets above.</span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedHeaders\">\n <span>Your upload contains duplicated column headers.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIds\">\n <span class=\"pr-1\">You have multiple</span>\n <code>{{ error.schema | pluralize }}</code>\n <span class=\"px-1\">with the same</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"px-1\">but different data. The</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"pl-1\">is:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.value}}</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.DuplicatedIdFields\">\n <span class=\"is-pr-1\">You have used both the</span>\n <code>@id</code>\n <span class=\"is-px-1\">and</span>\n <code>id</code>\n <span class=\"is-px-1\">fields in the same data. Please use</span>\n <code>@id</code>\n <span class=\"is-px-1\">when linking to existing nodes on the Platform, and</span>\n <code>id</code>\n <span class=\"is-px-1\">when linking to nodes you are uploading in this file using the same</span>\n <code>id</code>\n <span class=\"is-px-1\">field.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NestedHeaders\">\n <p>\n To link nodes together, you first need to define the node (e.g.,\n <code>source.id</code>\n ,\n <code>source.bibliography.title</code>\n ) and then create the link (e.g.,\n <code>cycle.defaultSource.id</code>\n ). We do not allow nesting (e.g.,\n <code>cycle.defaultSource.bibliography.title</code>\n ).\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ReferenceExistingHeaders\">\n <p>\n You have used the internal\n <code>@id</code>\n field to upload a new Node.\n </p>\n <p>\n The\n <code>@id</code>\n field should only be used to reference existing Node or Terms. Example:\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>cycle.@id,cycle.inputs.0.term.@id,source.id</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>cycle.id,cycle.inputs.0.term.@id,source.id</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.ObjectArrayInvalid\">\n <p>The values in the column {{ error.key }} must be represented as arrays.</p>\n\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>Examples:</p>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.value</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.value</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxSize\">\n <span>The maximum file size limit is {{ maxFileSizeMb }}Mb (current file size: {{ error.value }}Mb).</span>\n <span class=\"pl-1\">Please re-upload these data in multiple files.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxRows\">\n <span>\n Your file has {{ error.value | number }} rows. This might be an error caused by adding some data at the bottom\n of a spreadsheet by accident: delete any unused rows and resubmit the file.\n </span>\n </div>\n\n <div class=\"is-mb-2\" *ngIf=\"hasGeoJSONError\">\n <p>If the GeoJSON is too large, please try to simplify it following these steps:</p>\n <ul class=\"is-my-1 content is-list-style-decimal pl-5\">\n <li>\n <span class=\"is-pr-1\">Go to</span>\n <a href=\"https://mapshaper.org/\" target=\"_blank\">https://mapshaper.org/</a>\n </li>\n <li>\n <span>\n Save the boundary in a valid\n <code>.geojson</code>\n file.\n </span>\n </li>\n <li>\n <span>Import it on mapshaper.</span>\n </li>\n <li>\n <span>Click \"Simplify\" in the top right corner in the menu bar.</span>\n </li>\n <li>\n <span>Adjust the percentage to a lower value, like 50% to start with.</span>\n </li>\n <li>\n <span>\n Export to\n <code>GeoJson</code>\n or\n <code>CSV</code>\n .\n </span>\n </li>\n <li>\n <span>Copy the resulting content into your upload file.</span>\n </li>\n </ul>\n <p>If you encounter the error again, try again using a lower percentage at step 5.</p>\n </div>\n\n <div class=\"my-3\" *ngIf=\"columns.length || (error.index && !isSchemaError)\">\n <b>Hint:</b>\n <span class=\"pl-1\">the error might be located</span>\n <span class=\"pl-1\" *ngIf=\"error.index && !isSchemaError\">on row {{ error.index }}</span>\n <ng-container *ngIf=\"columns.length\">\n <span class=\"pl-1\">in {{ 'column' | pluralize: columns.length }}:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let column of columns\">\n <b class=\"pr-2\">{{ column.column }}</b>\n <code>{{ column.name }}</code>\n </li>\n </ul>\n </ng-container>\n </div>\n\n <div class=\"my-3\" *ngIf=\"error.suggestions?.length\">\n <b>Suggestions:</b>\n <span class=\"pl-1\">did you mean instead:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let suggestion of error.suggestions\">\n <code>{{ suggestion }}</code>\n </li>\n </ul>\n </div>\n\n <div *ngIf=\"showCsvPreview\" class=\"is-my-2\">\n <b>\n Preview\n <sup>1</sup>\n :\n </b>\n <div class=\"table-container is-mt-2\">\n <table class=\"table is-bordered is-fullwidth is-hoverable is-narrow mb-0\">\n <thead>\n <th *ngIf=\"error.index\"></th>\n <th *ngFor=\"let header of headers\">{{ header }}</th>\n </thead>\n <tbody>\n <ng-container *bindOnce=\"rows\">\n <tr *ngFor=\"let row of rows\">\n <td class=\"has-text-danger\" *ngIf=\"error.index\">\n <span class=\"is-nowrap\">Row {{ error.index }}</span>\n </td>\n <td *ngFor=\"let col of row; let colIndex = index\">\n <span\n [class.has-text-danger]=\"\n error?.message === ErrorKeys.DuplicatedIds && hasDuplicatedError(col, colIndex)\n \">\n {{ col | ellipsis: 50 }}\n </span>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n <p class=\"is-size-7\">\n <i>1. The preview does not necessarily reflect the original Upload's order or content.</i>\n </p>\n </div>\n\n <div *ngIf=\"showJsonPreview\" class=\"is-my-2\">\n <b>Preview:</b>\n <pre class=\"is-mt-2\"><code>{{stringify(error.node)}}</code></pre>\n </div>\n </div>\n</ng-container>\n\n<ng-template #defaultError>\n <p class=\"is-mt-2 has-text-black\">\n <span class=\"is-pr-1\">If you are still stuck, please see</span>\n <a [href]=\"baseUrl + '/upload#example'\" target=\"_blank\">the example uploads and videos</a>\n <span class=\"is-px-1\">\n or try using the Wizard to get the first few rows of data formatted correctly, or use the chat to ask for help.\n </span>\n </p>\n</ng-template>\n\n<ng-template #schemaError>\n <p>\n <span class=\"pr-1\">You can see the accepted field type and some examples</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">here</a>\n <span>.</span>\n </p>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i3.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i4.EllipsisPipe, name: "ellipsis" }, { kind: "pipe", type: i5.PluralizePipe, name: "pluralize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
132
128
  }
133
129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: FilesUploadErrorsComponent, decorators: [{
134
130
  type: Component,
135
- args: [{ selector: 'he-files-upload-errors', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!!error\">\n <div class=\"has-text-danger\" [ngSwitch]=\"error?.message\">\n <div *ngSwitchCase=\"ErrorKeys.InvalidJSON\">\n <p>The uploaded content does not appear to contain valid JSON data:</p>\n\n <div class=\"is-mt-2\">\n <pre><code>{{error.error}}</code></pre>\n </div>\n\n <p>\n Please validate your JSON content before uploading it using an\n <a href=\"https://jsoneditoronline.org\" target=\"_blank\">online tool</a>\n for example.\n </p>\n </div>\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoData\">\n <p>No Nodes could be found in your Upload. Please verify the column headers match the Hestia schema.</p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyNotFound\">\n <div class=\"notification is-danger\" role=\"alert\">\n <p>\n <fa-icon class=\"pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>You have column headers that do not match the Hestia schema.</span>\n <span class=\"px-1\">Please refer to the</span>\n <a [href]=\"schemaUrl\" target=\"_blank\">schema</a>\n <span class=\"pl-1\">and then correct the column headers indicated below.</span>\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\">\n <pre><code>{{error.key}}</code></pre>\n </div>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInvalidFormat\">\n <div class=\"is-mb-2\">\n <span>\n The following value in the column\n <i>{{ error.key }}</i>\n is not in the correct format:\n </span>\n <br />\n <pre class=\"is-mt-2\"><code>{{stringify(error.value)}}</code></pre>\n </div>\n <ng-container [ngSwitch]=\"hasNumberWithCommasError\">\n <ng-container *ngSwitchCase=\"true\">\n <p class=\"is-mt-2\">\n Please format your numbers to remove commas and use a decimal point to separate the whole part of the number\n from the fractional part of the number.\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>3,510.1</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>3510.1</code></pre>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"false\">\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>The error could either be a value in the column, or an error with the column header.</p>\n <p>\n If you are trying to set no data, we accept either\n <code>-</code>\n or an empty cell.\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyRequired\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The following field is required in the</span>\n <a class=\"pr-1\" *ngIf=\"error.schema\" [href]=\"schemaUrl\" target=\"_blank\">{{ error.schema }}</a>\n <span>schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.property}}</code></pre>\n </div>\n <p [ngSwitch]=\"error.property\">\n <span *ngSwitchCase=\"'id'\">\n You must assign a unique\n <code>id</code>\n for every record in your data.\n </span>\n <span *ngSwitchCase=\"'type'\">\n Every record in your data must contain a\n <code>type</code>\n .\n </span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInternal\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">\n The following field is\n <code>internal</code>\n in the\n </span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schema }} schema</a>\n <span>:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.schemaKey || error.key}}</code></pre>\n </div>\n <p>\n You cannot upload\n <code>internal</code>\n fields to Hestia.\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.SchemaNotFound\">\n <div class=\"is-mb-2\">\n <span>The following Node does not exist in the schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.key}}</code></pre>\n </div>\n <p>\n <span>The list of accepted values is:</span>\n </p>\n <div class=\"content\">\n <ul>\n <li *ngFor=\"let type of nodeTypes\">\n <i>{{ type }}</i>\n </li>\n </ul>\n </div>\n </div>\n\n <ng-container *ngSwitchCase=\"ErrorKeys.UploadsLimit\">\n <div class=\"is-mb-2\">\n <span>You have reached the upload limit of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>\n {{ error.schema }} in a single file (\n <b>{{ error.value }}</b>\n have been found).\n </span>\n </div>\n\n <p>\n <span>Please re-upload these data in multiple files with a maximum of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>{{ error.schema }} in each file.</span>\n </p>\n </ng-container>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidFirstColumn\">\n <span>\n No data in the Hestia format was detected on the first sheet. Either try selecting a different sheet in the\n upload screen, or check the sheet to ensure the headers follow the schema - see examples\n </span>\n <a class=\"pl-1\" routerLink=\"/upload\" fragment=\"example\">here</a>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoHeaders\">\n <p>\n No headers matching the Hestia schema were found on the first row. Please remove all empty rows at the begining\n of the file and try uploading again.\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidSheetName\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The Excel sheet</span>\n <code>{{ error.value }}</code>\n <span class=\"pl-1\">does not exist.</span>\n <span class=\"pl-1\">Your Excel file contains the following sheets:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let e of error.error.split(';')\">\n <code>{{ e }}</code>\n </li>\n </ul>\n </div>\n\n <p>\n <span>Please re-upload selecting one of the sheets above.</span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedHeaders\">\n <span>Your upload contains duplicated column headers.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIds\">\n <span class=\"pr-1\">You have multiple</span>\n <code>{{ error.schema | pluralize }}</code>\n <span class=\"px-1\">with the same</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"px-1\">but different data. The</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"pl-1\">is:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.value}}</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIdFields\">\n <span class=\"is-pr-1\">You have used both the</span>\n <code>@id</code>\n <span class=\"is-px-1\">and</span>\n <code>id</code>\n <span class=\"is-px-1\">fields in the same data. Please use</span>\n <code>@id</code>\n <span class=\"is-px-1\">when linking to existing nodes on the Platform, and</span>\n <code>id</code>\n <span class=\"is-px-1\">when linking to nodes you are uploading in this file using the same</span>\n <code>id</code>\n <span class=\"is-px-1\">field.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NestedHeaders\">\n <p>\n To link nodes together, you first need to define the node (e.g.,\n <code>source.id</code>\n ,\n <code>source.bibliography.title</code>\n ) and then create the link (e.g.,\n <code>cycle.defaultSource.id</code>\n ). We do not allow nesting (e.g.,\n <code>cycle.defaultSource.bibliography.title</code>\n ).\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ReferenceExistingHeaders\">\n <p>\n You have used the internal\n <code>@id</code>\n field to upload a new Node.\n </p>\n <p>\n The\n <code>@id</code>\n field should only be used to reference existing Node or Terms. Example:\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>cycle.@id,cycle.inputs.0.term.@id,source.id</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>cycle.id,cycle.inputs.0.term.@id,source.id</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ObjectArrayInvalid\">\n <p>The values in the column {{ error.key }} must be represented as arrays.</p>\n\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>Examples:</p>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.value</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.value</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxSize\">\n <span>The maximum file size limit is {{ maxFileSizeMb }}Mb (current file size: {{ error.value }}Mb).</span>\n <span class=\"pl-1\">Please re-upload these data in multiple files.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxRows\">\n <span>\n Your file has {{ error.value | number }} rows. This might be an error caused by adding some data at the bottom\n of a spreadsheet by accident: delete any unused rows and resubmit the file.\n </span>\n </div>\n\n <div class=\"is-mb-2\" *ngIf=\"hasGeoJSONError\">\n <p>If the GeoJSON is too large, please try to simplify it following these steps:</p>\n <ul class=\"is-my-1 content is-list-style-decimal pl-5\">\n <li>\n <span class=\"is-pr-1\">Go to</span>\n <a href=\"https://mapshaper.org/\" target=\"_blank\">https://mapshaper.org/</a>\n </li>\n <li>\n <span>\n Save the boundary in a valid\n <code>.geojson</code>\n file.\n </span>\n </li>\n <li>\n <span>Import it on mapshaper.</span>\n </li>\n <li>\n <span>Click \"Simplify\" in the top right corner in the menu bar.</span>\n </li>\n <li>\n <span>Adjust the percentage to a lower value, like 50% to start with.</span>\n </li>\n <li>\n <span>\n Export to\n <code>GeoJson</code>\n or\n <code>CSV</code>\n .\n </span>\n </li>\n <li>\n <span>Copy the resulting content into your upload file.</span>\n </li>\n </ul>\n <p>If you encounter the error again, try again using a lower percentage at step 5.</p>\n </div>\n\n <div class=\"my-3\" *ngIf=\"columns.length || (error.index && !isSchemaError)\">\n <b>Hint:</b>\n <span class=\"pl-1\">the error might be located</span>\n <span class=\"pl-1\" *ngIf=\"error.index && !isSchemaError\">on row {{ error.index }}</span>\n <ng-container *ngIf=\"columns.length\">\n <span class=\"pl-1\">in {{ 'column' | pluralize: columns.length }}:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let column of columns\">\n <b class=\"pr-2\">{{ column.column }}</b>\n <code>{{ column.name }}</code>\n </li>\n </ul>\n </ng-container>\n </div>\n\n <div class=\"my-3\" *ngIf=\"error.suggestions?.length\">\n <b>Suggestions:</b>\n <span class=\"pl-1\">did you mean instead:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let suggestion of error.suggestions\">\n <code>{{ suggestion }}</code>\n </li>\n </ul>\n </div>\n\n <div *ngIf=\"showCsvPreview\" class=\"is-my-2\">\n <b>\n Preview\n <sup>1</sup>\n :\n </b>\n <div class=\"table-container is-mt-2\">\n <table class=\"table is-bordered is-fullwidth is-hoverable is-narrow mb-0\">\n <thead>\n <th *ngIf=\"error.index\"></th>\n <th *ngFor=\"let header of headers\">{{ header }}</th>\n </thead>\n <tbody>\n <ng-container *bindOnce=\"rows\">\n <tr *ngFor=\"let row of rows\">\n <td class=\"has-text-danger\" *ngIf=\"error.index\">\n <span class=\"is-nowrap\">Row {{ error.index }}</span>\n </td>\n <td *ngFor=\"let col of row; let colIndex = index\">\n <span\n [class.has-text-danger]=\"\n error?.message === ErrorKeys.DuplicatedIds && hasDuplicatedError(col, colIndex)\n \">\n {{ col | ellipsis: 50 }}\n </span>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n <p class=\"is-size-7\">\n <i>1. The preview does not necessarily reflect the original Upload's order or content.</i>\n </p>\n </div>\n\n <div *ngIf=\"showJsonPreview\" class=\"is-my-2\">\n <b>Preview:</b>\n <pre class=\"is-mt-2\"><code>{{stringify(error.node)}}</code></pre>\n </div>\n </div>\n</ng-container>\n\n<ng-template #defaultError>\n <p class=\"is-mt-2 has-text-black\">\n <span class=\"is-pr-1\">If you are still stuck, please see</span>\n <a [href]=\"baseUrl + '/upload#example'\" target=\"_blank\">the example uploads and videos</a>\n <span class=\"is-px-1\">\n or try using the Wizard to get the first few rows of data formatted correctly, or use the chat to ask for help.\n </span>\n </p>\n</ng-template>\n\n<ng-template #schemaError>\n <p>\n <span class=\"pr-1\">You can see the accepted field type and some examples</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">here</a>\n <span>.</span>\n </p>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
131
+ args: [{ selector: 'he-files-upload-errors', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!!error\">\n <div class=\"has-text-danger\" [ngSwitch]=\"error?.message\">\n <div *ngSwitchCase=\"ErrorKeys.InvalidJSON\">\n <p>The uploaded content does not appear to contain valid JSON data:</p>\n\n <div class=\"is-mt-2\">\n <pre><code>{{error.error}}</code></pre>\n </div>\n\n <p>\n Please validate your JSON content before uploading it using an\n <a href=\"https://jsoneditoronline.org\" target=\"_blank\">online tool</a>\n for example.\n </p>\n </div>\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoData\">\n <p>No Nodes could be found in your Upload. Please verify the column headers match the Hestia schema.</p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.PropertyNotFound\">\n <div class=\"notification is-danger\" role=\"alert\">\n <p>\n <fa-icon class=\"pr-2\" icon=\"exclamation-triangle\"></fa-icon>\n <span>You have column headers that do not match the Hestia schema.</span>\n <span class=\"px-1\">Please refer to the</span>\n <a [href]=\"schemaUrl\" target=\"_blank\">schema</a>\n <span class=\"pl-1\">and then correct the column headers indicated below.</span>\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\">\n <pre><code>{{error.key}}</code></pre>\n </div>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.PropertyInvalidFormat\">\n <div class=\"is-mb-2\">\n <span>\n The following value in the column\n <i>{{ error.key }}</i>\n is not in the correct format:\n </span>\n <br />\n <pre class=\"is-mt-2\"><code>{{stringify(error.value)}}</code></pre>\n </div>\n <ng-container [ngSwitch]=\"hasNumberWithCommasError\">\n <ng-container *ngSwitchCase=\"true\">\n <p class=\"is-mt-2\">\n Please format your numbers to remove commas and use a decimal point to separate the whole part of the number\n from the fractional part of the number.\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>3,510.1</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>3510.1</code></pre>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"false\">\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>The error could either be a value in the column, or an error with the column header.</p>\n <p>\n If you are trying to set no data, we accept either\n <code>-</code>\n or an empty cell.\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyRequired\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The following field is required in the</span>\n <a class=\"pr-1\" *ngIf=\"error.schema\" [href]=\"schemaUrl\" target=\"_blank\">{{ error.schema }}</a>\n <span>schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.property}}</code></pre>\n </div>\n <p [ngSwitch]=\"error.property\">\n <span *ngSwitchCase=\"'id'\">\n You must assign a unique\n <code>id</code>\n for every record in your data.\n </span>\n <span *ngSwitchCase=\"'type'\">\n Every record in your data must contain a\n <code>type</code>\n .\n </span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.PropertyInternal\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">\n The following field is\n <code>internal</code>\n in the\n </span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schema }} schema</a>\n <span>:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.schemaKey || error.key}}</code></pre>\n </div>\n <p>\n You cannot upload\n <code>internal</code>\n fields to Hestia.\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.SchemaNotFound\">\n <div class=\"is-mb-2\">\n <span>The following Node does not exist in the schema:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.key}}</code></pre>\n </div>\n <p>\n <span>The list of accepted values is:</span>\n </p>\n <div class=\"content\">\n <ul>\n <li *ngFor=\"let type of nodeTypes\">\n <i>{{ type }}</i>\n </li>\n </ul>\n </div>\n </div>\n\n <ng-container *ngSwitchCase=\"ErrorKeys.UploadsLimit\">\n <div class=\"is-mb-2\">\n <span>You have reached the upload limit of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>\n {{ error.schema }} in a single file (\n <b>{{ error.value }}</b>\n have been found).\n </span>\n </div>\n\n <p>\n <span>Please re-upload these data in multiple files with a maximum of</span>\n <code class=\"mx-1\">{{ UploadLimit[error.schema] }}</code>\n <span>{{ error.schema }} in each file.</span>\n </p>\n </ng-container>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidFirstColumn\">\n <span>\n No data in the Hestia format was detected on the first sheet. Either try selecting a different sheet in the\n upload screen, or check the sheet to ensure the headers follow the schema - see examples\n </span>\n <a class=\"pl-1\" routerLink=\"/upload\" fragment=\"example\">here</a>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NoHeaders\">\n <p>\n No headers matching the Hestia schema were found on the first row. Please remove all empty rows at the begining\n of the file and try uploading again.\n </p>\n\n <ng-container *ngTemplateOutlet=\"defaultError\"></ng-container>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.InvalidSheetName\">\n <div class=\"is-mb-2\">\n <span class=\"pr-1\">The Excel sheet</span>\n <code>{{ error.value }}</code>\n <span class=\"pl-1\">does not exist.</span>\n <span class=\"pl-1\">Your Excel file contains the following sheets:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let e of error.error.split(';')\">\n <code>{{ e }}</code>\n </li>\n </ul>\n </div>\n\n <p>\n <span>Please re-upload selecting one of the sheets above.</span>\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedHeaders\">\n <span>Your upload contains duplicated column headers.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.DuplicatedIds\">\n <span class=\"pr-1\">You have multiple</span>\n <code>{{ error.schema | pluralize }}</code>\n <span class=\"px-1\">with the same</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"px-1\">but different data. The</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">{{ error.schemaKey }}</a>\n <span class=\"pl-1\">is:</span>\n <br />\n <pre class=\"is-mt-2\"><code>{{error.value}}</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.DuplicatedIdFields\">\n <span class=\"is-pr-1\">You have used both the</span>\n <code>@id</code>\n <span class=\"is-px-1\">and</span>\n <code>id</code>\n <span class=\"is-px-1\">fields in the same data. Please use</span>\n <code>@id</code>\n <span class=\"is-px-1\">when linking to existing nodes on the Platform, and</span>\n <code>id</code>\n <span class=\"is-px-1\">when linking to nodes you are uploading in this file using the same</span>\n <code>id</code>\n <span class=\"is-px-1\">field.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.NestedHeaders\">\n <p>\n To link nodes together, you first need to define the node (e.g.,\n <code>source.id</code>\n ,\n <code>source.bibliography.title</code>\n ) and then create the link (e.g.,\n <code>cycle.defaultSource.id</code>\n ). We do not allow nesting (e.g.,\n <code>cycle.defaultSource.bibliography.title</code>\n ).\n </p>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.ReferenceExistingHeaders\">\n <p>\n You have used the internal\n <code>@id</code>\n field to upload a new Node.\n </p>\n <p>\n The\n <code>@id</code>\n field should only be used to reference existing Node or Terms. Example:\n </p>\n\n <p class=\"is-mt-2 has-text-danger has-text-underline\">Incorrect:</p>\n <pre class=\"is-mt-2\"><code>cycle.@id,cycle.inputs.0.term.@id,source.id</code></pre>\n\n <p class=\"is-mt-2 has-text-success has-text-underline\">Correct:</p>\n <pre class=\"is-mt-2\"><code>cycle.id,cycle.inputs.0.term.@id,source.id</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"SchemaErrorKeys.ObjectArrayInvalid\">\n <p>The values in the column {{ error.key }} must be represented as arrays.</p>\n\n <ng-container *ngTemplateOutlet=\"schemaError\"></ng-container>\n\n <p>Examples:</p>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.0.value</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.term.name</code></pre>\n <pre class=\"is-mt-2\"><code>{{error.key}}.1.value</code></pre>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxSize\">\n <span>The maximum file size limit is {{ maxFileSizeMb }}Mb (current file size: {{ error.value }}Mb).</span>\n <span class=\"pl-1\">Please re-upload these data in multiple files.</span>\n </div>\n\n <div class=\"is-mb-2\" *ngSwitchCase=\"ErrorKeys.MaxRows\">\n <span>\n Your file has {{ error.value | number }} rows. This might be an error caused by adding some data at the bottom\n of a spreadsheet by accident: delete any unused rows and resubmit the file.\n </span>\n </div>\n\n <div class=\"is-mb-2\" *ngIf=\"hasGeoJSONError\">\n <p>If the GeoJSON is too large, please try to simplify it following these steps:</p>\n <ul class=\"is-my-1 content is-list-style-decimal pl-5\">\n <li>\n <span class=\"is-pr-1\">Go to</span>\n <a href=\"https://mapshaper.org/\" target=\"_blank\">https://mapshaper.org/</a>\n </li>\n <li>\n <span>\n Save the boundary in a valid\n <code>.geojson</code>\n file.\n </span>\n </li>\n <li>\n <span>Import it on mapshaper.</span>\n </li>\n <li>\n <span>Click \"Simplify\" in the top right corner in the menu bar.</span>\n </li>\n <li>\n <span>Adjust the percentage to a lower value, like 50% to start with.</span>\n </li>\n <li>\n <span>\n Export to\n <code>GeoJson</code>\n or\n <code>CSV</code>\n .\n </span>\n </li>\n <li>\n <span>Copy the resulting content into your upload file.</span>\n </li>\n </ul>\n <p>If you encounter the error again, try again using a lower percentage at step 5.</p>\n </div>\n\n <div class=\"my-3\" *ngIf=\"columns.length || (error.index && !isSchemaError)\">\n <b>Hint:</b>\n <span class=\"pl-1\">the error might be located</span>\n <span class=\"pl-1\" *ngIf=\"error.index && !isSchemaError\">on row {{ error.index }}</span>\n <ng-container *ngIf=\"columns.length\">\n <span class=\"pl-1\">in {{ 'column' | pluralize: columns.length }}:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let column of columns\">\n <b class=\"pr-2\">{{ column.column }}</b>\n <code>{{ column.name }}</code>\n </li>\n </ul>\n </ng-container>\n </div>\n\n <div class=\"my-3\" *ngIf=\"error.suggestions?.length\">\n <b>Suggestions:</b>\n <span class=\"pl-1\">did you mean instead:</span>\n <ul class=\"mt-1 content is-list-style-disc pl-5\">\n <li *ngFor=\"let suggestion of error.suggestions\">\n <code>{{ suggestion }}</code>\n </li>\n </ul>\n </div>\n\n <div *ngIf=\"showCsvPreview\" class=\"is-my-2\">\n <b>\n Preview\n <sup>1</sup>\n :\n </b>\n <div class=\"table-container is-mt-2\">\n <table class=\"table is-bordered is-fullwidth is-hoverable is-narrow mb-0\">\n <thead>\n <th *ngIf=\"error.index\"></th>\n <th *ngFor=\"let header of headers\">{{ header }}</th>\n </thead>\n <tbody>\n <ng-container *bindOnce=\"rows\">\n <tr *ngFor=\"let row of rows\">\n <td class=\"has-text-danger\" *ngIf=\"error.index\">\n <span class=\"is-nowrap\">Row {{ error.index }}</span>\n </td>\n <td *ngFor=\"let col of row; let colIndex = index\">\n <span\n [class.has-text-danger]=\"\n error?.message === ErrorKeys.DuplicatedIds && hasDuplicatedError(col, colIndex)\n \">\n {{ col | ellipsis: 50 }}\n </span>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n <p class=\"is-size-7\">\n <i>1. The preview does not necessarily reflect the original Upload's order or content.</i>\n </p>\n </div>\n\n <div *ngIf=\"showJsonPreview\" class=\"is-my-2\">\n <b>Preview:</b>\n <pre class=\"is-mt-2\"><code>{{stringify(error.node)}}</code></pre>\n </div>\n </div>\n</ng-container>\n\n<ng-template #defaultError>\n <p class=\"is-mt-2 has-text-black\">\n <span class=\"is-pr-1\">If you are still stuck, please see</span>\n <a [href]=\"baseUrl + '/upload#example'\" target=\"_blank\">the example uploads and videos</a>\n <span class=\"is-px-1\">\n or try using the Wizard to get the first few rows of data formatted correctly, or use the chat to ask for help.\n </span>\n </p>\n</ng-template>\n\n<ng-template #schemaError>\n <p>\n <span class=\"pr-1\">You can see the accepted field type and some examples</span>\n <a [href]=\"schemaKeyUrl\" target=\"_blank\">here</a>\n <span>.</span>\n </p>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
136
132
  }], propDecorators: { file: [{
137
133
  type: Input
138
134
  }], error: [{
139
135
  type: Input
140
136
  }] } });
141
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXMtdXBsb2FkLWVycm9ycy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmlsZXMvZmlsZXMtdXBsb2FkLWVycm9ycy9maWxlcy11cGxvYWQtZXJyb3JzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3NyYy9maWxlcy9maWxlcy11cGxvYWQtZXJyb3JzL2ZpbGVzLXVwbG9hZC1lcnJvcnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEYsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsVUFBVSxFQUNWLFFBQVEsRUFFUixXQUFXLEVBQ1gsWUFBWSxFQUNaLGdCQUFnQixFQUNqQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBUSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFckQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7Ozs7Ozs7QUFFNUQsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLElBQWMsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUVuRyxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztLQUMxQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssUUFBUSxDQUFDLElBQUksQ0FBQztL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Q0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFRCxJQUFXLGFBQWE7UUFDdEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVELElBQVcsY0FBYztRQUN2QixPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDOUYsQ0FBQztJQUVELElBQVcsZUFBZTtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDN0MsQ0FBQzs4R0F0RVUsMEJBQTBCO2tHQUExQiwwQkFBMEIsd0dDbkh2Qyxnd2RBK1lBOzsyRkQ1UmEsMEJBQTBCO2tCQU50QyxTQUFTOytCQUNFLHdCQUF3QixtQkFHakIsdUJBQXVCLENBQUMsTUFBTTs4QkFJdkMsSUFBSTtzQkFEWCxLQUFLO2dCQUdDLEtBQUs7c0JBRFgsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSAncGFwYXBhcnNlJztcbmltcG9ydCB7XG4gIFNjaGVtYVR5cGUsXG4gIE5vZGVUeXBlLFxuICBKU09OIGFzIEhlc3RpYUpzb24sXG4gIFVwbG9hZExpbWl0LFxuICBpc0V4cGFuZGFibGUsXG4gIHR5cGVUb1NjaGVtYVR5cGVcbn0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsgRmlsZSwgbWF4RmlsZVNpemVNYiwgU3VwcG9ydGVkRXh0ZW5zaW9ucyB9IGZyb20gJ0BoZXN0aWEtZWFydGgvYXBpJztcbmltcG9ydCB7IHRvQ3N2IH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEtY29udmVydCc7XG5cbmltcG9ydCB7IGJhc2VVcmwgfSBmcm9tICcuLi8uLi9jb21tb24nO1xuaW1wb3J0IHsgc2NoZW1hQmFzZVVybCB9IGZyb20gJy4uLy4uL3NjaGVtYS9zY2hlbWEuc2VydmljZSc7XG5cbmNvbnN0IG5vZGVUeXBlVG9TdHJpbmcgPSAodHlwZTogTm9kZVR5cGUpID0+IGAke3R5cGUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCl9JHt0eXBlLnN1YnN0cmluZygxKX1gO1xuXG5jb25zdCBhY2NlcHRlZFR5cGVzID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSlcbiAgLmZpbHRlcih2YWwgPT4gdmFsICE9PSBOb2RlVHlwZS5UZXJtKVxuICAubWFwKG5vZGVUeXBlVG9TdHJpbmcpO1xuXG5leHBvcnQgZW51bSBFcnJvcktleXMge1xuICBOb0RhdGEgPSAnbm8tZGF0YScsXG4gIE5vSGVhZGVycyA9ICduby1oZWFkZXJzJyxcbiAgSW52YWxpZEpTT04gPSAnaW52YWxpZC1qc29uJyxcbiAgSW52YWxpZFNoZWV0TmFtZSA9ICdpbnZhbGlkLXNoZWV0LW5hbWUnLFxuICBJbnZhbGlkRmlyc3RDb2x1bW4gPSAnaW52YWxpZC1maXJzdC1jb2x1bW4nLFxuICBEdXBsaWNhdGVkSGVhZGVycyA9ICdkdXBsaWNhdGVkLWhlYWRlcnMnLFxuICBEdXBsaWNhdGVkSWRzID0gJ2R1cGxpY2F0ZWQtaWRzJyxcbiAgRHVwbGljYXRlZElkRmllbGRzID0gJ2R1cGxpY2F0ZWQtaWQtZmllbGRzJyxcbiAgUHJvcGVydHlJbnZhbGlkRm9ybWF0ID0gJ3Byb3BlcnR5LWludmFsaWQtZm9ybWF0JyxcbiAgUHJvcGVydHlOb3RGb3VuZCA9ICdwcm9wZXJ0eS1ub3QtZm91bmQnLFxuICBQcm9wZXJ0eVJlcXVpcmVkID0gJ3Byb3BlcnR5LXJlcXVpcmVkJyxcbiAgUHJvcGVydHlJbnRlcm5hbCA9ICdwcm9wZXJ0eS1pbnRlcm5hbCcsXG4gIFNjaGVtYU5vdEZvdW5kID0gJ3NjaGVtYS1ub3QtZm91bmQnLFxuICBVcGxvYWRzTGltaXQgPSAndXBsb2FkLWxpbWl0JyxcbiAgTmVzdGVkSGVhZGVycyA9ICduZXN0ZWQtaGVhZGVycycsXG4gIFJlZmVyZW5jZUV4aXN0aW5nSGVhZGVycyA9ICdyZWZlcmVuY2UtZXhpc3RpbmctaGVhZGVycycsXG4gIE9iamVjdEFycmF5SW52YWxpZCA9ICdvYmplY3QtYXJyYXktaW52YWxpZCcsXG4gIE1heFNpemUgPSAnbWF4LXNpemUnLFxuICBNYXhSb3dzID0gJ21heC1yb3dzJ1xufVxuXG5pbnRlcmZhY2UgSUNTVkhlYWRlciB7XG4gIG5hbWU6IHN0cmluZztcbiAgaW5kZXg6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIElDU1ZDb2x1bW4gZXh0ZW5kcyBJQ1NWSGVhZGVyIHtcbiAgY29sdW1uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUVycm9yIHtcbiAgbWVzc2FnZTogRXJyb3JLZXlzO1xuICBzY2hlbWE/OiBTY2hlbWFUeXBlO1xuICBzY2hlbWFLZXk/OiBzdHJpbmc7XG4gIGtleT86IHN0cmluZztcbiAgcHJvcGVydHk/OiBzdHJpbmc7XG4gIHZhbHVlPzogYW55O1xuICBtaW4/OiBhbnk7XG4gIG1heD86IGFueTtcbiAgZXJyb3I/OiBzdHJpbmc7XG4gIG5vZGU/OiBIZXN0aWFKc29uPFNjaGVtYVR5cGU+O1xuICBpbmRleD86IG51bWJlcjtcbiAgaGVhZGVycz86IElDU1ZIZWFkZXJbXTtcbiAgc3VnZ2VzdGlvbnM/OiBzdHJpbmdbXTtcbn1cblxuY29uc3QgdmFsdWVUb05vZGVzID0gKHZhbHVlOiBhbnksIHR5cGU6IFNjaGVtYVR5cGUpID0+XG4gIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgPyBpc0V4cGFuZGFibGUodmFsdWUpXG4gICAgICA/IHZhbHVlLm1hcCh2YWwgPT4gKHtcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIC4uLnZhbFxuICAgICAgICB9KSlcbiAgICAgIDogbnVsbFxuICAgIDogdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuICAgID8gW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICAuLi52YWx1ZVxuICAgICAgICB9XG4gICAgICBdXG4gICAgOiBudWxsO1xuXG5jb25zdCBub2Rlc0Zyb21FcnJvciA9IChlcnJvcj86IElFcnJvciwgdHlwZT86IFNjaGVtYVR5cGUpID0+XG4gIGVycm9yID8gdmFsdWVUb05vZGVzKGVycm9yLm5vZGUsIHR5cGUpIHx8IHZhbHVlVG9Ob2RlcyhlcnJvci52YWx1ZSwgZXJyb3Iuc2NoZW1hKSB8fCBbXSA6IFtdO1xuXG5jb25zdCBlcnJvckNzdiA9IG5vZGVzID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdG9Dc3Yobm9kZXMsIHsgaW5jbHVkZUV4aXNpbmc6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKF9lcnIpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbn07XG5cbmNvbnN0IG51bWJlclRvQ29sID0gKG51bTogbnVtYmVyKSA9PiB7XG4gIGxldCB0b3RhbCA9IG51bSArIDE7IC8vIHN0YXJ0cyBhdCAwXG4gIGxldCBzdHIgPSAnJztcbiAgd2hpbGUgKHRvdGFsID4gMCkge1xuICAgIGNvbnN0IHEgPSAodG90YWwgLSAxKSAvIDI2O1xuICAgIGNvbnN0IHIgPSAodG90YWwgLSAxKSAlIDI2O1xuICAgIHRvdGFsID0gTWF0aC5mbG9vcihxKTtcbiAgICBzdHIgPSBgJHtTdHJpbmcuZnJvbUNoYXJDb2RlKDY1ICsgcil9JHtzdHJ9YDtcbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaGUtZmlsZXMtdXBsb2FkLWVycm9ycycsXG4gIHRlbXBsYXRlVXJsOiAnLi9maWxlcy11cGxvYWQtZXJyb3JzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZmlsZXMtdXBsb2FkLWVycm9ycy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBGaWxlc1VwbG9hZEVycm9yc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgZmlsZT86IFBpY2s8RmlsZSwgJ2ZpbGVuYW1lJyB8ICdzY2hlbWFWZXJzaW9uJz47XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBlcnJvcjogSUVycm9yO1xuXG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgbm9kZVR5cGVzID0gYWNjZXB0ZWRUeXBlcztcbiAgcHVibGljIEVycm9yS2V5cyA9IEVycm9yS2V5cztcbiAgcHVibGljIFVwbG9hZExpbWl0ID0gVXBsb2FkTGltaXQ7XG4gIHB1YmxpYyBtYXhGaWxlU2l6ZU1iID0gbWF4RmlsZVNpemVNYjtcbiAgcHVibGljIGNvbHVtbnM6IElDU1ZDb2x1bW5bXSA9IFtdO1xuICBwdWJsaWMgaGVhZGVyczogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIHJvd3M6IHN0cmluZ1tdW10gPSBbXTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbHVtbnMgPSAodGhpcy5lcnJvcj8uaGVhZGVycyB8fCBbXSkubWFwKGhlYWRlciA9PiAoe1xuICAgICAgLi4uaGVhZGVyLFxuICAgICAgY29sdW1uOiBudW1iZXJUb0NvbChoZWFkZXIuaW5kZXgpXG4gICAgfSkpO1xuICAgIGNvbnN0IHNjaGVtYVR5cGUgPSB0aGlzLmVycm9yPy5rZXkgPyB0eXBlVG9TY2hlbWFUeXBlKHRoaXMuZXJyb3Iua2V5LnNwbGl0KCcuJylbMF0pIDogbnVsbDtcbiAgICBjb25zdCBub2RlVHlwZSA9IE9iamVjdC52YWx1ZXMoU2NoZW1hVHlwZSkuaW5jbHVkZXMoc2NoZW1hVHlwZSkgPyBzY2hlbWFUeXBlIDogdGhpcy5lcnJvcj8uc2NoZW1hO1xuICAgIGNvbnN0IG5vZGVzID0gbm9kZXNGcm9tRXJyb3IodGhpcy5lcnJvciwgbm9kZVR5cGUpO1xuICAgIGNvbnN0IGNzdiA9IGVycm9yQ3N2KG5vZGVzKS50cmltKCk7XG4gICAgY29uc3Qge1xuICAgICAgZGF0YTogW2hlYWRlcnMsIC4uLnJvd3NdXG4gICAgfSA9IGNzdiA/IHBhcnNlKGNzdikgOiB7IGRhdGE6IFtbXV0gfTtcbiAgICB0aGlzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIHRoaXMucm93cyA9IHJvd3M7XG4gIH1cblxuICBwcml2YXRlIGdldCBpc0pTT05GaWxlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGU/LmZpbGVuYW1lPy5lbmRzV2l0aChTdXBwb3J0ZWRFeHRlbnNpb25zLmpzb24pO1xuICB9XG5cbiAgcHVibGljIHN0cmluZ2lmeSh2YWx1ZSkge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgMik7XG4gIH1cblxuICBwdWJsaWMgaGFzRHVwbGljYXRlZEVycm9yKHZhbHVlOiBzdHJpbmcsIGNvbEluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBmaXJzdFZhbCA9IHRoaXMucm93c1swXVtjb2xJbmRleF07XG4gICAgcmV0dXJuIHZhbHVlICE9PSBmaXJzdFZhbDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaGFzTnVtYmVyV2l0aENvbW1hc0Vycm9yKCkge1xuICAgIHJldHVybiB0aGlzLmVycm9yPy5lcnJvciA9PT0gJ2ZhaWxlZCB0byBwYXJzZSBudW1iZXInICYmIChgJHt0aGlzLmVycm9yPy52YWx1ZX1gIHx8ICcnKS5pbmNsdWRlcygnLCcpO1xuICB9XG5cbiAgcHVibGljIGdldCBoYXNHZW9KU09ORXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXJyb3I/LmVycm9yPy5pbmNsdWRlcygnVW5hYmxlIHRvIHBhcnNlIEdlb0pTT04gdmFsdWUnKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2NoZW1hVXJsKCkge1xuICAgIHJldHVybiBbc2NoZW1hQmFzZVVybCh0aGlzLmZpbGU/LnNjaGVtYVZlcnNpb24pLCB0aGlzLmVycm9yPy5zY2hlbWFdLmZpbHRlcihCb29sZWFuKS5qb2luKCcvJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNjaGVtYUtleVVybCgpIHtcbiAgICByZXR1cm4gW3RoaXMuc2NoZW1hVXJsLCB0aGlzLmVycm9yPy5zY2hlbWFLZXkgfHwgdGhpcy5lcnJvcj8ua2V5XS5maWx0ZXIoQm9vbGVhbikuam9pbignIycpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc1NjaGVtYUVycm9yKCkge1xuICAgIHJldHVybiBbRXJyb3JLZXlzLlByb3BlcnR5Tm90Rm91bmQsIEVycm9yS2V5cy5TY2hlbWFOb3RGb3VuZF0uaW5jbHVkZXModGhpcy5lcnJvcj8ubWVzc2FnZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNob3dDc3ZQcmV2aWV3KCkge1xuICAgIHJldHVybiB0aGlzLmhlYWRlcnM/Lmxlbmd0aCAmJiB0aGlzLnJvd3M/Lmxlbmd0aCAmJiAhdGhpcy5pc1NjaGVtYUVycm9yICYmICF0aGlzLmlzSlNPTkZpbGU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNob3dKc29uUHJldmlldygpIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcj8ubm9kZSAmJiB0aGlzLmlzSlNPTkZpbGU7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhIWVycm9yXCI+XG4gIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1kYW5nZXJcIiBbbmdTd2l0Y2hdPVwiZXJyb3I/Lm1lc3NhZ2VcIj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuSW52YWxpZEpTT05cIj5cbiAgICAgIDxwPlRoZSB1cGxvYWRlZCBjb250ZW50IGRvZXMgbm90IGFwcGVhciB0byBjb250YWluIHZhbGlkIEpTT04gZGF0YTo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tdC0yXCI+XG4gICAgICAgIDxwcmU+PGNvZGU+e3tlcnJvci5lcnJvcn19PC9jb2RlPjwvcHJlPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxwPlxuICAgICAgICBQbGVhc2UgdmFsaWRhdGUgeW91ciBKU09OIGNvbnRlbnQgYmVmb3JlIHVwbG9hZGluZyBpdCB1c2luZyBhblxuICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly9qc29uZWRpdG9yb25saW5lLm9yZ1wiIHRhcmdldD1cIl9ibGFua1wiPm9ubGluZSB0b29sPC9hPlxuICAgICAgICBmb3IgZXhhbXBsZS5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTm9EYXRhXCI+XG4gICAgICA8cD5ObyBOb2RlcyBjb3VsZCBiZSBmb3VuZCBpbiB5b3VyIFVwbG9hZC4gUGxlYXNlIHZlcmlmeSB0aGUgY29sdW1uIGhlYWRlcnMgbWF0Y2ggdGhlIEhlc3RpYSBzY2hlbWEuPC9wPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVmYXVsdEVycm9yXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuUHJvcGVydHlOb3RGb3VuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbiBpcy1kYW5nZXJcIiByb2xlPVwiYWxlcnRcIj5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPGZhLWljb24gY2xhc3M9XCJwci0yXCIgaWNvbj1cImV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDxzcGFuPllvdSBoYXZlIGNvbHVtbiBoZWFkZXJzIHRoYXQgZG8gbm90IG1hdGNoIHRoZSBIZXN0aWEgc2NoZW1hLjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInB4LTFcIj5QbGVhc2UgcmVmZXIgdG8gdGhlPC9zcGFuPlxuICAgICAgICAgIDxhIFtocmVmXT1cInNjaGVtYVVybFwiIHRhcmdldD1cIl9ibGFua1wiPnNjaGVtYTwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj5hbmQgdGhlbiBjb3JyZWN0IHRoZSBjb2x1bW4gaGVhZGVycyBpbmRpY2F0ZWQgYmVsb3cuPC9zcGFuPlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRlZmF1bHRFcnJvclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICAgIDxwcmU+PGNvZGU+e3tlcnJvci5rZXl9fTwvY29kZT48L3ByZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdTd2l0Y2hDYXNlPVwiRXJyb3JLZXlzLlByb3BlcnR5SW52YWxpZEZvcm1hdFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAgVGhlIGZvbGxvd2luZyB2YWx1ZSBpbiB0aGUgY29sdW1uXG4gICAgICAgICAgPGk+e3sgZXJyb3Iua2V5IH19PC9pPlxuICAgICAgICAgIGlzIG5vdCBpbiB0aGUgY29ycmVjdCBmb3JtYXQ6XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGJyIC8+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tzdHJpbmdpZnkoZXJyb3IudmFsdWUpfX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImhhc051bWJlcldpdGhDb21tYXNFcnJvclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJ0cnVlXCI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJpcy1tdC0yXCI+XG4gICAgICAgICAgICBQbGVhc2UgZm9ybWF0IHlvdXIgbnVtYmVycyB0byByZW1vdmUgY29tbWFzIGFuZCB1c2UgYSBkZWNpbWFsIHBvaW50IHRvIHNlcGFyYXRlIHRoZSB3aG9sZSBwYXJ0IG9mIHRoZSBudW1iZXJcbiAgICAgICAgICAgIGZyb20gdGhlIGZyYWN0aW9uYWwgcGFydCBvZiB0aGUgbnVtYmVyLlxuICAgICAgICAgIDwvcD5cblxuICAgICAgICAgIDxwIGNsYXNzPVwiaXMtbXQtMiBoYXMtdGV4dC1kYW5nZXIgaGFzLXRleHQtdW5kZXJsaW5lXCI+SW5jb3JyZWN0OjwvcD5cbiAgICAgICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPjMsNTEwLjE8L2NvZGU+PC9wcmU+XG5cbiAgICAgICAgICA8cCBjbGFzcz1cImlzLW10LTIgaGFzLXRleHQtc3VjY2VzcyBoYXMtdGV4dC11bmRlcmxpbmVcIj5Db3JyZWN0OjwvcD5cbiAgICAgICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPjM1MTAuMTwvY29kZT48L3ByZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiZmFsc2VcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic2NoZW1hRXJyb3JcIj48L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxwPlRoZSBlcnJvciBjb3VsZCBlaXRoZXIgYmUgYSB2YWx1ZSBpbiB0aGUgY29sdW1uLCBvciBhbiBlcnJvciB3aXRoIHRoZSBjb2x1bW4gaGVhZGVyLjwvcD5cbiAgICAgICAgICA8cD5cbiAgICAgICAgICAgIElmIHlvdSBhcmUgdHJ5aW5nIHRvIHNldCBubyBkYXRhLCB3ZSBhY2NlcHQgZWl0aGVyXG4gICAgICAgICAgICA8Y29kZT4tPC9jb2RlPlxuICAgICAgICAgICAgb3IgYW4gZW1wdHkgY2VsbC5cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuUHJvcGVydHlSZXF1aXJlZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwci0xXCI+VGhlIGZvbGxvd2luZyBmaWVsZCBpcyByZXF1aXJlZCBpbiB0aGU8L3NwYW4+XG4gICAgICAgIDxhIGNsYXNzPVwicHItMVwiICpuZ0lmPVwiZXJyb3Iuc2NoZW1hXCIgW2hyZWZdPVwic2NoZW1hVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hIH19PC9hPlxuICAgICAgICA8c3Bhbj5zY2hlbWE6PC9zcGFuPlxuICAgICAgICA8YnIgLz5cbiAgICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLnByb3BlcnR5fX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIFtuZ1N3aXRjaF09XCJlcnJvci5wcm9wZXJ0eVwiPlxuICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2lkJ1wiPlxuICAgICAgICAgIFlvdSBtdXN0IGFzc2lnbiBhIHVuaXF1ZVxuICAgICAgICAgIDxjb2RlPmlkPC9jb2RlPlxuICAgICAgICAgIGZvciBldmVyeSByZWNvcmQgaW4geW91ciBkYXRhLlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCIndHlwZSdcIj5cbiAgICAgICAgICBFdmVyeSByZWNvcmQgaW4geW91ciBkYXRhIG11c3QgY29udGFpbiBhXG4gICAgICAgICAgPGNvZGU+dHlwZTwvY29kZT5cbiAgICAgICAgICAuXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5Qcm9wZXJ0eUludGVybmFsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInByLTFcIj5cbiAgICAgICAgICBUaGUgZm9sbG93aW5nIGZpZWxkIGlzXG4gICAgICAgICAgPGNvZGU+aW50ZXJuYWw8L2NvZGU+XG4gICAgICAgICAgaW4gdGhlXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGEgW2hyZWZdPVwic2NoZW1hS2V5VXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hIH19IHNjaGVtYTwvYT5cbiAgICAgICAgPHNwYW4+Ojwvc3Bhbj5cbiAgICAgICAgPGJyIC8+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5zY2hlbWFLZXkgfHwgZXJyb3Iua2V5fX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwPlxuICAgICAgICBZb3UgY2Fubm90IHVwbG9hZFxuICAgICAgICA8Y29kZT5pbnRlcm5hbDwvY29kZT5cbiAgICAgICAgZmllbGRzIHRvIEhlc3RpYS5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5TY2hlbWFOb3RGb3VuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4+VGhlIGZvbGxvd2luZyBOb2RlIGRvZXMgbm90IGV4aXN0IGluIHRoZSBzY2hlbWE6PC9zcGFuPlxuICAgICAgICA8YnIgLz5cbiAgICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19PC9jb2RlPjwvcHJlPlxuICAgICAgPC9kaXY+XG4gICAgICA8cD5cbiAgICAgICAgPHNwYW4+VGhlIGxpc3Qgb2YgYWNjZXB0ZWQgdmFsdWVzIGlzOjwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50XCI+XG4gICAgICAgIDx1bD5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHR5cGUgb2Ygbm9kZVR5cGVzXCI+XG4gICAgICAgICAgICA8aT57eyB0eXBlIH19PC9pPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5VcGxvYWRzTGltaXRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICAgIDxzcGFuPllvdSBoYXZlIHJlYWNoZWQgdGhlIHVwbG9hZCBsaW1pdCBvZjwvc3Bhbj5cbiAgICAgICAgPGNvZGUgY2xhc3M9XCJteC0xXCI+e3sgVXBsb2FkTGltaXRbZXJyb3Iuc2NoZW1hXSB9fTwvY29kZT5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAge3sgZXJyb3Iuc2NoZW1hIH19IGluIGEgc2luZ2xlIGZpbGUgKFxuICAgICAgICAgIDxiPnt7IGVycm9yLnZhbHVlIH19PC9iPlxuICAgICAgICAgIGhhdmUgYmVlbiBmb3VuZCkuXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8cD5cbiAgICAgICAgPHNwYW4+UGxlYXNlIHJlLXVwbG9hZCB0aGVzZSBkYXRhIGluIG11bHRpcGxlIGZpbGVzIHdpdGggYSBtYXhpbXVtIG9mPC9zcGFuPlxuICAgICAgICA8Y29kZSBjbGFzcz1cIm14LTFcIj57eyBVcGxvYWRMaW1pdFtlcnJvci5zY2hlbWFdIH19PC9jb2RlPlxuICAgICAgICA8c3Bhbj57eyBlcnJvci5zY2hlbWEgfX0gaW4gZWFjaCBmaWxlLjwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5JbnZhbGlkRmlyc3RDb2x1bW5cIj5cbiAgICAgIDxzcGFuPlxuICAgICAgICBObyBkYXRhIGluIHRoZSBIZXN0aWEgZm9ybWF0IHdhcyBkZXRlY3RlZCBvbiB0aGUgZmlyc3Qgc2hlZXQuIEVpdGhlciB0cnkgc2VsZWN0aW5nIGEgZGlmZmVyZW50IHNoZWV0IGluIHRoZVxuICAgICAgICB1cGxvYWQgc2NyZWVuLCBvciBjaGVjayB0aGUgc2hlZXQgdG8gZW5zdXJlIHRoZSBoZWFkZXJzIGZvbGxvdyB0aGUgc2NoZW1hIC0gc2VlIGV4YW1wbGVzXG4gICAgICA8L3NwYW4+XG4gICAgICA8YSBjbGFzcz1cInBsLTFcIiByb3V0ZXJMaW5rPVwiL3VwbG9hZFwiIGZyYWdtZW50PVwiZXhhbXBsZVwiPmhlcmU8L2E+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTm9IZWFkZXJzXCI+XG4gICAgICA8cD5cbiAgICAgICAgTm8gaGVhZGVycyBtYXRjaGluZyB0aGUgSGVzdGlhIHNjaGVtYSB3ZXJlIGZvdW5kIG9uIHRoZSBmaXJzdCByb3cuIFBsZWFzZSByZW1vdmUgYWxsIGVtcHR5IHJvd3MgYXQgdGhlIGJlZ2luaW5nXG4gICAgICAgIG9mIHRoZSBmaWxlIGFuZCB0cnkgdXBsb2FkaW5nIGFnYWluLlxuICAgICAgPC9wPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVmYXVsdEVycm9yXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuSW52YWxpZFNoZWV0TmFtZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwci0xXCI+VGhlIEV4Y2VsIHNoZWV0PC9zcGFuPlxuICAgICAgICA8Y29kZT57eyBlcnJvci52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+ZG9lcyBub3QgZXhpc3QuPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj5Zb3VyIEV4Y2VsIGZpbGUgY29udGFpbnMgdGhlIGZvbGxvd2luZyBzaGVldHM6PC9zcGFuPlxuICAgICAgICA8dWwgY2xhc3M9XCJtdC0xIGNvbnRlbnQgaXMtbGlzdC1zdHlsZS1kaXNjIHBsLTVcIj5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGUgb2YgZXJyb3IuZXJyb3Iuc3BsaXQoJzsnKVwiPlxuICAgICAgICAgICAgPGNvZGU+e3sgZSB9fTwvY29kZT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxwPlxuICAgICAgICA8c3Bhbj5QbGVhc2UgcmUtdXBsb2FkIHNlbGVjdGluZyBvbmUgb2YgdGhlIHNoZWV0cyBhYm92ZS48L3NwYW4+XG4gICAgICA8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuRHVwbGljYXRlZEhlYWRlcnNcIj5cbiAgICAgIDxzcGFuPllvdXIgdXBsb2FkIGNvbnRhaW5zIGR1cGxpY2F0ZWQgY29sdW1uIGhlYWRlcnMuPC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdTd2l0Y2hDYXNlPVwiRXJyb3JLZXlzLkR1cGxpY2F0ZWRJZHNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwicHItMVwiPllvdSBoYXZlIG11bHRpcGxlPC9zcGFuPlxuICAgICAgPGNvZGU+e3sgZXJyb3Iuc2NoZW1hIHwgcGx1cmFsaXplIH19PC9jb2RlPlxuICAgICAgPHNwYW4gY2xhc3M9XCJweC0xXCI+d2l0aCB0aGUgc2FtZTwvc3Bhbj5cbiAgICAgIDxhIFtocmVmXT1cInNjaGVtYUtleVVybFwiIHRhcmdldD1cIl9ibGFua1wiPnt7IGVycm9yLnNjaGVtYUtleSB9fTwvYT5cbiAgICAgIDxzcGFuIGNsYXNzPVwicHgtMVwiPmJ1dCBkaWZmZXJlbnQgZGF0YS4gVGhlPC9zcGFuPlxuICAgICAgPGEgW2hyZWZdPVwic2NoZW1hS2V5VXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hS2V5IH19PC9hPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+aXM6PC9zcGFuPlxuICAgICAgPGJyIC8+XG4gICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPnt7ZXJyb3IudmFsdWV9fTwvY29kZT48L3ByZT5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5EdXBsaWNhdGVkSWRGaWVsZHNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPllvdSBoYXZlIHVzZWQgYm90aCB0aGU8L3NwYW4+XG4gICAgICA8Y29kZT5AaWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj5hbmQ8L3NwYW4+XG4gICAgICA8Y29kZT5pZDwvY29kZT5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHgtMVwiPmZpZWxkcyBpbiB0aGUgc2FtZSBkYXRhLiBQbGVhc2UgdXNlPC9zcGFuPlxuICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1weC0xXCI+d2hlbiBsaW5raW5nIHRvIGV4aXN0aW5nIG5vZGVzIG9uIHRoZSBQbGF0Zm9ybSwgYW5kPC9zcGFuPlxuICAgICAgPGNvZGU+aWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj53aGVuIGxpbmtpbmcgdG8gbm9kZXMgeW91IGFyZSB1cGxvYWRpbmcgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBzYW1lPC9zcGFuPlxuICAgICAgPGNvZGU+aWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj5maWVsZC48L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTmVzdGVkSGVhZGVyc1wiPlxuICAgICAgPHA+XG4gICAgICAgIFRvIGxpbmsgbm9kZXMgdG9nZXRoZXIsIHlvdSBmaXJzdCBuZWVkIHRvIGRlZmluZSB0aGUgbm9kZSAoZS5nLixcbiAgICAgICAgPGNvZGU+c291cmNlLmlkPC9jb2RlPlxuICAgICAgICAsXG4gICAgICAgIDxjb2RlPnNvdXJjZS5iaWJsaW9ncmFwaHkudGl0bGU8L2NvZGU+XG4gICAgICAgICkgYW5kIHRoZW4gY3JlYXRlIHRoZSBsaW5rIChlLmcuLFxuICAgICAgICA8Y29kZT5jeWNsZS5kZWZhdWx0U291cmNlLmlkPC9jb2RlPlxuICAgICAgICApLiBXZSBkbyBub3QgYWxsb3cgbmVzdGluZyAoZS5nLixcbiAgICAgICAgPGNvZGU+Y3ljbGUuZGVmYXVsdFNvdXJjZS5iaWJsaW9ncmFwaHkudGl0bGU8L2NvZGU+XG4gICAgICAgICkuXG4gICAgICA8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuUmVmZXJlbmNlRXhpc3RpbmdIZWFkZXJzXCI+XG4gICAgICA8cD5cbiAgICAgICAgWW91IGhhdmUgdXNlZCB0aGUgaW50ZXJuYWxcbiAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICBmaWVsZCB0byB1cGxvYWQgYSBuZXcgTm9kZS5cbiAgICAgIDwvcD5cbiAgICAgIDxwPlxuICAgICAgICBUaGVcbiAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICBmaWVsZCBzaG91bGQgb25seSBiZSB1c2VkIHRvIHJlZmVyZW5jZSBleGlzdGluZyBOb2RlIG9yIFRlcm1zLiBFeGFtcGxlOlxuICAgICAgPC9wPlxuXG4gICAgICA8cCBjbGFzcz1cImlzLW10LTIgaGFzLXRleHQtZGFuZ2VyIGhhcy10ZXh0LXVuZGVybGluZVwiPkluY29ycmVjdDo8L3A+XG4gICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPmN5Y2xlLkBpZCxjeWNsZS5pbnB1dHMuMC50ZXJtLkBpZCxzb3VyY2UuaWQ8L2NvZGU+PC9wcmU+XG5cbiAgICAgIDxwIGNsYXNzPVwiaXMtbXQtMiBoYXMtdGV4dC1zdWNjZXNzIGhhcy10ZXh0LXVuZGVybGluZVwiPkNvcnJlY3Q6PC9wPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT5jeWNsZS5pZCxjeWNsZS5pbnB1dHMuMC50ZXJtLkBpZCxzb3VyY2UuaWQ8L2NvZGU+PC9wcmU+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuT2JqZWN0QXJyYXlJbnZhbGlkXCI+XG4gICAgICA8cD5UaGUgdmFsdWVzIGluIHRoZSBjb2x1bW4ge3sgZXJyb3Iua2V5IH19IG11c3QgYmUgcmVwcmVzZW50ZWQgYXMgYXJyYXlzLjwvcD5cblxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInNjaGVtYUVycm9yXCI+PC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxwPkV4YW1wbGVzOjwvcD5cbiAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5rZXl9fS4wLnRlcm0ubmFtZTwvY29kZT48L3ByZT5cbiAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5rZXl9fS4wLnZhbHVlPC9jb2RlPjwvcHJlPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19LjEudGVybS5uYW1lPC9jb2RlPjwvcHJlPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19LjEudmFsdWU8L2NvZGU+PC9wcmU+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTWF4U2l6ZVwiPlxuICAgICAgPHNwYW4+VGhlIG1heGltdW0gZmlsZSBzaXplIGxpbWl0IGlzIHt7IG1heEZpbGVTaXplTWIgfX1NYiAoY3VycmVudCBmaWxlIHNpemU6IHt7IGVycm9yLnZhbHVlIH19TWIpLjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPlBsZWFzZSByZS11cGxvYWQgdGhlc2UgZGF0YSBpbiBtdWx0aXBsZSBmaWxlcy48L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTWF4Um93c1wiPlxuICAgICAgPHNwYW4+XG4gICAgICAgIFlvdXIgZmlsZSBoYXMge3sgZXJyb3IudmFsdWUgfCBudW1iZXIgfX0gcm93cy4gVGhpcyBtaWdodCBiZSBhbiBlcnJvciBjYXVzZWQgYnkgYWRkaW5nIHNvbWUgZGF0YSBhdCB0aGUgYm90dG9tXG4gICAgICAgIG9mIGEgc3ByZWFkc2hlZXQgYnkgYWNjaWRlbnQ6IGRlbGV0ZSBhbnkgdW51c2VkIHJvd3MgYW5kIHJlc3VibWl0IHRoZSBmaWxlLlxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdJZj1cImhhc0dlb0pTT05FcnJvclwiPlxuICAgICAgPHA+SWYgdGhlIEdlb0pTT04gaXMgdG9vIGxhcmdlLCBwbGVhc2UgdHJ5IHRvIHNpbXBsaWZ5IGl0IGZvbGxvd2luZyB0aGVzZSBzdGVwczo8L3A+XG4gICAgICA8dWwgY2xhc3M9XCJpcy1teS0xIGNvbnRlbnQgaXMtbGlzdC1zdHlsZS1kZWNpbWFsIHBsLTVcIj5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPkdvIHRvPC9zcGFuPlxuICAgICAgICAgIDxhIGhyZWY9XCJodHRwczovL21hcHNoYXBlci5vcmcvXCIgdGFyZ2V0PVwiX2JsYW5rXCI+aHR0cHM6Ly9tYXBzaGFwZXIub3JnLzwvYT5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgU2F2ZSB0aGUgYm91bmRhcnkgaW4gYSB2YWxpZFxuICAgICAgICAgICAgPGNvZGU+Lmdlb2pzb248L2NvZGU+XG4gICAgICAgICAgICBmaWxlLlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuPkltcG9ydCBpdCBvbiBtYXBzaGFwZXIuPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGk+XG4gICAgICAgICAgPHNwYW4+Q2xpY2sgXCJTaW1wbGlmeVwiIGluIHRoZSB0b3AgcmlnaHQgY29ybmVyIGluIHRoZSBtZW51IGJhci48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaT5cbiAgICAgICAgICA8c3Bhbj5BZGp1c3QgdGhlIHBlcmNlbnRhZ2UgdG8gYSBsb3dlciB2YWx1ZSwgbGlrZSA1MCUgdG8gc3RhcnQgd2l0aC48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaT5cbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIEV4cG9ydCB0b1xuICAgICAgICAgICAgPGNvZGU+R2VvSnNvbjwvY29kZT5cbiAgICAgICAgICAgIG9yXG4gICAgICAgICAgICA8Y29kZT5DU1Y8L2NvZGU+XG4gICAgICAgICAgICAuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGk+XG4gICAgICAgICAgPHNwYW4+Q29weSB0aGUgcmVzdWx0aW5nIGNvbnRlbnQgaW50byB5b3VyIHVwbG9hZCBmaWxlLjwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgICA8cD5JZiB5b3UgZW5jb3VudGVyIHRoZSBlcnJvciBhZ2FpbiwgdHJ5IGFnYWluIHVzaW5nIGEgbG93ZXIgcGVyY2VudGFnZSBhdCBzdGVwIDUuPC9wPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm15LTNcIiAqbmdJZj1cImNvbHVtbnMubGVuZ3RoIHx8IChlcnJvci5pbmRleCAmJiAhaXNTY2hlbWFFcnJvcilcIj5cbiAgICAgIDxiPkhpbnQ6PC9iPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+dGhlIGVycm9yIG1pZ2h0IGJlIGxvY2F0ZWQ8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cImVycm9yLmluZGV4ICYmICFpc1NjaGVtYUVycm9yXCI+b24gcm93IHt7IGVycm9yLmluZGV4IH19PC9zcGFuPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbnMubGVuZ3RoXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPmluIHt7ICdjb2x1bW4nIHwgcGx1cmFsaXplOiBjb2x1bW5zLmxlbmd0aCB9fTo8L3NwYW4+XG4gICAgICAgIDx1bCBjbGFzcz1cIm10LTEgY29udGVudCBpcy1saXN0LXN0eWxlLWRpc2MgcGwtNVwiPlxuICAgICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICAgIDxiIGNsYXNzPVwicHItMlwiPnt7IGNvbHVtbi5jb2x1bW4gfX08L2I+XG4gICAgICAgICAgICA8Y29kZT57eyBjb2x1bW4ubmFtZSB9fTwvY29kZT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibXktM1wiICpuZ0lmPVwiZXJyb3Iuc3VnZ2VzdGlvbnM/Lmxlbmd0aFwiPlxuICAgICAgPGI+U3VnZ2VzdGlvbnM6PC9iPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+ZGlkIHlvdSBtZWFuIGluc3RlYWQ6PC9zcGFuPlxuICAgICAgPHVsIGNsYXNzPVwibXQtMSBjb250ZW50IGlzLWxpc3Qtc3R5bGUtZGlzYyBwbC01XCI+XG4gICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgc3VnZ2VzdGlvbiBvZiBlcnJvci5zdWdnZXN0aW9uc1wiPlxuICAgICAgICAgIDxjb2RlPnt7IHN1Z2dlc3Rpb24gfX08L2NvZGU+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cInNob3dDc3ZQcmV2aWV3XCIgY2xhc3M9XCJpcy1teS0yXCI+XG4gICAgICA8Yj5cbiAgICAgICAgUHJldmlld1xuICAgICAgICA8c3VwPjE8L3N1cD5cbiAgICAgICAgOlxuICAgICAgPC9iPlxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lciBpcy1tdC0yXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWJvcmRlcmVkIGlzLWZ1bGx3aWR0aCBpcy1ob3ZlcmFibGUgaXMtbmFycm93IG1iLTBcIj5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dGggKm5nSWY9XCJlcnJvci5pbmRleFwiPjwvdGg+XG4gICAgICAgICAgICA8dGggKm5nRm9yPVwibGV0IGhlYWRlciBvZiBoZWFkZXJzXCI+e3sgaGVhZGVyIH19PC90aD5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKmJpbmRPbmNlPVwicm93c1wiPlxuICAgICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHJvdyBvZiByb3dzXCI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtZGFuZ2VyXCIgKm5nSWY9XCJlcnJvci5pbmRleFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXBcIj5Sb3cge3sgZXJyb3IuaW5kZXggfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbCBvZiByb3c7IGxldCBjb2xJbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaGFzLXRleHQtZGFuZ2VyXT1cIlxuICAgICAgICAgICAgICAgICAgICAgIGVycm9yPy5tZXNzYWdlID09PSBFcnJvcktleXMuRHVwbGljYXRlZElkcyAmJiBoYXNEdXBsaWNhdGVkRXJyb3IoY29sLCBjb2xJbmRleClcbiAgICAgICAgICAgICAgICAgICAgXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGNvbCB8IGVsbGlwc2lzOiA1MCB9fVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgICA8cCBjbGFzcz1cImlzLXNpemUtN1wiPlxuICAgICAgICA8aT4xLiBUaGUgcHJldmlldyBkb2VzIG5vdCBuZWNlc3NhcmlseSByZWZsZWN0IHRoZSBvcmlnaW5hbCBVcGxvYWQncyBvcmRlciBvciBjb250ZW50LjwvaT5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCJzaG93SnNvblByZXZpZXdcIiBjbGFzcz1cImlzLW15LTJcIj5cbiAgICAgIDxiPlByZXZpZXc6PC9iPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e3N0cmluZ2lmeShlcnJvci5ub2RlKX19PC9jb2RlPjwvcHJlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctdGVtcGxhdGUgI2RlZmF1bHRFcnJvcj5cbiAgPHAgY2xhc3M9XCJpcy1tdC0yIGhhcy10ZXh0LWJsYWNrXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1wci0xXCI+SWYgeW91IGFyZSBzdGlsbCBzdHVjaywgcGxlYXNlIHNlZTwvc3Bhbj5cbiAgICA8YSBbaHJlZl09XCJiYXNlVXJsICsgJy91cGxvYWQjZXhhbXBsZSdcIiB0YXJnZXQ9XCJfYmxhbmtcIj50aGUgZXhhbXBsZSB1cGxvYWRzIGFuZCB2aWRlb3M8L2E+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1weC0xXCI+XG4gICAgICBvciB0cnkgdXNpbmcgdGhlIFdpemFyZCB0byBnZXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIGRhdGEgZm9ybWF0dGVkIGNvcnJlY3RseSwgb3IgdXNlIHRoZSBjaGF0IHRvIGFzayBmb3IgaGVscC5cbiAgICA8L3NwYW4+XG4gIDwvcD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjc2NoZW1hRXJyb3I+XG4gIDxwPlxuICAgIDxzcGFuIGNsYXNzPVwicHItMVwiPllvdSBjYW4gc2VlIHRoZSBhY2NlcHRlZCBmaWVsZCB0eXBlIGFuZCBzb21lIGV4YW1wbGVzPC9zcGFuPlxuICAgIDxhIFtocmVmXT1cInNjaGVtYUtleVVybFwiIHRhcmdldD1cIl9ibGFua1wiPmhlcmU8L2E+XG4gICAgPHNwYW4+Ljwvc3Bhbj5cbiAgPC9wPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
137
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXMtdXBsb2FkLWVycm9ycy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmlsZXMvZmlsZXMtdXBsb2FkLWVycm9ycy9maWxlcy11cGxvYWQtZXJyb3JzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3NyYy9maWxlcy9maWxlcy11cGxvYWQtZXJyb3JzL2ZpbGVzLXVwbG9hZC1lcnJvcnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEYsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsVUFBVSxFQUNWLFFBQVEsRUFFUixXQUFXLEVBQ1gsWUFBWSxFQUNaLGdCQUFnQixFQUNqQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBUSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsSUFBSSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVuRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7OztBQUU1RCxNQUFNLGdCQUFnQixHQUFHLENBQUMsSUFBYyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBRW5HLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO0tBQzFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxRQUFRLENBQUMsSUFBSSxDQUFDO0tBQ3BDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBRXpCLE1BQU0sQ0FBTixJQUFZLFNBZVg7QUFmRCxXQUFZLFNBQVM7SUFDbkIsK0JBQWtCLENBQUE7SUFDbEIscUNBQXdCLENBQUE7SUFDeEIseUNBQTRCLENBQUE7SUFDNUIsb0RBQXVDLENBQUE7SUFDdkMsd0RBQTJDLENBQUE7SUFDM0MscURBQXdDLENBQUE7SUFDeEMsNkNBQWdDLENBQUE7SUFDaEMsbURBQXNDLENBQUE7SUFDdEMsbURBQXNDLENBQUE7SUFDdEMsMENBQTZCLENBQUE7SUFDN0IsNkNBQWdDLENBQUE7SUFDaEMsb0VBQXVELENBQUE7SUFDdkQsaUNBQW9CLENBQUE7SUFDcEIsaUNBQW9CLENBQUE7QUFDdEIsQ0FBQyxFQWZXLFNBQVMsS0FBVCxTQUFTLFFBZXBCO0FBMkJELE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBVSxFQUFFLElBQWdCLEVBQUUsRUFBRSxDQUNwRCxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUNsQixDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztRQUNuQixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEIsSUFBSTtZQUNKLEdBQUcsR0FBRztTQUNQLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxJQUFJO0lBQ1IsQ0FBQyxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFDM0IsQ0FBQyxDQUFDO1lBQ0U7Z0JBQ0UsSUFBSTtnQkFDSixHQUFHLEtBQUs7YUFDVDtTQUNGO1FBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUVYLE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBYyxFQUFFLElBQWlCLEVBQUUsRUFBRSxDQUMzRCxLQUFLLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUUvRixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsRUFBRTtJQUN2QixJQUFJO1FBQ0YsT0FBTyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7S0FDL0M7SUFBQyxPQUFPLElBQUksRUFBRTtRQUNiLE9BQU8sRUFBRSxDQUFDO0tBQ1g7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFO0lBQ2xDLElBQUksS0FBSyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxjQUFjO0lBQ25DLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNiLE9BQU8sS0FBSyxHQUFHLENBQUMsRUFBRTtRQUNoQixNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzNCLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDO0tBQzlDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDLENBQUM7QUFRRixNQUFNLE9BQU8sMEJBQTBCO0lBTnZDO1FBWVMsWUFBTyxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLGNBQVMsR0FBRyxhQUFhLENBQUM7UUFDMUIsb0JBQWUsR0FBRyxlQUFlLENBQUM7UUFDbEMsY0FBUyxHQUFHLFNBQVMsQ0FBQztRQUN0QixnQkFBVyxHQUFHLFdBQVcsQ0FBQztRQUMxQixrQkFBYSxHQUFHLGFBQWEsQ0FBQztRQUM5QixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUMzQixZQUFPLEdBQWEsRUFBRSxDQUFDO1FBQ3ZCLFNBQUksR0FBZSxFQUFFLENBQUM7S0E0RDlCO0lBMURDLFFBQVE7UUFDTixJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4RCxHQUFHLE1BQU07WUFDVCxNQUFNLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDbEMsQ0FBQyxDQUFDLENBQUM7UUFDSixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMzRixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQztRQUNsRyxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNuRCxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkMsTUFBTSxFQUNKLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUN6QixHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVELElBQVksVUFBVTtRQUNwQixPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sU0FBUyxDQUFDLEtBQUs7UUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVNLGtCQUFrQixDQUFDLEtBQWEsRUFBRSxRQUFnQjtRQUN2RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBVyx3QkFBd0I7UUFDakMsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssS0FBSyx3QkFBd0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVELElBQVcsZUFBZTtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRCxJQUFXLFNBQVM7UUFDbEIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5RixDQUFDO0lBRUQsSUFBVyxhQUFhO1FBQ3RCLE9BQU8sQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FDaEYsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUEwQixDQUN2QyxDQUFDO0lBQ0osQ0FBQztJQUVELElBQVcsY0FBYztRQUN2QixPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDOUYsQ0FBQztJQUVELElBQVcsZUFBZTtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDN0MsQ0FBQzs4R0F6RVUsMEJBQTBCO2tHQUExQiwwQkFBMEIsd0dDOUd2Qyw4eGRBK1lBOzsyRkRqU2EsMEJBQTBCO2tCQU50QyxTQUFTOytCQUNFLHdCQUF3QixtQkFHakIsdUJBQXVCLENBQUMsTUFBTTs4QkFJdkMsSUFBSTtzQkFEWCxLQUFLO2dCQUdDLEtBQUs7c0JBRFgsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSAncGFwYXBhcnNlJztcbmltcG9ydCB7XG4gIFNjaGVtYVR5cGUsXG4gIE5vZGVUeXBlLFxuICBKU09OIGFzIEhlc3RpYUpzb24sXG4gIFVwbG9hZExpbWl0LFxuICBpc0V4cGFuZGFibGUsXG4gIHR5cGVUb1NjaGVtYVR5cGVcbn0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsgRmlsZSwgbWF4RmlsZVNpemVNYiwgU3VwcG9ydGVkRXh0ZW5zaW9ucyB9IGZyb20gJ0BoZXN0aWEtZWFydGgvYXBpJztcbmltcG9ydCB7IHRvQ3N2LCBFcnJvcktleXMgYXMgU2NoZW1hRXJyb3JLZXlzIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEtY29udmVydCc7XG5cbmltcG9ydCB7IGJhc2VVcmwgfSBmcm9tICcuLi8uLi9jb21tb24nO1xuaW1wb3J0IHsgc2NoZW1hQmFzZVVybCB9IGZyb20gJy4uLy4uL3NjaGVtYS9zY2hlbWEuc2VydmljZSc7XG5cbmNvbnN0IG5vZGVUeXBlVG9TdHJpbmcgPSAodHlwZTogTm9kZVR5cGUpID0+IGAke3R5cGUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCl9JHt0eXBlLnN1YnN0cmluZygxKX1gO1xuXG5jb25zdCBhY2NlcHRlZFR5cGVzID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSlcbiAgLmZpbHRlcih2YWwgPT4gdmFsICE9PSBOb2RlVHlwZS5UZXJtKVxuICAubWFwKG5vZGVUeXBlVG9TdHJpbmcpO1xuXG5leHBvcnQgZW51bSBFcnJvcktleXMge1xuICBOb0RhdGEgPSAnbm8tZGF0YScsXG4gIE5vSGVhZGVycyA9ICduby1oZWFkZXJzJyxcbiAgSW52YWxpZEpTT04gPSAnaW52YWxpZC1qc29uJyxcbiAgSW52YWxpZFNoZWV0TmFtZSA9ICdpbnZhbGlkLXNoZWV0LW5hbWUnLFxuICBJbnZhbGlkRmlyc3RDb2x1bW4gPSAnaW52YWxpZC1maXJzdC1jb2x1bW4nLFxuICBEdXBsaWNhdGVkSGVhZGVycyA9ICdkdXBsaWNhdGVkLWhlYWRlcnMnLFxuICBEdXBsaWNhdGVkSWRzID0gJ2R1cGxpY2F0ZWQtaWRzJyxcbiAgUHJvcGVydHlSZXF1aXJlZCA9ICdwcm9wZXJ0eS1yZXF1aXJlZCcsXG4gIFByb3BlcnR5SW50ZXJuYWwgPSAncHJvcGVydHktaW50ZXJuYWwnLFxuICBVcGxvYWRzTGltaXQgPSAndXBsb2FkLWxpbWl0JyxcbiAgTmVzdGVkSGVhZGVycyA9ICduZXN0ZWQtaGVhZGVycycsXG4gIFJlZmVyZW5jZUV4aXN0aW5nSGVhZGVycyA9ICdyZWZlcmVuY2UtZXhpc3RpbmctaGVhZGVycycsXG4gIE1heFNpemUgPSAnbWF4LXNpemUnLFxuICBNYXhSb3dzID0gJ21heC1yb3dzJ1xufVxuXG5pbnRlcmZhY2UgSUNTVkhlYWRlciB7XG4gIG5hbWU6IHN0cmluZztcbiAgaW5kZXg6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIElDU1ZDb2x1bW4gZXh0ZW5kcyBJQ1NWSGVhZGVyIHtcbiAgY29sdW1uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUVycm9yIHtcbiAgbWVzc2FnZTogU2NoZW1hRXJyb3JLZXlzIHwgRXJyb3JLZXlzO1xuICBzY2hlbWE/OiBTY2hlbWFUeXBlO1xuICBzY2hlbWFLZXk/OiBzdHJpbmc7XG4gIGtleT86IHN0cmluZztcbiAgcHJvcGVydHk/OiBzdHJpbmc7XG4gIHZhbHVlPzogYW55O1xuICBtaW4/OiBhbnk7XG4gIG1heD86IGFueTtcbiAgZXJyb3I/OiBzdHJpbmc7XG4gIG5vZGU/OiBIZXN0aWFKc29uPFNjaGVtYVR5cGU+O1xuICBpbmRleD86IG51bWJlcjtcbiAgaGVhZGVycz86IElDU1ZIZWFkZXJbXTtcbiAgc3VnZ2VzdGlvbnM/OiBzdHJpbmdbXTtcbn1cblxuY29uc3QgdmFsdWVUb05vZGVzID0gKHZhbHVlOiBhbnksIHR5cGU6IFNjaGVtYVR5cGUpID0+XG4gIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgPyBpc0V4cGFuZGFibGUodmFsdWUpXG4gICAgICA/IHZhbHVlLm1hcCh2YWwgPT4gKHtcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIC4uLnZhbFxuICAgICAgICB9KSlcbiAgICAgIDogbnVsbFxuICAgIDogdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuICAgID8gW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICAuLi52YWx1ZVxuICAgICAgICB9XG4gICAgICBdXG4gICAgOiBudWxsO1xuXG5jb25zdCBub2Rlc0Zyb21FcnJvciA9IChlcnJvcj86IElFcnJvciwgdHlwZT86IFNjaGVtYVR5cGUpID0+XG4gIGVycm9yID8gdmFsdWVUb05vZGVzKGVycm9yLm5vZGUsIHR5cGUpIHx8IHZhbHVlVG9Ob2RlcyhlcnJvci52YWx1ZSwgZXJyb3Iuc2NoZW1hKSB8fCBbXSA6IFtdO1xuXG5jb25zdCBlcnJvckNzdiA9IG5vZGVzID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdG9Dc3Yobm9kZXMsIHsgaW5jbHVkZUV4aXNpbmc6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKF9lcnIpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbn07XG5cbmNvbnN0IG51bWJlclRvQ29sID0gKG51bTogbnVtYmVyKSA9PiB7XG4gIGxldCB0b3RhbCA9IG51bSArIDE7IC8vIHN0YXJ0cyBhdCAwXG4gIGxldCBzdHIgPSAnJztcbiAgd2hpbGUgKHRvdGFsID4gMCkge1xuICAgIGNvbnN0IHEgPSAodG90YWwgLSAxKSAvIDI2O1xuICAgIGNvbnN0IHIgPSAodG90YWwgLSAxKSAlIDI2O1xuICAgIHRvdGFsID0gTWF0aC5mbG9vcihxKTtcbiAgICBzdHIgPSBgJHtTdHJpbmcuZnJvbUNoYXJDb2RlKDY1ICsgcil9JHtzdHJ9YDtcbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaGUtZmlsZXMtdXBsb2FkLWVycm9ycycsXG4gIHRlbXBsYXRlVXJsOiAnLi9maWxlcy11cGxvYWQtZXJyb3JzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZmlsZXMtdXBsb2FkLWVycm9ycy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBGaWxlc1VwbG9hZEVycm9yc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgZmlsZT86IFBpY2s8RmlsZSwgJ2ZpbGVuYW1lJyB8ICdzY2hlbWFWZXJzaW9uJz47XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBlcnJvcjogSUVycm9yO1xuXG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgbm9kZVR5cGVzID0gYWNjZXB0ZWRUeXBlcztcbiAgcHVibGljIFNjaGVtYUVycm9yS2V5cyA9IFNjaGVtYUVycm9yS2V5cztcbiAgcHVibGljIEVycm9yS2V5cyA9IEVycm9yS2V5cztcbiAgcHVibGljIFVwbG9hZExpbWl0ID0gVXBsb2FkTGltaXQ7XG4gIHB1YmxpYyBtYXhGaWxlU2l6ZU1iID0gbWF4RmlsZVNpemVNYjtcbiAgcHVibGljIGNvbHVtbnM6IElDU1ZDb2x1bW5bXSA9IFtdO1xuICBwdWJsaWMgaGVhZGVyczogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIHJvd3M6IHN0cmluZ1tdW10gPSBbXTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbHVtbnMgPSAodGhpcy5lcnJvcj8uaGVhZGVycyB8fCBbXSkubWFwKGhlYWRlciA9PiAoe1xuICAgICAgLi4uaGVhZGVyLFxuICAgICAgY29sdW1uOiBudW1iZXJUb0NvbChoZWFkZXIuaW5kZXgpXG4gICAgfSkpO1xuICAgIGNvbnN0IHNjaGVtYVR5cGUgPSB0aGlzLmVycm9yPy5rZXkgPyB0eXBlVG9TY2hlbWFUeXBlKHRoaXMuZXJyb3Iua2V5LnNwbGl0KCcuJylbMF0pIDogbnVsbDtcbiAgICBjb25zdCBub2RlVHlwZSA9IE9iamVjdC52YWx1ZXMoU2NoZW1hVHlwZSkuaW5jbHVkZXMoc2NoZW1hVHlwZSkgPyBzY2hlbWFUeXBlIDogdGhpcy5lcnJvcj8uc2NoZW1hO1xuICAgIGNvbnN0IG5vZGVzID0gbm9kZXNGcm9tRXJyb3IodGhpcy5lcnJvciwgbm9kZVR5cGUpO1xuICAgIGNvbnN0IGNzdiA9IGVycm9yQ3N2KG5vZGVzKS50cmltKCk7XG4gICAgY29uc3Qge1xuICAgICAgZGF0YTogW2hlYWRlcnMsIC4uLnJvd3NdXG4gICAgfSA9IGNzdiA/IHBhcnNlKGNzdikgOiB7IGRhdGE6IFtbXV0gfTtcbiAgICB0aGlzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIHRoaXMucm93cyA9IHJvd3M7XG4gIH1cblxuICBwcml2YXRlIGdldCBpc0pTT05GaWxlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGU/LmZpbGVuYW1lPy5lbmRzV2l0aChTdXBwb3J0ZWRFeHRlbnNpb25zLmpzb24pO1xuICB9XG5cbiAgcHVibGljIHN0cmluZ2lmeSh2YWx1ZSkge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgMik7XG4gIH1cblxuICBwdWJsaWMgaGFzRHVwbGljYXRlZEVycm9yKHZhbHVlOiBzdHJpbmcsIGNvbEluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBmaXJzdFZhbCA9IHRoaXMucm93c1swXVtjb2xJbmRleF07XG4gICAgcmV0dXJuIHZhbHVlICE9PSBmaXJzdFZhbDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaGFzTnVtYmVyV2l0aENvbW1hc0Vycm9yKCkge1xuICAgIHJldHVybiB0aGlzLmVycm9yPy5lcnJvciA9PT0gJ2ZhaWxlZCB0byBwYXJzZSBudW1iZXInICYmIChgJHt0aGlzLmVycm9yPy52YWx1ZX1gIHx8ICcnKS5pbmNsdWRlcygnLCcpO1xuICB9XG5cbiAgcHVibGljIGdldCBoYXNHZW9KU09ORXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXJyb3I/LmVycm9yPy5pbmNsdWRlcygnVW5hYmxlIHRvIHBhcnNlIEdlb0pTT04gdmFsdWUnKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2NoZW1hVXJsKCkge1xuICAgIHJldHVybiBbc2NoZW1hQmFzZVVybCh0aGlzLmZpbGU/LnNjaGVtYVZlcnNpb24pLCB0aGlzLmVycm9yPy5zY2hlbWFdLmZpbHRlcihCb29sZWFuKS5qb2luKCcvJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNjaGVtYUtleVVybCgpIHtcbiAgICByZXR1cm4gW3RoaXMuc2NoZW1hVXJsLCB0aGlzLmVycm9yPy5zY2hlbWFLZXkgfHwgdGhpcy5lcnJvcj8ua2V5XS5maWx0ZXIoQm9vbGVhbikuam9pbignIycpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc1NjaGVtYUVycm9yKCkge1xuICAgIHJldHVybiBbU2NoZW1hRXJyb3JLZXlzLlByb3BlcnR5Tm90Rm91bmQsIFNjaGVtYUVycm9yS2V5cy5TY2hlbWFOb3RGb3VuZF0uaW5jbHVkZXMoXG4gICAgICB0aGlzLmVycm9yPy5tZXNzYWdlIGFzIFNjaGVtYUVycm9yS2V5c1xuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNob3dDc3ZQcmV2aWV3KCkge1xuICAgIHJldHVybiB0aGlzLmhlYWRlcnM/Lmxlbmd0aCAmJiB0aGlzLnJvd3M/Lmxlbmd0aCAmJiAhdGhpcy5pc1NjaGVtYUVycm9yICYmICF0aGlzLmlzSlNPTkZpbGU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNob3dKc29uUHJldmlldygpIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcj8ubm9kZSAmJiB0aGlzLmlzSlNPTkZpbGU7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhIWVycm9yXCI+XG4gIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1kYW5nZXJcIiBbbmdTd2l0Y2hdPVwiZXJyb3I/Lm1lc3NhZ2VcIj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuSW52YWxpZEpTT05cIj5cbiAgICAgIDxwPlRoZSB1cGxvYWRlZCBjb250ZW50IGRvZXMgbm90IGFwcGVhciB0byBjb250YWluIHZhbGlkIEpTT04gZGF0YTo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tdC0yXCI+XG4gICAgICAgIDxwcmU+PGNvZGU+e3tlcnJvci5lcnJvcn19PC9jb2RlPjwvcHJlPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxwPlxuICAgICAgICBQbGVhc2UgdmFsaWRhdGUgeW91ciBKU09OIGNvbnRlbnQgYmVmb3JlIHVwbG9hZGluZyBpdCB1c2luZyBhblxuICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly9qc29uZWRpdG9yb25saW5lLm9yZ1wiIHRhcmdldD1cIl9ibGFua1wiPm9ubGluZSB0b29sPC9hPlxuICAgICAgICBmb3IgZXhhbXBsZS5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTm9EYXRhXCI+XG4gICAgICA8cD5ObyBOb2RlcyBjb3VsZCBiZSBmb3VuZCBpbiB5b3VyIFVwbG9hZC4gUGxlYXNlIHZlcmlmeSB0aGUgY29sdW1uIGhlYWRlcnMgbWF0Y2ggdGhlIEhlc3RpYSBzY2hlbWEuPC9wPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVmYXVsdEVycm9yXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJTY2hlbWFFcnJvcktleXMuUHJvcGVydHlOb3RGb3VuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGlmaWNhdGlvbiBpcy1kYW5nZXJcIiByb2xlPVwiYWxlcnRcIj5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPGZhLWljb24gY2xhc3M9XCJwci0yXCIgaWNvbj1cImV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDxzcGFuPllvdSBoYXZlIGNvbHVtbiBoZWFkZXJzIHRoYXQgZG8gbm90IG1hdGNoIHRoZSBIZXN0aWEgc2NoZW1hLjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInB4LTFcIj5QbGVhc2UgcmVmZXIgdG8gdGhlPC9zcGFuPlxuICAgICAgICAgIDxhIFtocmVmXT1cInNjaGVtYVVybFwiIHRhcmdldD1cIl9ibGFua1wiPnNjaGVtYTwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj5hbmQgdGhlbiBjb3JyZWN0IHRoZSBjb2x1bW4gaGVhZGVycyBpbmRpY2F0ZWQgYmVsb3cuPC9zcGFuPlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRlZmF1bHRFcnJvclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICAgIDxwcmU+PGNvZGU+e3tlcnJvci5rZXl9fTwvY29kZT48L3ByZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdTd2l0Y2hDYXNlPVwiU2NoZW1hRXJyb3JLZXlzLlByb3BlcnR5SW52YWxpZEZvcm1hdFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAgVGhlIGZvbGxvd2luZyB2YWx1ZSBpbiB0aGUgY29sdW1uXG4gICAgICAgICAgPGk+e3sgZXJyb3Iua2V5IH19PC9pPlxuICAgICAgICAgIGlzIG5vdCBpbiB0aGUgY29ycmVjdCBmb3JtYXQ6XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGJyIC8+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tzdHJpbmdpZnkoZXJyb3IudmFsdWUpfX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImhhc051bWJlcldpdGhDb21tYXNFcnJvclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJ0cnVlXCI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJpcy1tdC0yXCI+XG4gICAgICAgICAgICBQbGVhc2UgZm9ybWF0IHlvdXIgbnVtYmVycyB0byByZW1vdmUgY29tbWFzIGFuZCB1c2UgYSBkZWNpbWFsIHBvaW50IHRvIHNlcGFyYXRlIHRoZSB3aG9sZSBwYXJ0IG9mIHRoZSBudW1iZXJcbiAgICAgICAgICAgIGZyb20gdGhlIGZyYWN0aW9uYWwgcGFydCBvZiB0aGUgbnVtYmVyLlxuICAgICAgICAgIDwvcD5cblxuICAgICAgICAgIDxwIGNsYXNzPVwiaXMtbXQtMiBoYXMtdGV4dC1kYW5nZXIgaGFzLXRleHQtdW5kZXJsaW5lXCI+SW5jb3JyZWN0OjwvcD5cbiAgICAgICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPjMsNTEwLjE8L2NvZGU+PC9wcmU+XG5cbiAgICAgICAgICA8cCBjbGFzcz1cImlzLW10LTIgaGFzLXRleHQtc3VjY2VzcyBoYXMtdGV4dC11bmRlcmxpbmVcIj5Db3JyZWN0OjwvcD5cbiAgICAgICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPjM1MTAuMTwvY29kZT48L3ByZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiZmFsc2VcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic2NoZW1hRXJyb3JcIj48L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxwPlRoZSBlcnJvciBjb3VsZCBlaXRoZXIgYmUgYSB2YWx1ZSBpbiB0aGUgY29sdW1uLCBvciBhbiBlcnJvciB3aXRoIHRoZSBjb2x1bW4gaGVhZGVyLjwvcD5cbiAgICAgICAgICA8cD5cbiAgICAgICAgICAgIElmIHlvdSBhcmUgdHJ5aW5nIHRvIHNldCBubyBkYXRhLCB3ZSBhY2NlcHQgZWl0aGVyXG4gICAgICAgICAgICA8Y29kZT4tPC9jb2RlPlxuICAgICAgICAgICAgb3IgYW4gZW1wdHkgY2VsbC5cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuUHJvcGVydHlSZXF1aXJlZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwci0xXCI+VGhlIGZvbGxvd2luZyBmaWVsZCBpcyByZXF1aXJlZCBpbiB0aGU8L3NwYW4+XG4gICAgICAgIDxhIGNsYXNzPVwicHItMVwiICpuZ0lmPVwiZXJyb3Iuc2NoZW1hXCIgW2hyZWZdPVwic2NoZW1hVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hIH19PC9hPlxuICAgICAgICA8c3Bhbj5zY2hlbWE6PC9zcGFuPlxuICAgICAgICA8YnIgLz5cbiAgICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLnByb3BlcnR5fX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIFtuZ1N3aXRjaF09XCJlcnJvci5wcm9wZXJ0eVwiPlxuICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2lkJ1wiPlxuICAgICAgICAgIFlvdSBtdXN0IGFzc2lnbiBhIHVuaXF1ZVxuICAgICAgICAgIDxjb2RlPmlkPC9jb2RlPlxuICAgICAgICAgIGZvciBldmVyeSByZWNvcmQgaW4geW91ciBkYXRhLlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCIndHlwZSdcIj5cbiAgICAgICAgICBFdmVyeSByZWNvcmQgaW4geW91ciBkYXRhIG11c3QgY29udGFpbiBhXG4gICAgICAgICAgPGNvZGU+dHlwZTwvY29kZT5cbiAgICAgICAgICAuXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5Qcm9wZXJ0eUludGVybmFsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInByLTFcIj5cbiAgICAgICAgICBUaGUgZm9sbG93aW5nIGZpZWxkIGlzXG4gICAgICAgICAgPGNvZGU+aW50ZXJuYWw8L2NvZGU+XG4gICAgICAgICAgaW4gdGhlXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGEgW2hyZWZdPVwic2NoZW1hS2V5VXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hIH19IHNjaGVtYTwvYT5cbiAgICAgICAgPHNwYW4+Ojwvc3Bhbj5cbiAgICAgICAgPGJyIC8+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5zY2hlbWFLZXkgfHwgZXJyb3Iua2V5fX08L2NvZGU+PC9wcmU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwPlxuICAgICAgICBZb3UgY2Fubm90IHVwbG9hZFxuICAgICAgICA8Y29kZT5pbnRlcm5hbDwvY29kZT5cbiAgICAgICAgZmllbGRzIHRvIEhlc3RpYS5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIlNjaGVtYUVycm9yS2V5cy5TY2hlbWFOb3RGb3VuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4+VGhlIGZvbGxvd2luZyBOb2RlIGRvZXMgbm90IGV4aXN0IGluIHRoZSBzY2hlbWE6PC9zcGFuPlxuICAgICAgICA8YnIgLz5cbiAgICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19PC9jb2RlPjwvcHJlPlxuICAgICAgPC9kaXY+XG4gICAgICA8cD5cbiAgICAgICAgPHNwYW4+VGhlIGxpc3Qgb2YgYWNjZXB0ZWQgdmFsdWVzIGlzOjwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50XCI+XG4gICAgICAgIDx1bD5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHR5cGUgb2Ygbm9kZVR5cGVzXCI+XG4gICAgICAgICAgICA8aT57eyB0eXBlIH19PC9pPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5VcGxvYWRzTGltaXRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICAgIDxzcGFuPllvdSBoYXZlIHJlYWNoZWQgdGhlIHVwbG9hZCBsaW1pdCBvZjwvc3Bhbj5cbiAgICAgICAgPGNvZGUgY2xhc3M9XCJteC0xXCI+e3sgVXBsb2FkTGltaXRbZXJyb3Iuc2NoZW1hXSB9fTwvY29kZT5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAge3sgZXJyb3Iuc2NoZW1hIH19IGluIGEgc2luZ2xlIGZpbGUgKFxuICAgICAgICAgIDxiPnt7IGVycm9yLnZhbHVlIH19PC9iPlxuICAgICAgICAgIGhhdmUgYmVlbiBmb3VuZCkuXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8cD5cbiAgICAgICAgPHNwYW4+UGxlYXNlIHJlLXVwbG9hZCB0aGVzZSBkYXRhIGluIG11bHRpcGxlIGZpbGVzIHdpdGggYSBtYXhpbXVtIG9mPC9zcGFuPlxuICAgICAgICA8Y29kZSBjbGFzcz1cIm14LTFcIj57eyBVcGxvYWRMaW1pdFtlcnJvci5zY2hlbWFdIH19PC9jb2RlPlxuICAgICAgICA8c3Bhbj57eyBlcnJvci5zY2hlbWEgfX0gaW4gZWFjaCBmaWxlLjwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIkVycm9yS2V5cy5JbnZhbGlkRmlyc3RDb2x1bW5cIj5cbiAgICAgIDxzcGFuPlxuICAgICAgICBObyBkYXRhIGluIHRoZSBIZXN0aWEgZm9ybWF0IHdhcyBkZXRlY3RlZCBvbiB0aGUgZmlyc3Qgc2hlZXQuIEVpdGhlciB0cnkgc2VsZWN0aW5nIGEgZGlmZmVyZW50IHNoZWV0IGluIHRoZVxuICAgICAgICB1cGxvYWQgc2NyZWVuLCBvciBjaGVjayB0aGUgc2hlZXQgdG8gZW5zdXJlIHRoZSBoZWFkZXJzIGZvbGxvdyB0aGUgc2NoZW1hIC0gc2VlIGV4YW1wbGVzXG4gICAgICA8L3NwYW4+XG4gICAgICA8YSBjbGFzcz1cInBsLTFcIiByb3V0ZXJMaW5rPVwiL3VwbG9hZFwiIGZyYWdtZW50PVwiZXhhbXBsZVwiPmhlcmU8L2E+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTm9IZWFkZXJzXCI+XG4gICAgICA8cD5cbiAgICAgICAgTm8gaGVhZGVycyBtYXRjaGluZyB0aGUgSGVzdGlhIHNjaGVtYSB3ZXJlIGZvdW5kIG9uIHRoZSBmaXJzdCByb3cuIFBsZWFzZSByZW1vdmUgYWxsIGVtcHR5IHJvd3MgYXQgdGhlIGJlZ2luaW5nXG4gICAgICAgIG9mIHRoZSBmaWxlIGFuZCB0cnkgdXBsb2FkaW5nIGFnYWluLlxuICAgICAgPC9wPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVmYXVsdEVycm9yXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuSW52YWxpZFNoZWV0TmFtZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwci0xXCI+VGhlIEV4Y2VsIHNoZWV0PC9zcGFuPlxuICAgICAgICA8Y29kZT57eyBlcnJvci52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+ZG9lcyBub3QgZXhpc3QuPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj5Zb3VyIEV4Y2VsIGZpbGUgY29udGFpbnMgdGhlIGZvbGxvd2luZyBzaGVldHM6PC9zcGFuPlxuICAgICAgICA8dWwgY2xhc3M9XCJtdC0xIGNvbnRlbnQgaXMtbGlzdC1zdHlsZS1kaXNjIHBsLTVcIj5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGUgb2YgZXJyb3IuZXJyb3Iuc3BsaXQoJzsnKVwiPlxuICAgICAgICAgICAgPGNvZGU+e3sgZSB9fTwvY29kZT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxwPlxuICAgICAgICA8c3Bhbj5QbGVhc2UgcmUtdXBsb2FkIHNlbGVjdGluZyBvbmUgb2YgdGhlIHNoZWV0cyBhYm92ZS48L3NwYW4+XG4gICAgICA8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuRHVwbGljYXRlZEhlYWRlcnNcIj5cbiAgICAgIDxzcGFuPllvdXIgdXBsb2FkIGNvbnRhaW5zIGR1cGxpY2F0ZWQgY29sdW1uIGhlYWRlcnMuPC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdTd2l0Y2hDYXNlPVwiRXJyb3JLZXlzLkR1cGxpY2F0ZWRJZHNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwicHItMVwiPllvdSBoYXZlIG11bHRpcGxlPC9zcGFuPlxuICAgICAgPGNvZGU+e3sgZXJyb3Iuc2NoZW1hIHwgcGx1cmFsaXplIH19PC9jb2RlPlxuICAgICAgPHNwYW4gY2xhc3M9XCJweC0xXCI+d2l0aCB0aGUgc2FtZTwvc3Bhbj5cbiAgICAgIDxhIFtocmVmXT1cInNjaGVtYUtleVVybFwiIHRhcmdldD1cIl9ibGFua1wiPnt7IGVycm9yLnNjaGVtYUtleSB9fTwvYT5cbiAgICAgIDxzcGFuIGNsYXNzPVwicHgtMVwiPmJ1dCBkaWZmZXJlbnQgZGF0YS4gVGhlPC9zcGFuPlxuICAgICAgPGEgW2hyZWZdPVwic2NoZW1hS2V5VXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3sgZXJyb3Iuc2NoZW1hS2V5IH19PC9hPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+aXM6PC9zcGFuPlxuICAgICAgPGJyIC8+XG4gICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPnt7ZXJyb3IudmFsdWV9fTwvY29kZT48L3ByZT5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCIgKm5nU3dpdGNoQ2FzZT1cIlNjaGVtYUVycm9yS2V5cy5EdXBsaWNhdGVkSWRGaWVsZHNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPllvdSBoYXZlIHVzZWQgYm90aCB0aGU8L3NwYW4+XG4gICAgICA8Y29kZT5AaWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj5hbmQ8L3NwYW4+XG4gICAgICA8Y29kZT5pZDwvY29kZT5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHgtMVwiPmZpZWxkcyBpbiB0aGUgc2FtZSBkYXRhLiBQbGVhc2UgdXNlPC9zcGFuPlxuICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1weC0xXCI+d2hlbiBsaW5raW5nIHRvIGV4aXN0aW5nIG5vZGVzIG9uIHRoZSBQbGF0Zm9ybSwgYW5kPC9zcGFuPlxuICAgICAgPGNvZGU+aWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj53aGVuIGxpbmtpbmcgdG8gbm9kZXMgeW91IGFyZSB1cGxvYWRpbmcgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBzYW1lPC9zcGFuPlxuICAgICAgPGNvZGU+aWQ8L2NvZGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXB4LTFcIj5maWVsZC48L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTmVzdGVkSGVhZGVyc1wiPlxuICAgICAgPHA+XG4gICAgICAgIFRvIGxpbmsgbm9kZXMgdG9nZXRoZXIsIHlvdSBmaXJzdCBuZWVkIHRvIGRlZmluZSB0aGUgbm9kZSAoZS5nLixcbiAgICAgICAgPGNvZGU+c291cmNlLmlkPC9jb2RlPlxuICAgICAgICAsXG4gICAgICAgIDxjb2RlPnNvdXJjZS5iaWJsaW9ncmFwaHkudGl0bGU8L2NvZGU+XG4gICAgICAgICkgYW5kIHRoZW4gY3JlYXRlIHRoZSBsaW5rIChlLmcuLFxuICAgICAgICA8Y29kZT5jeWNsZS5kZWZhdWx0U291cmNlLmlkPC9jb2RlPlxuICAgICAgICApLiBXZSBkbyBub3QgYWxsb3cgbmVzdGluZyAoZS5nLixcbiAgICAgICAgPGNvZGU+Y3ljbGUuZGVmYXVsdFNvdXJjZS5iaWJsaW9ncmFwaHkudGl0bGU8L2NvZGU+XG4gICAgICAgICkuXG4gICAgICA8L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuUmVmZXJlbmNlRXhpc3RpbmdIZWFkZXJzXCI+XG4gICAgICA8cD5cbiAgICAgICAgWW91IGhhdmUgdXNlZCB0aGUgaW50ZXJuYWxcbiAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICBmaWVsZCB0byB1cGxvYWQgYSBuZXcgTm9kZS5cbiAgICAgIDwvcD5cbiAgICAgIDxwPlxuICAgICAgICBUaGVcbiAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICBmaWVsZCBzaG91bGQgb25seSBiZSB1c2VkIHRvIHJlZmVyZW5jZSBleGlzdGluZyBOb2RlIG9yIFRlcm1zLiBFeGFtcGxlOlxuICAgICAgPC9wPlxuXG4gICAgICA8cCBjbGFzcz1cImlzLW10LTIgaGFzLXRleHQtZGFuZ2VyIGhhcy10ZXh0LXVuZGVybGluZVwiPkluY29ycmVjdDo8L3A+XG4gICAgICA8cHJlIGNsYXNzPVwiaXMtbXQtMlwiPjxjb2RlPmN5Y2xlLkBpZCxjeWNsZS5pbnB1dHMuMC50ZXJtLkBpZCxzb3VyY2UuaWQ8L2NvZGU+PC9wcmU+XG5cbiAgICAgIDxwIGNsYXNzPVwiaXMtbXQtMiBoYXMtdGV4dC1zdWNjZXNzIGhhcy10ZXh0LXVuZGVybGluZVwiPkNvcnJlY3Q6PC9wPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT5jeWNsZS5pZCxjeWNsZS5pbnB1dHMuMC50ZXJtLkBpZCxzb3VyY2UuaWQ8L2NvZGU+PC9wcmU+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJTY2hlbWFFcnJvcktleXMuT2JqZWN0QXJyYXlJbnZhbGlkXCI+XG4gICAgICA8cD5UaGUgdmFsdWVzIGluIHRoZSBjb2x1bW4ge3sgZXJyb3Iua2V5IH19IG11c3QgYmUgcmVwcmVzZW50ZWQgYXMgYXJyYXlzLjwvcD5cblxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInNjaGVtYUVycm9yXCI+PC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxwPkV4YW1wbGVzOjwvcD5cbiAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5rZXl9fS4wLnRlcm0ubmFtZTwvY29kZT48L3ByZT5cbiAgICAgIDxwcmUgY2xhc3M9XCJpcy1tdC0yXCI+PGNvZGU+e3tlcnJvci5rZXl9fS4wLnZhbHVlPC9jb2RlPjwvcHJlPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19LjEudGVybS5uYW1lPC9jb2RlPjwvcHJlPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e2Vycm9yLmtleX19LjEudmFsdWU8L2NvZGU+PC9wcmU+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTWF4U2l6ZVwiPlxuICAgICAgPHNwYW4+VGhlIG1heGltdW0gZmlsZSBzaXplIGxpbWl0IGlzIHt7IG1heEZpbGVTaXplTWIgfX1NYiAoY3VycmVudCBmaWxlIHNpemU6IHt7IGVycm9yLnZhbHVlIH19TWIpLjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPlBsZWFzZSByZS11cGxvYWQgdGhlc2UgZGF0YSBpbiBtdWx0aXBsZSBmaWxlcy48L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaXMtbWItMlwiICpuZ1N3aXRjaENhc2U9XCJFcnJvcktleXMuTWF4Um93c1wiPlxuICAgICAgPHNwYW4+XG4gICAgICAgIFlvdXIgZmlsZSBoYXMge3sgZXJyb3IudmFsdWUgfCBudW1iZXIgfX0gcm93cy4gVGhpcyBtaWdodCBiZSBhbiBlcnJvciBjYXVzZWQgYnkgYWRkaW5nIHNvbWUgZGF0YSBhdCB0aGUgYm90dG9tXG4gICAgICAgIG9mIGEgc3ByZWFkc2hlZXQgYnkgYWNjaWRlbnQ6IGRlbGV0ZSBhbnkgdW51c2VkIHJvd3MgYW5kIHJlc3VibWl0IHRoZSBmaWxlLlxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIiAqbmdJZj1cImhhc0dlb0pTT05FcnJvclwiPlxuICAgICAgPHA+SWYgdGhlIEdlb0pTT04gaXMgdG9vIGxhcmdlLCBwbGVhc2UgdHJ5IHRvIHNpbXBsaWZ5IGl0IGZvbGxvd2luZyB0aGVzZSBzdGVwczo8L3A+XG4gICAgICA8dWwgY2xhc3M9XCJpcy1teS0xIGNvbnRlbnQgaXMtbGlzdC1zdHlsZS1kZWNpbWFsIHBsLTVcIj5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPkdvIHRvPC9zcGFuPlxuICAgICAgICAgIDxhIGhyZWY9XCJodHRwczovL21hcHNoYXBlci5vcmcvXCIgdGFyZ2V0PVwiX2JsYW5rXCI+aHR0cHM6Ly9tYXBzaGFwZXIub3JnLzwvYT5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgU2F2ZSB0aGUgYm91bmRhcnkgaW4gYSB2YWxpZFxuICAgICAgICAgICAgPGNvZGU+Lmdlb2pzb248L2NvZGU+XG4gICAgICAgICAgICBmaWxlLlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpPlxuICAgICAgICAgIDxzcGFuPkltcG9ydCBpdCBvbiBtYXBzaGFwZXIuPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGk+XG4gICAgICAgICAgPHNwYW4+Q2xpY2sgXCJTaW1wbGlmeVwiIGluIHRoZSB0b3AgcmlnaHQgY29ybmVyIGluIHRoZSBtZW51IGJhci48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaT5cbiAgICAgICAgICA8c3Bhbj5BZGp1c3QgdGhlIHBlcmNlbnRhZ2UgdG8gYSBsb3dlciB2YWx1ZSwgbGlrZSA1MCUgdG8gc3RhcnQgd2l0aC48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaT5cbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIEV4cG9ydCB0b1xuICAgICAgICAgICAgPGNvZGU+R2VvSnNvbjwvY29kZT5cbiAgICAgICAgICAgIG9yXG4gICAgICAgICAgICA8Y29kZT5DU1Y8L2NvZGU+XG4gICAgICAgICAgICAuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGk+XG4gICAgICAgICAgPHNwYW4+Q29weSB0aGUgcmVzdWx0aW5nIGNvbnRlbnQgaW50byB5b3VyIHVwbG9hZCBmaWxlLjwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgICA8cD5JZiB5b3UgZW5jb3VudGVyIHRoZSBlcnJvciBhZ2FpbiwgdHJ5IGFnYWluIHVzaW5nIGEgbG93ZXIgcGVyY2VudGFnZSBhdCBzdGVwIDUuPC9wPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm15LTNcIiAqbmdJZj1cImNvbHVtbnMubGVuZ3RoIHx8IChlcnJvci5pbmRleCAmJiAhaXNTY2hlbWFFcnJvcilcIj5cbiAgICAgIDxiPkhpbnQ6PC9iPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+dGhlIGVycm9yIG1pZ2h0IGJlIGxvY2F0ZWQ8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cImVycm9yLmluZGV4ICYmICFpc1NjaGVtYUVycm9yXCI+b24gcm93IHt7IGVycm9yLmluZGV4IH19PC9zcGFuPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbnMubGVuZ3RoXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPmluIHt7ICdjb2x1bW4nIHwgcGx1cmFsaXplOiBjb2x1bW5zLmxlbmd0aCB9fTo8L3NwYW4+XG4gICAgICAgIDx1bCBjbGFzcz1cIm10LTEgY29udGVudCBpcy1saXN0LXN0eWxlLWRpc2MgcGwtNVwiPlxuICAgICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnNcIj5cbiAgICAgICAgICAgIDxiIGNsYXNzPVwicHItMlwiPnt7IGNvbHVtbi5jb2x1bW4gfX08L2I+XG4gICAgICAgICAgICA8Y29kZT57eyBjb2x1bW4ubmFtZSB9fTwvY29kZT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibXktM1wiICpuZ0lmPVwiZXJyb3Iuc3VnZ2VzdGlvbnM/Lmxlbmd0aFwiPlxuICAgICAgPGI+U3VnZ2VzdGlvbnM6PC9iPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+ZGlkIHlvdSBtZWFuIGluc3RlYWQ6PC9zcGFuPlxuICAgICAgPHVsIGNsYXNzPVwibXQtMSBjb250ZW50IGlzLWxpc3Qtc3R5bGUtZGlzYyBwbC01XCI+XG4gICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgc3VnZ2VzdGlvbiBvZiBlcnJvci5zdWdnZXN0aW9uc1wiPlxuICAgICAgICAgIDxjb2RlPnt7IHN1Z2dlc3Rpb24gfX08L2NvZGU+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cInNob3dDc3ZQcmV2aWV3XCIgY2xhc3M9XCJpcy1teS0yXCI+XG4gICAgICA8Yj5cbiAgICAgICAgUHJldmlld1xuICAgICAgICA8c3VwPjE8L3N1cD5cbiAgICAgICAgOlxuICAgICAgPC9iPlxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lciBpcy1tdC0yXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWJvcmRlcmVkIGlzLWZ1bGx3aWR0aCBpcy1ob3ZlcmFibGUgaXMtbmFycm93IG1iLTBcIj5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dGggKm5nSWY9XCJlcnJvci5pbmRleFwiPjwvdGg+XG4gICAgICAgICAgICA8dGggKm5nRm9yPVwibGV0IGhlYWRlciBvZiBoZWFkZXJzXCI+e3sgaGVhZGVyIH19PC90aD5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKmJpbmRPbmNlPVwicm93c1wiPlxuICAgICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHJvdyBvZiByb3dzXCI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtZGFuZ2VyXCIgKm5nSWY9XCJlcnJvci5pbmRleFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXBcIj5Sb3cge3sgZXJyb3IuaW5kZXggfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbCBvZiByb3c7IGxldCBjb2xJbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaGFzLXRleHQtZGFuZ2VyXT1cIlxuICAgICAgICAgICAgICAgICAgICAgIGVycm9yPy5tZXNzYWdlID09PSBFcnJvcktleXMuRHVwbGljYXRlZElkcyAmJiBoYXNEdXBsaWNhdGVkRXJyb3IoY29sLCBjb2xJbmRleClcbiAgICAgICAgICAgICAgICAgICAgXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGNvbCB8IGVsbGlwc2lzOiA1MCB9fVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgICA8cCBjbGFzcz1cImlzLXNpemUtN1wiPlxuICAgICAgICA8aT4xLiBUaGUgcHJldmlldyBkb2VzIG5vdCBuZWNlc3NhcmlseSByZWZsZWN0IHRoZSBvcmlnaW5hbCBVcGxvYWQncyBvcmRlciBvciBjb250ZW50LjwvaT5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCJzaG93SnNvblByZXZpZXdcIiBjbGFzcz1cImlzLW15LTJcIj5cbiAgICAgIDxiPlByZXZpZXc6PC9iPlxuICAgICAgPHByZSBjbGFzcz1cImlzLW10LTJcIj48Y29kZT57e3N0cmluZ2lmeShlcnJvci5ub2RlKX19PC9jb2RlPjwvcHJlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctdGVtcGxhdGUgI2RlZmF1bHRFcnJvcj5cbiAgPHAgY2xhc3M9XCJpcy1tdC0yIGhhcy10ZXh0LWJsYWNrXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1wci0xXCI+SWYgeW91IGFyZSBzdGlsbCBzdHVjaywgcGxlYXNlIHNlZTwvc3Bhbj5cbiAgICA8YSBbaHJlZl09XCJiYXNlVXJsICsgJy91cGxvYWQjZXhhbXBsZSdcIiB0YXJnZXQ9XCJfYmxhbmtcIj50aGUgZXhhbXBsZSB1cGxvYWRzIGFuZCB2aWRlb3M8L2E+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1weC0xXCI+XG4gICAgICBvciB0cnkgdXNpbmcgdGhlIFdpemFyZCB0byBnZXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIGRhdGEgZm9ybWF0dGVkIGNvcnJlY3RseSwgb3IgdXNlIHRoZSBjaGF0IHRvIGFzayBmb3IgaGVscC5cbiAgICA8L3NwYW4+XG4gIDwvcD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjc2NoZW1hRXJyb3I+XG4gIDxwPlxuICAgIDxzcGFuIGNsYXNzPVwicHItMVwiPllvdSBjYW4gc2VlIHRoZSBhY2NlcHRlZCBmaWVsZCB0eXBlIGFuZCBzb21lIGV4YW1wbGVzPC9zcGFuPlxuICAgIDxhIFtocmVmXT1cInNjaGVtYUtleVVybFwiIHRhcmdldD1cIl9ibGFua1wiPmhlcmU8L2E+XG4gICAgPHNwYW4+Ljwvc3Bhbj5cbiAgPC9wPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
@@ -94,11 +94,11 @@ export class NodeCsvSelectHeadersComponent {
94
94
  });
95
95
  }
96
96
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeCsvSelectHeadersComponent, deps: [{ token: i1.HeSchemaService }], target: i0.ɵɵFactoryTarget.Component }); }
97
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeCsvSelectHeadersComponent, selector: "he-node-csv-select-headers", inputs: { csv: "csv", keys: "keys", includeDefaultCSV: "includeDefaultCSV" }, outputs: { headersChanged: "headersChanged" }, ngImport: i0, template: "<p class=\"mb-2\">Please select which columns you would like to include:</p>\n\n<p class=\"my-2 is-size-7\">\n <i>You can drag and drop the headers to sort them as they would appear in the CSV file.</i>\n</p>\n\n<div class=\"columns toggle-all mx-4 pb-1 mb-0\">\n <div class=\"column\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"allSelected\" (change)=\"toggleAll(); refresh()\" />\n <span class=\"ml-2\">Toggle All</span>\n </label>\n </div>\n\n <div class=\"column is-narrow has-text-right\">\n <div\n class=\"dropdown is-right has-text-left\"\n [class.is-active]=\"showSelectTermFields\"\n (clickOutside)=\"showSelectTermFields = false\">\n <div class=\"dropdown-trigger\" (click)=\"showSelectTermFields = !showSelectTermFields\">\n <button class=\"button is-small\" aria-haspopup=\"true\" aria-controls=\"select-menu\">\n <span>Advanced Filters</span>\n <span class=\"icon is-small\">\n <fa-icon icon=\"filter\" aria-hidden=\"true\"></fa-icon>\n </span>\n </button>\n </div>\n <div class=\"dropdown-menu\" id=\"select-menu\" role=\"menu\">\n <div class=\"dropdown-content\">\n <a class=\"dropdown-item\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"showNonIncluded\" (change)=\"refresh()\" />\n <span class=\"ml-2\">\n Include\n <code>internal</code>\n fields\n </span>\n </label>\n </a>\n <div class=\"dropdown-item\">\n <p>Toggle Term Fields</p>\n </div>\n <a class=\"dropdown-item\" *ngFor=\"let field of termFields\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"termFieldSelected[field]\"\n (change)=\"toggleTermField(field)\" />\n <span class=\"ml-2\">{{ field }}</span>\n </label>\n </a>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"drag-container\" *ngIf=\"!loading; else loader\">\n <div class=\"card\" *ngFor=\"let group of headers | keys\">\n <header class=\"card-header\" *ngIf=\"group.key\">\n <div class=\"card-header-title\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [indeterminate]=\"group.value.partialSelected\"\n [(ngModel)]=\"group.value.selected\"\n (change)=\"updateGroup(group.key); refresh()\" />\n <span class=\"ml-2\">{{ group.key }}</span>\n </label>\n </div>\n <span\n class=\"card-header-icon has-text-secondary\"\n aria-label=\"open / close\"\n (click)=\"group.value.open = !group.value.open\"\n pointer>\n <span class=\"icon\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!group.value.open\"></fa-icon>\n <fa-icon icon=\"angle-left\" [class.is-hidden]=\"group.value.open\"></fa-icon>\n </span>\n </span>\n </header>\n\n <div class=\"card-content p-3\" [class.is-hidden]=\"!group.value.open\">\n <ul cdkDropList (cdkDropListDropped)=\"dropHeader($event, group.key)\">\n <ng-container *ngFor=\"let header of group.value.headers\">\n <ng-container *ngIf=\"header.included || showNonIncluded\">\n <li cdkDrag>\n <label class=\"checkbox ml-2\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"header.selected\"\n (change)=\"updateGroupHeader(group.key); refresh()\" />\n <span class=\"ml-2\">{{ header.header }}</span>\n </label>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [".toggle-all{border-bottom:1px solid #4A4A4A}.drag-container,.table-container{max-height:45vh;overflow-y:auto}.cdk-drag-preview{border-radius:3px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i5.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i6.ClickOutsideDirective, selector: "[clickOutside]", outputs: ["clickOutside"] }, { kind: "pipe", type: i7.KeysPipe, name: "keys" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
97
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeCsvSelectHeadersComponent, selector: "he-node-csv-select-headers", inputs: { csv: "csv", keys: "keys", includeDefaultCSV: "includeDefaultCSV" }, outputs: { headersChanged: "headersChanged" }, ngImport: i0, template: "<p class=\"mb-2\">Please select which columns you would like to include:</p>\n\n<p class=\"my-2 is-size-7\">\n <i>You can drag and drop the headers to sort them as they would appear in the CSV file.</i>\n</p>\n\n<div class=\"columns toggle-all mx-4 pb-1 mb-0\">\n <div class=\"column\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"allSelected\" (change)=\"toggleAll(); refresh()\" />\n <span class=\"ml-2\">Toggle All</span>\n </label>\n </div>\n\n <div class=\"column is-narrow has-text-right\">\n <div\n class=\"dropdown is-right has-text-left\"\n [class.is-active]=\"showSelectTermFields\"\n (clickOutside)=\"showSelectTermFields = false\">\n <div class=\"dropdown-trigger\" (click)=\"showSelectTermFields = !showSelectTermFields\">\n <button class=\"button is-small\" aria-haspopup=\"true\" aria-controls=\"select-menu\">\n <span>Advanced Filters</span>\n <span class=\"icon is-small\">\n <fa-icon icon=\"filter\" aria-hidden=\"true\"></fa-icon>\n </span>\n </button>\n </div>\n <div class=\"dropdown-menu\" id=\"select-menu\" role=\"menu\">\n <div class=\"dropdown-content\">\n <a class=\"dropdown-item\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"showNonIncluded\" (change)=\"refresh()\" />\n <span class=\"ml-2\">\n Include\n <code>internal</code>\n fields\n </span>\n </label>\n </a>\n <div class=\"dropdown-item\">\n <p>Toggle Term Fields</p>\n </div>\n <a class=\"dropdown-item\" *ngFor=\"let field of termFields\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"termFieldSelected[field]\"\n (change)=\"toggleTermField(field)\" />\n <span class=\"ml-2\">{{ field }}</span>\n </label>\n </a>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"drag-container\" *ngIf=\"!loading; else loader\">\n <div class=\"card\" *ngFor=\"let group of headers | keys\">\n <header class=\"card-header\" *ngIf=\"group.key\">\n <div class=\"card-header-title\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [indeterminate]=\"group.value.partialSelected\"\n [(ngModel)]=\"group.value.selected\"\n (change)=\"updateGroup(group.key); refresh()\" />\n <span class=\"ml-2\">{{ group.key }}</span>\n </label>\n </div>\n <span\n class=\"card-header-icon has-text-secondary\"\n aria-label=\"open / close\"\n (click)=\"group.value.open = !group.value.open\"\n pointer>\n <span class=\"icon\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!group.value.open\"></fa-icon>\n <fa-icon icon=\"angle-left\" [class.is-hidden]=\"group.value.open\"></fa-icon>\n </span>\n </span>\n </header>\n\n <div class=\"card-content p-3\" [class.is-hidden]=\"!group.value.open\">\n <ul cdkDropList (cdkDropListDropped)=\"dropHeader($event, group.key)\">\n <ng-container *ngFor=\"let header of group.value.headers\">\n <ng-container *ngIf=\"header.included || showNonIncluded\">\n <li cdkDrag>\n <label class=\"checkbox ml-2\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"header.selected\"\n (change)=\"updateGroupHeader(group.key); refresh()\" />\n <span class=\"ml-2\">{{ header.header }}</span>\n </label>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [".toggle-all{border-bottom:1px solid #4a4a4a}.drag-container,.table-container{max-height:45vh;overflow-y:auto}.cdk-drag-preview{border-radius:3px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i5.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i6.ClickOutsideDirective, selector: "[clickOutside]", outputs: ["clickOutside"] }, { kind: "pipe", type: i7.KeysPipe, name: "keys" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
98
98
  }
99
99
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeCsvSelectHeadersComponent, decorators: [{
100
100
  type: Component,
101
- args: [{ selector: 'he-node-csv-select-headers', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p class=\"mb-2\">Please select which columns you would like to include:</p>\n\n<p class=\"my-2 is-size-7\">\n <i>You can drag and drop the headers to sort them as they would appear in the CSV file.</i>\n</p>\n\n<div class=\"columns toggle-all mx-4 pb-1 mb-0\">\n <div class=\"column\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"allSelected\" (change)=\"toggleAll(); refresh()\" />\n <span class=\"ml-2\">Toggle All</span>\n </label>\n </div>\n\n <div class=\"column is-narrow has-text-right\">\n <div\n class=\"dropdown is-right has-text-left\"\n [class.is-active]=\"showSelectTermFields\"\n (clickOutside)=\"showSelectTermFields = false\">\n <div class=\"dropdown-trigger\" (click)=\"showSelectTermFields = !showSelectTermFields\">\n <button class=\"button is-small\" aria-haspopup=\"true\" aria-controls=\"select-menu\">\n <span>Advanced Filters</span>\n <span class=\"icon is-small\">\n <fa-icon icon=\"filter\" aria-hidden=\"true\"></fa-icon>\n </span>\n </button>\n </div>\n <div class=\"dropdown-menu\" id=\"select-menu\" role=\"menu\">\n <div class=\"dropdown-content\">\n <a class=\"dropdown-item\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"showNonIncluded\" (change)=\"refresh()\" />\n <span class=\"ml-2\">\n Include\n <code>internal</code>\n fields\n </span>\n </label>\n </a>\n <div class=\"dropdown-item\">\n <p>Toggle Term Fields</p>\n </div>\n <a class=\"dropdown-item\" *ngFor=\"let field of termFields\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"termFieldSelected[field]\"\n (change)=\"toggleTermField(field)\" />\n <span class=\"ml-2\">{{ field }}</span>\n </label>\n </a>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"drag-container\" *ngIf=\"!loading; else loader\">\n <div class=\"card\" *ngFor=\"let group of headers | keys\">\n <header class=\"card-header\" *ngIf=\"group.key\">\n <div class=\"card-header-title\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [indeterminate]=\"group.value.partialSelected\"\n [(ngModel)]=\"group.value.selected\"\n (change)=\"updateGroup(group.key); refresh()\" />\n <span class=\"ml-2\">{{ group.key }}</span>\n </label>\n </div>\n <span\n class=\"card-header-icon has-text-secondary\"\n aria-label=\"open / close\"\n (click)=\"group.value.open = !group.value.open\"\n pointer>\n <span class=\"icon\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!group.value.open\"></fa-icon>\n <fa-icon icon=\"angle-left\" [class.is-hidden]=\"group.value.open\"></fa-icon>\n </span>\n </span>\n </header>\n\n <div class=\"card-content p-3\" [class.is-hidden]=\"!group.value.open\">\n <ul cdkDropList (cdkDropListDropped)=\"dropHeader($event, group.key)\">\n <ng-container *ngFor=\"let header of group.value.headers\">\n <ng-container *ngIf=\"header.included || showNonIncluded\">\n <li cdkDrag>\n <label class=\"checkbox ml-2\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"header.selected\"\n (change)=\"updateGroupHeader(group.key); refresh()\" />\n <span class=\"ml-2\">{{ header.header }}</span>\n </label>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [".toggle-all{border-bottom:1px solid #4A4A4A}.drag-container,.table-container{max-height:45vh;overflow-y:auto}.cdk-drag-preview{border-radius:3px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
101
+ args: [{ selector: 'he-node-csv-select-headers', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p class=\"mb-2\">Please select which columns you would like to include:</p>\n\n<p class=\"my-2 is-size-7\">\n <i>You can drag and drop the headers to sort them as they would appear in the CSV file.</i>\n</p>\n\n<div class=\"columns toggle-all mx-4 pb-1 mb-0\">\n <div class=\"column\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"allSelected\" (change)=\"toggleAll(); refresh()\" />\n <span class=\"ml-2\">Toggle All</span>\n </label>\n </div>\n\n <div class=\"column is-narrow has-text-right\">\n <div\n class=\"dropdown is-right has-text-left\"\n [class.is-active]=\"showSelectTermFields\"\n (clickOutside)=\"showSelectTermFields = false\">\n <div class=\"dropdown-trigger\" (click)=\"showSelectTermFields = !showSelectTermFields\">\n <button class=\"button is-small\" aria-haspopup=\"true\" aria-controls=\"select-menu\">\n <span>Advanced Filters</span>\n <span class=\"icon is-small\">\n <fa-icon icon=\"filter\" aria-hidden=\"true\"></fa-icon>\n </span>\n </button>\n </div>\n <div class=\"dropdown-menu\" id=\"select-menu\" role=\"menu\">\n <div class=\"dropdown-content\">\n <a class=\"dropdown-item\">\n <label class=\"checkbox ml-1\">\n <input type=\"checkbox\" class=\"selector\" [(ngModel)]=\"showNonIncluded\" (change)=\"refresh()\" />\n <span class=\"ml-2\">\n Include\n <code>internal</code>\n fields\n </span>\n </label>\n </a>\n <div class=\"dropdown-item\">\n <p>Toggle Term Fields</p>\n </div>\n <a class=\"dropdown-item\" *ngFor=\"let field of termFields\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"termFieldSelected[field]\"\n (change)=\"toggleTermField(field)\" />\n <span class=\"ml-2\">{{ field }}</span>\n </label>\n </a>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"drag-container\" *ngIf=\"!loading; else loader\">\n <div class=\"card\" *ngFor=\"let group of headers | keys\">\n <header class=\"card-header\" *ngIf=\"group.key\">\n <div class=\"card-header-title\">\n <label class=\"checkbox ml-1\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [indeterminate]=\"group.value.partialSelected\"\n [(ngModel)]=\"group.value.selected\"\n (change)=\"updateGroup(group.key); refresh()\" />\n <span class=\"ml-2\">{{ group.key }}</span>\n </label>\n </div>\n <span\n class=\"card-header-icon has-text-secondary\"\n aria-label=\"open / close\"\n (click)=\"group.value.open = !group.value.open\"\n pointer>\n <span class=\"icon\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!group.value.open\"></fa-icon>\n <fa-icon icon=\"angle-left\" [class.is-hidden]=\"group.value.open\"></fa-icon>\n </span>\n </span>\n </header>\n\n <div class=\"card-content p-3\" [class.is-hidden]=\"!group.value.open\">\n <ul cdkDropList (cdkDropListDropped)=\"dropHeader($event, group.key)\">\n <ng-container *ngFor=\"let header of group.value.headers\">\n <ng-container *ngIf=\"header.included || showNonIncluded\">\n <li cdkDrag>\n <label class=\"checkbox ml-2\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"header.selected\"\n (change)=\"updateGroupHeader(group.key); refresh()\" />\n <span class=\"ml-2\">{{ header.header }}</span>\n </label>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [".toggle-all{border-bottom:1px solid #4a4a4a}.drag-container,.table-container{max-height:45vh;overflow-y:auto}.cdk-drag-preview{border-radius:3px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
102
102
  }], ctorParameters: function () { return [{ type: i1.HeSchemaService }]; }, propDecorators: { csv: [{
103
103
  type: Input
104
104
  }], keys: [{
@@ -248,7 +248,7 @@ export class SelectComponent extends ControlValueAccessor {
248
248
  provide: SELECT_TOKEN,
249
249
  useExisting: forwardRef(() => SelectComponent)
250
250
  }
251
- ], queries: [{ propertyName: "nodes", predicate: NODE_ELEMENT_TOKEN, descendants: true }, { propertyName: "options", predicate: SELECT_OPTION_TOKEN, descendants: true }], viewQueries: [{ propertyName: "searchInputEl", first: true, predicate: ["input"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <ng-container\n *ngTemplateOutlet=\"\n selectTemplate ?? defaultSelectTemplate;\n context: {\n $implicit: this,\n value,\n displayValue,\n labelState,\n icon,\n placeholder,\n searchPlaceholder,\n width,\n valueTemplate\n }\n \"></ng-container>\n</div>\n\n<ng-template\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n [cdkConnectedOverlayOffsetX]=\"overlayOptions?.offsetX ?? -11\"\n [cdkConnectedOverlayOffsetY]=\"overlayOptions?.offsetY ?? 4\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n cdkConnectedOverlayHasBackdrop>\n <div [style.min-width]=\"width\" class=\"select-panel\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n\n<ng-template #defaultSelectTemplate>\n <div class=\"select-host\">\n <div class=\"control | is-flex is-justify-content-space-between is-align-items-center\">\n <ng-container [ngSwitch]=\"labelState\">\n <input\n #input\n (input)=\"onHandleInput($event)\"\n *ngSwitchCase=\"'search'\"\n [placeholder]=\"searchPlaceholder\"\n class=\"select-search | is-transparent\" />\n\n <ng-container *ngSwitchCase=\"'value'\">\n <ng-container\n *ngTemplateOutlet=\"valueTemplate ?? defaultValueTemplate; context: { $implicit: value }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <span class=\"drop-down-icon ml-2\">\n <fa-icon [icon]=\"icon\"></fa-icon>\n </span>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultValueTemplate>\n <span [ngClass]=\"{ empty: !value }\" class=\"selected-value\">{{ displayValue || placeholder }}</span>\n</ng-template>\n", styles: ["body.is-os-windows::-webkit-scrollbar,body.is-os-windows *::-webkit-scrollbar{border-radius:10px;height:10px;width:10px;border:none;background:transparent}body.is-os-windows::-webkit-scrollbar-button,body.is-os-windows *::-webkit-scrollbar-button{background:#DDE1E6;color:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb,body.is-os-windows *::-webkit-scrollbar-thumb{border-radius:10px;background:#DDE1E6}body.is-os-windows::-webkit-scrollbar-thumb:hover,body.is-os-windows *::-webkit-scrollbar-thumb:hover{background:#DDE1E6}body.is-os-windows::-webkit-scrollbar-track,body.is-os-windows *::-webkit-scrollbar-track{border:none;background-color:transparent;background-repeat:no-repeat;background-image:url(https://cdn.hestia.earth/prod/assets/images/scrollbar-thumb.png);background-position:center}body.is-os-windows::-webkit-scrollbar-track:vertical,body.is-os-windows *::-webkit-scrollbar-track:vertical{background-repeat:repeat-y}body.is-os-windows::-webkit-scrollbar-track:horizontal,body.is-os-windows *::-webkit-scrollbar-track:horizontal{background-repeat:repeat-x}body.is-os-windows .is-dark::-webkit-scrollbar-button{background:#4C7194;color:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb{background:#4C7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb:hover{background:#4C7194}::ng-deep:root{--select-border-radius: 6px;--select-min-width: 250px;--select-shadow: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .06) 0px 2px 4px -1px}.select-host{display:flex;justify-content:flex-start;flex-direction:column;padding:5px 10px;box-sizing:border-box;min-width:var(--select-min-width);border-radius:var(--select-border-radius);border:1px solid #F5F5F5;background:hsl(0,0%,100%);box-shadow:var(--select-shadow)}.select-host:hover{cursor:pointer;background-color:var(--color-background, #eceff1)}.select-host.select-panel-open{position:relative;z-index:1001;border-radius:var(--select-border-radius) var(--select-border-radius) 0 0;box-shadow:none}.select-host.is-disabled{opacity:.5;pointer-events:none;-webkit-user-select:none;user-select:none}.selected-value.empty{opacity:.6}.select-search{border:none;outline:none;background:transparent}.select-panel{box-sizing:border-box;border-radius:0 0 var(--select-border-radius, 6px) var(--select-border-radius, 6px);border:1px solid #F5F5F5;background-color:#fff;transform-origin:top;max-height:350px;overflow:auto;box-shadow:var(--select-shadow)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i3.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
251
+ ], queries: [{ propertyName: "nodes", predicate: NODE_ELEMENT_TOKEN, descendants: true }, { propertyName: "options", predicate: SELECT_OPTION_TOKEN, descendants: true }], viewQueries: [{ propertyName: "searchInputEl", first: true, predicate: ["input"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <ng-container\n *ngTemplateOutlet=\"\n selectTemplate ?? defaultSelectTemplate;\n context: {\n $implicit: this,\n value,\n displayValue,\n labelState,\n icon,\n placeholder,\n searchPlaceholder,\n width,\n valueTemplate\n }\n \"></ng-container>\n</div>\n\n<ng-template\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n [cdkConnectedOverlayOffsetX]=\"overlayOptions?.offsetX ?? -11\"\n [cdkConnectedOverlayOffsetY]=\"overlayOptions?.offsetY ?? 4\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n cdkConnectedOverlayHasBackdrop>\n <div [style.min-width]=\"width\" class=\"select-panel\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n\n<ng-template #defaultSelectTemplate>\n <div class=\"select-host\">\n <div class=\"control | is-flex is-justify-content-space-between is-align-items-center\">\n <ng-container [ngSwitch]=\"labelState\">\n <input\n #input\n (input)=\"onHandleInput($event)\"\n *ngSwitchCase=\"'search'\"\n [placeholder]=\"searchPlaceholder\"\n class=\"select-search | is-transparent\" />\n\n <ng-container *ngSwitchCase=\"'value'\">\n <ng-container\n *ngTemplateOutlet=\"valueTemplate ?? defaultValueTemplate; context: { $implicit: value }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <span class=\"drop-down-icon ml-2\">\n <fa-icon [icon]=\"icon\"></fa-icon>\n </span>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultValueTemplate>\n <span [ngClass]=\"{ empty: !value }\" class=\"selected-value\">{{ displayValue || placeholder }}</span>\n</ng-template>\n", styles: ["body.is-os-windows::-webkit-scrollbar,body.is-os-windows *::-webkit-scrollbar{border-radius:10px;height:10px;width:10px;border:none;background:transparent}body.is-os-windows::-webkit-scrollbar-button,body.is-os-windows *::-webkit-scrollbar-button{background:#dde1e6;color:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb,body.is-os-windows *::-webkit-scrollbar-thumb{border-radius:10px;background:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb:hover,body.is-os-windows *::-webkit-scrollbar-thumb:hover{background:#dde1e6}body.is-os-windows::-webkit-scrollbar-track,body.is-os-windows *::-webkit-scrollbar-track{border:none;background-color:transparent;background-repeat:no-repeat;background-image:url(https://cdn.hestia.earth/prod/assets/images/scrollbar-thumb.png);background-position:center}body.is-os-windows::-webkit-scrollbar-track:vertical,body.is-os-windows *::-webkit-scrollbar-track:vertical{background-repeat:repeat-y}body.is-os-windows::-webkit-scrollbar-track:horizontal,body.is-os-windows *::-webkit-scrollbar-track:horizontal{background-repeat:repeat-x}body.is-os-windows .is-dark::-webkit-scrollbar-button{background:#4c7194;color:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb{background:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb:hover{background:#4c7194}::ng-deep:root{--select-border-radius: 6px;--select-min-width: 250px;--select-shadow: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .06) 0px 2px 4px -1px}.select-host{display:flex;justify-content:flex-start;flex-direction:column;padding:5px 10px;box-sizing:border-box;min-width:var(--select-min-width);border-radius:var(--select-border-radius);border:1px solid #f5f5f5;background:hsl(0,0%,100%);box-shadow:var(--select-shadow)}.select-host:hover{cursor:pointer;background-color:var(--color-background, #eceff1)}.select-host.select-panel-open{position:relative;z-index:1001;border-radius:var(--select-border-radius) var(--select-border-radius) 0 0;box-shadow:none}.select-host.is-disabled{opacity:.5;pointer-events:none;-webkit-user-select:none;user-select:none}.selected-value.empty{opacity:.6}.select-search{border:none;outline:none;background:transparent}.select-panel{box-sizing:border-box;border-radius:0 0 var(--select-border-radius, 6px) var(--select-border-radius, 6px);border:1px solid #f5f5f5;background-color:#fff;transform-origin:top;max-height:350px;overflow:auto;box-shadow:var(--select-shadow)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i3.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
252
252
  }
253
253
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: SelectComponent, decorators: [{
254
254
  type: Component,
@@ -262,7 +262,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
262
262
  provide: SELECT_TOKEN,
263
263
  useExisting: forwardRef(() => SelectComponent)
264
264
  }
265
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <ng-container\n *ngTemplateOutlet=\"\n selectTemplate ?? defaultSelectTemplate;\n context: {\n $implicit: this,\n value,\n displayValue,\n labelState,\n icon,\n placeholder,\n searchPlaceholder,\n width,\n valueTemplate\n }\n \"></ng-container>\n</div>\n\n<ng-template\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n [cdkConnectedOverlayOffsetX]=\"overlayOptions?.offsetX ?? -11\"\n [cdkConnectedOverlayOffsetY]=\"overlayOptions?.offsetY ?? 4\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n cdkConnectedOverlayHasBackdrop>\n <div [style.min-width]=\"width\" class=\"select-panel\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n\n<ng-template #defaultSelectTemplate>\n <div class=\"select-host\">\n <div class=\"control | is-flex is-justify-content-space-between is-align-items-center\">\n <ng-container [ngSwitch]=\"labelState\">\n <input\n #input\n (input)=\"onHandleInput($event)\"\n *ngSwitchCase=\"'search'\"\n [placeholder]=\"searchPlaceholder\"\n class=\"select-search | is-transparent\" />\n\n <ng-container *ngSwitchCase=\"'value'\">\n <ng-container\n *ngTemplateOutlet=\"valueTemplate ?? defaultValueTemplate; context: { $implicit: value }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <span class=\"drop-down-icon ml-2\">\n <fa-icon [icon]=\"icon\"></fa-icon>\n </span>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultValueTemplate>\n <span [ngClass]=\"{ empty: !value }\" class=\"selected-value\">{{ displayValue || placeholder }}</span>\n</ng-template>\n", styles: ["body.is-os-windows::-webkit-scrollbar,body.is-os-windows *::-webkit-scrollbar{border-radius:10px;height:10px;width:10px;border:none;background:transparent}body.is-os-windows::-webkit-scrollbar-button,body.is-os-windows *::-webkit-scrollbar-button{background:#DDE1E6;color:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb,body.is-os-windows *::-webkit-scrollbar-thumb{border-radius:10px;background:#DDE1E6}body.is-os-windows::-webkit-scrollbar-thumb:hover,body.is-os-windows *::-webkit-scrollbar-thumb:hover{background:#DDE1E6}body.is-os-windows::-webkit-scrollbar-track,body.is-os-windows *::-webkit-scrollbar-track{border:none;background-color:transparent;background-repeat:no-repeat;background-image:url(https://cdn.hestia.earth/prod/assets/images/scrollbar-thumb.png);background-position:center}body.is-os-windows::-webkit-scrollbar-track:vertical,body.is-os-windows *::-webkit-scrollbar-track:vertical{background-repeat:repeat-y}body.is-os-windows::-webkit-scrollbar-track:horizontal,body.is-os-windows *::-webkit-scrollbar-track:horizontal{background-repeat:repeat-x}body.is-os-windows .is-dark::-webkit-scrollbar-button{background:#4C7194;color:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb{background:#4C7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb:hover{background:#4C7194}::ng-deep:root{--select-border-radius: 6px;--select-min-width: 250px;--select-shadow: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .06) 0px 2px 4px -1px}.select-host{display:flex;justify-content:flex-start;flex-direction:column;padding:5px 10px;box-sizing:border-box;min-width:var(--select-min-width);border-radius:var(--select-border-radius);border:1px solid #F5F5F5;background:hsl(0,0%,100%);box-shadow:var(--select-shadow)}.select-host:hover{cursor:pointer;background-color:var(--color-background, #eceff1)}.select-host.select-panel-open{position:relative;z-index:1001;border-radius:var(--select-border-radius) var(--select-border-radius) 0 0;box-shadow:none}.select-host.is-disabled{opacity:.5;pointer-events:none;-webkit-user-select:none;user-select:none}.selected-value.empty{opacity:.6}.select-search{border:none;outline:none;background:transparent}.select-panel{box-sizing:border-box;border-radius:0 0 var(--select-border-radius, 6px) var(--select-border-radius, 6px);border:1px solid #F5F5F5;background-color:#fff;transform-origin:top;max-height:350px;overflow:auto;box-shadow:var(--select-shadow)}\n"] }]
265
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <ng-container\n *ngTemplateOutlet=\"\n selectTemplate ?? defaultSelectTemplate;\n context: {\n $implicit: this,\n value,\n displayValue,\n labelState,\n icon,\n placeholder,\n searchPlaceholder,\n width,\n valueTemplate\n }\n \"></ng-container>\n</div>\n\n<ng-template\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n [cdkConnectedOverlayOffsetX]=\"overlayOptions?.offsetX ?? -11\"\n [cdkConnectedOverlayOffsetY]=\"overlayOptions?.offsetY ?? 4\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n cdkConnectedOverlayHasBackdrop>\n <div [style.min-width]=\"width\" class=\"select-panel\">\n <ng-content></ng-content>\n </div>\n</ng-template>\n\n<ng-template #defaultSelectTemplate>\n <div class=\"select-host\">\n <div class=\"control | is-flex is-justify-content-space-between is-align-items-center\">\n <ng-container [ngSwitch]=\"labelState\">\n <input\n #input\n (input)=\"onHandleInput($event)\"\n *ngSwitchCase=\"'search'\"\n [placeholder]=\"searchPlaceholder\"\n class=\"select-search | is-transparent\" />\n\n <ng-container *ngSwitchCase=\"'value'\">\n <ng-container\n *ngTemplateOutlet=\"valueTemplate ?? defaultValueTemplate; context: { $implicit: value }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <span class=\"drop-down-icon ml-2\">\n <fa-icon [icon]=\"icon\"></fa-icon>\n </span>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultValueTemplate>\n <span [ngClass]=\"{ empty: !value }\" class=\"selected-value\">{{ displayValue || placeholder }}</span>\n</ng-template>\n", styles: ["body.is-os-windows::-webkit-scrollbar,body.is-os-windows *::-webkit-scrollbar{border-radius:10px;height:10px;width:10px;border:none;background:transparent}body.is-os-windows::-webkit-scrollbar-button,body.is-os-windows *::-webkit-scrollbar-button{background:#dde1e6;color:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb,body.is-os-windows *::-webkit-scrollbar-thumb{border-radius:10px;background:#dde1e6}body.is-os-windows::-webkit-scrollbar-thumb:hover,body.is-os-windows *::-webkit-scrollbar-thumb:hover{background:#dde1e6}body.is-os-windows::-webkit-scrollbar-track,body.is-os-windows *::-webkit-scrollbar-track{border:none;background-color:transparent;background-repeat:no-repeat;background-image:url(https://cdn.hestia.earth/prod/assets/images/scrollbar-thumb.png);background-position:center}body.is-os-windows::-webkit-scrollbar-track:vertical,body.is-os-windows *::-webkit-scrollbar-track:vertical{background-repeat:repeat-y}body.is-os-windows::-webkit-scrollbar-track:horizontal,body.is-os-windows *::-webkit-scrollbar-track:horizontal{background-repeat:repeat-x}body.is-os-windows .is-dark::-webkit-scrollbar-button{background:#4c7194;color:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb{background:#4c7194}body.is-os-windows .is-dark::-webkit-scrollbar-thumb:hover{background:#4c7194}::ng-deep:root{--select-border-radius: 6px;--select-min-width: 250px;--select-shadow: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .06) 0px 2px 4px -1px}.select-host{display:flex;justify-content:flex-start;flex-direction:column;padding:5px 10px;box-sizing:border-box;min-width:var(--select-min-width);border-radius:var(--select-border-radius);border:1px solid #f5f5f5;background:hsl(0,0%,100%);box-shadow:var(--select-shadow)}.select-host:hover{cursor:pointer;background-color:var(--color-background, #eceff1)}.select-host.select-panel-open{position:relative;z-index:1001;border-radius:var(--select-border-radius) var(--select-border-radius) 0 0;box-shadow:none}.select-host.is-disabled{opacity:.5;pointer-events:none;-webkit-user-select:none;user-select:none}.selected-value.empty{opacity:.6}.select-search{border:none;outline:none;background:transparent}.select-panel{box-sizing:border-box;border-radius:0 0 var(--select-border-radius, 6px) var(--select-border-radius, 6px);border:1px solid #f5f5f5;background-color:#fff;transform-origin:top;max-height:350px;overflow:auto;box-shadow:var(--select-shadow)}\n"] }]
266
266
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.DestroyRef }]; }, propDecorators: { placeholder: [{
267
267
  type: Input
268
268
  }], searchPlaceholder: [{