ngx-filters
Version:
This library was generated for all type of frameworks such as Angular Material, Prime Ng, etc. Providing Filters such as Number Box, TextBox, Date, Single Select, Multi Select And True/False Filters for grids or list.
461 lines • 68.7 kB
JavaScript
import { ComponentFactoryResolver, Inject, Injectable, Injector, Optional } from '@angular/core';
import { NgxFilterConfig } from "./ngx-filter-config";
import { DateComponent } from "./components/date/date.component";
import { NumberBoxComponent } from "./components/number-box/number-box.component";
import { TextBoxComponent } from "./components/text-box/text-box.component";
import { TrueFalseComponent } from "./components/true-false/true-false.component";
import { MultiSelectBoxComponent } from "./components/select/multi-select-box/multi-select-box.component";
import { SelectBoxComponent } from "./components/select/select-box/select-box.component";
import * as moment from "jalali-moment";
import { ConditionsSelectorComponent } from "./components/conditions-selector/conditions-selector.component";
import { ConditionOperator, FilterTranslator, FilterTypes, PageFilter } from "./ngx-types";
import { NGX_FILTERS_CONFIGS } from "./ngx-filters-token";
import * as i0 from "@angular/core";
import * as i1 from "./ngx-filters-token";
export class NgxFiltersService {
constructor(injector, configs, resolver) {
this.resolver = resolver;
this.translator = {};
this.filtersComponent = {};
this.conditionSource = [];
this.useJalaliDate = false;
const defaultConfigs = {
trueFalseComponent: TrueFalseComponent,
dateComponent: DateComponent,
multiSelectBoxComponent: MultiSelectBoxComponent,
selectBoxComponent: SelectBoxComponent,
numberBoxComponent: NumberBoxComponent,
textBoxComponent: TextBoxComponent,
conditionSelectorComponent: ConditionsSelectorComponent,
translator: new FilterTranslator(),
};
if (!configs) {
configs = defaultConfigs;
}
else {
configs = Object.assign(defaultConfigs, configs);
}
this._configs = configs;
this.filtersComponent.textBox = this.resolver.resolveComponentFactory(configs.textBoxComponent);
this.filtersComponent.numberBox = this.resolver
.resolveComponentFactory(configs.numberBoxComponent);
this.filtersComponent.date = this.resolver
.resolveComponentFactory(configs.dateComponent);
this.filtersComponent.selectBox = this.resolver.resolveComponentFactory(configs.selectBoxComponent);
this.filtersComponent.multiSelectBox = this.resolver.resolveComponentFactory(configs.multiSelectBoxComponent);
this.filtersComponent.trueFalse = this.resolver.resolveComponentFactory(configs.trueFalseComponent);
this.filtersComponent.conditionSelector = this.resolver.resolveComponentFactory(configs.conditionSelectorComponent);
this.translator = configs.translator;
}
getComponentFactory(filterType) {
let component = null;
switch (filterType) {
case FilterTypes.DateTime:
component = this._configs.dateComponent;
break;
//case FilterTypes.ListCheck:
case FilterTypes.MultiSelect:
component = this._configs.multiSelectBoxComponent;
break;
case FilterTypes.Number:
component = this._configs.numberBoxComponent;
break;
case FilterTypes.SingleSelect:
component = this._configs.selectBoxComponent;
break;
case FilterTypes.TextBox:
component = this._configs.textBoxComponent;
break;
case FilterTypes.TrueFalse:
component = this._configs.trueFalseComponent;
break;
default: {
component = this._configs.conditionSelectorComponent;
}
}
if (component)
return this.resolver
.resolveComponentFactory(component);
return null;
}
checkHasFilter(filter) {
let hasFilter = (this.noValueConditions.includes(filter.conditionOperator))
||
(filter.type == FilterTypes.MultiSelect ? filter.values && filter.values.length > 0 : !!filter.value);
if (!hasFilter) {
if (filter.type === FilterTypes.Number && filter.value == 0) {
hasFilter = true;
}
if (filter.type === FilterTypes.Number && filter.conditionOperator === ConditionOperator.Between && filter.valueTo) {
filter.value = 0;
hasFilter = true;
}
}
return (hasFilter);
}
getConditionSource() {
const conditions = [];
for (let enumMember in ConditionOperator) {
const condition = ConditionOperator[enumMember];
const gcplat = this.getCondition(condition, null);
if (gcplat) {
conditions.push({
key: ConditionOperator[enumMember],
label: gcplat.label,
types: gcplat.types
});
}
}
return conditions;
}
getDefaultCondition(filterType) {
switch (filterType) {
case FilterTypes.MultiSelect:
case FilterTypes.ListCheck: {
return ConditionOperator.InRange;
}
case FilterTypes.TrueFalse:
case FilterTypes.SingleSelect:
case FilterTypes.Number: {
return ConditionOperator.Equal;
}
case FilterTypes.TextBox: {
return ConditionOperator.Contains;
}
case FilterTypes.DateTime: {
return ConditionOperator.Between;
}
}
}
getConditionLabel(condition) {
if (condition) {
const conditionKey = condition[0].toLowerCase() + condition.substring(1);
if (this.translator) {
return this.translator[conditionKey + 'Label'];
}
else {
return condition;
}
}
return "";
}
getCondition(condition, filter) {
condition = condition || filter.conditionOperator;
const label = this.getConditionLabel(condition);
switch (condition) {
case ConditionOperator.Between:
return { label, types: [FilterTypes.Number, FilterTypes.DateTime], hasValue: true };
case ConditionOperator.Contains:
return { label, types: [FilterTypes.TextBox], hasValue: true };
case ConditionOperator.EndWith:
return { label, types: [FilterTypes.TextBox], hasValue: true };
case ConditionOperator.NotContains:
return { label, types: [FilterTypes.TextBox], hasValue: true };
case ConditionOperator.Equal:
return { label, types: [FilterTypes.Number], hasValue: true };
case ConditionOperator.Exact:
return { label, types: [FilterTypes.DateTime, FilterTypes.TextBox], hasValue: true };
case ConditionOperator.GreaterThan:
return { label, types: [FilterTypes.Number, FilterTypes.DateTime], hasValue: true };
case ConditionOperator.GreaterThanOrEqual:
return { label, types: [FilterTypes.Number, FilterTypes.DateTime], hasValue: true };
case ConditionOperator.LessThan:
return { label, types: [FilterTypes.Number, FilterTypes.DateTime], hasValue: true };
case ConditionOperator.LessThanOrEqual:
return { label, types: [FilterTypes.Number, FilterTypes.DateTime], hasValue: true };
case ConditionOperator.NotEqual:
return { label, types: [FilterTypes.Number], hasValue: true };
case ConditionOperator.StartWith:
return { label, types: [FilterTypes.TextBox], hasValue: true };
case ConditionOperator.InRange:
return { label, types: [FilterTypes.ListCheck], hasValue: true };
case ConditionOperator.LastMonth:
return { label, types: [FilterTypes.DateTime], hasValue: false };
case ConditionOperator.LastWeek:
return { label, types: [FilterTypes.DateTime], hasValue: false };
case ConditionOperator.CurrentMonth:
return { label, types: [FilterTypes.DateTime], hasValue: false };
case ConditionOperator.CurrentWeek:
return { label, types: [FilterTypes.DateTime], hasValue: false };
case ConditionOperator.CurrentYear:
return { label, types: [FilterTypes.DateTime], hasValue: false };
case ConditionOperator.ToDay:
return { label, types: [FilterTypes.DateTime], hasValue: false };
}
}
get noValueConditions() {
return [
ConditionOperator.LastWeek,
ConditionOperator.LastMonth,
ConditionOperator.CurrentYear,
ConditionOperator.CurrentWeek,
ConditionOperator.CurrentMonth,
ConditionOperator.ToDay
];
}
getTime(dt) {
if (!dt) {
return '';
}
const date = new Date(dt);
const day = date.getDate(); // yields date
const month = date.getMonth() + 1; // yields month (add one as '.getMonth()' is zero indexed)
const year = date.getFullYear(); // yields year
const hour = date.getHours(); // yields hours
const minute = date.getMinutes(); // yields minutes
const second = date.getSeconds(); // yields seconds
// After this construct a string with the above results as below
return day + '/' + month + '/' + year + " " + hour + ':' + minute + ':' + second;
}
setValueForDateHasNoValue(filter) {
if (filter.type === FilterTypes.DateTime) {
const date = new Date();
let fromDate = filter.value;
let toDate = filter.valueTo;
switch (filter.conditionOperator) {
case ConditionOperator.LastWeek:
{
fromDate = date.setTime(date.getTime() - 6 * 24 * 60 * 60 * 1000);
toDate = date.setTime(date.getTime() - (date.getDay() ? date.getDay() : 7) * 24 * 60 * 60 * 1000);
}
break;
case ConditionOperator.LastMonth:
{
fromDate = new Date(date.getFullYear(), date.getMonth() - 1, 1);
toDate = new Date(date.getFullYear(), date.getMonth(), 0);
}
break;
case ConditionOperator.CurrentWeek:
{
const first = date.getDate() - date.getDay(); // First day is the day of the month - the day of the week
const last = first + 6; // last day is the first day + 6
fromDate = new Date(date.setDate(first)).toUTCString();
toDate = new Date(date.setDate(last)).toUTCString();
}
break;
case ConditionOperator.CurrentMonth:
{
const y = date.getFullYear(), m = date.getMonth();
fromDate = new Date(y, m, 1);
toDate = new Date(y, m + 1, 0);
}
break;
case ConditionOperator.CurrentYear:
{
fromDate = new Date(date.getFullYear(), 0, 1);
toDate = new Date(date.getFullYear() + 1, 0, 0);
}
break;
case ConditionOperator.ToDay:
{
fromDate = date.setHours(0, 0, 0, 0);
const end = new Date();
end.setHours(23, 59, 59, 999);
toDate = end;
}
break;
}
filter.value = fromDate;
filter.valueTo = toDate;
}
}
clearFilter(filter) {
filter.hasFilter = false;
if (filter.type === FilterTypes.DateTime) {
filter.conditionOperator = this.getDefaultCondition(filter.type);
}
switch (filter.type) {
case FilterTypes.DateTime:
case FilterTypes.Number:
case FilterTypes.TextBox:
case FilterTypes.SingleSelect:
case FilterTypes.TrueFalse:
{
filter.value = null;
filter.valueTo = null;
}
break;
case FilterTypes.MultiSelect:
case FilterTypes.ListCheck: {
filter.values = null;
}
}
}
getDisplayLabel(filter, hasConditionName = true) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
let condition = this.getCondition(null, filter);
if (!condition) {
return ' ';
}
filter.conditionName = condition.label;
if (this.noValueConditions.includes(filter.conditionOperator)) {
return filter.conditionName;
}
let conditionName = hasConditionName ? filter.conditionName : '';
if (!condition.hasValue) {
return conditionName;
}
if (filter.type == FilterTypes.MultiSelect) {
if (!filter.values) {
return '';
}
return filter.values.map(z => { var _a, _b; return z[(_b = (_a = filter.options) === null || _a === void 0 ? void 0 : _a.selectBoxOptions) === null || _b === void 0 ? void 0 : _b.displayMember]; }).join(' ,');
}
else if (filter.type == FilterTypes.SingleSelect) {
if (!filter.value) {
return '';
}
return filter.value[(_b = (_a = filter.options) === null || _a === void 0 ? void 0 : _a.selectBoxOptions) === null || _b === void 0 ? void 0 : _b.displayMember];
}
else {
if (!filter.value) {
return '';
}
if (filter.type == FilterTypes.TrueFalse) {
if (filter.value == true) {
filter.valueName = ((_d = (_c = filter === null || filter === void 0 ? void 0 : filter.options) === null || _c === void 0 ? void 0 : _c.trueFalseOptions) === null || _d === void 0 ? void 0 : _d.trueLabel) ? filter.options.trueFalseOptions.trueLabel : 'Yes';
}
else {
filter.valueName = ((_f = (_e = filter === null || filter === void 0 ? void 0 : filter.options) === null || _e === void 0 ? void 0 : _e.trueFalseOptions) === null || _f === void 0 ? void 0 : _f.falseLabel) ? filter.options.trueFalseOptions.falseLabel : 'No';
}
return `${filter.valueName}`;
}
if (filter.type == FilterTypes.DateTime) {
if (!this.useJalaliDate) {
filter.valueName = moment(filter.value).format('YYYY/MM/DD');
}
else {
filter.valueName = moment(filter.value).format('jYYYY/jMM/jDD');
}
if (filter.conditionOperator == ConditionOperator.Between) {
conditionName = '';
const fromLabel = (this.translator.fromLabel) ? this.translator.fromLabel : 'from';
const toLabel = ((_g = this.translator) === null || _g === void 0 ? void 0 : _g.toLabel) ? this.translator.toLabel : 'to';
if (filter.valueTo) {
if (!this.useJalaliDate) {
filter.valueToName = moment(filter.valueTo).format('YYYY/MM/DD');
}
else {
filter.valueToName = moment(filter.valueTo).format('jYYYY/jMM/jDD');
}
}
else {
filter.valueToName = '...';
}
// filter.valueName = moment(filter.value).format('jYYYY/jMM/jDD');
return `${conditionName} ${fromLabel} ${filter.valueName} ${toLabel} ${filter.valueToName}`;
}
return `${conditionName} ${filter.valueName}`;
}
else {
let prefix = (_j = (_h = filter.options) === null || _h === void 0 ? void 0 : _h.numberBoxOptions) === null || _j === void 0 ? void 0 : _j.prefixTextForHint;
prefix = prefix ? prefix : '';
if (!prefix && ((_l = (_k = filter.options) === null || _k === void 0 ? void 0 : _k.numberBoxOptions) === null || _l === void 0 ? void 0 : _l.isMoney)) {
prefix = '$';
}
if (((_o = (_m = filter.options) === null || _m === void 0 ? void 0 : _m.numberBoxOptions) === null || _o === void 0 ? void 0 : _o.isMoney) && filter.type == FilterTypes.Number) {
filter.valueName = this._money(filter.value);
filter.valueTo ? filter.valueToName = this._money(filter.valueTo) : '...';
}
else {
filter.valueName = filter.value;
filter.valueToName = filter.valueTo;
}
if (filter.conditionOperator == ConditionOperator.Between) {
conditionName = '';
const fromLabel = ((_p = this.translator) === null || _p === void 0 ? void 0 : _p.fromLabel) ? this.translator.fromLabel : 'from';
const toLabel = ((_q = this.translator) === null || _q === void 0 ? void 0 : _q.toLabel) ? this.translator.toLabel : 'to';
return `${conditionName} ${fromLabel} ${filter.valueName}${prefix} ${toLabel} ${filter.valueToName ? filter.valueToName : '...'}${prefix}`;
}
else {
return `${conditionName} ${filter.valueName}${prefix}`;
}
}
}
}
toQueryString(queryObject) {
const parts = [];
Object.keys(queryObject).forEach((property) => {
const value = queryObject[property];
if (value !== undefined && value !== undefined) {
parts.push(encodeURIComponent(property) + '=' + encodeURIComponent(value));
}
});
return parts.join('&');
}
getFiltersInQueryString(filterBy) {
let obj = '';
filterBy.forEach((f, i) => {
Object.keys(f).forEach((prop) => {
const value = filterBy[i][prop];
if (Array.isArray(value)) {
const values = value;
let bb = 0;
values.forEach((b) => {
if (b !== undefined && b !== null) {
obj =
obj +
'&' +
encodeURIComponent('filters') +
`[${i}]` +
'.' +
`${encodeURIComponent(prop)}[${bb}]` +
'=' +
encodeURIComponent(b);
bb++;
}
});
}
else if (value !== undefined && value !== null) {
obj =
obj +
'&' +
encodeURIComponent('filters') +
`[${i}]` +
'.' +
encodeURIComponent(prop) +
'=' +
encodeURIComponent(value);
}
});
});
return obj;
}
getPageFilterInQueryString(queryObject) {
let obj;
if (queryObject && queryObject.filters) {
const filterBy = queryObject.filters.slice();
const query = new PageFilter();
Object.keys(queryObject).forEach((o) => {
// copy(slice) from queryObject
query[o] = queryObject[o];
});
delete query.filters;
obj = this.toQueryString(query);
obj += this.getFiltersInQueryString(filterBy);
}
return obj;
}
_numberWithCommas(x) {
var _a;
return (_a = x === null || x === void 0 ? void 0 : x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')) !== null && _a !== void 0 ? _a : '';
}
_money(value) {
if (value != null) {
return this._numberWithCommas(value);
}
return '0';
}
}
NgxFiltersService.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgxFiltersService_Factory() { return new NgxFiltersService(i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.NGX_FILTERS_CONFIGS, 8), i0.ɵɵinject(i0.ComponentFactoryResolver)); }, token: NgxFiltersService, providedIn: "root" });
NgxFiltersService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
NgxFiltersService.ctorParameters = () => [
{ type: Injector },
{ type: NgxFilterConfig, decorators: [{ type: Optional }, { type: Inject, args: [NGX_FILTERS_CONFIGS,] }] },
{ type: ComponentFactoryResolver }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWZpbHRlcnMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJDOi9Vc2Vycy9hLm1vaGFtbWFkaS9zb3VyY2UvcmVwb3MvTXlsaWJyYXJ5L0FuZ3VsYXIuTGlicmFyeS9saWJzL3Byb2plY3RzL25neC1maWx0ZXJzL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9uZ3gtZmlsdGVycy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBbUIsd0JBQXdCLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ2pILE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDL0QsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sOENBQThDLENBQUM7QUFDaEYsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMENBQTBDLENBQUM7QUFDMUUsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sOENBQThDLENBQUM7QUFDaEYsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0saUVBQWlFLENBQUM7QUFDeEcsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0scURBQXFELENBQUM7QUFDdkYsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sZ0VBQWdFLENBQUM7QUFDM0csT0FBTyxFQUFDLGlCQUFpQixFQUFVLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFDakcsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0scUJBQXFCLENBQUM7OztBQU14RCxNQUFNLE9BQU8saUJBQWlCO0lBYTVCLFlBQ0UsUUFBa0IsRUFDdUIsT0FBd0IsRUFDekQsUUFBa0M7UUFBbEMsYUFBUSxHQUFSLFFBQVEsQ0FB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QUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxDQUFDO1lBQzlELEtBQUssaUJBQWlCLENBQUMsU0FBUztnQkFDOUIsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxDQUFDO1lBQy9ELEtBQUssaUJBQWlCLENBQUMsT0FBTztnQkFDNUIsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsU0FBUztnQkFDOUIsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsUUFBUTtnQkFDN0IsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsWUFBWTtnQkFDakMsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsV0FBVztnQkFDaEMsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsV0FBVztnQkFDaEMsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO1lBQ2pFLEtBQUssaUJBQWlCLENBQUMsS0FB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L0IsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDckMsK0JBQStCO2dCQUMvQixLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQ3JCLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hDLEdBQUcsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDL0M7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxDQUFDOztRQUN6QixhQUFPLENBQUMsYUFBRCxDQUFDLHVCQUFELENBQUMsQ0FBRSxRQUFRLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixFQUFFLEdBQUcsb0NBQUssRUFBRSxDQUFDO0lBQ25FLENBQUM7SUFFTyxNQUFNLENBQUMsS0FBVTtRQUV2QixJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7WUFDakIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDdEM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7Ozs7WUFuZEYsVUFBVSxTQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COzs7WUFoQnVFLFFBQVE7WUFDeEUsZUFBZSx1QkErQmxCLFFBQVEsWUFBSSxNQUFNLFNBQUMsbUJBQW1CO1lBaENqQix3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudEZhY3RvcnksIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3RvciwgT3B0aW9uYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtOZ3hGaWx0ZXJDb25maWd9IGZyb20gXCIuL25neC1maWx0ZXItY29uZmlnXCI7XG5pbXBvcnQge0RhdGVDb21wb25lbnR9IGZyb20gXCIuL2NvbXBvbmVudHMvZGF0ZS9kYXRlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHtOdW1iZXJCb3hDb21wb25lbnR9IGZyb20gXCIuL2NvbXBvbmVudHMvbnVtYmVyLWJveC9udW1iZXItYm94LmNvbXBvbmVudFwiO1xuaW1wb3J0IHtUZXh0Qm94Q29tcG9uZW50fSBmcm9tIFwiLi9jb21wb25lbnRzL3RleHQtYm94L3RleHQtYm94LmNvbXBvbmVudFwiO1xuaW1wb3J0IHtUcnVlRmFsc2VDb21wb25lbnR9IGZyb20gXCIuL2NvbXBvbmVudHMvdHJ1ZS1mYWxzZS90cnVlLWZhbHNlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHtNdWx0aVNlbGVjdEJveENvbXBvbmVudH0gZnJvbSBcIi4vY29tcG9uZW50cy9zZWxlY3QvbXVsdGktc2VsZWN0LWJveC9tdWx0aS1zZWxlY3QtYm94LmNvbXBvbmVudFwiO1xuaW1wb3J0IHtTZWxlY3RCb3hDb21wb25lbnR9IGZyb20gXCIuL2NvbXBvbmVudHMvc2VsZWN0L3NlbGVjdC1ib3gvc2VsZWN0LWJveC5jb21wb25lbnRcIjtcbmltcG9ydCAqIGFzIG1vbWVudCBmcm9tIFwiamFsYWxpLW1vbWVudFwiO1xuaW1wb3J0IHtDb25kaXRpb25zU2VsZWN0b3JDb21wb25lbnR9IGZyb20gXCIuL2NvbXBvbmVudHMvY29uZGl0aW9ucy1zZWxlY3Rvci9jb25kaXRpb25zLXNlbGVjdG9yLmNvbXBvbmVudFwiO1xuaW1wb3J0IHtDb25kaXRpb25PcGVyYXRvciwgRmlsdGVyLCBGaWx0ZXJUcmFuc2xhdG9yLCBGaWx0ZXJUeXBlcywgUGFnZUZpbHRlcn0gZnJvbSBcIi4vbmd4LXR5cGVzXCI7XG5pbXBvcnQge05HWF9GSUxURVJTX0NPTkZJR1N9IGZyb20gXCIuL25neC1maWx0ZXJzLXRva2VuXCI7XG5cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTmd4RmlsdGVyc1NlcnZpY2Uge1xuICB0cmFuc2xhdG9yOiBGaWx0ZXJUcmFuc2xhdG9yID0ge30gYXMgYW55XG4gIGZpbHRlcnNDb21wb25lbnQ6IHtcbiAgICB0ZXh0Qm94PzogQ29tcG9uZW50RmFjdG9yeTxhbnk+LFxuICAgIG51bWJlckJveD86IENvbXBvbmVudEZhY3Rvcnk8YW55PixcbiAgICBkYXRlPzogQ29tcG9uZW50RmFjdG9yeTxhbnk+LFxuICAgIHNlbGVjdEJveD86IENvbXBvbmVudEZhY3Rvcnk8YW55PixcbiAgICBtdWx0aVNlbGVjdEJveD86IENvbXBvbmVudEZhY3Rvcnk8YW55PixcbiAgICB0cnVlRmFsc2U/OiBDb21wb25lbnRGYWN0b3J5PGFueT4sXG4gICAgY29uZGl0aW9uU2VsZWN0b3I/OiBDb21wb25lbnRGYWN0b3J5PGFueT5cbiAgfSA9IHt9O1xuICBwcml2YXRlIF9jb25maWdzOiBOZ3hGaWx0ZXJDb25maWc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTkdYX0ZJTFRFUlNfQ09ORklHUykgY29uZmlnczogTmd4RmlsdGVyQ29uZmlnLFxuICAgIHByaXZhdGUgcmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgKSB7XG4gICAgY29uc3QgZGVmYXVsdENvbmZpZ3MgPSB7XG4gICAgICB0cnVlRmFsc2VDb21wb25lbnQ6IFRydWVGYWxzZUNvbXBvbmVudCxcbiAgICAgIGRhdGVDb21wb25lbnQ6IERhdGVDb21wb25lbnQsXG4gICAgICBtdWx0aVNlbGVjdEJveENvbXBvbmVudDogTXVsdGlTZWxlY3RCb3hDb21wb25lbnQsXG4gICAgICBzZWxlY3RCb3hDb21wb25lbnQ6IFNlbGVjdEJveENvbXBvbmVudCxcbiAgICAgIG51bWJlckJveENvbXBvbmVudDogTnVtYmVyQm94Q29tcG9uZW50LFxuICAgICAgdGV4dEJveENvbXBvbmVudDogVGV4dEJveENvbXBvbmVudCxcbiAgICAgIGNvbmRpdGlvblNlbGVjdG9yQ29tcG9uZW50OiBDb25kaXRpb25zU2VsZWN0b3JDb21wb25lbnQsXG4gICAgICB0cmFuc2xhdG9yOiBuZXcgRmlsdGVyVHJhbnNsYXRvcigpLFxuICAgIH1cbiAgICBpZiAoIWNvbmZpZ3MpIHtcbiAgICAgIGNvbmZpZ3MgPSBkZWZhdWx0Q29uZmlncztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlncyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdENvbmZpZ3MsIGNvbmZpZ3MpO1xuICAgIH1cbiAgICB0aGlzLl9jb25maWdzID0gY29uZmlncztcbiAgICB0aGlzLmZpbHRlcnNDb21wb25lbnQudGV4dEJveCA9IHRoaXMucmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoY29uZmlncy50ZXh0Qm94Q29tcG9uZW50KTtcbiAgICB0aGlzLmZpbHRlcnNDb21wb25lbnQubnVtYmVyQm94ID0gdGhpcy5yZXNvbHZlclxuICAgICAgLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbmZpZ3MubnVtYmVyQm94Q29tcG9uZW50KTtcbiAgICB0aGlzLmZpbHRlcnNDb21wb25lbnQuZGF0ZSA9IHRoaXMucmVzb2x2ZXJcbiAgICAgIC5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShjb25maWdzLmRhdGVDb21wb25lbnQpO1xuICAgIHRoaXMuZmlsdGVyc0NvbXBvbmVudC5zZWxlY3RCb3ggPSB0aGlzLnJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbmZpZ3Muc2VsZWN0Qm94Q29tcG9uZW50KTtcbiAgICB0aGlzLmZpbHRlcnNDb21wb25lbnQubXVsdGlTZWxlY3RCb3ggPSB0aGlzLnJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbmZpZ3MubXVsdGlTZWxlY3RCb3hDb21wb25lbnQpO1xuICAgIHRoaXMuZmlsdGVyc0NvbXBvbmVudC50cnVlRmFsc2UgPSB0aGlzLnJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbmZpZ3MudHJ1ZUZhbHNlQ29tcG9uZW50KTtcbiAgICB0aGlzLmZpbHRlcnNDb21wb25lbnQuY29uZGl0aW9uU2VsZWN0b3IgPSB0aGlzLnJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KGNvbmZpZ3MuY29uZGl0aW9uU2VsZWN0b3JDb21wb25lbnQpO1xuICAgIHRoaXMudHJhbnNsYXRvciA9IGNvbmZpZ3MudHJhbnNsYXRvcjtcbiAgfVxuXG4gIGdldENvbXBvbmVudEZhY3Rvcnk8VD4oZmlsdGVyVHlwZTogRmlsdGVyVHlwZXMpOiBDb21wb25lbnRGYWN0b3J5PFQ+IHtcbiAgICBsZXQgY29tcG9uZW50OiBhbnkgPSBudWxsO1xuICAgIHN3aXRjaCAoZmlsdGVyVHlwZSkge1xuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5EYXRlVGltZTpcbiAgICAgICAgY29tcG9uZW50ID0gdGhpcy5fY29uZmlncy5kYXRlQ29tcG9uZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIC8vY2FzZSBGaWx0ZXJUeXBlcy5MaXN0Q2hlY2s6XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLk11bHRpU2VsZWN0OlxuICAgICAgICBjb21wb25lbnQgPSB0aGlzLl9jb25maWdzLm11bHRpU2VsZWN0Qm94Q29tcG9uZW50XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5OdW1iZXI6XG4gICAgICAgIGNvbXBvbmVudCA9IHRoaXMuX2NvbmZpZ3MubnVtYmVyQm94Q29tcG9uZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRmlsdGVyVHlwZXMuU2luZ2xlU2VsZWN0OlxuICAgICAgICBjb21wb25lbnQgPSB0aGlzLl9jb25maWdzLnNlbGVjdEJveENvbXBvbmVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLlRleHRCb3g6XG4gICAgICAgIGNvbXBvbmVudCA9IHRoaXMuX2NvbmZpZ3MudGV4dEJveENvbXBvbmVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLlRydWVGYWxzZTpcbiAgICAgICAgY29tcG9uZW50ID0gdGhpcy5fY29uZmlncy50cnVlRmFsc2VDb21wb25lbnQ7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbXBvbmVudCA9IHRoaXMuX2NvbmZpZ3MuY29uZGl0aW9uU2VsZWN0b3JDb21wb25lbnQ7XG5cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNvbXBvbmVudClcbiAgICAgIHJldHVybiB0aGlzLnJlc29sdmVyXG4gICAgICAgIC5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeTxUPihjb21wb25lbnQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uZGl0aW9uU291cmNlOiBhbnlbXSA9IFtdO1xuXG4gIHB1YmxpYyB1c2VKYWxhbGlEYXRlID0gZmFsc2U7XG5cbiAgY2hlY2tIYXNGaWx0ZXIoZmlsdGVyOiBGaWx0ZXIpOiBib29sZWFuIHtcbiAgICBsZXQgaGFzRmlsdGVyID0gKHRoaXMubm9WYWx1ZUNvbmRpdGlvbnMuaW5jbHVkZXMoZmlsdGVyLmNvbmRpdGlvbk9wZXJhdG9yKSlcbiAgICAgIHx8XG4gICAgICAoZmlsdGVyLnR5cGUgPT0gRmlsdGVyVHlwZXMuTXVsdGlTZWxlY3QgPyBmaWx0ZXIudmFsdWVzICYmIGZpbHRlci52YWx1ZXMubGVuZ3RoID4gMCA6ICEhZmlsdGVyLnZhbHVlKTtcbiAgICBpZiAoIWhhc0ZpbHRlcikge1xuICAgICAgaWYgKGZpbHRlci50eXBlID09PSBGaWx0ZXJUeXBlcy5OdW1iZXIgJiYgZmlsdGVyLnZhbHVlID09IDApIHtcbiAgICAgICAgaGFzRmlsdGVyID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWx0ZXIudHlwZSA9PT0gRmlsdGVyVHlwZXMuTnVtYmVyICYmIGZpbHRlci5jb25kaXRpb25PcGVyYXRvciA9PT0gQ29uZGl0aW9uT3BlcmF0b3IuQmV0d2VlbiAmJiBmaWx0ZXIudmFsdWVUbykge1xuICAgICAgICBmaWx0ZXIudmFsdWUgPSAwO1xuICAgICAgICBoYXNGaWx0ZXIgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKGhhc0ZpbHRlcik7XG5cbiAgfVxuXG4gIHB1YmxpYyBnZXRDb25kaXRpb25Tb3VyY2UoKSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogYW55W10gPSBbXTtcbiAgICBmb3IgKGxldCBlbnVtTWVtYmVyIGluIENvbmRpdGlvbk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSBDb25kaXRpb25PcGVyYXRvcltlbnVtTWVtYmVyXTtcbiAgICAgIGNvbnN0IGdjcGxhdCA9IHRoaXMuZ2V0Q29uZGl0aW9uKGNvbmRpdGlvbiwgbnVsbCk7XG4gICAgICBpZiAoZ2NwbGF0KSB7XG4gICAgICAgIGNvbmRpdGlvbnMucHVzaCh7XG4gICAgICAgICAga2V5OiBDb25kaXRpb25PcGVyYXRvcltlbnVtTWVtYmVyXSxcbiAgICAgICAgICBsYWJlbDogZ2NwbGF0LmxhYmVsLFxuICAgICAgICAgIHR5cGVzOiBnY3BsYXQudHlwZXNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgZ2V0RGVmYXVsdENvbmRpdGlvbihmaWx0ZXJUeXBlOiBGaWx0ZXJUeXBlcyk6IENvbmRpdGlvbk9wZXJhdG9yIHtcbiAgICBzd2l0Y2ggKGZpbHRlclR5cGUpIHtcbiAgICAgIGNhc2UgRmlsdGVyVHlwZXMuTXVsdGlTZWxlY3Q6XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLkxpc3RDaGVjazoge1xuICAgICAgICByZXR1cm4gQ29uZGl0aW9uT3BlcmF0b3IuSW5SYW5nZTtcbiAgICAgIH1cbiAgICAgIGNhc2UgRmlsdGVyVHlwZXMuVHJ1ZUZhbHNlOlxuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5TaW5nbGVTZWxlY3Q6XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLk51bWJlcjoge1xuICAgICAgICByZXR1cm4gQ29uZGl0aW9uT3BlcmF0b3IuRXF1YWw7XG4gICAgICB9XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLlRleHRCb3g6IHtcbiAgICAgICAgcmV0dXJuIENvbmRpdGlvbk9wZXJhdG9yLkNvbnRhaW5zO1xuICAgICAgfVxuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5EYXRlVGltZToge1xuICAgICAgICByZXR1cm4gQ29uZGl0aW9uT3BlcmF0b3IuQmV0d2VlbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldENvbmRpdGlvbkxhYmVsKGNvbmRpdGlvbjogQ29uZGl0aW9uT3BlcmF0b3IpOiBzdHJpbmcge1xuICAgIGlmIChjb25kaXRpb24pIHtcbiAgICAgIGNvbnN0IGNvbmRpdGlvbktleSA9IGNvbmRpdGlvblswXS50b0xvd2VyQ2FzZSgpICsgY29uZGl0aW9uLnN1YnN0cmluZygxKTtcbiAgICAgIGlmICh0aGlzLnRyYW5zbGF0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRvcltjb25kaXRpb25LZXkgKyAnTGFiZWwnXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjb25kaXRpb247XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBcIlwiO1xuXG4gIH1cblxuXG4gIHB1YmxpYyBnZXRDb25kaXRpb24oY29uZGl0aW9uOiBDb25kaXRpb25PcGVyYXRvciwgZmlsdGVyOiBGaWx0ZXIpOiB7IGxhYmVsOiBzdHJpbmcsIHR5cGVzOiBGaWx0ZXJUeXBlc1tdLCBoYXNWYWx1ZTogYm9vbGVhbiB9IHtcbiAgICBjb25kaXRpb24gPSBjb25kaXRpb24gfHwgZmlsdGVyLmNvbmRpdGlvbk9wZXJhdG9yO1xuICAgIGNvbnN0IGxhYmVsID0gdGhpcy5nZXRDb25kaXRpb25MYWJlbChjb25kaXRpb24pO1xuICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkJldHdlZW46XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuTnVtYmVyLCBGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiB0cnVlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuQ29udGFpbnM6XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuVGV4dEJveF0sIGhhc1ZhbHVlOiB0cnVlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuRW5kV2l0aDpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5UZXh0Qm94XSwgaGFzVmFsdWU6IHRydWV9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5Ob3RDb250YWluczpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5UZXh0Qm94XSwgaGFzVmFsdWU6IHRydWV9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5FcXVhbDpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5OdW1iZXJdLCBoYXNWYWx1ZTogdHJ1ZX07XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkV4YWN0OlxuICAgICAgICByZXR1cm4ge2xhYmVsLCB0eXBlczogW0ZpbHRlclR5cGVzLkRhdGVUaW1lLCBGaWx0ZXJUeXBlcy5UZXh0Qm94XSwgaGFzVmFsdWU6IHRydWV9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5HcmVhdGVyVGhhbjpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5OdW1iZXIsIEZpbHRlclR5cGVzLkRhdGVUaW1lXSwgaGFzVmFsdWU6IHRydWV9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5HcmVhdGVyVGhhbk9yRXF1YWw6XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuTnVtYmVyLCBGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiB0cnVlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuTGVzc1RoYW46XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuTnVtYmVyLCBGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiB0cnVlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuTGVzc1RoYW5PckVxdWFsOlxuICAgICAgICByZXR1cm4ge2xhYmVsLCB0eXBlczogW0ZpbHRlclR5cGVzLk51bWJlciwgRmlsdGVyVHlwZXMuRGF0ZVRpbWVdLCBoYXNWYWx1ZTogdHJ1ZX07XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLk5vdEVxdWFsOlxuICAgICAgICByZXR1cm4ge2xhYmVsLCB0eXBlczogW0ZpbHRlclR5cGVzLk51bWJlcl0sIGhhc1ZhbHVlOiB0cnVlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuU3RhcnRXaXRoOlxuICAgICAgICByZXR1cm4ge2xhYmVsLCB0eXBlczogW0ZpbHRlclR5cGVzLlRleHRCb3hdLCBoYXNWYWx1ZTogdHJ1ZX07XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkluUmFuZ2U6XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuTGlzdENoZWNrXSwgaGFzVmFsdWU6IHRydWV9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5MYXN0TW9udGg6XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuRGF0ZVRpbWVdLCBoYXNWYWx1ZTogZmFsc2V9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5MYXN0V2VlazpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiBmYWxzZX07XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkN1cnJlbnRNb250aDpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiBmYWxzZX07XG4gICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkN1cnJlbnRXZWVrOlxuICAgICAgICByZXR1cm4ge2xhYmVsLCB0eXBlczogW0ZpbHRlclR5cGVzLkRhdGVUaW1lXSwgaGFzVmFsdWU6IGZhbHNlfTtcbiAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuQ3VycmVudFllYXI6XG4gICAgICAgIHJldHVybiB7bGFiZWwsIHR5cGVzOiBbRmlsdGVyVHlwZXMuRGF0ZVRpbWVdLCBoYXNWYWx1ZTogZmFsc2V9O1xuICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5Ub0RheTpcbiAgICAgICAgcmV0dXJuIHtsYWJlbCwgdHlwZXM6IFtGaWx0ZXJUeXBlcy5EYXRlVGltZV0sIGhhc1ZhbHVlOiBmYWxzZX07XG5cbiAgICB9XG4gIH1cblxuICBnZXQgbm9WYWx1ZUNvbmRpdGlvbnMoKTogQ29uZGl0aW9uT3BlcmF0b3JbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIENvbmRpdGlvbk9wZXJhdG9yLkxhc3RXZWVrLFxuICAgICAgQ29uZGl0aW9uT3BlcmF0b3IuTGFzdE1vbnRoLFxuICAgICAgQ29uZGl0aW9uT3BlcmF0b3IuQ3VycmVudFllYXIsXG4gICAgICBDb25kaXRpb25PcGVyYXRvci5DdXJyZW50V2VlayxcbiAgICAgIENvbmRpdGlvbk9wZXJhdG9yLkN1cnJlbnRNb250aCxcbiAgICAgIENvbmRpdGlvbk9wZXJhdG9yLlRvRGF5XG4gICAgXTtcbiAgfVxuXG4gIGdldFRpbWUoZHQpOiBzdHJpbmcge1xuICAgIGlmICghZHQpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGR0KTtcbiAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKTsgICAgICAgLy8geWllbGRzIGRhdGVcbiAgICBjb25zdCBtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7ICAgIC8vIHlpZWxkcyBtb250aCAoYWRkIG9uZSBhcyAnLmdldE1vbnRoKCknIGlzIHplcm8gaW5kZXhlZClcbiAgICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpOyAgLy8geWllbGRzIHllYXJcbiAgICBjb25zdCBob3VyID0gZGF0ZS5nZXRIb3VycygpOyAgICAgLy8geWllbGRzIGhvdXJzXG4gICAgY29uc3QgbWludXRlID0gZGF0ZS5nZXRNaW51dGVzKCk7IC8vIHlpZWxkcyBtaW51dGVzXG4gICAgY29uc3Qgc2Vjb25kID0gZGF0ZS5nZXRTZWNvbmRzKCk7IC8vIHlpZWxkcyBzZWNvbmRzXG5cbi8vIEFmdGVyIHRoaXMgY29uc3RydWN0IGEgc3RyaW5nIHdpdGggdGhlIGFib3ZlIHJlc3VsdHMgYXMgYmVsb3dcbiAgICByZXR1cm4gZGF5ICsgJy8nICsgbW9udGggKyAnLycgKyB5ZWFyICsgXCIgXCIgKyBob3VyICsgJzonICsgbWludXRlICsgJzonICsgc2Vjb25kO1xuXG4gIH1cblxuICBzZXRWYWx1ZUZvckRhdGVIYXNOb1ZhbHVlKGZpbHRlcjogRmlsdGVyKTogdm9pZCB7XG4gICAgaWYgKGZpbHRlci50eXBlID09PSBGaWx0ZXJUeXBlcy5EYXRlVGltZSkge1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICBsZXQgZnJvbURhdGUgPSBmaWx0ZXIudmFsdWU7XG4gICAgICBsZXQgdG9EYXRlID0gZmlsdGVyLnZhbHVlVG87XG4gICAgICBzd2l0Y2ggKGZpbHRlci5jb25kaXRpb25PcGVyYXRvcikge1xuICAgICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkxhc3RXZWVrOiB7XG4gICAgICAgICAgZnJvbURhdGUgPSBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgLSA2ICogMjQgKiA2MCAqIDYwICogMTAwMCk7XG4gICAgICAgICAgdG9EYXRlID0gZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gKGRhdGUuZ2V0RGF5KCkgPyBkYXRlLmdldERheSgpIDogNykgKiAyNCAqIDYwICogNjAgKiAxMDAwKTtcbiAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENvbmRpdGlvbk9wZXJhdG9yLkxhc3RNb250aDoge1xuICAgICAgICAgIGZyb21EYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCkgLSAxLCAxKTtcbiAgICAgICAgICB0b0RhdGUgPSBuZXcgRGF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5DdXJyZW50V2Vlazoge1xuICAgICAgICAgIGNvbnN0IGZpcnN0ID0gZGF0ZS5nZXREYXRlKCkgLSBkYXRlLmdldERheSgpOyAvLyBGaXJzdCBkYXkgaXMgdGhlIGRheSBvZiB0aGUgbW9udGggLSB0aGUgZGF5IG9mIHRoZSB3ZWVrXG4gICAgICAgICAgY29uc3QgbGFzdCA9IGZpcnN0ICsgNjsgLy8gbGFzdCBkYXkgaXMgdGhlIGZpcnN0IGRheSArIDZcblxuICAgICAgICAgIGZyb21EYXRlID0gbmV3IERhdGUoZGF0ZS5zZXREYXRlKGZpcnN0KSkudG9VVENTdHJpbmcoKTtcbiAgICAgICAgICB0b0RhdGUgPSBuZXcgRGF0ZShkYXRlLnNldERhdGUobGFzdCkpLnRvVVRDU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5DdXJyZW50TW9udGg6IHtcbiAgICAgICAgICBjb25zdCB5ID0gZGF0ZS5nZXRGdWxsWWVhcigpLCBtID0gZGF0ZS5nZXRNb250aCgpO1xuICAgICAgICAgIGZyb21EYXRlID0gbmV3IERhdGUoeSwgbSwgMSk7XG4gICAgICAgICAgdG9EYXRlID0gbmV3IERhdGUoeSwgbSArIDEsIDApO1xuICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ29uZGl0aW9uT3BlcmF0b3IuQ3VycmVudFllYXI6IHtcbiAgICAgICAgICBmcm9tRGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgMCwgMSk7XG4gICAgICAgICAgdG9EYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpICsgMSwgMCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBDb25kaXRpb25PcGVyYXRvci5Ub0RheToge1xuICAgICAgICAgIGZyb21EYXRlID0gZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcblxuICAgICAgICAgIGNvbnN0IGVuZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgZW5kLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XG4gICAgICAgICAgdG9EYXRlID0gZW5kO1xuICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgIH1cbiAgICAgIGZpbHRlci52YWx1ZSA9IGZyb21EYXRlO1xuICAgICAgZmlsdGVyLnZhbHVlVG8gPSB0b0RhdGU7XG4gICAgfVxuICB9XG5cbiAgY2xlYXJGaWx0ZXIoZmlsdGVyOiBGaWx0ZXIpOiB2b2lkIHtcbiAgICBmaWx0ZXIuaGFzRmlsdGVyID0gZmFsc2U7XG4gICAgaWYgKGZpbHRlci50eXBlID09PSBGaWx0ZXJUeXBlcy5EYXRlVGltZSkge1xuICAgICAgZmlsdGVyLmNvbmRpdGlvbk9wZXJhdG9yID0gdGhpcy5nZXREZWZhdWx0Q29uZGl0aW9uKGZpbHRlci50eXBlKTtcbiAgICB9XG4gICAgc3dpdGNoIChmaWx0ZXIudHlwZSkge1xuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5EYXRlVGltZTpcbiAgICAgIGNhc2UgRmlsdGVyVHlwZXMuTnVtYmVyOlxuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5UZXh0Qm94OlxuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5TaW5nbGVTZWxlY3Q6XG4gICAgICBjYXNlIEZpbHRlclR5cGVzLlRydWVGYWxzZToge1xuICAgICAgICBmaWx0ZXIudmFsdWUgPSBudWxsO1xuICAgICAgICBmaWx0ZXIudmFsdWVUbyA9IG51bGw7XG4gICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBGaWx0ZXJUeXBlcy5NdWx0aVNlbGVjdDpcbiAgICAgIGNhc2UgRmlsdGVyVHlwZXMuTGlzdENoZWNrOiB7XG4gICAgICAgIGZpbHRlci52YWx1ZXMgPSBudWxsO1xuICAgICAgfVxuXG4gICAgfVxuICB9XG5cbiAgZ2V0RGlzcGxheUxhYmVsKGZpbHRlcjogRmlsdGVyLCBoYXNDb25kaXRpb25OYW1lOiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyB7XG5cbiAgICBsZXQgY29uZGl0aW9uID0gdGhpcy5nZXRDb25kaXRpb24obnVsbCwgZmlsdGVyKTtcbiAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgcmV0dXJuICcgJztcbiAgICB9XG5cbiAgICBmaWx0ZXIuY29uZGl0aW9uTmFtZSA9IGNvbmRpdGlvbi5sYWJlbDtcbiAgICBpZiAodGhpcy5ub1ZhbHVlQ29uZGl0aW9ucy5pbmNsdWRlcyhmaWx0ZXIuY29uZGl0aW9uT3BlcmF0b3IpKSB7XG4gICAgICByZXR1cm4gZmlsdGVyLmNvbmRpdGlvbk5hbWU7XG4gICAgfVxuXG4gICAgbGV0IGNvbmRpdGlvbk5hbWUgPSBoYXNDb25kaXRpb25OYW1lID8gZmlsdGVyLmNvbmRpdGlvbk5hbWUgOiAnJztcblxuICAgIGlmICghY29uZGl0aW9uLmhhc1ZhbHVlKSB7XG4gICAgICByZXR1cm4gY29uZGl0aW9uTmFtZTtcbiAgICB9XG5cbiAgICBpZiAoZmlsdGVyLnR5cGUgPT0gRmlsdGVyVHlwZXMuTXVsdGlTZWxlY3QpIHtcbiAgICAgIGlmICghZmlsdGVyLnZhbHVlcykge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmlsdGVyLnZhbHVlcy5tYXAoeiA9PiB6W2ZpbHRlci5vcHRpb25zPy5zZWxlY3RCb3hPcHRpb25zPy5kaXNwbGF5TWVtYmVyXSkuam9pbignICwnKTtcbiAgICB9IGVsc2UgaWYgKGZpbHRlci50eXBlID09IEZpbHRlclR5cGVzLlNpbmdsZVNlbGVjdCkge1xuICAgICAgaWYgKCFmaWx0ZXIudmFsdWUpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZpbHRlci52YWx1ZVtmaWx0ZXIub3B0aW9ucz8uc2VsZWN0Qm94T3B0aW9ucz8uZGlzcGxheU1lbWJlcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghZmlsdGVyLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICAgIGlmIChmaWx0ZXIudHlwZSA9PSBGaWx0ZXJUeXBlcy5UcnVlRmFsc2UpIHtcbiAgICAgICAgaWYgKGZpbHRlci52YWx1ZSA9PSB0cnVlKSB7XG4gICAgICAgICAgZmlsdGVyLnZhbHVlTmFtZSA9IGZpbHRlcj8ub3B0aW9ucz8udHJ1ZUZhbHNlT3B0aW9ucz8udHJ1ZUxhYmVsID8gZmlsdGVyLm9wdGlvbnMudHJ1ZUZhbHNlT3B0aW9ucy50cnVlTGFiZWwgOiAnWWVzJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWx0ZXIudmFsdWVOYW1lID0gZmlsdGVyPy5vcHRpb25zPy50cnVlRmFsc2VPcHRpb25zPy5mYWxzZUxhYmVsID8gZmlsdGVyLm9wdGlvbnMudHJ1ZUZhbHNlT3B0aW9ucy5mYWxzZUxhYmVsIDogJ05vJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYCR7ZmlsdGVyLnZhbHVlTmFtZX1gO1xuICAgICAgfVxuICAgICAgaWYgKGZpbHRlci50eXBlID09IEZpbHRlclR5cGVzLkRhdGVUaW1lKSB7XG4gICAgICAgIGlmICghdGhpcy51c2VKYWxhbGlEYXRlKSB7XG4gICAgICAgICAgZmlsdGVyLnZhbHVlTmFtZSA9IG1vbWVudChmaWx0ZXIudmFsdWUpLmZvcm1hdCgnWVlZWS9NTS9ERCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZpbHRlci52YWx1ZU5hbWUgPSBtb21lbnQoZmlsdGVyLnZhbHVlKS5mb3JtYXQoJ2pZWVlZL2pNTS9qREQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLmNvbmRpdGlvbk9wZXJhdG9yID09IENvbmRpdGlvbk9wZXJhdG9yLkJldHdlZW4pIHtcbiAgICAgICAgICBjb25kaXRpb25OYW1lID0gJyc7XG4gICAgICAgICAgY29uc3QgZnJvbUxhYmVsID0gKHRoaXMudHJhbnNsYXRvci5mcm9tTGFiZWwpID8gdGhpcy50cmFuc2xhdG9yLmZyb21MYWJlbCA6ICdmcm9tJztcbiAgICAgICAgICBjb25zdCB0b0xhYmVsID0gKHRoaXMudHJhbnNsYXRvcj8udG9MYWJlbCkgPyB0aGlzLnRyYW5zbGF0b3IudG9MYWJlbCA6ICd0byc7XG4gICAgICAgICAgaWYgKGZpbHRlci52YWx1ZVRvKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudXNlSmFsYWxpRGF0ZSkge1xuICAgICAgICAgICAgICBmaWx0ZXIudmFsdWVUb05hbWUgPSBtb21lbnQoZmlsdGVyLnZhbHVlVG8pLmZvcm1hdCgnWVlZWS9NTS9ERCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmlsdGVyLnZhbHVlVG9OYW1lID0gbW9tZW50KGZpbHRlci52YWx1ZVRvKS5mb3JtYXQoJ2pZWVlZL2pNTS9qREQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmlsdGVyLnZhbHVlVG9OYW1lID0gJy4uLic7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGZpbHRlci52YWx1ZU5hbWUgPSBtb21lbnQoZmlsdGVyLnZhbHVlKS5mb3JtYXQoJ2pZWVlZL2pNTS9qREQnKTtcbiAgICAgICAgICByZXR1cm4gYCR7Y29uZGl0aW9uTmFtZX0gJHtmcm9tTGFiZWx9ICR7ZmlsdGVyLnZhbHVlTmFtZX0gJHt0b0xhYmVsfSAke2ZpbHRlci52YWx1ZVRvTmFtZX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgJHtjb25kaXRpb25OYW1lfSAke2ZpbHRlci52YWx1ZU5hbWV9YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBwcmVmaXggPSBmaWx0ZXIub3B0aW9ucz8ubnVtYmVyQm94T3B0aW9ucz8ucHJlZml4VGV4dEZvckhpbnQ7XG4gICAgICAgIHByZWZpeCA9IHByZWZpeCA/IHByZWZpeCA6ICcnO1xuICAgICAgICBpZiAoIXByZWZpeCAmJiBmaWx0ZXIub3B0aW9ucz8ubnVtYmVyQm94T3B0aW9ucz8uaXNNb25leSkge1xuICAgICAgICAgIHByZWZpeCA9ICckJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLm9wdGlvbnM/Lm51bWJlckJveE9wdGlvbnM/LmlzTW9uZXkgJiYgZmlsdGVyLnR5cGUgPT0gRmlsdGVyVHlwZXMuTnVtYmVyKSB7XG4gICAgICAgICAgZmlsdGVyLnZhbHVlTmFtZSA9IHRoaXMuX21vbmV5KGZpbHRlci52YWx1ZSk7XG4gICAgICAgICAgZmlsdGVyLnZhbHVlVG8gPyBmaWx0ZXIudmFsdWVUb05hbWUgPSB0aGlzLl9tb25leShmaWx0ZXIudmFsdWVUbykgOiAnLi4uJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWx0ZXIudmFsdWVOYW1lID0gZmlsdGVyLnZhbHVlO1xuICAgICAgICAgIGZpbHRlci52YWx1ZVRvTmFtZSA9IGZpbHRlci52YWx1ZVRvO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXIuY29uZGl0aW9uT3BlcmF0b3IgPT0gQ29uZGl0aW9uT3BlcmF0b3IuQmV0d2Vlbikge1xuICAgICAgICAgIGNvbmRpdGlvbk5hbWUgPSAnJztcbiAgICAgICAgICBjb25zdCBmcm9tTGFiZWwgPSAodGhpcy50cmFuc2xhdG9yPy5mcm9tTGFiZWwpID8gdGhpcy50cmFuc2xhdG9yLmZyb21MYWJlbCA6ICdmcm9tJztcbiAgICAgICAgICBjb25zdCB0b0xhYmVsID0gKHRoaXMudHJhbnNsYXRvcj8udG9MYWJlbCkgPyB0aGlzLnRyYW5zbGF0b3IudG9MYWJlbCA6ICd0byc7XG5cbiAgICAgICAgICByZXR1cm4gYCR7Y29uZGl0aW9uTmFtZX0gJHtmcm9tTGFiZWx9ICR7ZmlsdGVyLnZhbHVlTmFtZX0ke3ByZWZpeH0gJHt0b0xhYmVsfSAke2ZpbHRlci52YWx1ZVRvTmFtZSA/IGZpbHRlci52YWx1ZVRvTmFtZSA6ICcuLi4nfSR7cHJlZml4fWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGAke2NvbmRpdGlvbk5hbWV9ICR7ZmlsdGVyLnZhbHVlTmFtZX0ke3ByZWZpeH1gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0b1F1ZXJ5U3RyaW5nKHF1ZXJ5T2JqZWN0OiBQYWdlRmlsdGVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJ0cyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKHF1ZXJ5T2JqZWN0KS5mb3JFYWNoKChwcm9wZXJ0eSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBxdWVyeU9iamVjdFtwcm9wZXJ0eV07XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBhcnRzLnB1c2goXG4gICAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KHByb3BlcnR5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcGFydHMuam9pbignJicpO1xuICB9XG5cbiAgZ2V0RmlsdGVyc0luUXVlcnlTdHJpbmcoZmlsdGVyQnk6IEZpbHRlcltdKTogc3RyaW5nIHtcbiAgICBsZXQgb2JqID0gJyc7XG4gICAgZmlsdGVyQnkuZm9yRWFjaCgoZiwgaSkgPT4ge1xuICAgICAgT2JqZWN0LmtleXMoZikuZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGZpbHRlckJ5W2ldW3Byb3BdO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZXMgPSB2YWx1ZSBhcyBzdHJpbmdbXTtcbiAgICAgICAgICBsZXQgYmIgPSAwO1xuICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKChiKSA9PiB7XG4gICAgICAgICAgICBpZiAoYiAhPT0gdW5kZWZpbmVkICYmIGIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgb2JqID1cbiAgICAgICAgICAgICAgICBvYmogK1xuICAgICAgICAgICAgICAgICcmJyArXG4gICAgICAgICAgICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KCdmaWx0ZXJzJykgK1xuICAgICAgICAgICAgICAgIGBbJHtpfV1gICtcbiAgICAgICAgICAgICAgICAnLicgK1xuICAgICAgICAgICAgICAgIGAke2VuY29kZVVSSUNvbXBvbmVudChwcm9wKX1bJHtiYn1dYCArXG4gICAgICAgICAgICAgICAgJz0nICtcbiAgICAgICAgICAgICAgICBlbmNvZGVVUklDb21wb25lbnQoYik7XG4gICAgICAgICAgICAgIGJiKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIG9iaiA9XG4gICAgICAgICAgICBvYmogK1xuICAgICAgICAgICAgJyYnICtcbiAgICAgICAgICAgIGVuY29kZVVSSUNvbXBvbmVudCgnZmlsdGVycycpICtcbiAgICAgICAgICAgIGBbJHtpfV1gICtcbiAgICAgICAgICAgICcuJyArXG4gICAgICAgICAgICBlbmNvZGVVUklDb21wb25lbnQocHJvcCkgK1xuICAgICAgICAgICAgJz0nICtcbiAgICAgICAgICAgIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBnZXRQYWdlRmlsdGVySW5RdWVyeVN0cmluZyhxdWVyeU9iamVjdDogUGFnZUZpbHRlcik6IHN0cmluZyB7XG4gICAgbGV0IG9iajogc3RyaW5nO1xuICAgIGlmIChxdWVyeU9iamVjdCAmJiBxdWVyeU9iamVjdC5maWx0ZXJzKSB7XG4gICAgICBjb25zdCBmaWx0ZXJCeSA9IHF1ZXJ5T2JqZWN0LmZpbHRlcnMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0gbmV3IFBhZ2VGaWx0ZXIoKTtcbiAgICAgIE9iamVjdC5rZXlzKHF1ZXJ5T2JqZWN0KS5mb3JFYWNoKChvKSA9PiB7XG4gICAgICAgIC8vIGNvcHkoc2xpY2UpIGZyb20gcXVlcnlPYmplY3RcbiAgICAgICAgcXVlcnlbb10gPSBxdWVyeU9iamVjdFtvXTtcbiAgICAgIH0pO1xuICAgICAgZGVsZXRlIHF1ZXJ5LmZpbHRlcnM7XG4gICAgICBvYmogPSB0aGlzLnRvUXVlcnlTdHJpbmcocXVlcnkpO1xuICAgICAgb2JqICs9IHRoaXMuZ2V0RmlsdGVyc0luUXVlcnlTdHJpbmcoZmlsdGVyQnkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgcHJpdmF0ZSBfbnVtYmVyV2l0aENvbW1hcyh4KSB7XG4gICAgcmV0dXJuIHg/LnRvU3RyaW5nKCkucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgJywnKSA/PyAnJztcbiAgfVxuXG4gIHByaXZhdGUgX21vbmV5KHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuXG4gICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLl9udW1iZXJXaXRoQ29tbWFzKHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuICcwJztcbiAgfVxufVxuIl19