@hestia-earth/ui-components 0.12.2 → 0.12.3

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.
@@ -35,13 +35,15 @@ const logIcon = {
35
35
  [LogStatus.success]: 'check',
36
36
  [LogStatus.error]: 'times',
37
37
  [LogStatus.skipHierarchy]: ['far', 'circle'],
38
- [LogStatus.dataProvided]: 'circle'
38
+ [LogStatus.dataProvided]: 'circle',
39
+ [LogStatus.notRequired]: 'dot-circle'
39
40
  };
40
41
  const logColor = {
41
42
  [LogStatus.success]: 'success',
42
43
  [LogStatus.error]: 'danger',
43
44
  [LogStatus.skipHierarchy]: 'dark',
44
- [LogStatus.dataProvided]: 'dark'
45
+ [LogStatus.dataProvided]: 'dark',
46
+ [LogStatus.notRequired]: 'grey'
45
47
  };
46
48
  const methodIdLabel = (methodId, model) => (methodId
47
49
  ? ({
@@ -174,10 +176,10 @@ export class NodeLogsModelsComponent {
174
176
  }
175
177
  }
176
178
  NodeLogsModelsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: NodeLogsModelsComponent, deps: [{ token: i1.HeNodeService }, { token: i2.HeSearchService }, { token: i3.HeEngineService }], target: i0.ɵɵFactoryTarget.Component });
