@hestia-earth/ui-components 0.23.0 → 0.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/common/utils.d.ts +1 -0
  2. package/engine/engine-models-version-link/engine-models-version-link.component.d.ts +2 -1
  3. package/esm2022/common/utils.mjs +8 -1
  4. package/esm2022/cycles/cycles-activity/cycles-activity.component.mjs +4 -4
  5. package/esm2022/cycles/cycles-completeness/cycles-completeness.component.mjs +4 -4
  6. package/esm2022/cycles/cycles-emissions/cycles-emissions.component.mjs +4 -4
  7. package/esm2022/cycles/cycles-practices/cycles-practices.component.mjs +4 -4
  8. package/esm2022/engine/engine-models-version-link/engine-models-version-link.component.mjs +6 -3
  9. package/esm2022/engine/engine-orchestrator-edit/engine-orchestrator-edit.component.mjs +2 -2
  10. package/esm2022/files/files-error.model.mjs +11 -10
  11. package/esm2022/files/files-form/files-form.component.mjs +3 -12
  12. package/esm2022/files/files-upload-errors/files-upload-errors.component.mjs +6 -10
  13. package/esm2022/impact-assessments/impact-assessments-products/impact-assessments-products.component.mjs +5 -3
  14. package/esm2022/node/node-csv-select-headers/node-csv-select-headers.component.mjs +2 -2
  15. package/esm2022/node/node-logs-models/node-logs-models.component.mjs +6 -5
  16. package/esm2022/select/select.component.mjs +2 -2
  17. package/esm2022/sites/sites-measurements/sites-measurements.component.mjs +4 -4
  18. package/fesm2022/hestia-earth-ui-components.mjs +58 -57
  19. package/fesm2022/hestia-earth-ui-components.mjs.map +1 -1
  20. package/files/files-form/files-form.component.d.ts +1 -1
  21. package/files/files-upload-errors/files-upload-errors.component.d.ts +3 -6
  22. package/node/node-logs-models/node-logs-models.component.d.ts +1 -0
  23. package/package.json +4 -4
@@ -7,7 +7,7 @@ import { propertyValue } from '@hestia-earth/utils/dist/term';
7
7
  import { loadResourceKey } from '@hestia-earth/glossary';
8
8
  import { LogStatus, groupLogsByModel, groupLogsByTerm, modelCount, computeTerms, logValueArray, groupdLogsByKey, computeKeys } from './node-logs-models.model';
9
9
  import { matchExactQuery, matchId, matchTermType, matchType } from '../../search/search.model';
10
- import { baseUrl, isExternal } from '../../common/utils';
10
+ import { baseUrl, isExternal, typeaheadFocus } from '../../common/utils';
11
11
  import { termTypeLabel } from '../../terms/terms.model';
12
12
  import * as i0 from "@angular/core";
13
13
  import * as i1 from "../node.service";
@@ -85,7 +85,7 @@ const matchTermTypeFromKey = {
85
85
  impacts: indicatorTermTermType.term,
86
86
  endpoints: indicatorTermTermType.term
87
87
  };
