@hestia-earth/ui-components 0.23.13 → 0.23.15

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 (39) hide show
  1. package/common/common.light.module.d.ts +2 -1
  2. package/common/maps-utils.d.ts +21 -0
  3. package/engine/engine.service.d.ts +2 -1
  4. package/esm2022/common/common.light.module.mjs +6 -5
  5. package/esm2022/common/maps-utils.mjs +30 -1
  6. package/esm2022/engine/engine.service.mjs +5 -2
  7. package/esm2022/node/node-logs-models/node-logs-models.component.mjs +20 -12
  8. package/esm2022/public-api.mjs +2 -1
  9. package/esm2022/search/search.model.mjs +2 -1
  10. package/esm2022/sites/sites-maps/sites-maps.component.mjs +17 -21
  11. package/esm2022/svg-icons/index.mjs +2 -0
  12. package/esm2022/svg-icons/svg-icons.module.mjs +30 -0
  13. package/fesm2022/hestia-earth-ui-components.mjs +181 -121
  14. package/fesm2022/hestia-earth-ui-components.mjs.map +1 -1
  15. package/package.json +3 -1
  16. package/public-api.d.ts +1 -0
  17. package/search/search.model.d.ts +8 -0
  18. package/sites/sites-maps/sites-maps.component.d.ts +9 -11
  19. package/svg-icons/far-arrow-down-to-bracket.svg +8 -0
  20. package/svg-icons/far-arrow-left.svg +3 -0
  21. package/svg-icons/far-arrow-right.svg +3 -0
  22. package/svg-icons/far-circle-info.svg +8 -0
  23. package/svg-icons/far-down-arrow.svg +3 -0
  24. package/svg-icons/far-download.svg +9 -0
  25. package/svg-icons/far-filter.svg +5 -0
  26. package/svg-icons/far-home.svg +11 -0
  27. package/svg-icons/far-info-circle.svg +5 -0
  28. package/svg-icons/far-magnifier.svg +5 -0
  29. package/svg-icons/far-question-circle-thin.svg +9 -0
  30. package/svg-icons/far-question-circle.svg +17 -0
  31. package/svg-icons/far-search.svg +5 -0
  32. package/svg-icons/far-share-nodes.svg +15 -0
  33. package/svg-icons/far-share.svg +15 -0
  34. package/svg-icons/file-csv.svg +18 -0
  35. package/svg-icons/icons.json +82 -0
  36. package/svg-icons/index.d.ts +1 -0
  37. package/svg-icons/svg-icons.module.d.ts +9 -0
  38. package/svg-icons/turn-phone.svg +27 -0
  39. package/svg-icons/xmark.svg +6 -0
@@ -2,10 +2,11 @@ import { Component, Input } from '@angular/core';
2
2
  import { from, of } from 'rxjs';
3
3
  import { distinct, filter, reduce, toArray, map, distinctUntilChanged, switchMap, mergeMap, mergeAll } from 'rxjs/operators';
4
4
  import { CycleFunctionalUnit, EmissionMethodTier, NodeType, TermTermType, emissionTermTermType, indicatorTermTermType, inputTermTermType, measurementTermTermType, practiceTermTermType, productTermTermType } from '@hestia-earth/schema';
5
- import { keyToLabel } from '@hestia-earth/utils';
5
+ import { keyToLabel, unique } from '@hestia-earth/utils';
6
6
  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
+ import { findOrchestratorModel } from '../../engine/engine.service';
9
10
  import { matchExactQuery, matchId, matchTermType, matchType } from '../../search/search.model';
10
11
  import { baseUrl, isExternal, typeaheadFocus } from '../../common/utils';
11
12
  import { termTypeLabel } from '../../terms/terms.model';
@@ -80,12 +81,19 @@ const isSystemBoundary = (termId) => ({ isRecalculated, isRequired }) => {
80
81
  return !inSystemBoundary ? [isRecalculated, isRequired].some(Boolean) : `${inSystemBoundary}` === 'true';
81
82
  };
82
83
  const isGenericTerm = (termId) => [termId.startsWith('excreta')].every(Boolean);
83
- const extraTermIdsFromConfig = (config, key) => config.models
84
- .flat()
85
- .filter(m => m.key === key)
86
- .map(m => m.value)
87
- .filter(Boolean)
88
- .filter(v => !isGenericTerm(v));
84
+ const extraTermIdsFromConfig = (config, key, logs) => unique([
85
+ ...config.models
86
+ .flat()
87
+ .filter(m => m.key === key)
88
+ .map(m => m.value)
89
+ .filter(Boolean)
90
+ .filter(v => !isGenericTerm(v)),
91
+ // match logs with a configuration
92
+ ...Object.entries(logs)
93
+ .filter(([_id, value]) => typeof value === 'object' &&
94
+ Object.entries(value).some(([model, v]) => findOrchestratorModel(config, { key, model, value: v.model_key })))
95
+ .map(([key]) => key)
96
+ ]);
89
97
  const matchTermTypeFromKey = {
90
98
  products: productTermTermType.term,
91
99
  inputs: inputTermTermType.term,
@@ -165,7 +173,7 @@ export class NodeLogsModelsComponent {
165
173
  const engineModels = await this.engineService.models();
166
174
  this.isBlankNodes
167
175
  ? await this.processBlankNodes(logs, engineModels, config)
168
- : await this.processNonBlankNodes(logs, engineModels, config);
176
+ : this.processNonBlankNodes(logs, engineModels, config);
169
177
  this.filterResults();
170
178
  this.loading = false;
171
179
  }
@@ -184,7 +192,7 @@ export class NodeLogsModelsComponent {
184
192
  return results;
185
193
  }
186
194
  async processBlankNodes(logs, engineModels, config) {
187
- const extraTermIds = extraTermIdsFromConfig(config, this.nodeKey);
195
+ const extraTermIds = extraTermIdsFromConfig(config, this.nodeKey, logs);
188
196
  const matchTermTypes = [...(matchTermTypeFromKey[this.nodeKey] || []), ...(this.filterTermTypes || [])];
189
197
  const extraTerms = await this.searchTerms({
190
198
  bool: {
@@ -265,11 +273,11 @@ export class NodeLogsModelsComponent {
265
273
  return this.node?.functionalUnit;
266
274
  }
267
275
  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 }); }
268
- 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", noDataMessage: "noDataMessage" }, 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>{{ noDataMessage || '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\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</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" }] }); }
276
+ 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", noDataMessage: "noDataMessage" }, 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>{{ noDataMessage || '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\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</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 class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is 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 class=\"is-mx-1\">{{ 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 class=\"is-mx-1\">{{ 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" }] }); }
269
277
  }
270
278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
271
279
  type: Component,
272
- 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>{{ noDataMessage || '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\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</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"] }]
280
+ 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>{{ noDataMessage || '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\">\n <ng-template #defaultMessage>\n <ng-container [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{ key | keyToLabel }}</ng-container>\n\n <ng-container *ngSwitchCase=\"'property_id'\">Property Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'product_id'\">Product Term @id</ng-container>\n <ng-container *ngSwitchCase=\"'input_id'\">Input Term @id</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">Node</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">\n <span>Is the current</span>\n <code class=\"is-mx-1\">siteType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_id_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'product_termType_allowed'\">\n <span>Are any of the Product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_id_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input_termType_allowed'\">\n <span>Are any of the Input</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <!-- Deprecated -->\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">@id</code>\n <span>allowed to run this model</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">\n <span>Is the current primary product</span>\n <code class=\"is-mx-1\">termType</code>\n <span>allowed to run this model</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">\n Has geospatial data necessary to run this model\n </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=\"'has_pesticides_inputs'\">\n <span>Cycle contains</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">\n <span>All</span>\n <code class=\"is-mx-1\">pesticideAI</code>\n <span>Inputs have a lookup value</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\">\n <code class=\"is-mr-1\">aboveGroundCropResidueBurnt</code>\n <span>is present as Product</span>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </ng-container>\n </ng-template>\n\n <ng-container *ngIf=\"parseLogCompleteness(key); let completeness; else: defaultMessage\">\n <span>Data completeness for</span>\n <code class=\"is-mx-1\">{{ completeness.key }}</code>\n <span>must be</span>\n <code class=\"is-mx-1\">{{ completeness.value }}</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 class=\"is-mx-1\">site.siteType</code>\n is not relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.product_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Product</code>\n <code class=\"is-mr-1\">term.termType</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_id_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.@id</code>\n is relevant.\n </li>\n <li *ngIf=\"model.logs.logs?.input_termType_allowed === 'False'\">\n None of the\n <code class=\"is-mx-1\">Input</code>\n <code class=\"is-mr-1\">term.termType</code>\n is 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 class=\"is-mx-1\">{{ 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 class=\"is-mx-1\">{{ 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"] }]
273
281
  }], ctorParameters: function () { return [{ type: i1.HeNodeService }, { type: i2.HeSearchService }, { type: i3.HeEngineService }]; }, propDecorators: { node: [{
274
282
  type: Input
275
283
  }], nodeKey: [{
@@ -289,4 +297,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
289
297
  }], noDataMessage: [{
290
298
  type: Input
291
299
  }] } });
