UNPKG

@neocomplexx/ngx-neo-pipes

Version:

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.0.5.

749 lines 53.8 kB
import { __values } from 'tslib';
import { Pipe, Injectable, NgModule } from '@angular/core';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Filter object array from property
 */
var FuncFilterPipe = /** @class */ (function () {
    function FuncFilterPipe() {
    }
    /**
     * @param {?} items
     * @param {?} callback
     * @return {?}
     */
    FuncFilterPipe.prototype.transform = /**
     * @param {?} items
     * @param {?} callback
     * @return {?}
     */
    function (items, callback) {
        if (!items || !callback) {
            return [];
        }
        return items.filter(callback);
    };
    FuncFilterPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'functionFilter'
                },] },
        { type: Injectable }
    ];
    return FuncFilterPipe;
}());
/**
 * Filter object array from property
 */
var TextPipe = /** @class */ (function () {
    function TextPipe() {
    }
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
     * idea general : items.field == value
     * NO FUNCIONA CON NUMEROS
     */
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
     * idea general : items.field == value
     * NO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    TextPipe.prototype.transform = /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
     * idea general : items.field == value
     * NO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    function (items, field, value) {
        if (!items) {
            return [];
        }
        if (!field || !value) {
            return items;
        }
        return items.filter(function (singleItem) { return singleItem[field].toLowerCase().includes(value.toLowerCase()); });
    };
    TextPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'textFilter'
                },] },
        { type: Injectable }
    ];
    return TextPipe;
}());
/**
 * Array filter with string value with 2 indirection level
 */
var TextPipeTwoLevel = /** @class */ (function () {
    function TextPipeTwoLevel() {
    }
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * NO FUNCIONA CON NUMEROS
     */
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * NO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    TextPipeTwoLevel.prototype.transform = /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * NO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    function (items, firstField, secondField, value) {
        if (!items) {
            return [];
        }
        if (!firstField || !secondField || !value) {
            return items;
        }
        return items.filter(function (singleItem) { return (singleItem[firstField][secondField]).toLowerCase().includes(value.toLowerCase()); });
    };
    TextPipeTwoLevel.decorators = [
        { type: Pipe, args: [{
                    name: 'textFilter2Level'
                },] },
        { type: Injectable }
    ];
    return TextPipeTwoLevel;
}());
var NumberPipe = /** @class */ (function () {
    function NumberPipe() {
    }
    /**
    * @author jcangelosi
    * Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
    * idea general : items.field == value
    * SOLO FUNCIONA CON NUMEROS
    */
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
     * idea general : items.field == value
     * SOLO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    NumberPipe.prototype.transform = /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
     * idea general : items.field == value
     * SOLO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    function (items, field, value) {
        if (!items) {
            return [];
        }
        if (!field || !value) {
            return items;
        }
        return items.filter(function (singleItem) { return singleItem[field].toString().includes(value.toString()); });
    };
    NumberPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'numberFilter'
                },] },
        { type: Injectable }
    ];
    return NumberPipe;
}());
var ToStringPipe = /** @class */ (function () {
    function ToStringPipe() {
    }
    /**
     * @param {?} items
     * @param {?} value
     * @return {?}
     */
    ToStringPipe.prototype.transform = /**
     * @param {?} items
     * @param {?} value
     * @return {?}
     */
    function (items, value) {
        if (!items) {
            return [];
        }
        if (!value) {
            return items;
        }
        return items.filter(function (singleItem) { return singleItem.toString().toLowerCase().includes(value.toLowerCase()); });
    };
    ToStringPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'toStringFilter'
                },] },
        { type: Injectable }
    ];
    return ToStringPipe;
}());
var NumberPipeTwoLevel = /** @class */ (function () {
    function NumberPipeTwoLevel() {
    }
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * SOLO FUNCIONA CON NUMEROS
     */
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * SOLO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    NumberPipeTwoLevel.prototype.transform = /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
     * idea general : items.field.secondField == value
     * SOLO FUNCIONA CON NUMEROS
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    function (items, firstField, secondField, value) {
        if (!items) {
            return [];
        }
        if (!firstField || !secondField || !value) {
            return items;
        }
        return items.filter(function (singleItem) { return singleItem[firstField][secondField].toString().includes(value.toString()); });
    };
    NumberPipeTwoLevel.decorators = [
        { type: Pipe, args: [{
                    name: 'numberFilter2Level'
                },] },
        { type: Injectable }
    ];
    return NumberPipeTwoLevel;
}());
var RangePipe = /** @class */ (function () {
    function RangePipe() {
    }
    /**
     * @author jcangelosi
     *  Filtrara el arreglo en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     */
    /**
     * @author jcangelosi
     *  Filtrara el arreglo en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    RangePipe.prototype.transform = /**
     * @author jcangelosi
     *  Filtrara el arreglo en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    function (items, field, value) {
        if (!items) {
            return [];
        }
        if (!field || !value) {
            return items;
        }
        if (value.toString().includes('<')) { // Caso 1: es menor
            // Caso 1: es menor
            /** @type {?} */
            var numeros = value.split('<');
            /** @type {?} */
            var numero_1 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[field] < numero_1; });
        }
        if (value.toString().includes('-')) { // Caso 2: Rango
            // Caso 2: Rango
            /** @type {?} */
            var numeros = value.split('-');
            /** @type {?} */
            var numero1_1 = +numeros[0];
            /** @type {?} */
            var numero2_1 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[field] >= numero1_1 && singleItem[field] < numero2_1; });
        }
        if (value.toString().includes('>=')) { // Caso 3: Mayor o Igual
            // Caso 3: Mayor o Igual
            /** @type {?} */
            var numeros = value.split('>=');
            /** @type {?} */
            var numero_2 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[field] >= numero_2; });
        }
        // Caso 4, item vacio
        return items;
    };
    RangePipe.decorators = [
        { type: Pipe, args: [{
                    name: 'rangeFilter'
                },] },
        { type: Injectable }
    ];
    return RangePipe;
}());
var RangePipeTwoLevel = /** @class */ (function () {
    function RangePipeTwoLevel() {
    }
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     */
    /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    RangePipeTwoLevel.prototype.transform = /**
     * @author jcangelosi
     * Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
     *  Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
     * @param {?} items
     * @param {?} firstField
     * @param {?} secondField
     * @param {?} value
     * @return {?}
     */
    function (items, firstField, secondField, value) {
        if (!items) {
            return [];
        }
        if (!firstField || !secondField || !value) {
            return items;
        }
        if (value.toString().includes('<')) { // Caso 1: es menor
            // Caso 1: es menor
            /** @type {?} */
            var numeros = value.split('<');
            /** @type {?} */
            var numero_3 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[firstField][secondField] < numero_3; });
        }
        if (value.toString().includes('-')) { // Caso 2: Rango
            // Caso 2: Rango
            /** @type {?} */
            var numeros = value.split('-');
            /** @type {?} */
            var numero1_2 = +numeros[0];
            /** @type {?} */
            var numero2_2 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[firstField][secondField] >= numero1_2 &&
                singleItem[firstField][secondField] < numero2_2; });
        }
        if (value.toString().includes('>')) { // Caso 3: Mayor o Igual
            // Caso 3: Mayor o Igual
            /** @type {?} */
            var numeros = value.split('>');
            /** @type {?} */
            var numero_4 = +numeros[1];
            return items.filter(function (singleItem) { return singleItem[firstField][secondField] >= numero_4; });
        }
        // Caso 4, item vacio
        return items;
    };
    RangePipeTwoLevel.decorators = [
        { type: Pipe, args: [{
                    name: 'rangeFilter2Level'
                },] },
        { type: Injectable }
    ];
    return RangePipeTwoLevel;
}());
var DatePipe = /** @class */ (function () {
    function DatePipe() {
    }
    /**
     * @author jcangelosi
     * Filtrara el arreglo items por una fecha representada por un string
     */
    /**
     * @author jcangelosi
     * Filtrara el arreglo items por una fecha representada por un string
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    DatePipe.prototype.transform = /**
     * @author jcangelosi
     * Filtrara el arreglo items por una fecha representada por un string
     * @param {?} items
     * @param {?} field
     * @param {?} value
     * @return {?}
     */
    function (items, field, value) {
        if (!items) {
            return [];
        }
        if (!field || !value) {
            return items;
        }
        // caso contrario la fecha es valida
        /** @type {?} */
        var valores = value.split('-');
        /** @type {?} */
        var fecha = valores[2] + '/' + valores[1] + '/' + valores[0];
        return items.filter(function (singleItem) { return singleItem[field].toLowerCase().includes(fecha); });
    };
    DatePipe.decorators = [
        { type: Pipe, args: [{
                    name: 'dateFilter'
                },] },
        { type: Injectable }
    ];
    return DatePipe;
}());
/**
 * Pipe que se utiliza para separar los string de los nombres de los enumerables por palabra, de manera que queden mas agradables
 * visualmente.
 */
var BeautifyPipe = /** @class */ (function () {
    function BeautifyPipe() {
    }
    /**
     * @param {?} text
     * @return {?}
     */
    BeautifyPipe.prototype.transform = /**
     * @param {?} text
     * @return {?}
     */
    function (text) {
        var e_1, _a;
        if (text) {
            /** @type {?} */
            var palabras = text.split(/(?=[A-Z])/);
            /** @type {?} */
            var palabraAretornar = '';
            try {
                for (var palabras_1 = __values(palabras), palabras_1_1 = palabras_1.next(); !palabras_1_1.done; palabras_1_1 = palabras_1.next()) {
                    var palabra = palabras_1_1.value;
                    palabraAretornar = palabraAretornar.concat(' ', palabra);
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (palabras_1_1 && !palabras_1_1.done && (_a = palabras_1.return)) _a.call(palabras_1);
                }
                finally { if (e_1) throw e_1.error; }
            }
            return palabraAretornar;
        }
        return text;
    };
    BeautifyPipe.decorators = [
        { type: Pipe, args: [{ name: 'beautify' },] }
    ];
    return BeautifyPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Filter object array from property
 */
var PadLeftPipe = /** @class */ (function () {
    function PadLeftPipe() {
    }
    /**
     * @param {?} value
     * @param {?} size
     * @param {?} pad
     * @return {?}
     */
    PadLeftPipe.prototype.transform = /**
     * @param {?} value
     * @param {?} size
     * @param {?} pad
     * @return {?}
     */
    function (value, size, pad) {
        /** @type {?} */
        var s = String(value);
        while (s.length < (size || 2)) {
            s = pad + s;
        }
        return s;
    };
    PadLeftPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'padLeft'
                },] },
        { type: Injectable }
    ];
    return PadLeftPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Filter object array from property
 */
var SafeStringPipe = /** @class */ (function () {
    function SafeStringPipe() {
    }
    /**
     * @param {?} value
     * @return {?}
     */
    SafeStringPipe.prototype.transform = /**
     * @param {?} value
     * @return {?}
     */
    function (value) {
        if (value) {
            return value;
        }
        else {
            return '-';
        }
    };
    SafeStringPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'safeString'
                },] },
        { type: Injectable }
    ];
    return SafeStringPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Pipe que se utiliza para separar los string de los nombres de los enumerables por palabra, de manera que queden mas agradables
 * visualmente.
 * Se le pasa por parámetro el string separador, el cual no se visualizará en pantalla.
 */
var SplitBeautyPipe = /** @class */ (function () {
    function SplitBeautyPipe() {
    }
    /**
     * @param {?} text
     * @param {?} args
     * @return {?}
     */
    SplitBeautyPipe.prototype.transform = /**
     * @param {?} text
     * @param {?} args
     * @return {?}
     */
    function (text, args) {
        var e_1, _a;
        if (text && args) {
            /** @type {?} */
            var palabras = text.split(args);
            /** @type {?} */
            var palabraAretornar = '';
            try {
                for (var palabras_1 = __values(palabras), palabras_1_1 = palabras_1.next(); !palabras_1_1.done; palabras_1_1 = palabras_1.next()) {
                    var palabra = palabras_1_1.value;
                    palabraAretornar = palabraAretornar.concat(' ', palabra);
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (palabras_1_1 && !palabras_1_1.done && (_a = palabras_1.return)) _a.call(palabras_1);
                }
                finally { if (e_1) throw e_1.error; }
            }
            return palabraAretornar;
        }
        return text;
    };
    SplitBeautyPipe.decorators = [
        { type: Pipe, args: [{ name: 'splitBeauty' },] }
    ];
    return SplitBeautyPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Filter object array from property
 */
var UnisexPipe = /** @class */ (function () {
    function UnisexPipe() {
    }
    /**
     * @param {?} value
     * @param {?=} last
     * @return {?}
     */
    UnisexPipe.prototype.transform = /**
     * @param {?} value
     * @param {?=} last
     * @return {?}
     */
    function (value, last) {
        if (last === void 0) { last = 'x'; }
        if (value) {
            if (value.slice(-1) === last) {
                return value.slice(0, -1) + "o/a";
            }
            return value;
        }
        else {
            throw new Error('Undefined value in unisex pipe');
        }
    };
    UnisexPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'unisex'
                },] },
        { type: Injectable }
    ];
    return UnisexPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * Filter object array from property
 */
var AccentPipe = /** @class */ (function () {
    function AccentPipe() {
    }
    /**
     * @param {?} value
     * @param {?} replace
     * @return {?}
     */
    AccentPipe.prototype.transform = /**
     * @param {?} value
     * @param {?} replace
     * @return {?}
     */
    function (value, replace) {
        if (value) {
            if (replace) {
                /** @type {?} */
                var val = value;
                val = val.replace(/1a/g, 'á');
                val = val.replace(/1e/g, 'é');
                val = val.replace(/1i/g, 'í');
                val = val.replace(/1o/g, 'ó');
                val = val.replace(/1u/g, 'ú');
                return val;
            }
            else {
                return value.replace(/1/g, '');
            }
        }
    };
    AccentPipe.decorators = [
        { type: Pipe, args: [{
                    name: 'accent'
                },] },
        { type: Injectable }
    ];
    return AccentPipe;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var NgxNeoPipesModule = /** @class */ (function () {
    function NgxNeoPipesModule() {
    }
    /**
     * @return {?}
     */
    NgxNeoPipesModule.forRoot = /**
     * @return {?}
     */
    function () {
        return {
            ngModule: NgxNeoPipesModule,
        };
    };
    NgxNeoPipesModule.decorators = [
        { type: NgModule, args: [{
                    declarations: [NumberPipe, TextPipe, TextPipeTwoLevel, NumberPipeTwoLevel, ToStringPipe, FuncFilterPipe,
                        BeautifyPipe, DatePipe, RangePipe, RangePipeTwoLevel, PadLeftPipe, SafeStringPipe, SplitBeautyPipe, UnisexPipe, AccentPipe],
                    exports: [NumberPipe, TextPipe, TextPipeTwoLevel, NumberPipeTwoLevel, ToStringPipe, FuncFilterPipe,
                        BeautifyPipe, DatePipe, RangePipe, RangePipeTwoLevel, PadLeftPipe, SafeStringPipe, SplitBeautyPipe, UnisexPipe, AccentPipe],
                },] }
    ];
    return NgxNeoPipesModule;
}());

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { NgxNeoPipesModule, FuncFilterPipe, TextPipe, TextPipeTwoLevel, NumberPipe, ToStringPipe, NumberPipeTwoLevel, RangePipe, RangePipeTwoLevel, DatePipe, BeautifyPipe, SafeStringPipe, UnisexPipe, AccentPipe, PadLeftPipe as ɵa, SplitBeautyPipe as ɵb };

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVvY29tcGxleHgtbmd4LW5lby1waXBlcy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQG5lb2NvbXBsZXh4L25neC1uZW8tcGlwZXMvbGliL2ZpbHRlcnMucGlwZS50cyIsIm5nOi8vQG5lb2NvbXBsZXh4L25neC1uZW8tcGlwZXMvbGliL251bWJlci5waXBlLnRzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvc2FmZS1zdHJpbmcucGlwZS50cyIsIm5nOi8vQG5lb2NvbXBsZXh4L25neC1uZW8tcGlwZXMvbGliL3NwbGl0QmVhdXR5LnBpcGUudHMiLCJuZzovL0BuZW9jb21wbGV4eC9uZ3gtbmVvLXBpcGVzL2xpYi91bmlzZXgucGlwZS50cyIsIm5nOi8vQG5lb2NvbXBsZXh4L25neC1uZW8tcGlwZXMvbGliL2FjY2VudC5waXBlLnRzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvbmd4LW5lby1waXBlcy5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuLyoqXHJcbiAqIEZpbHRlciBvYmplY3QgYXJyYXkgZnJvbSBwcm9wZXJ0eVxyXG4gKi9cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ2Z1bmN0aW9uRmlsdGVyJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBGdW5jRmlsdGVyUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgY2FsbGJhY2s6ICh2YWx1ZTogYW55KSA9PiBib29sZWFuKTogYW55W10ge1xyXG5cclxuICAgICAgICBpZiAoIWl0ZW1zIHx8ICFjYWxsYmFjaykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKGNhbGxiYWNrKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbHRlciBvYmplY3QgYXJyYXkgZnJvbSBwcm9wZXJ0eVxyXG4gKi9cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3RleHRGaWx0ZXInXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFRleHRQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICAvKipcclxuICAgICAqIEBhdXRob3IgamNhbmdlbG9zaVxyXG4gICAgICogRmlsdHJhIGVsIGFycmVnbG8gaXRlbXMgY29tcGFyYW5kbyBlbCB2YWxvciBkZSBzdSBjYW1wbyBmaWVsZCAoZGUgdGlwbyBzdHJpbmcpIGNvbiBlbCB2YWxvciBkZSB2YWx1ZVxyXG4gICAgICogaWRlYSBnZW5lcmFsIDogaXRlbXMuZmllbGQgPT0gdmFsdWVcclxuICAgICAqIE5PIEZVTkNJT05BIENPTiBOVU1FUk9TXHJcbiAgICAgKi9cclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBhbnlbXSB7XHJcbiAgICAgICAgaWYgKCFpdGVtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghZmllbGQgfHwgIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW1bZmllbGRdLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUudG9Mb3dlckNhc2UoKSkpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBBcnJheSBmaWx0ZXIgd2l0aCBzdHJpbmcgdmFsdWUgd2l0aCAyIGluZGlyZWN0aW9uIGxldmVsXHJcbiAqL1xyXG5AUGlwZSh7XHJcbiAgICBuYW1lOiAndGV4dEZpbHRlcjJMZXZlbCdcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgVGV4dFBpcGVUd29MZXZlbCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBAYXV0aG9yIGpjYW5nZWxvc2lcclxuICAgICAqIEZpbHRyYSBlbCBhcnJlZ2xvIGl0ZW1zIGNvbXBhcmFuZG8gZWwgdmFsb3IgZGUgc3UgY2FtcG8gc2Vjb25kZmllbGQgY29uIGVsIHZhbG9yIGRlIHZhbHVlXHJcbiAgICAgKiBpZGVhIGdlbmVyYWwgOiBpdGVtcy5maWVsZC5zZWNvbmRGaWVsZCA9PSB2YWx1ZVxyXG4gICAgICogTk8gRlVOQ0lPTkEgQ09OIE5VTUVST1NcclxuICAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgZmlyc3RGaWVsZDogc3RyaW5nLCBzZWNvbmRGaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogYW55W10ge1xyXG5cclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaXJzdEZpZWxkIHx8ICFzZWNvbmRGaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gKHNpbmdsZUl0ZW1bZmlyc3RGaWVsZF1bc2Vjb25kRmllbGRdKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlLnRvTG93ZXJDYXNlKCkpKTtcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ251bWJlckZpbHRlcidcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTnVtYmVyUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgLyoqXHJcbiAgICAqIEBhdXRob3IgamNhbmdlbG9zaVxyXG4gICAgKiBGaWx0cmEgZWwgYXJyZWdsbyBpdGVtcyBjb21wYXJhbmRvIGVsIHZhbG9yIGRlIHN1IGNhbXBvIGZpZWxkIChkZSB0aXBvIG51bWJlcikgY29uIGVsIHZhbG9yIGRlIHZhbHVlXHJcbiAgICAqIGlkZWEgZ2VuZXJhbCA6IGl0ZW1zLmZpZWxkID09IHZhbHVlXHJcbiAgICAqIFNPTE8gRlVOQ0lPTkEgQ09OIE5VTUVST1NcclxuICAgICovXHJcbiAgICB0cmFuc2Zvcm0oaXRlbXM6IGFueVtdLCBmaWVsZDogc3RyaW5nLCB2YWx1ZTogbnVtYmVyKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpZWxkIHx8ICF2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpZWxkXS50b1N0cmluZygpLmluY2x1ZGVzKHZhbHVlLnRvU3RyaW5nKCkpKTtcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3RvU3RyaW5nRmlsdGVyJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBUb1N0cmluZ1BpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIHZhbHVlOiBzdHJpbmcpOiBhbnlbXSB7XHJcbiAgICAgICAgaWYgKCFpdGVtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUudG9Mb3dlckNhc2UoKSkpO1xyXG4gICAgfVxyXG59XHJcblxyXG5AUGlwZSh7XHJcbiAgICBuYW1lOiAnbnVtYmVyRmlsdGVyMkxldmVsJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOdW1iZXJQaXBlVHdvTGV2ZWwgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIC8qKlxyXG4gICAgICogQGF1dGhvciBqY2FuZ2Vsb3NpXHJcbiAgICAgKiBGaWx0cmEgZWwgYXJyZWdsbyBpdGVtcyBjb21wYXJhbmRvIGVsIHZhbG9yIGRlIHN1IGNhbXBvIHNlY29uZGZpZWxkIGNvbiBlbCB2YWxvciBkZSB2YWx1ZVxyXG4gICAgICogaWRlYSBnZW5lcmFsIDogaXRlbXMuZmllbGQuc2Vjb25kRmllbGQgPT0gdmFsdWVcclxuICAgICAqIFNPTE8gRlVOQ0lPTkEgQ09OIE5VTUVST1NcclxuICAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgZmlyc3RGaWVsZDogc3RyaW5nLCBzZWNvbmRGaWVsZDogc3RyaW5nLCB2YWx1ZTogbnVtYmVyKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpcnN0RmllbGQgfHwgIXNlY29uZEZpZWxkIHx8ICF2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXS50b1N0cmluZygpLmluY2x1ZGVzKHZhbHVlLnRvU3RyaW5nKCkpKTtcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3JhbmdlRmlsdGVyJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBSYW5nZVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIC8qKlxyXG4gICAgICogQGF1dGhvciBqY2FuZ2Vsb3NpXHJcbiAgICAgKiAgRmlsdHJhcmEgZWwgYXJyZWdsbyBlbiBiYXNlIGEgdW4gcmFuZ28gZGUgdmFsb3JlcyBudW1lcmljb3MgZGVudHJvIGRlIHVuIHN0cmluZ1xyXG4gICAgICogIEFjZXB0YSBsbyBzaWd1aWVudGU6IDxudW1lcm8sIG51bWVybzEtbnVtZXJvMiAoPj1udW1lcm8xIHkgPG51bWVybzIpLCA+PW51bWVybzJcclxuICAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgZmllbGQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IGFueVtdIHtcclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUudG9TdHJpbmcoKS5pbmNsdWRlcygnPCcpKSB7IC8vIENhc28gMTogZXMgbWVub3JcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvcyA9IHZhbHVlLnNwbGl0KCc8Jyk7XHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVybzogbnVtYmVyID0gK251bWVyb3NbMV07XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpZWxkXSA8IG51bWVybyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZS50b1N0cmluZygpLmluY2x1ZGVzKCctJykpIHsgLy8gQ2FzbyAyOiBSYW5nb1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm9zID0gdmFsdWUuc3BsaXQoJy0nKTtcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvMTogbnVtYmVyID0gKyBudW1lcm9zWzBdO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm8yOiBudW1iZXIgPSArIG51bWVyb3NbMV07XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpZWxkXSA+PSBudW1lcm8xICYmIHNpbmdsZUl0ZW1bZmllbGRdIDwgbnVtZXJvMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZS50b1N0cmluZygpLmluY2x1ZGVzKCc+PScpKSB7IC8vIENhc28gMzogTWF5b3IgbyBJZ3VhbFxyXG4gICAgICAgICAgICBjb25zdCBudW1lcm9zID0gdmFsdWUuc3BsaXQoJz49Jyk7XHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVybzogbnVtYmVyID0gKyBudW1lcm9zWzFdO1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaWVsZF0gPj0gbnVtZXJvKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQ2FzbyA0LCBpdGVtIHZhY2lvXHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgfVxyXG59XHJcblxyXG5AUGlwZSh7XHJcbiAgICBuYW1lOiAncmFuZ2VGaWx0ZXIyTGV2ZWwnXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFJhbmdlUGlwZVR3b0xldmVsIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICAvKipcclxuICAgICAqIEBhdXRob3IgamNhbmdlbG9zaVxyXG4gICAgICogRmlsdHJhIGVsIGFycmVnbG8gaXRlbXMgY29tcGFyYW5kbyBlbCB2YWxvciBkZSBzdSBjYW1wbyBzZWNvbmRmaWVsZCBlbiBiYXNlIGEgdW4gcmFuZ28gZGUgdmFsb3JlcyBudW1lcmljb3MgZGVudHJvIGRlIHVuIHN0cmluZ1xyXG4gICAgICogIEFjZXB0YSBsbyBzaWd1aWVudGU6IDxudW1lcm8sIG51bWVybzEtbnVtZXJvMiAoPj1udW1lcm8xIHkgPG51bWVybzIpLCA+PW51bWVybzJcclxuICAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgZmlyc3RGaWVsZDogc3RyaW5nLCBzZWNvbmRGaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpcnN0RmllbGQgfHwgIXNlY29uZEZpZWxkIHx8ICF2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZS50b1N0cmluZygpLmluY2x1ZGVzKCc8JykpIHsgLy8gQ2FzbyAxOiBlcyBtZW5vclxyXG4gICAgICAgICAgICBjb25zdCBudW1lcm9zID0gdmFsdWUuc3BsaXQoJzwnKTtcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvOiBudW1iZXIgPSArbnVtZXJvc1sxXTtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW1bZmlyc3RGaWVsZF1bc2Vjb25kRmllbGRdIDwgbnVtZXJvKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZhbHVlLnRvU3RyaW5nKCkuaW5jbHVkZXMoJy0nKSkgeyAvLyBDYXNvIDI6IFJhbmdvXHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVyb3MgPSB2YWx1ZS5zcGxpdCgnLScpO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm8xOiBudW1iZXIgPSArIG51bWVyb3NbMF07XHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVybzI6IG51bWJlciA9ICsgbnVtZXJvc1sxXTtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW1bZmlyc3RGaWVsZF1bc2Vjb25kRmllbGRdID49IG51bWVybzEgJiZcclxuICAgICAgICAgICAgICAgIHNpbmdsZUl0ZW1bZmlyc3RGaWVsZF1bc2Vjb25kRmllbGRdIDwgbnVtZXJvMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZS50b1N0cmluZygpLmluY2x1ZGVzKCc+JykpIHsgLy8gQ2FzbyAzOiBNYXlvciBvIElndWFsXHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVyb3MgPSB2YWx1ZS5zcGxpdCgnPicpO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm86IG51bWJlciA9ICsgbnVtZXJvc1sxXTtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW1bZmlyc3RGaWVsZF1bc2Vjb25kRmllbGRdID49IG51bWVybyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENhc28gNCwgaXRlbSB2YWNpb1xyXG4gICAgICAgIHJldHVybiBpdGVtcztcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ2RhdGVGaWx0ZXInXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuLyoqXHJcbiAqIEZpbHRyYXJhIGFycmVnbG9zIG1lZGlhbnRlIHVuIGxvcyB2YWxvcmVzIGRlIHVuIGNhbXBvIGRlIHRpcG8gZmVjaGFcclxuICovXHJcbmV4cG9ydCBjbGFzcyBEYXRlUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBAYXV0aG9yIGpjYW5nZWxvc2lcclxuICAgICAqIEZpbHRyYXJhIGVsIGFycmVnbG8gaXRlbXMgcG9yIHVuYSBmZWNoYSByZXByZXNlbnRhZGEgcG9yIHVuIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICB0cmFuc2Zvcm0oaXRlbXM6IHN0cmluZ1tdLCBmaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpZWxkIHx8ICF2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNhc28gY29udHJhcmlvIGxhIGZlY2hhIGVzIHZhbGlkYVxyXG4gICAgICAgIGNvbnN0IHZhbG9yZXM6IFN0cmluZ1tdID0gdmFsdWUuc3BsaXQoJy0nKTtcclxuICAgICAgICBjb25zdCBmZWNoYTogU3RyaW5nID0gdmFsb3Jlc1syXSArICcvJyArIHZhbG9yZXNbMV0gKyAnLycgKyB2YWxvcmVzWzBdO1xyXG4gICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpZWxkXS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGZlY2hhKSk7XHJcbiAgICB9XHJcbn1cclxuLyoqXHJcbiAqIFBpcGUgcXVlIHNlIHV0aWxpemEgcGFyYSBzZXBhcmFyIGxvcyBzdHJpbmcgZGUgbG9zIG5vbWJyZXMgZGUgbG9zIGVudW1lcmFibGVzIHBvciBwYWxhYnJhLCBkZSBtYW5lcmEgcXVlIHF1ZWRlbiBtYXMgYWdyYWRhYmxlc1xyXG4gKiB2aXN1YWxtZW50ZS5cclxuICovXHJcbkBQaXBlKHsgbmFtZTogJ2JlYXV0aWZ5JyB9KVxyXG5leHBvcnQgY2xhc3MgQmVhdXRpZnlQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICB0cmFuc2Zvcm0odGV4dDogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKHRleHQpIHtcclxuICAgICAgICAgICAgY29uc3QgcGFsYWJyYXM6IHN0cmluZ1tdID0gdGV4dC5zcGxpdCgvKD89W0EtWl0pLyk7XHJcbiAgICAgICAgICAgIGxldCBwYWxhYnJhQXJldG9ybmFyID0gJyc7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGFsYWJyYSBvZiBwYWxhYnJhcykge1xyXG4gICAgICAgICAgICAgICAgcGFsYWJyYUFyZXRvcm5hciA9IHBhbGFicmFBcmV0b3JuYXIuY29uY2F0KCcgJywgcGFsYWJyYSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHBhbGFicmFBcmV0b3JuYXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0ZXh0O1xyXG4gICAgfVxyXG59XHJcbiIsIi8qKlxyXG4gKiBAYXV0aG9yIFNlYmFzdGlhbiBMYXJyaWV1XHJcbiAqIEBlbWFpbCBzbGFycmlldUB0ZWFtLm5lb2NvbXBsZXh4LmNvbVxyXG4gKiBAY3JlYXRlIGRhdGUgMjAxOS0wMi0wMSAxNToxMjo1OFxyXG4gKi9cclxuaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuLyoqXHJcbiAqIEZpbHRlciBvYmplY3QgYXJyYXkgZnJvbSBwcm9wZXJ0eVxyXG4gKi9cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3BhZExlZnQnXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFBhZExlZnRQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcblxyXG4gICAgdHJhbnNmb3JtKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsIHNpemU6IG51bWJlciwgcGFkOiBzdHJpbmcpIHtcclxuICAgICAgICBsZXQgcyA9IFN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgd2hpbGUgKHMubGVuZ3RoIDwgKHNpemUgfHwgMikpIHsgcyA9IHBhZCArIHM7IH1cclxuICAgICAgICByZXR1cm4gcztcclxuICAgIH1cclxufVxyXG4iLCIvKipcclxuICogQGF1dGhvciBTZWJhc3RpYW4gTGFycmlldVxyXG4gKiBAZW1haWwgc2xhcnJpZXVAdGVhbS5uZW9jb21wbGV4eC5jb21cclxuICogQGNyZWF0ZSBkYXRlIDIwMTktMDItMDEgMTU6MTI6NThcclxuICovXHJcbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdzYWZlU3RyaW5nJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBTYWZlU3RyaW5nUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG5cclxuICAgIHRyYW5zZm9ybSh2YWx1ZTogYW55KSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gJy0nO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgeyBQaXBlVHJhbnNmb3JtLCBQaXBlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbi8qKlxyXG4gKiBQaXBlIHF1ZSBzZSB1dGlsaXphIHBhcmEgc2VwYXJhciBsb3Mgc3RyaW5nIGRlIGxvcyBub21icmVzIGRlIGxvcyBlbnVtZXJhYmxlcyBwb3IgcGFsYWJyYSwgZGUgbWFuZXJhIHF1ZSBxdWVkZW4gbWFzIGFncmFkYWJsZXNcclxuICogdmlzdWFsbWVudGUuXHJcbiAqIFNlIGxlIHBhc2EgcG9yIHBhcsODwqFtZXRybyBlbCBzdHJpbmcgc2VwYXJhZG9yLCBlbCBjdWFsIG5vIHNlIHZpc3VhbGl6YXLDg8KhIGVuIHBhbnRhbGxhLlxyXG4gKi9cclxuQFBpcGUoeyBuYW1lOiAnc3BsaXRCZWF1dHknIH0pXHJcbmV4cG9ydCBjbGFzcyBTcGxpdEJlYXV0eVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIFxyXG4gICAgdHJhbnNmb3JtKHRleHQ6IHN0cmluZywgYXJnczogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAodGV4dCAmJiBhcmdzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhbGFicmFzOiBzdHJpbmdbXSA9IHRleHQuc3BsaXQoYXJncyk7XHJcbiAgICAgICAgICAgIGxldCBwYWxhYnJhQXJldG9ybmFyID0gJyc7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGFsYWJyYSBvZiBwYWxhYnJhcykge1xyXG4gICAgICAgICAgICAgICAgcGFsYWJyYUFyZXRvcm5hciA9IHBhbGFicmFBcmV0b3JuYXIuY29uY2F0KCcgJywgcGFsYWJyYSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHBhbGFicmFBcmV0b3JuYXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0ZXh0O1xyXG4gICAgfVxyXG59XHJcbiIsIi8qKlxyXG4gKiBAYXV0aG9yIFNlYmFzdGlhbiBMYXJyaWV1XHJcbiAqIEBlbWFpbCBzbGFycmlldUB0ZWFtLm5lb2NvbXBsZXh4LmNvbVxyXG4gKiBAY3JlYXRlIGRhdGUgMjAyMC0wMS0xNyAxNjozMTozMlxyXG4gKi9cclxuaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuLyoqXHJcbiAqIEZpbHRlciBvYmplY3QgYXJyYXkgZnJvbSBwcm9wZXJ0eVxyXG4gKi9cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3VuaXNleCdcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgVW5pc2V4UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG5cclxuICAgIHRyYW5zZm9ybSh2YWx1ZTogc3RyaW5nLCBsYXN0OiBzdHJpbmcgPSAneCcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlLnNsaWNlKC0xKSA9PT0gbGFzdCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3ZhbHVlLnNsaWNlKDAsIC0xKX1vL2FgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZGVmaW5lZCB2YWx1ZSBpbiB1bmlzZXggcGlwZScpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvKiBkYXRlIDIwMjAtMDMtMTMgMTA6NDA6MzBcclxuICogQGF1dGhvciBTZWJhc3RpYW4gTGFycmlldVxyXG4gKiBAZW1haWwgc2xhcnJpZXVAdGVhbS5uZW9jb21wbGV4eC5jb21cclxuICogQGNyZWF0ZSBkYXRlIDIwMjAtMDEtMTcgMTY6MzE6MzJcclxuICovXHJcbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdhY2NlbnQnXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEFjY2VudFBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuXHJcbiAgICB0cmFuc2Zvcm0odmFsdWU6IHN0cmluZywgcmVwbGFjZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAocmVwbGFjZSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHZhbCA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgdmFsID0gdmFsLnJlcGxhY2UoLzFhL2csICfDg8KhJyk7XHJcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWwucmVwbGFjZSgvMWUvZywgJ8ODwqknKTtcclxuICAgICAgICAgICAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKC8xaS9nLCAnw4PCrScpO1xyXG4gICAgICAgICAgICAgICAgdmFsID0gdmFsLnJlcGxhY2UoLzFvL2csICfDg8KzJyk7XHJcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWwucmVwbGFjZSgvMXUvZywgJ8ODwronKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUucmVwbGFjZSgvMS9nLCAnJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBOdW1iZXJQaXBlLCBUZXh0UGlwZSwgVGV4dFBpcGVUd29MZXZlbCwgTnVtYmVyUGlwZVR3b0xldmVsLFxyXG4gIEJlYXV0aWZ5UGlwZSwgRGF0ZVBpcGUsIFJhbmdlUGlwZSwgUmFuZ2VQaXBlVHdvTGV2ZWwsIFRvU3RyaW5nUGlwZSwgRnVuY0ZpbHRlclBpcGVcclxufSBmcm9tICcuL2ZpbHRlcnMucGlwZSc7XHJcbmltcG9ydCB7IFBhZExlZnRQaXBlIH0gZnJvbSAnLi9udW1iZXIucGlwZSc7XHJcbmltcG9ydCB7IFNhZmVTdHJpbmdQaXBlIH0gZnJvbSAnLi9zYWZlLXN0cmluZy5waXBlJztcclxuaW1wb3J0IHsgU3BsaXRCZWF1dHlQaXBlIH0gZnJvbSAnLi9zcGxpdEJlYXV0eS5waXBlJztcclxuaW1wb3J0IHsgVW5pc2V4UGlwZSB9IGZyb20gJy4vdW5pc2V4LnBpcGUnO1xyXG5pbXBvcnQgeyBBY2NlbnRQaXBlIH0gZnJvbSAnLi9hY2NlbnQucGlwZSc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGRlY2xhcmF0aW9uczogW051bWJlclBpcGUsIFRleHRQaXBlLCBUZXh0UGlwZVR3b0xldmVsLCBOdW1iZXJQaXBlVHdvTGV2ZWwsIFRvU3RyaW5nUGlwZSwgRnVuY0ZpbHRlclBpcGUsXHJcbiAgICBCZWF1dGlmeVBpcGUsIERhdGVQaXBlLCBSYW5nZVBpcGUsIFJhbmdlUGlwZVR3b0xldmVsLCBQYWRMZWZ0UGlwZSwgU2FmZVN0cmluZ1BpcGUsIFNwbGl0QmVhdXR5UGlwZSwgVW5pc2V4UGlwZSwgQWNjZW50UGlwZV0sXHJcbiAgZXhwb3J0czogW051bWJlclBpcGUsIFRleHRQaXBlLCBUZXh0UGlwZVR3b0xldmVsLCBOdW1iZXJQaXBlVHdvTGV2ZWwsIFRvU3RyaW5nUGlwZSwgRnVuY0ZpbHRlclBpcGUsXHJcbiAgICBCZWF1dGlmeVBpcGUsIERhdGVQaXBlLCBSYW5nZVBpcGUsIFJhbmdlUGlwZVR3b0xldmVsLCBQYWRMZWZ0UGlwZSwgU2FmZVN0cmluZ1BpcGUsIFNwbGl0QmVhdXR5UGlwZSwgVW5pc2V4UGlwZSwgQWNjZW50UGlwZV0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ3hOZW9QaXBlc01vZHVsZSB7XHJcbiAgc3RhdGljIGZvclJvb3QoKTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBuZ01vZHVsZTogTmd4TmVvUGlwZXNNb2R1bGUsXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iXSwibmFtZXMiOlsidHNsaWJfMS5fX3ZhbHVlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUtBO0lBQUE7S0FhQzs7Ozs7O0lBUkcsa0NBQVM7Ozs7O0lBQVQsVUFBVSxLQUFZLEVBQUUsUUFBaUM7UUFFckQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNyQixPQUFPLEVBQUUsQ0FBQztTQUNiO1FBRUQsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ2pDOztnQkFaSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLGdCQUFnQjtpQkFDekI7Z0JBQ0EsVUFBVTs7SUFVWCxxQkFBQztDQWJELElBYUM7Ozs7QUFLRDtJQUFBO0tBb0JDOzs7Ozs7Ozs7Ozs7Ozs7OztJQVRHLDRCQUFTOzs7Ozs7Ozs7O0lBQVQsVUFBVSxLQUFZLEVBQUUsS0FBYSxFQUFFLEtBQWE7UUFDaEQsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNSLE9BQU8sRUFBRSxDQUFDO1NBQ2I7UUFDRCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2xCLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBQSxDQUFDLENBQUM7S0FDcEc7O2dCQW5CSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLFlBQVk7aUJBQ3JCO2dCQUNBLFVBQVU7O0lBaUJYLGVBQUM7Q0FwQkQsSUFvQkM7Ozs7QUFJRDtJQUFBO0tBcUJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFWRyxvQ0FBUzs7Ozs7Ozs7Ozs7SUFBVCxVQUFVLEtBQVksRUFBRSxVQUFrQixFQUFFLFdBQW1CLEVBQUUsS0FBYTtRQUUxRSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUNELElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDdkMsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUEsQ0FBQyxDQUFDO0tBQ3hIOztnQkFwQkosSUFBSSxTQUFDO29CQUNGLElBQUksRUFBRSxrQkFBa0I7aUJBQzNCO2dCQUNBLFVBQVU7O0lBa0JYLHVCQUFDO0NBckJELElBcUJDOztJQUVEO0tBb0JDOzs7Ozs7Ozs7Ozs7Ozs7OztJQVRHLDhCQUFTOzs7Ozs7Ozs7O0lBQVQsVUFBVSxLQUFZLEVBQUUsS0FBYSxFQUFFLEtBQWE7UUFDaEQsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNSLE9BQU8sRUFBRSxDQUFDO1NBQ2I7UUFDRCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2xCLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBQSxDQUFDLENBQUM7S0FDOUY7O2dCQW5CSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLGNBQWM7aUJBQ3ZCO2dCQUNBLFVBQVU7O0lBaUJYLGlCQUFDO0NBcEJELElBb0JDOztJQUVEO0tBY0M7Ozs7OztJQVRHLGdDQUFTOzs7OztJQUFULFVBQVUsS0FBWSxFQUFFLEtBQWE7UUFDakMsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNSLE9BQU8sRUFBRSxDQUFDO1NBQ2I7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxHQUFBLENBQUMsQ0FBQztLQUN4Rzs7Z0JBYkosSUFBSSxTQUFDO29CQUNGLElBQUksRUFBRSxnQkFBZ0I7aUJBQ3pCO2dCQUNBLFVBQVU7O0lBV1gsbUJBQUM7Q0FkRCxJQWNDOztJQUVEO0tBb0JDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFURyxzQ0FBUzs7Ozs7Ozs7Ozs7SUFBVCxVQUFVLEtBQVksRUFBRSxVQUFrQixFQUFFLFdBQW1CLEVBQUUsS0FBYTtRQUMxRSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUNELElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDdkMsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFBLENBQUMsQ0FBQztLQUNoSDs7Z0JBbkJKLElBQUksU0FBQztvQkFDRixJQUFJLEVBQUUsb0JBQW9CO2lCQUM3QjtnQkFDQSxVQUFVOztJQWlCWCx5QkFBQztDQXBCRCxJQW9CQzs7SUFFRDtLQW9DQzs7Ozs7Ozs7Ozs7Ozs7O0lBMUJHLDZCQUFTOzs7Ozs7Ozs7SUFBVCxVQUFVLEtBQVksRUFBRSxLQUFhLEVBQUUsS0FBYTtRQUNoRCxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUNELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDbEIsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7OztnQkFDMUIsT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDOztnQkFDMUIsUUFBTSxHQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNsQyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBTSxHQUFBLENBQUMsQ0FBQztTQUNqRTtRQUNELElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTs7O2dCQUMxQixPQUFPLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7O2dCQUMxQixTQUFPLEdBQVcsQ0FBRSxPQUFPLENBQUMsQ0FBQyxDQUFDOztnQkFDOUIsU0FBTyxHQUFXLENBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNwQyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksU0FBTyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxTQUFPLEdBQUEsQ0FBQyxDQUFDO1NBQ2xHO1FBQ0QsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFOzs7Z0JBQzNCLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQzs7Z0JBQzNCLFFBQU0sR0FBVyxDQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQU0sR0FBQSxDQUFDLENBQUM7U0FDbEU7O1FBRUQsT0FBTyxLQUFLLENBQUM7S0FDaEI7O2dCQW5DSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLGFBQWE7aUJBQ3RCO2dCQUNBLFVBQVU7O0lBaUNYLGdCQUFDO0NBcENELElBb0NDOztJQUVEO0tBcUNDOzs7Ozs7Ozs7Ozs7Ozs7O0lBM0JHLHFDQUFTOzs7Ozs7Ozs7O0lBQVQsVUFBVSxLQUFZLEVBQUUsVUFBa0IsRUFBRSxXQUFtQixFQUFFLEtBQWE7UUFDMUUsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNSLE9BQU8sRUFBRSxDQUFDO1NBQ2I7UUFDRCxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ3ZDLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBQ0QsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFOzs7Z0JBQzFCLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7Z0JBQzFCLFFBQU0sR0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDbEMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLFFBQU0sR0FBQSxDQUFDLENBQUM7U0FDbkY7UUFDRCxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7OztnQkFDMUIsT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDOztnQkFDMUIsU0FBTyxHQUFXLENBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQzs7Z0JBQzlCLFNBQU8sR0FBVyxDQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDcEMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLFNBQU87Z0JBQzVFLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxXQUFXLENBQUMsR0FBRyxTQUFPLEdBQUEsQ0FBQyxDQUFDO1NBQ3REO1FBQ0QsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFOzs7Z0JBQzFCLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7Z0JBQzFCLFFBQU0sR0FBVyxDQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsVUFBVSxJQUFJLE9BQUEsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLFFBQU0sR0FBQSxDQUFDLENBQUM7U0FDcEY7O1FBRUQsT0FBTyxLQUFLLENBQUM7S0FDaEI7O2dCQXBDSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLG1CQUFtQjtpQkFDNUI7Z0JBQ0EsVUFBVTs7SUFrQ1gsd0JBQUM7Q0FyQ0QsSUFxQ0M7O0lBRUQ7S0F3QkM7Ozs7Ozs7Ozs7Ozs7SUFaRyw0QkFBUzs7Ozs7Ozs7SUFBVCxVQUFVLEtBQWUsRUFBRSxLQUFhLEVBQUUsS0FBYTtRQUNuRCxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1IsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUNELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDbEIsT0FBTyxLQUFLLENBQUM7U0FDaEI7OztZQUVLLE9BQU8sR0FBYSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQzs7WUFDcEMsS0FBSyxHQUFXLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFBLFVBQVUsSUFBSSxPQUFBLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUEsQ0FBQyxDQUFDO0tBQ3RGOztnQkF2QkosSUFBSSxTQUFDO29CQUNGLElBQUksRUFBRSxZQUFZO2lCQUNyQjtnQkFDQSxVQUFVOztJQXFCWCxlQUFDO0NBeEJELElBd0JDOzs7OztBQUtEO0lBQUE7S0FhQzs7Ozs7SUFYRyxnQ0FBUzs7OztJQUFULFVBQVUsSUFBWTs7UUFDbEIsSUFBSSxJQUFJLEVBQUU7O2dCQUNBLFFBQVEsR0FBYSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQzs7Z0JBQzlDLGdCQUFnQixHQUFHLEVBQUU7O2dCQUN6QixLQUFzQixJQUFBLGFBQUFBLFNBQUEsUUFBUSxDQUFBLGtDQUFBLHdEQUFFO29CQUEzQixJQUFNLE9BQU8scUJBQUE7b0JBQ2QsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztpQkFDNUQ7Ozs7Ozs7OztZQUNELE9BQU8sZ0JBQWdCLENBQUM7U0FDM0I7UUFDRCxPQUFPLElBQUksQ0FBQztLQUNmOztnQkFaSixJQUFJLFNBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFOztJQWExQixtQkFBQztDQWJEOzs7Ozs7Ozs7QUNsT0E7SUFBQTtLQVdDOzs7Ozs7O0lBTEcsK0JBQVM7Ozs7OztJQUFULFVBQVUsS0FBc0IsRUFBRSxJQUFZLEVBQUUsR0FBVzs7WUFDbkQsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDckIsT0FBTyxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsRUFBRTtZQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQUU7UUFDL0MsT0FBTyxDQUFDLENBQUM7S0FDWjs7Z0JBVkosSUFBSSxTQUFDO29CQUNGLElBQUksRUFBRSxTQUFTO2lCQUNsQjtnQkFDQSxVQUFVOztJQVFYLGtCQUFDO0NBWEQ7Ozs7Ozs7OztBQ0FBO0lBQUE7S0FhQzs7Ozs7SUFQRyxrQ0FBUzs7OztJQUFULFVBQVUsS0FBVTtRQUNoQixJQUFJLEtBQUssRUFBRTtZQUNQLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO2FBQU07WUFDSCxPQUFPLEdBQUcsQ0FBQztTQUNkO0tBQ0o7O2dCQVpKLElBQUksU0FBQztvQkFDRixJQUFJLEVBQUUsWUFBWTtpQkFDckI7Z0JBQ0EsVUFBVTs7SUFVWCxxQkFBQztDQWJEOzs7Ozs7Ozs7OztBQ0hBO0lBQUE7S0FjQzs7Ozs7O0lBWEcsbUNBQVM7Ozs7O0lBQVQsVUFBVSxJQUFZLEVBQUUsSUFBWTs7UUFDaEMsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFOztnQkFDUixRQUFRLEdBQWEsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7O2dCQUN2QyxnQkFBZ0IsR0FBRyxFQUFFOztnQkFDekIsS0FBc0IsSUFBQSxhQUFBQSxTQUFBLFFBQVEsQ0FBQSxrQ0FBQSx3REFBRTtvQkFBM0IsSUFBTSxPQUFPLHFCQUFBO29CQUNkLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7aUJBQzVEOzs7Ozs7Ozs7WUFDRCxPQUFPLGdCQUFnQixDQUFDO1NBQzNCO1FBQ0QsT0FBTyxJQUFJLENBQUM7S0FDZjs7Z0JBYkosSUFBSSxTQUFDLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRTs7SUFjN0Isc0JBQUM7Q0FkRDs7Ozs7Ozs7O0FDR0E7SUFBQTtLQWdCQzs7Ozs7O0lBVkcsOEJBQVM7Ozs7O0lBQVQsVUFBVSxLQUFhLEVBQUUsSUFBa0I7UUFBbEIscUJBQUEsRUFBQSxVQUFrQjtRQUN2QyxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDMUIsT0FBVSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFLLENBQUM7YUFDckM7WUFDRCxPQUFPLEtBQUssQ0FBQztTQUNoQjthQUFNO1lBQ0gsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1NBQ3JEO0tBQ0o7O2dCQWZKLElBQUksU0FBQztvQkFDRixJQUFJLEVBQUUsUUFBUTtpQkFDakI7Z0JBQ0EsVUFBVTs7SUFhWCxpQkFBQztDQWhCRDs7Ozs7Ozs7O0FDQUE7SUFBQTtLQXFCQzs7Ozs7O0lBZkcsOEJBQVM7Ozs7O0lBQVQsVUFBVSxLQUFhLEVBQUUsT0FBZ0I7UUFDckMsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLE9BQU8sRUFBRTs7b0JBQ0wsR0FBRyxHQUFHLEtBQUs7Z0JBQ2YsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QixHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzlCLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDOUIsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QixHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzlCLE9BQU8sR0FBRyxDQUFDO2FBQ2Q7aUJBQU07Z0JBQ0gsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQzthQUNsQztTQUNKO0tBQ0o7O2dCQXBCSixJQUFJLFNBQUM7b0JBQ0YsSUFBSSxFQUFFLFFBQVE7aUJBQ2pCO2dCQUNBLFVBQVU7O0lBa0JYLGlCQUFDO0NBckJEOzs7Ozs7QUNWQTtJQVdBO0tBWUM7Ozs7SUFMUSx5QkFBTzs7O0lBQWQ7UUFDRSxPQUFPO1lBQ0wsUUFBUSxFQUFFLGlCQUFpQjtTQUM1QixDQUFDO0tBQ0g7O2dCQVhGLFFBQVEsU0FBQztvQkFDUixZQUFZLEVBQUUsQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxjQUFjO3dCQUNyRyxZQUFZLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDO29CQUM3SCxPQUFPLEVBQUUsQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxjQUFjO3dCQUNoRyxZQUFZLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDO2lCQUM5SDs7SUFPRCx3QkFBQztDQVpEOzs7Ozs7Ozs7Ozs7OzsifQ==