88
- const termSearch = (term) => term.replace(/[,\s]/g, '').toLowerCase();
88
+ const termSearch = (term = '') => term.replace(/[,\s]/g, '').toLowerCase();
89
89
  export class NodeLogsModelsComponent {
90
90
  constructor(nodeService, searchService, engineService) {
91
91
  this.nodeService = nodeService;
@@ -117,6 +117,7 @@ export class NodeLogsModelsComponent {
117
117
  this.showLegend = true;
118
118
  this.allTerms = [];
119
119
  this.suggestTerm = (text$) => text$.pipe(distinctUntilChanged(), switchMap(v => this.suggestByTerm(v)));
120
+ this.typeaheadFocus = typeaheadFocus;
120
121
  }
121
122
  async ngOnInit() {
122
123
  this.logsUrl = this.nodeService.nodeLogsUrl(this.node);
@@ -238,11 +239,11 @@ export class NodeLogsModelsComponent {
238
239
  return this.node?.functionalUnit;
239
240
  }
240
241
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeLogsModelsComponent, deps: [{ token: i1.HeNodeService }, { token: i2.HeSearchService }, { token: i3.HeEngineService }], target: i0.ɵɵFactoryTarget.Component }); }
241
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", filterTermTypesLabel: "filterTermTypesLabel", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\" *ngIf=\"allTerms?.length\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [(ngModel)]=\"term\"\n name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term\" (click)=\"term = ''; filterResults()\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per&nbsp;</span>\n <span [ngSwitch]=\"functionalUnit\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes\">Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{ i + 1 }})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <span *ngIf=\"blankNode.key\">{{ blankNode.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{ blankNode.originalValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{ blankNode.recalculatedValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{ subValue.key | keyToLabel }}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{ subValue.id | keyToLabel }}</span>\n <he-node-link\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\" (click)=\"showLegend = !showLegend\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{ logColor[status.value] }}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{ status.value }}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\" />\n <span class=\"ml-2\">\n Show only {{ filteredType | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\n <td class=\"blank-node-index-{{ i }}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else: noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{ data.filename }}</td>\n <td>{{ data.column }}</td>\n <td>{{ data.termId }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{ value }}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else: defaultValue\">\n <he-node-link\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n Is the current\n <code>Node</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n Is the current\n <code>siteType</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n Is the current primary product\n <code>@id</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n Is the current primary product\n <code>termType</code>\n allowed to run this model\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">\n Pesticide data are\n <code>complete</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">\n Cycle contains\n <code>pesticideAI</code>\n Inputs\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n All\n <code>pesticideAI</code>\n Inputs have a lookup value\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code>aboveGroundCropResidueBurnt</code>\n is present as Product\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_complete'\">\n Data completeness for \"cropResidue\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_complete'\">\n Data completeness for \"excreta\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_complete'\">\n Data completeness for \"fertiliser\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_complete'\">\n Data completeness for \"material\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_complete'\">\n Data completeness for \"other\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_complete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>true</code>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_incomplete'\">\n Data completeness for \"cropResidue\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_incomplete'\">\n Data completeness for \"excreta\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_incomplete'\">\n Data completeness for \"fertiliser\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_incomplete'\">\n Data completeness for \"material\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_incomplete'\">\n Data completeness for \"other\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_incomplete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>false</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{ v.key }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{ v }}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{ vv.value }}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n </tr>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ model.status }}</span>\n </div>\n\n <ng-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code>siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n The primary product\n <code>@id</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n The primary product\n <code>termType</code>\n is not relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{ nodeType | pluralize: 0 }}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{ data.type || 'blank node' }} with Term\n <code>{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code>{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "selectOnExact", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: i6.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.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: i8.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "component", type: i9.BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType"] }, { kind: "component", type: i10.ClipboardComponent, selector: "he-clipboard", inputs: ["value", "disabled", "hideText", "icon", "size", "rotate", "clipboardClass"] }, { kind: "component", type: i11.DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "component", type: i12.NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink", "linkClass"] }, { kind: "pipe", type: i13.CompoundPipe, name: "compound" }, { kind: "pipe", type: i14.DefaultPipe, name: "default" }, { kind: "pipe", type: i15.KeysPipe, name: "keys" }, { kind: "pipe", type: i16.PluralizePipe, name: "pluralize" }, { kind: "pipe", type: i17.KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: i18.PrecisionPipe, name: "precision" }, { kind: "pipe", type: i19.TimesPipe, name: "times" }, { kind: "pipe", type: i20.IsArrayPipe, name: "isArray" }, { kind: "pipe", type: i21.IsObjectPipe, name: "isObject" }] }); }
242
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", filterTermTypesLabel: "filterTermTypesLabel", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\" *ngIf=\"allTerms?.length\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [(ngModel)]=\"term\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"filterResults()\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term\" (click)=\"term = ''; filterResults()\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per&nbsp;</span>\n <span [ngSwitch]=\"functionalUnit\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes\">Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{ i + 1 }})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <span *ngIf=\"blankNode.key\">{{ blankNode.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{ blankNode.originalValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{ blankNode.recalculatedValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{ subValue.key | keyToLabel }}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{ subValue.id | keyToLabel }}</span>\n <he-node-link\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\" (click)=\"showLegend = !showLegend\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{ logColor[status.value] }}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{ status.value }}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\" />\n <span class=\"ml-2\">\n Show only {{ filteredType | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\n <td class=\"blank-node-index-{{ i }}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else: noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{ data.filename }}</td>\n <td>{{ data.column }}</td>\n <td>{{ data.termId }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{ value }}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else: defaultValue\">\n <he-node-link\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n Is the current\n <code>Node</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n Is the current\n <code>siteType</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n Is the current primary product\n <code>@id</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n Is the current primary product\n <code>termType</code>\n allowed to run this model\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">\n Pesticide data are\n <code>complete</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">\n Cycle contains\n <code>pesticideAI</code>\n Inputs\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n All\n <code>pesticideAI</code>\n Inputs have a lookup value\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code>aboveGroundCropResidueBurnt</code>\n is present as Product\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_complete'\">\n Data completeness for \"cropResidue\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_complete'\">\n Data completeness for \"excreta\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_complete'\">\n Data completeness for \"fertiliser\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_complete'\">\n Data completeness for \"material\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_complete'\">\n Data completeness for \"other\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_complete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>true</code>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_incomplete'\">\n Data completeness for \"cropResidue\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_incomplete'\">\n Data completeness for \"excreta\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_incomplete'\">\n Data completeness for \"fertiliser\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_incomplete'\">\n Data completeness for \"material\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_incomplete'\">\n Data completeness for \"other\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_incomplete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>false</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{ v.key }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{ v }}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{ vv.value }}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n </tr>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ model.status }}</span>\n </div>\n\n <ng-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code>siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n The primary product\n <code>@id</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n The primary product\n <code>termType</code>\n is not relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{ nodeType | pluralize: 0 }}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{ data.type || 'blank node' }} with Term\n <code>{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code>{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "container", "editable", "focusFirst", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate", "selectOnExact", "showHint", "placement", "popperOptions", "popupClass"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { kind: "directive", type: i6.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "ngbPopover", "popoverTitle", "placement", "popperOptions", "triggers", "positionTarget", "container", "disablePopover", "popoverClass", "popoverContext", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.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: i8.BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { kind: "component", type: i9.BlankNodeValueDeltaComponent, selector: "he-blank-node-value-delta", inputs: ["value", "originalValue", "displayType"] }, { kind: "component", type: i10.ClipboardComponent, selector: "he-clipboard", inputs: ["value", "disabled", "hideText", "icon", "size", "rotate", "clipboardClass"] }, { kind: "component", type: i11.DataTableComponent, selector: "he-data-table", inputs: ["minHeight", "maxHeight", "small"] }, { kind: "component", type: i12.NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink", "linkClass"] }, { kind: "pipe", type: i13.CompoundPipe, name: "compound" }, { kind: "pipe", type: i14.DefaultPipe, name: "default" }, { kind: "pipe", type: i15.KeysPipe, name: "keys" }, { kind: "pipe", type: i16.PluralizePipe, name: "pluralize" }, { kind: "pipe", type: i17.KeyToLabelPipe, name: "keyToLabel" }, { kind: "pipe", type: i18.PrecisionPipe, name: "precision" }, { kind: "pipe", type: i19.TimesPipe, name: "times" }, { kind: "pipe", type: i20.IsArrayPipe, name: "isArray" }, { kind: "pipe", type: i21.IsObjectPipe, name: "isObject" }] }); }
242
243
  }
243
244
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
244
245
  type: Component,
245
- args: [{ selector: 'he-node-logs-models', template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\" *ngIf=\"allTerms?.length\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [(ngModel)]=\"term\"\n name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term\" (click)=\"term = ''; filterResults()\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per&nbsp;</span>\n <span [ngSwitch]=\"functionalUnit\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes\">Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{ i + 1 }})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <span *ngIf=\"blankNode.key\">{{ blankNode.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{ blankNode.originalValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{ blankNode.recalculatedValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{ subValue.key | keyToLabel }}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{ subValue.id | keyToLabel }}</span>\n <he-node-link\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\" (click)=\"showLegend = !showLegend\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{ logColor[status.value] }}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{ status.value }}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\" />\n <span class=\"ml-2\">\n Show only {{ filteredType | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\n <td class=\"blank-node-index-{{ i }}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else: noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{ data.filename }}</td>\n <td>{{ data.column }}</td>\n <td>{{ data.termId }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{ value }}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else: defaultValue\">\n <he-node-link\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n Is the current\n <code>Node</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n Is the current\n <code>siteType</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n Is the current primary product\n <code>@id</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n Is the current primary product\n <code>termType</code>\n allowed to run this model\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">\n Pesticide data are\n <code>complete</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">\n Cycle contains\n <code>pesticideAI</code>\n Inputs\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n All\n <code>pesticideAI</code>\n Inputs have a lookup value\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code>aboveGroundCropResidueBurnt</code>\n is present as Product\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_complete'\">\n Data completeness for \"cropResidue\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_complete'\">\n Data completeness for \"excreta\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_complete'\">\n Data completeness for \"fertiliser\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_complete'\">\n Data completeness for \"material\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_complete'\">\n Data completeness for \"other\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_complete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>true</code>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_incomplete'\">\n Data completeness for \"cropResidue\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_incomplete'\">\n Data completeness for \"excreta\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_incomplete'\">\n Data completeness for \"fertiliser\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_incomplete'\">\n Data completeness for \"material\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_incomplete'\">\n Data completeness for \"other\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_incomplete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>false</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{ v.key }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{ v }}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{ vv.value }}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n </tr>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ model.status }}</span>\n </div>\n\n <ng-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code>siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n The primary product\n <code>@id</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n The primary product\n <code>termType</code>\n is not relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{ nodeType | pluralize: 0 }}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{ data.type || 'blank node' }} with Term\n <code>{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code>{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"] }]
246
+ args: [{ selector: 'he-node-logs-models', template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" maxHeight=\"320\">\n <table class=\"table is-fullwidth is-narrow is-striped\">\n <thead>\n <tr>\n <th class=\"width-auto has-border-right\">\n <div class=\"field\" *ngIf=\"allTerms?.length\">\n <div class=\"control is-expanded has-icons-right\">\n <input\n class=\"input search-input is-small\"\n [(ngModel)]=\"term\"\n name=\"term\"\n placeholder=\"Select entry by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"true\"\n (focus)=\"typeaheadFocus($event)\"\n (selectItem)=\"filterResults()\" />\n <a class=\"icon is-small is-right\" [class.is-hidden]=\"!term\" (click)=\"term = ''; filterResults()\">\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th *ngIf=\"isBlankNodes\">\n <span class=\"is-pr-1\">Units</span>\n <span>(per&nbsp;</span>\n <span [ngSwitch]=\"functionalUnit\">\n <ng-container *ngSwitchCase=\"CycleFunctionalUnit['1 ha']\">hectare</ng-container>\n <ng-container *ngSwitchDefault>kg product</ng-container>\n </span>\n <span>)</span>\n </th>\n <th>Original</th>\n <th>Recalculated</th>\n <th *ngIf=\"isBlankNodes\">Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{ i + 1 }})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\" [class.is-open]=\"blankNode.isOpen\">\n <td class=\"width-auto has-border-right is-nowrap\" [attr.title]=\"blankNode.term?.name || blankNode.key\">\n <a\n class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!blankNode.isOpen\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"blankNode.isOpen\"></fa-icon>\n </a>\n <he-node-link class=\"is-inline-block is-pre-wrap\" *ngIf=\"blankNode.term\" [node]=\"blankNode.term\">\n <span [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n <span *ngIf=\"blankNode.key\">{{ blankNode.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <ng-template #defaultOriginalValue>\n <span>{{ blankNode.originalValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultOriginalValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.originalValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </td>\n <td>\n <ng-container *ngIf=\"!blankNode.isOriginal || blankNode.isRecalculated; else notRecalculated\">\n <ng-template #defaultRecalculatedValue>\n <span>{{ blankNode.recalculatedValue | precision: 3 | default: '-' }}</span>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultRecalculatedValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n {{ blankNode.recalculatedValueByMethodId[model.methodId] | precision: 3 | default: '-' }}\n </div>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\" class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta\n *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"></he-blank-node-value-delta>\n </ng-template>\n <ng-container *ngIf=\"blankNode.allParallel; else defaultDeltaValue\">\n <div *ngFor=\"let model of blankNode.configModels[0]\">\n <he-blank-node-value-delta\n *ngIf=\"\n blankNode.originalValueByMethodId[model.methodId] !== null &&\n blankNode.recalculatedValueByMethodId[model.methodId] !== null;\n else noValue\n \"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"></he-blank-node-value-delta>\n </div>\n </ng-container>\n </td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: blankNode }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.keys\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.has-sub-rows]=\"blankNode.subValues?.length\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right is-nowrap\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a\n class=\"is-inline-block is-pre-wrap\"\n *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\"\n target=\"_blank\"\n [title]=\"subValue.key\">\n <span>{{ subValue.key }}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{ subValue.key }}</span>\n </td>\n <td *ngIf=\"isBlankNodes\"></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated || subValue.key === 'impactAssessment'; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n\n <tr\n *ngFor=\"let subValue of blankNode.subValues\"\n [class.is-hidden]=\"!blankNode.isOpen\"\n [class.is-sub-row]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3\">{{ subValue.key | keyToLabel }}</span>\n\n <ng-container *ngIf=\"subValue.id\">\n <span class=\"is-inline-block\" class=\"is-inline-block is-align-top pr-1\">:</span>\n\n <ng-container [ngSwitch]=\"subValue.key\">\n <span class=\"is-inline-block\" *ngSwitchCase=\"'backgroundData'\">{{ subValue.id | keyToLabel }}</span>\n <he-node-link\n *ngSwitchDefault\n class=\"is-block pl-4\"\n [node]=\"termById(subValue.id)\"\n [attr.title]=\"termById(subValue.id).name\">\n <span [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td *ngIf=\"isBlankNodes\">\n <span class=\"is-nowrap\" *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">\n {{ subValue.originalValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{ subValue.recalculatedValue | precision: 3 | default: '-' }}\n </span>\n </td>\n <td *ngIf=\"isBlankNodes\">-</td>\n <ng-container *ngTemplateOutlet=\"blankNodeModels; context: { data: subValue }\"></ng-container>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </he-data-table>\n\n <div class=\"is-size-7 is-italic\">\n <div class=\"columns is-variable is-1 my-0\">\n <div class=\"column is-narrow\">\n <p>\n <a class=\"is-inline-block pr-2\" (click)=\"showLegend = !showLegend\">\n <fa-icon icon=\"angle-down\" [class.is-hidden]=\"!showLegend\"></fa-icon>\n <fa-icon icon=\"angle-right\" [class.is-hidden]=\"showLegend\"></fa-icon>\n </a>\n <span class=\"is-inline-block\">Legend:</span>\n </p>\n <ul class=\"content pl-2\" [class.is-hidden]=\"!showLegend\">\n <ng-container *ngFor=\"let status of LogStatus | keys\">\n <li *ngIf=\"logIcon[status.value]\" class=\"has-text-{{ logColor[status.value] }}\">\n <fa-icon [icon]=\"logIcon[status.value]\"></fa-icon>\n <span class=\"pl-1\">{{ status.value }}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n <div class=\"column has-text-right\" *ngIf=\"filteredType\">\n <label class=\"is-inline-block checkbox\">\n <input\n type=\"checkbox\"\n class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\" />\n <span class=\"ml-2\">\n Show only {{ filteredType | pluralize }} included in the default Hestia system boundary\n </span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\n <ng-template #notInSystemBoundary>\n <td [attr.colspan]=\"methodModelsCount\">\n <span>Not in Hestia system boundary</span>\n </td>\n </ng-template>\n\n <ng-container *ngIf=\"isSystemBoundary(data); else noValue\">\n <td class=\"blank-node-index-{{ i }}\" *ngFor=\"let c of methodModelsCount | times; let i = index\">\n <ng-container *ngIf=\"getModelsAt(data, i); let models; else: noValue\">\n <ng-template #modelSerie>\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model: models, data }\"></ng-container>\n </ng-template>\n <div *ngIf=\"models | isArray; else modelSerie\">\n <p *ngFor=\"let model of models\">\n <ng-container *ngTemplateOutlet=\"blankNodeModel; context: { model, data }\"></ng-container>\n </p>\n </div>\n </ng-container>\n </td>\n </ng-container>\n</ng-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n class=\"is-nowrap\"\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"p.isOpen() ? p.close() : model.showLogs ? p.open({ logs: model.logs }) : null\">\n <span class=\"is-capitalized\">{{ methodName(model) }}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">\n [{{ model.logs?.methodTier || model.model?.methodTier }}]\n </span>\n\n <span\n class=\"pl-1 has-text-{{ logColor[model.status] }} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\"\n [autoClose]=\"'outside'\"\n popoverClass=\"is-narrow\"\n triggers=\"manual\"\n #p1=\"ngbPopover\"\n placement=\"left\"\n container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\">\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (\n <ng-container *ngTemplateOutlet=\"docsLink; context: { $implicit: model.model }\"></ng-container>\n )\n </span>\n </span>\n</ng-template>\n\n<ng-template #noValue>-</ng-template>\n\n<ng-template #notRecalculated>not recalculated</ng-template>\n\n<ng-template #logDetails let-logs=\"logs\">\n <div class=\"table-container\" *bindOnce=\"logs\">\n <table class=\"table is-dark is-fullwidth\">\n <tbody>\n <ng-container *ngIf=\"logs?.requirements\">\n <ng-container *ngFor=\"let key of requirementKeys(logs.requirements)\">\n <ng-container *ngTemplateOutlet=\"logLine; context: { key, value: logs.requirements[key] }\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"logs?.logs\">\n <ng-container *ngFor=\"let key of logs.logs | keys\">\n <ng-container *ngTemplateOutlet=\"logLine; context: key\"></ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n </table>\n </div>\n\n <ng-container *bindOnce=\"logs\">\n <div class=\"it-mt-2\" *ngIf=\"logs?.missingLookups?.length\">\n <p>Optional data missing:</p>\n\n <div class=\"table-container data-table-container\">\n <table class=\"table is-dark is-fullwidth is-striped\">\n <thead>\n <tr>\n <th class=\"has-text-white\">\n <span>Filename</span>\n </th>\n <th class=\"has-text-white\">\n <span>Column Title</span>\n </th>\n <th class=\"has-text-white\">\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-text-white\">\n <tr *ngFor=\"let data of logs.missingLookups\">\n <td>{{ data.filename }}</td>\n <td>{{ data.column }}</td>\n <td>{{ data.termId }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #logLineValue let-key=\"key\" let-value=\"value\">\n <ng-template #defaultValue>\n <span class=\"is-inline-block is-align-middle\">{{ value }}</span>\n </ng-template>\n <ng-container *ngIf=\"requirementLinkedNode(key, value); let linkedNode; else: defaultValue\">\n <he-node-link\n class=\"is-inline-block is-align-middle\"\n linkClass=\"is-dark\"\n [node]=\"linkedNode\"\n [showExternalLink]=\"true\"></he-node-link>\n </ng-container>\n</ng-template>\n\n<ng-template #logLine let-key=\"key\" let-value=\"value\">\n <tr>\n <td class=\"has-border-right copy-log\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n Is the current\n <code>Node</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n Is the current\n <code>siteType</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n Is the current primary product\n <code>@id</code>\n allowed to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n Is the current primary product\n <code>termType</code>\n allowed to run this model\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">\n Has geospatial data necessary to run this model\n </ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">\n Pesticide data are\n <code>complete</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">\n Cycle contains\n <code>pesticideAI</code>\n Inputs\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n All\n <code>pesticideAI</code>\n Inputs have a lookup value\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code>aboveGroundCropResidueBurnt</code>\n is present as Product\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_complete'\">\n Data completeness for \"cropResidue\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_complete'\">\n Data completeness for \"excreta\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_complete'\">\n Data completeness for \"fertiliser\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_complete'\">\n Data completeness for \"material\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_complete'\">\n Data completeness for \"other\" must be\n <code>true</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_complete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>true</code>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'term_type_cropResidue_incomplete'\">\n Data completeness for \"cropResidue\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_excreta_incomplete'\">\n Data completeness for \"excreta\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_fertiliser_incomplete'\">\n Data completeness for \"fertiliser\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_material_incomplete'\">\n Data completeness for \"material\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_other_incomplete'\">\n Data completeness for \"other\" must be\n <code>false</code>\n </ng-container>\n <ng-container *ngSwitchCase=\"'term_type_pesticidesAntibiotics_incomplete'\">\n Data completeness for \"pesticidesAntibiotics\" must be\n <code>false</code>\n </ng-container>\n </span>\n <he-clipboard\n class=\"is-inline-block is-align-middle\"\n clipboardClass=\"is-size-7 is-p-1\"\n [icon]=\"['far', 'clone']\"\n [value]=\"key\"\n [hideText]=\"true\"></he-clipboard>\n </td>\n <td>\n <ng-template #singleValue>\n <ng-container *ngTemplateOutlet=\"logLineValue; context: { key, value }\"></ng-container>\n </ng-template>\n <div *ngIf=\"logValueArray(value); let valueArray; else: singleValue\">\n <table class=\"table is-dark is-bordered is-striped\">\n <thead *ngIf=\"valueArray[0] | isObject\">\n <tr>\n <th class=\"has-text-white\" *ngFor=\"let v of valueArray[0] | keys\">{{ v.key }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let v of valueArray\">\n <ng-template #singleArrayValue>\n <td>{{ v }}</td>\n </ng-template>\n <ng-container *ngIf=\"v | isObject; else singleArrayValue\">\n <td *ngFor=\"let vv of v | keys\">{{ vv.value }}</td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </div>\n </td>\n </tr>\n</ng-template>\n\n<ng-template #logStatusDetails let-model=\"model\" let-data=\"data\">\n <ng-container *bindOnce=\"model\">\n <div class=\"is-mb-2\">\n <span>Status:</span>\n <span class=\"is-pl-1\">{{ model.status }}</span>\n </div>\n\n <ng-container *ngIf=\"model.status === LogStatus.notRequired && model.logs?.is_not_relevant === 'True'\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <li *ngIf=\"model.logs.logs?.siteType_allowed === 'False'\">\n The\n <code>siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n The primary product\n <code>@id</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n The primary product\n <code>termType</code>\n is not relevant.\n </li>\n </ul>\n </ng-container>\n\n <ng-container\n *ngIf=\"model.logs && model.status !== LogStatus.notRequired && model.status !== LogStatus.skipHierarchy\">\n <ul class=\"is-pl-3 is-list-style-disc\">\n <ng-template #showRunOrchestrator>\n <li class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <ng-container *ngIf=\"!model.logs?.shouldRun\">\n <p>Some of the requirements were not met to run the model.</p>\n <p>You can click on the model name on the left to view the debugging logs.</p>\n </ng-container>\n <ng-container *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p>\n <code>{{ model.logs.logs.error }}</code>\n </p>\n </ng-container>\n </li>\n </ng-template>\n\n <li\n class=\"is-no-run-orchestrator\"\n *ngIf=\"model.logs?.shouldRunOrchestrator === false; else showRunOrchestrator\">\n <ng-container *ngIf=\"!model.logs.runRequired\">\n <span class=\"is-run-node-type-not-allowed\" *ngIf=\"model.logs.logs?.node_type_allowed === 'False'\">\n This model should not run for {{ nodeType | pluralize: 0 }}\n </span>\n </ng-container>\n\n <ng-template #runNoConfig>\n <span class=\"is-run-not-empty\" *ngIf=\"model.logs.logs?.is_empty === 'False'\">\n The {{ data.type || 'blank node' }} with Term\n <code>{{ data.termId }}</code>\n is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <p class=\"is-run-strategy-{{ model.config.runStrategy }}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">We only gap-fill this key if not present</span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">We only gap-fill this Blank Node if not present.</span>\n </p>\n\n <p class=\"is-mt-1\">\n <span\n class=\"is-run-with-measured\"\n *ngIf=\"\n model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\n \">\n The\n <code>{{ model.config.value }}</code>\n was reported as measured.\n </span>\n </p>\n </ng-container>\n </li>\n\n <li *ngIf=\"model.logs?.replaceLowerTier !== undefined\">\n <span>\n The recalculated\n <b>methodTier</b>\n was\n </span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"!model.logs.replaceLowerTier\">lower than</span>\n <span class=\"is-pl-1 is-underlined\" *ngIf=\"model.logs.replaceLowerTier\">higher than or equal to</span>\n <span class=\"is-pl-1\">\n the original\n <b>methodTier</b>\n .\n </span>\n </li>\n\n <li class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.replaceLowerTier\">\n <span>The recalculated</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}</b>\n <span class=\"is-pl-1\">was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">less than</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">more than or equal to</span>\n <b class=\"is-pl-1\">{{ model.config.mergeArgs.replaceThreshold[1] * 100 }}%</b>\n </ng-container>\n <ng-container *ngIf=\"!model.config?.mergeArgs\">\n <span class=\"is-underlined\" *ngIf=\"!model.logs.replaceThreshold\">not sufficiently</span>\n <span class=\"is-underlined\" *ngIf=\"model.logs.replaceThreshold\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <b class=\"is-pl-1\">{{ model.config?.mergeArgs?.replaceThreshold?.[0] || 'value' }}.</b>\n </li>\n </ul>\n </ng-container>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\" (click)=\"$event.stopPropagation()\">\n <span>Docs</span>\n <fa-icon class=\"ml-1\" icon=\"external-link-alt\" size=\"sm\"></fa-icon>\n </a>\n</ng-template>\n", styles: [":host{display:block}::ng-deep .table{background-color:transparent}::ng-deep .table td he-node-link{width:190px}@media screen and (max-width: 768px){::ng-deep .table td he-node-link{width:150px}}::ng-deep .table td .open-node+he-node-link{width:170px}@media screen and (max-width: 768px){::ng-deep .table td .open-node+he-node-link{width:130px}}::ng-deep .table td.has-border-right{box-shadow:1px 0 #6c8093}::ng-deep .table .has-sub-rows.is-open>td:first-child:before,::ng-deep .table .is-sub-row>td:first-child:before{display:block;position:absolute;content:\" \";background-color:#6c809333;height:100%;width:1px;top:0;left:12px}::ng-deep .table .has-sub-rows.is-open>td:first-child:before{top:25px}::ng-deep .table .popover-body .table-container{max-height:260px;overflow-y:auto}::ng-deep .copy-log he-clipboard{visibility:hidden}::ng-deep .copy-log:hover he-clipboard{visibility:visible}\n"] }]
246
247
  }], ctorParameters: function () { return [{ type: i1.HeNodeService }, { type: i2.HeSearchService }, { type: i3.HeEngineService }]; }, propDecorators: { node: [{
247
248
  type: Input
248
249
  }], nodeKey: [{
@@ -260,4 +261,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
260
261
  }], logsKey: [{
261
262
  type: Input
262
263
  }] } });