177
- NodeLogsModelsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" 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\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\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\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [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]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</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]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></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 *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></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 >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</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>-</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 >\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 *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</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\"\n (click)=\"showLegend = !showLegend\"\n >\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 type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\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-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\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>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black 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 class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [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\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [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-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *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 <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\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 tr.has-sub-rows td{border-bottom-style:dotted}::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}\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", "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", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "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", "nbRows", "small", "height", "width"] }, { 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" }] });
179
+ NodeLogsModelsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: NodeLogsModelsComponent, selector: "he-node-logs-models", inputs: { node: "node", nodeKey: "nodeKey", originalValues: "originalValues", recalculatedValues: "recalculatedValues", terms: "terms", filterTermTypes: "filterTermTypes", logsKey: "logsKey" }, ngImport: i0, template: "<div class=\"px-3 pb-3\">\n <div class=\"has-text-right mb-2\" *ngIf=\"!isExternal\">\n <a class=\"is-size-7\" *ngIf=\"logsUrl\" [href]=\"logsUrl\" target=\"_blank\">\n <fa-icon icon=\"external-link-alt\"></fa-icon>\n <span class=\"pl-2\">Open Full Logs</span>\n </a>\n </div>\n\n <he-data-table class=\"mb-1 is-small\" [small]=\"true\" [nbRows]=\"rowsCount\" 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\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\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\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [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]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</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]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></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 *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></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 >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</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>-</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 >\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 *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</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\"\n (click)=\"showLegend = !showLegend\"\n >\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 type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\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-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\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>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black 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 class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [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\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [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-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *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 <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\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}\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", "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", "openDelay", "closeDelay"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { kind: "component", type: i7.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "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", "nbRows", "small", "height", "width"] }, { 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" }] });
178
180
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: NodeLogsModelsComponent, decorators: [{
179
181
  type: Component,
180
- 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\" [nbRows]=\"rowsCount\" 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\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\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\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [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]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</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]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></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 *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></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 >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</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>-</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 >\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 *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</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\"\n (click)=\"showLegend = !showLegend\"\n >\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 type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\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-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\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>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black 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 class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [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\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [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-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *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 <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\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 tr.has-sub-rows td{border-bottom-style:dotted}::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}\n"] }]
182
+ 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\" [nbRows]=\"rowsCount\" 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\">\n <div class=\"control is-expanded has-icons-right\">\n <input class=\"input search-input is-small\"\n [(ngModel)]=\"term\" name=\"term\"\n placeholder=\"Filter by name\"\n [ngbTypeahead]=\"suggestTerm\"\n [focusFirst]=\"false\"\n (selectItem)=\"filterResults()\"\n >\n <a class=\"icon is-small is-right\"\n [class.is-hidden]=\"!term\"\n (click)=\"term = ''; filterResults();\"\n >\n <fa-icon icon=\"times\"></fa-icon>\n </a>\n </div>\n </div>\n </th>\n <th>Units</th>\n <th>Original</th>\n <th>Recalculated</th>\n <th>Difference</th>\n <th *ngFor=\"let c of methodModelsCount | times; let i = index\">({{i + 1}})</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngIf=\"loading\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"!loading && blankNodes.length === 0\">\n <td class=\"has-text-centered\" colspan=\"6\">\n <span>No data</span>\n </td>\n </tr>\n <ng-container *ngFor=\"let blankNode of blankNodes; trackBy: trackByBlankNode\">\n <tr [class.has-sub-rows]=\"blankNode.canOpen\">\n <td class=\"width-auto has-border-right\" [attr.title]=\"blankNode.term.name\">\n <a class=\"is-inline-block is-align-top pr-2 open-node\"\n (click)=\"blankNode.isOpen = !blankNode.isOpen\"\n *ngIf=\"blankNode.canOpen\"\n >\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\" [node]=\"blankNode.term\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"blankNode.term.name | compound\"></span>\n </he-node-link>\n </td>\n <td>\n <span [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]\">{{blankNode.originalValueByMethodId[model.methodId] | precision:3 | default:'-'}}</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]\">{{blankNode.recalculatedValueByMethodId[model.methodId] | precision:3 | default:'-'}}</div>\n </ng-container>\n </ng-container>\n </td>\n <td class=\"is-nowrap\">\n <ng-template #defaultDeltaValue>\n <he-blank-node-value-delta *ngIf=\"blankNode.original.length && blankNode.isRecalculated; else noValue\"\n [value]=\"blankNode.recalculatedValue\"\n [originalValue]=\"blankNode.originalValue\"\n ></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 *ngIf=\"blankNode.originalValueByMethodId[model.methodId] !== null && blankNode.recalculatedValueByMethodId[model.methodId] !== null; else noValue\"\n [value]=\"blankNode.recalculatedValueByMethodId[model.methodId]\"\n [originalValue]=\"blankNode.originalValueByMethodId[model.methodId]\"\n ></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 >\n <td class=\"width-auto has-border-right\">\n <span class=\"is-inline-block is-align-top pl-3 pr-1 field-node\">Field:</span>\n\n <a class=\"is-inline-block\" *ngIf=\"blankNode.type\"\n [href]=\"baseUrl + '/schema/' + blankNode.type + '#' + subValue.key\" target=\"_blank\" [title]=\"subValue.key\"\n >\n <span class=\"is-nowrap has-text-ellipsis\">{{subValue.key}}</span>\n </a>\n <span class=\"is-inline-block is-align-top\" *ngIf=\"!blankNode.type\">{{subValue.key}}</span>\n </td>\n <td></td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</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>-</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 >\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 *ngSwitchDefault class=\"is-block pl-4\" [node]=\"termById(subValue.id)\" [attr.title]=\"termById(subValue.id).name\">\n <span class=\"is-nowrap has-text-ellipsis\" [innerHtml]=\"termById(subValue.id).name | compound\"></span>\n </he-node-link>\n </ng-container>\n </ng-container>\n </td>\n <td>\n <span *ngIf=\"subValue.showUnits\" [innerHtml]=\"blankNode.term?.units | compound\"></span>\n </td>\n <td>\n <span *ngIf=\"subValue.originalValue !== null; else noValue\">{{subValue.originalValue | precision:3 | default:'-'}}</span>\n </td>\n <td>\n <span *ngIf=\"subValue.isRecalculated; else notRecalculated\">\n {{subValue.recalculatedValue | precision:3 | default:'-'}}\n </span>\n </td>\n <td>-</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\"\n (click)=\"showLegend = !showLegend\"\n >\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 type=\"checkbox\" class=\"selector\"\n [(ngModel)]=\"onlyRequired\"\n (change)=\"filterResults()\"\n [disabled]=\"!!term\"\n >\n <span class=\"ml-2\">Show only {{filteredType | pluralize}} included in the default Hestia system boundary</span>\n </label>\n </div>\n </div>\n </div>\n</div>\n\n<ng-template #blankNodeModels let-data=\"data\">\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-template>\n\n<ng-template #blankNodeModel let-model=\"model\" let-data=\"data\">\n <span\n [class.trigger-popover]=\"model.showLogs\"\n [ngbPopover]=\"logDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"p.isOpen() ? p.close() : (model.showLogs ? p.open({ logs: model.logs }) : null)\"\n >\n <span class=\"is-capitalized\">{{methodName(model)}}</span>\n <span class=\"pl-1\" *ngIf=\"model.logs?.methodTier || model.model?.methodTier\">[{{model.logs?.methodTier || model.model?.methodTier}}]</span>\n\n <span class=\"pl-1 has-text-{{logColor[model.status]}} trigger-popover\"\n [ngbPopover]=\"logStatusDetails\" [autoClose]=\"'outside'\" popoverClass=\"is-narrow\"\n triggers=\"manual\" #p1=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"$event.stopPropagation(); p1.isOpen() ? p1.close() : p1.open({ model, data })\"\n >\n <fa-icon [icon]=\"logIcon[model.status]\"></fa-icon>\n </span>\n\n <span class=\"pl-1\" *ngIf=\"model.model\">\n (<ng-container *ngTemplateOutlet=\"docsLink; context: {$implicit: model.model}\"></ng-container>)\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>\n <span>Filename</span>\n </th>\n <th>\n <span>Column Title</span>\n </th>\n <th>\n <span>Row (term.id)</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"has-background-black 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 class=\"is-inline-block is-align-middle\" linkClass=\"is-dark\" [node]=\"linkedNode\" [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\">\n <span class=\"is-inline-block is-align-middle\" [ngSwitch]=\"key\">\n <ng-container *ngSwitchDefault>{{key | keyToLabel}}</ng-container>\n\n <ng-container *ngSwitchCase=\"'node_type_allowed'\">Is the current <code>Node</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'siteType_allowed'\">Is the current <code>siteType</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_id_allowed'\">Is the current primary product <code>@id</code> allowed to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'primary_product_termType_allowed'\">Is the current primary product <code>termType</code> allowed to run this model</ng-container>\n\n <ng-container *ngSwitchCase=\"'geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'contains_geospatial_data'\">Has geospatial data necessary to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'current_size'\">Current polygon area</ng-container>\n <ng-container *ngSwitchCase=\"'max_area_size'\">Maximum polygon area to run this model</ng-container>\n <ng-container *ngSwitchCase=\"'below_max_area_size'\">Polygon below the maximum area</ng-container>\n <ng-container *ngSwitchCase=\"'region_factor'\">Factor from region lookup</ng-container>\n\n <ng-container *ngSwitchCase=\"'pesticides_complete'\">Pesticide data are <code>complete</code></ng-container>\n <ng-container *ngSwitchCase=\"'has_pesticides_inputs'\">Cycle contains <code>pesticideAI</code> Inputs</ng-container>\n <ng-container *ngSwitchCase=\"'all_pesticideAI_have_lookup_value'\">All <code>pesticideAI</code> Inputs have a lookup value</ng-container>\n\n <ng-container *ngSwitchCase=\"'has_crop_residue_burnt'\"><code>aboveGroundCropResidueBurnt</code> is present as Product</ng-container>\n\n <ng-container *ngSwitchCase=\"'liquid_slurry_sludge_P'\">Liquid, Slurry, and Sludge P</ng-container>\n </span>\n <he-clipboard class=\"is-inline-block is-align-middle\" clipboardClass=\"is-size-7 is-p-1\" [icon]=\"['far', 'clone']\" [value]=\"key\" [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-template #showRunOrchestrator>\n <div class=\"is-run-orchestrator\">\n <p *ngIf=\"model.logs?.shouldRun\">All the requirements were met to run the model.</p>\n <p *ngIf=\"!model.logs?.shouldRun\">\n Some of the requirements were not met to run the model.\n You can click on the model name on the left to view the debugging logs.\n </p>\n <div *ngIf=\"model.logs?.logs?.error\">\n <p>The model failed to run for the following reason:</p>\n <p><code>{{model.logs.logs.error}}</code></p>\n </div>\n </div>\n </ng-template>\n\n <div class=\"is-no-run-orchestrator\" *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 <code>{{data.termId}}</code> is already present or already added by another model.\n </span>\n </ng-template>\n\n <ng-container *ngIf=\"model.config; else runNoConfig\">\n <div class=\"is-run-strategy-{{model.config.runStrategy}}\" [ngSwitch]=\"model.config.runStrategy\">\n <span *ngSwitchCase=\"'always'\"></span>\n <span *ngSwitchCase=\"'add_key_if_missing'\">\n We only gap-fill this key if not present\n </span>\n <span *ngSwitchCase=\"'add_blank_node_if_missing'\">\n We only gap-fill this Blank Node if not present.\n </span>\n\n <span class=\"is-run-with-measured\" *ngIf=\"model.config.runArgs?.runNonMeasured && hasMethodTier(data.original, EmissionMethodTier.measured)\">\n The <code>{{model.config.value}}</code> was already reported as measured.\n </span>\n </div>\n </ng-container>\n </div>\n\n <div class=\"is-no-merge-orchestrator\" *ngIf=\"model.logs?.shouldMerge === false\">\n <p class=\"is-merge-replaceThreshold\" *ngIf=\"model.logs.logs?.replaceThreshold\">\n <span>The</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}</span>\n <span class=\"is-pl-1\">from this model was</span>\n <span class=\"is-pl-1\">\n <ng-container *ngIf=\"model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">less than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">more than</span>\n <span class=\"is-pl-1\">{{model.config.mergeArgs.replaceThreshold[1] * 100}}%</span>\n </ng-container>\n <ng-container *ngIf=\"!model.config.mergeArgs\">\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'False'\">not sufficiently</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceThreshold === 'True'\">sufficiently</span>\n </ng-container>\n </span>\n <span class=\"is-pl-1\">different from the original</span>\n <span class=\"is-pl-1\">{{model.config?.mergeArgs?.replaceThreshold?.[0] || 'value'}}.</span>\n </p>\n </div>\n <p class=\"is-merge-replaceLowerTier\" *ngIf=\"model.logs.logs?.replaceLowerTier\">\n <span>The model <code>methodTier</code> was</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'False'\">higher than</span>\n <span class=\"is-pl-1\" *ngIf=\"model.logs.logs.replaceLowerTier === 'True'\">lower than</span>\n <span class=\"is-pl-1\">the original <code>methodTier</code></span>\n </p>\n </ng-container>\n</ng-template>\n\n<ng-template #docsLink let-model>\n <a [href]=\"model.apiDocsPath || model.docPath || model.path\" target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n >\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}\n"] }]
181
183
  }], ctorParameters: function () { return [{ type: i1.HeNodeService }, { type: i2.HeSearchService }, { type: i3.HeEngineService }]; }, propDecorators: { node: [{
182
184
  type: Input
183
185
  }], nodeKey: [{
@@ -193,4 +195,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
193
195
  }], logsKey: [{
194
196
  type: Input
195
197
  }] } });
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQVMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGtCQUFrQixFQUF1QixRQUFRLEVBQVEsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0csT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQ2lDLFNBQVMsRUFBMkIsZ0JBQWdCLEVBQUUsZUFBZSxFQUMzRyxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDeEMsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0RixPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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LEtBQUssVUFBVSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVNLFFBQVEsQ0FBQyxFQUFVO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSTtZQUMzQixPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUk7WUFDdEIsS0FBSyxFQUFFLEVBQUU7WUFDVCxJQUFJLEVBQUUsYUFBYSxDQUFDLEVBQUUsQ0FBQztTQUNULENBQUM7SUFDbkIsQ0FBQzs7b0hBL0tVLHVCQUF1Qjt3R0FBdkIsdUJBQXVCLDZQQ3BGcEMsOGhyQkFtY0E7MkZEL1dhLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSxxQkFBcUI7Z0tBZ0J2QixJQUFJO3NCQURYLEtBQUs7Z0JBR0UsT0FBTztzQkFEZCxLQUFLO2dCQUdFLGNBQWM7c0JBRHJCLEtBQUs7Z0JBR0Usa0JBQWtCO3NCQUR6QixLQUFLO2dCQUdFLEtBQUs7c0JBRFosS0FBSztnQkFHRSxlQUFlO3NCQUR0QixLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZnJvbSwgbWVyZ2UsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdCwgZmlsdGVyLCByZWR1Y2UsIHRvQXJyYXksIG1hcCwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHN3aXRjaE1hcCwgbWVyZ2VNYXAsIG1lcmdlQWxsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRW1pc3Npb25NZXRob2RUaWVyLCBJVGVybUpTT05MRCwgSlNPTkxELCBOb2RlVHlwZSwgVGVybSwgVGVybVRlcm1UeXBlIH0gZnJvbSAnQGhlc3RpYS1lYXJ0aC9zY2hlbWEnO1xuaW1wb3J0IHsga2V5VG9MYWJlbCB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMnO1xuaW1wb3J0IHsgcHJvcGVydHlWYWx1ZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvdXRpbHMvZGlzdC90ZXJtJztcblxuaW1wb3J0IHtcbiAgSUJsYW5rTm9kZUxvZ1N1YlZhbHVlLCBJQmxhbmtOb2RlTG9nLCBMb2dTdGF0dXMsIElDb25maWdNb2RlbCwgYmxhbmtOb2RlLCBncm91cExvZ3NCeU1vZGVsLCBncm91cExvZ3NCeVRlcm0sXG4gIG1vZGVsQ291bnQsIGNvbXB1dGVUZXJtcywgbG9nVmFsdWVBcnJheVxufSBmcm9tICcuL25vZGUtbG9ncy1tb2RlbHMubW9kZWwnO1xuaW1wb3J0IHsgSUpTT05Ob2RlLCBIZU5vZGVTZXJ2aWNlIH0gZnJvbSAnLi4vbm9kZS5zZXJ2aWNlJztcbmltcG9ydCB7IEhlRW5naW5lU2VydmljZSwgSU1vZGVsIH0gZnJvbSAnLi4vLi4vZW5naW5lL2VuZ2luZS5zZXJ2aWNlJztcbmltcG9ydCB7IG1hdGNoRXhhY3RRdWVyeSwgbWF0Y2hUZXJtVHlwZSwgbWF0Y2hUeXBlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5tb2RlbCc7XG5pbXBvcnQgeyBIZVNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgYmFzZVVybCwgaXNFeHRlcm5hbCB9IGZyb20gJy4uLy4uL2NvbW1vbi91dGlscyc7XG5pbXBvcnQgeyB0ZXJtVHlwZUxhYmVsIH0gZnJvbSAnLi4vLi4vdGVybXMvdGVybXMubW9kZWwnO1xuXG5jb25zdCBub2RlVHlwZXNMb3dlckNhc2UgPSBPYmplY3QudmFsdWVzKE5vZGVUeXBlKS5tYXAodiA9PiB2LnRvTG93ZXJDYXNlKCkpO1xuXG5jb25zdCBsb2dJY29uOiB7XG4gIFtzdGF0dXMgaW4gTG9nU3RhdHVzXT86IHN0cmluZyB8IHN0cmluZ1tdO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ2NoZWNrJyxcbiAgW0xvZ1N0YXR1cy5lcnJvcl06ICd0aW1lcycsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06IFsnZmFyJywgJ2NpcmNsZSddLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdjaXJjbGUnXG59O1xuXG5jb25zdCBsb2dDb2xvcjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmc7XG59ID0ge1xuICBbTG9nU3RhdHVzLnN1Y2Nlc3NdOiAnc3VjY2VzcycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAnZGFuZ2VyJyxcbiAgW0xvZ1N0YXR1cy5za2lwSGllcmFyY2h5XTogJ2RhcmsnLFxuICBbTG9nU3RhdHVzLmRhdGFQcm92aWRlZF06ICdkYXJrJ1xufTtcblxuY29uc3QgbWV0aG9kSWRMYWJlbCA9IChtZXRob2RJZDogc3RyaW5nLCBtb2RlbD86IElNb2RlbCkgPT5cbiAgKFxuICAgIG1ldGhvZElkXG4gICAgICA/ICh7XG4gICAgICAgICdjeWNsZS90cmFuc2Zvcm1hdGlvbic6ICdEYXRhIEZyb20gVHJhbnNmb3JtYXRpb24nLFxuICAgICAgICBpbXBhY3RfYXNzZXNzbWVudDogJ0RhdGEgRnJvbSBDeWNsZSdcbiAgICAgIH0pW21ldGhvZElkXVxuICAgICAgOiAnJ1xuICApIHx8IChcbiAgICBtZXRob2RJZC5pbmNsdWRlcygnLycpID8gbWV0aG9kSWQuc3BsaXQoJy8nKVswXSA6IGtleVRvTGFiZWwobWV0aG9kSWQpXG4gICk7XG5cbmNvbnN0IGdldE1vZGVsc0F0ID0gKGxvZzogSUJsYW5rTm9kZUxvZ1N1YlZhbHVlIHwgSUJsYW5rTm9kZUxvZywgaW5kZXg6IG51bWJlcikgPT5cbiAgKCdtb2RlbHNJblN1YlZhbHVlcycgaW4gbG9nID8gIWxvZy5tb2RlbHNJblN1YlZhbHVlcyB8fCAhbG9nLmlzT3BlbiA6IHRydWUpICYmIGxvZy5jb25maWdNb2RlbHNbaW5kZXhdO1xuXG5jb25zdCByZXF1aXJlbWVudEtleXMgPSAocmVxdWlyZW1lbnRzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSA9PlxuICBPYmplY3Qua2V5cyhyZXF1aXJlbWVudHMpLmZpbHRlcihrID0+ICFub2RlVHlwZXNMb3dlckNhc2UuaW5jbHVkZXMoaykpO1xuXG5jb25zdCByZXF1aXJlbWVudENvbG9yID0gKHZhbHVlOiBhbnkpID0+ICF2YWx1ZSB8fCBbJ05vbmUnLCAnRmFsc2UnLCAnMCcsICcwLjAnXS5pbmNsdWRlcyh2YWx1ZSkgPyAnZGFuZ2VyJyA6ICd3aGl0ZSc7XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5OiB7XG4gIFtrZXk6IHN0cmluZ106ICh2YWx1ZTogc3RyaW5nKSA9PiBQYXJ0aWFsPEpTT05MRDxOb2RlVHlwZT4+O1xufSA9IHtcbiAgcmVsYXRlZF9jeWNsZXM6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBjeWNsZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5DeWNsZSwgJ0BpZCc6IHYgfSksXG4gIGltcGFjdF9hc3Nlc3NtZW50X2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkltcGFjdEFzc2Vzc21lbnQsICdAaWQnOiB2IH0pLFxuICBzaXRlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNpdGUsICdAaWQnOiB2IH0pLFxuICBzb3VyY2VfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuU291cmNlLCAnQGlkJzogdiB9KVxufTtcblxuY29uc3QgcmVxdWlyZW1lbnRMaW5rZWROb2RlID0gKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PlxuICBrZXkgaW4gcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXkgJiZcbiAgcmVxdWlyZW1lbnRMaW5rZWROb2RlQnlLZXlba2V5XSh2YWx1ZSk7XG5cbmNvbnN0IGlzU3lzdGVtQm91bmRhcnkgPSAoXG4gIHsgaXNSZWNhbGN1bGF0ZWQsIGlzUmVxdWlyZWQgfTogUGljazxJQmxhbmtOb2RlTG9nIHwgSUJsYW5rTm9kZUxvZ1N1YlZhbHVlLCAnaXNSZWNhbGN1bGF0ZWQnIHwgJ2lzUmVxdWlyZWQnPlxuKSA9PiBbXG4gIGlzUmVjYWxjdWxhdGVkLFxuICBpc1JlcXVpcmVkXG5dLnNvbWUoQm9vbGVhbik7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLW5vZGUtbG9ncy1tb2RlbHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vbm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOb2RlTG9nc01vZGVsc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgbG9nczogc3RyaW5nO1xuICBwcml2YXRlIGFsbFRlcm1zOiAoVGVybSB8IElUZXJtSlNPTkxEKVtdID0gW107XG4gIHByaXZhdGUgYWxsQmxhbmtOb2RlczogSUJsYW5rTm9kZUxvZ1tdID0gW107XG4gIHByaXZhdGUgbWV0aG9kc0J5SWQ/OiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfTtcbiAgcHJpdmF0ZSB0ZXJtc0J5SWQ6IHtcbiAgICBbaWQ6IHN0cmluZ106IElUZXJtSlNPTkxEO1xuICB9ID0ge307XG5cbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlPzogSUpTT05Ob2RlO1xuICBASW5wdXQoKVxuICBwcml2YXRlIG5vZGVLZXk/OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgb3JpZ2luYWxWYWx1ZXM6IGJsYW5rTm9kZVtdID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgcmVjYWxjdWxhdGVkVmFsdWVzOiBibGFua05vZGVbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHRlcm1zOiBJVGVybUpTT05MRFtdID0gW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgZmlsdGVyVGVybVR5cGVzPzogVGVybVRlcm1UeXBlW107XG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbG9nc0tleT86IHN0cmluZztcblxuICBwdWJsaWMgbG9nc1VybD86IHN0cmluZztcbiAgcHVibGljIGJhc2VVcmwgPSBiYXNlVXJsKCk7XG4gIHB1YmxpYyBpc0V4dGVybmFsID0gaXNFeHRlcm5hbCgpO1xuICBwdWJsaWMgRW1pc3Npb25NZXRob2RUaWVyID0gRW1pc3Npb25NZXRob2RUaWVyO1xuICBwdWJsaWMgTG9nU3RhdHVzID0gTG9nU3RhdHVzO1xuICBwdWJsaWMgbG9nSWNvbiA9IGxvZ0ljb247XG4gIHB1YmxpYyBsb2dDb2xvciA9IGxvZ0NvbG9yO1xuICBwdWJsaWMgcHJvcGVydHlWYWx1ZSA9IHByb3BlcnR5VmFsdWU7XG4gIHB1YmxpYyBnZXRNb2RlbHNBdCA9IGdldE1vZGVsc0F0O1xuICBwdWJsaWMgcmVxdWlyZW1lbnRLZXlzID0gcmVxdWlyZW1lbnRLZXlzO1xuICBwdWJsaWMgcmVxdWlyZW1lbnRDb2xvciA9IHJlcXVpcmVtZW50Q29sb3I7XG4gIHB1YmxpYyBsb2dWYWx1ZUFycmF5ID0gbG9nVmFsdWVBcnJheTtcbiAgcHVibGljIHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IHJlcXVpcmVtZW50TGlua2VkTm9kZTtcbiAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xuICBwdWJsaWMgbm9kZVR5cGU6IE5vZGVUeXBlO1xuICBwdWJsaWMgYmxhbmtOb2RlczogSUJsYW5rTm9kZUxvZ1tdID0gW107XG4gIHB1YmxpYyBtZXRob2RNb2RlbHNDb3VudCA9IDA7XG4gIHB1YmxpYyByb3dzQ291bnQgPSAwO1xuICBwdWJsaWMgb25seVJlcXVpcmVkID0gdHJ1ZTtcbiAgcHVibGljIHNob3dMZWdlbmQgPSB0cnVlO1xuXG4gIHB1YmxpYyB0ZXJtPzogc3RyaW5nO1xuICBwdWJsaWMgc3VnZ2VzdFRlcm0gPSAodGV4dCQ6IE9ic2VydmFibGU8c3RyaW5nPikgPT5cbiAgICB0ZXh0JC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHN3aXRjaE1hcCh2ID0+IHRoaXMuc3VnZ2VzdEJ5VGVybSh2KSksXG4gICAgKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBIZU5vZGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2VhcmNoU2VydmljZTogSGVTZWFyY2hTZXJ2aWNlLFxuICAgIHByaXZhdGUgZW5naW5lU2VydmljZTogSGVFbmdpbmVTZXJ2aWNlXG4gICkgeyB9XG5cbiAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5sb2dzVXJsID0gdGhpcy5ub2RlU2VydmljZS5ub2RlTG9nc1VybCh0aGlzLm5vZGUpO1xuICAgIC8vIHNhdmUgYXMgbG9jYWwgdmFyaWFibGUgdG8gYXZvaWQgXCJyZXNlcnZlZCB5aWVsZCBrZXl3b3JkXCIgaXNzdWVcbiAgICB0aGlzLmxvZ3MgPSBhd2FpdCB0aGlzLmdldExvZ3MoKTtcbiAgICBjb25zdCBncm91cGVkTG9ncyA9IGdyb3VwTG9nc0J5TW9kZWwodGhpcy5sb2dzKTtcbiAgICBjb25zdCBsb2dzID0gdGhpcy5sb2dzS2V5ID8gZ3JvdXBlZExvZ3NbdGhpcy5sb2dzS2V5XSA6IGdyb3VwZWRMb2dzO1xuXG4gICAgdGhpcy5ub2RlVHlwZSA9IHRoaXMubm9kZVsnQHR5cGUnXSB8fCB0aGlzLm5vZGUudHlwZTtcbiAgICBjb25zdCBjb25maWcgPSBhd2FpdCB0aGlzLmVuZ2luZVNlcnZpY2Uub2NoZXN0cmF0b3JDb25maWcodGhpcy5ub2RlVHlwZSwgdGhpcy5ub2RlWydAaWQnXSB8fCB0aGlzLm5vZGUuaWQpO1xuXG4gICAgY29uc3QgbW9kZWxzID0gYXdhaXQgdGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICBib29sOiB7XG4gICAgICAgIG11c3Q6IFtcbiAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSksXG4gICAgICAgICAgbWF0Y2hUZXJtVHlwZShUZXJtVGVybVR5cGUubW9kZWwpXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubWV0aG9kc0J5SWQgPSBhd2FpdCBmcm9tKG1vZGVscykucGlwZShcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICBkaXN0aW5jdCh2ID0+IHZbJ0BpZCddKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIC8vIGZyb20gYG1vZGVsLWxpbmtzLmpzb25gIGZpbGVcbiAgICBjb25zdCBlbmdpbmVNb2RlbHMgPSBhd2FpdCB0aGlzLmVuZ2luZVNlcnZpY2UubW9kZWxzKCk7XG5cbiAgICB0aGlzLmFsbFRlcm1zID0gYXdhaXQgY29tcHV0ZVRlcm1zKHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLnRlcm1zLCB0aGlzLmZpbHRlclRlcm1UeXBlcyk7XG5cbiAgICB0aGlzLmFsbEJsYW5rTm9kZXMgPSB0aGlzLmFsbFRlcm1zLmZsYXRNYXAoXG4gICAgICBncm91cExvZ3NCeVRlcm0odGhpcy5ub2RlVHlwZSwgbG9ncywgZW5naW5lTW9kZWxzLCBjb25maWcsIHRoaXMub3JpZ2luYWxWYWx1ZXMsIHRoaXMucmVjYWxjdWxhdGVkVmFsdWVzLCB0aGlzLm5vZGVLZXkpXG4gICAgKTtcbiAgICB0aGlzLm1ldGhvZE1vZGVsc0NvdW50ID0gbW9kZWxDb3VudCh0aGlzLmFsbEJsYW5rTm9kZXMpO1xuICAgIHRoaXMucm93c0NvdW50ID0gdGhpcy5hbGxCbGFua05vZGVzLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIDEgKyBjdXJyLnN1YlZhbHVlcy5sZW5ndGggKyBjdXJyLmtleXMubGVuZ3RoLCAwKTtcblxuICAgIHRoaXMudGVybXNCeUlkID0gYXdhaXQgb2YodGhpcy5hbGxCbGFua05vZGVzKS5waXBlKFxuICAgICAgbWVyZ2VNYXAodiA9PiB2LmZsYXRNYXAodnYgPT4gdnYuc3ViVmFsdWVzKSksXG4gICAgICBtYXAodiA9PiB2LmlkKSxcbiAgICAgIGRpc3RpbmN0KCksXG4gICAgICB0b0FycmF5KCksXG4gICAgICBtZXJnZU1hcChpZHMgPT4gZnJvbSh0aGlzLnNlYXJjaFRlcm1zKHtcbiAgICAgICAgYm9vbDoge1xuICAgICAgICAgIG11c3Q6IFtcbiAgICAgICAgICAgIG1hdGNoVHlwZShOb2RlVHlwZS5UZXJtKVxuICAgICAgICAgIF0sXG4gICAgICAgICAgc2hvdWxkOiBpZHMubWFwKGlkID0+IG1hdGNoRXhhY3RRdWVyeSgnQGlkJywgaWQpKSxcbiAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICB9XG4gICAgICB9KSkpLFxuICAgICAgbWVyZ2VBbGwoKSxcbiAgICAgIHJlZHVjZSgocHJldiwgY3VycikgPT4gKHsgLi4ucHJldiwgW2N1cnJbJ0BpZCddXTogY3VyciB9KSwge30pXG4gICAgKS50b1Byb21pc2UoKTtcblxuICAgIHRoaXMuZmlsdGVyUmVzdWx0cygpO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGdldExvZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZVNlcnZpY2UuZ2V0TG9nKHRoaXMubm9kZSkudG9Qcm9taXNlKCk7XG4gIH1cblxuICBwcml2YXRlIHN1Z2dlc3RCeVRlcm0odGVybTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGZyb20odGhpcy5hbGxUZXJtcykucGlwZShcbiAgICAgIG1hcCh2ID0+IHYubmFtZSksXG4gICAgICBmaWx0ZXIodiA9PiB2LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybS50b0xvd2VyQ2FzZSgpKSksXG4gICAgICB0b0FycmF5KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZWFyY2hUZXJtcyhxdWVyeTogYW55KSB7XG4gICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICBmaWVsZHM6IFsnQHR5cGUnLCAnQGlkJywgJ25hbWUnXSxcbiAgICAgIGxpbWl0OiAxMDAwMCxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwdWJsaWMgdHJhY2tCeUJsYW5rTm9kZShfaW5kZXg6IG51bWJlciwgbm9kZTogSUJsYW5rTm9kZUxvZykge1xuICAgIHJldHVybiBub2RlLnRlcm1JZDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZmlsdGVyZWRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRlcm1UeXBlcz8ubWFwKHRlcm1UeXBlTGFiZWwpLmpvaW4oJyAmICcpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlclJlc3VsdHMoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmJsYW5rTm9kZXMgPSB0aGlzLmFsbEJsYW5rTm9kZXMuZmlsdGVyKCh7IHRlcm06IHsgbmFtZSB9LCBzdWJWYWx1ZXMsIC4uLmxvZyB9KSA9PlxuICAgICAgICB0aGlzLnRlcm1cbiAgICAgICAgICA/IG5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLnRlcm0udG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICA6IChcbiAgICAgICAgICAgICF0aGlzLmZpbHRlclRlcm1UeXBlcz8ubGVuZ3RoIHx8XG4gICAgICAgICAgICAhdGhpcy5vbmx5UmVxdWlyZWQgfHwgaXNTeXN0ZW1Cb3VuZGFyeShsb2cpIHx8IHN1YlZhbHVlcy5zb21lKGlzU3lzdGVtQm91bmRhcnkpXG4gICAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBtZXRob2ROYW1lKHsgbWV0aG9kSWQsIG1vZGVsIH06IElDb25maWdNb2RlbCkge1xuICAgIHJldHVybiB0aGlzLm1ldGhvZHNCeUlkW21ldGhvZElkXT8ubmFtZSB8fCBtZXRob2RJZExhYmVsKG1ldGhvZElkLCBtb2RlbCk7XG4gIH1cblxuICBwdWJsaWMgaGFzTWV0aG9kVGllcih2YWx1ZXM6IGJsYW5rTm9kZVtdLCBtZXRob2RUaWVyOiBFbWlzc2lvbk1ldGhvZFRpZXIpIHtcbiAgICByZXR1cm4gdmFsdWVzLnNvbWUodiA9PiAnbWV0aG9kVGllcicgaW4gdiAmJiB2Lm1ldGhvZFRpZXIgPT09IG1ldGhvZFRpZXIpO1xuICB9XG5cbiAgcHVibGljIHRlcm1CeUlkKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50ZXJtc0J5SWRbaWRdIHx8IHtcbiAgICAgICdAdHlwZSc6IE5vZGVUeXBlLlRlcm0sXG4gICAgICAnQGlkJzogaWQsXG4gICAgICBuYW1lOiB0ZXJtVHlwZUxhYmVsKGlkKVxuICAgIH0gYXMgSVRlcm1KU09OTEQ7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweC0zIHBiLTNcIj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LXJpZ2h0IG1iLTJcIiAqbmdJZj1cIiFpc0V4dGVybmFsXCI+XG4gICAgPGEgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cImxvZ3NVcmxcIiBbaHJlZl09XCJsb2dzVXJsXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICA8ZmEtaWNvbiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIj48L2ZhLWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cInBsLTJcIj5PcGVuIEZ1bGwgTG9nczwvc3Bhbj5cbiAgICA8L2E+XG4gIDwvZGl2PlxuXG4gIDxoZS1kYXRhLXRhYmxlIGNsYXNzPVwibWItMSBpcy1zbWFsbFwiIFtzbWFsbF09XCJ0cnVlXCIgW25iUm93c109XCJyb3dzQ291bnRcIiBtYXhIZWlnaHQ9XCIzMjBcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1mdWxsd2lkdGggaXMtbmFycm93IGlzLXN0cmlwZWRcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250cm9sIGlzLWV4cGFuZGVkIGhhcy1pY29ucy1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlucHV0IHNlYXJjaC1pbnB1dCBpcy1zbWFsbFwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRlcm1cIiBuYW1lPVwidGVybVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkZpbHRlciBieSBuYW1lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ2JUeXBlYWhlYWRdPVwic3VnZ2VzdFRlcm1cIlxuICAgICAgICAgICAgICAgICAgW2ZvY3VzRmlyc3RdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwiZmlsdGVyUmVzdWx0cygpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJpY29uIGlzLXNtYWxsIGlzLXJpZ2h0XCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXRlcm1cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRlcm0gPSAnJzsgZmlsdGVyUmVzdWx0cygpO1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cInRpbWVzXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5Vbml0czwvdGg+XG4gICAgICAgICAgPHRoPk9yaWdpbmFsPC90aD5cbiAgICAgICAgICA8dGg+UmVjYWxjdWxhdGVkPC90aD5cbiAgICAgICAgICA8dGg+RGlmZmVyZW5jZTwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj4oe3tpICsgMX19KTwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3RoZWFkPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgICAgPHRkIGNsYXNzPVwiaGFzLXRleHQtY2VudGVyZWRcIiBjb2xzcGFuPVwiNlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJzcGlubmVyXCIgW3B1bHNlXT1cInRydWVcIiBzaXplPVwibGdcIj48L2ZhLWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZyAmJiBibGFua05vZGVzLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxzcGFuPk5vIGRhdGE8L3NwYW4+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYmxhbmtOb2RlIG9mIGJsYW5rTm9kZXM7IHRyYWNrQnk6IHRyYWNrQnlCbGFua05vZGVcIj5cbiAgICAgICAgICA8dHIgW2NsYXNzLmhhcy1zdWItcm93c109XCJibGFua05vZGUuY2FuT3BlblwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCIgW2F0dHIudGl0bGVdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMiBvcGVuLW5vZGVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJibGFua05vZGUuaXNPcGVuID0gIWJsYW5rTm9kZS5pc09wZW5cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiYmxhbmtOb2RlLmNhbk9wZW5cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgW25vZGVdPVwiYmxhbmtOb2RlLnRlcm1cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLW5vd3JhcCBoYXMtdGV4dC1lbGxpcHNpc1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0ubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcmlnaW5hbFZhbHVlPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7YmxhbmtOb2RlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdE9yaWdpbmFsVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUub3JpZ2luYWxWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFibGFua05vZGUuaXNPcmlnaW5hbCB8fCBibGFua05vZGUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVjYWxjdWxhdGVkVmFsdWU+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57e2JsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+e3tibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJpcy1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVsdGFWYWx1ZT5cbiAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YSAqbmdJZj1cImJsYW5rTm9kZS5vcmlnaW5hbC5sZW5ndGggJiYgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbb3JpZ2luYWxWYWx1ZV09XCJibGFua05vZGUub3JpZ2luYWxWYWx1ZVwiXG4gICAgICAgICAgICAgICAgPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsYW5rTm9kZS5hbGxQYXJhbGxlbDsgZWxzZSBkZWZhdWx0RGVsdGFWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG1vZGVsIG9mIGJsYW5rTm9kZS5jb25maWdNb2RlbHNbMF1cIj5cbiAgICAgICAgICAgICAgICAgIDxoZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhICpuZ0lmPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbCAmJiBibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImJsYW5rTm9kZS5yZWNhbGN1bGF0ZWRWYWx1ZUJ5TWV0aG9kSWRbbW9kZWwubWV0aG9kSWRdXCJcbiAgICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiXG4gICAgICAgICAgICAgICAgICA+PC9oZS1ibGFuay1ub2RlLXZhbHVlLWRlbHRhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7ZGF0YTogYmxhbmtOb2RlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG5cbiAgICAgICAgICA8dHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzdWJWYWx1ZSBvZiBibGFua05vZGUua2V5c1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLnN1YlZhbHVlcz8ubGVuZ3RoXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTMgcHItMSBmaWVsZC1ub2RlXCI+RmllbGQ6PC9zcGFuPlxuXG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nSWY9XCJibGFua05vZGUudHlwZVwiXG4gICAgICAgICAgICAgICAgW2hyZWZdPVwiYmFzZVVybCArICcvc2NoZW1hLycgKyBibGFua05vZGUudHlwZSArICcjJyArIHN1YlZhbHVlLmtleVwiIHRhcmdldD1cIl9ibGFua1wiIFt0aXRsZV09XCJzdWJWYWx1ZS5rZXlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIj57e3N1YlZhbHVlLmtleX19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcFwiICpuZ0lmPVwiIWJsYW5rTm9kZS50eXBlXCI+e3tzdWJWYWx1ZS5rZXl9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj57e3N1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkIHx8IHN1YlZhbHVlLmtleSA9PT0gJ2ltcGFjdEFzc2Vzc21lbnQnOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7c3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHtkYXRhOiBzdWJWYWx1ZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLnN1YlZhbHVlc1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHBsLTNcIj57e3N1YlZhbHVlLmtleSB8IGtleVRvTGFiZWx9fTwvc3Bhbj5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3ViVmFsdWUuaWRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwci0xXCI+Ojwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInN1YlZhbHVlLmtleVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiAqbmdTd2l0Y2hDYXNlPVwiJ2JhY2tncm91bmREYXRhJ1wiPnt7c3ViVmFsdWUuaWQgfCBrZXlUb0xhYmVsfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aGUtbm9kZS1saW5rICpuZ1N3aXRjaERlZmF1bHQgY2xhc3M9XCJpcy1ibG9jayBwbC00XCIgW25vZGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpXCIgW2F0dHIudGl0bGVdPVwidGVybUJ5SWQoc3ViVmFsdWUuaWQpLm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIiBbaW5uZXJIdG1sXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2hlLW5vZGUtbGluaz5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLnNob3dVbml0c1wiIFtpbm5lckh0bWxdPVwiYmxhbmtOb2RlLnRlcm0/LnVuaXRzIHwgY29tcG91bmRcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLm9yaWdpbmFsVmFsdWUgIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiPnt7c3ViVmFsdWUub3JpZ2luYWxWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUuaXNSZWNhbGN1bGF0ZWQ7IGVsc2Ugbm90UmVjYWxjdWxhdGVkXCI+XG4gICAgICAgICAgICAgICAge3tzdWJWYWx1ZS5yZWNhbGN1bGF0ZWRWYWx1ZSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPi08L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDoge2RhdGE6IHN1YlZhbHVlfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2hlLWRhdGEtdGFibGU+XG5cbiAgPGRpdiBjbGFzcz1cImlzLXNpemUtNyBpcy1pdGFsaWNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1ucyBpcy12YXJpYWJsZSBpcy0xIG15LTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaXMtbmFycm93XCI+XG4gICAgICAgIDxwPlxuICAgICAgICAgIDxhIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIHByLTJcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNob3dMZWdlbmQgPSAhc2hvd0xlZ2VuZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLWRvd25cIiBbY2xhc3MuaXMtaGlkZGVuXT1cIiFzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPGZhLWljb24gaWNvbj1cImFuZ2xlLXJpZ2h0XCIgW2NsYXNzLmlzLWhpZGRlbl09XCJzaG93TGVnZW5kXCI+PC9mYS1pY29uPlxuICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiPkxlZ2VuZDo8L3NwYW4+XG4gICAgICAgIDwvcD5cbiAgICAgICAgPHVsIGNsYXNzPVwiY29udGVudCBwbC0yXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YXR1cyBvZiBMb2dTdGF0dXMgfCBrZXlzXCI+XG4gICAgICAgICAgICA8bGkgKm5nSWY9XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIiBjbGFzcz1cImhhcy10ZXh0LXt7bG9nQ29sb3Jbc3RhdHVzLnZhbHVlXX19XCI+XG4gICAgICAgICAgICAgIDxmYS1pY29uIFtpY29uXT1cImxvZ0ljb25bc3RhdHVzLnZhbHVlXVwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCI+e3tzdGF0dXMudmFsdWV9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4gaGFzLXRleHQtcmlnaHRcIiAqbmdJZj1cImZpbHRlcmVkVHlwZVwiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgY2hlY2tib3hcIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJzZWxlY3RvclwiXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm9ubHlSZXF1aXJlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cImZpbHRlclJlc3VsdHMoKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiISF0ZXJtXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2hvdyBvbmx5IHt7ZmlsdGVyZWRUeXBlIHwgcGx1cmFsaXplfX0gaW5jbHVkZWQgaW4gdGhlIGRlZmF1bHQgSGVzdGlhIHN5c3RlbSBib3VuZGFyeTwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2JsYW5rTm9kZU1vZGVscyBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHRkIGNsYXNzPVwiYmxhbmstbm9kZS1pbmRleC17e2l9fVwiICpuZ0Zvcj1cImxldCBjIG9mIG1ldGhvZE1vZGVsc0NvdW50IHwgdGltZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0TW9kZWxzQXQoZGF0YSwgaSk7IGxldCBtb2RlbHM7IGVsc2Ugbm9WYWx1ZVwiPlxuICAgICAgPG5nLXRlbXBsYXRlICNtb2RlbFNlcmllPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWw7IGNvbnRleHQ6IHttb2RlbDptb2RlbHMsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cIm1vZGVscyB8IGlzQXJyYXk7IGVsc2UgbW9kZWxTZXJpZVwiPlxuICAgICAgICA8cCAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgbW9kZWxzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7bW9kZWwsIGRhdGF9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3RkPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbCBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8c3BhblxuICAgIFtjbGFzcy50cmlnZ2VyLXBvcG92ZXJdPVwibW9kZWwuc2hvd0xvZ3NcIlxuICAgIFtuZ2JQb3BvdmVyXT1cImxvZ0RldGFpbHNcIiBbYXV0b0Nsb3NlXT1cIidvdXRzaWRlJ1wiIHBvcG92ZXJDbGFzcz1cImlzLW5hcnJvd1wiXG4gICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcD1cIm5nYlBvcG92ZXJcIiBwbGFjZW1lbnQ9XCJsZWZ0XCIgY29udGFpbmVyPVwiYm9keVwiXG4gICAgKGNsaWNrKT1cInAuaXNPcGVuKCkgPyBwLmNsb3NlKCkgOiAobW9kZWwuc2hvd0xvZ3MgPyBwLm9wZW4oeyBsb2dzOiBtb2RlbC5sb2dzIH0pIDogbnVsbClcIlxuICA+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1jYXBpdGFsaXplZFwiPnt7bWV0aG9kTmFtZShtb2RlbCl9fTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cInBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/Lm1ldGhvZFRpZXIgfHwgbW9kZWwubW9kZWw/Lm1ldGhvZFRpZXJcIj5be3ttb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyfX1dPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xIGhhcy10ZXh0LXt7bG9nQ29sb3JbbW9kZWwuc3RhdHVzXX19IHRyaWdnZXItcG9wb3ZlclwiXG4gICAgICBbbmdiUG9wb3Zlcl09XCJsb2dTdGF0dXNEZXRhaWxzXCIgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIiBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgICAgdHJpZ2dlcnM9XCJtYW51YWxcIiAjcDE9XCJuZ2JQb3BvdmVyXCIgcGxhY2VtZW50PVwibGVmdFwiIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcDEuaXNPcGVuKCkgPyBwMS5jbG9zZSgpIDogcDEub3Blbih7IG1vZGVsLCBkYXRhIH0pXCJcbiAgICA+XG4gICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW21vZGVsLnN0YXR1c11cIj48L2ZhLWljb24+XG4gICAgPC9zcGFuPlxuXG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5tb2RlbFwiPlxuICAgICAgKDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkb2NzTGluazsgY29udGV4dDogeyRpbXBsaWNpdDogbW9kZWwubW9kZWx9XCI+PC9uZy1jb250YWluZXI+KVxuICAgIDwvc3Bhbj5cbiAgPC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub1ZhbHVlPi08L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI25vdFJlY2FsY3VsYXRlZD5ub3QgcmVjYWxjdWxhdGVkPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dEZXRhaWxzIGxldC1sb2dzPVwibG9nc1wiPlxuICA8ZGl2IGNsYXNzPVwidGFibGUtY29udGFpbmVyXCIgKmJpbmRPbmNlPVwibG9nc1wiPlxuICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtZnVsbHdpZHRoXCI+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5yZXF1aXJlbWVudHNcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgcmVxdWlyZW1lbnRLZXlzKGxvZ3MucmVxdWlyZW1lbnRzKVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6e2tleSwgdmFsdWU6bG9ncy5yZXF1aXJlbWVudHNba2V5XX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvZ3M/LmxvZ3NcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBrZXkgb2YgbG9ncy5sb2dzIHwga2V5c1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvZ0xpbmU7IGNvbnRleHQ6a2V5XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2Rpdj5cblxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaXQtbXQtMlwiICpuZ0lmPVwibG9ncz8ubWlzc2luZ0xvb2t1cHM/Lmxlbmd0aFwiPlxuICAgICAgPHA+T3B0aW9uYWwgZGF0YSBtaXNzaW5nOjwvcD5cblxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lciBkYXRhLXRhYmxlLWNvbnRhaW5lclwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWZ1bGx3aWR0aCBpcy1zdHJpcGVkXCI+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGg+XG4gICAgICAgICAgICAgICAgPHNwYW4+RmlsZW5hbWU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aD5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Db2x1bW4gVGl0bGU8L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aD5cbiAgICAgICAgICAgICAgICA8c3Bhbj5Sb3cgKHRlcm0uaWQpPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keSBjbGFzcz1cImhhcy1iYWNrZ3JvdW5kLWJsYWNrIGhhcy10ZXh0LXdoaXRlXCI+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IGRhdGEgb2YgbG9ncy5taXNzaW5nTG9va3Vwc1wiPlxuICAgICAgICAgICAgICA8dGQ+e3tkYXRhLmZpbGVuYW1lfX08L3RkPlxuICAgICAgICAgICAgICA8dGQ+e3tkYXRhLmNvbHVtbn19PC90ZD5cbiAgICAgICAgICAgICAgPHRkPnt7ZGF0YS50ZXJtSWR9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0xpbmVWYWx1ZSBsZXQta2V5PVwia2V5XCIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAgPG5nLXRlbXBsYXRlICNkZWZhdWx0VmFsdWU+XG4gICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tbWlkZGxlXCI+e3t2YWx1ZX19PC9zcGFuPlxuICA8L25nLXRlbXBsYXRlPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVxdWlyZW1lbnRMaW5rZWROb2RlKGtleSwgdmFsdWUpOyBsZXQgbGlua2VkTm9kZTsgZWxzZSBkZWZhdWx0VmFsdWVcIj5cbiAgICA8aGUtbm9kZS1saW5rIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiIGxpbmtDbGFzcz1cImlzLWRhcmtcIiBbbm9kZV09XCJsaW5rZWROb2RlXCIgW3Nob3dFeHRlcm5hbExpbmtdPVwidHJ1ZVwiPjwvaGUtbm9kZS1saW5rPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nTGluZSBsZXQta2V5PVwia2V5XCIgbGV0LXZhbHVlPVwidmFsdWVcIj5cbiAgPHRyPlxuICAgIDx0ZCBjbGFzcz1cImhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiIFtuZ1N3aXRjaF09XCJrZXlcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0Pnt7a2V5IHwga2V5VG9MYWJlbH19PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ25vZGVfdHlwZV9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IDxjb2RlPk5vZGU8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3NpdGVUeXBlX2FsbG93ZWQnXCI+SXMgdGhlIGN1cnJlbnQgPGNvZGU+c2l0ZVR5cGU8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF9pZF9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdCA8Y29kZT5AaWQ8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3ByaW1hcnlfcHJvZHVjdF90ZXJtVHlwZV9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IHByaW1hcnkgcHJvZHVjdCA8Y29kZT50ZXJtVHlwZTwvY29kZT4gYWxsb3dlZCB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidnZW9zcGF0aWFsX2RhdGEnXCI+SGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2NvbnRhaW5zX2dlb3NwYXRpYWxfZGF0YSdcIj5IYXMgZ2Vvc3BhdGlhbCBkYXRhIG5lY2Vzc2FyeSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY3VycmVudF9zaXplJ1wiPkN1cnJlbnQgcG9seWdvbiBhcmVhPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtYXhfYXJlYV9zaXplJ1wiPk1heGltdW0gcG9seWdvbiBhcmVhIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidiZWxvd19tYXhfYXJlYV9zaXplJ1wiPlBvbHlnb24gYmVsb3cgdGhlIG1heGltdW0gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCIncmVnaW9uX2ZhY3RvcidcIj5GYWN0b3IgZnJvbSByZWdpb24gbG9va3VwPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3Blc3RpY2lkZXNfY29tcGxldGUnXCI+UGVzdGljaWRlIGRhdGEgYXJlIDxjb2RlPmNvbXBsZXRlPC9jb2RlPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaGFzX3Blc3RpY2lkZXNfaW5wdXRzJ1wiPkN5Y2xlIGNvbnRhaW5zIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPiBJbnB1dHM8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2FsbF9wZXN0aWNpZGVBSV9oYXZlX2xvb2t1cF92YWx1ZSdcIj5BbGwgPGNvZGU+cGVzdGljaWRlQUk8L2NvZGU+IElucHV0cyBoYXZlIGEgbG9va3VwIHZhbHVlPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19jcm9wX3Jlc2lkdWVfYnVybnQnXCI+PGNvZGU+YWJvdmVHcm91bmRDcm9wUmVzaWR1ZUJ1cm50PC9jb2RlPiBpcyBwcmVzZW50IGFzIFByb2R1Y3Q8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbGlxdWlkX3NsdXJyeV9zbHVkZ2VfUCdcIj5MaXF1aWQsIFNsdXJyeSwgYW5kIFNsdWRnZSBQPC9uZy1jb250YWluZXI+XG4gICAgICA8L3NwYW4+XG4gICAgICA8aGUtY2xpcGJvYXJkIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiIGNsaXBib2FyZENsYXNzPVwiaXMtc2l6ZS03IGlzLXAtMVwiIFtpY29uXT1cIlsnZmFyJywgJ2Nsb25lJ11cIiBbdmFsdWVdPVwia2V5XCIgW2hpZGVUZXh0XT1cInRydWVcIj48L2hlLWNsaXBib2FyZD5cbiAgICA8L3RkPlxuICAgIDx0ZD5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlVmFsdWU+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lVmFsdWU7IGNvbnRleHQ6e2tleSx2YWx1ZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8ZGl2ICpuZ0lmPVwibG9nVmFsdWVBcnJheSh2YWx1ZSk7IGxldCB2YWx1ZUFycmF5OyBlbHNlIHNpbmdsZVZhbHVlXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIGlzLWRhcmsgaXMtYm9yZGVyZWQgaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZCAqbmdJZj1cInZhbHVlQXJyYXlbMF0gfCBpc09iamVjdFwiPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJoYXMtdGV4dC13aGl0ZVwiICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlbMF0gfCBrZXlzXCI+e3t2LmtleX19PC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHYgb2YgdmFsdWVBcnJheVwiPlxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZUFycmF5VmFsdWU+XG4gICAgICAgICAgICAgICAgPHRkPnt7dn19PC90ZD5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInYgfCBpc09iamVjdDsgZWxzZSBzaW5nbGVBcnJheVZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCB2diBvZiB2IHwga2V5c1wiPnt7dnYudmFsdWV9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbiAgPC90cj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nU3RhdHVzRGV0YWlscyBsZXQtbW9kZWw9XCJtb2RlbFwiIGxldC1kYXRhPVwiZGF0YVwiPlxuICA8bmctY29udGFpbmVyICpiaW5kT25jZT1cIm1vZGVsXCI+XG4gICAgPGRpdiBjbGFzcz1cImlzLW1iLTJcIj5cbiAgICAgIDxzcGFuPlN0YXR1czo8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57e21vZGVsLnN0YXR1c319PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICNzaG93UnVuT3JjaGVzdHJhdG9yPlxuICAgICAgPGRpdiBjbGFzcz1cImlzLXJ1bi1vcmNoZXN0cmF0b3JcIj5cbiAgICAgICAgPHAgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5cIj5BbGwgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG1ldCB0byBydW4gdGhlIG1vZGVsLjwvcD5cbiAgICAgICAgPHAgKm5nSWY9XCIhbW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+XG4gICAgICAgICAgU29tZSBvZiB0aGUgcmVxdWlyZW1lbnRzIHdlcmUgbm90IG1ldCB0byBydW4gdGhlIG1vZGVsLlxuICAgICAgICAgIFlvdSBjYW4gY2xpY2sgb24gdGhlIG1vZGVsIG5hbWUgb24gdGhlIGxlZnQgdG8gdmlldyB0aGUgZGVidWdnaW5nIGxvZ3MuXG4gICAgICAgIDwvcD5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVsLmxvZ3M/LmxvZ3M/LmVycm9yXCI+XG4gICAgICAgICAgPHA+VGhlIG1vZGVsIGZhaWxlZCB0byBydW4gZm9yIHRoZSBmb2xsb3dpbmcgcmVhc29uOjwvcD5cbiAgICAgICAgICA8cD48Y29kZT57e21vZGVsLmxvZ3MubG9ncy5lcnJvcn19PC9jb2RlPjwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLXJ1bi1vcmNoZXN0cmF0b3JcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZFJ1bk9yY2hlc3RyYXRvciA9PT0gZmFsc2U7IGVsc2Ugc2hvd1J1bk9yY2hlc3RyYXRvclwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5sb2dzLnJ1blJlcXVpcmVkXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcnVuLW5vZGUtdHlwZS1ub3QtYWxsb3dlZFwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5ub2RlX3R5cGVfYWxsb3dlZCA9PT0gJ0ZhbHNlJ1wiPlxuICAgICAgICAgIFRoaXMgbW9kZWwgc2hvdWxkIG5vdCBydW4gZm9yIHt7bm9kZVR5cGUgfCBwbHVyYWxpemU6MH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctdGVtcGxhdGUgI3J1bk5vQ29uZmlnPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub3QtZW1wdHlcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8uaXNfZW1wdHkgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGUge3tkYXRhLnR5cGUgfHwgJ2JsYW5rIG5vZGUnfX0gd2l0aCBUZXJtIDxjb2RlPnt7ZGF0YS50ZXJtSWR9fTwvY29kZT4gaXMgYWxyZWFkeSBwcmVzZW50IG9yIGFscmVhZHkgYWRkZWQgYnkgYW5vdGhlciBtb2RlbC5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGVsLmNvbmZpZzsgZWxzZSBydW5Ob0NvbmZpZ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaXMtcnVuLXN0cmF0ZWd5LXt7bW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5fX1cIiBbbmdTd2l0Y2hdPVwibW9kZWwuY29uZmlnLnJ1blN0cmF0ZWd5XCI+XG4gICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhbHdheXMnXCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWRkX2tleV9pZl9taXNzaW5nJ1wiPlxuICAgICAgICAgICAgV2Ugb25seSBnYXAtZmlsbCB0aGlzIGtleSBpZiBub3QgcHJlc2VudFxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9ibGFua19ub2RlX2lmX21pc3NpbmcnXCI+XG4gICAgICAgICAgICBXZSBvbmx5IGdhcC1maWxsIHRoaXMgQmxhbmsgTm9kZSBpZiBub3QgcHJlc2VudC5cbiAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi13aXRoLW1lYXN1cmVkXCIgKm5nSWY9XCJtb2RlbC5jb25maWcucnVuQXJncz8ucnVuTm9uTWVhc3VyZWQgJiYgaGFzTWV0aG9kVGllcihkYXRhLm9yaWdpbmFsLCBFbWlzc2lvbk1ldGhvZFRpZXIubWVhc3VyZWQpXCI+XG4gICAgICAgICAgICBUaGUgPGNvZGU+e3ttb2RlbC5jb25maWcudmFsdWV9fTwvY29kZT4gd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXMgbWVhc3VyZWQuXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImlzLW5vLW1lcmdlLW9yY2hlc3RyYXRvclwiICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkTWVyZ2UgPT09IGZhbHNlXCI+XG4gICAgICA8cCBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VUaHJlc2hvbGRcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucmVwbGFjZVRocmVzaG9sZFwiPlxuICAgICAgICA8c3Bhbj5UaGU8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPmZyb20gdGhpcyBtb2RlbCB3YXM8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bGVzcyB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZVRocmVzaG9sZCA9PT0gJ1RydWUnXCI+bW9yZSB0aGFuPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+e3ttb2RlbC5jb25maWcubWVyZ2VBcmdzLnJlcGxhY2VUaHJlc2hvbGRbMV0gKiAxMDB9fSU8L3NwYW4+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtb2RlbC5jb25maWcubWVyZ2VBcmdzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnRmFsc2UnXCI+bm90IHN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VUaHJlc2hvbGQgPT09ICdUcnVlJ1wiPnN1ZmZpY2llbnRseTwvc3Bhbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5kaWZmZXJlbnQgZnJvbSB0aGUgb3JpZ2luYWw8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnPy5tZXJnZUFyZ3M/LnJlcGxhY2VUaHJlc2hvbGQ/LlswXSB8fCAndmFsdWUnfX0uPC9zcGFuPlxuICAgICAgPC9wPlxuICAgIDwvZGl2PlxuICAgIDxwIGNsYXNzPVwiaXMtbWVyZ2UtcmVwbGFjZUxvd2VyVGllclwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzPy5yZXBsYWNlTG93ZXJUaWVyXCI+XG4gICAgICA8c3Bhbj5UaGUgbW9kZWwgPGNvZGU+bWV0aG9kVGllcjwvY29kZT4gd2FzPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ0ZhbHNlJ1wiPmhpZ2hlciB0aGFuPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZUxvd2VyVGllciA9PT0gJ1RydWUnXCI+bG93ZXIgdGhhbjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnRoZSBvcmlnaW5hbCA8Y29kZT5tZXRob2RUaWVyPC9jb2RlPjwvc3Bhbj5cbiAgICA8L3A+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNkb2NzTGluayBsZXQtbW9kZWw+XG4gIDxhIFtocmVmXT1cIm1vZGVsLmFwaURvY3NQYXRoIHx8IG1vZGVsLmRvY1BhdGggfHwgbW9kZWwucGF0aFwiIHRhcmdldD1cIl9ibGFua1wiXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gID5cbiAgICA8c3Bhbj5Eb2NzPC9zcGFuPlxuICAgIDxmYS1pY29uIGNsYXNzPVwibWwtMVwiIGljb249XCJleHRlcm5hbC1saW5rLWFsdFwiIHNpemU9XCJzbVwiPjwvZmEtaWNvbj5cbiAgPC9hPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1sb2dzLW1vZGVscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbm9kZS9ub2RlLWxvZ3MtbW9kZWxzL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL25vZGUvbm9kZS1sb2dzLW1vZGVscy9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBYyxJQUFJLEVBQVMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGtCQUFrQixFQUF1QixRQUFRLEVBQVEsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0csT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQ2lDLFNBQVMsRUFBMkIsZ0JBQWdCLEVBQUUsZUFBZSxFQUMzRyxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFDeEMsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0RixPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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dEUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFVBQVUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFTSxRQUFRLENBQUMsRUFBVTtRQUN4QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUk7WUFDM0IsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJO1lBQ3RCLEtBQUssRUFBRSxFQUFFO1lBQ1QsSUFBSSxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7U0FDVCxDQUFDO0lBQ25CLENBQUM7O29IQS9LVSx1QkFBdUI7d0dBQXZCLHVCQUF1Qiw2UEN0RnBDLDhockJBbWNBOzJGRDdXYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCO2dLQWdCdkIsSUFBSTtzQkFEWCxLQUFLO2dCQUdFLE9BQU87c0JBRGQsS0FBSztnQkFHRSxjQUFjO3NCQURyQixLQUFLO2dCQUdFLGtCQUFrQjtzQkFEekIsS0FBSztnQkFHRSxLQUFLO3NCQURaLEtBQUs7Z0JBR0UsZUFBZTtzQkFEdEIsS0FBSztnQkFHRSxPQUFPO3NCQURkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG1lcmdlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3QsIGZpbHRlciwgcmVkdWNlLCB0b0FycmF5LCBtYXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzd2l0Y2hNYXAsIG1lcmdlTWFwLCBtZXJnZUFsbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEVtaXNzaW9uTWV0aG9kVGllciwgSVRlcm1KU09OTEQsIEpTT05MRCwgTm9kZVR5cGUsIFRlcm0sIFRlcm1UZXJtVHlwZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IGtleVRvTGFiZWwgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcbmltcG9ydCB7IHByb3BlcnR5VmFsdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzL2Rpc3QvdGVybSc7XG5cbmltcG9ydCB7XG4gIElCbGFua05vZGVMb2dTdWJWYWx1ZSwgSUJsYW5rTm9kZUxvZywgTG9nU3RhdHVzLCBJQ29uZmlnTW9kZWwsIGJsYW5rTm9kZSwgZ3JvdXBMb2dzQnlNb2RlbCwgZ3JvdXBMb2dzQnlUZXJtLFxuICBtb2RlbENvdW50LCBjb21wdXRlVGVybXMsIGxvZ1ZhbHVlQXJyYXlcbn0gZnJvbSAnLi9ub2RlLWxvZ3MtbW9kZWxzLm1vZGVsJztcbmltcG9ydCB7IElKU09OTm9kZSwgSGVOb2RlU2VydmljZSB9IGZyb20gJy4uL25vZGUuc2VydmljZSc7XG5pbXBvcnQgeyBIZUVuZ2luZVNlcnZpY2UsIElNb2RlbCB9IGZyb20gJy4uLy4uL2VuZ2luZS9lbmdpbmUuc2VydmljZSc7XG5pbXBvcnQgeyBtYXRjaEV4YWN0UXVlcnksIG1hdGNoVGVybVR5cGUsIG1hdGNoVHlwZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2gubW9kZWwnO1xuaW1wb3J0IHsgSGVTZWFyY2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5zZXJ2aWNlJztcbmltcG9ydCB7IGJhc2VVcmwsIGlzRXh0ZXJuYWwgfSBmcm9tICcuLi8uLi9jb21tb24vdXRpbHMnO1xuaW1wb3J0IHsgdGVybVR5cGVMYWJlbCB9IGZyb20gJy4uLy4uL3Rlcm1zL3Rlcm1zLm1vZGVsJztcblxuY29uc3Qgbm9kZVR5cGVzTG93ZXJDYXNlID0gT2JqZWN0LnZhbHVlcyhOb2RlVHlwZSkubWFwKHYgPT4gdi50b0xvd2VyQ2FzZSgpKTtcblxuY29uc3QgbG9nSWNvbjoge1xuICBbc3RhdHVzIGluIExvZ1N0YXR1c10/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbn0gPSB7XG4gIFtMb2dTdGF0dXMuc3VjY2Vzc106ICdjaGVjaycsXG4gIFtMb2dTdGF0dXMuZXJyb3JdOiAndGltZXMnLFxuICBbTG9nU3RhdHVzLnNraXBIaWVyYXJjaHldOiBbJ2ZhcicsICdjaXJjbGUnXSxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnY2lyY2xlJyxcbiAgW0xvZ1N0YXR1cy5ub3RSZXF1aXJlZF06ICdkb3QtY2lyY2xlJ1xufTtcblxuY29uc3QgbG9nQ29sb3I6IHtcbiAgW3N0YXR1cyBpbiBMb2dTdGF0dXNdPzogc3RyaW5nO1xufSA9IHtcbiAgW0xvZ1N0YXR1cy5zdWNjZXNzXTogJ3N1Y2Nlc3MnLFxuICBbTG9nU3RhdHVzLmVycm9yXTogJ2RhbmdlcicsXG4gIFtMb2dTdGF0dXMuc2tpcEhpZXJhcmNoeV06ICdkYXJrJyxcbiAgW0xvZ1N0YXR1cy5kYXRhUHJvdmlkZWRdOiAnZGFyaycsXG4gIFtMb2dTdGF0dXMubm90UmVxdWlyZWRdOiAnZ3JleSdcbn07XG5cbmNvbnN0IG1ldGhvZElkTGFiZWwgPSAobWV0aG9kSWQ6IHN0cmluZywgbW9kZWw/OiBJTW9kZWwpID0+XG4gIChcbiAgICBtZXRob2RJZFxuICAgICAgPyAoe1xuICAgICAgICAnY3ljbGUvdHJhbnNmb3JtYXRpb24nOiAnRGF0YSBGcm9tIFRyYW5zZm9ybWF0aW9uJyxcbiAgICAgICAgaW1wYWN0X2Fzc2Vzc21lbnQ6ICdEYXRhIEZyb20gQ3ljbGUnXG4gICAgICB9KVttZXRob2RJZF1cbiAgICAgIDogJydcbiAgKSB8fCAoXG4gICAgbWV0aG9kSWQuaW5jbHVkZXMoJy8nKSA/IG1ldGhvZElkLnNwbGl0KCcvJylbMF0gOiBrZXlUb0xhYmVsKG1ldGhvZElkKVxuICApO1xuXG5jb25zdCBnZXRNb2RlbHNBdCA9IChsb2c6IElCbGFua05vZGVMb2dTdWJWYWx1ZSB8IElCbGFua05vZGVMb2csIGluZGV4OiBudW1iZXIpID0+XG4gICgnbW9kZWxzSW5TdWJWYWx1ZXMnIGluIGxvZyA/ICFsb2cubW9kZWxzSW5TdWJWYWx1ZXMgfHwgIWxvZy5pc09wZW4gOiB0cnVlKSAmJiBsb2cuY29uZmlnTW9kZWxzW2luZGV4XTtcblxuY29uc3QgcmVxdWlyZW1lbnRLZXlzID0gKHJlcXVpcmVtZW50czogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkgPT5cbiAgT2JqZWN0LmtleXMocmVxdWlyZW1lbnRzKS5maWx0ZXIoayA9PiAhbm9kZVR5cGVzTG93ZXJDYXNlLmluY2x1ZGVzKGspKTtcblxuY29uc3QgcmVxdWlyZW1lbnRDb2xvciA9ICh2YWx1ZTogYW55KSA9PiAhdmFsdWUgfHwgWydOb25lJywgJ0ZhbHNlJywgJzAnLCAnMC4wJ10uaW5jbHVkZXModmFsdWUpID8gJ2RhbmdlcicgOiAnd2hpdGUnO1xuXG5jb25zdCByZXF1aXJlbWVudExpbmtlZE5vZGVCeUtleToge1xuICBba2V5OiBzdHJpbmddOiAodmFsdWU6IHN0cmluZykgPT4gUGFydGlhbDxKU09OTEQ8Tm9kZVR5cGU+Pjtcbn0gPSB7XG4gIHJlbGF0ZWRfY3ljbGVzOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLkN5Y2xlLCAnQGlkJzogdiB9KSxcbiAgY3ljbGVfaWQ6IHYgPT4gKHsgJ0B0eXBlJzogTm9kZVR5cGUuQ3ljbGUsICdAaWQnOiB2IH0pLFxuICBpbXBhY3RfYXNzZXNzbWVudF9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5JbXBhY3RBc3Nlc3NtZW50LCAnQGlkJzogdiB9KSxcbiAgc2l0ZV9pZDogdiA9PiAoeyAnQHR5cGUnOiBOb2RlVHlwZS5TaXRlLCAnQGlkJzogdiB9KSxcbiAgc291cmNlX2lkOiB2ID0+ICh7ICdAdHlwZSc6IE5vZGVUeXBlLlNvdXJjZSwgJ0BpZCc6IHYgfSlcbn07XG5cbmNvbnN0IHJlcXVpcmVtZW50TGlua2VkTm9kZSA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT5cbiAga2V5IGluIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5ICYmXG4gIHJlcXVpcmVtZW50TGlua2VkTm9kZUJ5S2V5W2tleV0odmFsdWUpO1xuXG5jb25zdCBpc1N5c3RlbUJvdW5kYXJ5ID0gKFxuICB7IGlzUmVjYWxjdWxhdGVkLCBpc1JlcXVpcmVkIH06IFBpY2s8SUJsYW5rTm9kZUxvZyB8IElCbGFua05vZGVMb2dTdWJWYWx1ZSwgJ2lzUmVjYWxjdWxhdGVkJyB8ICdpc1JlcXVpcmVkJz5cbikgPT4gW1xuICBpc1JlY2FsY3VsYXRlZCxcbiAgaXNSZXF1aXJlZFxuXS5zb21lKEJvb2xlYW4pO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoZS1ub2RlLWxvZ3MtbW9kZWxzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25vZGUtbG9ncy1tb2RlbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ub2RlLWxvZ3MtbW9kZWxzLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTm9kZUxvZ3NNb2RlbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGxvZ3M6IHN0cmluZztcbiAgcHJpdmF0ZSBhbGxUZXJtczogKFRlcm0gfCBJVGVybUpTT05MRClbXSA9IFtdO1xuICBwcml2YXRlIGFsbEJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwcml2YXRlIG1ldGhvZHNCeUlkPzoge1xuICAgIFtpZDogc3RyaW5nXTogSVRlcm1KU09OTEQ7XG4gIH07XG4gIHByaXZhdGUgdGVybXNCeUlkOiB7XG4gICAgW2lkOiBzdHJpbmddOiBJVGVybUpTT05MRDtcbiAgfSA9IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHByaXZhdGUgbm9kZT86IElKU09OTm9kZTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSBub2RlS2V5Pzogc3RyaW5nO1xuICBASW5wdXQoKVxuICBwcml2YXRlIG9yaWdpbmFsVmFsdWVzOiBibGFua05vZGVbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIHJlY2FsY3VsYXRlZFZhbHVlczogYmxhbmtOb2RlW10gPSBbXTtcbiAgQElucHV0KClcbiAgcHJpdmF0ZSB0ZXJtczogSVRlcm1KU09OTERbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGZpbHRlclRlcm1UeXBlcz86IFRlcm1UZXJtVHlwZVtdO1xuICBASW5wdXQoKVxuICBwcml2YXRlIGxvZ3NLZXk/OiBzdHJpbmc7XG5cbiAgcHVibGljIGxvZ3NVcmw/OiBzdHJpbmc7XG4gIHB1YmxpYyBiYXNlVXJsID0gYmFzZVVybCgpO1xuICBwdWJsaWMgaXNFeHRlcm5hbCA9IGlzRXh0ZXJuYWwoKTtcbiAgcHVibGljIEVtaXNzaW9uTWV0aG9kVGllciA9IEVtaXNzaW9uTWV0aG9kVGllcjtcbiAgcHVibGljIExvZ1N0YXR1cyA9IExvZ1N0YXR1cztcbiAgcHVibGljIGxvZ0ljb24gPSBsb2dJY29uO1xuICBwdWJsaWMgbG9nQ29sb3IgPSBsb2dDb2xvcjtcbiAgcHVibGljIHByb3BlcnR5VmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xuICBwdWJsaWMgZ2V0TW9kZWxzQXQgPSBnZXRNb2RlbHNBdDtcbiAgcHVibGljIHJlcXVpcmVtZW50S2V5cyA9IHJlcXVpcmVtZW50S2V5cztcbiAgcHVibGljIHJlcXVpcmVtZW50Q29sb3IgPSByZXF1aXJlbWVudENvbG9yO1xuICBwdWJsaWMgbG9nVmFsdWVBcnJheSA9IGxvZ1ZhbHVlQXJyYXk7XG4gIHB1YmxpYyByZXF1aXJlbWVudExpbmtlZE5vZGUgPSByZXF1aXJlbWVudExpbmtlZE5vZGU7XG4gIHB1YmxpYyBsb2FkaW5nID0gdHJ1ZTtcbiAgcHVibGljIG5vZGVUeXBlOiBOb2RlVHlwZTtcbiAgcHVibGljIGJsYW5rTm9kZXM6IElCbGFua05vZGVMb2dbXSA9IFtdO1xuICBwdWJsaWMgbWV0aG9kTW9kZWxzQ291bnQgPSAwO1xuICBwdWJsaWMgcm93c0NvdW50ID0gMDtcbiAgcHVibGljIG9ubHlSZXF1aXJlZCA9IHRydWU7XG4gIHB1YmxpYyBzaG93TGVnZW5kID0gdHJ1ZTtcblxuICBwdWJsaWMgdGVybT86IHN0cmluZztcbiAgcHVibGljIHN1Z2dlc3RUZXJtID0gKHRleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4pID0+XG4gICAgdGV4dCQucGlwZShcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBzd2l0Y2hNYXAodiA9PiB0aGlzLnN1Z2dlc3RCeVRlcm0odikpLFxuICAgICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBub2RlU2VydmljZTogSGVOb2RlU2VydmljZSxcbiAgICBwcml2YXRlIHNlYXJjaFNlcnZpY2U6IEhlU2VhcmNoU2VydmljZSxcbiAgICBwcml2YXRlIGVuZ2luZVNlcnZpY2U6IEhlRW5naW5lU2VydmljZVxuICApIHsgfVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMubG9nc1VybCA9IHRoaXMubm9kZVNlcnZpY2Uubm9kZUxvZ3NVcmwodGhpcy5ub2RlKTtcbiAgICAvLyBzYXZlIGFzIGxvY2FsIHZhcmlhYmxlIHRvIGF2b2lkIFwicmVzZXJ2ZWQgeWllbGQga2V5d29yZFwiIGlzc3VlXG4gICAgdGhpcy5sb2dzID0gYXdhaXQgdGhpcy5nZXRMb2dzKCk7XG4gICAgY29uc3QgZ3JvdXBlZExvZ3MgPSBncm91cExvZ3NCeU1vZGVsKHRoaXMubG9ncyk7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc0tleSA/IGdyb3VwZWRMb2dzW3RoaXMubG9nc0tleV0gOiBncm91cGVkTG9ncztcblxuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLm5vZGVbJ0B0eXBlJ10gfHwgdGhpcy5ub2RlLnR5cGU7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm9jaGVzdHJhdG9yQ29uZmlnKHRoaXMubm9kZVR5cGUsIHRoaXMubm9kZVsnQGlkJ10gfHwgdGhpcy5ub2RlLmlkKTtcblxuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMuc2VhcmNoVGVybXMoe1xuICAgICAgYm9vbDoge1xuICAgICAgICBtdXN0OiBbXG4gICAgICAgICAgbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pLFxuICAgICAgICAgIG1hdGNoVGVybVR5cGUoVGVybVRlcm1UeXBlLm1vZGVsKVxuICAgICAgICBdXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1ldGhvZHNCeUlkID0gYXdhaXQgZnJvbShtb2RlbHMpLnBpcGUoXG4gICAgICBmaWx0ZXIodiA9PiAhIXYpLFxuICAgICAgZGlzdGluY3QodiA9PiB2WydAaWQnXSksXG4gICAgICByZWR1Y2UoKHByZXYsIGN1cnIpID0+ICh7IC4uLnByZXYsIFtjdXJyWydAaWQnXV06IGN1cnIgfSksIHt9KVxuICAgICkudG9Qcm9taXNlKCk7XG5cbiAgICAvLyBmcm9tIGBtb2RlbC1saW5rcy5qc29uYCBmaWxlXG4gICAgY29uc3QgZW5naW5lTW9kZWxzID0gYXdhaXQgdGhpcy5lbmdpbmVTZXJ2aWNlLm1vZGVscygpO1xuXG4gICAgdGhpcy5hbGxUZXJtcyA9IGF3YWl0IGNvbXB1dGVUZXJtcyh0aGlzLm9yaWdpbmFsVmFsdWVzLCB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcywgdGhpcy50ZXJtcywgdGhpcy5maWx0ZXJUZXJtVHlwZXMpO1xuXG4gICAgdGhpcy5hbGxCbGFua05vZGVzID0gdGhpcy5hbGxUZXJtcy5mbGF0TWFwKFxuICAgICAgZ3JvdXBMb2dzQnlUZXJtKHRoaXMubm9kZVR5cGUsIGxvZ3MsIGVuZ2luZU1vZGVscywgY29uZmlnLCB0aGlzLm9yaWdpbmFsVmFsdWVzLCB0aGlzLnJlY2FsY3VsYXRlZFZhbHVlcywgdGhpcy5ub2RlS2V5KVxuICAgICk7XG4gICAgdGhpcy5tZXRob2RNb2RlbHNDb3VudCA9IG1vZGVsQ291bnQodGhpcy5hbGxCbGFua05vZGVzKTtcbiAgICB0aGlzLnJvd3NDb3VudCA9IHRoaXMuYWxsQmxhbmtOb2Rlcy5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHByZXYgKyAxICsgY3Vyci5zdWJWYWx1ZXMubGVuZ3RoICsgY3Vyci5rZXlzLmxlbmd0aCwgMCk7XG5cbiAgICB0aGlzLnRlcm1zQnlJZCA9IGF3YWl0IG9mKHRoaXMuYWxsQmxhbmtOb2RlcykucGlwZShcbiAgICAgIG1lcmdlTWFwKHYgPT4gdi5mbGF0TWFwKHZ2ID0+IHZ2LnN1YlZhbHVlcykpLFxuICAgICAgbWFwKHYgPT4gdi5pZCksXG4gICAgICBkaXN0aW5jdCgpLFxuICAgICAgdG9BcnJheSgpLFxuICAgICAgbWVyZ2VNYXAoaWRzID0+IGZyb20odGhpcy5zZWFyY2hUZXJtcyh7XG4gICAgICAgIGJvb2w6IHtcbiAgICAgICAgICBtdXN0OiBbXG4gICAgICAgICAgICBtYXRjaFR5cGUoTm9kZVR5cGUuVGVybSlcbiAgICAgICAgICBdLFxuICAgICAgICAgIHNob3VsZDogaWRzLm1hcChpZCA9PiBtYXRjaEV4YWN0UXVlcnkoJ0BpZCcsIGlkKSksXG4gICAgICAgICAgbWluaW11bV9zaG91bGRfbWF0Y2g6IDFcbiAgICAgICAgfVxuICAgICAgfSkpKSxcbiAgICAgIG1lcmdlQWxsKCksXG4gICAgICByZWR1Y2UoKHByZXYsIGN1cnIpID0+ICh7IC4uLnByZXYsIFtjdXJyWydAaWQnXV06IGN1cnIgfSksIHt9KVxuICAgICkudG9Qcm9taXNlKCk7XG5cbiAgICB0aGlzLmZpbHRlclJlc3VsdHMoKTtcblxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dzKCkge1xuICAgIHJldHVybiB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyh0aGlzLm5vZGUpLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWdnZXN0QnlUZXJtKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiBmcm9tKHRoaXMuYWxsVGVybXMpLnBpcGUoXG4gICAgICBtYXAodiA9PiB2Lm5hbWUpLFxuICAgICAgZmlsdGVyKHYgPT4gdi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0udG9Mb3dlckNhc2UoKSkpLFxuICAgICAgdG9BcnJheSgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VhcmNoVGVybXMocXVlcnk6IGFueSkge1xuICAgIGNvbnN0IHsgcmVzdWx0cyB9ID0gYXdhaXQgdGhpcy5zZWFyY2hTZXJ2aWNlLnNlYXJjaDxJVGVybUpTT05MRCwgTm9kZVR5cGUuVGVybT4oe1xuICAgICAgZmllbGRzOiBbJ0B0eXBlJywgJ0BpZCcsICduYW1lJ10sXG4gICAgICBsaW1pdDogMTAwMDAsXG4gICAgICBxdWVyeVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgcHVibGljIHRyYWNrQnlCbGFua05vZGUoX2luZGV4OiBudW1iZXIsIG5vZGU6IElCbGFua05vZGVMb2cpIHtcbiAgICByZXR1cm4gbm9kZS50ZXJtSWQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZpbHRlcmVkVHlwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJUZXJtVHlwZXM/Lm1hcCh0ZXJtVHlwZUxhYmVsKS5qb2luKCcgJiAnKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXJSZXN1bHRzKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5ibGFua05vZGVzID0gdGhpcy5hbGxCbGFua05vZGVzLmZpbHRlcigoeyB0ZXJtOiB7IG5hbWUgfSwgc3ViVmFsdWVzLCAuLi5sb2cgfSkgPT5cbiAgICAgICAgdGhpcy50ZXJtXG4gICAgICAgICAgPyBuYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGhpcy50ZXJtLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgOiAoXG4gICAgICAgICAgICAhdGhpcy5maWx0ZXJUZXJtVHlwZXM/Lmxlbmd0aCB8fFxuICAgICAgICAgICAgIXRoaXMub25seVJlcXVpcmVkIHx8IGlzU3lzdGVtQm91bmRhcnkobG9nKSB8fCBzdWJWYWx1ZXMuc29tZShpc1N5c3RlbUJvdW5kYXJ5KVxuICAgICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbWV0aG9kTmFtZSh7IG1ldGhvZElkLCBtb2RlbCB9OiBJQ29uZmlnTW9kZWwpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRob2RzQnlJZFttZXRob2RJZF0/Lm5hbWUgfHwgbWV0aG9kSWRMYWJlbChtZXRob2RJZCwgbW9kZWwpO1xuICB9XG5cbiAgcHVibGljIGhhc01ldGhvZFRpZXIodmFsdWVzOiBibGFua05vZGVbXSwgbWV0aG9kVGllcjogRW1pc3Npb25NZXRob2RUaWVyKSB7XG4gICAgcmV0dXJuIHZhbHVlcy5zb21lKHYgPT4gJ21ldGhvZFRpZXInIGluIHYgJiYgdi5tZXRob2RUaWVyID09PSBtZXRob2RUaWVyKTtcbiAgfVxuXG4gIHB1YmxpYyB0ZXJtQnlJZChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMudGVybXNCeUlkW2lkXSB8fCB7XG4gICAgICAnQHR5cGUnOiBOb2RlVHlwZS5UZXJtLFxuICAgICAgJ0BpZCc6IGlkLFxuICAgICAgbmFtZTogdGVybVR5cGVMYWJlbChpZClcbiAgICB9IGFzIElUZXJtSlNPTkxEO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicHgtMyBwYi0zXCI+XG4gIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1yaWdodCBtYi0yXCIgKm5nSWY9XCIhaXNFeHRlcm5hbFwiPlxuICAgIDxhIGNsYXNzPVwiaXMtc2l6ZS03XCIgKm5nSWY9XCJsb2dzVXJsXCIgW2hyZWZdPVwibG9nc1VybFwiIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgPGZhLWljb24gaWNvbj1cImV4dGVybmFsLWxpbmstYWx0XCI+PC9mYS1pY29uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0yXCI+T3BlbiBGdWxsIExvZ3M8L3NwYW4+XG4gICAgPC9hPlxuICA8L2Rpdj5cblxuICA8aGUtZGF0YS10YWJsZSBjbGFzcz1cIm1iLTEgaXMtc21hbGxcIiBbc21hbGxdPVwidHJ1ZVwiIFtuYlJvd3NdPVwicm93c0NvdW50XCIgbWF4SGVpZ2h0PVwiMzIwXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZnVsbHdpZHRoIGlzLW5hcnJvdyBpcy1zdHJpcGVkXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ3aWR0aC1hdXRvIGhhcy1ib3JkZXItcmlnaHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udHJvbCBpcy1leHBhbmRlZCBoYXMtaWNvbnMtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbnB1dCBzZWFyY2gtaW5wdXQgaXMtc21hbGxcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ0ZXJtXCIgbmFtZT1cInRlcm1cIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgYnkgbmFtZVwiXG4gICAgICAgICAgICAgICAgICBbbmdiVHlwZWFoZWFkXT1cInN1Z2dlc3RUZXJtXCJcbiAgICAgICAgICAgICAgICAgIFtmb2N1c0ZpcnN0XT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgIChzZWxlY3RJdGVtKT1cImZpbHRlclJlc3VsdHMoKVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiaWNvbiBpcy1zbWFsbCBpcy1yaWdodFwiXG4gICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaGlkZGVuXT1cIiF0ZXJtXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0ZXJtID0gJyc7IGZpbHRlclJlc3VsdHMoKTtcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJ0aW1lc1wiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90aD5cbiAgICAgICAgICA8dGg+VW5pdHM8L3RoPlxuICAgICAgICAgIDx0aD5PcmlnaW5hbDwvdGg+XG4gICAgICAgICAgPHRoPlJlY2FsY3VsYXRlZDwvdGg+XG4gICAgICAgICAgPHRoPkRpZmZlcmVuY2U8L3RoPlxuICAgICAgICAgIDx0aCAqbmdGb3I9XCJsZXQgYyBvZiBtZXRob2RNb2RlbHNDb3VudCB8IHRpbWVzOyBsZXQgaSA9IGluZGV4XCI+KHt7aSArIDF9fSk8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyICpuZ0lmPVwibG9hZGluZ1wiPlxuICAgICAgICAgIDx0ZCBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkXCIgY29sc3Bhbj1cIjZcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXIgcHktM1wiPlxuICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwic3Bpbm5lclwiIFtwdWxzZV09XCJ0cnVlXCIgc2l6ZT1cImxnXCI+PC9mYS1pY29uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyICpuZ0lmPVwiIWxvYWRpbmcgJiYgYmxhbmtOb2Rlcy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiIGNvbHNwYW49XCI2XCI+XG4gICAgICAgICAgICA8c3Bhbj5ObyBkYXRhPC9zcGFuPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGJsYW5rTm9kZSBvZiBibGFua05vZGVzOyB0cmFja0J5OiB0cmFja0J5QmxhbmtOb2RlXCI+XG4gICAgICAgICAgPHRyIFtjbGFzcy5oYXMtc3ViLXJvd3NdPVwiYmxhbmtOb2RlLmNhbk9wZW5cIj5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIndpZHRoLWF1dG8gaGFzLWJvcmRlci1yaWdodFwiIFthdHRyLnRpdGxlXT1cImJsYW5rTm9kZS50ZXJtLm5hbWVcIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2sgaXMtYWxpZ24tdG9wIHByLTIgb3Blbi1ub2RlXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiYmxhbmtOb2RlLmlzT3BlbiA9ICFibGFua05vZGUuaXNPcGVuXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImJsYW5rTm9kZS5jYW5PcGVuXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgICAgICA8ZmEtaWNvbiBpY29uPVwiYW5nbGUtcmlnaHRcIiBbY2xhc3MuaXMtaGlkZGVuXT1cImJsYW5rTm9kZS5pc09wZW5cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGhlLW5vZGUtbGluayBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiIFtub2RlXT1cImJsYW5rTm9kZS50ZXJtXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ub3dyYXAgaGFzLXRleHQtZWxsaXBzaXNcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtLm5hbWUgfCBjb21wb3VuZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0T3JpZ2luYWxWYWx1ZT5cbiAgICAgICAgICAgICAgICA8c3Bhbj57e2JsYW5rTm9kZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319PC9zcGFuPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRPcmlnaW5hbFZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPnt7YmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXSB8IHByZWNpc2lvbjozIHwgZGVmYXVsdDonLSd9fTwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYmxhbmtOb2RlLmlzT3JpZ2luYWwgfHwgYmxhbmtOb2RlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFJlY2FsY3VsYXRlZFZhbHVlPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3tibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxhbmtOb2RlLmFsbFBhcmFsbGVsOyBlbHNlIGRlZmF1bHRSZWNhbGN1bGF0ZWRWYWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbW9kZWwgb2YgYmxhbmtOb2RlLmNvbmZpZ01vZGVsc1swXVwiPnt7YmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwiaXMtbm93cmFwXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdERlbHRhVmFsdWU+XG4gICAgICAgICAgICAgICAgPGhlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGEgKm5nSWY9XCJibGFua05vZGUub3JpZ2luYWwubGVuZ3RoICYmIGJsYW5rTm9kZS5pc1JlY2FsY3VsYXRlZDsgZWxzZSBub1ZhbHVlXCJcbiAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW29yaWdpbmFsVmFsdWVdPVwiYmxhbmtOb2RlLm9yaWdpbmFsVmFsdWVcIlxuICAgICAgICAgICAgICAgID48L2hlLWJsYW5rLW5vZGUtdmFsdWUtZGVsdGE+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJibGFua05vZGUuYWxsUGFyYWxsZWw7IGVsc2UgZGVmYXVsdERlbHRhVmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtb2RlbCBvZiBibGFua05vZGUuY29uZmlnTW9kZWxzWzBdXCI+XG4gICAgICAgICAgICAgICAgICA8aGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YSAqbmdJZj1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gIT09IG51bGwgJiYgYmxhbmtOb2RlLnJlY2FsY3VsYXRlZFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF0gIT09IG51bGw7IGVsc2Ugbm9WYWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJibGFua05vZGUucmVjYWxjdWxhdGVkVmFsdWVCeU1ldGhvZElkW21vZGVsLm1ldGhvZElkXVwiXG4gICAgICAgICAgICAgICAgICAgIFtvcmlnaW5hbFZhbHVlXT1cImJsYW5rTm9kZS5vcmlnaW5hbFZhbHVlQnlNZXRob2RJZFttb2RlbC5tZXRob2RJZF1cIlxuICAgICAgICAgICAgICAgICAgPjwvaGUtYmxhbmstbm9kZS12YWx1ZS1kZWx0YT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsczsgY29udGV4dDoge2RhdGE6IGJsYW5rTm9kZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgPHRyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3ViVmFsdWUgb2YgYmxhbmtOb2RlLmtleXNcIlxuICAgICAgICAgICAgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgICBbY2xhc3MuaGFzLXN1Yi1yb3dzXT1cImJsYW5rTm9kZS5zdWJWYWx1ZXM/Lmxlbmd0aFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zIHByLTEgZmllbGQtbm9kZVwiPkZpZWxkOjwvc3Bhbj5cblxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9ja1wiICpuZ0lmPVwiYmxhbmtOb2RlLnR5cGVcIlxuICAgICAgICAgICAgICAgIFtocmVmXT1cImJhc2VVcmwgKyAnL3NjaGVtYS8nICsgYmxhbmtOb2RlLnR5cGUgKyAnIycgKyBzdWJWYWx1ZS5rZXlcIiB0YXJnZXQ9XCJfYmxhbmtcIiBbdGl0bGVdPVwic3ViVmFsdWUua2V5XCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwIGhhcy10ZXh0LWVsbGlwc2lzXCI+e3tzdWJWYWx1ZS5rZXl9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3BcIiAqbmdJZj1cIiFibGFua05vZGUudHlwZVwiPnt7c3ViVmFsdWUua2V5fX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic3ViVmFsdWUub3JpZ2luYWxWYWx1ZSAhPT0gbnVsbDsgZWxzZSBub1ZhbHVlXCI+e3tzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5pc1JlY2FsY3VsYXRlZCB8fCBzdWJWYWx1ZS5rZXkgPT09ICdpbXBhY3RBc3Nlc3NtZW50JzsgZWxzZSBub3RSZWNhbGN1bGF0ZWRcIj5cbiAgICAgICAgICAgICAgICB7e3N1YlZhbHVlLnJlY2FsY3VsYXRlZFZhbHVlIHwgcHJlY2lzaW9uOjMgfCBkZWZhdWx0OictJ319XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+LTwvdGQ+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmxhbmtOb2RlTW9kZWxzOyBjb250ZXh0OiB7ZGF0YTogc3ViVmFsdWV9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90cj5cblxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IHN1YlZhbHVlIG9mIGJsYW5rTm9kZS5zdWJWYWx1ZXNcIlxuICAgICAgICAgICAgW2NsYXNzLmlzLWhpZGRlbl09XCIhYmxhbmtOb2RlLmlzT3BlblwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwid2lkdGgtYXV0byBoYXMtYm9yZGVyLXJpZ2h0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLXRvcCBwbC0zXCI+e3tzdWJWYWx1ZS5rZXkgfCBrZXlUb0xhYmVsfX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN1YlZhbHVlLmlkXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi10b3AgcHItMVwiPjo8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJzdWJWYWx1ZS5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrXCIgKm5nU3dpdGNoQ2FzZT1cIidiYWNrZ3JvdW5kRGF0YSdcIj57e3N1YlZhbHVlLmlkIHwga2V5VG9MYWJlbH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGhlLW5vZGUtbGluayAqbmdTd2l0Y2hEZWZhdWx0IGNsYXNzPVwiaXMtYmxvY2sgcGwtNFwiIFtub2RlXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKVwiIFthdHRyLnRpdGxlXT1cInRlcm1CeUlkKHN1YlZhbHVlLmlkKS5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtbm93cmFwIGhhcy10ZXh0LWVsbGlwc2lzXCIgW2lubmVySHRtbF09XCJ0ZXJtQnlJZChzdWJWYWx1ZS5pZCkubmFtZSB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9oZS1ub2RlLWxpbms+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5zaG93VW5pdHNcIiBbaW5uZXJIdG1sXT1cImJsYW5rTm9kZS50ZXJtPy51bml0cyB8IGNvbXBvdW5kXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdWJWYWx1ZS5vcmlnaW5hbFZhbHVlICE9PSBudWxsOyBlbHNlIG5vVmFsdWVcIj57e3N1YlZhbHVlLm9yaWdpbmFsVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX08L3NwYW4+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInN1YlZhbHVlLmlzUmVjYWxjdWxhdGVkOyBlbHNlIG5vdFJlY2FsY3VsYXRlZFwiPlxuICAgICAgICAgICAgICAgIHt7c3ViVmFsdWUucmVjYWxjdWxhdGVkVmFsdWUgfCBwcmVjaXNpb246MyB8IGRlZmF1bHQ6Jy0nfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbHM7IGNvbnRleHQ6IHtkYXRhOiBzdWJWYWx1ZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9oZS1kYXRhLXRhYmxlPlxuXG4gIDxkaXYgY2xhc3M9XCJpcy1zaXplLTcgaXMtaXRhbGljXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbnMgaXMtdmFyaWFibGUgaXMtMSBteS0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGlzLW5hcnJvd1wiPlxuICAgICAgICA8cD5cbiAgICAgICAgICA8YSBjbGFzcz1cImlzLWlubGluZS1ibG9jayBwci0yXCJcbiAgICAgICAgICAgIChjbGljayk9XCJzaG93TGVnZW5kID0gIXNob3dMZWdlbmRcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1kb3duXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhc2hvd0xlZ2VuZFwiPjwvZmEtaWNvbj5cbiAgICAgICAgICAgIDxmYS1pY29uIGljb249XCJhbmdsZS1yaWdodFwiIFtjbGFzcy5pcy1oaWRkZW5dPVwic2hvd0xlZ2VuZFwiPjwvZmEtaWNvbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1pbmxpbmUtYmxvY2tcIj5MZWdlbmQ6PC9zcGFuPlxuICAgICAgICA8L3A+XG4gICAgICAgIDx1bCBjbGFzcz1cImNvbnRlbnQgcGwtMlwiIFtjbGFzcy5pcy1oaWRkZW5dPVwiIXNob3dMZWdlbmRcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdGF0dXMgb2YgTG9nU3RhdHVzIHwga2V5c1wiPlxuICAgICAgICAgICAgPGxpICpuZ0lmPVwibG9nSWNvbltzdGF0dXMudmFsdWVdXCIgY2xhc3M9XCJoYXMtdGV4dC17e2xvZ0NvbG9yW3N0YXR1cy52YWx1ZV19fVwiPlxuICAgICAgICAgICAgICA8ZmEtaWNvbiBbaWNvbl09XCJsb2dJY29uW3N0YXR1cy52YWx1ZV1cIj48L2ZhLWljb24+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiPnt7c3RhdHVzLnZhbHVlfX08L3NwYW4+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGhhcy10ZXh0LXJpZ2h0XCIgKm5nSWY9XCJmaWx0ZXJlZFR5cGVcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGNoZWNrYm94XCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwic2VsZWN0b3JcIlxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJvbmx5UmVxdWlyZWRcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJmaWx0ZXJSZXN1bHRzKClcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiEhdGVybVwiXG4gICAgICAgICAgPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlNob3cgb25seSB7e2ZpbHRlcmVkVHlwZSB8IHBsdXJhbGl6ZX19IGluY2x1ZGVkIGluIHRoZSBkZWZhdWx0IEhlc3RpYSBzeXN0ZW0gYm91bmRhcnk8L3NwYW4+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNibGFua05vZGVNb2RlbHMgbGV0LWRhdGE9XCJkYXRhXCI+XG4gIDx0ZCBjbGFzcz1cImJsYW5rLW5vZGUtaW5kZXgte3tpfX1cIiAqbmdGb3I9XCJsZXQgYyBvZiBtZXRob2RNb2RlbHNDb3VudCB8IHRpbWVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldE1vZGVsc0F0KGRhdGEsIGkpOyBsZXQgbW9kZWxzOyBlbHNlIG5vVmFsdWVcIj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjbW9kZWxTZXJpZT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImJsYW5rTm9kZU1vZGVsOyBjb250ZXh0OiB7bW9kZWw6bW9kZWxzLCBkYXRhfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxkaXYgKm5nSWY9XCJtb2RlbHMgfCBpc0FycmF5OyBlbHNlIG1vZGVsU2VyaWVcIj5cbiAgICAgICAgPHAgKm5nRm9yPVwibGV0IG1vZGVsIG9mIG1vZGVsc1wiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJibGFua05vZGVNb2RlbDsgY29udGV4dDoge21vZGVsLCBkYXRhfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC90ZD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjYmxhbmtOb2RlTW9kZWwgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPHNwYW5cbiAgICBbY2xhc3MudHJpZ2dlci1wb3BvdmVyXT1cIm1vZGVsLnNob3dMb2dzXCJcbiAgICBbbmdiUG9wb3Zlcl09XCJsb2dEZXRhaWxzXCIgW2F1dG9DbG9zZV09XCInb3V0c2lkZSdcIiBwb3BvdmVyQ2xhc3M9XCJpcy1uYXJyb3dcIlxuICAgIHRyaWdnZXJzPVwibWFudWFsXCIgI3A9XCJuZ2JQb3BvdmVyXCIgcGxhY2VtZW50PVwibGVmdFwiIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgIChjbGljayk9XCJwLmlzT3BlbigpID8gcC5jbG9zZSgpIDogKG1vZGVsLnNob3dMb2dzID8gcC5vcGVuKHsgbG9nczogbW9kZWwubG9ncyB9KSA6IG51bGwpXCJcbiAgPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtY2FwaXRhbGl6ZWRcIj57e21ldGhvZE5hbWUobW9kZWwpfX08L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzPy5tZXRob2RUaWVyIHx8IG1vZGVsLm1vZGVsPy5tZXRob2RUaWVyXCI+W3t7bW9kZWwubG9ncz8ubWV0aG9kVGllciB8fCBtb2RlbC5tb2RlbD8ubWV0aG9kVGllcn19XTwvc3Bhbj5cblxuICAgIDxzcGFuIGNsYXNzPVwicGwtMSBoYXMtdGV4dC17e2xvZ0NvbG9yW21vZGVsLnN0YXR1c119fSB0cmlnZ2VyLXBvcG92ZXJcIlxuICAgICAgW25nYlBvcG92ZXJdPVwibG9nU3RhdHVzRGV0YWlsc1wiIFthdXRvQ2xvc2VdPVwiJ291dHNpZGUnXCIgcG9wb3ZlckNsYXNzPVwiaXMtbmFycm93XCJcbiAgICAgIHRyaWdnZXJzPVwibWFudWFsXCIgI3AxPVwibmdiUG9wb3ZlclwiIHBsYWNlbWVudD1cImxlZnRcIiBjb250YWluZXI9XCJib2R5XCJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IHAxLmlzT3BlbigpID8gcDEuY2xvc2UoKSA6IHAxLm9wZW4oeyBtb2RlbCwgZGF0YSB9KVwiXG4gICAgPlxuICAgICAgPGZhLWljb24gW2ljb25dPVwibG9nSWNvblttb2RlbC5zdGF0dXNdXCI+PC9mYS1pY29uPlxuICAgIDwvc3Bhbj5cblxuICAgIDxzcGFuIGNsYXNzPVwicGwtMVwiICpuZ0lmPVwibW9kZWwubW9kZWxcIj5cbiAgICAgICg8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZG9jc0xpbms7IGNvbnRleHQ6IHskaW1wbGljaXQ6IG1vZGVsLm1vZGVsfVwiPjwvbmctY29udGFpbmVyPilcbiAgICA8L3NwYW4+XG4gIDwvc3Bhbj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbm9WYWx1ZT4tPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNub3RSZWNhbGN1bGF0ZWQ+bm90IHJlY2FsY3VsYXRlZDwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbG9nRGV0YWlscyBsZXQtbG9ncz1cImxvZ3NcIj5cbiAgPGRpdiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lclwiICpiaW5kT25jZT1cImxvZ3NcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWZ1bGx3aWR0aFwiPlxuICAgICAgPHRib2R5PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9ncz8ucmVxdWlyZW1lbnRzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIHJlcXVpcmVtZW50S2V5cyhsb2dzLnJlcXVpcmVtZW50cylcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OntrZXksIHZhbHVlOmxvZ3MucmVxdWlyZW1lbnRzW2tleV19XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2dzPy5sb2dzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQga2V5IG9mIGxvZ3MubG9ncyB8IGtleXNcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2dMaW5lOyBjb250ZXh0OmtleVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJsb2dzXCI+XG4gICAgPGRpdiBjbGFzcz1cIml0LW10LTJcIiAqbmdJZj1cImxvZ3M/Lm1pc3NpbmdMb29rdXBzPy5sZW5ndGhcIj5cbiAgICAgIDxwPk9wdGlvbmFsIGRhdGEgbWlzc2luZzo8L3A+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXIgZGF0YS10YWJsZS1jb250YWluZXJcIj5cbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgaXMtZGFyayBpcy1mdWxsd2lkdGggaXMtc3RyaXBlZFwiPlxuICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoPlxuICAgICAgICAgICAgICAgIDxzcGFuPkZpbGVuYW1lPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGg+XG4gICAgICAgICAgICAgICAgPHNwYW4+Q29sdW1uIFRpdGxlPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGg+XG4gICAgICAgICAgICAgICAgPHNwYW4+Um93ICh0ZXJtLmlkKTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XCJoYXMtYmFja2dyb3VuZC1ibGFjayBoYXMtdGV4dC13aGl0ZVwiPlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBkYXRhIG9mIGxvZ3MubWlzc2luZ0xvb2t1cHNcIj5cbiAgICAgICAgICAgICAgPHRkPnt7ZGF0YS5maWxlbmFtZX19PC90ZD5cbiAgICAgICAgICAgICAgPHRkPnt7ZGF0YS5jb2x1bW59fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57e2RhdGEudGVybUlkfX08L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2dMaW5lVmFsdWUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFZhbHVlPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtaW5saW5lLWJsb2NrIGlzLWFsaWduLW1pZGRsZVwiPnt7dmFsdWV9fTwvc3Bhbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInJlcXVpcmVtZW50TGlua2VkTm9kZShrZXksIHZhbHVlKTsgbGV0IGxpbmtlZE5vZGU7IGVsc2UgZGVmYXVsdFZhbHVlXCI+XG4gICAgPGhlLW5vZGUtbGluayBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBsaW5rQ2xhc3M9XCJpcy1kYXJrXCIgW25vZGVdPVwibGlua2VkTm9kZVwiIFtzaG93RXh0ZXJuYWxMaW5rXT1cInRydWVcIj48L2hlLW5vZGUtbGluaz5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ0xpbmUgbGV0LWtleT1cImtleVwiIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gIDx0cj5cbiAgICA8dGQgY2xhc3M9XCJoYXMtYm9yZGVyLXJpZ2h0XCI+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBbbmdTd2l0Y2hdPVwia2V5XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD57e2tleSB8IGtleVRvTGFiZWx9fTwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidub2RlX3R5cGVfYWxsb3dlZCdcIj5JcyB0aGUgY3VycmVudCA8Y29kZT5Ob2RlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzaXRlVHlwZV9hbGxvd2VkJ1wiPklzIHRoZSBjdXJyZW50IDxjb2RlPnNpdGVUeXBlPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfaWRfYWxsb3dlZCdcIj5JcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3QgPGNvZGU+QGlkPC9jb2RlPiBhbGxvd2VkIHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwcmltYXJ5X3Byb2R1Y3RfdGVybVR5cGVfYWxsb3dlZCdcIj5JcyB0aGUgY3VycmVudCBwcmltYXJ5IHByb2R1Y3QgPGNvZGU+dGVybVR5cGU8L2NvZGU+IGFsbG93ZWQgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInZ2Vvc3BhdGlhbF9kYXRhJ1wiPkhhcyBnZW9zcGF0aWFsIGRhdGEgbmVjZXNzYXJ5IHRvIHJ1biB0aGlzIG1vZGVsPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidjb250YWluc19nZW9zcGF0aWFsX2RhdGEnXCI+SGFzIGdlb3NwYXRpYWwgZGF0YSBuZWNlc3NhcnkgdG8gcnVuIHRoaXMgbW9kZWw8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2N1cnJlbnRfc2l6ZSdcIj5DdXJyZW50IHBvbHlnb24gYXJlYTwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInbWF4X2FyZWFfc2l6ZSdcIj5NYXhpbXVtIHBvbHlnb24gYXJlYSB0byBydW4gdGhpcyBtb2RlbDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInYmVsb3dfbWF4X2FyZWFfc2l6ZSdcIj5Qb2x5Z29uIGJlbG93IHRoZSBtYXhpbXVtIGFyZWE8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3JlZ2lvbl9mYWN0b3InXCI+RmFjdG9yIGZyb20gcmVnaW9uIGxvb2t1cDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidwZXN0aWNpZGVzX2NvbXBsZXRlJ1wiPlBlc3RpY2lkZSBkYXRhIGFyZSA8Y29kZT5jb21wbGV0ZTwvY29kZT48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2hhc19wZXN0aWNpZGVzX2lucHV0cydcIj5DeWNsZSBjb250YWlucyA8Y29kZT5wZXN0aWNpZGVBSTwvY29kZT4gSW5wdXRzPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidhbGxfcGVzdGljaWRlQUlfaGF2ZV9sb29rdXBfdmFsdWUnXCI+QWxsIDxjb2RlPnBlc3RpY2lkZUFJPC9jb2RlPiBJbnB1dHMgaGF2ZSBhIGxvb2t1cCB2YWx1ZTwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidoYXNfY3JvcF9yZXNpZHVlX2J1cm50J1wiPjxjb2RlPmFib3ZlR3JvdW5kQ3JvcFJlc2lkdWVCdXJudDwvY29kZT4gaXMgcHJlc2VudCBhcyBQcm9kdWN0PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2xpcXVpZF9zbHVycnlfc2x1ZGdlX1AnXCI+TGlxdWlkLCBTbHVycnksIGFuZCBTbHVkZ2UgUDwvbmctY29udGFpbmVyPlxuICAgICAgPC9zcGFuPlxuICAgICAgPGhlLWNsaXBib2FyZCBjbGFzcz1cImlzLWlubGluZS1ibG9jayBpcy1hbGlnbi1taWRkbGVcIiBjbGlwYm9hcmRDbGFzcz1cImlzLXNpemUtNyBpcy1wLTFcIiBbaWNvbl09XCJbJ2ZhcicsICdjbG9uZSddXCIgW3ZhbHVlXT1cImtleVwiIFtoaWRlVGV4dF09XCJ0cnVlXCI+PC9oZS1jbGlwYm9hcmQ+XG4gICAgPC90ZD5cbiAgICA8dGQ+XG4gICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVZhbHVlPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9nTGluZVZhbHVlOyBjb250ZXh0OntrZXksdmFsdWV9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPGRpdiAqbmdJZj1cImxvZ1ZhbHVlQXJyYXkodmFsdWUpOyBsZXQgdmFsdWVBcnJheTsgZWxzZSBzaW5nbGVWYWx1ZVwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBpcy1kYXJrIGlzLWJvcmRlcmVkIGlzLXN0cmlwZWRcIj5cbiAgICAgICAgICA8dGhlYWQgKm5nSWY9XCJ2YWx1ZUFycmF5WzBdIHwgaXNPYmplY3RcIj5cbiAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiaGFzLXRleHQtd2hpdGVcIiAqbmdGb3I9XCJsZXQgdiBvZiB2YWx1ZUFycmF5WzBdIHwga2V5c1wiPnt7di5rZXl9fTwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB2IG9mIHZhbHVlQXJyYXlcIj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNzaW5nbGVBcnJheVZhbHVlPlxuICAgICAgICAgICAgICAgIDx0ZD57e3Z9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2IHwgaXNPYmplY3Q7IGVsc2Ugc2luZ2xlQXJyYXlWYWx1ZVwiPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgdnYgb2YgdiB8IGtleXNcIj57e3Z2LnZhbHVlfX08L3RkPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvdGQ+XG4gIDwvdHI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvZ1N0YXR1c0RldGFpbHMgbGV0LW1vZGVsPVwibW9kZWxcIiBsZXQtZGF0YT1cImRhdGFcIj5cbiAgPG5nLWNvbnRhaW5lciAqYmluZE9uY2U9XCJtb2RlbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJpcy1tYi0yXCI+XG4gICAgICA8c3Bhbj5TdGF0dXM6PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+e3ttb2RlbC5zdGF0dXN9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cblxuICAgIDxuZy10ZW1wbGF0ZSAjc2hvd1J1bk9yY2hlc3RyYXRvcj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpcy1ydW4tb3JjaGVzdHJhdG9yXCI+XG4gICAgICAgIDxwICpuZ0lmPVwibW9kZWwubG9ncz8uc2hvdWxkUnVuXCI+QWxsIHRoZSByZXF1aXJlbWVudHMgd2VyZSBtZXQgdG8gcnVuIHRoZSBtb2RlbC48L3A+XG4gICAgICAgIDxwICpuZ0lmPVwiIW1vZGVsLmxvZ3M/LnNob3VsZFJ1blwiPlxuICAgICAgICAgIFNvbWUgb2YgdGhlIHJlcXVpcmVtZW50cyB3ZXJlIG5vdCBtZXQgdG8gcnVuIHRoZSBtb2RlbC5cbiAgICAgICAgICBZb3UgY2FuIGNsaWNrIG9uIHRoZSBtb2RlbCBuYW1lIG9uIHRoZSBsZWZ0IHRvIHZpZXcgdGhlIGRlYnVnZ2luZyBsb2dzLlxuICAgICAgICA8L3A+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJtb2RlbC5sb2dzPy5sb2dzPy5lcnJvclwiPlxuICAgICAgICAgIDxwPlRoZSBtb2RlbCBmYWlsZWQgdG8gcnVuIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbjo8L3A+XG4gICAgICAgICAgPHA+PGNvZGU+e3ttb2RlbC5sb2dzLmxvZ3MuZXJyb3J9fTwvY29kZT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1uby1ydW4tb3JjaGVzdHJhdG9yXCIgKm5nSWY9XCJtb2RlbC5sb2dzPy5zaG91bGRSdW5PcmNoZXN0cmF0b3IgPT09IGZhbHNlOyBlbHNlIHNob3dSdW5PcmNoZXN0cmF0b3JcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwubG9ncy5ydW5SZXF1aXJlZFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXJ1bi1ub2RlLXR5cGUtbm90LWFsbG93ZWRcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ubm9kZV90eXBlX2FsbG93ZWQgPT09ICdGYWxzZSdcIj5cbiAgICAgICAgICBUaGlzIG1vZGVsIHNob3VsZCBub3QgcnVuIGZvciB7e25vZGVUeXBlIHwgcGx1cmFsaXplOjB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLXRlbXBsYXRlICNydW5Ob0NvbmZpZz5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ydW4tbm90LWVtcHR5XCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LmlzX2VtcHR5ID09PSAnRmFsc2UnXCI+XG4gICAgICAgICAgVGhlIHt7ZGF0YS50eXBlIHx8ICdibGFuayBub2RlJ319IHdpdGggVGVybSA8Y29kZT57e2RhdGEudGVybUlkfX08L2NvZGU+IGlzIGFscmVhZHkgcHJlc2VudCBvciBhbHJlYWR5IGFkZGVkIGJ5IGFub3RoZXIgbW9kZWwuXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlbC5jb25maWc7IGVsc2UgcnVuTm9Db25maWdcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlzLXJ1bi1zdHJhdGVneS17e21vZGVsLmNvbmZpZy5ydW5TdHJhdGVneX19XCIgW25nU3dpdGNoXT1cIm1vZGVsLmNvbmZpZy5ydW5TdHJhdGVneVwiPlxuICAgICAgICAgIDxzcGFuICpuZ1N3aXRjaENhc2U9XCInYWx3YXlzJ1wiPjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdTd2l0Y2hDYXNlPVwiJ2FkZF9rZXlfaWZfbWlzc2luZydcIj5cbiAgICAgICAgICAgIFdlIG9ubHkgZ2FwLWZpbGwgdGhpcyBrZXkgaWYgbm90IHByZXNlbnRcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nU3dpdGNoQ2FzZT1cIidhZGRfYmxhbmtfbm9kZV9pZl9taXNzaW5nJ1wiPlxuICAgICAgICAgICAgV2Ugb25seSBnYXAtZmlsbCB0aGlzIEJsYW5rIE5vZGUgaWYgbm90IHByZXNlbnQuXG4gICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1ydW4td2l0aC1tZWFzdXJlZFwiICpuZ0lmPVwibW9kZWwuY29uZmlnLnJ1bkFyZ3M/LnJ1bk5vbk1lYXN1cmVkICYmIGhhc01ldGhvZFRpZXIoZGF0YS5vcmlnaW5hbCwgRW1pc3Npb25NZXRob2RUaWVyLm1lYXN1cmVkKVwiPlxuICAgICAgICAgICAgVGhlIDxjb2RlPnt7bW9kZWwuY29uZmlnLnZhbHVlfX08L2NvZGU+IHdhcyBhbHJlYWR5IHJlcG9ydGVkIGFzIG1lYXN1cmVkLlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJpcy1uby1tZXJnZS1vcmNoZXN0cmF0b3JcIiAqbmdJZj1cIm1vZGVsLmxvZ3M/LnNob3VsZE1lcmdlID09PSBmYWxzZVwiPlxuICAgICAgPHAgY2xhc3M9XCJpcy1tZXJnZS1yZXBsYWNlVGhyZXNob2xkXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3M/LnJlcGxhY2VUaHJlc2hvbGRcIj5cbiAgICAgICAgPHNwYW4+VGhlPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57e21vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzPy5yZXBsYWNlVGhyZXNob2xkPy5bMF0gfHwgJ3ZhbHVlJ319PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5mcm9tIHRoaXMgbW9kZWwgd2FzPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZWwuY29uZmlnLm1lcmdlQXJnc1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZVRocmVzaG9sZCA9PT0gJ0ZhbHNlJ1wiPmxlc3MgdGhhbjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VUaHJlc2hvbGQgPT09ICdUcnVlJ1wiPm1vcmUgdGhhbjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiPnt7bW9kZWwuY29uZmlnLm1lcmdlQXJncy5yZXBsYWNlVGhyZXNob2xkWzFdICogMTAwfX0lPC9zcGFuPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbW9kZWwuY29uZmlnLm1lcmdlQXJnc1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCIgKm5nSWY9XCJtb2RlbC5sb2dzLmxvZ3MucmVwbGFjZVRocmVzaG9sZCA9PT0gJ0ZhbHNlJ1wiPm5vdCBzdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncy5yZXBsYWNlVGhyZXNob2xkID09PSAnVHJ1ZSdcIj5zdWZmaWNpZW50bHk8L3NwYW4+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpcy1wbC0xXCI+ZGlmZmVyZW50IGZyb20gdGhlIG9yaWdpbmFsPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj57e21vZGVsLmNvbmZpZz8ubWVyZ2VBcmdzPy5yZXBsYWNlVGhyZXNob2xkPy5bMF0gfHwgJ3ZhbHVlJ319Ljwvc3Bhbj5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgICA8cCBjbGFzcz1cImlzLW1lcmdlLXJlcGxhY2VMb3dlclRpZXJcIiAqbmdJZj1cIm1vZGVsLmxvZ3MubG9ncz8ucmVwbGFjZUxvd2VyVGllclwiPlxuICAgICAgPHNwYW4+VGhlIG1vZGVsIDxjb2RlPm1ldGhvZFRpZXI8L2NvZGU+IHdhczwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VMb3dlclRpZXIgPT09ICdGYWxzZSdcIj5oaWdoZXIgdGhhbjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwibW9kZWwubG9ncy5sb2dzLnJlcGxhY2VMb3dlclRpZXIgPT09ICdUcnVlJ1wiPmxvd2VyIHRoYW48L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXBsLTFcIj50aGUgb3JpZ2luYWwgPGNvZGU+bWV0aG9kVGllcjwvY29kZT48L3NwYW4+XG4gICAgPC9wPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZG9jc0xpbmsgbGV0LW1vZGVsPlxuICA8YSBbaHJlZl09XCJtb2RlbC5hcGlEb2NzUGF0aCB8fCBtb2RlbC5kb2NQYXRoIHx8IG1vZGVsLnBhdGhcIiB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICA+XG4gICAgPHNwYW4+RG9jczwvc3Bhbj5cbiAgICA8ZmEtaWNvbiBjbGFzcz1cIm1sLTFcIiBpY29uPVwiZXh0ZXJuYWwtbGluay1hbHRcIiBzaXplPVwic21cIj48L2ZhLWljb24+XG4gIDwvYT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=