292
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1AsR0FBRyxFQUNILG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsUUFBUSxFQUNSLFFBQVEsRUFDVCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsa0JBQWtCLEVBR2xCLFFBQVEsRUFFUixZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLHFCQUFxQixFQUNyQixpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDcEIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBR0wsU0FBUyxFQUdULGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixhQUFhLEVBSWIsZUFBZSxFQUdmLFdBQVcsRUFHWixNQUFNLDBCQUEwQixDQUFDO0FBR2xDLE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUUvRixPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRXhELE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUU3RSxNQUFNLE9BQU8sR0FFVDtJQUNGLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDNUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTztJQUMxQixDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7SUFDNUMsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsUUFBUTtJQUNsQyxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxZQUFZO0NBQ3RDLENBQUM7QUFFRixNQUFNLFFBQVEsR0FFVjtJQUNGLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFNBQVM7SUFDOUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUTtJQUMzQixDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxNQUFNO0lBQ2pDLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxFQUFFLE1BQU07SUFDaEMsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEVBQUUsTUFBTTtDQUNoQyxDQUFDO0FBRUYsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLFlBQTJCLEVBQUUsRUFBRSxDQUMxRDtJQUNFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTTtJQUNsQyxZQUFZLEVBQUUsSUFBSSxFQUFFLE1BQU07SUFDMUIsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNO0lBQy9CLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTTtJQUM5QixZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU07Q0FDbkMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFFbEIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxRQUFnQixFQUFFLE1BQWUsRUFBRSxFQUFFLENBQzFELENBQUMsUUFBUTtJQUNQLENBQUMsQ0FBQztRQUNFLHNCQUFzQixFQUFFLDBCQUEwQjtRQUNsRCxpQkFBaUIsRUFBRSxpQkFBaUI7S0FDckMsQ0FBQyxRQUFRLENBQUM7SUFDYixDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUV0RixNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQTBDLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FDaEYsQ0FBQyxtQkFBbUIsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV6RyxNQUFNLGVBQWUsR0FBRyxDQUFDLFlBQW9DLEVBQUUsRUFBRSxDQUMvRCxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFekUsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUV4SCxNQUFNLDBCQUEwQixHQUU1QjtJQUNGLGNBQWMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDNUQsUUFBUSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUN0RCxvQkFBb0IsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM3RSxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ3BELFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDeEQsV0FBVyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUN4RCxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ3JELFVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDdkQsV0FBVyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUN6RCxDQUFDO0FBRUYsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUFVLEVBQUUsRUFBRSxDQUN4RCxHQUFHLElBQUksMEJBQTBCLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSwwQkFBMEIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUVwSCxNQUFNLGdCQUFnQixHQUNwQixDQUFDLE1BQWUsRUFBRSxFQUFFLENBQ3BCLENBQUMsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUF1RSxFQUFFLEVBQUU7SUFDdEcsNkJBQTZCO0lBQzdCLE1BQU0sZ0JBQWdCLEdBQUcsZUFBZSxDQUFDLG9DQUFvQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZGLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLGdCQUFnQixFQUFFLEtBQUssTUFBTSxDQUFDO0FBQzNHLENBQUMsQ0FBQztBQUVKLE1BQU0sYUFBYSxHQUFHLENBQUMsTUFBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7QUFFeEYsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLE1BQTJCLEVBQUUsR0FBaUIsRUFBRSxFQUFFLENBQ2hGLE1BQU0sQ0FBQyxNQUFNO0tBQ1YsSUFBSSxFQUFFO0tBQ04sTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUM7S0FDMUIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztLQUNqQixNQUFNLENBQUMsT0FBTyxDQUFDO0tBQ2YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVwQyxNQUFNLG9CQUFvQixHQUV0QjtJQUNGLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxJQUFJO0lBQ2xDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO0lBQzlCLFlBQVksRUFBRSx1QkFBdUIsQ0FBQyxJQUFJO0lBQzFDLFNBQVMsRUFBRSxvQkFBb0IsQ0FBQyxJQUFJO0lBQ3BDLFNBQVMsRUFBRSxvQkFBb0IsQ0FBQyxJQUFJO0lBQ3BDLG9CQUFvQixFQUFFLHFCQUFxQixDQUFDLElBQUk7SUFDaEQsT0FBTyxFQUFFLHFCQUFxQixDQUFDLElBQUk7SUFDbkMsU0FBUyxFQUFFLHFCQUFxQixDQUFDLElBQUk7Q0FDdEMsQ0FBQztBQUVGLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7QUFFM0UsTUFBTSwwQkFBMEIsR0FBRyxXQUFXLENBQUM7QUFDL0MsTUFBTSw0QkFBNEIsR0FBRyxhQUFhLENBQUM7QUFDbkQsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQzNDO0lBQ0UsR0FBRyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7SUFDNUIsR0FBRyxDQUFDLFFBQVEsQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsNEJBQTRCLENBQUM7Q0FDdkYsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ2QsQ0FBQyxDQUFDO1FBQ0UsR0FBRyxFQUFFLEdBQUc7YUFDTCxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQzthQUN6QixPQUFPLENBQUMsMEJBQTBCLEVBQUUsRUFBRSxDQUFDO2FBQ3ZDLE9BQU8sQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLENBQUM7UUFDNUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsMEJBQTBCLENBQUM7S0FDaEQ7SUFDSCxDQUFDLENBQUMsSUFBSSxDQUFDO0FBT1gsTUFBTSxPQUFPLHVCQUF1QjtJQThEbEMsWUFDVSxXQUEwQixFQUMxQixhQUE4QixFQUM5QixhQUE4QjtRQUY5QixnQkFBVyxHQUFYLFdBQVcsQ0FBZTtRQUMxQixrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFDOUIsa0JBQWEsR0FBYixhQUFhLENBQWlCO1FBL0RoQyxrQkFBYSxHQUF5QyxFQUFFLENBQUM7UUFJekQsY0FBUyxHQUViLEVBQUUsQ0FBQztRQU9DLG1CQUFjLEdBQStCLEVBQUUsQ0FBQztRQUVoRCx1QkFBa0IsR0FBK0IsRUFBRSxDQUFDO1FBRXBELFVBQUssR0FBa0IsRUFBRSxDQUFDO1FBVzNCLFlBQU8sR0FBRyxPQUFPLEVBQUUsQ0FBQztRQUNwQixlQUFVLEdBQUcsVUFBVSxFQUFFLENBQUM7UUFDMUIsd0JBQW1CLEdBQUcsbUJBQW1CLENBQUM7UUFDMUMsdUJBQWtCLEdBQUcsa0JBQWtCLENBQUM7UUFDeEMsY0FBUyxHQUFHLFNBQVMsQ0FBQztRQUN0QixZQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ2xCLGFBQVEsR0FBRyxRQUFRLENBQUM7UUFDcEIsa0JBQWEsR0FBRyxhQUFhLENBQUM7UUFDOUIsZ0JBQVcsR0FBRyxXQUFXLENBQUM7UUFDMUIsb0JBQWUsR0FBRyxlQUFlLENBQUM7UUFDbEMscUJBQWdCLEdBQUcsZ0JBQWdCLENBQUM7UUFDcEMsa0JBQWEsR0FBRyxhQUFhLENBQUM7UUFDOUIsMEJBQXFCLEdBQUcscUJBQXFCLENBQUM7UUFDOUMscUJBQWdCLEdBQUcsZ0JBQWdCLENBQUM7UUFDcEMseUJBQW9CLEdBQUcsb0JBQW9CLENBQUM7UUFDNUMsWUFBTyxHQUFHLElBQUksQ0FBQztRQUVmLGVBQVUsR0FBeUMsRUFBRSxDQUFDO1FBQ3RELHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUN0QixpQkFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixlQUFVLEdBQUcsSUFBSSxDQUFDO1FBR2xCLGFBQVEsR0FBMkIsRUFBRSxDQUFDO1FBQ3RDLGdCQUFXLEdBQUcsQ0FBQyxLQUF5QixFQUFFLEVBQUUsQ0FDakQsS0FBSyxDQUFDLElBQUksQ0FDUixvQkFBb0IsRUFBRSxFQUN0QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ3RDLENBQUM7UUFFRyxtQkFBYyxHQUFHLGNBQWMsQ0FBQztJQU1wQyxDQUFDO0lBRUosS0FBSyxDQUFDLFFBQVE7UUFDWixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RCxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQyxNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO1FBRXBFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUNyRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFM0csTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ3BDLElBQUksRUFBRTtnQkFDSixJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLGFBQWEsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDcEU7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQzthQUNsQyxJQUFJLENBQ0gsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFDdkIsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDL0Q7YUFDQSxTQUFTLEVBQUUsQ0FBQztRQUVmLCtCQUErQjtRQUMvQixNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFdkQsSUFBSSxDQUFDLFlBQVk7WUFDZixDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUM7WUFDMUQsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFaEUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7SUFFTyxPQUFPO1FBQ2IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDeEQsQ0FBQztJQUVPLGFBQWEsQ0FBQyxJQUFZO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFDaEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNyRCxPQUFPLEVBQUUsQ0FDVixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBVTtRQUNsQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBNkI7WUFDOUUsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUM7WUFDaEMsS0FBSyxFQUFFLEtBQUs7WUFDWixLQUFLO1NBQ04sQ0FBQyxDQUFDO1FBQ0gsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsSUFBK0IsRUFDL0IsWUFBc0IsRUFDdEIsTUFBMkI7UUFFM0IsTUFBTSxZQUFZLEdBQUcsc0JBQXNCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUF1QixDQUFDLENBQUM7UUFDbEYsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDeEcsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ3hDLElBQUksRUFBRTtnQkFDSixJQUFJLEVBQUU7b0JBQ0osU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7b0JBQ3hCLGNBQWMsQ0FBQyxNQUFNO3dCQUNuQixDQUFDLENBQUM7NEJBQ0UsSUFBSSxFQUFFO2dDQUNKLE1BQU0sRUFBRSxjQUFjLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztnQ0FDekMsb0JBQW9CLEVBQUUsQ0FBQzs2QkFDeEI7eUJBQ0Y7d0JBQ0gsQ0FBQyxDQUFDLElBQUk7aUJBQ1QsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO2dCQUNqQixNQUFNLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7Z0JBQ2pDLG9CQUFvQixFQUFFLENBQUM7YUFDeEI7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sWUFBWSxDQUNoQyxJQUFJLENBQUMsY0FBNkIsRUFDbEMsSUFBSSxDQUFDLGtCQUFpQyxFQUN0QyxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxlQUFlLEVBQ3BCLFVBQVUsQ0FDWCxDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUM3QixJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksRUFDSixZQUFZLEVBQ1osTUFBTSxFQUNOLElBQUksQ0FBQyxjQUE2QixFQUNsQyxJQUFJLENBQUMsa0JBQWlDLEVBQ3RDLElBQUksQ0FBQyxPQUF1QixDQUM3QixDQUFDO1FBQ0YsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDakYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sRUFBRSxDQUFDLGFBQWEsQ0FBQzthQUNyQyxJQUFJLENBQ0gsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUM1QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQ2QsUUFBUSxFQUFFLEVBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixPQUFPLEVBQUUsRUFDVCxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FDYixJQUFJLENBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUNmLElBQUksRUFBRTtnQkFDSixJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ2pELG9CQUFvQixFQUFFLENBQUM7YUFDeEI7U0FDRixDQUFDLENBQ0gsQ0FDRixFQUNELFFBQVEsRUFBRSxFQUNWLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQy9EO2FBQ0EsU0FBUyxFQUFFLENBQUM7UUFFZixJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztJQUNyQyxDQUFDO0lBRU8sb0JBQW9CLENBQUMsSUFBK0IsRUFBRSxZQUFzQixFQUFFLE9BQTRCO1FBQ2hILE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FDN0IsSUFBSSxDQUFDLFFBQVEsRUFDYixJQUFJLENBQUMsT0FBMEIsRUFDL0IsSUFBSSxFQUNKLFlBQVksRUFDWixJQUFJLENBQUMsY0FBOEIsRUFDbkMsSUFBSSxDQUFDLGtCQUFrQyxDQUN4QyxDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxjQUE4QixFQUFFLElBQUksQ0FBQyxrQkFBa0MsQ0FBQyxDQUFDO1FBQ3ZHLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN0RixDQUFDO0lBRU0sZ0JBQWdCLENBQUMsTUFBYyxFQUFFLElBQVM7UUFDL0MsT0FBTyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDakMsQ0FBQztJQUVELElBQVcsWUFBWTtRQUNyQixPQUFPLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVPLGVBQWUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEdBQUcsR0FBRyxFQUFpQjtRQUNyRixPQUFPLElBQUksQ0FBQyxJQUFJO1lBQ2QsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0RCxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLE1BQU07Z0JBQzNCLENBQUMsSUFBSSxDQUFDLFlBQVk7Z0JBQ2xCLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDekIsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTSxhQUFhO1FBQ2xCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDcEcsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sVUFBVSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBZ0I7UUFDakQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksSUFBSSxhQUFhLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFTSxhQUFhLENBQUMsTUFBbUIsRUFBRSxVQUE4QjtRQUN0RSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVNLFFBQVEsQ0FBQyxFQUFVO1FBQ3hCLE9BQU8sQ0FDTCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNqQjtnQkFDQyxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUk7Z0JBQ3RCLEtBQUssRUFBRSxFQUFFO2dCQUNULElBQUksRUFBRSxhQUFhLENBQUMsRUFBRSxDQUFDO2FBQ1IsQ0FDbEIsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFXLGNBQWM7UUFDdkIsT0FBUSxJQUFJLENBQUMsSUFBWSxFQUFFLGNBQXFDLENBQUM7SUFDbkUsQ0FBQzs4R0FsUVUsdUJBQXVCO2tHQUF2Qix1QkFBdUIsMlVDbExwQyxxZzJCQXltQkE7OzJGRHZiYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCO2dLQWV2QixJQUFJO3NCQURYLEtBQUs7Z0JBR0UsT0FBTztzQkFEZCxLQUFLO2dCQUdFLGNBQWM7c0JBRHJCLEtBQUs7Z0JBR0Usa0JBQWtCO3NCQUR6QixLQUFLO2dCQUdFLEtBQUs7c0JBRFosS0FBSztnQkFHRSxlQUFlO3NCQUR0QixLQUFLO2dCQUdFLG9CQUFvQjtzQkFEM0IsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUs7Z0JBR0MsYUFBYTtzQkFEbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZnJvbSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGRpc3RpbmN0LFxuICBmaWx0ZXIsXG4gIHJlZHVjZSxcbiAgdG9BcnJheSxcbiAgbWFwLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgc3dpdGNoTWFwLFxuICBtZXJnZU1hcCxcbiAgbWVyZ2VBbGxcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgQ3ljbGVGdW5jdGlvbmFsVW5pdCxcbiAgRW1pc3Npb25NZXRob2RUaWVyLFxuICBJVGVybUpTT05MRCxcbiAgSlNPTkxELFxuICBOb2RlVHlwZSxcbiAgVGVybSxcbiAgVGVybVRlcm1UeXBlLFxuICBlbWlzc2lvblRlcm1UZXJtVHlwZSxcbiAgaW5kaWNhdG9yVGVybVRlcm1UeXBlLFxuICBpbnB1dFRlcm1UZXJtVHlwZSxcbiAgbWVhc3VyZW1lbnRUZXJtVGVybVR5cGUsXG4gIHByYWN0aWNlVGVybVRlcm1UeXBlLFxuICBwcm9kdWN0VGVybVRlcm1UeXBlXG59IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IGtleVRvTGFiZWwgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcbmltcG9ydCB7IHByb3BlcnR5VmFsdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzL2Rpc3QvdGVybSc7XG5pbXBvcnQgeyBsb2FkUmVzb3VyY2VLZXkgfSBmcm9tICdAaGVzdGlhLWVhcnRoL2dsb3NzYXJ5JztcblxuaW1wb3J0IHtcbiAgSUJsYW5rTm9kZUxvZ1N1YlZhbHVlLFxuICBJQmxhbmtOb2RlTG9nLFxuICBMb2dTdGF0dXMsXG4gIElDb25maWdNb2RlbCxcbiAgYmxhbmtOb2RlLFxuICBncm91cExvZ3NCeU1vZGVsLFxuICBncm91cExvZ3NCeVRlcm0sXG4gIG1vZGVsQ291bnQsXG4gIGNvbXB1dGVUZXJtcyxcbiAgbG9nVmFsdWVBcnJheSxcbiAgSU5vZGVUZXJtTG9ncyxcbiAgSU5vZGVMb2dzLFxuICBub25CbGFua05vZGUsXG4gIGdyb3VwZExvZ3NCeUtleSxcbiAgSU5vbkJsYW5rTm9kZUxvZyxcbiAgSUxvZyxcbiAgY29tcHV0ZUtleXMsXG4gIG5vZGVNb2RlbEtleSxcbiAgbm9uTm9kZU1vZGVsS2V5XG59IGZyb20gJy4vbm9kZS1sb2dzLW1vZGVscy5tb2RlbCc7XG5pbXBvcnQgeyBJSlNPTk5vZGUsIEhlTm9kZVNlcnZpY2UgfSBmcm9tICcuLi9ub2RlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGVFbmdpbmVTZXJ2aWNlLCBJTW9kZWwsIElPcmNoZXN0cmF0b3JDb25maWcgfSBmcm9tICcuLi8uLi9lbmdpbmUvZW5naW5lLnNlcnZpY2UnO1xuaW1wb3J0IHsgbWF0Y2hFeGFjdFF1ZXJ5LCBtYXRjaElkLCBtYXRjaFRlcm1UeXBlLCBtYXRjaFR5cGUgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLm1vZGVsJztcbmltcG9ydCB7IEhlU2VhcmNoU2VydmljZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2guc2VydmljZSc7XG5pbXBvcnQgeyBiYXNlVXJsLCBpc0V4dGVybmFsLCB0eXBlYWhlYWRGb2N1cyB9IGZyb20gJy4uLy4uL2NvbW1vbi91dGlscyc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuXG5jb25zdCBub2RlVHlwZXNMb3dlckNhc2UgPSBPYmplY3QudmFsdWVzKE5vZGVUeXBlKS5tYXAodiA9PiB2LnRvTG93ZXJDYXNlKCkpO1xuXG5jb25zdCBsb2dJY29uOiB7XG4gIFtzdGF0dXMgaW4gTG9nU3RhdHVzXT86IHN0cmluZyB8IHN0cmluZ1tdO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ2NoZWNrJyxcbiAgW0xvZ1N0YXR1cy5lcnJvcl06ICd0aW1lcycsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06IFsnZmFyJywgJ2NpcmNsZSddLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdjaXJjbGUnLFxuICBbTG9nU3RhdHVzLm5vdFJlcXVpcmVkXTogJ2RvdC1jaXJjbGUnXG59O1xuXG5jb25zdCBsb2dDb2xvcjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmc7XG59ID0ge1xuICBbTG9nU3RhdHVzLnN1Y2Nlc3NdOiAnc3VjY2VzcycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAnZGFuZ2VyJyxcbiAgW0xvZ1N0YXR1cy5za2lwSGllcmFyY2h5XTogJ2RhcmsnLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdncmV5J1xufTtcblxuY29uc3Qgc2hvdWxkU2hvd0JsYW5rTm9kZSA9IChibGFua05vZGVMb2c6IElCbGFua05vZGVMb2cpID0+XG4gIFtcbiAgICBibGFua05vZGVMb2c/LmNvbmZpZ01vZGVscz8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8ua2V5cz8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8uc3ViVmFsdWVzPy5sZW5ndGgsXG4gICAgYmxhbmtOb2RlTG9nPy5vcmlnaW5hbD8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8ucmVjYWxjdWxhdGVkPy5sZW5ndGhcbiAgXS5zb21lKEJvb2xlYW4pO1xuXG5jb25zdCBtZXRob2RJZExhYmVsID0gKG1ldGhvZElkOiBzdHJpbmcsIF9tb2RlbD86IElNb2RlbCkgPT5cbiAgKG1ldGhvZElkXG4gICAgPyB7XG4gICAgICAgICdjeWNsZS90cmFuc2Zvcm1hdGlvbic6ICdEYXRhIEZyb20gVHJhbnNmb3JtYXRpb24nLFxuICAgICAgICBpbXBhY3RfYXNzZXNzbWVudDogJ0RhdGEgRnJvbSBDeWNsZSdcbiAgICAgIH1bbWV0aG9kSWRdXG4gICAgOiAnJykgfHwgKG1ldGhvZElkLmluY2x1ZGVzKCcvJykgPyBtZXRob2RJZC5zcGxpdCgnLycpWzBdIDoga2V5VG9MYWJlbChtZXRob2RJZCkpO1xuXG5jb25zdCBnZXRNb2RlbHNBdCA9IChsb2c6IElCbGFua05vZGVMb2dTdWJWYWx1ZSB8IElCbGFua05vZGVMb2csIGluZGV4OiBudW1iZXIpID0+XG4gICgnbW9kZWxzSW5TdWJWYWx1ZXMnIGluIGxvZyA/ICFsb2cubW9kZWxzSW5TdWJWYWx1ZXMgfHwgIWxvZy5pc09wZW4gOiB0cnVlKSAmJiBsb2cuY29uZmlnTW9kZWxzW2luZGV4XTtcblxuY29uc3QgcmVxdWlyZW1lbnRLZXlzID0gKHJlcXVpcmVtZW50czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkgPT5cbiAgT2JqZWN0LmtleXMocmVxdWlyZW1lbnRzKS5maWx0ZXIoayA9PiAhbm9kZVR5cGVzTG93ZXJDYXNlLmluY2x1ZGVzKGspKTtcblxuY29uc3QgcmVxdWlyZW1lbnRDb2xvciA9ICh2YWx1ZTogYW55KSA9PiAoIXZhbHVlIHx8IFsnTm9uZScsICdGYWxzZScsICcwJywgJzAuMCddLmluY2x1ZGVzKHZhbHVlKSA/ICdkYW5nZXInIDogJ3doaXRlJyk7XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5OiB7XG4gIFtrZXk6IHN0cmluZ106ICh2YWx1ZTogc3RyaW5nKSA9PiBQYXJ0aWFsPEpTT05MRDxOb2RlVHlwZT4+O1xufSA9IHtcbiAgcmVsYXRlZF9jeWNsZXM6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBjeWNsZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGltcGFjdF9hc3Nlc3NtZW50X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkltcGFjdEFzc2Vzc21lbnQsICdAaWQnOiB2IH0pLFxuICBzaXRlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNpdGUsICdAaWQnOiB2IH0pLFxuICBzb3VyY2VfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU291cmNlLCAnQGlkJzogdiB9KSxcbiAgcHJvcGVydHlfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSwgJ0BpZCc6IHYgfSksXG4gIGlucHV0X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pLFxuICBwcm9kdWN0X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pLFxuICBwcmFjdGljZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLCAnQGlkJzogdiB9KVxufTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlID0gKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PlxuICBrZXkgaW4gcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXkgJiYgWydOb25lJywgJycsIG51bGxdLmluY2x1ZGVzKHZhbHVlKSAmJiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleVtrZXldKHZhbHVlKTtcblxuY29uc3QgaXNTeXN0ZW1Cb3VuZGFyeSA9XG4gICh0ZXJtSWQ/OiBzdHJpbmcpID0+XG4gICh7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz4pID0+IHtcbiAgICAvLyBvbmx5IGV4aXN0cyBmb3Igc29tZSB0ZXJtc1xuICAgIGNvbnN0IGluU3lzdGVtQm91bmRhcnkgPSBsb2FkUmVzb3VyY2VLZXkoJ2luSGVzdGlhRGVmYXVsdFN5c3RlbUJvdW5kYXJ5Lmpzb24nLCB0ZXJtSWQpO1xuICAgIHJldHVybiAhaW5TeXN0ZW1Cb3VuZGFyeSA/IFtpc1JlY2FsY3VsYXRlZCwgaXNSZXF1aXJlZF0uc29tZShCb29sZWFuKSA6IGAke2luU3lzdGVtQm91bmRhcnl9YCA9PT0gJ3RydWUnO1xuICB9O1xuXG5jb25zdCBpc0dlbmVyaWNUZXJtID0gKHRlcm1JZDogc3RyaW5nKSA9PiBbdGVybUlkLnN0YXJ0c1dpdGgoJ2V4Y3JldGEnKV0uZXZlcnkoQm9vbGVhbik7XG5cbmNvbnN0IGV4dHJhVGVybUlkc0Zyb21Db25maWcgPSAoY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnLCBrZXk6IG5vZGVNb2RlbEtleSkgPT5cbiAgY29uZmlnLm1vZGVsc1xuICAgIC5mbGF0KClcbiAgICAuZmlsdGVyKG0gPT4gbS5rZXkgPT09IGtleSlcbiAgICAubWFwKG0gPT4gbS52YWx1ZSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmZpbHRlcih2ID0+ICFpc0dlbmVyaWNUZXJtKHYpKTtcblxuY29uc3QgbWF0Y2hUZXJtVHlwZUZyb21LZXk6IHtcbiAgW2tleTogc3RyaW5nXTogVGVybVRlcm1UeXBlW107XG59ID0ge1xuICBwcm9kdWN0czogcHJvZHVjdFRlcm1UZXJtVHlwZS50ZXJtLFxuICBpbnB1dHM6IGlucHV0VGVybVRlcm1UeXBlLnRlcm0sXG4gIG1lYXN1cmVtZW50czogbWVhc3VyZW1lbnRUZXJtVGVybVR5cGUudGVybSxcbiAgcHJhY3RpY2VzOiBwcmFjdGljZVRlcm1UZXJtVHlwZS50ZXJtLFxuICBlbWlzc2lvbnM6IGVtaXNzaW9uVGVybVRlcm1UeXBlLnRlcm0sXG4gIGVtaXNzaW9uc1Jlc291cmNlVXNlOiBpbmRpY2F0b3JUZXJtVGVybVR5cGUudGVybSxcbiAgaW1wYWN0czogaW5kaWNhdG9yVGVybVRlcm1UeXBlLnRlcm0sXG4gIGVuZHBvaW50czogaW5kaWNhdG9yVGVybVRlcm1UeXBlLnRlcm1cbn07XG5cbmNvbnN0IHRlcm1TZWFyY2ggPSAodGVybSA9ICcnKSA9PiB0ZXJtLnJlcGxhY2UoL1ssXFxzXS9nLCAnJykudG9Mb3dlckNhc2UoKTtcblxuY29uc3QgY29tcGxldGVuZXNzQ29tcGxldGVTdWZmaXggPSAnX2NvbXBsZXRlJztcbmNvbnN0IGNvbXBsZXRlbmVzc0luY29tcGxldGVTdWZmaXggPSAnX2luY29tcGxldGUnO1xuY29uc3QgcGFyc2VMb2dDb21wbGV0ZW5lc3MgPSAoa2V5OiBzdHJpbmcpID0+XG4gIFtcbiAgICBrZXkuc3RhcnRzV2l0aCgndGVybV90eXBlXycpLFxuICAgIGtleS5lbmRzV2l0aChjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeCkgfHwga2V5LmVuZHNXaXRoKGNvbXBsZXRlbmVzc0luY29tcGxldGVTdWZmaXgpXG4gIF0uZXZlcnkoQm9vbGVhbilcbiAgICA/IHtcbiAgICAgICAga2V5OiBrZXlcbiAgICAgICAgICAucmVwbGFjZSgndGVybV90eXBlXycsICcnKVxuICAgICAgICAgIC5yZXBsYWNlKGNvbXBsZXRlbmVzc0NvbXBsZXRlU3VmZml4LCAnJylcbiAgICAgICAgICAucmVwbGFjZShjb21wbGV0ZW5lc3NJbmNvbXBsZXRlU3VmZml4LCAnJyksXG4gICAgICAgIHZhbHVlOiBrZXkuZW5kc1dpdGgoY29tcGxldGVuZXNzQ29tcGxldGVTdWZmaXgpXG4gICAgICB9XG4gICAgOiBudWxsO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoZS1ub2RlLWxvZ3MtbW9kZWxzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTm9kZUxvZ3NNb2RlbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGxvZ3M6IHN0cmluZztcbiAgcHJpdmF0ZSBhbGxCbGFua05vZGVzOiAoSUJsYW5rTm9kZUxvZyB8IElOb25CbGFua05vZGVMb2cpW10gPSBbXTtcbiAgcHJpdmF0ZSBtZXRob2RzQnlJZD86IHtcbiAgICBbaWQ6IHN0cmluZ106IElUZXJtSlNPTkxEO1xuICB9O1xuICBwcml2YXRlIHRlcm1zQnlJZDoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH0gPSB7fTtcblxuICBASW5wdXQoKVxuICBwcml2YXRlIG5vZGU/OiBJSlNPTk5vZGU7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZUtleTogbm9kZU1vZGVsS2V5IHwgbm9uTm9kZU1vZGVsS2V5O1xuICBASW5wdXQoKVxuICBwcml2YXRlIG9yaWdpbmFsVmFsdWVzOiBibGFua05vZGVbXSB8IG5vbkJsYW5rTm9kZSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHJlY2FsY3VsYXRlZFZhbHVlczogYmxhbmtOb2RlW10gfCBub25CbGFua05vZGUgPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSB0ZXJtczogSVRlcm1KU09OTERbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGZpbHRlclRlcm1UeXBlcz86IFRlcm1UZXJtVHlwZVtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGZpbHRlclRlcm1UeXBlc0xhYmVsPzogc3RyaW5nO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGxvZ3NLZXk/OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBub0RhdGFNZXNzYWdlPzogc3RyaW5nO1xuXG4gIHB1YmxpYyBsb2dzVXJsPzogc3RyaW5nO1xuICBwdWJsaWMgYmFzZVVybCA9IGJhc2VVcmwoKTtcbiAgcHVibGljIGlzRXh0ZXJuYWwgPSBpc0V4dGVybmFsKCk7XG4gIHB1YmxpYyBDeWNsZUZ1bmN0aW9uYWxVbml0ID0gQ3ljbGVGdW5jdGlvbmFsVW5pdDtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBpc1N5c3RlbUJvdW5kYXJ5ID0gaXNTeXN0ZW1Cb3VuZGFyeTtcbiAgcHVibGljIHBhcnNlTG9nQ29tcGxldGVuZXNzID0gcGFyc2VMb2dDb21wbGV0ZW5lc3M7XG4gIHB1YmxpYyBsb2FkaW5nID0gdHJ1ZTtcbiAgcHVibGljIG5vZGVUeXBlOiBOb2RlVHlwZTtcbiAgcHVibGljIGJsYW5rTm9kZXM6IChJQmxhbmtOb2RlTG9nIHwgSU5vbkJsYW5rTm9kZUxvZylbXSA9IFtdO1xuICBwdWJsaWMgbWV0aG9kTW9kZWxzQ291bnQgPSAwO1xuICBwdWJsaWMgb25seVJlcXVpcmVkID0gdHJ1ZTtcbiAgcHVibGljIHNob3dMZWdlbmQgPSB0cnVlO1xuXG4gIHB1YmxpYyB0ZXJtPzogc3RyaW5nO1xuICBwdWJsaWMgYWxsVGVybXM6IChUZXJtIHwgSVRlcm1KU09OTEQpW10gPSBbXTtcbiAgcHVibGljIHN1Z2dlc3RUZXJtID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pID0+XG4gICAgdGV4dCQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzd2l0Y2hNYXAodiA9PiB0aGlzLnN1Z2dlc3RCeVRlcm0odikpXG4gICAgKTtcblxuICBwdWJsaWMgdHlwZWFoZWFkRm9jdXMgPSB0eXBlYWhlYWRGb2N1cztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBIZU5vZGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2VhcmNoU2VydmljZTogSGVTZWFyY2hTZXJ2aWNlLFxuICAgIHByaXZhdGUgZW5naW5lU2VydmljZTogSGVFbmdpbmVTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmxvZ3NVcmwgPSB0aGlzLm5vZGVTZXJ2aWNlLm5vZGVMb2dzVXJsKHRoaXMubm9kZSk7XG4gICAgLy8gc2F2ZSBhcyBsb2NhbCB2YXJpYWJsZSB0byBhdm9pZCBcInJlc2VydmVkIHlpZWxkIGtleXdvcmRcIiBpc3N1ZVxuICAgIHRoaXMubG9ncyA9IGF3YWl0IHRoaXMuZ2V0TG9ncygpO1xuICAgIGNvbnN0IGdyb3VwZWRMb2dzID0gZ3JvdXBMb2dzQnlNb2RlbCh0aGlzLmxvZ3MpO1xuICAgIGNvbnN0IGxvZ3MgPSB0aGlzLmxvZ3NLZXkgPyBncm91cGVkTG9nc1t0aGlzLmxvZ3NLZXldIDogZ3JvdXBlZExvZ3M7XG5cbiAgICB0aGlzLm5vZGVUeXBlID0gdGhpcy5ub2RlWydAdHlwZSddIHx8IHRoaXMubm9kZS50eXBlO1xuICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IHRoaXMuZW5naW5lU2VydmljZS5vY2hlc3RyYXRvckNvbmZpZyh0aGlzLm5vZGVUeXBlLCB0aGlzLm5vZGVbJ0BpZCddIHx8IHRoaXMubm9kZS5pZCk7XG5cbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgIGJvb2w6IHtcbiAgICAgICAgbXVzdDogW21hdGNoVHlwZShOb2RlVHlwZS5UZXJtKSwgbWF0Y2hUZXJtVHlwZShUZXJtVGVybVR5cGUubW9kZWwpXVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5tZXRob2RzQnlJZCA9IGF3YWl0IGZyb20obW9kZWxzKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICAgIGRpc3RpbmN0KHYgPT4gdlsnQGlkJ10pLFxuICAgICAgICByZWR1Y2UoKHByZXYsIGN1cnIpID0+ICh7IC4uLnByZXYsIFtjdXJyWydAaWQnXV06IGN1cnIgfSksIHt9KVxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgLy8gZnJvbSBgbW9kZWwtbGlua3MuanNvbmAgZmlsZVxuICAgIGNvbnN0IGVuZ2luZU1vZGVscyA9IGF3YWl0IHRoaXMuZW5naW5lU2VydmljZS5tb2RlbHMoKTtcblxuICAgIHRoaXMuaXNCbGFua05vZGVzXG4gICAgICA/IGF3YWl0IHRoaXMucHJvY2Vzc0JsYW5rTm9kZXMobG9ncywgZW5naW5lTW9kZWxzLCBjb25maWcpXG4gICAgICA6IGF3YWl0IHRoaXMucHJvY2Vzc05vbkJsYW5rTm9kZXMobG9ncywgZW5naW5lTW9kZWxzLCBjb25maWcpO1xuXG4gICAgdGhpcy5maWx0ZXJSZXN1bHRzKCk7XG5cbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TG9ncygpIHtcbiAgICByZXR1cm4gdGhpcy5ub2RlU2VydmljZS5nZXRMb2codGhpcy5ub2RlKS50b1Byb21pc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgc3VnZ2VzdEJ5VGVybSh0ZXJtOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZnJvbSh0aGlzLmFsbFRlcm1zKS5waXBlKFxuICAgICAgbWFwKHYgPT4gdi5uYW1lKSxcbiAgICAgIGZpbHRlcih2ID0+IHRlcm1TZWFyY2godikuaW5jbHVkZXModGVybVNlYXJjaCh0ZXJtKSkpLFxuICAgICAgdG9BcnJheSgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VhcmNoVGVybXMocXVlcnk6IGFueSkge1xuICAgIGNvbnN0IHsgcmVzdWx0cyB9ID0gYXdhaXQgdGhpcy5zZWFyY2hTZXJ2aWNlLnNlYXJjaDxJVGVybUpTT05MRCwgTm9kZVR5cGUuVGVybT4oe1xuICAgICAgZmllbGRzOiBbJ0B0eXBlJywgJ0BpZCcsICduYW1lJ10sXG4gICAgICBsaW1pdDogMTAwMDAsXG4gICAgICBxdWVyeVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzQmxhbmtOb2RlcyhcbiAgICBsb2dzOiBJTm9kZUxvZ3MgfCBJTm9kZVRlcm1Mb2dzLFxuICAgIGVuZ2luZU1vZGVsczogSU1vZGVsW10sXG4gICAgY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnXG4gICkge1xuICAgIGNvbnN0IGV4dHJhVGVybUlkcyA9IGV4dHJhVGVybUlkc0Zyb21Db25maWcoY29uZmlnLCB0aGlzLm5vZGVLZXkgYXMgbm9kZU1vZGVsS2V5KTtcbiAgICBjb25zdCBtYXRjaFRlcm1UeXBlcyA9IFsuLi4obWF0Y2hUZXJtVHlwZUZyb21LZXlbdGhpcy5ub2RlS2V5XSB8fCBbXSksIC4uLih0aGlzLmZpbHRlclRlcm1UeXBlcyB8fCBbXSldO1xuICAgIGNvbnN0IGV4dHJhVGVybXMgPSBhd2FpdCB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgIGJvb2w6IHtcbiAgICAgICAgbXVzdDogW1xuICAgICAgICAgIG1hdGNoVHlwZShOb2RlVHlwZS5UZXJtKSxcbiAgICAgICAgICBtYXRjaFRlcm1UeXBlcy5sZW5ndGhcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGJvb2w6IHtcbiAgICAgICAgICAgICAgICAgIHNob3VsZDogbWF0Y2hUZXJtVHlwZXMubWFwKG1hdGNoVGVybVR5cGUpLFxuICAgICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogbnVsbFxuICAgICAgICBdLmZpbHRlcihCb29sZWFuKSxcbiAgICAgICAgc2hvdWxkOiBleHRyYVRlcm1JZHMubWFwKG1hdGNoSWQpLFxuICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5hbGxUZXJtcyA9IGF3YWl0IGNvbXB1dGVUZXJtcyhcbiAgICAgIHRoaXMub3JpZ2luYWxWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyBhcyBibGFua05vZGVbXSxcbiAgICAgIHRoaXMudGVybXMsXG4gICAgICB0aGlzLmZpbHRlclRlcm1UeXBlcyxcbiAgICAgIGV4dHJhVGVybXNcbiAgICApO1xuICAgIGNvbnN0IG1hcEZ1bmMgPSBncm91cExvZ3NCeVRlcm0oXG4gICAgICB0aGlzLm5vZGVUeXBlLFxuICAgICAgbG9ncyxcbiAgICAgIGVuZ2luZU1vZGVscyxcbiAgICAgIGNvbmZpZyxcbiAgICAgIHRoaXMub3JpZ2luYWxWYWx1ZXMgYXMgYmxhbmtOb2RlW10sXG4gICAgICB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyBhcyBibGFua05vZGVbXSxcbiAgICAgIHRoaXMubm9kZUtleSBhcyBub2RlTW9kZWxLZXlcbiAgICApO1xuICAgIGNvbnN0IGFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAobWFwRnVuYykuZmlsdGVyKHNob3VsZFNob3dCbGFua05vZGUpO1xuICAgIHRoaXMubWV0aG9kTW9kZWxzQ291bnQgPSBtb2RlbENvdW50KGFsbEJsYW5rTm9kZXMpO1xuXG4gICAgdGhpcy50ZXJtc0J5SWQgPSBhd2FpdCBvZihhbGxCbGFua05vZGVzKVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1lcmdlTWFwKHYgPT4gdi5mbGF0TWFwKHZ2ID0+IHZ2LnN1YlZhbHVlcykpLFxuICAgICAgICBtYXAodiA9PiB2LmlkKSxcbiAgICAgICAgZGlzdGluY3QoKSxcbiAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcbiAgICAgICAgdG9BcnJheSgpLFxuICAgICAgICBtZXJnZU1hcChpZHMgPT5cbiAgICAgICAgICBmcm9tKFxuICAgICAgICAgICAgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICAgICAgICAgIGJvb2w6IHtcbiAgICAgICAgICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pXSxcbiAgICAgICAgICAgICAgICBzaG91bGQ6IGlkcy5tYXAoaWQgPT4gbWF0Y2hFeGFjdFF1ZXJ5KCdAaWQnLCBpZCkpLFxuICAgICAgICAgICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICBtZXJnZUFsbCgpLFxuICAgICAgICByZWR1Y2UoKHByZXYsIGN1cnIpID0+ICh7IC4uLnByZXYsIFtjdXJyWydAaWQnXV06IGN1cnIgfSksIHt9KVxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpO1xuXG4gICAgdGhpcy5hbGxCbGFua05vZGVzID0gYWxsQmxhbmtOb2RlcztcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc05vbkJsYW5rTm9kZXMobG9nczogSU5vZGVMb2dzIHwgSU5vZGVUZXJtTG9ncywgZW5naW5lTW9kZWxzOiBJTW9kZWxbXSwgX2NvbmZpZzogSU9yY2hlc3RyYXRvckNvbmZpZykge1xuICAgIGNvbnN0IG1hcEZ1bmMgPSBncm91cGRMb2dzQnlLZXkoXG4gICAgICB0aGlzLm5vZGVUeXBlLFxuICAgICAgdGhpcy5ub2RlS2V5IGFzIG5vbk5vZGVNb2RlbEtleSxcbiAgICAgIGxvZ3MsXG4gICAgICBlbmdpbmVNb2RlbHMsXG4gICAgICB0aGlzLm9yaWdpbmFsVmFsdWVzIGFzIG5vbkJsYW5rTm9kZSxcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzIGFzIG5vbkJsYW5rTm9kZVxuICAgICk7XG4gICAgY29uc3Qga2V5cyA9IGNvbXB1dGVLZXlzKHRoaXMub3JpZ2luYWxWYWx1ZXMgYXMgbm9uQmxhbmtOb2RlLCB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyBhcyBub25CbGFua05vZGUpO1xuICAgIGNvbnN0IGFsbEJsYW5rTm9kZXMgPSBrZXlzLmZsYXRNYXAobWFwRnVuYyk7XG4gICAgdGhpcy5hbGxCbGFua05vZGVzID0gYWxsQmxhbmtOb2RlcztcbiAgICB0aGlzLm1ldGhvZE1vZGVsc0NvdW50ID0gMTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaXNCbGFua05vZGVzKCkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHRoaXMub3JpZ2luYWxWYWx1ZXMpIHx8IEFycmF5LmlzQXJyYXkodGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMpO1xuICB9XG5cbiAgcHVibGljIHRyYWNrQnlCbGFua05vZGUoX2luZGV4OiBudW1iZXIsIG5vZGU6IGFueSkge1xuICAgIHJldHVybiBub2RlLnRlcm1JZCB8fCBub2RlLmtleTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZmlsdGVyZWRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRlcm1UeXBlc0xhYmVsIHx8IHRoaXMuZmlsdGVyVGVybVR5cGVzPy5tYXAodGVybVR5cGVMYWJlbCkuam9pbignICYgJyk7XG4gIH1cblxuICBwcml2YXRlIGZpbHRlckJsYW5rTm9kZSh7IHRlcm06IHsgbmFtZSwgJ0BpZCc6IGlkIH0sIHN1YlZhbHVlcywgLi4ubG9nIH06IElCbGFua05vZGVMb2cpIHtcbiAgICByZXR1cm4gdGhpcy50ZXJtXG4gICAgICA/IG5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLnRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICAgIDogIXRoaXMuZmlsdGVyVGVybVR5cGVzPy5sZW5ndGggfHxcbiAgICAgICAgICAhdGhpcy5vbmx5UmVxdWlyZWQgfHxcbiAgICAgICAgICBpc1N5c3RlbUJvdW5kYXJ5KGlkKShsb2cpIHx8XG4gICAgICAgICAgc3ViVmFsdWVzLnNvbWUoaXNTeXN0ZW1Cb3VuZGFyeShpZCkpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlclJlc3VsdHMoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmJsYW5rTm9kZXMgPSB0aGlzLmFsbEJsYW5rTm9kZXMuZmlsdGVyKGxvZyA9PiAhKCd0ZXJtJyBpbiBsb2cpIHx8IHRoaXMuZmlsdGVyQmxhbmtOb2RlKGxvZykpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG1ldGhvZE5hbWUoeyBtZXRob2RJZCwgbW9kZWwgfTogSUNvbmZpZ01vZGVsKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0aG9kc0J5SWRbbWV0aG9kSWRdPy5uYW1lIHx8IG1ldGhvZElkTGFiZWwobWV0aG9kSWQsIG1vZGVsKTtcbiAgfVxuXG4gIHB1YmxpYyBoYXNNZXRob2RUaWVyKHZhbHVlczogYmxhbmtOb2RlW10sIG1ldGhvZFRpZXI6IEVtaXNzaW9uTWV0aG9kVGllcikge1xuICAgIHJldHVybiB2YWx1ZXMuc29tZSh2ID0+ICdtZXRob2RUaWVyJyBpbiB2ICYmIHYubWV0aG9kVGllciA9PT0gbWV0aG9kVGllcik7XG4gIH1cblxuICBwdWJsaWMgdGVybUJ5SWQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnRlcm1zQnlJZFtpZF0gfHxcbiAgICAgICh7XG4gICAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAgICdAaWQnOiBpZCxcbiAgICAgICAgbmFtZTogdGVybVR5cGVMYWJlbChpZClcbiAgICAgIH0gYXMgSVRlcm1KU09OTEQpXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZnVuY3Rpb25hbFVuaXQoKSB7XG4gICAgcmV0dXJuICh0aGlzLm5vZGUgYXMgYW55KT8uZnVuY3Rpb25hbFVuaXQgYXMgQ3ljbGVGdW5jdGlvbmFsVW5pdDtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInB4LTMgcGItM1wiPlxuICA8ZGl2IGNsYXNzPVwiaGFzLXRleHQtcmlnaHQgbWItMlwiICpuZ0lmPVwiIWlzRXh0ZXJuYWxcIj5cbiAgICA8YSBjbGFzcz1cImlzLXNpemUtN1wiICpuZ0lmPVwibG9nc1VybFwiIFtocmVmXT1cImxvZ3NVcmxcIiB0YXJnZXQ9XCJfYmxhbmtcIj5cbiAgICAgIDxmYS1pY29uIGljb249XCJleHRlcm5hbC1saW5rLWFsdFwiPjwvZmEtaWNvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwicGwtMlwiPk9wZW4gRnVsbCBMb2dzPC9zcGFuPlxuICAgIDwvYT5cbiAgPC9kaXY+XG5cbiAgPGhlLWRhdGEtdGFibGUgY2xhc3M9XCJtYi0xIGlzLXNtYWxsXCIgW3NtYWxsXT1cInRydWVcIiBtYXhIZWlnaHQ9XCIzMjBcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1mdWxsd2lkdGggaXMtbmFycm93IGlzLXN0cmlwZWRcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkXCIgKm5nSWY9XCJhbGxUZXJtcz8ubGVuZ3RoXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250cm9sIGlzLWV4cGFuZGVkIGhhcy1pY29ucy1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnB1dCBzZWFyY2gtaW5wdXQgaXMtc21hbGxcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ0ZXJtXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0ZXJtXCJcbiAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IGVudHJ5IGJ5IG5hbWVcIlxuICAgICAgICAgICAgICAgICAgW25nYlR5cGVhaGVhZF09XCJzdWdnZXN0VGVybVwiXG4gICAgICAgICAgICAgICAgICBbZm9jdXNGaXJzdF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJ0eXBlYWhlYWRGb2N1cygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChzZWxlY3RJdGVtKT1cImZpbHRlclJlc3VsdHMoKVwiIC8+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJpY29uIGlzLXNtYWxsIGlzLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhdGVybVwiIChjbGljayk9XCJ0ZXJtID0gJyc7IGZpbHRlclJlc3VsdHMoKVwiPlxuICAgICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInRpbWVzXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wci0xXCI+VW5pdHM8L3NwYW4+XG4gICAgICAgICAgICA8c3Bhbj4ocGVyJm5ic3A7PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gW25nU3dpdGNoXT1cImZ1bmN0aW9uYWxVbml0XCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIkN5Y2xlRnVuY3Rpb25hbFVuaXRbJzEgaGEnXVwiPmhlY3RhcmU8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0PmtnIHByb2R1Y3Q8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPik8L3NwYW4+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8dGg+T3JpZ2luYWw8L3RoPlxuICAgICAgICAgIDx0aD5SZWNhbGN1bGF0ZWQ8L3RoPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPkRpZmZlcmVuY2U8L3RoPlxuICAgICAgICAgIDx0aCAqbmdGb3I9XCJsZXQgYyBvZiBtZXRob2RNb2RlbHNDb3VudCB8IHRpbWVzOyBsZXQgaSA9IGluZGV4XCI+KHt7IGkgKyAxIH19KTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZyAmJiBibGFua05vZGVzLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxzcGFuPnt7IG5vRGF0YU1lc3NhZ2UgfHwgJ05vIGRhdGEnIH19PC9zcGFuPlxuICAgICAgICAgIDwvdGQ+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+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0TWVzc2FnZT5cbiAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJrZXlcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD57eyBrZXkgfCBrZXlUb0xhYmVsIH19PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9wZXJ0eV9pZCdcIj5Qcm9wZXJ0eSBUZXJtIEBpZDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Byb2R1Y3RfaWQnXCI+UHJvZHVjdCBUZXJtIEBpZDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0X2lkJ1wiPklucHV0IFRlcm0gQGlkPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidub2RlX3R5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+SXMgdGhlIGN1cnJlbnQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPk5vZGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzaXRlVHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5JcyB0aGUgY3VycmVudDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+c2l0ZVR5cGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcm9kdWN0X2lkX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIFByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPkBpZDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Byb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QXJlIGFueSBvZiB0aGUgUHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+dGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidpbnB1dF9pZF9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BcmUgYW55IG9mIHRoZSBJbnB1dDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+QGlkPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXRfdGVybVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QXJlIGFueSBvZiB0aGUgSW5wdXQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS0gRGVwcmVjYXRlZCAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfaWRfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+SXMgdGhlIGN1cnJlbnQgcHJpbWFyeSBwcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5AaWQ8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+SXMgdGhlIGN1cnJlbnQgcHJpbWFyeSBwcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInZ2Vvc3BhdGlhbF9kYXRhJ1wiPlxuICAgICAgICAgICAgICBIYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbFxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY29udGFpbnNfZ2Vvc3BhdGlhbF9kYXRhJ1wiPlxuICAgICAgICAgICAgICBIYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbFxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY3VycmVudF9zaXplJ1wiPkN1cnJlbnQgcG9seWdvbiBhcmVhPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbWF4X2FyZWFfc2l6ZSdcIj5NYXhpbXVtIHBvbHlnb24gYXJlYSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2JlbG93X21heF9hcmVhX3NpemUnXCI+UG9seWdvbiBiZWxvdyB0aGUgbWF4aW11bSBhcmVhPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncmVnaW9uX2ZhY3RvcidcIj5GYWN0b3IgZnJvbSByZWdpb24gbG9va3VwPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfcGVzdGljaWRlc19pbnB1dHMnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkN5Y2xlIGNvbnRhaW5zPC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5wZXN0aWNpZGVBSTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+SW5wdXRzPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYWxsX3Blc3RpY2lkZUFJX2hhdmVfbG9va3VwX3ZhbHVlJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BbGw8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnBlc3RpY2lkZUFJPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5JbnB1dHMgaGF2ZSBhIGxvb2t1cCB2YWx1ZTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX2Nyb3BfcmVzaWR1ZV9idXJudCdcIj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1tci0xXCI+YWJvdmVHcm91bmRDcm9wUmVzaWR1ZUJ1cm50PC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5pcyBwcmVzZW50IGFzIFByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2xpcXVpZF9zbHVycnlfc2x1ZGdlX1AnXCI+TGlxdWlkLCBTbHVycnksIGFuZCBTbHVkZ2UgUDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwYXJzZUxvZ0NvbXBsZXRlbmVzcyhrZXkpOyBsZXQgY29tcGxldGVuZXNzOyBlbHNlOiBkZWZhdWx0TWVzc2FnZVwiPlxuICAgICAgICAgIDxzcGFuPkRhdGEgY29tcGxldGVuZXNzIGZvcjwvc3Bhbj5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj57eyBjb21wbGV0ZW5lc3Mua2V5IH19PC9jb2RlPlxuICAgICAgICAgIDxzcGFuPm11c3QgYmU8L3NwYW4+XG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+e3sgY29tcGxldGVuZXNzLnZhbHVlIH19PC9jb2RlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxoZS1jbGlwYm9hcmRcbiAgICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCJcbiAgICAgICAgY2xpcGJvYXJkQ2xhc3M9XCJpcy1zaXplLTcgaXMtcC0xXCJcbiAgICAgICAgW2ljb25dPVwiWydmYXInLCAnY2xvbmUnXVwiXG4gICAgICAgIFt2YWx1ZV09XCJrZXlcIlxuICAgICAgICBbaGlkZVRleHRdPVwidHJ1ZVwiPjwvaGUtY2xpcGJvYXJkPlxuICAgIDwvdGQ+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
300
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1AsR0FBRyxFQUNILG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsUUFBUSxFQUNSLFFBQVEsRUFDVCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsa0JBQWtCLEVBR2xCLFFBQVEsRUFFUixZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLHFCQUFxQixFQUNyQixpQkFBaUIsRUFDakIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDcEIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFekQsT0FBTyxFQUdMLFNBQVMsRUFHVCxnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osYUFBYSxFQUliLGVBQWUsRUFHZixXQUFXLEVBR1osTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQWdE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QUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsS0FBSyxVQUFVLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRU0sUUFBUSxDQUFDLEVBQVU7UUFDeEIsT0FBTyxDQUNMLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ2pCO2dCQUNDLE9BQU8sRUFBRSxRQUFRLENBQUMsSUFBSTtnQkFDdEIsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7YUFDUixDQUNsQixDQUFDO0lBQ0osQ0FBQztJQUVELElBQVcsY0FBYztRQUN2QixPQUFRLElBQUksQ0FBQyxJQUFZLEVBQUUsY0FBcUMsQ0FBQztJQUNuRSxDQUFDOzhHQWxRVSx1QkFBdUI7a0dBQXZCLHVCQUF1QiwyVUM5THBDLG1wM0JBdW5CQTs7MkZEemJhLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSxxQkFBcUI7Z0tBZXZCLElBQUk7c0JBRFgsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUs7Z0JBR0UsY0FBYztzQkFEckIsS0FBSztnQkFHRSxrQkFBa0I7c0JBRHpCLEtBQUs7Z0JBR0UsS0FBSztzQkFEWixLQUFLO2dCQUdFLGVBQWU7c0JBRHRCLEtBQUs7Z0JBR0Usb0JBQW9CO3NCQUQzQixLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSztnQkFHQyxhQUFhO3NCQURuQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmcm9tLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGlzdGluY3QsXG4gIGZpbHRlcixcbiAgcmVkdWNlLFxuICB0b0FycmF5LFxuICBtYXAsXG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBzd2l0Y2hNYXAsXG4gIG1lcmdlTWFwLFxuICBtZXJnZUFsbFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDeWNsZUZ1bmN0aW9uYWxVbml0LFxuICBFbWlzc2lvbk1ldGhvZFRpZXIsXG4gIElUZXJtSlNPTkxELFxuICBKU09OTEQsXG4gIE5vZGVUeXBlLFxuICBUZXJtLFxuICBUZXJtVGVybVR5cGUsXG4gIGVtaXNzaW9uVGVybVRlcm1UeXBlLFxuICBpbmRpY2F0b3JUZXJtVGVybVR5cGUsXG4gIGlucHV0VGVybVRlcm1UeXBlLFxuICBtZWFzdXJlbWVudFRlcm1UZXJtVHlwZSxcbiAgcHJhY3RpY2VUZXJtVGVybVR5cGUsXG4gIHByb2R1Y3RUZXJtVGVybVR5cGVcbn0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsga2V5VG9MYWJlbCwgdW5pcXVlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscyc7XG5pbXBvcnQgeyBwcm9wZXJ0eVZhbHVlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC91dGlscy9kaXN0L3Rlcm0nO1xuaW1wb3J0IHsgbG9hZFJlc291cmNlS2V5IH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9nbG9zc2FyeSc7XG5cbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSxcbiAgSUJsYW5rTm9kZUxvZyxcbiAgTG9nU3RhdHVzLFxuICBJQ29uZmlnTW9kZWwsXG4gIGJsYW5rTm9kZSxcbiAgZ3JvdXBMb2dzQnlNb2RlbCxcbiAgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LFxuICBjb21wdXRlVGVybXMsXG4gIGxvZ1ZhbHVlQXJyYXksXG4gIElOb2RlVGVybUxvZ3MsXG4gIElOb2RlTG9ncyxcbiAgbm9uQmxhbmtOb2RlLFxuICBncm91cGRMb2dzQnlLZXksXG4gIElOb25CbGFua05vZGVMb2csXG4gIElMb2csXG4gIGNvbXB1dGVLZXlzLFxuICBub2RlTW9kZWxLZXksXG4gIG5vbk5vZGVNb2RlbEtleVxufSBmcm9tICcuL25vZGUtbG9ncy1tb2RlbHMubW9kZWwnO1xuaW1wb3J0IHsgSUpTT05Ob2RlLCBIZU5vZGVTZXJ2aWNlIH0gZnJvbSAnLi4vbm9kZS5zZXJ2aWNlJztcbmltcG9ydCB7IEhlRW5naW5lU2VydmljZSwgSU1vZGVsLCBJT3JjaGVzdHJhdG9yQ29uZmlnLCBmaW5kT3JjaGVzdHJhdG9yTW9kZWwgfSBmcm9tICcuLi8uLi9lbmdpbmUvZW5naW5lLnNlcnZpY2UnO1xuaW1wb3J0IHsgbWF0Y2hFeGFjdFF1ZXJ5LCBtYXRjaElkLCBtYXRjaFRlcm1UeXBlLCBtYXRjaFR5cGUgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLm1vZGVsJztcbmltcG9ydCB7IEhlU2VhcmNoU2VydmljZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2guc2VydmljZSc7XG5pbXBvcnQgeyBiYXNlVXJsLCBpc0V4dGVybmFsLCB0eXBlYWhlYWRGb2N1cyB9IGZyb20gJy4uLy4uL2NvbW1vbi91dGlscyc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuXG5jb25zdCBub2RlVHlwZXNMb3dlckNhc2UgPSBPYmplY3QudmFsdWVzKE5vZGVUeXBlKS5tYXAodiA9PiB2LnRvTG93ZXJDYXNlKCkpO1xuXG5jb25zdCBsb2dJY29uOiB7XG4gIFtzdGF0dXMgaW4gTG9nU3RhdHVzXT86IHN0cmluZyB8IHN0cmluZ1tdO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ2NoZWNrJyxcbiAgW0xvZ1N0YXR1cy5lcnJvcl06ICd0aW1lcycsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06IFsnZmFyJywgJ2NpcmNsZSddLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdjaXJjbGUnLFxuICBbTG9nU3RhdHVzLm5vdFJlcXVpcmVkXTogJ2RvdC1jaXJjbGUnXG59O1xuXG5jb25zdCBsb2dDb2xvcjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmc7XG59ID0ge1xuICBbTG9nU3RhdHVzLnN1Y2Nlc3NdOiAnc3VjY2VzcycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAnZGFuZ2VyJyxcbiAgW0xvZ1N0YXR1cy5za2lwSGllcmFyY2h5XTogJ2RhcmsnLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdncmV5J1xufTtcblxuY29uc3Qgc2hvdWxkU2hvd0JsYW5rTm9kZSA9IChibGFua05vZGVMb2c6IElCbGFua05vZGVMb2cpID0+XG4gIFtcbiAgICBibGFua05vZGVMb2c/LmNvbmZpZ01vZGVscz8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8ua2V5cz8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8uc3ViVmFsdWVzPy5sZW5ndGgsXG4gICAgYmxhbmtOb2RlTG9nPy5vcmlnaW5hbD8ubGVuZ3RoLFxuICAgIGJsYW5rTm9kZUxvZz8ucmVjYWxjdWxhdGVkPy5sZW5ndGhcbiAgXS5zb21lKEJvb2xlYW4pO1xuXG5jb25zdCBtZXRob2RJZExhYmVsID0gKG1ldGhvZElkOiBzdHJpbmcsIF9tb2RlbD86IElNb2RlbCkgPT5cbiAgKG1ldGhvZElkXG4gICAgPyB7XG4gICAgICAgICdjeWNsZS90cmFuc2Zvcm1hdGlvbic6ICdEYXRhIEZyb20gVHJhbnNmb3JtYXRpb24nLFxuICAgICAgICBpbXBhY3RfYXNzZXNzbWVudDogJ0RhdGEgRnJvbSBDeWNsZSdcbiAgICAgIH1bbWV0aG9kSWRdXG4gICAgOiAnJykgfHwgKG1ldGhvZElkLmluY2x1ZGVzKCcvJykgPyBtZXRob2RJZC5zcGxpdCgnLycpWzBdIDoga2V5VG9MYWJlbChtZXRob2RJZCkpO1xuXG5jb25zdCBnZXRNb2RlbHNBdCA9IChsb2c6IElCbGFua05vZGVMb2dTdWJWYWx1ZSB8IElCbGFua05vZGVMb2csIGluZGV4OiBudW1iZXIpID0+XG4gICgnbW9kZWxzSW5TdWJWYWx1ZXMnIGluIGxvZyA/ICFsb2cubW9kZWxzSW5TdWJWYWx1ZXMgfHwgIWxvZy5pc09wZW4gOiB0cnVlKSAmJiBsb2cuY29uZmlnTW9kZWxzW2luZGV4XTtcblxuY29uc3QgcmVxdWlyZW1lbnRLZXlzID0gKHJlcXVpcmVtZW50czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkgPT5cbiAgT2JqZWN0LmtleXMocmVxdWlyZW1lbnRzKS5maWx0ZXIoayA9PiAhbm9kZVR5cGVzTG93ZXJDYXNlLmluY2x1ZGVzKGspKTtcblxuY29uc3QgcmVxdWlyZW1lbnRDb2xvciA9ICh2YWx1ZTogYW55KSA9PiAoIXZhbHVlIHx8IFsnTm9uZScsICdGYWxzZScsICcwJywgJzAuMCddLmluY2x1ZGVzKHZhbHVlKSA/ICdkYW5nZXInIDogJ3doaXRlJyk7XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5OiB7XG4gIFtrZXk6IHN0cmluZ106ICh2YWx1ZTogc3RyaW5nKSA9PiBQYXJ0aWFsPEpTT05MRDxOb2RlVHlwZT4+O1xufSA9IHtcbiAgcmVsYXRlZF9jeWNsZXM6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBjeWNsZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGltcGFjdF9hc3Nlc3NtZW50X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkltcGFjdEFzc2Vzc21lbnQsICdAaWQnOiB2IH0pLFxuICBzaXRlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNpdGUsICdAaWQnOiB2IH0pLFxuICBzb3VyY2VfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU291cmNlLCAnQGlkJzogdiB9KSxcbiAgcHJvcGVydHlfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSwgJ0BpZCc6IHYgfSksXG4gIGlucHV0X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pLFxuICBwcm9kdWN0X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sICdAaWQnOiB2IH0pLFxuICBwcmFjdGljZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLCAnQGlkJzogdiB9KVxufTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlID0gKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PlxuICBrZXkgaW4gcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXkgJiYgWydOb25lJywgJycsIG51bGxdLmluY2x1ZGVzKHZhbHVlKSAmJiByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleVtrZXldKHZhbHVlKTtcblxuY29uc3QgaXNTeXN0ZW1Cb3VuZGFyeSA9XG4gICh0ZXJtSWQ/OiBzdHJpbmcpID0+XG4gICh7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz4pID0+IHtcbiAgICAvLyBvbmx5IGV4aXN0cyBmb3Igc29tZSB0ZXJtc1xuICAgIGNvbnN0IGluU3lzdGVtQm91bmRhcnkgPSBsb2FkUmVzb3VyY2VLZXkoJ2luSGVzdGlhRGVmYXVsdFN5c3RlbUJvdW5kYXJ5Lmpzb24nLCB0ZXJtSWQpO1xuICAgIHJldHVybiAhaW5TeXN0ZW1Cb3VuZGFyeSA/IFtpc1JlY2FsY3VsYXRlZCwgaXNSZXF1aXJlZF0uc29tZShCb29sZWFuKSA6IGAke2luU3lzdGVtQm91bmRhcnl9YCA9PT0gJ3RydWUnO1xuICB9O1xuXG5jb25zdCBpc0dlbmVyaWNUZXJtID0gKHRlcm1JZDogc3RyaW5nKSA9PiBbdGVybUlkLnN0YXJ0c1dpdGgoJ2V4Y3JldGEnKV0uZXZlcnkoQm9vbGVhbik7XG5cbmNvbnN0IGV4dHJhVGVybUlkc0Zyb21Db25maWcgPSAoY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnLCBrZXk6IG5vZGVNb2RlbEtleSwgbG9nczogSU5vZGVMb2dzIHwgSU5vZGVUZXJtTG9ncykgPT5cbiAgdW5pcXVlKFtcbiAgICAuLi5jb25maWcubW9kZWxzXG4gICAgICAuZmxhdCgpXG4gICAgICAuZmlsdGVyKG0gPT4gbS5rZXkgPT09IGtleSlcbiAgICAgIC5tYXAobSA9PiBtLnZhbHVlKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmZpbHRlcih2ID0+ICFpc0dlbmVyaWNUZXJtKHYpKSxcbiAgICAvLyBtYXRjaCBsb2dzIHdpdGggYSBjb25maWd1cmF0aW9uXG4gICAgLi4uT2JqZWN0LmVudHJpZXMobG9ncylcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChbX2lkLCB2YWx1ZV0pID0+XG4gICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5zb21lKChbbW9kZWwsIHZdOiBbbW9kZWw6IHN0cmluZywgdmFsdWU6IGFueV0pID0+XG4gICAgICAgICAgICBmaW5kT3JjaGVzdHJhdG9yTW9kZWwoY29uZmlnLCB7IGtleSwgbW9kZWwsIHZhbHVlOiB2Lm1vZGVsX2tleSB9KVxuICAgICAgICAgIClcbiAgICAgIClcbiAgICAgIC5tYXAoKFtrZXldKSA9PiBrZXkpXG4gIF0pO1xuXG5jb25zdCBtYXRjaFRlcm1UeXBlRnJvbUtleToge1xuICBba2V5OiBzdHJpbmddOiBUZXJtVGVybVR5cGVbXTtcbn0gPSB7XG4gIHByb2R1Y3RzOiBwcm9kdWN0VGVybVRlcm1UeXBlLnRlcm0sXG4gIGlucHV0czogaW5wdXRUZXJtVGVybVR5cGUudGVybSxcbiAgbWVhc3VyZW1lbnRzOiBtZWFzdXJlbWVudFRlcm1UZXJtVHlwZS50ZXJtLFxuICBwcmFjdGljZXM6IHByYWN0aWNlVGVybVRlcm1UeXBlLnRlcm0sXG4gIGVtaXNzaW9uczogZW1pc3Npb25UZXJtVGVybVR5cGUudGVybSxcbiAgZW1pc3Npb25zUmVzb3VyY2VVc2U6IGluZGljYXRvclRlcm1UZXJtVHlwZS50ZXJtLFxuICBpbXBhY3RzOiBpbmRpY2F0b3JUZXJtVGVybVR5cGUudGVybSxcbiAgZW5kcG9pbnRzOiBpbmRpY2F0b3JUZXJtVGVybVR5cGUudGVybVxufTtcblxuY29uc3QgdGVybVNlYXJjaCA9ICh0ZXJtID0gJycpID0+IHRlcm0ucmVwbGFjZSgvWyxcXHNdL2csICcnKS50b0xvd2VyQ2FzZSgpO1xuXG5jb25zdCBjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeCA9ICdfY29tcGxldGUnO1xuY29uc3QgY29tcGxldGVuZXNzSW5jb21wbGV0ZVN1ZmZpeCA9ICdfaW5jb21wbGV0ZSc7XG5jb25zdCBwYXJzZUxvZ0NvbXBsZXRlbmVzcyA9IChrZXk6IHN0cmluZykgPT5cbiAgW1xuICAgIGtleS5zdGFydHNXaXRoKCd0ZXJtX3R5cGVfJyksXG4gICAga2V5LmVuZHNXaXRoKGNvbXBsZXRlbmVzc0NvbXBsZXRlU3VmZml4KSB8fCBrZXkuZW5kc1dpdGgoY29tcGxldGVuZXNzSW5jb21wbGV0ZVN1ZmZpeClcbiAgXS5ldmVyeShCb29sZWFuKVxuICAgID8ge1xuICAgICAgICBrZXk6IGtleVxuICAgICAgICAgIC5yZXBsYWNlKCd0ZXJtX3R5cGVfJywgJycpXG4gICAgICAgICAgLnJlcGxhY2UoY29tcGxldGVuZXNzQ29tcGxldGVTdWZmaXgsICcnKVxuICAgICAgICAgIC5yZXBsYWNlKGNvbXBsZXRlbmVzc0luY29tcGxldGVTdWZmaXgsICcnKSxcbiAgICAgICAgdmFsdWU6IGtleS5lbmRzV2l0aChjb21wbGV0ZW5lc3NDb21wbGV0ZVN1ZmZpeClcbiAgICAgIH1cbiAgICA6IG51bGw7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLW5vZGUtbG9ncy1tb2RlbHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOb2RlTG9nc01vZGVsc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgbG9nczogc3RyaW5nO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IChJQmxhbmtOb2RlTG9nIHwgSU5vbkJsYW5rTm9kZUxvZylbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5OiBub2RlTW9kZWxLZXkgfCBub25Ob2RlTW9kZWxLZXk7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgb3JpZ2luYWxWYWx1ZXM6IGJsYW5rTm9kZVtdIHwgbm9uQmxhbmtOb2RlID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgcmVjYWxjdWxhdGVkVmFsdWVzOiBibGFua05vZGVbXSB8IG5vbkJsYW5rTm9kZSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHRlcm1zOiBJVGVybUpTT05MRFtdID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgZmlsdGVyVGVybVR5cGVzPzogVGVybVRlcm1UeXBlW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgZmlsdGVyVGVybVR5cGVzTGFiZWw/OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbG9nc0tleT86IHN0cmluZztcbiAgQElucHV0KClcbiAgcHVibGljIG5vRGF0YU1lc3NhZ2U/OiBzdHJpbmc7XG5cbiAgcHVibGljIGxvZ3NVcmw/OiBzdHJpbmc7XG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgaXNFeHRlcm5hbCA9IGlzRXh0ZXJuYWwoKTtcbiAgcHVibGljIEN5Y2xlRnVuY3Rpb25hbFVuaXQgPSBDeWNsZUZ1bmN0aW9uYWxVbml0O1xuICBwdWJsaWMgRW1pc3Npb25NZXRob2RUaWVyID0gRW1pc3Npb25NZXRob2RUaWVyO1xuICBwdWJsaWMgTG9nU3RhdHVzID0gTG9nU3RhdHVzO1xuICBwdWJsaWMgbG9nSWNvbiA9IGxvZ0ljb247XG4gIHB1YmxpYyBsb2dDb2xvciA9IGxvZ0NvbG9yO1xuICBwdWJsaWMgcHJvcGVydHlWYWx1ZSA9IHByb3BlcnR5VmFsdWU7XG4gIHB1YmxpYyBnZXRNb2RlbHNBdCA9IGdldE1vZGVsc0F0O1xuICBwdWJsaWMgcmVxdWlyZW1lbnRLZXlzID0gcmVxdWlyZW1lbnRLZXlzO1xuICBwdWJsaWMgcmVxdWlyZW1lbnRDb2xvciA9IHJlcXVpcmVtZW50Q29sb3I7XG4gIHB1YmxpYyBsb2dWYWx1ZUFycmF5ID0gbG9nVmFsdWVBcnJheTtcbiAgcHVibGljIHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IHJlcXVpcmVtZW50TGlua2VkTm9kZTtcbiAgcHVibGljIGlzU3lzdGVtQm91bmRhcnkgPSBpc1N5c3RlbUJvdW5kYXJ5O1xuICBwdWJsaWMgcGFyc2VMb2dDb21wbGV0ZW5lc3MgPSBwYXJzZUxvZ0NvbXBsZXRlbmVzcztcbiAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xuICBwdWJsaWMgbm9kZVR5cGU6IE5vZGVUeXBlO1xuICBwdWJsaWMgYmxhbmtOb2RlczogKElCbGFua05vZGVMb2cgfCBJTm9uQmxhbmtOb2RlTG9nKVtdID0gW107XG4gIHB1YmxpYyBtZXRob2RNb2RlbHNDb3VudCA9IDA7XG4gIHB1YmxpYyBvbmx5UmVxdWlyZWQgPSB0cnVlO1xuICBwdWJsaWMgc2hvd0xlZ2VuZCA9IHRydWU7XG5cbiAgcHVibGljIHRlcm0/OiBzdHJpbmc7XG4gIHB1YmxpYyBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwdWJsaWMgc3VnZ2VzdFRlcm0gPSAodGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPikgPT5cbiAgICB0ZXh0JC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHN3aXRjaE1hcCh2ID0+IHRoaXMuc3VnZ2VzdEJ5VGVybSh2KSlcbiAgICApO1xuXG4gIHB1YmxpYyB0eXBlYWhlYWRGb2N1cyA9IHR5cGVhaGVhZEZvY3VzO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IEhlTm9kZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZWFyY2hTZXJ2aWNlOiBIZVNlYXJjaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmdpbmVTZXJ2aWNlOiBIZUVuZ2luZVNlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUsIHRoaXMubm9kZVsnQGlkJ10gfHwgdGhpcy5ub2RlLmlkKTtcblxuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgYm9vbDoge1xuICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pLCBtYXRjaFRlcm1UeXBlKFRlcm1UZXJtVHlwZS5tb2RlbCldXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1ldGhvZHNCeUlkID0gYXdhaXQgZnJvbShtb2RlbHMpXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcbiAgICAgICAgZGlzdGluY3QodiA9PiB2WydAaWQnXSksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICAvLyBmcm9tIGBtb2RlbC1saW5rcy5qc29uYCBmaWxlXG4gICAgY29uc3QgZW5naW5lTW9kZWxzID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm1vZGVscygpO1xuXG4gICAgdGhpcy5pc0JsYW5rTm9kZXNcbiAgICAgID8gYXdhaXQgdGhpcy5wcm9jZXNzQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZylcbiAgICAgIDogdGhpcy5wcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzLCBlbmdpbmVNb2RlbHMsIGNvbmZpZyk7XG5cbiAgICB0aGlzLmZpbHRlclJlc3VsdHMoKTtcblxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dzKCkge1xuICAgIHJldHVybiB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyh0aGlzLm5vZGUpLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWdnZXN0QnlUZXJtKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiBmcm9tKHRoaXMuYWxsVGVybXMpLnBpcGUoXG4gICAgICBtYXAodiA9PiB2Lm5hbWUpLFxuICAgICAgZmlsdGVyKHYgPT4gdGVybVNlYXJjaCh2KS5pbmNsdWRlcyh0ZXJtU2VhcmNoKHRlcm0pKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NCbGFua05vZGVzKFxuICAgIGxvZ3M6IElOb2RlTG9ncyB8IElOb2RlVGVybUxvZ3MsXG4gICAgZW5naW5lTW9kZWxzOiBJTW9kZWxbXSxcbiAgICBjb25maWc6IElPcmNoZXN0cmF0b3JDb25maWdcbiAgKSB7XG4gICAgY29uc3QgZXh0cmFUZXJtSWRzID0gZXh0cmFUZXJtSWRzRnJvbUNvbmZpZyhjb25maWcsIHRoaXMubm9kZUtleSBhcyBub2RlTW9kZWxLZXksIGxvZ3MpO1xuICAgIGNvbnN0IG1hdGNoVGVybVR5cGVzID0gWy4uLihtYXRjaFRlcm1UeXBlRnJvbUtleVt0aGlzLm5vZGVLZXldIHx8IFtdKSwgLi4uKHRoaXMuZmlsdGVyVGVybVR5cGVzIHx8IFtdKV07XG4gICAgY29uc3QgZXh0cmFUZXJtcyA9IGF3YWl0IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgYm9vbDoge1xuICAgICAgICBtdXN0OiBbXG4gICAgICAgICAgbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pLFxuICAgICAgICAgIG1hdGNoVGVybVR5cGVzLmxlbmd0aFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgICAgICAgc2hvdWxkOiBtYXRjaFRlcm1UeXBlcy5tYXAobWF0Y2hUZXJtVHlwZSksXG4gICAgICAgICAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBudWxsXG4gICAgICAgIF0uZmlsdGVyKEJvb2xlYW4pLFxuICAgICAgICBzaG91bGQ6IGV4dHJhVGVybUlkcy5tYXAobWF0Y2hJZCksXG4gICAgICAgIG1pbmltdW1fc2hvdWxkX21hdGNoOiAxXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsbFRlcm1zID0gYXdhaXQgY29tcHV0ZVRlcm1zKFxuICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlcyBhcyBibGFua05vZGVbXSxcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy50ZXJtcyxcbiAgICAgIHRoaXMuZmlsdGVyVGVybVR5cGVzLFxuICAgICAgZXh0cmFUZXJtc1xuICAgICk7XG4gICAgY29uc3QgbWFwRnVuYyA9IGdyb3VwTG9nc0J5VGVybShcbiAgICAgIHRoaXMubm9kZVR5cGUsXG4gICAgICBsb2dzLFxuICAgICAgZW5naW5lTW9kZWxzLFxuICAgICAgY29uZmlnLFxuICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlcyBhcyBibGFua05vZGVbXSxcbiAgICAgIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzIGFzIGJsYW5rTm9kZVtdLFxuICAgICAgdGhpcy5ub2RlS2V5IGFzIG5vZGVNb2RlbEtleVxuICAgICk7XG4gICAgY29uc3QgYWxsQmxhbmtOb2RlcyA9IHRoaXMuYWxsVGVybXMuZmxhdE1hcChtYXBGdW5jKS5maWx0ZXIoc2hvdWxkU2hvd0JsYW5rTm9kZSk7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IG1vZGVsQ291bnQoYWxsQmxhbmtOb2Rlcyk7XG5cbiAgICB0aGlzLnRlcm1zQnlJZCA9IGF3YWl0IG9mKGFsbEJsYW5rTm9kZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICAgIG1hcCh2ID0+IHYuaWQpLFxuICAgICAgICBkaXN0aW5jdCgpLFxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxuICAgICAgICB0b0FycmF5KCksXG4gICAgICAgIG1lcmdlTWFwKGlkcyA9PlxuICAgICAgICAgIGZyb20oXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgICAgICAgYm9vbDoge1xuICAgICAgICAgICAgICAgIG11c3Q6IFttYXRjaFR5cGUoTm9kZVR5cGUuVGVybSldLFxuICAgICAgICAgICAgICAgIHNob3VsZDogaWRzLm1hcChpZCA9PiBtYXRjaEV4YWN0UXVlcnkoJ0BpZCcsIGlkKSksXG4gICAgICAgICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG1lcmdlQWxsKCksXG4gICAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSBhbGxCbGFua05vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTm9uQmxhbmtOb2Rlcyhsb2dzOiBJTm9kZUxvZ3MgfCBJTm9kZVRlcm1Mb2dzLCBlbmdpbmVNb2RlbHM6IElNb2RlbFtdLCBfY29uZmlnOiBJT3JjaGVzdHJhdG9yQ29uZmlnKSB7XG4gICAgY29uc3QgbWFwRnVuYyA9IGdyb3VwZExvZ3NCeUtleShcbiAgICAgIHRoaXMubm9kZVR5cGUsXG4gICAgICB0aGlzLm5vZGVLZXkgYXMgbm9uTm9kZU1vZGVsS2V5LFxuICAgICAgbG9ncyxcbiAgICAgIGVuZ2luZU1vZGVscyxcbiAgICAgIHRoaXMub3JpZ2luYWxWYWx1ZXMgYXMgbm9uQmxhbmtOb2RlLFxuICAgICAgdGhpcy5yZWNhbGN1bGF0ZWRWYWx1ZXMgYXMgbm9uQmxhbmtOb2RlXG4gICAgKTtcbiAgICBjb25zdCBrZXlzID0gY29tcHV0ZUtleXModGhpcy5vcmlnaW5hbFZhbHVlcyBhcyBub25CbGFua05vZGUsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzIGFzIG5vbkJsYW5rTm9kZSk7XG4gICAgY29uc3QgYWxsQmxhbmtOb2RlcyA9IGtleXMuZmxhdE1hcChtYXBGdW5jKTtcbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSBhbGxCbGFua05vZGVzO1xuICAgIHRoaXMubWV0aG9kTW9kZWxzQ291bnQgPSAxO1xuICB9XG5cbiAgcHVibGljIGdldCBpc0JsYW5rTm9kZXMoKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodGhpcy5vcmlnaW5hbFZhbHVlcykgfHwgQXJyYXkuaXNBcnJheSh0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcyk7XG4gIH1cblxuICBwdWJsaWMgdHJhY2tCeUJsYW5rTm9kZShfaW5kZXg6IG51bWJlciwgbm9kZTogYW55KSB7XG4gICAgcmV0dXJuIG5vZGUudGVybUlkIHx8IG5vZGUua2V5O1xuICB9XG5cbiAgcHVibGljIGdldCBmaWx0ZXJlZFR5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyVGVybVR5cGVzTGFiZWwgfHwgdGhpcy5maWx0ZXJUZXJtVHlwZXM/Lm1hcCh0ZXJtVHlwZUxhYmVsKS5qb2luKCcgJiAnKTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyQmxhbmtOb2RlKHsgdGVybTogeyBuYW1lLCAnQGlkJzogaWQgfSwgc3ViVmFsdWVzLCAuLi5sb2cgfTogSUJsYW5rTm9kZUxvZykge1xuICAgIHJldHVybiB0aGlzLnRlcm1cbiAgICAgID8gbmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRoaXMudGVybS50b0xvd2VyQ2FzZSgpKVxuICAgICAgOiAhdGhpcy5maWx0ZXJUZXJtVHlwZXM/Lmxlbmd0aCB8fFxuICAgICAgICAgICF0aGlzLm9ubHlSZXF1aXJlZCB8fFxuICAgICAgICAgIGlzU3lzdGVtQm91bmRhcnkoaWQpKGxvZykgfHxcbiAgICAgICAgICBzdWJWYWx1ZXMuc29tZShpc1N5c3RlbUJvdW5kYXJ5KGlkKSk7XG4gIH1cblxuICBwdWJsaWMgZmlsdGVyUmVzdWx0cygpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuYmxhbmtOb2RlcyA9IHRoaXMuYWxsQmxhbmtOb2Rlcy5maWx0ZXIobG9nID0+ICEoJ3Rlcm0nIGluIGxvZykgfHwgdGhpcy5maWx0ZXJCbGFua05vZGUobG9nKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbWV0aG9kTmFtZSh7IG1ldGhvZElkLCBtb2RlbCB9OiBJQ29uZmlnTW9kZWwpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRob2RzQnlJZFttZXRob2RJZF0/Lm5hbWUgfHwgbWV0aG9kSWRMYWJlbChtZXRob2RJZCwgbW9kZWwpO1xuICB9XG5cbiAgcHVibGljIGhhc01ldGhvZFRpZXIodmFsdWVzOiBibGFua05vZGVbXSwgbWV0aG9kVGllcjogRW1pc3Npb25NZXRob2RUaWVyKSB7XG4gICAgcmV0dXJuIHZhbHVlcy5zb21lKHYgPT4gJ21ldGhvZFRpZXInIGluIHYgJiYgdi5tZXRob2RUaWVyID09PSBtZXRob2RUaWVyKTtcbiAgfVxuXG4gIHB1YmxpYyB0ZXJtQnlJZChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMudGVybXNCeUlkW2lkXSB8fFxuICAgICAgKHtcbiAgICAgICAgJ0B0eXBlJzogTm9kZVR5cGUuVGVybSxcbiAgICAgICAgJ0BpZCc6IGlkLFxuICAgICAgICBuYW1lOiB0ZXJtVHlwZUxhYmVsKGlkKVxuICAgICAgfSBhcyBJVGVybUpTT05MRClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGdldCBmdW5jdGlvbmFsVW5pdCgpIHtcbiAgICByZXR1cm4gKHRoaXMubm9kZSBhcyBhbnkpPy5mdW5jdGlvbmFsVW5pdCBhcyBDeWNsZUZ1bmN0aW9uYWxVbml0O1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicHgtMyBwYi0zXCI+XG4gIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1yaWdodCBtYi0yXCIgKm5nSWY9XCIhaXNFeHRlcm5hbFwiPlxuICAgIDxhIGNsYXNzPVwiaXMtc2l6ZS03XCIgKm5nSWY9XCJsb2dzVXJsXCIgW2hyZWZdPVwibG9nc1VybFwiIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgPGZhLWljb24gaWNvbj1cImV4dGVybmFsLWxpbmstYWx0XCI+PC9mYS1pY29uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0yXCI+T3BlbiBGdWxsIExvZ3M8L3NwYW4+XG4gICAgPC9hPlxuICA8L2Rpdj5cblxuICA8aGUtZGF0YS10YWJsZSBjbGFzcz1cIm1iLTEgaXMtc21hbGxcIiBbc21hbGxdPVwidHJ1ZVwiIG1heEhlaWdodD1cIjMyMFwiPlxuICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWZ1bGx3aWR0aCBpcy1uYXJyb3cgaXMtc3RyaXBlZFwiPlxuICAgICAgPHRoZWFkPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRoIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGRcIiAqbmdJZj1cImFsbFRlcm1zPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wgaXMtZXhwYW5kZWQgaGFzLWljb25zLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRlcm1cIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRlcm1cIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgZW50cnkgYnkgbmFtZVwiXG4gICAgICAgICAgICAgICAgICBbbmdiVHlwZWFoZWFkXT1cInN1Z2dlc3RUZXJtXCJcbiAgICAgICAgICAgICAgICAgIFtmb2N1c0ZpcnN0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cInR5cGVhaGVhZEZvY3VzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwiZmlsdGVyUmVzdWx0cygpXCIgLz5cbiAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImljb24gaXMtc21hbGwgaXMtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiF0ZXJtXCIgKGNsaWNrKT1cInRlcm0gPSAnJzsgZmlsdGVyUmVzdWx0cygpXCI+XG4gICAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwidGltZXNcIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXByLTFcIj5Vbml0czwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPihwZXImbmJzcDs8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBbbmdTd2l0Y2hdPVwiZnVuY3Rpb25hbFVuaXRcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiQ3ljbGVGdW5jdGlvbmFsVW5pdFsnMSBoYSddXCI+aGVjdGFyZTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+a2cgcHJvZHVjdDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+KTwvc3Bhbj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5PcmlnaW5hbDwvdGg+XG4gICAgICAgICAgPHRoPlJlY2FsY3VsYXRlZDwvdGg+XG4gICAgICAgICAgPHRoICpuZ0lmPVwiaXNCbGFua05vZGVzXCI+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj4oe3sgaSArIDEgfX0pPC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDx0ciAqbmdJZj1cImxvYWRpbmdcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGFzLXRleHQtY2VudGVyIHB5LTNcIj5cbiAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInNwaW5uZXJcIiBbcHVsc2VdPVwidHJ1ZVwiIHNpemU9XCJsZ1wiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0ciAqbmdJZj1cIiFsb2FkaW5nICYmIGJsYW5rTm9kZXMubGVuZ3RoID09PSAwXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPHNwYW4+e3sgbm9EYXRhTWVzc2FnZSB8fCAnTm8gZGF0YScgfX08L3NwYW4+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYmxhbmtOb2RlIG9mIGJsYW5rTm9kZXM7IHRyYWNrQnk6IHRyYWNrQnlCbGFua05vZGVcIj5cbiAgICAgICAgICA8dHIgW2NsYXNzLmhhcy1zdWItcm93c109XCJibGFua05vZGUuY2FuT3BlblwiIFtjbGFzcy5pcy1vcGVuXT1cImJsYW5rTm9kZS5pc09wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodCBpcy1ub3dyYXBcIiBbYXR0ci50aXRsZV09XCJibGFua05vZGUudGVybT8ubmFtZSB8fCBibGFua05vZGUua2V5XCI+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHByLTIgb3Blbi1ub2RlXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiYmxhbmtOb2RlLmlzT3BlbiA9ICFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS5jYW5PcGVuXCI+XG4gICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLXByZS13cmFwXCIgKm5nSWY9XCJibGFua05vZGUudGVybVwiIFtub2RlXT1cImJsYW5rTm9kZS50ZXJtXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySHRtbF09XCJibGFua05vZGUudGVybS5uYW1lIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvaGUtbm9kZS1saW5rPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImJsYW5rTm9kZS5rZXlcIj57eyBibGFua05vZGUua2V5IH19PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcFwiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRPcmlnaW5hbFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPlxuICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYmxhbmtOb2RlLmlzT3JpZ2luYWwgfHwgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgICAge3sgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gfCBwcmVjaXNpb246IDMgfCBkZWZhdWx0OiAnLScgfX1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIiBjbGFzcz1cImlzLW5vd3JhcFwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHREZWx0YVZhbHVlPlxuICAgICAgICAgICAgICAgIDxoZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS5vcmlnaW5hbC5sZW5ndGggJiYgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbb3JpZ2luYWxWYWx1ZV09XCJibGFua05vZGUub3JpZ2luYWxWYWx1ZVwiPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0RGVsdGFWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgIDxoZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgICAgICAgICAgYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gIT09IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgZWxzZSBub1ZhbHVlXG4gICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiXG4gICAgICAgICAgICAgICAgICAgIFtvcmlnaW5hbFZhbHVlXT1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF1cIj48L2hlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGE+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHsgZGF0YTogYmxhbmtOb2RlIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLmtleXNcIlxuICAgICAgICAgICAgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICBbY2xhc3MuaGFzLXN1Yi1yb3dzXT1cImJsYW5rTm9kZS5zdWJWYWx1ZXM/Lmxlbmd0aFwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtc3ViLXJvd109XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0IGlzLW5vd3JhcFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcGwtMyBwci0xIGZpZWxkLW5vZGVcIj5GaWVsZDo8L3NwYW4+XG5cbiAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1wcmUtd3JhcFwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJibGFua05vZGUudHlwZVwiXG4gICAgICAgICAgICAgICAgW2hyZWZdPVwiYmFzZVVybCArICcvc2NoZW1hLycgKyBibGFua05vZGUudHlwZSArICcjJyArIHN1YlZhbHVlLmtleVwiXG4gICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICBbdGl0bGVdPVwic3ViVmFsdWUua2V5XCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgc3ViVmFsdWUua2V5IH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcFwiICpuZ0lmPVwiIWJsYW5rTm9kZS50eXBlXCI+e3sgc3ViVmFsdWUua2V5IH19PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUub3JpZ2luYWxWYWx1ZSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkIHx8IHN1YlZhbHVlLmtleSA9PT0gJ2ltcGFjdEFzc2Vzc21lbnQnOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHsgZGF0YTogc3ViVmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUuc3ViVmFsdWVzXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgW2NsYXNzLmlzLXN1Yi1yb3ddPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcGwtM1wiPnt7IHN1YlZhbHVlLmtleSB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN1YlZhbHVlLmlkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMVwiPjo8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nU3dpdGNoQ2FzZT1cIidiYWNrZ3JvdW5kRGF0YSdcIj57eyBzdWJWYWx1ZS5pZCB8IGtleVRvTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rXG4gICAgICAgICAgICAgICAgICAgICpuZ1N3aXRjaERlZmF1bHRcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpcy1ibG9jayBwbC00XCJcbiAgICAgICAgICAgICAgICAgICAgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySHRtbF09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZCkubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImlzQmxhbmtOb2Rlc1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcFwiICpuZ0lmPVwic3ViVmFsdWUuc2hvd1VuaXRzXCIgW2lubmVySHRtbF09XCJibGFua05vZGUudGVybT8udW5pdHMgfCBjb21wb3VuZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUub3JpZ2luYWxWYWx1ZSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCI+XG4gICAgICAgICAgICAgICAge3sgc3ViVmFsdWUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjogMyB8IGRlZmF1bHQ6ICctJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7IHN1YlZhbHVlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOiAzIHwgZGVmYXVsdDogJy0nIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgKm5nSWY9XCJpc0JsYW5rTm9kZXNcIj4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHsgZGF0YTogc3ViVmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2hlLWRhdGEtdGFibGU+XG5cbiAgPGRpdiBjbGFzcz1cImlzLXNpemUtNyBpcy1pdGFsaWNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1ucyBpcy12YXJpYWJsZSBpcy0xIG15LTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaXMtbmFycm93XCI+XG4gICAgICAgIDxwPlxuICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIHByLTJcIiAoY2xpY2spPVwic2hvd0xlZ2VuZCA9ICFzaG93TGVnZW5kXCI+XG4gICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtZG93blwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXNob3dMZWdlbmRcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cInNob3dMZWdlbmRcIj48L2ZhLWljb24+XG4gICAgICAgICAgPC9hPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCI+TGVnZW5kOjwvc3Bhbj5cbiAgICAgICAgPC9wPlxuICAgICAgICA8dWwgY2xhc3M9XCJjb250ZW50IHBsLTJcIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhdHVzIG9mIExvZ1N0YXR1cyB8IGtleXNcIj5cbiAgICAgICAgICAgIDxsaSAqbmdJZj1cImxvZ0ljb25bc3RhdHVzLnZhbHVlXVwiIGNsYXNzPVwiaGFzLXRleHQte3sgbG9nQ29sb3Jbc3RhdHVzLnZhbHVlXSB9fVwiPlxuICAgICAgICAgICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPnt7IHN0YXR1cy52YWx1ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaGFzLXRleHQtcmlnaHRcIiAqbmdJZj1cImZpbHRlcmVkVHlwZVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICBjbGFzcz1cInNlbGVjdG9yXCJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwib25seVJlcXVpcmVkXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsdGVyUmVzdWx0cygpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhIXRlcm1cIiAvPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlxuICAgICAgICAgICAgU2hvdyBvbmx5IHt7IGZpbHRlcmVkVHlwZSB8IHBsdXJhbGl6ZSB9fSBpbmNsdWRlZCBpbiB0aGUgZGVmYXVsdCBIZXN0aWEgc3lzdGVtIGJvdW5kYXJ5XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZSAjYmxhbmtOb2RlTW9kZWxzIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctdGVtcGxhdGUgI25vdEluU3lzdGVtQm91bmRhcnk+XG4gICAgPHRkIFthdHRyLmNvbHNwYW5dPVwibWV0aG9kTW9kZWxzQ291bnRcIj5cbiAgICAgIDxzcGFuPk5vdCBpbiBIZXN0aWEgc3lzdGVtIGJvdW5kYXJ5PC9zcGFuPlxuICAgIDwvdGQ+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzU3lzdGVtQm91bmRhcnkoZGF0YSk7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgIDx0ZCBjbGFzcz1cImJsYW5rLW5vZGUtaW5kZXgte3sgaSB9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRNb2RlbHNBdChkYXRhLCBpKTsgbGV0IG1vZGVsczsgZWxzZTogbm9WYWx1ZVwiPlxuICAgICAgICA8bmctdGVtcGxhdGUgI21vZGVsU2VyaWU+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7IG1vZGVsOiBtb2RlbHMsIGRhdGEgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwibW9kZWxzIHwgaXNBcnJheTsgZWxzZSBtb2RlbFNlcmllXCI+XG4gICAgICAgICAgPHAgKm5nRm9yPVwibGV0IG1vZGVsIG9mIG1vZGVsc1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7IG1vZGVsLCBkYXRhIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC90ZD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVsIGxldC1tb2RlbD1cIm1vZGVsXCIgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIDxzcGFuXG4gICAgY2xhc3M9XCJpcy1ub3dyYXBcIlxuICAgIFtjbGFzcy50cmlnZ2VyLXBvcG92ZXJdPVwibW9kZWwuc2hvd0xvZ3NcIlxuICAgIFtuZ2JQb3BvdmVyXT1cImxvZ0RldGFpbHNcIlxuICAgIFthdXRvQ2xvc2VdPVwiJ291dHNpZGUnXCJcbiAgICBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgIHRyaWdnZXJzPVwibWFudWFsXCJcbiAgICAjcD1cIm5nYlBvcG92ZXJcIlxuICAgIHBsYWNlbWVudD1cImxlZnRcIlxuICAgIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgIChjbGljayk9XCJwLmlzT3BlbigpID8gcC5jbG9zZSgpIDogbW9kZWwuc2hvd0xvZ3MgPyBwLm9wZW4oeyBsb2dzOiBtb2RlbC5sb2dzIH0pIDogbnVsbFwiPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtY2FwaXRhbGl6ZWRcIj57eyBtZXRob2ROYW1lKG1vZGVsKSB9fTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXJcIj5cbiAgICAgIFt7eyBtb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyIH19XVxuICAgIDwvc3Bhbj5cblxuICAgIDxzcGFuXG4gICAgICBjbGFzcz1cInBsLTEgaGFzLXRleHQte3sgbG9nQ29sb3JbbW9kZWwuc3RhdHVzXSB9fSB0cmlnZ2VyLXBvcG92ZXJcIlxuICAgICAgW25nYlBvcG92ZXJdPVwibG9nU3RhdHVzRGV0YWlsc1wiXG4gICAgICBbYXV0b0Nsb3NlXT1cIidvdXRzaWRlJ1wiXG4gICAgICBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgICAgdHJpZ2dlcnM9XCJtYW51YWxcIlxuICAgICAgI3AxPVwibmdiUG9wb3ZlclwiXG4gICAgICBwbGFjZW1lbnQ9XCJsZWZ0XCJcbiAgICAgIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcDEuaXNPcGVuKCkgPyBwMS5jbG9zZSgpIDogcDEub3Blbih7IG1vZGVsLCBkYXRhIH0pXCI+XG4gICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW21vZGVsLnN0YXR1c11cIj48L2ZhLWljb24+XG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5tb2RlbFwiPlxuICAgICAgKFxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRvY3NMaW5rOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogbW9kZWwubW9kZWwgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgKVxuICAgIDwvc3Bhbj5cbiAgPC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub1ZhbHVlPi08L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vdFJlY2FsY3VsYXRlZD5ub3QgcmVjYWxjdWxhdGVkPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dEZXRhaWxzIGxldC1sb2dzPVwibG9nc1wiPlxuICA8ZGl2IGNsYXNzPVwidGFibGUtY29udGFpbmVyXCIgKmJpbmRPbmNlPVwibG9nc1wiPlxuICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtZnVsbHdpZHRoXCI+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5yZXF1aXJlbWVudHNcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgcmVxdWlyZW1lbnRLZXlzKGxvZ3MucmVxdWlyZW1lbnRzKVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6IHsga2V5LCB2YWx1ZTogbG9ncy5yZXF1aXJlbWVudHNba2V5XSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5sb2dzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIGxvZ3MubG9ncyB8IGtleXNcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OiBrZXlcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKmJpbmRPbmNlPVwibG9nc1wiPlxuICAgIDxkaXYgY2xhc3M9XCJpdC1tdC0yXCIgKm5nSWY9XCJsb2dzPy5taXNzaW5nTG9va3Vwcz8ubGVuZ3RoXCI+XG4gICAgICA8cD5PcHRpb25hbCBkYXRhIG1pc3Npbmc6PC9wPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwidGFibGUtY29udGFpbmVyIGRhdGEtdGFibGUtY29udGFpbmVyXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtZnVsbHdpZHRoIGlzLXN0cmlwZWRcIj5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+RmlsZW5hbWU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cImhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+Q29sdW1uIFRpdGxlPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPlJvdyAodGVybS5pZCk8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5IGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIj5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgZGF0YSBvZiBsb2dzLm1pc3NpbmdMb29rdXBzXCI+XG4gICAgICAgICAgICAgIDx0ZD57eyBkYXRhLmZpbGVuYW1lIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkPnt7IGRhdGEuY29sdW1uIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkPnt7IGRhdGEudGVybUlkIH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nTGluZVZhbHVlIGxldC1rZXk9XCJrZXlcIiBsZXQtdmFsdWU9XCJ2YWx1ZVwiPlxuICA8bmctdGVtcGxhdGUgI2RlZmF1bHRWYWx1ZT5cbiAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIj57eyB2YWx1ZSB9fTwvc3Bhbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInJlcXVpcmVtZW50TGlua2VkTm9kZShrZXksIHZhbHVlKTsgbGV0IGxpbmtlZE5vZGU7IGVsc2U6IGRlZmF1bHRWYWx1ZVwiPlxuICAgIDxoZS1ub2RlLWxpbmtcbiAgICAgIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiXG4gICAgICBsaW5rQ2xhc3M9XCJpcy1kYXJrXCJcbiAgICAgIFtub2RlXT1cImxpbmtlZE5vZGVcIlxuICAgICAgW3Nob3dFeHRlcm5hbExpbmtdPVwidHJ1ZVwiPjwvaGUtbm9kZS1saW5rPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nTGluZSBsZXQta2V5PVwia2V5XCIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAgPHRyPlxuICAgIDx0ZCBjbGFzcz1cImhhcy1ib3JkZXItcmlnaHQgY29weS1sb2dcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRNZXNzYWdlPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImtleVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0Pnt7IGtleSB8IGtleVRvTGFiZWwgfX08L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Byb3BlcnR5X2lkJ1wiPlByb3BlcnR5IFRlcm0gQGlkPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvZHVjdF9pZCdcIj5Qcm9kdWN0IFRlcm0gQGlkPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXRfaWQnXCI+SW5wdXQgVGVybSBAaWQ8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ25vZGVfdHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5JcyB0aGUgY3VycmVudDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+Tm9kZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3NpdGVUeXBlX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPklzIHRoZSBjdXJyZW50PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5zaXRlVHlwZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Byb2R1Y3RfaWRfYWxsb3dlZCdcIj5cbiAgICAgICAgICAgICAgPHNwYW4+QXJlIGFueSBvZiB0aGUgUHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+QGlkPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncHJvZHVjdF90ZXJtVHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BcmUgYW55IG9mIHRoZSBQcm9kdWN0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0X2lkX2FsbG93ZWQnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFyZSBhbnkgb2YgdGhlIElucHV0PC9zcGFuPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5AaWQ8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidpbnB1dF90ZXJtVHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5BcmUgYW55IG9mIHRoZSBJbnB1dDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+dGVybVR5cGU8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPCEtLSBEZXByZWNhdGVkIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF9pZF9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5JcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPkBpZDwvY29kZT5cbiAgICAgICAgICAgICAgPHNwYW4+YWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF90ZXJtVHlwZV9hbGxvd2VkJ1wiPlxuICAgICAgICAgICAgICA8c3Bhbj5JcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3Q8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5hbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidnZW9zcGF0aWFsX2RhdGEnXCI+XG4gICAgICAgICAgICAgIEhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidjb250YWluc19nZW9zcGF0aWFsX2RhdGEnXCI+XG4gICAgICAgICAgICAgIEhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidjdXJyZW50X3NpemUnXCI+Q3VycmVudCBwb2x5Z29uIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtYXhfYXJlYV9zaXplJ1wiPk1heGltdW0gcG9seWdvbiBhcmVhIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYmVsb3dfbWF4X2FyZWFfc2l6ZSdcIj5Qb2x5Z29uIGJlbG93IHRoZSBtYXhpbXVtIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidyZWdpb25fZmFjdG9yJ1wiPkZhY3RvciBmcm9tIHJlZ2lvbiBsb29rdXA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19wZXN0aWNpZGVzX2lucHV0cydcIj5cbiAgICAgICAgICAgICAgPHNwYW4+Q3ljbGUgY29udGFpbnM8L3NwYW4+XG4gICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnBlc3RpY2lkZUFJPC9jb2RlPlxuICAgICAgICAgICAgICA8c3Bhbj5JbnB1dHM8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidhbGxfcGVzdGljaWRlQUlfaGF2ZV9sb29rdXBfdmFsdWUnXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkFsbDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+cGVzdGljaWRlQUk8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPklucHV0cyBoYXZlIGEgbG9va3VwIHZhbHVlPC9zcGFuPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfY3JvcF9yZXNpZHVlX2J1cm50J1wiPlxuICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj5hYm92ZUdyb3VuZENyb3BSZXNpZHVlQnVybnQ8L2NvZGU+XG4gICAgICAgICAgICAgIDxzcGFuPmlzIHByZXNlbnQgYXMgUHJvZHVjdDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbGlxdWlkX3NsdXJyeV9zbHVkZ2VfUCdcIj5MaXF1aWQsIFNsdXJyeSwgYW5kIFNsdWRnZSBQPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhcnNlTG9nQ29tcGxldGVuZXNzKGtleSk7IGxldCBjb21wbGV0ZW5lc3M7IGVsc2U6IGRlZmF1bHRNZXNzYWdlXCI+XG4gICAgICAgICAgPHNwYW4+RGF0YSBjb21wbGV0ZW5lc3MgZm9yPC9zcGFuPlxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IGNvbXBsZXRlbmVzcy5rZXkgfX08L2NvZGU+XG4gICAgICAgICAgPHNwYW4+bXVzdCBiZTwvc3Bhbj5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj57eyBjb21wbGV0ZW5lc3MudmFsdWUgfX08L2NvZGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9zcGFuPlxuICAgICAgPGhlLWNsaXBib2FyZFxuICAgICAgICBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIlxuICAgICAgICBjbGlwYm9hcmRDbGFzcz1cImlzLXNpemUtNyBpcy1wLTFcIlxuICAgICAgICBbaWNvbl09XCJbJ2ZhcicsICdjbG9uZSddXCJcbiAgICAgICAgW3ZhbHVlXT1cImtleVwiXG4gICAgICAgIFtoaWRlVGV4dF09XCJ0cnVlXCI+PC9oZS1jbGlwYm9hcmQ+XG4gICAgPC90ZD5cbiAgICA8dGQ+XG4gICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVZhbHVlPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZVZhbHVlOyBjb250ZXh0OiB7IGtleSwgdmFsdWUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxkaXYgKm5nSWY9XCJsb2dWYWx1ZUFycmF5KHZhbHVlKTsgbGV0IHZhbHVlQXJyYXk7IGVsc2U6IHNpbmdsZVZhbHVlXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtYm9yZGVyZWQgaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZCAqbmdJZj1cInZhbHVlQXJyYXlbMF0gfCBpc09iamVjdFwiPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlbMF0gfCBrZXlzXCI+e3sgdi5rZXkgfX08L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5XCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlQXJyYXlWYWx1ZT5cbiAgICAgICAgICAgICAgICA8dGQ+e3sgdiB9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2IHwgaXNPYmplY3Q7IGVsc2Ugc2luZ2xlQXJyYXlWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgdnYgb2YgdiB8IGtleXNcIj57eyB2di52YWx1ZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbiAgPC90cj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nU3RhdHVzRGV0YWlscyBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cIm1vZGVsXCI+XG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxzcGFuPlN0YXR1czo8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5zdGF0dXMgfX08L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuc3RhdHVzID09PSBMb2dTdGF0dXMubm90UmVxdWlyZWQgJiYgbW9kZWwubG9ncz8uaXNfbm90X3JlbGV2YW50ID09PSAnVHJ1ZSdcIj5cbiAgICAgIDx1bCBjbGFzcz1cImlzLXBsLTMgaXMtbGlzdC1zdHlsZS1kaXNjXCI+XG4gICAgICAgIDxsaSAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uc2l0ZVR5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIFRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnNpdGUuc2l0ZVR5cGU8L2NvZGU+XG4gICAgICAgICAgaXMgbm90IHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LnByb2R1Y3RfaWRfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIE5vbmUgb2YgdGhlXG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+UHJvZHVjdDwvY29kZT5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj50ZXJtLkBpZDwvY29kZT5cbiAgICAgICAgICBpcyByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5wcm9kdWN0X3Rlcm1UeXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBOb25lIG9mIHRoZVxuICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPlByb2R1Y3Q8L2NvZGU+XG4gICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1tci0xXCI+dGVybS50ZXJtVHlwZTwvY29kZT5cbiAgICAgICAgICBpcyByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5pbnB1dF9pZF9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgTm9uZSBvZiB0aGVcbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5JbnB1dDwvY29kZT5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj50ZXJtLkBpZDwvY29kZT5cbiAgICAgICAgICBpcyByZWxldmFudC5cbiAgICAgICAgPC9saT5cbiAgICAgICAgPGxpICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5pbnB1dF90ZXJtVHlwZV9hbGxvd2VkID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgTm9uZSBvZiB0aGVcbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW14LTFcIj5JbnB1dDwvY29kZT5cbiAgICAgICAgICA8Y29kZSBjbGFzcz1cImlzLW1yLTFcIj50ZXJtLnRlcm1UeXBlPC9jb2RlPlxuICAgICAgICAgIGlzIHJlbGV2YW50LlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXJcbiAgICAgICpuZ0lmPVwibW9kZWwubG9ncyAmJiBtb2RlbC5zdGF0dXMgIT09IExvZ1N0YXR1cy5ub3RSZXF1aXJlZCAmJiBtb2RlbC5zdGF0dXMgIT09IExvZ1N0YXR1cy5za2lwSGllcmFyY2h5XCI+XG4gICAgICA8dWwgY2xhc3M9XCJpcy1wbC0zIGlzLWxpc3Qtc3R5bGUtZGlzY1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgI3Nob3dSdW5PcmNoZXN0cmF0b3I+XG4gICAgICAgICAgPGxpIGNsYXNzPVwiaXMtcnVuLW9yY2hlc3RyYXRvclwiPlxuICAgICAgICAgICAgPHAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5BbGwgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+XG4gICAgICAgICAgICAgIDxwPlNvbWUgb2YgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG5vdCBtZXQgdG8gcnVuIHRoZSBtb2RlbC48L3A+XG4gICAgICAgICAgICAgIDxwPllvdSBjYW4gY2xpY2sgb24gdGhlIG1vZGVsIG5hbWUgb24gdGhlIGxlZnQgdG8gdmlldyB0aGUgZGVidWdnaW5nIGxvZ3MuPC9wPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwubG9ncz8ubG9ncz8uZXJyb3JcIj5cbiAgICAgICAgICAgICAgPHA+VGhlIG1vZGVsIGZhaWxlZCB0byBydW4gZm9yIHRoZSBmb2xsb3dpbmcgcmVhc29uOjwvcD5cbiAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgPGNvZGU+e3sgbW9kZWwubG9ncy5sb2dzLmVycm9yIH19PC9jb2RlPlxuICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxsaVxuICAgICAgICAgIGNsYXNzPVwiaXMtbm8tcnVuLW9yY2hlc3RyYXRvclwiXG4gICAgICAgICAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5PcmNoZXN0cmF0b3IgPT09IGZhbHNlOyBlbHNlIHNob3dSdW5PcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1vZGVsLmxvZ3MucnVuUmVxdWlyZWRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vZGUtdHlwZS1ub3QtYWxsb3dlZFwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5ub2RlX3R5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgICAgICBUaGlzIG1vZGVsIHNob3VsZCBub3QgcnVuIGZvciB7eyBub2RlVHlwZSB8IHBsdXJhbGl6ZTogMCB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNydW5Ob0NvbmZpZz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vdC1lbXB0eVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5pc19lbXB0eSA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgICAgICBUaGUge3sgZGF0YS50eXBlIHx8ICdibGFuayBub2RlJyB9fSB3aXRoIFRlcm1cbiAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJpcy1teC0xXCI+e3sgZGF0YS50ZXJtSWQgfX08L2NvZGU+XG4gICAgICAgICAgICAgIGlzIGFscmVhZHkgcHJlc2VudCBvciBhbHJlYWR5IGFkZGVkIGJ5IGFub3RoZXIgbW9kZWwuXG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc7IGVsc2UgcnVuTm9Db25maWdcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiaXMtcnVuLXN0cmF0ZWd5LXt7IG1vZGVsLmNvbmZpZy5ydW5TdHJhdGVneSB9fVwiIFtuZ1N3aXRjaF09XCJtb2RlbC5jb25maWcucnVuU3RyYXRlZ3lcIj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhbHdheXMnXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9rZXlfaWZfbWlzc2luZydcIj5XZSBvbmx5IGdhcC1maWxsIHRoaXMga2V5IGlmIG5vdCBwcmVzZW50PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9ibGFua19ub2RlX2lmX21pc3NpbmcnXCI+V2Ugb25seSBnYXAtZmlsbCB0aGlzIEJsYW5rIE5vZGUgaWYgbm90IHByZXNlbnQuPC9zcGFuPlxuICAgICAgICAgICAgPC9wPlxuXG4gICAgICAgICAgICA8cCBjbGFzcz1cImlzLW10LTFcIj5cbiAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICBjbGFzcz1cImlzLXJ1bi13aXRoLW1lYXN1cmVkXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgbW9kZWwuY29uZmlnLnJ1bkFyZ3M/LnJ1bk5vbk1lYXN1cmVkICYmIGhhc01ldGhvZFRpZXIoZGF0YS5vcmlnaW5hbCwgRW1pc3Npb25NZXRob2RUaWVyLm1lYXN1cmVkKVxuICAgICAgICAgICAgICAgIFwiPlxuICAgICAgICAgICAgICAgIFRoZVxuICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiaXMtbXgtMVwiPnt7IG1vZGVsLmNvbmZpZy52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICB3YXMgcmVwb3J0ZWQgYXMgbWVhc3VyZWQuXG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9saT5cblxuICAgICAgICA8bGkgKm5nSWY9XCJtb2RlbC5sb2dzPy5yZXBsYWNlTG93ZXJUaWVyICE9PSB1bmRlZmluZWRcIj5cbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIFRoZSByZWNhbGN1bGF0ZWRcbiAgICAgICAgICAgIDxiPm1ldGhvZFRpZXI8L2I+XG4gICAgICAgICAgICB3YXNcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xIGlzLXVuZGVybGluZWRcIiAqbmdJZj1cIiFtb2RlbC5sb2dzLnJlcGxhY2VMb3dlclRpZXJcIj5sb3dlciB0aGFuPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMSBpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VMb3dlclRpZXJcIj5oaWdoZXIgdGhhbiBvciBlcXVhbCB0bzwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICAgIHRoZSBvcmlnaW5hbFxuICAgICAgICAgICAgPGI+bWV0aG9kVGllcjwvYj5cbiAgICAgICAgICAgIC5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGk+XG5cbiAgICAgICAgPGxpIGNsYXNzPVwiaXMtbWVyZ2UtcmVwbGFjZUxvd2VyVGllclwiICpuZ0lmPVwibW9kZWwubG9ncy5yZXBsYWNlTG93ZXJUaWVyXCI+XG4gICAgICAgICAgPHNwYW4+VGhlIHJlY2FsY3VsYXRlZDwvc3Bhbj5cbiAgICAgICAgICA8YiBjbGFzcz1cImlzLXBsLTFcIj57eyBtb2RlbC5jb25maWc/Lm1lcmdlQXJncz8ucmVwbGFjZVRocmVzaG9sZD8uWzBdIHx8ICd2YWx1ZScgfX08L2I+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+d2FzPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdW5kZXJsaW5lZFwiICpuZ0lmPVwiIW1vZGVsLmxvZ3MucmVwbGFjZVRocmVzaG9sZFwiPmxlc3MgdGhhbjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5tb3JlIHRoYW4gb3IgZXF1YWwgdG88L3NwYW4+XG4gICAgICAgICAgICAgIDxiIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLmNvbmZpZy5tZXJnZUFyZ3MucmVwbGFjZVRocmVzaG9sZFsxXSAqIDEwMCB9fSU8L2I+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwuY29uZmlnPy5tZXJnZUFyZ3NcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCIhbW9kZWwubG9ncy5yZXBsYWNlVGhyZXNob2xkXCI+bm90IHN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy11bmRlcmxpbmVkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLnJlcGxhY2VUaHJlc2hvbGRcIj5zdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+ZGlmZmVyZW50IGZyb20gdGhlIG9yaWdpbmFsPC9zcGFuPlxuICAgICAgICAgIDxiIGNsYXNzPVwiaXMtcGwtMVwiPnt7IG1vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzPy5yZXBsYWNlVGhyZXNob2xkPy5bMF0gfHwgJ3ZhbHVlJyB9fS48L2I+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZG9jc0xpbmsgbGV0LW1vZGVsPlxuICA8YSBbaHJlZl09XCJtb2RlbC5hcGlEb2NzUGF0aCB8fCBtb2RlbC5kb2NQYXRoIHx8IG1vZGVsLnBhdGhcIiB0YXJnZXQ9XCJfYmxhbmtcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgPHNwYW4+RG9jczwvc3Bhbj5cbiAgICA8ZmEtaWNvbiBjbGFzcz1cIm1sLTFcIiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIiBzaXplPVwic21cIj48L2ZhLWljb24+XG4gIDwvYT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=