263
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1AsR0FBRyxFQUNILG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsUUFBUSxFQUNSLFFBQVEsRUFDVCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsa0JBQWtCLEVBR2xCLFFBQVEsRUFFUixZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLHFCQUFxQixFQUNyQixpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDcEIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBR0wsU0FBUyxFQUdULGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixhQUFhLEVBSWIsZUFBZSxFQUdmLFdBQVcsRUFDWixNQUFNLDBCQUEwQixDQUFDO0FBR2xDLE9BQU8sRUFBRSxlQUFlLEVBQUUs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SSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFVBQVUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFTSxRQUFRLENBQUMsRUFBVTtRQUN4QixPQUFPLENBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDakI7Z0JBQ0MsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUN0QixLQUFLLEVBQUUsRUFBRTtnQkFDVCxJQUFJLEVBQUUsYUFBYSxDQUFDLEVBQUUsQ0FBQzthQUNSLENBQ2xCLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3ZCLE9BQVEsSUFBSSxDQUFDLElBQVksRUFBRSxjQUFxQyxDQUFDO0lBQ25FLENBQUM7OEdBNVBVLHVCQUF1QjtrR0FBdkIsdUJBQXVCLDJTQzdKcEMsa2kyQkF1bkJBOzsyRkQxZGEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLHFCQUFxQjtnS0FldkIsSUFBSTtzQkFEWCxLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSztnQkFHRSxjQUFjO3NCQURyQixLQUFLO2dCQUdFLGtCQUFrQjtzQkFEekIsS0FBSztnQkFHRSxLQUFLO3NCQURaLEtBQUs7Z0JBR0UsZUFBZTtzQkFEdEIsS0FBSztnQkFHRSxvQkFBb0I7c0JBRDNCLEtBQUs7Z0JBR0UsT0FBTztzQkFEZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmcm9tLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGlzdGluY3QsXG4gIGZpbHRlcixcbiAgcmVkdWNlLFxuICB0b0FycmF5LFxuICBtYXAsXG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBzd2l0Y2hNYXAsXG4gIG1lcmdlTWFwLFxuICBtZXJnZUFsbFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDeWNsZUZ1bmN0aW9uYWxVbml0LFxuICBFbWlzc2lvbk1ldGhvZFRpZXIsXG4gIElUZXJtSlNPTkxELFxuICBKU09OTEQsXG4gIE5vZGVUeXBlLFxuICBUZXJtLFxuICBUZXJtVGVybVR5cGUsXG4gIGVtaXNzaW9uVGVybVRlcm1UeXBlLFxuICBpbmRpY2F0b3JUZXJtVGVybVR5cGUsXG4gIGlucHV0VGVybVRlcm1UeXBlLFxuICBtZWFzdXJlbWVudFRlcm1UZXJtVHlwZSxcbiAgcHJhY3RpY2VUZXJtVGVybVR5cGUsXG4gIHByb2R1Y3RUZXJtVGVybVR5cGVcbn0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsga2V5VG9MYWJlbCB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMnO1xuaW1wb3J0IHsgcHJvcGVydHlWYWx1ZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMvZGlzdC90ZXJtJztcbmltcG9ydCB7IGxvYWRSZXNvdXJjZUtleSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvZ2xvc3NhcnknO1xuXG5pbXBvcnQge1xuICBJQmxhbmtOb2RlTG9nU3ViVmFsdWUsXG4gIElCbGFua05vZGVMb2csXG4gIExvZ1N0YXR1cyxcbiAgSUNvbmZpZ01vZGVsLFxuICBibGFua05vZGUsXG4gIGdyb3VwTG9nc0J5TW9kZWwsXG4gIGdyb3VwTG9nc0J5VGVybSxcbiAgbW9kZWxDb3VudCxcbiAgY29tcHV0ZVRlcm1zLFxuICBsb2dWYWx1ZUFycmF5LFxuICBJTm9kZVRlcm1Mb2dzLFxuICBJTm9kZUxvZ3MsXG4gIG5vbkJsYW5rTm9kZSxcbiAgZ3JvdXBkTG9nc0J5S2V5LFxuICBJTm9uQmxhbmtOb2RlTG9nLFxuICBJTG9nLFxuICBjb21wdXRlS2V5c1xufSBmcm9tICcuL25vZGUtbG9ncy1tb2RlbHMubW9kZWwnO1xuaW1wb3J0IHsgSUpTT05Ob2RlLCBIZU5vZGVTZXJ2aWNlIH0gZnJvbSAnLi4vbm9kZS5zZXJ2aWNlJztcbmltcG9ydCB7IEhlRW5naW5lU2VydmljZSwgSU1vZGVsLCBJT3JjaGVzdHJhdG9yQ29uZmlnIH0gZnJvbSAnLi4vLi4vZW5naW5lL2VuZ2luZS5zZXJ2aWNlJztcbmltcG9ydCB7IG1hdGNoRXhhY3RRdWVyeSwgbWF0Y2hJZCwgbWF0Y2hUZXJtVHlwZSwgbWF0Y2hUeXBlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5tb2RlbCc7XG5pbXBvcnQgeyBIZVNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgYmFzZVVybCwgaXNFeHRlcm5hbCB9IGZyb20gJy4uLy4uL2NvbW1vbi91dGlscyc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuXG50eXBlIG5vZGVLZXkgPVxuICB8ICdpbnB1dHMnXG4gIHwgJ3Byb2R1Y3RzJ1xuICB8ICdjb21wbGV0ZW5lc3MnXG4gIHwgJ3ByYWN0aWNlcydcbiAgfCAnZW1pc3Npb25zJ1xuICB8ICdlbWlzc2lvbnNSZXNvdXJjZVVzZSdcbiAgfCAnaW1wYWN0cydcbiAgfCAnZW5kcG9pbnRzJztcblxuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdkb3QtY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaycsXG4gIFtMb2dTdGF0dXMubm90UmVxdWlyZWRdOiAnZ3JleSdcbn07XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgX21vZGVsPzogSU1vZGVsKSA9PlxuICAobWV0aG9kSWRcbiAgICA/IHtcbiAgICAgICAgJ2N5Y2xlL3RyYW5zZm9ybWF0aW9uJzogJ0RhdGEgRnJvbSBUcmFuc2Zvcm1hdGlvbicsXG4gICAgICAgIGltcGFjdF9hc3Nlc3NtZW50OiAnRGF0YSBGcm9tIEN5Y2xlJ1xuICAgICAgfVttZXRob2RJZF1cbiAgICA6ICcnKSB8fCAobWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKSk7XG5cbmNvbnN0IGdldE1vZGVsc0F0ID0gKGxvZzogSUJsYW5rTm9kZUxvZ1N1YlZhbHVlIHwgSUJsYW5rTm9kZUxvZywgaW5kZXg6IG51bWJlcikgPT5cbiAgKCdtb2RlbHNJblN1YlZhbHVlcycgaW4gbG9nID8gIWxvZy5tb2RlbHNJblN1YlZhbHVlcyB8fCAhbG9nLmlzT3BlbiA6IHRydWUpICYmIGxvZy5jb25maWdNb2RlbHNbaW5kZXhdO1xuXG5jb25zdCByZXF1aXJlbWVudEtleXMgPSAocmVxdWlyZW1lbnRzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSA9PlxuICBPYmplY3Qua2V5cyhyZXF1aXJlbWVudHMpLmZpbHRlcihrID0+ICFub2RlVHlwZXNMb3dlckNhc2UuaW5jbHVkZXMoaykpO1xuXG5jb25zdCByZXF1aXJlbWVudENvbG9yID0gKHZhbHVlOiBhbnkpID0+ICghdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnKTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXk6IHtcbiAgW2tleTogc3RyaW5nXTogKHZhbHVlOiBzdHJpbmcpID0+IFBhcnRpYWw8SlNPTkxEPE5vZGVUeXBlPj47XG59ID0ge1xuICByZWxhdGVkX2N5Y2xlczogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGN5Y2xlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgaW1wYWN0X2Fzc2Vzc21lbnRfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuSW1wYWN0QXNzZXNzbWVudCwgJ0BpZCc6IHYgfSksXG4gIHNpdGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU2l0ZSwgJ0BpZCc6IHYgfSksXG4gIHNvdXJjZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5Tb3VyY2UsICdAaWQnOiB2IH0pXG59O1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGUgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+XG4gIGtleSBpbiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleSAmJiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleVtrZXldKHZhbHVlKTtcblxuY29uc3QgaXNTeXN0ZW1Cb3VuZGFyeSA9XG4gICh0ZXJtSWQ/OiBzdHJpbmcpID0+XG4gICh7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz4pID0+IHtcbiAgICAvLyBvbmx5IGV4aXN0cyBmb3Igc29tZSB0ZXJtc1xuICAgIGNvbnN0IGluU3lzdGVtQm91bmRhcnkgPSBsb2FkUmVzb3VyY2VLZXkoJ2luSGVzdGlhRGVmYXVsdFN5c3RlbUJvdW5kYXJ5Lmpzb24nLCB0ZXJtSWQpO1xuICAgIHJldHVybiAhaW5TeXN0ZW1Cb3VuZGFyeSA/IFtpc1JlY2FsY3VsYXRlZCwgaXNSZXF1aXJlZF0uc29tZShCb29sZWFuKSA6IGAke2luU3lzdGVtQm91bmRhcnl9YCA9PT0gJ3RydWUnO1xuICB9O1xuXG5jb25zdCBpc0dlbmVyaWNUZXJtID0gKHRlcm1JZDogc3RyaW5nKSA9PiBbdGVybUlkLnN0YXJ0c1dpdGgoJ2V4Y3JldGEnKV0uZXZlcnkoQm9vbGVhbik7XG5cbmNvbnN0IGV4dHJhVGVybUlkc0Zyb21Db25maWcgPSAoY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnLCBrZXk6IG5vZGVLZXkpID0+XG4gIGNvbmZpZy5tb2RlbHNcbiAgICAuZmxhdCgpXG4gICAgLmZpbHRlcihtID0+IG0ua2V5ID09PSBrZXkpXG4gICAgLm1hcChtID0+IG0udmFsdWUpXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5maWx0ZXIodiA9PiAhaXNHZW5lcmljVGVybSh2KSk7XG5cbmNvbnN0IG1hdGNoVGVybVR5cGVGcm9tS2V5OiB7XG4gIFtrZXk6IHN0cmluZ106IFRlcm1UZXJtVHlwZVtdO1xufSA9IHtcbiAgcHJvZHVjdHM6IHByb2R1Y3RUZXJtVGVybVR5cGUudGVybSxcbiAgaW5wdXRzOiBpbnB1dFRlcm1UZXJtVHlwZS50ZXJtLFxuICBtZWFzdXJlbWVudHM6IG1lYXN1cmVtZW50VGVybVRlcm1UeXBlLnRlcm0sXG4gIHByYWN0aWNlczogcHJhY3RpY2VUZXJtVGVybVR5cGUudGVybSxcbiAgZW1pc3Npb25zOiBlbWlzc2lvblRlcm1UZXJtVHlwZS50ZXJtLFxuICBlbWlzc2lvbnNSZXNvdXJjZVVzZTogaW5kaWNhdG9yVGVybVRlcm1UeXBlLnRlcm0sXG4gIGltcGFjdHM6IGluZGljYXRvclRlcm1UZXJtVHlwZS50ZXJtLFxuICBlbmRwb2ludHM6IGluZGljYXRvclRlcm1UZXJtVHlwZS50ZXJtXG59O1xuXG5jb25zdCB0ZXJtU2VhcmNoID0gKHRlcm06IHN0cmluZykgPT4gdGVybS5yZXBsYWNlKC9bLFxcc10vZywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLW5vZGUtbG9ncy1tb2RlbHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOb2RlTG9nc01vZGVsc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgbG9nczogc3RyaW5nO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IChJQmxhbmtOb2RlTG9nIHwgSU5vbkJsYW5rTm9kZUxvZylbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5Pzogbm9kZUtleTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBvcmlnaW5hbFZhbHVlczogYmxhbmtOb2RlW10gfCBub25CbGFua05vZGUgPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSByZWNhbGN1bGF0ZWRWYWx1ZXM6IGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgdGVybXM6IElUZXJtSlNPTkxEW10gPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBmaWx0ZXJUZXJtVHlwZXM/OiBUZXJtVGVybVR5cGVbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBmaWx0ZXJUZXJtVHlwZXNMYWJlbD86IHN0cmluZztcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBsb2dzS2V5Pzogc3RyaW5nO1xuXG4gIHB1YmxpYyBsb2dzVXJsPzogc3RyaW5nO1xuICBwdWJsaWMgYmFzZVVybCA9IGJhc2VVcmwoKTtcbiAgcHVibGljIGlzRXh0ZXJuYWwgPSBpc0V4dGVybmFsKCk7XG4gIHB1YmxpYyBDeWNsZUZ1bmN0aW9uYWxVbml0ID0gQ3ljbGVGdW5jdGlvbmFsVW5pdDtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBpc1N5c3RlbUJvdW5kYXJ5ID0gaXNTeXN0ZW1Cb3VuZGFyeTtcbiAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xuICBwdWJsaWMgbm9kZVR5cGU6IE5vZGVUeXBlO1xuICBwdWJsaWMgYmxhbmtOb2RlczogKElCbGFua05vZGVMb2cgfCBJTm9uQmxhbmtOb2RlTG9nKVtdID0gW107XG4gIHB1YmxpYyBtZXRob2RNb2RlbHNDb3VudCA9IDA7XG4gIHB1YmxpYyBvbmx5UmVxdWlyZWQgPSB0cnVlO1xuICBwdWJsaWMgc2hvd0xlZ2VuZCA9IHRydWU7XG5cbiAgcHVibGljIHRlcm0/OiBzdHJpbmc7XG4gIHB1YmxpYyBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwdWJsaWMgc3VnZ2VzdFRlcm0gPSAodGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPikgPT5cbiAgICB0ZXh0JC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHN3aXRjaE1hcCh2ID0+IHRoaXMuc3VnZ2VzdEJ5VGVybSh2KSlcbiAgICApO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IEhlTm9kZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZWFyY2hTZXJ2aWNlOiBIZVNlYXJjaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmdpbmVTZXJ2aWNlOiBIZUVuZ2luZVNlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUsIHRoaXMubm9kZVsnQGlkJ10gfHwgdGhpcy5ub2RlLmlkKTtcblxuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgYm9vbDoge1xuICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pLCBtYXRjaFRlcm1UeXBlKFRlcm1UZXJtVHlwZS5tb2RlbCldXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1ldGhvZHNCeUlkID0gYXdhaXQgZnJvbShtb2RlbHMpXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcbiAgICAgICAgZGlzdGluY3QodiA9PiB2WydAaWQnXSksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICAvLyBmcm9tIGBtb2RlbC1saW5rcy5qc29uYCBmaWxlXG4gICAgY29uc3QgZW5naW5lTW9kZWxzID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm1vZGVscygpO1xuXG4gICAgdGhpcy5pc0JsYW5rTm9kZXNcbiAgICAgID8gYXdhaXQgdGhpcy5wcm9jZXNzQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZylcbiAgICAgIDogYXdhaXQgdGhpcy5wcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZyk7XG5cbiAgICB0aGlzLmZpbHRlclJlc3VsdHMoKTtcblxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dzKCkge1xuICAgIHJldHVybiB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyh0aGlzLm5vZGUpLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWdnZXN0QnlUZXJtKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiBmcm9tKHRoaXMuYWxsVGVybXMpLnBpcGUoXG4gICAgICBtYXAodiA9PiB2Lm5hbWUpLFxuICAgICAgZmlsdGVyKHYgPT4gdGVybVNlYXJjaCh2KS5pbmNsdWRlcyh0ZXJtU2VhcmNoKHRlcm0pKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NCbGFua05vZGVzKFxuICAgIGxvZ3M6IElOb2RlTG9ncyB8IElOb2RlVGVybUxvZ3MsXG4gICAgZW5naW5lTW9kZWxzOiBJTW9kZWxbXSxcbiAgICBjb25maWc6IElPcmNoZXN0cmF0b3JDb25maWdcbiAgKSB7XG4gICAgY29uc3QgZXh0cmFUZXJtSWRzID0gZXh0cmFUZXJtSWRzRnJvbUNvbmZpZyhjb25maWcsIHRoaXMubm9kZUtleSk7XG4gICAgY29uc3QgbWF0Y2hUZXJtVHlwZXMgPSBbLi4uKG1hdGNoVGVybVR5cGVGcm9tS2V5W3RoaXMubm9kZUtleV0gfHwgW10pLCAuLi4odGhpcy5maWx0ZXJUZXJtVHlwZXMgfHwgW10pXTtcbiAgICBjb25zdCBleHRyYVRlcm1zID0gYXdhaXQgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFtcbiAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksXG4gICAgICAgICAgbWF0Y2hUZXJtVHlwZXMubGVuZ3RoXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBib29sOiB7XG4gICAgICAgICAgICAgICAgICBzaG91bGQ6IG1hdGNoVGVybVR5cGVzLm1hcChtYXRjaFRlcm1UeXBlKSxcbiAgICAgICAgICAgICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGxcbiAgICAgICAgXS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICAgIHNob3VsZDogZXh0cmFUZXJtSWRzLm1hcChtYXRjaElkKSxcbiAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYWxsVGVybXMgPSBhd2FpdCBjb21wdXRlVGVybXMoXG4gICAgICB0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLnRlcm1zLFxuICAgICAgdGhpcy5maWx0ZXJUZXJtVHlwZXMsXG4gICAgICBleHRyYVRlcm1zXG4gICAgKTtcbiAgICBjb25zdCBtYXBGdW5jID0gZ3JvdXBMb2dzQnlUZXJtKFxuICAgICAgdGhpcy5ub2RlVHlwZSxcbiAgICAgIGxvZ3MsXG4gICAgICBlbmdpbmVNb2RlbHMsXG4gICAgICBjb25maWcsXG4gICAgICB0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLm5vZGVLZXlcbiAgICApO1xuICAgIGNvbnN0IGFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAobWFwRnVuYyk7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IG1vZGVsQ291bnQoYWxsQmxhbmtOb2Rlcyk7XG5cbiAgICB0aGlzLnRlcm1zQnlJZCA9IGF3YWl0IG9mKGFsbEJsYW5rTm9kZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICAgIG1hcCh2ID0+IHYuaWQpLFxuICAgICAgICBkaXN0aW5jdCgpLFxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxuICAgICAgICB0b0FycmF5KCksXG4gICAgICAgIG1lcmdlTWFwKGlkcyA9PlxuICAgICAgICAgIGZyb20oXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSldLFxuICAgICAgICAgICAgICAgIHNob3VsZDogaWRzLm1hcChpZCA9PiBtYXRjaEV4YWN0UXVlcnkoJ0BpZCcsIGlkKSksXG4gICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG1lcmdlQWxsKCksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSBhbGxCbGFua05vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzOiBJTm9kZUxvZ3MgfCBJTm9kZVRlcm1Mb2dzLCBlbmdpbmVNb2RlbHM6IElNb2RlbFtdLCBfY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnKSB7XG4gICAgY29uc3QgbWFwRnVuYyA9IGdyb3VwZExvZ3NCeUtleShcbiAgICAgIHRoaXMubm9kZVR5cGUsXG4gICAgICBsb2dzLFxuICAgICAgZW5naW5lTW9kZWxzLFxuICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlcyBhcyBub25CbGFua05vZGUsXG4gICAgICB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyBhcyBub25CbGFua05vZGVcbiAgICApO1xuICAgIGNvbnN0IGtleXMgPSBjb21wdXRlS2V5cyh0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIG5vbkJsYW5rTm9kZSwgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgbm9uQmxhbmtOb2RlKTtcbiAgICBjb25zdCBhbGxCbGFua05vZGVzID0ga2V5cy5mbGF0TWFwKG1hcEZ1bmMpO1xuICAgIHRoaXMuYWxsQmxhbmtOb2RlcyA9IGFsbEJsYW5rTm9kZXM7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IDE7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGlzQmxhbmtOb2RlcygpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh0aGlzLm9yaWdpbmFsVmFsdWVzKSB8fCBBcnJheS5pc0FycmF5KHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzKTtcbiAgfVxuXG4gIHB1YmxpYyB0cmFja0J5QmxhbmtOb2RlKF9pbmRleDogbnVtYmVyLCBub2RlOiBhbnkpIHtcbiAgICByZXR1cm4gbm9kZS50ZXJtSWQgfHwgbm9kZS5rZXk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpbHRlcmVkVHlwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJUZXJtVHlwZXNMYWJlbCB8fCB0aGlzLmZpbHRlclRlcm1UeXBlcz8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWx0ZXJCbGFua05vZGUoeyB0ZXJtOiB7IG5hbWUsICdAaWQnOiBpZCB9LCBzdWJWYWx1ZXMsIC4uLmxvZyB9OiBJQmxhbmtOb2RlTG9nKSB7XG4gICAgcmV0dXJuIHRoaXMudGVybVxuICAgICAgPyBuYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGhpcy50ZXJtLnRvTG93ZXJDYXNlKCkpXG4gICAgICA6ICF0aGlzLmZpbHRlclRlcm1UeXBlcz8ubGVuZ3RoIHx8XG4gICAgICAgICAgIXRoaXMub25seVJlcXVpcmVkIHx8XG4gICAgICAgICAgaXNTeXN0ZW1Cb3VuZGFyeShpZCkobG9nKSB8fFxuICAgICAgICAgIHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkoaWQpKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXJSZXN1bHRzKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5ibGFua05vZGVzID0gdGhpcy5hbGxCbGFua05vZGVzLmZpbHRlcihsb2cgPT4gISgndGVybScgaW4gbG9nKSB8fCB0aGlzLmZpbHRlckJsYW5rTm9kZShsb2cpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkW21ldGhvZElkXT8ubmFtZSB8fCBtZXRob2RJZExhYmVsKG1ldGhvZElkLCBtb2RlbCk7XG4gIH1cblxuICBwdWJsaWMgaGFzTWV0aG9kVGllcih2YWx1ZXM6IGJsYW5rTm9kZVtdLCBtZXRob2RUaWVyOiBFbWlzc2lvbk1ldGhvZFRpZXIpIHtcbiAgICByZXR1cm4gdmFsdWVzLnNvbWUodiA9PiAnbWV0aG9kVGllcicgaW4gdiAmJiB2Lm1ldGhvZFRpZXIgPT09IG1ldGhvZFRpZXIpO1xuICB9XG5cbiAgcHVibGljIHRlcm1CeUlkKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy50ZXJtc0J5SWRbaWRdIHx8XG4gICAgICAoe1xuICAgICAgICAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLFxuICAgICAgICAnQGlkJzogaWQsXG4gICAgICAgIG5hbWU6IHRlcm1UeXBlTGFiZWwoaWQpXG4gICAgICB9IGFzIElUZXJtSlNPTkxEKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZ1bmN0aW9uYWxVbml0KCkge1xuICAgIHJldHVybiAodGhpcy5ub2RlIGFzIGFueSk/LmZ1bmN0aW9uYWxVbml0IGFzIEN5Y2xlRnVuY3Rpb25hbFVuaXQ7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweC0zIHBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IG1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsXCI+XG4gICAgPGEgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cImxvZ3NVcmxcIiBbaHJlZl09XCJsb2dzVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgbWF4SGVpZ2h0PVwiMzIwXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIGlzLW5hcnJvdyBpcy1zdHJpcGVkXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiICpuZ0lmPVwiYWxsVGVybXM/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udHJvbCBpcy1leHBhbmRlZCBoYXMtaWNvbnMtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5wdXQgc2VhcmNoLWlucHV0IGlzLXNtYWxsXCJcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkZpbHRlciBieSBuYW1lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ2JUeXBlYWhlYWRdPVwic3VnZ2VzdFRlcm1cIlxuICAgICAgICAgICAgICAgICAgW2ZvY3VzRmlyc3RdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwiZmlsdGVyUmVzdWx0cygpXCIgLz5cbiAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImljb24gaXMtc21hbGwgaXMtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiF0ZXJtXCIgKGNsaWNrKT1cInRlcm0gPSAnJzsgZmlsdGVyUmVzdWx0cygpXCI+XG4gICAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwidGltZXNcIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXByLTFcIj5Vbml0czwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPihwZXImbmJzcDs8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBbbmdTd2l0Y2hdPVwiZnVuY3Rpb25hbFVuaXRcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiQ3ljbGVGdW5jdGlvbmFsVW5pdFsnMSBoYSddXCI+aGVjdGFyZTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+a2cgcHJvZHVjdDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+KTwvc3Bhbj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5PcmlnaW5hbDwvdGg+XG4gICAgICAgICAgPHRoPlJlY2FsY3VsYXRlZDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj4oe3sgaSArIDEgfX0pPC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDx0ciAqbmdJZj1cImxvYWRpbmdcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFzLXRleHQtY2VudGVyIHB5LTNcIj5cbiAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInNwaW5uZXJcIiBbcHVsc2VdPVwidHJ1ZVwiIHNpemU9XCJsZ1wiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0ciAqbmdJZj1cIiFsb2FkaW5nICYmIGJsYW5rTm9kZXMubGVuZ3RoID09PSAwXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPHNwYW4+Tm8gZGF0YTwvc3Bhbj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBibGFua05vZGUgb2YgYmxhbmtOb2RlczsgdHJhY2tCeTogdHJhY2tCeUJsYW5rTm9kZVwiPlxuICAgICAgICAgIDx0ciBbY2xhc3MuaGFzLXN1Yi1yb3dzXT1cImJsYW5rTm9kZS5jYW5PcGVuXCIgW2NsYXNzLmlzLW9wZW5dPVwiYmxhbmtOb2RlLmlzT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0IGlzLW5vd3JhcFwiIFthdHRyLnRpdGxlXT1cImJsYW5rTm9kZS50ZXJtPy5uYW1lIHx8IGJsYW5rTm9kZS5rZXlcIj5cbiAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMiBvcGVuLW5vZGVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJibGFua05vZGUuaXNPcGVuID0gIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtZG93blwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiIWJsYW5rTm9kZS5pc09wZW5cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJibGFua05vZGUuaXNPcGVuXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxoZS1ub2RlLWxpbmsgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtcHJlLXdyYXBcIiAqbmdJZj1cImJsYW5rTm9kZS50ZXJtXCIgW25vZGVdPVwiYmxhbmtOb2RlLnRlcm1cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtLm5hbWUgfCBjb21wb3VuZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYmxhbmtOb2RlLmtleVwiPnt7IGJsYW5rTm9kZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwXCIgW2lubmVySHRtbF09XCJibGFua05vZGUudGVybT8udW5pdHMgfCBjb21wb3VuZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdE9yaWdpbmFsVmFsdWU+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdE9yaWdpbmFsVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+XG4gICAgICAgICAgICAgICAgICB7eyBibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFibGFua05vZGUuaXNPcmlnaW5hbCB8fCBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWU+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRSZWNhbGN1bGF0ZWRWYWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAgICB7eyBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiIGNsYXNzPVwiaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdERlbHRhVmFsdWU+XG4gICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsLmxlbmd0aCAmJiBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm9WYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlXCJcbiAgICAgICAgICAgICAgICAgIFtvcmlnaW5hbFZhbHVlXT1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlXCI+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHREZWx0YVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGFcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICBlbHNlIG5vVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDogeyBkYXRhOiBibGFua05vZGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1zdWItcm93XT1cImJsYW5rTm9kZS5jYW5PcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zIHByLTEgZmllbGQtbm9kZVwiPkZpZWxkOjwvc3Bhbj5cblxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLXByZS13cmFwXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS50eXBlXCJcbiAgICAgICAgICAgICAgICBbaHJlZl09XCJiYXNlVXJsICsgJy9zY2hlbWEvJyArIGJsYW5rTm9kZS50eXBlICsgJyMnICsgc3ViVmFsdWUua2V5XCJcbiAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wXCIgKm5nSWY9XCIhYmxhbmtOb2RlLnR5cGVcIj57eyBzdWJWYWx1ZS5rZXkgfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQgfHwgc3ViVmFsdWUua2V5ID09PSAnaW1wYWN0QXNzZXNzbWVudCc7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPi08L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDogeyBkYXRhOiBzdWJWYWx1ZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90cj5cblxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IHN1YlZhbHVlIG9mIGJsYW5rTm9kZS5zdWJWYWx1ZXNcIlxuICAgICAgICAgICAgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtc3ViLXJvd109XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zXCI+e3sgc3ViVmFsdWUua2V5IHwga2V5VG9MYWJlbCB9fTwvc3Bhbj5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3ViVmFsdWUuaWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0xXCI+Ojwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInN1YlZhbHVlLmtleVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiAqbmdTd2l0Y2hDYXNlPVwiJ2JhY2tncm91bmREYXRhJ1wiPnt7IHN1YlZhbHVlLmlkIHwga2V5VG9MYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxoZS1ub2RlLWxpbmtcbiAgICAgICAgICAgICAgICAgICAgKm5nU3dpdGNoRGVmYXVsdFxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlzLWJsb2NrIHBsLTRcIlxuICAgICAgICAgICAgICAgICAgICBbbm9kZV09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZClcIlxuICAgICAgICAgICAgICAgICAgICBbYXR0ci50aXRsZV09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZCkubmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIdG1sXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwXCIgKm5nSWY9XCJzdWJWYWx1ZS5zaG93VW5pdHNcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPi08L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDogeyBkYXRhOiBzdWJWYWx1ZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvaGUtZGF0YS10YWJsZT5cblxuICA8ZGl2IGNsYXNzPVwiaXMtc2l6ZS03IGlzLWl0YWxpY1wiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2x1bW5zIGlzLXZhcmlhYmxlIGlzLTEgbXktMFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbHVtbiBpcy1uYXJyb3dcIj5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPGEgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgcHItMlwiIChjbGljayk9XCJzaG93TGVnZW5kID0gIXNob3dMZWdlbmRcIj5cbiAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwic2hvd0xlZ2VuZFwiPjwvZmEtaWNvbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIj5MZWdlbmQ6PC9zcGFuPlxuICAgICAgICA8L3A+XG4gICAgICAgIDx1bCBjbGFzcz1cImNvbnRlbnQgcGwtMlwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXNob3dMZWdlbmRcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdGF0dXMgb2YgTG9nU3RhdHVzIHwga2V5c1wiPlxuICAgICAgICAgICAgPGxpICpuZ0lmPVwibG9nSWNvbltzdGF0dXMudmFsdWVdXCIgY2xhc3M9XCJoYXMtdGV4dC17eyBsb2dDb2xvcltzdGF0dXMudmFsdWVdIH19XCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bc3RhdHVzLnZhbHVlXVwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+e3sgc3RhdHVzLnZhbHVlIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC91bD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbHVtbiBoYXMtdGV4dC1yaWdodFwiICpuZ0lmPVwiZmlsdGVyZWRUeXBlXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImlzLWlubGluZS1ibG9jayBjaGVja2JveFwiPlxuICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgIGNsYXNzPVwic2VsZWN0b3JcIlxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJvbmx5UmVxdWlyZWRcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJmaWx0ZXJSZXN1bHRzKClcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiEhdGVybVwiIC8+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+XG4gICAgICAgICAgICBTaG93IG9ubHkge3sgZmlsdGVyZWRUeXBlIHwgcGx1cmFsaXplIH19IGluY2x1ZGVkIGluIHRoZSBkZWZhdWx0IEhlc3RpYSBzeXN0ZW0gYm91bmRhcnlcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbHMgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIDxuZy10ZW1wbGF0ZSAjbm90SW5TeXN0ZW1Cb3VuZGFyeT5cbiAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJtZXRob2RNb2RlbHNDb3VudFwiPlxuICAgICAgPHNwYW4+Tm90IGluIEhlc3RpYSBzeXN0ZW0gYm91bmRhcnk8L3NwYW4+XG4gICAgPC90ZD5cbiAgPC9uZy10ZW1wbGF0ZT5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNTeXN0ZW1Cb3VuZGFyeShkYXRhKTsgZWxzZSBub1ZhbHVlXCI+XG4gICAgPHRkIGNsYXNzPVwiYmxhbmstbm9kZS1pbmRleC17eyBpIH19XCIgKm5nRm9yPVwibGV0IGMgb2YgbWV0aG9kTW9kZWxzQ291bnQgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldE1vZGVsc0F0KGRhdGEsIGkpOyBsZXQgbW9kZWxzOyBlbHNlOiBub1ZhbHVlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjbW9kZWxTZXJpZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWw6IG1vZGVscywgZGF0YSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJtb2RlbHMgfCBpc0FycmF5OyBlbHNlIG1vZGVsU2VyaWVcIj5cbiAgICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHsgbW9kZWwsIGRhdGEgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L3RkPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjYmxhbmtOb2RlTW9kZWwgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHNwYW5cbiAgICBjbGFzcz1cImlzLW5vd3JhcFwiXG4gICAgW2NsYXNzLnRyaWdnZXItcG9wb3Zlcl09XCJtb2RlbC5zaG93TG9nc1wiXG4gICAgW25nYlBvcG92ZXJdPVwibG9nRGV0YWlsc1wiXG4gICAgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIlxuICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIlxuICAgICNwPVwibmdiUG9wb3ZlclwiXG4gICAgcGxhY2VtZW50PVwibGVmdFwiXG4gICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiBtb2RlbC5zaG93TG9ncyA/IHAub3Blbih7IGxvZ3M6IG1vZGVsLmxvZ3MgfSkgOiBudWxsXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7IG1ldGhvZE5hbWUobW9kZWwpIH19PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncz8ubWV0aG9kVGllciB8fCBtb2RlbC5tb2RlbD8ubWV0aG9kVGllclwiPlxuICAgICAgW3t7IG1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXIgfX1dXG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW5cbiAgICAgIGNsYXNzPVwicGwtMSBoYXMtdGV4dC17eyBsb2dDb2xvclttb2RlbC5zdGF0dXNdIH19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCJcbiAgICAgIFthdXRvQ2xvc2VdPVwiJ291dHNpZGUnXCJcbiAgICAgIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgICB0cmlnZ2Vycz1cIm1hbnVhbFwiXG4gICAgICAjcDE9XCJuZ2JQb3BvdmVyXCJcbiAgICAgIHBsYWNlbWVudD1cImxlZnRcIlxuICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBwMS5pc09wZW4oKSA/IHAxLmNsb3NlKCkgOiBwMS5vcGVuKHsgbW9kZWwsIGRhdGEgfSlcIj5cbiAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bbW9kZWwuc3RhdHVzXVwiPjwvZmEtaWNvbj5cbiAgICA8L3NwYW4+XG5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLm1vZGVsXCI+XG4gICAgICAoXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZG9jc0xpbms7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBtb2RlbC5tb2RlbCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICApXG4gICAgPC9zcGFuPlxuICA8L3NwYW4+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vVmFsdWU+LTwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbm90UmVjYWxjdWxhdGVkPm5vdCByZWNhbGN1bGF0ZWQ8L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0RldGFpbHMgbGV0LWxvZ3M9XCJsb2dzXCI+XG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXJcIiAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGhcIj5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LnJlcXVpcmVtZW50c1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiByZXF1aXJlbWVudEtleXMobG9ncy5yZXF1aXJlbWVudHMpXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZTsgY29udGV4dDogeyBrZXksIHZhbHVlOiBsb2dzLnJlcXVpcmVtZW50c1trZXldIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LmxvZ3NcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgbG9ncy5sb2dzIHwga2V5c1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6IGtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPGRpdiBjbGFzcz1cIml0LW10LTJcIiAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGggaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5GaWxlbmFtZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Db2x1bW4gVGl0bGU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+Um93ICh0ZXJtLmlkKTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGxvZ3MubWlzc2luZ0xvb2t1cHNcIj5cbiAgICAgICAgICAgICAgPHRkPnt7IGRhdGEuZmlsZW5hbWUgfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS5jb2x1bW4gfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS50ZXJtSWQgfX08L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lVmFsdWUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFZhbHVlPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiPnt7IHZhbHVlIH19PC9zcGFuPlxuICA8L25nLXRlbXBsYXRlPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVxdWlyZW1lbnRMaW5rZWROb2RlKGtleSwgdmFsdWUpOyBsZXQgbGlua2VkTm9kZTsgZWxzZTogZGVmYXVsdFZhbHVlXCI+XG4gICAgPGhlLW5vZGUtbGlua1xuICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCJcbiAgICAgIGxpbmtDbGFzcz1cImlzLWRhcmtcIlxuICAgICAgW25vZGVdPVwibGlua2VkTm9kZVwiXG4gICAgICBbc2hvd0V4dGVybmFsTGlua109XCJ0cnVlXCI+PC9oZS1ub2RlLWxpbms+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8dHI+XG4gICAgPHRkIGNsYXNzPVwiaGFzLWJvcmRlci1yaWdodCBjb3B5LWxvZ1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCIgW25nU3dpdGNoXT1cImtleVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+e3sga2V5IHwga2V5VG9MYWJlbCB9fTwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidub2RlX3R5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICBJcyB0aGUgY3VycmVudFxuICAgICAgICAgIDxjb2RlPk5vZGU8L2NvZGU+XG4gICAgICAgICAgYWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbFxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3NpdGVUeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgSXMgdGhlIGN1cnJlbnRcbiAgICAgICAgICA8Y29kZT5zaXRlVHlwZTwvY29kZT5cbiAgICAgICAgICBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJpbWFyeV9wcm9kdWN0X2lkX2FsbG93ZWQnXCI+XG4gICAgICAgICAgSXMgdGhlIGN1cnJlbnQgcHJpbWFyeSBwcm9kdWN0XG4gICAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICAgIGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICBJcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3RcbiAgICAgICAgICA8Y29kZT50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidnZW9zcGF0aWFsX2RhdGEnXCI+SGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5cbiAgICAgICAgICBIYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbFxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2N1cnJlbnRfc2l6ZSdcIj5DdXJyZW50IHBvbHlnb24gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbWF4X2FyZWFfc2l6ZSdcIj5NYXhpbXVtIHBvbHlnb24gYXJlYSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYmVsb3dfbWF4X2FyZWFfc2l6ZSdcIj5Qb2x5Z29uIGJlbG93IHRoZSBtYXhpbXVtIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3JlZ2lvbl9mYWN0b3InXCI+RmFjdG9yIGZyb20gcmVnaW9uIGxvb2t1cDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwZXN0aWNpZGVzX2NvbXBsZXRlJ1wiPlxuICAgICAgICAgIFBlc3RpY2lkZSBkYXRhIGFyZVxuICAgICAgICAgIDxjb2RlPmNvbXBsZXRlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19wZXN0aWNpZGVzX2lucHV0cydcIj5cbiAgICAgICAgICBDeWNsZSBjb250YWluc1xuICAgICAgICAgIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPlxuICAgICAgICAgIElucHV0c1xuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2FsbF9wZXN0aWNpZGVBSV9oYXZlX2xvb2t1cF92YWx1ZSdcIj5cbiAgICAgICAgICBBbGxcbiAgICAgICAgICA8Y29kZT5wZXN0aWNpZGVBSTwvY29kZT5cbiAgICAgICAgICBJbnB1dHMgaGF2ZSBhIGxvb2t1cCB2YWx1ZVxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX2Nyb3BfcmVzaWR1ZV9idXJudCdcIj5cbiAgICAgICAgICA8Y29kZT5hYm92ZUdyb3VuZENyb3BSZXNpZHVlQnVybnQ8L2NvZGU+XG4gICAgICAgICAgaXMgcHJlc2VudCBhcyBQcm9kdWN0XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidsaXF1aWRfc2x1cnJ5X3NsdWRnZV9QJ1wiPkxpcXVpZCwgU2x1cnJ5LCBhbmQgU2x1ZGdlIFA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2Nyb3BSZXNpZHVlX2NvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcImNyb3BSZXNpZHVlXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPnRydWU8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2V4Y3JldGFfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwiZXhjcmV0YVwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9mZXJ0aWxpc2VyX2NvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcImZlcnRpbGlzZXJcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfbWF0ZXJpYWxfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwibWF0ZXJpYWxcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfb3RoZXJfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwib3RoZXJcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfcGVzdGljaWRlc0FudGliaW90aWNzX2NvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcInBlc3RpY2lkZXNBbnRpYmlvdGljc1wiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2Nyb3BSZXNpZHVlX2luY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwiY3JvcFJlc2lkdWVcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2V4Y3JldGFfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJleGNyZXRhXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9mZXJ0aWxpc2VyX2luY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwiZmVydGlsaXNlclwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfbWF0ZXJpYWxfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJtYXRlcmlhbFwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfb3RoZXJfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJvdGhlclwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfcGVzdGljaWRlc0FudGliaW90aWNzX2luY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwicGVzdGljaWRlc0FudGliaW90aWNzXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxoZS1jbGlwYm9hcmRcbiAgICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCJcbiAgICAgICAgY2xpcGJvYXJkQ2xhc3M9XCJpcy1zaXplLTcgaXMtcC0xXCJcbiAgICAgICAgW2ljb25dPVwiWydmYXInLCAnY2xvbmUnXVwiXG4gICAgICAgIFt2YWx1ZV09XCJrZXlcIlxuICAgICAgICBbaGlkZVRleHRdPVwidHJ1ZVwiPjwvaGUtY2xpcGJvYXJkPlxuICAgIDwvdGQ+XG4gICAgPHRkPlxuICAgICAgPG5nLXRlbXBsYXRlICNzaW5nbGVWYWx1ZT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmVWYWx1ZTsgY29udGV4dDogeyBrZXksIHZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8ZGl2ICpuZ0lmPVwibG9nVmFsdWVBcnJheSh2YWx1ZSk7IGxldCB2YWx1ZUFycmF5OyBlbHNlOiBzaW5nbGVWYWx1ZVwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWJvcmRlcmVkIGlzLXN0cmlwZWRcIj5cbiAgICAgICAgICA8dGhlYWQgKm5nSWY9XCJ2YWx1ZUFycmF5WzBdIHwgaXNPYmplY3RcIj5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIiAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5WzBdIHwga2V5c1wiPnt7IHYua2V5IH19PC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZUFycmF5VmFsdWU+XG4gICAgICAgICAgICAgICAgPHRkPnt7IHYgfX08L3RkPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidiB8IGlzT2JqZWN0OyBlbHNlIHNpbmdsZUFycmF5VmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IHZ2IG9mIHYgfCBrZXlzXCI+e3sgdnYudmFsdWUgfX08L3RkPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvdGQ+XG4gIDwvdHI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ1N0YXR1c0RldGFpbHMgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJtb2RlbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICA8c3Bhbj5TdGF0dXM6PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+e3sgbW9kZWwuc3RhdHVzIH19PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLnN0YXR1cyA9PT0gTG9nU3RhdHVzLm5vdFJlcXVpcmVkICYmIG1vZGVsLmxvZ3M/LmlzX25vdF9yZWxldmFudCA9PT0gJ1RydWUnXCI+XG4gICAgICA8dWwgY2xhc3M9XCJpcy1wbC0zIGlzLWxpc3Qtc3R5bGUtZGlzY1wiPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LnNpdGVUeXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGVcbiAgICAgICAgICA8Y29kZT5zaXRlVHlwZTwvY29kZT5cbiAgICAgICAgICBpcyBub3QgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucHJvZHVjdF9pZF9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgVGhlIHByaW1hcnkgcHJvZHVjdFxuICAgICAgICAgIDxjb2RlPkBpZDwvY29kZT5cbiAgICAgICAgICBpcyBub3QgcmVsZXZhbnQuXG4gICAgICAgIDwvbGk+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucHJvZHVjdF90ZXJtVHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgVGhlIHByaW1hcnkgcHJvZHVjdFxuICAgICAgICAgIDxjb2RlPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgIGlzIG5vdCByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICAqbmdJZj1cIm1vZGVsLmxvZ3MgJiYgbW9kZWwuc3RhdHVzICE9PSBMb2dTdGF0dXMubm90UmVxdWlyZWQgJiYgbW9kZWwuc3RhdHVzICE9PSBMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeVwiPlxuICAgICAgPHVsIGNsYXNzPVwiaXMtcGwtMyBpcy1saXN0LXN0eWxlLWRpc2NcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNzaG93UnVuT3JjaGVzdHJhdG9yPlxuICAgICAgICAgIDxsaSBjbGFzcz1cImlzLXJ1bi1vcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgICAgIDxwICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+QWxsIHRoZSByZXF1aXJlbWVudHMgd2VyZSBtZXQgdG8gcnVuIHRoZSBtb2RlbC48L3A+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmxvZ3M/LnNob3VsZFJ1blwiPlxuICAgICAgICAgICAgICA8cD5Tb21lIG9mIHRoZSByZXF1aXJlbWVudHMgd2VyZSBub3QgbWV0IHRvIHJ1biB0aGUgbW9kZWwuPC9wPlxuICAgICAgICAgICAgICA8cD5Zb3UgY2FuIGNsaWNrIG9uIHRoZSBtb2RlbCBuYW1lIG9uIHRoZSBsZWZ0IHRvIHZpZXcgdGhlIGRlYnVnZ2luZyBsb2dzLjwvcD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmxvZ3M/LmxvZ3M/LmVycm9yXCI+XG4gICAgICAgICAgICAgIDxwPlRoZSBtb2RlbCBmYWlsZWQgdG8gcnVuIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbjo8L3A+XG4gICAgICAgICAgICAgIDxwPlxuICAgICAgICAgICAgICAgIDxjb2RlPnt7IG1vZGVsLmxvZ3MubG9ncy5lcnJvciB9fTwvY29kZT5cbiAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICA8bGlcbiAgICAgICAgICBjbGFzcz1cImlzLW5vLXJ1bi1vcmNoZXN0cmF0b3JcIlxuICAgICAgICAgICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkUnVuT3JjaGVzdHJhdG9yID09PSBmYWxzZTsgZWxzZSBzaG93UnVuT3JjaGVzdHJhdG9yXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzLnJ1blJlcXVpcmVkXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub2RlLXR5cGUtbm90LWFsbG93ZWRcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ubm9kZV90eXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICAgICAgVGhpcyBtb2RlbCBzaG91bGQgbm90IHJ1biBmb3Ige3sgbm9kZVR5cGUgfCBwbHVyYWxpemU6IDAgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcnVuTm9Db25maWc+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICAgICAgVGhlIHt7IGRhdGEudHlwZSB8fCAnYmxhbmsgbm9kZScgfX0gd2l0aCBUZXJtXG4gICAgICAgICAgICAgIDxjb2RlPnt7IGRhdGEudGVybUlkIH19PC9jb2RlPlxuICAgICAgICAgICAgICBpcyBhbHJlYWR5IHByZXNlbnQgb3IgYWxyZWFkeSBhZGRlZCBieSBhbm90aGVyIG1vZGVsLlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuY29uZmlnOyBlbHNlIHJ1bk5vQ29uZmlnXCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImlzLXJ1bi1zdHJhdGVneS17eyBtb2RlbC5jb25maWcucnVuU3RyYXRlZ3kgfX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWx3YXlzJ1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfa2V5X2lmX21pc3NpbmcnXCI+V2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfYmxhbmtfbm9kZV9pZl9taXNzaW5nJ1wiPldlIG9ubHkgZ2FwLWZpbGwgdGhpcyBCbGFuayBOb2RlIGlmIG5vdCBwcmVzZW50Ljwvc3Bhbj5cbiAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgPHAgY2xhc3M9XCJpcy1tdC0xXCI+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ydW4td2l0aC1tZWFzdXJlZFwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgIG1vZGVsLmNvbmZpZy5ydW5BcmdzPy5ydW5Ob25NZWFzdXJlZCAmJiBoYXNNZXRob2RUaWVyKGRhdGEub3JpZ2luYWwsIEVtaXNzaW9uTWV0aG9kVGllci5tZWFzdXJlZClcbiAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICBUaGVcbiAgICAgICAgICAgICAgICA8Y29kZT57eyBtb2RlbC5jb25maWcudmFsdWUgfX08L2NvZGU+XG4gICAgICAgICAgICAgICAgd2FzIHJlcG9ydGVkIGFzIG1lYXN1cmVkLlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncz8ucmVwbGFjZUxvd2VyVGllciAhPT0gdW5kZWZpbmVkXCI+XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICBUaGUgcmVjYWxjdWxhdGVkXG4gICAgICAgICAgICA8Yj5tZXRob2RUaWVyPC9iPlxuICAgICAgICAgICAgd2FzXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMSBpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCIhbW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTEgaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+aGlnaGVyIHRoYW4gb3IgZXF1YWwgdG88L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+XG4gICAgICAgICAgICB0aGUgb3JpZ2luYWxcbiAgICAgICAgICAgIDxiPm1ldGhvZFRpZXI8L2I+XG4gICAgICAgICAgICAuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuXG4gICAgICAgIDxsaSBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VMb3dlclRpZXJcIiAqbmdJZj1cIm1vZGVsLmxvZ3MucmVwbGFjZUxvd2VyVGllclwiPlxuICAgICAgICAgIDxzcGFuPlRoZSByZWNhbGN1bGF0ZWQ8L3NwYW4+XG4gICAgICAgICAgPGIgY2xhc3M9XCJpcy1wbC0xXCI+e3sgbW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnIH19PC9iPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPndhczwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc/Lm1lcmdlQXJnc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXVuZGVybGluZWRcIiAqbmdJZj1cIiFtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5sZXNzIHRoYW48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+bW9yZSB0aGFuIG9yIGVxdWFsIHRvPC9zcGFuPlxuICAgICAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDAgfX0lPC9iPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwiIW1vZGVsLmxvZ3MucmVwbGFjZVRocmVzaG9sZFwiPm5vdCBzdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+c3VmZmljaWVudGx5PC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbDwvc3Bhbj5cbiAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWc/Lm1lcmdlQXJncz8ucmVwbGFjZVRocmVzaG9sZD8uWzBdIHx8ICd2YWx1ZScgfX0uPC9iPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2RvY3NMaW5rIGxldC1tb2RlbD5cbiAgPGEgW2hyZWZdPVwibW9kZWwuYXBpRG9jc1BhdGggfHwgbW9kZWwuZG9jUGF0aCB8fCBtb2RlbC5wYXRoXCIgdGFyZ2V0PVwiX2JsYW5rXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxzcGFuPkRvY3M8L3NwYW4+XG4gICAgPGZhLWljb24gY2xhc3M9XCJtbC0xXCIgaWNvbj1cImV4dGVybmFsLWxpbmstYWx0XCIgc2l6ZT1cInNtXCI+PC9mYS1pY29uPlxuICA8L2E+XG48L25nLXRlbXBsYXRlPlxuIl19
264
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1AsR0FBRyxFQUNILG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsUUFBUSxFQUNSLFFBQVEsRUFDVCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsa0JBQWtCLEVBR2xCLFFBQVEsRUFFUixZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLHFCQUFxQixFQUNyQixpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDcEIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBR0wsU0FBUyxFQUdULGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixhQUFhLEVBSWIsZUFBZSxFQUdmLFdBQVcsRUFDWixNQUFNLDBCQUEwQixDQUFDO0FBR2xDLE9BQU8sRUFBRSxlQUFlLEVBQUUs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LENBQUMsTUFBbUIsRUFBRSxVQUE4QjtRQUN0RSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVNLFFBQVEsQ0FBQyxFQUFVO1FBQ3hCLE9BQU8sQ0FDTCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNqQjtnQkFDQyxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUk7Z0JBQ3RCLEtBQUssRUFBRSxFQUFFO2dCQUNULElBQUksRUFBRSxhQUFhLENBQUMsRUFBRSxDQUFDO2FBQ1IsQ0FDbEIsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFXLGNBQWM7UUFDdkIsT0FBUSxJQUFJLENBQUMsSUFBWSxFQUFFLGNBQXFDLENBQUM7SUFDbkUsQ0FBQzs4R0E5UFUsdUJBQXVCO2tHQUF2Qix1QkFBdUIsMlNDN0pwQyw2bDJCQXduQkE7OzJGRDNkYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCO2dLQWV2QixJQUFJO3NCQURYLEtBQUs7Z0JBR0UsT0FBTztzQkFEZCxLQUFLO2dCQUdFLGNBQWM7c0JBRHJCLEtBQUs7Z0JBR0Usa0JBQWtCO3NCQUR6QixLQUFLO2dCQUdFLEtBQUs7c0JBRFosS0FBSztnQkFHRSxlQUFlO3NCQUR0QixLQUFLO2dCQUdFLG9CQUFvQjtzQkFEM0IsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBkaXN0aW5jdCxcbiAgZmlsdGVyLFxuICByZWR1Y2UsXG4gIHRvQXJyYXksXG4gIG1hcCxcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIHN3aXRjaE1hcCxcbiAgbWVyZ2VNYXAsXG4gIG1lcmdlQWxsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIEN5Y2xlRnVuY3Rpb25hbFVuaXQsXG4gIEVtaXNzaW9uTWV0aG9kVGllcixcbiAgSVRlcm1KU09OTEQsXG4gIEpTT05MRCxcbiAgTm9kZVR5cGUsXG4gIFRlcm0sXG4gIFRlcm1UZXJtVHlwZSxcbiAgZW1pc3Npb25UZXJtVGVybVR5cGUsXG4gIGluZGljYXRvclRlcm1UZXJtVHlwZSxcbiAgaW5wdXRUZXJtVGVybVR5cGUsXG4gIG1lYXN1cmVtZW50VGVybVRlcm1UeXBlLFxuICBwcmFjdGljZVRlcm1UZXJtVHlwZSxcbiAgcHJvZHVjdFRlcm1UZXJtVHlwZVxufSBmcm9tICdAaGVzdGlhLWVhcnRoL3NjaGVtYSc7XG5pbXBvcnQgeyBrZXlUb0xhYmVsIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscyc7XG5pbXBvcnQgeyBwcm9wZXJ0eVZhbHVlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscy9kaXN0L3Rlcm0nO1xuaW1wb3J0IHsgbG9hZFJlc291cmNlS2V5IH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9nbG9zc2FyeSc7XG5cbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSxcbiAgSUJsYW5rTm9kZUxvZyxcbiAgTG9nU3RhdHVzLFxuICBJQ29uZmlnTW9kZWwsXG4gIGJsYW5rTm9kZSxcbiAgZ3JvdXBMb2dzQnlNb2RlbCxcbiAgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LFxuICBjb21wdXRlVGVybXMsXG4gIGxvZ1ZhbHVlQXJyYXksXG4gIElOb2RlVGVybUxvZ3MsXG4gIElOb2RlTG9ncyxcbiAgbm9uQmxhbmtOb2RlLFxuICBncm91cGRMb2dzQnlLZXksXG4gIElOb25CbGFua05vZGVMb2csXG4gIElMb2csXG4gIGNvbXB1dGVLZXlzXG59IGZyb20gJy4vbm9kZS1sb2dzLW1vZGVscy5tb2RlbCc7XG5pbXBvcnQgeyBJSlNPTk5vZGUsIEhlTm9kZVNlcnZpY2UgfSBmcm9tICcuLi9ub2RlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGVFbmdpbmVTZXJ2aWNlLCBJTW9kZWwsIElPcmNoZXN0cmF0b3JDb25maWcgfSBmcm9tICcuLi8uLi9lbmdpbmUvZW5naW5lLnNlcnZpY2UnO1xuaW1wb3J0IHsgbWF0Y2hFeGFjdFF1ZXJ5LCBtYXRjaElkLCBtYXRjaFRlcm1UeXBlLCBtYXRjaFR5cGUgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLm1vZGVsJztcbmltcG9ydCB7IEhlU2VhcmNoU2VydmljZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2guc2VydmljZSc7XG5pbXBvcnQgeyBiYXNlVXJsLCBpc0V4dGVybmFsLCB0eXBlYWhlYWRGb2N1cyB9IGZyb20gJy4uLy4uL2NvbW1vbi91dGlscyc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuXG50eXBlIG5vZGVLZXkgPVxuICB8ICdpbnB1dHMnXG4gIHwgJ3Byb2R1Y3RzJ1xuICB8ICdjb21wbGV0ZW5lc3MnXG4gIHwgJ3ByYWN0aWNlcydcbiAgfCAnZW1pc3Npb25zJ1xuICB8ICdlbWlzc2lvbnNSZXNvdXJjZVVzZSdcbiAgfCAnaW1wYWN0cydcbiAgfCAnZW5kcG9pbnRzJztcblxuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdkb3QtY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaycsXG4gIFtMb2dTdGF0dXMubm90UmVxdWlyZWRdOiAnZ3JleSdcbn07XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgX21vZGVsPzogSU1vZGVsKSA9PlxuICAobWV0aG9kSWRcbiAgICA/IHtcbiAgICAgICAgJ2N5Y2xlL3RyYW5zZm9ybWF0aW9uJzogJ0RhdGEgRnJvbSBUcmFuc2Zvcm1hdGlvbicsXG4gICAgICAgIGltcGFjdF9hc3Nlc3NtZW50OiAnRGF0YSBGcm9tIEN5Y2xlJ1xuICAgICAgfVttZXRob2RJZF1cbiAgICA6ICcnKSB8fCAobWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKSk7XG5cbmNvbnN0IGdldE1vZGVsc0F0ID0gKGxvZzogSUJsYW5rTm9kZUxvZ1N1YlZhbHVlIHwgSUJsYW5rTm9kZUxvZywgaW5kZXg6IG51bWJlcikgPT5cbiAgKCdtb2RlbHNJblN1YlZhbHVlcycgaW4gbG9nID8gIWxvZy5tb2RlbHNJblN1YlZhbHVlcyB8fCAhbG9nLmlzT3BlbiA6IHRydWUpICYmIGxvZy5jb25maWdNb2RlbHNbaW5kZXhdO1xuXG5jb25zdCByZXF1aXJlbWVudEtleXMgPSAocmVxdWlyZW1lbnRzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSA9PlxuICBPYmplY3Qua2V5cyhyZXF1aXJlbWVudHMpLmZpbHRlcihrID0+ICFub2RlVHlwZXNMb3dlckNhc2UuaW5jbHVkZXMoaykpO1xuXG5jb25zdCByZXF1aXJlbWVudENvbG9yID0gKHZhbHVlOiBhbnkpID0+ICghdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnKTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXk6IHtcbiAgW2tleTogc3RyaW5nXTogKHZhbHVlOiBzdHJpbmcpID0+IFBhcnRpYWw8SlNPTkxEPE5vZGVUeXBlPj47XG59ID0ge1xuICByZWxhdGVkX2N5Y2xlczogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGN5Y2xlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgaW1wYWN0X2Fzc2Vzc21lbnRfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuSW1wYWN0QXNzZXNzbWVudCwgJ0BpZCc6IHYgfSksXG4gIHNpdGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU2l0ZSwgJ0BpZCc6IHYgfSksXG4gIHNvdXJjZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5Tb3VyY2UsICdAaWQnOiB2IH0pXG59O1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGUgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+XG4gIGtleSBpbiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleSAmJiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleVtrZXldKHZhbHVlKTtcblxuY29uc3QgaXNTeXN0ZW1Cb3VuZGFyeSA9XG4gICh0ZXJtSWQ/OiBzdHJpbmcpID0+XG4gICh7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz4pID0+IHtcbiAgICAvLyBvbmx5IGV4aXN0cyBmb3Igc29tZSB0ZXJtc1xuICAgIGNvbnN0IGluU3lzdGVtQm91bmRhcnkgPSBsb2FkUmVzb3VyY2VLZXkoJ2luSGVzdGlhRGVmYXVsdFN5c3RlbUJvdW5kYXJ5Lmpzb24nLCB0ZXJtSWQpO1xuICAgIHJldHVybiAhaW5TeXN0ZW1Cb3VuZGFyeSA/IFtpc1JlY2FsY3VsYXRlZCwgaXNSZXF1aXJlZF0uc29tZShCb29sZWFuKSA6IGAke2luU3lzdGVtQm91bmRhcnl9YCA9PT0gJ3RydWUnO1xuICB9O1xuXG5jb25zdCBpc0dlbmVyaWNUZXJtID0gKHRlcm1JZDogc3RyaW5nKSA9PiBbdGVybUlkLnN0YXJ0c1dpdGgoJ2V4Y3JldGEnKV0uZXZlcnkoQm9vbGVhbik7XG5cbmNvbnN0IGV4dHJhVGVybUlkc0Zyb21Db25maWcgPSAoY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnLCBrZXk6IG5vZGVLZXkpID0+XG4gIGNvbmZpZy5tb2RlbHNcbiAgICAuZmxhdCgpXG4gICAgLmZpbHRlcihtID0+IG0ua2V5ID09PSBrZXkpXG4gICAgLm1hcChtID0+IG0udmFsdWUpXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5maWx0ZXIodiA9PiAhaXNHZW5lcmljVGVybSh2KSk7XG5cbmNvbnN0IG1hdGNoVGVybVR5cGVGcm9tS2V5OiB7XG4gIFtrZXk6IHN0cmluZ106IFRlcm1UZXJtVHlwZVtdO1xufSA9IHtcbiAgcHJvZHVjdHM6IHByb2R1Y3RUZXJtVGVybVR5cGUudGVybSxcbiAgaW5wdXRzOiBpbnB1dFRlcm1UZXJtVHlwZS50ZXJtLFxuICBtZWFzdXJlbWVudHM6IG1lYXN1cmVtZW50VGVybVRlcm1UeXBlLnRlcm0sXG4gIHByYWN0aWNlczogcHJhY3RpY2VUZXJtVGVybVR5cGUudGVybSxcbiAgZW1pc3Npb25zOiBlbWlzc2lvblRlcm1UZXJtVHlwZS50ZXJtLFxuICBlbWlzc2lvbnNSZXNvdXJjZVVzZTogaW5kaWNhdG9yVGVybVRlcm1UeXBlLnRlcm0sXG4gIGltcGFjdHM6IGluZGljYXRvclRlcm1UZXJtVHlwZS50ZXJtLFxuICBlbmRwb2ludHM6IGluZGljYXRvclRlcm1UZXJtVHlwZS50ZXJtXG59O1xuXG5jb25zdCB0ZXJtU2VhcmNoID0gKHRlcm0gPSAnJykgPT4gdGVybS5yZXBsYWNlKC9bLFxcc10vZywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLW5vZGUtbG9ncy1tb2RlbHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOb2RlTG9nc01vZGVsc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgbG9nczogc3RyaW5nO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IChJQmxhbmtOb2RlTG9nIHwgSU5vbkJsYW5rTm9kZUxvZylbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5Pzogbm9kZUtleTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBvcmlnaW5hbFZhbHVlczogYmxhbmtOb2RlW10gfCBub25CbGFua05vZGUgPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSByZWNhbGN1bGF0ZWRWYWx1ZXM6IGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgdGVybXM6IElUZXJtSlNPTkxEW10gPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBmaWx0ZXJUZXJtVHlwZXM/OiBUZXJtVGVybVR5cGVbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBmaWx0ZXJUZXJtVHlwZXNMYWJlbD86IHN0cmluZztcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBsb2dzS2V5Pzogc3RyaW5nO1xuXG4gIHB1YmxpYyBsb2dzVXJsPzogc3RyaW5nO1xuICBwdWJsaWMgYmFzZVVybCA9IGJhc2VVcmwoKTtcbiAgcHVibGljIGlzRXh0ZXJuYWwgPSBpc0V4dGVybmFsKCk7XG4gIHB1YmxpYyBDeWNsZUZ1bmN0aW9uYWxVbml0ID0gQ3ljbGVGdW5jdGlvbmFsVW5pdDtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBpc1N5c3RlbUJvdW5kYXJ5ID0gaXNTeXN0ZW1Cb3VuZGFyeTtcbiAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xuICBwdWJsaWMgbm9kZVR5cGU6IE5vZGVUeXBlO1xuICBwdWJsaWMgYmxhbmtOb2RlczogKElCbGFua05vZGVMb2cgfCBJTm9uQmxhbmtOb2RlTG9nKVtdID0gW107XG4gIHB1YmxpYyBtZXRob2RNb2RlbHNDb3VudCA9IDA7XG4gIHB1YmxpYyBvbmx5UmVxdWlyZWQgPSB0cnVlO1xuICBwdWJsaWMgc2hvd0xlZ2VuZCA9IHRydWU7XG5cbiAgcHVibGljIHRlcm0/OiBzdHJpbmc7XG4gIHB1YmxpYyBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwdWJsaWMgc3VnZ2VzdFRlcm0gPSAodGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPikgPT5cbiAgICB0ZXh0JC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHN3aXRjaE1hcCh2ID0+IHRoaXMuc3VnZ2VzdEJ5VGVybSh2KSlcbiAgICApO1xuXG4gIHB1YmxpYyB0eXBlYWhlYWRGb2N1cyA9IHR5cGVhaGVhZEZvY3VzO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IEhlTm9kZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZWFyY2hTZXJ2aWNlOiBIZVNlYXJjaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmdpbmVTZXJ2aWNlOiBIZUVuZ2luZVNlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUsIHRoaXMubm9kZVsnQGlkJ10gfHwgdGhpcy5ub2RlLmlkKTtcblxuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgYm9vbDoge1xuICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pLCBtYXRjaFRlcm1UeXBlKFRlcm1UZXJtVHlwZS5tb2RlbCldXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1ldGhvZHNCeUlkID0gYXdhaXQgZnJvbShtb2RlbHMpXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcbiAgICAgICAgZGlzdGluY3QodiA9PiB2WydAaWQnXSksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICAvLyBmcm9tIGBtb2RlbC1saW5rcy5qc29uYCBmaWxlXG4gICAgY29uc3QgZW5naW5lTW9kZWxzID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm1vZGVscygpO1xuXG4gICAgdGhpcy5pc0JsYW5rTm9kZXNcbiAgICAgID8gYXdhaXQgdGhpcy5wcm9jZXNzQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZylcbiAgICAgIDogYXdhaXQgdGhpcy5wcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZyk7XG5cbiAgICB0aGlzLmZpbHRlclJlc3VsdHMoKTtcblxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dzKCkge1xuICAgIHJldHVybiB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyh0aGlzLm5vZGUpLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWdnZXN0QnlUZXJtKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiBmcm9tKHRoaXMuYWxsVGVybXMpLnBpcGUoXG4gICAgICBtYXAodiA9PiB2Lm5hbWUpLFxuICAgICAgZmlsdGVyKHYgPT4gdGVybVNlYXJjaCh2KS5pbmNsdWRlcyh0ZXJtU2VhcmNoKHRlcm0pKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NCbGFua05vZGVzKFxuICAgIGxvZ3M6IElOb2RlTG9ncyB8IElOb2RlVGVybUxvZ3MsXG4gICAgZW5naW5lTW9kZWxzOiBJTW9kZWxbXSxcbiAgICBjb25maWc6IElPcmNoZXN0cmF0b3JDb25maWdcbiAgKSB7XG4gICAgY29uc3QgZXh0cmFUZXJtSWRzID0gZXh0cmFUZXJtSWRzRnJvbUNvbmZpZyhjb25maWcsIHRoaXMubm9kZUtleSk7XG4gICAgY29uc3QgbWF0Y2hUZXJtVHlwZXMgPSBbLi4uKG1hdGNoVGVybVR5cGVGcm9tS2V5W3RoaXMubm9kZUtleV0gfHwgW10pLCAuLi4odGhpcy5maWx0ZXJUZXJtVHlwZXMgfHwgW10pXTtcbiAgICBjb25zdCBleHRyYVRlcm1zID0gYXdhaXQgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFtcbiAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksXG4gICAgICAgICAgbWF0Y2hUZXJtVHlwZXMubGVuZ3RoXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBib29sOiB7XG4gICAgICAgICAgICAgICAgICBzaG91bGQ6IG1hdGNoVGVybVR5cGVzLm1hcChtYXRjaFRlcm1UeXBlKSxcbiAgICAgICAgICAgICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGxcbiAgICAgICAgXS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICAgIHNob3VsZDogZXh0cmFUZXJtSWRzLm1hcChtYXRjaElkKSxcbiAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYWxsVGVybXMgPSBhd2FpdCBjb21wdXRlVGVybXMoXG4gICAgICB0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLnRlcm1zLFxuICAgICAgdGhpcy5maWx0ZXJUZXJtVHlwZXMsXG4gICAgICBleHRyYVRlcm1zXG4gICAgKTtcbiAgICBjb25zdCBtYXBGdW5jID0gZ3JvdXBMb2dzQnlUZXJtKFxuICAgICAgdGhpcy5ub2RlVHlwZSxcbiAgICAgIGxvZ3MsXG4gICAgICBlbmdpbmVNb2RlbHMsXG4gICAgICBjb25maWcsXG4gICAgICB0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLm5vZGVLZXlcbiAgICApO1xuICAgIGNvbnN0IGFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAobWFwRnVuYyk7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IG1vZGVsQ291bnQoYWxsQmxhbmtOb2Rlcyk7XG5cbiAgICB0aGlzLnRlcm1zQnlJZCA9IGF3YWl0IG9mKGFsbEJsYW5rTm9kZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICAgIG1hcCh2ID0+IHYuaWQpLFxuICAgICAgICBkaXN0aW5jdCgpLFxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxuICAgICAgICB0b0FycmF5KCksXG4gICAgICAgIG1lcmdlTWFwKGlkcyA9PlxuICAgICAgICAgIGZyb20oXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSldLFxuICAgICAgICAgICAgICAgIHNob3VsZDogaWRzLm1hcChpZCA9PiBtYXRjaEV4YWN0UXVlcnkoJ0BpZCcsIGlkKSksXG4gICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG1lcmdlQWxsKCksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSBhbGxCbGFua05vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzOiBJTm9kZUxvZ3MgfCBJTm9kZVRlcm1Mb2dzLCBlbmdpbmVNb2RlbHM6IElNb2RlbFtdLCBfY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnKSB7XG4gICAgY29uc3QgbWFwRnVuYyA9IGdyb3VwZExvZ3NCeUtleShcbiAgICAgIHRoaXMubm9kZVR5cGUsXG4gICAgICBsb2dzLFxuICAgICAgZW5naW5lTW9kZWxzLFxuICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlcyBhcyBub25CbGFua05vZGUsXG4gICAgICB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyBhcyBub25CbGFua05vZGVcbiAgICApO1xuICAgIGNvbnN0IGtleXMgPSBjb21wdXRlS2V5cyh0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIG5vbkJsYW5rTm9kZSwgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgbm9uQmxhbmtOb2RlKTtcbiAgICBjb25zdCBhbGxCbGFua05vZGVzID0ga2V5cy5mbGF0TWFwKG1hcEZ1bmMpO1xuICAgIHRoaXMuYWxsQmxhbmtOb2RlcyA9IGFsbEJsYW5rTm9kZXM7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IDE7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGlzQmxhbmtOb2RlcygpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh0aGlzLm9yaWdpbmFsVmFsdWVzKSB8fCBBcnJheS5pc0FycmF5KHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzKTtcbiAgfVxuXG4gIHB1YmxpYyB0cmFja0J5QmxhbmtOb2RlKF9pbmRleDogbnVtYmVyLCBub2RlOiBhbnkpIHtcbiAgICByZXR1cm4gbm9kZS50ZXJtSWQgfHwgbm9kZS5rZXk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpbHRlcmVkVHlwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJUZXJtVHlwZXNMYWJlbCB8fCB0aGlzLmZpbHRlclRlcm1UeXBlcz8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWx0ZXJCbGFua05vZGUoeyB0ZXJtOiB7IG5hbWUsICdAaWQnOiBpZCB9LCBzdWJWYWx1ZXMsIC4uLmxvZyB9OiBJQmxhbmtOb2RlTG9nKSB7XG4gICAgcmV0dXJuIHRoaXMudGVybVxuICAgICAgPyBuYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGhpcy50ZXJtLnRvTG93ZXJDYXNlKCkpXG4gICAgICA6ICF0aGlzLmZpbHRlclRlcm1UeXBlcz8ubGVuZ3RoIHx8XG4gICAgICAgICAgIXRoaXMub25seVJlcXVpcmVkIHx8XG4gICAgICAgICAgaXNTeXN0ZW1Cb3VuZGFyeShpZCkobG9nKSB8fFxuICAgICAgICAgIHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkoaWQpKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXJSZXN1bHRzKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5ibGFua05vZGVzID0gdGhpcy5hbGxCbGFua05vZGVzLmZpbHRlcihsb2cgPT4gISgndGVybScgaW4gbG9nKSB8fCB0aGlzLmZpbHRlckJsYW5rTm9kZShsb2cpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkW21ldGhvZElkXT8ubmFtZSB8fCBtZXRob2RJZExhYmVsKG1ldGhvZElkLCBtb2RlbCk7XG4gIH1cblxuICBwdWJsaWMgaGFzTWV0aG9kVGllcih2YWx1ZXM6IGJsYW5rTm9kZVtdLCBtZXRob2RUaWVyOiBFbWlzc2lvbk1ldGhvZFRpZXIpIHtcbiAgICByZXR1cm4gdmFsdWVzLnNvbWUodiA9PiAnbWV0aG9kVGllcicgaW4gdiAmJiB2Lm1ldGhvZFRpZXIgPT09IG1ldGhvZFRpZXIpO1xuICB9XG5cbiAgcHVibGljIHRlcm1CeUlkKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy50ZXJtc0J5SWRbaWRdIHx8XG4gICAgICAoe1xuICAgICAgICAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLFxuICAgICAgICAnQGlkJzogaWQsXG4gICAgICAgIG5hbWU6IHRlcm1UeXBlTGFiZWwoaWQpXG4gICAgICB9IGFzIElUZXJtSlNPTkxEKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZ1bmN0aW9uYWxVbml0KCkge1xuICAgIHJldHVybiAodGhpcy5ub2RlIGFzIGFueSk/LmZ1bmN0aW9uYWxVbml0IGFzIEN5Y2xlRnVuY3Rpb25hbFVuaXQ7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweC0zIHBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IG1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsXCI+XG4gICAgPGEgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cImxvZ3NVcmxcIiBbaHJlZl09XCJsb2dzVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgbWF4SGVpZ2h0PVwiMzIwXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIGlzLW5hcnJvdyBpcy1zdHJpcGVkXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiICpuZ0lmPVwiYWxsVGVybXM/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udHJvbCBpcy1leHBhbmRlZCBoYXMtaWNvbnMtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5wdXQgc2VhcmNoLWlucHV0IGlzLXNtYWxsXCJcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdCBlbnRyeSBieSBuYW1lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ2JUeXBlYWhlYWRdPVwic3VnZ2VzdFRlcm1cIlxuICAgICAgICAgICAgICAgICAgW2ZvY3VzRmlyc3RdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAoZm9jdXMpPVwidHlwZWFoZWFkRm9jdXMoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoc2VsZWN0SXRlbSk9XCJmaWx0ZXJSZXN1bHRzKClcIiAvPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiaWNvbiBpcy1zbWFsbCBpcy1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXRlcm1cIiAoY2xpY2spPVwidGVybSA9ICcnOyBmaWx0ZXJSZXN1bHRzKClcIj5cbiAgICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJ0aW1lc1wiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8dGggKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcHItMVwiPlVuaXRzPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+KHBlciZuYnNwOzwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIFtuZ1N3aXRjaF09XCJmdW5jdGlvbmFsVW5pdFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJDeWNsZUZ1bmN0aW9uYWxVbml0WycxIGhhJ11cIj5oZWN0YXJlPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD5rZyBwcm9kdWN0PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8c3Bhbj4pPC9zcGFuPlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRoPk9yaWdpbmFsPC90aD5cbiAgICAgICAgICA8dGg+UmVjYWxjdWxhdGVkPC90aD5cbiAgICAgICAgICA8dGggKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj5EaWZmZXJlbmNlPC90aD5cbiAgICAgICAgICA8dGggKm5nRm9yPVwibGV0IGMgb2YgbWV0aG9kTW9kZWxzQ291bnQgfCB0aW1lczsgbGV0IGkgPSBpbmRleFwiPih7eyBpICsgMSB9fSk8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyICpuZ0lmPVwibG9hZGluZ1wiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXIgcHktM1wiPlxuICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwic3Bpbm5lclwiIFtwdWxzZV09XCJ0cnVlXCIgc2l6ZT1cImxnXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyICpuZ0lmPVwiIWxvYWRpbmcgJiYgYmxhbmtOb2Rlcy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8c3Bhbj5ObyBkYXRhPC9zcGFuPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGJsYW5rTm9kZSBvZiBibGFua05vZGVzOyB0cmFja0J5OiB0cmFja0J5QmxhbmtOb2RlXCI+XG4gICAgICAgICAgPHRyIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLmNhbk9wZW5cIiBbY2xhc3MuaXMtb3Blbl09XCJibGFua05vZGUuaXNPcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHQgaXMtbm93cmFwXCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0/Lm5hbWUgfHwgYmxhbmtOb2RlLmtleVwiPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0yIG9wZW4tbm9kZVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImJsYW5rTm9kZS5pc09wZW4gPSAhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cImJsYW5rTm9kZS5pc09wZW5cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGhlLW5vZGUtbGluayBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1wcmUtd3JhcFwiICpuZ0lmPVwiYmxhbmtOb2RlLnRlcm1cIiBbbm9kZV09XCJibGFua05vZGUudGVybVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJibGFua05vZGUua2V5XCI+e3sgYmxhbmtOb2RlLmtleSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXBcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0T3JpZ2luYWxWYWx1ZT5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBibGFua05vZGUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0T3JpZ2luYWxWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgIHt7IGJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWJsYW5rTm9kZS5pc09yaWdpbmFsIHx8IGJsYW5rTm9kZS5pc1JlY2FsY3VsYXRlZDsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRSZWNhbGN1bGF0ZWRWYWx1ZT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCIgY2xhc3M9XCJpcy1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVsdGFWYWx1ZT5cbiAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YVxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJibGFua05vZGUub3JpZ2luYWwubGVuZ3RoICYmIGJsYW5rTm9kZS5pc1JlY2FsY3VsYXRlZDsgZWxzZSBub1ZhbHVlXCJcbiAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVcIj48L2hlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGE+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdERlbHRhVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+XG4gICAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YVxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgIGJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdICE9PSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9WYWx1ZVxuICAgICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF1cIlxuICAgICAgICAgICAgICAgICAgICBbb3JpZ2luYWxWYWx1ZV09XCJibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCI+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7IGRhdGE6IGJsYW5rTm9kZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90cj5cblxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IHN1YlZhbHVlIG9mIGJsYW5rTm9kZS5rZXlzXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgW2NsYXNzLmhhcy1zdWItcm93c109XCJibGFua05vZGUuc3ViVmFsdWVzPy5sZW5ndGhcIlxuICAgICAgICAgICAgW2NsYXNzLmlzLXN1Yi1yb3ddPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodCBpcy1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTMgcHItMSBmaWVsZC1ub2RlXCI+RmllbGQ6PC9zcGFuPlxuXG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtcHJlLXdyYXBcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLnR5cGVcIlxuICAgICAgICAgICAgICAgIFtocmVmXT1cImJhc2VVcmwgKyAnL3NjaGVtYS8nICsgYmxhbmtOb2RlLnR5cGUgKyAnIycgKyBzdWJWYWx1ZS5rZXlcIlxuICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgW3RpdGxlXT1cInN1YlZhbHVlLmtleVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IHN1YlZhbHVlLmtleSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3BcIiAqbmdJZj1cIiFibGFua05vZGUudHlwZVwiPnt7IHN1YlZhbHVlLmtleSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5pc1JlY2FsY3VsYXRlZCB8fCBzdWJWYWx1ZS5rZXkgPT09ICdpbXBhY3RBc3Nlc3NtZW50JzsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+LTwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7IGRhdGE6IHN1YlZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLnN1YlZhbHVlc1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1zdWItcm93XT1cImJsYW5rTm9kZS5jYW5PcGVuXCI+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTNcIj57eyBzdWJWYWx1ZS5rZXkgfCBrZXlUb0xhYmVsIH19PC9zcGFuPlxuXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzdWJWYWx1ZS5pZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHByLTFcIj46PC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwic3ViVmFsdWUua2V5XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiICpuZ1N3aXRjaENhc2U9XCInYmFja2dyb3VuZERhdGEnXCI+e3sgc3ViVmFsdWUuaWQgfCBrZXlUb0xhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGhlLW5vZGUtbGlua1xuICAgICAgICAgICAgICAgICAgICAqbmdTd2l0Y2hEZWZhdWx0XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaXMtYmxvY2sgcGwtNFwiXG4gICAgICAgICAgICAgICAgICAgIFtub2RlXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnRpdGxlXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWUgfCBjb21wb3VuZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvaGUtbm9kZS1saW5rPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXBcIiAqbmdJZj1cInN1YlZhbHVlLnNob3dVbml0c1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5pc1JlY2FsY3VsYXRlZDsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICB7eyBzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+LTwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7IGRhdGE6IHN1YlZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9oZS1kYXRhLXRhYmxlPlxuXG4gIDxkaXYgY2xhc3M9XCJpcy1zaXplLTcgaXMtaXRhbGljXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbnMgaXMtdmFyaWFibGUgaXMtMSBteS0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGlzLW5hcnJvd1wiPlxuICAgICAgICA8cD5cbiAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBwci0yXCIgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7IGxvZ0NvbG9yW3N0YXR1cy52YWx1ZV0gfX1cIj5cbiAgICAgICAgICAgICAgPGZhLWljb24gW2ljb25dPVwibG9nSWNvbltzdGF0dXMudmFsdWVdXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBsLTFcIj57eyBzdGF0dXMudmFsdWUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGhhcy10ZXh0LXJpZ2h0XCIgKm5nSWY9XCJmaWx0ZXJlZFR5cGVcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGNoZWNrYm94XCI+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgY2xhc3M9XCJzZWxlY3RvclwiXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cImZpbHRlclJlc3VsdHMoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtXCIgLz5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1sLTJcIj5cbiAgICAgICAgICAgIFNob3cgb25seSB7eyBmaWx0ZXJlZFR5cGUgfCBwbHVyYWxpemUgfX0gaW5jbHVkZWQgaW4gdGhlIGRlZmF1bHQgSGVzdGlhIHN5c3RlbSBib3VuZGFyeVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPG5nLXRlbXBsYXRlICNub3RJblN5c3RlbUJvdW5kYXJ5PlxuICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIm1ldGhvZE1vZGVsc0NvdW50XCI+XG4gICAgICA8c3Bhbj5Ob3QgaW4gSGVzdGlhIHN5c3RlbSBib3VuZGFyeTwvc3Bhbj5cbiAgICA8L3RkPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1N5c3RlbUJvdW5kYXJ5KGRhdGEpOyBlbHNlIG5vVmFsdWVcIj5cbiAgICA8dGQgY2xhc3M9XCJibGFuay1ub2RlLWluZGV4LXt7IGkgfX1cIiAqbmdGb3I9XCJsZXQgYyBvZiBtZXRob2RNb2RlbHNDb3VudCB8IHRpbWVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0TW9kZWxzQXQoZGF0YSwgaSk7IGxldCBtb2RlbHM7IGVsc2U6IG5vVmFsdWVcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNtb2RlbFNlcmllPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbDsgY29udGV4dDogeyBtb2RlbDogbW9kZWxzLCBkYXRhIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVscyB8IGlzQXJyYXk7IGVsc2UgbW9kZWxTZXJpZVwiPlxuICAgICAgICAgIDxwICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBtb2RlbHNcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbDsgY29udGV4dDogeyBtb2RlbCwgZGF0YSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvdGQ+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbCBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8c3BhblxuICAgIGNsYXNzPVwiaXMtbm93cmFwXCJcbiAgICBbY2xhc3MudHJpZ2dlci1wb3BvdmVyXT1cIm1vZGVsLnNob3dMb2dzXCJcbiAgICBbbmdiUG9wb3Zlcl09XCJsb2dEZXRhaWxzXCJcbiAgICBbYXV0b0Nsb3NlXT1cIidvdXRzaWRlJ1wiXG4gICAgcG9wb3ZlckNsYXNzPVwiaXMtbmFycm93XCJcbiAgICB0cmlnZ2Vycz1cIm1hbnVhbFwiXG4gICAgI3A9XCJuZ2JQb3BvdmVyXCJcbiAgICBwbGFjZW1lbnQ9XCJsZWZ0XCJcbiAgICBjb250YWluZXI9XCJib2R5XCJcbiAgICAoY2xpY2spPVwicC5pc09wZW4oKSA/IHAuY2xvc2UoKSA6IG1vZGVsLnNob3dMb2dzID8gcC5vcGVuKHsgbG9nczogbW9kZWwubG9ncyB9KSA6IG51bGxcIj5cbiAgICA8c3BhbiBjbGFzcz1cImlzLWNhcGl0YWxpemVkXCI+e3sgbWV0aG9kTmFtZShtb2RlbCkgfX08L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyXCI+XG4gICAgICBbe3sgbW9kZWwubG9ncz8ubWV0aG9kVGllciB8fCBtb2RlbC5tb2RlbD8ubWV0aG9kVGllciB9fV1cbiAgICA8L3NwYW4+XG5cbiAgICA8c3BhblxuICAgICAgY2xhc3M9XCJwbC0xIGhhcy10ZXh0LXt7IGxvZ0NvbG9yW21vZGVsLnN0YXR1c10gfX0gdHJpZ2dlci1wb3BvdmVyXCJcbiAgICAgIFtuZ2JQb3BvdmVyXT1cImxvZ1N0YXR1c0RldGFpbHNcIlxuICAgICAgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIlxuICAgICAgcG9wb3ZlckNsYXNzPVwiaXMtbmFycm93XCJcbiAgICAgIHRyaWdnZXJzPVwibWFudWFsXCJcbiAgICAgICNwMT1cIm5nYlBvcG92ZXJcIlxuICAgICAgcGxhY2VtZW50PVwibGVmdFwiXG4gICAgICBjb250YWluZXI9XCJib2R5XCJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IHAxLmlzT3BlbigpID8gcDEuY2xvc2UoKSA6IHAxLm9wZW4oeyBtb2RlbCwgZGF0YSB9KVwiPlxuICAgICAgPGZhLWljb24gW2ljb25dPVwibG9nSWNvblttb2RlbC5zdGF0dXNdXCI+PC9mYS1pY29uPlxuICAgIDwvc3Bhbj5cblxuICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiICpuZ0lmPVwibW9kZWwubW9kZWxcIj5cbiAgICAgIChcbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkb2NzTGluazsgY29udGV4dDogeyAkaW1wbGljaXQ6IG1vZGVsLm1vZGVsIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIClcbiAgICA8L3NwYW4+XG4gIDwvc3Bhbj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbm9WYWx1ZT4tPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub3RSZWNhbGN1bGF0ZWQ+bm90IHJlY2FsY3VsYXRlZDwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nRGV0YWlscyBsZXQtbG9ncz1cImxvZ3NcIj5cbiAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lclwiICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWZ1bGx3aWR0aFwiPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9ncz8ucmVxdWlyZW1lbnRzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIHJlcXVpcmVtZW50S2V5cyhsb2dzLnJlcXVpcmVtZW50cylcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OiB7IGtleSwgdmFsdWU6IGxvZ3MucmVxdWlyZW1lbnRzW2tleV0gfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9ncz8ubG9nc1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiBsb2dzLmxvZ3MgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZTsgY29udGV4dDoga2V5XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2Rpdj5cblxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaXQtbXQtMlwiICpuZ0lmPVwibG9ncz8ubWlzc2luZ0xvb2t1cHM/Lmxlbmd0aFwiPlxuICAgICAgPHA+T3B0aW9uYWwgZGF0YSBtaXNzaW5nOjwvcD5cblxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lciBkYXRhLXRhYmxlLWNvbnRhaW5lclwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWZ1bGx3aWR0aCBpcy1zdHJpcGVkXCI+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPkZpbGVuYW1lPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPkNvbHVtbiBUaXRsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Sb3cgKHRlcm0uaWQpPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keSBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IGRhdGEgb2YgbG9ncy5taXNzaW5nTG9va3Vwc1wiPlxuICAgICAgICAgICAgICA8dGQ+e3sgZGF0YS5maWxlbmFtZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57eyBkYXRhLmNvbHVtbiB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57eyBkYXRhLnRlcm1JZCB9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0xpbmVWYWx1ZSBsZXQta2V5PVwia2V5XCIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAgPG5nLXRlbXBsYXRlICNkZWZhdWx0VmFsdWU+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+e3sgdmFsdWUgfX08L3NwYW4+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJyZXF1aXJlbWVudExpbmtlZE5vZGUoa2V5LCB2YWx1ZSk7IGxldCBsaW5rZWROb2RlOyBlbHNlOiBkZWZhdWx0VmFsdWVcIj5cbiAgICA8aGUtbm9kZS1saW5rXG4gICAgICBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIlxuICAgICAgbGlua0NsYXNzPVwiaXMtZGFya1wiXG4gICAgICBbbm9kZV09XCJsaW5rZWROb2RlXCJcbiAgICAgIFtzaG93RXh0ZXJuYWxMaW5rXT1cInRydWVcIj48L2hlLW5vZGUtbGluaz5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0xpbmUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDx0cj5cbiAgICA8dGQgY2xhc3M9XCJoYXMtYm9yZGVyLXJpZ2h0IGNvcHktbG9nXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD57eyBrZXkgfCBrZXlUb0xhYmVsIH19PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ25vZGVfdHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgIElzIHRoZSBjdXJyZW50XG4gICAgICAgICAgPGNvZGU+Tm9kZTwvY29kZT5cbiAgICAgICAgICBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2l0ZVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICBJcyB0aGUgY3VycmVudFxuICAgICAgICAgIDxjb2RlPnNpdGVUeXBlPC9jb2RlPlxuICAgICAgICAgIGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfaWRfYWxsb3dlZCdcIj5cbiAgICAgICAgICBJcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3RcbiAgICAgICAgICA8Y29kZT5AaWQ8L2NvZGU+XG4gICAgICAgICAgYWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbFxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF90ZXJtVHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgIElzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdFxuICAgICAgICAgIDxjb2RlPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgIGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWxcbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2dlb3NwYXRpYWxfZGF0YSdcIj5IYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY29udGFpbnNfZ2Vvc3BhdGlhbF9kYXRhJ1wiPlxuICAgICAgICAgIEhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY3VycmVudF9zaXplJ1wiPkN1cnJlbnQgcG9seWdvbiBhcmVhPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtYXhfYXJlYV9zaXplJ1wiPk1heGltdW0gcG9seWdvbiBhcmVhIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncmVnaW9uX2ZhY3RvcidcIj5GYWN0b3IgZnJvbSByZWdpb24gbG9va3VwPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Blc3RpY2lkZXNfY29tcGxldGUnXCI+XG4gICAgICAgICAgUGVzdGljaWRlIGRhdGEgYXJlXG4gICAgICAgICAgPGNvZGU+Y29tcGxldGU8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPlxuICAgICAgICAgIEN5Y2xlIGNvbnRhaW5zXG4gICAgICAgICAgPGNvZGU+cGVzdGljaWRlQUk8L2NvZGU+XG4gICAgICAgICAgSW5wdXRzXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYWxsX3Blc3RpY2lkZUFJX2hhdmVfbG9va3VwX3ZhbHVlJ1wiPlxuICAgICAgICAgIEFsbFxuICAgICAgICAgIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPlxuICAgICAgICAgIElucHV0cyBoYXZlIGEgbG9va3VwIHZhbHVlXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfY3JvcF9yZXNpZHVlX2J1cm50J1wiPlxuICAgICAgICAgIDxjb2RlPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT5cbiAgICAgICAgICBpcyBwcmVzZW50IGFzIFByb2R1Y3RcbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2xpcXVpZF9zbHVycnlfc2x1ZGdlX1AnXCI+TGlxdWlkLCBTbHVycnksIGFuZCBTbHVkZ2UgUDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfY3JvcFJlc2lkdWVfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwiY3JvcFJlc2lkdWVcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+dHJ1ZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfZXhjcmV0YV9jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJleGNyZXRhXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPnRydWU8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2ZlcnRpbGlzZXJfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwiZmVydGlsaXNlclwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9tYXRlcmlhbF9jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJtYXRlcmlhbFwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9vdGhlcl9jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJvdGhlclwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT50cnVlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9wZXN0aWNpZGVzQW50aWJpb3RpY3NfY29tcGxldGUnXCI+XG4gICAgICAgICAgRGF0YSBjb21wbGV0ZW5lc3MgZm9yIFwicGVzdGljaWRlc0FudGliaW90aWNzXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPnRydWU8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfY3JvcFJlc2lkdWVfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJjcm9wUmVzaWR1ZVwiIG11c3QgYmVcbiAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXJtX3R5cGVfZXhjcmV0YV9pbmNvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcImV4Y3JldGFcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIndGVybV90eXBlX2ZlcnRpbGlzZXJfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJmZXJ0aWxpc2VyXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9tYXRlcmlhbF9pbmNvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcIm1hdGVyaWFsXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9vdGhlcl9pbmNvbXBsZXRlJ1wiPlxuICAgICAgICAgIERhdGEgY29tcGxldGVuZXNzIGZvciBcIm90aGVyXCIgbXVzdCBiZVxuICAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Rlcm1fdHlwZV9wZXN0aWNpZGVzQW50aWJpb3RpY3NfaW5jb21wbGV0ZSdcIj5cbiAgICAgICAgICBEYXRhIGNvbXBsZXRlbmVzcyBmb3IgXCJwZXN0aWNpZGVzQW50aWJpb3RpY3NcIiBtdXN0IGJlXG4gICAgICAgICAgPGNvZGU+ZmFsc2U8L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9zcGFuPlxuICAgICAgPGhlLWNsaXBib2FyZFxuICAgICAgICBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIlxuICAgICAgICBjbGlwYm9hcmRDbGFzcz1cImlzLXNpemUtNyBpcy1wLTFcIlxuICAgICAgICBbaWNvbl09XCJbJ2ZhcicsICdjbG9uZSddXCJcbiAgICAgICAgW3ZhbHVlXT1cImtleVwiXG4gICAgICAgIFtoaWRlVGV4dF09XCJ0cnVlXCI+PC9oZS1jbGlwYm9hcmQ+XG4gICAgPC90ZD5cbiAgICA8dGQ+XG4gICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVZhbHVlPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZVZhbHVlOyBjb250ZXh0OiB7IGtleSwgdmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxkaXYgKm5nSWY9XCJsb2dWYWx1ZUFycmF5KHZhbHVlKTsgbGV0IHZhbHVlQXJyYXk7IGVsc2U6IHNpbmdsZVZhbHVlXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtYm9yZGVyZWQgaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZCAqbmdJZj1cInZhbHVlQXJyYXlbMF0gfCBpc09iamVjdFwiPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlbMF0gfCBrZXlzXCI+e3sgdi5rZXkgfX08L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5XCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlQXJyYXlWYWx1ZT5cbiAgICAgICAgICAgICAgICA8dGQ+e3sgdiB9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2IHwgaXNPYmplY3Q7IGVsc2Ugc2luZ2xlQXJyYXlWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgdnYgb2YgdiB8IGtleXNcIj57eyB2di52YWx1ZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbiAgPC90cj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nU3RhdHVzRGV0YWlscyBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cIm1vZGVsXCI+XG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxzcGFuPlN0YXR1czo8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5zdGF0dXMgfX08L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuc3RhdHVzID09PSBMb2dTdGF0dXMubm90UmVxdWlyZWQgJiYgbW9kZWwubG9ncz8uaXNfbm90X3JlbGV2YW50ID09PSAnVHJ1ZSdcIj5cbiAgICAgIDx1bCBjbGFzcz1cImlzLXBsLTMgaXMtbGlzdC1zdHlsZS1kaXNjXCI+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uc2l0ZVR5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIFRoZVxuICAgICAgICAgIDxjb2RlPnNpdGVUeXBlPC9jb2RlPlxuICAgICAgICAgIGlzIG5vdCByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5wcm9kdWN0X2lkX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGUgcHJpbWFyeSBwcm9kdWN0XG4gICAgICAgICAgPGNvZGU+QGlkPC9jb2RlPlxuICAgICAgICAgIGlzIG5vdCByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGUgcHJpbWFyeSBwcm9kdWN0XG4gICAgICAgICAgPGNvZGU+dGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgaXMgbm90IHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXJcbiAgICAgICpuZ0lmPVwibW9kZWwubG9ncyAmJiBtb2RlbC5zdGF0dXMgIT09IExvZ1N0YXR1cy5ub3RSZXF1aXJlZCAmJiBtb2RlbC5zdGF0dXMgIT09IExvZ1N0YXR1cy5za2lwSGllcmFyY2h5XCI+XG4gICAgICA8dWwgY2xhc3M9XCJpcy1wbC0zIGlzLWxpc3Qtc3R5bGUtZGlzY1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgI3Nob3dSdW5PcmNoZXN0cmF0b3I+XG4gICAgICAgICAgPGxpIGNsYXNzPVwiaXMtcnVuLW9yY2hlc3RyYXRvclwiPlxuICAgICAgICAgICAgPHAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5BbGwgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+XG4gICAgICAgICAgICAgIDxwPlNvbWUgb2YgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG5vdCBtZXQgdG8gcnVuIHRoZSBtb2RlbC48L3A+XG4gICAgICAgICAgICAgIDxwPllvdSBjYW4gY2xpY2sgb24gdGhlIG1vZGVsIG5hbWUgb24gdGhlIGxlZnQgdG8gdmlldyB0aGUgZGVidWdnaW5nIGxvZ3MuPC9wPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwubG9ncz8ubG9ncz8uZXJyb3JcIj5cbiAgICAgICAgICAgICAgPHA+VGhlIG1vZGVsIGZhaWxlZCB0byBydW4gZm9yIHRoZSBmb2xsb3dpbmcgcmVhc29uOjwvcD5cbiAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgPGNvZGU+e3sgbW9kZWwubG9ncy5sb2dzLmVycm9yIH19PC9jb2RlPlxuICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxsaVxuICAgICAgICAgIGNsYXNzPVwiaXMtbm8tcnVuLW9yY2hlc3RyYXRvclwiXG4gICAgICAgICAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5PcmNoZXN0cmF0b3IgPT09IGZhbHNlOyBlbHNlIHNob3dSdW5PcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmxvZ3MucnVuUmVxdWlyZWRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vZGUtdHlwZS1ub3QtYWxsb3dlZFwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5ub2RlX3R5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgICAgICBUaGlzIG1vZGVsIHNob3VsZCBub3QgcnVuIGZvciB7eyBub2RlVHlwZSB8IHBsdXJhbGl6ZTogMCB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNydW5Ob0NvbmZpZz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vdC1lbXB0eVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5pc19lbXB0eSA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgICAgICBUaGUge3sgZGF0YS50eXBlIHx8ICdibGFuayBub2RlJyB9fSB3aXRoIFRlcm1cbiAgICAgICAgICAgICAgPGNvZGU+e3sgZGF0YS50ZXJtSWQgfX08L2NvZGU+XG4gICAgICAgICAgICAgIGlzIGFscmVhZHkgcHJlc2VudCBvciBhbHJlYWR5IGFkZGVkIGJ5IGFub3RoZXIgbW9kZWwuXG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc7IGVsc2UgcnVuTm9Db25maWdcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiaXMtcnVuLXN0cmF0ZWd5LXt7IG1vZGVsLmNvbmZpZy5ydW5TdHJhdGVneSB9fVwiIFtuZ1N3aXRjaF09XCJtb2RlbC5jb25maWcucnVuU3RyYXRlZ3lcIj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhbHdheXMnXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9rZXlfaWZfbWlzc2luZydcIj5XZSBvbmx5IGdhcC1maWxsIHRoaXMga2V5IGlmIG5vdCBwcmVzZW50PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9ibGFua19ub2RlX2lmX21pc3NpbmcnXCI+V2Ugb25seSBnYXAtZmlsbCB0aGlzIEJsYW5rIE5vZGUgaWYgbm90IHByZXNlbnQuPC9zcGFuPlxuICAgICAgICAgICAgPC9wPlxuXG4gICAgICAgICAgICA8cCBjbGFzcz1cImlzLW10LTFcIj5cbiAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICBjbGFzcz1cImlzLXJ1bi13aXRoLW1lYXN1cmVkXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgbW9kZWwuY29uZmlnLnJ1bkFyZ3M/LnJ1bk5vbk1lYXN1cmVkICYmIGhhc01ldGhvZFRpZXIoZGF0YS5vcmlnaW5hbCwgRW1pc3Npb25NZXRob2RUaWVyLm1lYXN1cmVkKVxuICAgICAgICAgICAgICAgIFwiPlxuICAgICAgICAgICAgICAgIFRoZVxuICAgICAgICAgICAgICAgIDxjb2RlPnt7IG1vZGVsLmNvbmZpZy52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICB3YXMgcmVwb3J0ZWQgYXMgbWVhc3VyZWQuXG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9saT5cblxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzPy5yZXBsYWNlTG93ZXJUaWVyICE9PSB1bmRlZmluZWRcIj5cbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIFRoZSByZWNhbGN1bGF0ZWRcbiAgICAgICAgICAgIDxiPm1ldGhvZFRpZXI8L2I+XG4gICAgICAgICAgICB3YXNcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xIGlzLXVuZGVybGluZWRcIiAqbmdJZj1cIiFtb2RlbC5sb2dzLnJlcGxhY2VMb3dlclRpZXJcIj5sb3dlciB0aGFuPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMSBpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VMb3dlclRpZXJcIj5oaWdoZXIgdGhhbiBvciBlcXVhbCB0bzwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICAgIHRoZSBvcmlnaW5hbFxuICAgICAgICAgICAgPGI+bWV0aG9kVGllcjwvYj5cbiAgICAgICAgICAgIC5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpIGNsYXNzPVwiaXMtbWVyZ2UtcmVwbGFjZUxvd2VyVGllclwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+XG4gICAgICAgICAgPHNwYW4+VGhlIHJlY2FsY3VsYXRlZDwvc3Bhbj5cbiAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWc/Lm1lcmdlQXJncz8ucmVwbGFjZVRocmVzaG9sZD8uWzBdIHx8ICd2YWx1ZScgfX08L2I+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+d2FzPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwiIW1vZGVsLmxvZ3MucmVwbGFjZVRocmVzaG9sZFwiPmxlc3MgdGhhbjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5tb3JlIHRoYW4gb3IgZXF1YWwgdG88L3NwYW4+XG4gICAgICAgICAgICAgIDxiIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLmNvbmZpZy5tZXJnZUFyZ3MucmVwbGFjZVRocmVzaG9sZFsxXSAqIDEwMCB9fSU8L2I+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwuY29uZmlnPy5tZXJnZUFyZ3NcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCIhbW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+bm90IHN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5zdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+ZGlmZmVyZW50IGZyb20gdGhlIG9yaWdpbmFsPC9zcGFuPlxuICAgICAgICAgIDxiIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzPy5yZXBsYWNlVGhyZXNob2xkPy5bMF0gfHwgJ3ZhbHVlJyB9fS48L2I+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZG9jc0xpbmsgbGV0LW1vZGVsPlxuICA8YSBbaHJlZl09XCJtb2RlbC5hcGlEb2NzUGF0aCB8fCBtb2RlbC5kb2NQYXRoIHx8IG1vZGVsLnBhdGhcIiB0YXJnZXQ9XCJfYmxhbmtcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgPHNwYW4+RG9jczwvc3Bhbj5cbiAgICA8ZmEtaWNvbiBjbGFzcz1cIm1sLTFcIiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIiBzaXplPVwic21cIj48L2ZhLWljb24+XG4gIDwvYT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=