UNPKG

@greg-md/ng-flex-css-layout

Version:

Flex-CSS-Layout is an alternative behaviour of Flex-Layout directives, that will still work with Angular Universal and App Shell.

2,516 lines 218 kB
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { Injectable, Inject, InjectionToken, Directive, ElementRef, Input, Renderer2, Optional, Self, Host, SkipSelf, PLATFORM_ID, NgModule } from '@angular/core';
import { ReplaySubject } from 'rxjs';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/**
 * Applies CSS prefixes to appropriate style keys.
 *
 * Note: `-ms-`, `-moz` and `-webkit-box` are no longer supported. e.g.
 *    {
 *      display: -webkit-flex;     NEW - Safari 6.1+. iOS 7.1+, BB10
 *      display: flex;             NEW, Spec - Firefox, Chrome, Opera
 *      // display: -webkit-box;   OLD - iOS 6-, Safari 3.1-6, BB7
 *      // display: -ms-flexbox;   TWEENER - IE 10
 *      // display: -moz-flexbox;  OLD - Firefox
 *    }
 * @param {?} target
 * @return {?}
 */
function applyCssPrefixes(target) {
    Object.keys(target).forEach(key => {
        let /** @type {?} */ value = target[key] || '';
        switch (key) {
            case 'display':
                if (value === 'flex') {
                    target['display'] = [
                        '-webkit-flex',
                        'flex'
                    ];
                }
                else if (value === 'inline-flex') {
                    target['display'] = [
                        '-webkit-inline-flex',
                        'inline-flex'
                    ];
                }
                else {
                    target['display'] = value;
                }
                break;
            case 'align-items':
            case 'align-self':
            case 'align-content':
            case 'flex':
            case 'flex-basis':
            case 'flex-flow':
            case 'flex-grow':
            case 'flex-shrink':
            case 'flex-wrap':
            case 'justify-content':
                target['-webkit-' + key] = value;
                break;
            case 'flex-direction':
                value = value || 'row';
                target['-webkit-flex-direction'] = value;
                target['flex-direction'] = value;
                break;
            case 'order':
                target['order'] = target['-webkit-' + key] = isNaN(value) ? '0' : value;
                break;
        }
    });
    return target;
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
const /** @type {?} */ INLINE = 'inline';
const /** @type {?} */ LAYOUT_VALUES = ['row', 'column', 'row-reverse', 'column-reverse'];
/**
 * Validate the value to be one of the acceptable value options
 * Use default fallback of 'row'
 * @param {?} value
 * @return {?}
 */
function validateValue(value) {
    value = value ? value.toLowerCase() : '';
    let [direction, wrap, inline] = value.split(' ');
    // First value must be the `flex-direction`
    if (!LAYOUT_VALUES.find(x => x === direction)) {
        direction = LAYOUT_VALUES[0];
    }
    if (wrap === INLINE) {
        wrap = (inline !== INLINE) ? inline : '';
        inline = INLINE;
    }
    return [direction, validateWrapValue(wrap), !!inline];
}
/**
 * Determine if the validated, flex-direction value specifies
 * a horizontal/row flow.
 * @param {?} value
 * @return {?}
 */
function isFlowHorizontal(value) {
    const [flow,] = validateValue(value);
    return flow.indexOf('row') > -1;
}
/**
 * Convert layout-wrap='<value>' to expected flex-wrap style
 * @param {?} value
 * @return {?}
 */
function validateWrapValue(value) {
    if (!!value) {
        switch (value.toLowerCase()) {
            case 'reverse':
            case 'wrap-reverse':
            case 'reverse-wrap':
                value = 'wrap-reverse';
                break;
            case 'no':
            case 'none':
            case 'nowrap':
                value = 'nowrap';
                break;
            // All other values fallback to 'wrap'
            default:
                value = 'wrap';
                break;
        }
    }
    return value;
}
/**
 * Build the CSS that should be assigned to the element instance
 * BUG:
 *   1) min-height on a column flex container won’t apply to its flex item children in IE 10-11.
 *      Use height instead if possible; height : <xxx>vh;
 *
 *  This way any padding or border specified on the child elements are
 *  laid out and drawn inside that element's specified width and height.
 * @param {?} direction
 * @param {?=} wrap
 * @param {?=} inline
 * @return {?}
 */
function buildCSS(direction, wrap = null, inline = false) {
    return {
        'display': inline ? 'inline-flex' : 'flex',
        'box-sizing': 'border-box',
        'flex-direction': direction,
        'flex-wrap': !!wrap ? wrap : null
    };
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @param {?} align
 * @return {?}
 */
function normalizeLayoutAlignValue(align) {
    align = align || 'start stretch';
    let [mainAxis, crossAxis] = align.split(' ');
    switch (mainAxis) {
        case 'center':
        case 'space-around':
        case 'space-between':
        case 'space-evenly':
            break;
        case 'end':
        case 'flex-end':
            mainAxis = 'flex-end';
            break;
        case 'start':
        case 'flex-start':
        default:
            mainAxis = 'flex-start'; // default main axis
            break;
    }
    switch (crossAxis) {
        case 'start':
        case 'flex-start':
            crossAxis = 'flex-start';
            break;
        case 'baseline':
        case 'center':
            crossAxis = 'center';
            break;
        case 'end':
        case 'flex-end':
            crossAxis = 'flex-end';
            break;
        case 'stretch':
        default:
            // 'stretch'
            crossAxis = 'stretch'; // default cross axis
            break;
    }
    return [mainAxis, crossAxis];
}
/**
 * @param {?} direction
 * @param {?} wrap
 * @param {?} isInline
 * @param {?} breakpoint
 * @return {?}
 */
function generateLayoutClassName(direction, wrap, isInline, breakpoint) {
    return 'fcLayout'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + direction + (wrap ? '-' + wrap : '') + (isInline ? '-inline' : '');
}
/**
 * @param {?} mainAxis
 * @param {?} crossAxis
 * @param {?} breakpoint
 * @return {?}
 */
function generateLayoutAlignClassName(mainAxis, crossAxis, breakpoint) {
    return 'fcLayoutAlign'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + mainAxis + '-' + crossAxis;
}
/**
 * @param {?} value
 * @param {?} breakpoint
 * @return {?}
 */
function generateLayoutGapClassName(value, breakpoint) {
    return 'fcLayoutGap'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(value);
}
/**
 * @param {?} grow
 * @param {?} shrink
 * @param {?} basis
 * @param {?} breakpoint
 * @return {?}
 */
function generateFlexClassName(grow, shrink, basis, breakpoint) {
    return 'fcFlex'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(grow) + '-' + valueToClassName(shrink) + (basis ? '-' + valueToClassName(basis) : '');
}
/**
 * @param {?} order
 * @param {?} breakpoint
 * @return {?}
 */
function generateFlexOrderClassName(order, breakpoint) {
    return 'fcFlexOrder'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(order);
}
/**
 * @param {?} offset
 * @param {?} breakpoint
 * @return {?}
 */
function generateFlexOffsetClassName(offset, breakpoint) {
    return 'fcFlexOffset'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(offset);
}
/**
 * @param {?} align
 * @param {?} breakpoint
 * @return {?}
 */
function generateFlexAlignClassName(align, breakpoint) {
    return 'fcFlexAlign'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(align);
}
/**
 * @return {?}
 */
function generateFlexFillClassName() {
    return 'fcFlexFill';
}
/**
 * @param {?} display
 * @param {?} show
 * @param {?} breakpoint
 * @return {?}
 */
function generateFlexShowHideClassName(display, show, breakpoint) {
    return 'fcShow'
        + (breakpoint !== 'all' ? '--' + breakpoint : '')
        + '--' + valueToClassName(display)
        + '--' + (show ? 'show' : 'hide');
}
/**
 * @param {?} value
 * @return {?}
 */
function valueToClassName(value) {
    return String(value).replace(/[^a-zA-Z0-9-]/, '-');
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/**
 * The flex API permits 3 or 1 parts of the value:
 *    - `flex-grow flex-shrink flex-basis`, or
 *    - `flex-basis`
 * @param {?} basis
 * @param {?=} grow
 * @param {?=} shrink
 * @return {?}
 */
function validateBasis(basis, grow = '1', shrink = '1') {
    let /** @type {?} */ parts = [grow, shrink, basis];
    const /** @type {?} */ j = basis.indexOf('calc');
    if (j > 0) {
        parts[2] = _validateCalcValue(basis.substring(j).trim());
        const /** @type {?} */ matches = basis.substr(0, j).trim().split(' ');
        if (matches.length === 2) {
            parts[0] = matches[0];
            parts[1] = matches[1];
        }
    }
    else if (j === 0) {
        parts[2] = _validateCalcValue(basis.trim());
    }
    else {
        const /** @type {?} */ matches = basis.split(' ');
        parts = (matches.length === 3) ? matches : [
            grow, shrink, basis
        ];
    }
    return parts;
}
/**
 * Calc expressions require whitespace before & after any expression operators
 * This is a simple, crude whitespace padding solution.
 *   - '3 3 calc(15em + 20px)'
 *   - calc(100% / 7 * 2)
 *   - 'calc(15em + 20px)'
 *   - 'calc(15em+20px)'
 *   - '37px'
 *   = '43%'
 * @param {?} calc
 * @return {?}
 */
function _validateCalcValue(calc) {
    return calc.replace(/[\s]/g, '').replace(/[\/\*\+\-]/g, ' $& ');
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
const /** @type {?} */ FLEX_CSS_DEFAULT_BREAKPOINTS = [
    { alias: 'gt-xs', media: ['screen', '(min-width: 600px)'] },
    { alias: 'lt-xl', media: ['screen', '(max-width: 1919px)'] },
    { alias: 'gt-sm', media: ['screen', '(min-width: 960px)'] },
    { alias: 'lt-lg', media: ['screen', '(max-width: 1279px)'] },
    { alias: 'gt-md', media: ['screen', '(min-width: 1280px)'] },
    { alias: 'lt-md', media: ['screen', '(max-width: 959px)'] },
    { alias: 'gt-lg', media: ['screen', '(min-width: 1920px)'] },
    { alias: 'lt-sm', media: ['screen', '(max-width: 599px)'] },
    { alias: 'xl', media: ['screen', '(min-width: 1920px)', '(max-width: 5000px)'] },
    { alias: 'lg', media: ['screen', '(min-width: 1280px)', '(max-width: 1919px)'] },
    { alias: 'md', media: ['screen', '(min-width: 960px)', '(max-width: 1279px)'] },
    { alias: 'sm', media: ['screen', '(min-width: 600px)', '(max-width: 959px)'] },
    { alias: 'xs', media: ['screen', '(max-width: 599px)'] },
];
const /** @type {?} */ FLEX_CSS_BREAKPOINTS = new InjectionToken('flex_css_breakpoints');
class FlexCssStyleElement {
    /**
     * @param {?} style
     */
    constructor(style) {
        this.style = style;
        this.storage = {};
    }
}
class FlexCssService {
    /**
     * @param {?} doc
     * @param {?} breakpoints
     */
    constructor(doc, breakpoints) {
        this.doc = doc;
        this.breakpoints = breakpoints;
        this.initLayout();
        this.initFlex();
        this.initFill();
    }
    /**
     * @return {?}
     */
    initLayout() {
        const /** @type {?} */ style = this.doc.createElement('style');
        style.id = 'fc-layout';
        this.doc.head.appendChild(style);
        this.layout = new FlexCssStyleElement(style);
    }
    /**
     * @return {?}
     */
    initFlex() {
        const /** @type {?} */ style = this.doc.createElement('style');
        style.id = 'fc-flex';
        this.doc.head.appendChild(style);
        this.flex = new FlexCssStyleElement(style);
    }
    /**
     * @return {?}
     */
    initFill() {
        const /** @type {?} */ style = this.doc.createElement('style');
        style.id = 'fc-fill';
        this.doc.head.appendChild(style);
        this.fill = new FlexCssStyleElement(style);
    }
    /**
     * @param {?} layout
     * @param {?} breakpoint
     * @return {?}
     */
    addLayout(layout, breakpoint) {
        const [direction, wrap, isInline] = validateValue(layout);
        const /** @type {?} */ className = generateLayoutClassName(direction, wrap, isInline, breakpoint);
        if (!this.hasInLayoutStorage(className, breakpoint)) {
            const /** @type {?} */ style = buildCSS(direction, wrap, isInline);
            this.addToLayoutStorage(className, style, breakpoint);
        }
        return className;
    }
    /**
     * @param {?} layout
     * @param {?} layoutBreakpoint
     * @param {?} align
     * @param {?} breakpoint
     * @return {?}
     */
    addLayoutAlign(layout, layoutBreakpoint, align, breakpoint) {
        const [mainAxis, crossAxis] = normalizeLayoutAlignValue(align);
        const /** @type {?} */ layoutAlignClassName = generateLayoutAlignClassName(mainAxis, crossAxis, breakpoint);
        if (!this.hasInLayoutStorage(layoutAlignClassName, breakpoint)) {
            const /** @type {?} */ style = {
                'justify-content': mainAxis,
            };
            switch (crossAxis) {
                case 'baseline':
                    style['align-items'] = crossAxis;
                    break;
                default:
                    style['align-items'] = style['align-content'] = crossAxis;
                    break;
            }
            this.addToLayoutStorage(layoutAlignClassName, style, breakpoint);
        }
        if (crossAxis === 'stretch') {
            const [direction, wrap, isInline] = validateValue(layout);
            const /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
            const /** @type {?} */ className = layoutAlignClassName + '.' + layoutClassName;
            if (!this.hasInLayoutStorage(className, breakpoint)) {
                const /** @type {?} */ style = isFlowHorizontal(layout) ? { 'max-height': '100%' } : { 'max-width': '100%' };
                this.addToLayoutStorage(className, style, breakpoint, [layoutBreakpoint]);
            }
        }
        return layoutAlignClassName;
    }
    /**
     * @param {?} layout
     * @param {?} layoutBreakpoint
     * @param {?} value
     * @param {?} breakpoint
     * @return {?}
     */
    addLayoutGap(layout, layoutBreakpoint, value, breakpoint) {
        value = value || '0';
        const [direction, wrap, isInline] = validateValue(layout);
        const /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
        const /** @type {?} */ layoutGapClassName = generateLayoutGapClassName(value, breakpoint);
        const /** @type {?} */ className = layoutGapClassName + '.' + layoutClassName + ' > *:not(:last-child)';
        if (!this.hasInLayoutStorage(className, breakpoint)) {
            const /** @type {?} */ style = isFlowHorizontal(layout) ? { 'margin-right': value } : { 'margin-bottom': value };
            this.addToLayoutStorage(className, style, breakpoint, [layoutBreakpoint]);
        }
        return layoutGapClassName;
    }
    /**
     * @param {?} layout
     * @param {?} layoutBreakpoint
     * @param {?} value
     * @param {?} breakpoint
     * @param {?=} grow
     * @param {?=} shrink
     * @return {?}
     */
    addFlex(layout, layoutBreakpoint, value, breakpoint, grow, shrink) {
        value = value.replace(';', '');
        let [theGrow, theShrink, theBasis] = validateBasis(value, grow, shrink);
        theGrow = (theGrow === '0') ? 0 : theGrow;
        theShrink = (theShrink === '0') ? 0 : theShrink;
        // flex-basis allows you to specify the initial/starting main-axis size of the element,
        // before anything else is computed. It can either be a percentage or an absolute value.
        // It is, however, not the breaking point for flex-grow/shrink properties
        //
        // flex-grow can be seen as this:
        //   0: Do not stretch. Either size to element's content width, or obey 'flex-basis'.
        //   1: (Default value). Stretch; will be the same size to all other flex items on
        //       the same row since they have a default value of 1.
        //   ≥2 (integer n): Stretch. Will be n times the size of other elements
        //      with 'flex-grow: 1' on the same row.
        const /** @type {?} */ style = {
            'box-sizing': 'border-box',
        };
        switch (theBasis || '') {
            case '':
                style['flex'] = `${theGrow} ${theShrink} 0.000000001px`;
                break;
            case 'initial': // default
            case 'nogrow':
                theGrow = 0;
                style['flex'] = `0 1 auto`;
                break;
            case 'grow':
                style['flex'] = `1 1 100%`;
                break;
            case 'noshrink':
                theShrink = 0;
                style['flex'] = `1 0 auto`;
                break;
            case 'auto':
                style['flex'] = `${theGrow} ${theShrink} auto`;
                break;
            case 'none':
                theGrow = 0;
                theShrink = 0;
                style['flex'] = `0 0 auto`;
                break;
            default:
                const /** @type {?} */ isCalc = String(theBasis).indexOf('calc') > -1;
                const /** @type {?} */ isPercent = !isCalc && String(theBasis).indexOf('%') > -1;
                const /** @type {?} */ isValue = isCalc || isPercent ||
                    String(theBasis).indexOf('px') > -1 ||
                    String(theBasis).indexOf('em') > -1 ||
                    String(theBasis).indexOf('vw') > -1 ||
                    String(theBasis).indexOf('vh') > -1;
                // Defaults to percentage sizing unless `px` is explicitly set
                if (!isValue && !isPercent && !isNaN(/** @type {?} */ (theBasis))) {
                    theBasis = theBasis + '%';
                }
                if (theBasis === '0px') {
                    theBasis = '0%';
                }
                style['flex-grow'] = `${theGrow}`;
                style['flex-shrink'] = `${theShrink}`;
                style['flex-basis'] = style['min-width'] = style['max-width'] = isValue ? `${theBasis}` : '100%';
                break;
        }
        const /** @type {?} */ flexClassName = generateFlexClassName(theGrow, theShrink, theBasis, breakpoint);
        if (!this.hasInFlexStorage(flexClassName, breakpoint)) {
            this.addToFlexStorage(flexClassName, style, breakpoint);
        }
        const [direction, wrap, isInline] = validateValue(layout);
        const /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
        const /** @type {?} */ className = flexClassName + '.' + layoutClassName;
        if (!this.hasInFlexStorage(className, breakpoint)) {
            const /** @type {?} */ max = isFlowHorizontal(direction) ? 'max-width' : 'max-height';
            const /** @type {?} */ min = isFlowHorizontal(direction) ? 'min-width' : 'min-height';
            const /** @type {?} */ usingCalc = (String(theBasis).indexOf('calc') > -1) || (theBasis === 'auto');
            const /** @type {?} */ isPx = String(theBasis).indexOf('px') > -1 || usingCalc;
            // make box inflexible when shrink and grow are both zero
            // should not set a min when the grow is zero
            // should not set a max when the shrink is zero
            const /** @type {?} */ isFixed = !theGrow && !theShrink;
            const /** @type {?} */ layoutStyle = {};
            layoutStyle[min] = (theBasis === '0%') ? 0 : isFixed || (isPx && theGrow) ? theBasis : null;
            layoutStyle[max] = (theBasis === '0%') ? 0 : isFixed || (!usingCalc && theShrink) ? theBasis : null;
            this.addToFlexStorage(className, layoutStyle, breakpoint, [layoutBreakpoint]);
        }
        return flexClassName;
    }
    /**
     * @param {?} order
     * @param {?} breakpoint
     * @return {?}
     */
    addFlexOrder(order, breakpoint) {
        order = parseInt(order, 10);
        order = isNaN(order) ? 0 : order;
        const /** @type {?} */ className = generateFlexOrderClassName(order, breakpoint);
        if (!this.hasInFlexStorage(className, breakpoint)) {
            const /** @type {?} */ style = { 'order': order };
            this.addToFlexStorage(className, style, breakpoint);
        }
        return className;
    }
    /**
     * @param {?} layout
     * @param {?} layoutBreakpoint
     * @param {?} offset
     * @param {?} breakpoint
     * @return {?}
     */
    addFlexOffset(layout, layoutBreakpoint, offset, breakpoint) {
        const /** @type {?} */ isPercent = String(offset).indexOf('%') > -1;
        const /** @type {?} */ isPx = String(offset).indexOf('px') > -1;
        if (!isPx && !isPercent && !isNaN(offset)) {
            offset = offset + '%';
        }
        const [direction, wrap, isInline] = validateValue(layout);
        const /** @type {?} */ offsetClassName = generateFlexOffsetClassName(offset, breakpoint);
        const /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
        const /** @type {?} */ className = offsetClassName + '.' + layoutClassName;
        if (!this.hasInFlexStorage(className, breakpoint)) {
            const /** @type {?} */ style = isFlowHorizontal(direction) ? { 'margin-left': `${offset}` } : { 'margin-top': `${offset}` };
            this.addToFlexStorage(className, style, breakpoint, [layoutBreakpoint]);
        }
        return offsetClassName;
    }
    /**
     * @param {?} align
     * @param {?} breakpoint
     * @return {?}
     */
    addFlexAlign(align, breakpoint) {
        align = align || 'stretch';
        // Cross-axis
        switch (align) {
            case 'start':
                align = 'flex-start';
                break;
            case 'end':
                align = 'flex-end';
                break;
        }
        const /** @type {?} */ className = generateFlexAlignClassName(align, breakpoint);
        if (!this.hasInFlexStorage(className, breakpoint)) {
            const /** @type {?} */ style = { 'align-self': align };
            this.addToFlexStorage(className, style, breakpoint);
        }
        return className;
    }
    /**
     * @return {?}
     */
    addFlexFill() {
        const /** @type {?} */ className = generateFlexFillClassName();
        if (!this.hasInFillStorage(className, 'all')) {
            const /** @type {?} */ style = {
                'margin': 0,
                'width': '100%',
                'height': '100%',
                'min-width': '100%',
                'min-height': '100%',
            };
            this.addToFillStorage(className, style, 'all');
        }
        return className;
    }
    /**
     * @param {?} display
     * @param {?} show
     * @param {?} breakpoint
     * @return {?}
     */
    addShowHide(display, show, breakpoint) {
        const /** @type {?} */ className = generateFlexShowHideClassName(display, show, breakpoint);
        if (!this.hasInFillStorage(className, breakpoint)) {
            const /** @type {?} */ style = {
                'display': show ? display || 'block' : 'none',
            };
            this.addToFillStorage(className, style, breakpoint);
        }
        return className;
    }
    /**
     * @param {?} className
     * @param {?} breakpoint
     * @return {?}
     */
    hasInLayoutStorage(className, breakpoint) {
        return this.hasInStorage(this.layout, className, breakpoint);
    }
    /**
     * @param {?} className
     * @param {?} style
     * @param {?} breakpoint
     * @param {?=} customBreakpoints
     * @return {?}
     */
    addToLayoutStorage(className, style, breakpoint, customBreakpoints) {
        return this.addToStorage(this.layout, className, style, breakpoint, customBreakpoints);
    }
    /**
     * @param {?} className
     * @param {?} breakpoint
     * @return {?}
     */
    hasInFlexStorage(className, breakpoint) {
        return this.hasInStorage(this.flex, className, breakpoint);
    }
    /**
     * @param {?} className
     * @param {?} style
     * @param {?} breakpoint
     * @param {?=} customBreakpoints
     * @return {?}
     */
    addToFlexStorage(className, style, breakpoint, customBreakpoints) {
        return this.addToStorage(this.flex, className, style, breakpoint, customBreakpoints);
    }
    /**
     * @param {?} className
     * @param {?} breakpoint
     * @return {?}
     */
    hasInFillStorage(className, breakpoint) {
        return this.hasInStorage(this.fill, className, breakpoint);
    }
    /**
     * @param {?} className
     * @param {?} style
     * @param {?} breakpoint
     * @param {?=} customBreakpoints
     * @return {?}
     */
    addToFillStorage(className, style, breakpoint, customBreakpoints) {
        return this.addToStorage(this.fill, className, style, breakpoint, customBreakpoints);
    }
    /**
     * @param {?} styleElement
     * @param {?} className
     * @param {?} breakpoint
     * @return {?}
     */
    hasInStorage(styleElement, className, breakpoint) {
        return !!(styleElement.storage[breakpoint] && styleElement.storage[breakpoint][className]);
    }
    /**
     * @param {?} styleElement
     * @param {?} className
     * @param {?} style
     * @param {?} breakpoint
     * @param {?=} customBreakpoints
     * @return {?}
     */
    addToStorage(styleElement, className, style, breakpoint, customBreakpoints) {
        customBreakpoints = customBreakpoints || [];
        const /** @type {?} */ styles = applyCssPrefixes(style);
        const /** @type {?} */ css = this.generateCss(styles);
        if (css !== '') {
            const /** @type {?} */ classCss = '.' + className + ' { ' + css + ' }';
            const /** @type {?} */ cssElement = this.doc.createTextNode(this.addBreakpoints([breakpoint].concat(customBreakpoints), classCss));
            if (!styleElement.storage[breakpoint]) {
                styleElement.storage[breakpoint] = {};
            }
            styleElement.storage[breakpoint][className] = cssElement;
            this.reorderTextElements(styleElement);
        }
    }
    /**
     * @param {?} styleElement
     * @return {?}
     */
    reorderTextElements(styleElement) {
        let /** @type {?} */ position = this.reorderBreakpointElements(styleElement, 'all');
        this.breakpoints.forEach(breakpoint => {
            position = this.reorderBreakpointElements(styleElement, breakpoint.alias, position);
        });
    }
    /**
     * @param {?} styleElement
     * @param {?} breakpoint
     * @param {?=} position
     * @return {?}
     */
    reorderBreakpointElements(styleElement, breakpoint, position = 0) {
        const /** @type {?} */ breakpointElements = styleElement.storage[breakpoint];
        if (!breakpointElements) {
            return position;
        }
        Object.keys(breakpointElements).forEach(key => {
            if (styleElement.style.children.length) {
                styleElement.style.insertBefore(breakpointElements[key], styleElement.style.children[position]);
            }
            else {
                styleElement.style.appendChild(breakpointElements[key]);
            }
            ++position;
        });
        return position;
    }
    /**
     * @param {?} styles
     * @return {?}
     */
    generateCss(styles) {
        const /** @type {?} */ css = [];
        Object.keys(styles).sort().forEach(key => {
            const /** @type {?} */ values = Array.isArray(styles[key]) ? styles[key] : [styles[key]];
            values.sort();
            values.forEach(value => {
                if (value !== null && value !== '') {
                    css.push(key + ': ' + value + ';');
                }
            });
        });
        return css.join(' ');
    }
    /**
     * @param {?} breakpointsAliases
     * @param {?} css
     * @return {?}
     */
    addBreakpoints(breakpointsAliases, css) {
        breakpointsAliases = breakpointsAliases.filter(breakpoint => breakpoint !== 'all');
        if (!breakpointsAliases.length) {
            return css;
        }
        let /** @type {?} */ theBreakpoints = [];
        this.breakpoints
            .filter(breakpoint => breakpointsAliases.indexOf(breakpoint.alias) >= 0)
            .forEach(breakpoint => theBreakpoints = theBreakpoints.concat(breakpoint.media));
        theBreakpoints = theBreakpoints.filter((value, index, self) => self.indexOf(value) === index);
        return '@media ' + theBreakpoints.join(' and ') + ' { ' + css + ' }';
    }
}
FlexCssService.decorators = [
    { type: Injectable },
];
/** @nocollapse */
FlexCssService.ctorParameters = () => [
    { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
    { type: undefined, decorators: [{ type: Inject, args: [FLEX_CSS_BREAKPOINTS,] }] }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @abstract
 */
class BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     */
    constructor(elementRef, renderer) {
        this.elementRef = elementRef;
        this.renderer = renderer;
        this.classNames = [];
    }
    /**
     * @param {?} classNames
     * @return {?}
     */
    setClassNames(classNames) {
        classNames = classNames.filter((value, index, self) => self.indexOf(value) === index);
        classNames.forEach(className => this.addClassName(className));
        this.classNames
            .filter(className => classNames.indexOf(className) < 0)
            .forEach(className => this.removeClassName(className));
        this.classNames = classNames;
    }
    /**
     * @param {?} className
     * @return {?}
     */
    addClassName(className) {
        this.renderer.addClass(this.elementRef.nativeElement, className);
    }
    /**
     * @param {?} className
     * @return {?}
     */
    removeClassName(className) {
        this.renderer.removeClass(this.elementRef.nativeElement, className);
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class LayoutDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     */
    constructor(elementRef, renderer, service) {
        super(elementRef, renderer);
        this.service = service;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set layout(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set layoutLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            classNames.push(this.service.addLayout(this.fcValues[breakpoint], breakpoint));
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @param {?} breakpoints
     * @param {?=} defaultValue
     * @return {?}
     */
    addNewBreakpoints(breakpoints, defaultValue) {
        breakpoints.forEach(breakpoint => {
            if (!this.fcValues[breakpoint]) {
                this.fcValues[breakpoint] = defaultValue;
            }
        });
        this.reload();
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
LayoutDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcLayout],
    [fcLayout.xs], [fcLayout.sm], [fcLayout.md], [fcLayout.lg], [fcLayout.xl],
    [fcLayout.lt-sm], [fcLayout.lt-md], [fcLayout.lt-lg], [fcLayout.lt-xl],
    [fcLayout.gt-xs], [fcLayout.gt-sm], [fcLayout.gt-md], [fcLayout.gt-lg]
  `,
            },] },
];
/** @nocollapse */
LayoutDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService }
];
LayoutDirective.propDecorators = {
    layout: [{ type: Input, args: ['fcLayout',] }],
    layoutXs: [{ type: Input, args: ['fcLayout.xs',] }],
    layoutSm: [{ type: Input, args: ['fcLayout.sm',] }],
    layoutMd: [{ type: Input, args: ['fcLayout.md',] }],
    layoutLg: [{ type: Input, args: ['fcLayout.lg',] }],
    layoutXl: [{ type: Input, args: ['fcLayout.xl',] }],
    layoutGtXs: [{ type: Input, args: ['fcLayout.gt-xs',] }],
    layoutGtSm: [{ type: Input, args: ['fcLayout.gt-sm',] }],
    layoutGtMd: [{ type: Input, args: ['fcLayout.gt-md',] }],
    layoutGtLg: [{ type: Input, args: ['fcLayout.gt-lg',] }],
    layoutLtSm: [{ type: Input, args: ['fcLayout.lt-sm',] }],
    layoutLtMd: [{ type: Input, args: ['fcLayout.lt-md',] }],
    layoutLtLg: [{ type: Input, args: ['fcLayout.lt-lg',] }],
    layoutLtXl: [{ type: Input, args: ['fcLayout.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class LayoutAlignDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.layout = layout;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set align(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            Object.keys(this.layoutValues).forEach(layoutBreakpoint => {
                classNames.push(this.service.addLayoutAlign(this.layoutValues[layoutBreakpoint], layoutBreakpoint, this.fcValues[breakpoint], breakpoint));
            });
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints, 'row');
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.addClassName(this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get layoutValues() {
        return this.layout ? this.layout.fcValues : { 'all': '' };
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
LayoutAlignDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcLayoutAlign],
    [fcLayoutAlign.xs], [fcLayoutAlign.sm], [fcLayoutAlign.md], [fcLayoutAlign.lg],[fcLayoutAlign.xl],
    [fcLayoutAlign.lt-sm], [fcLayoutAlign.lt-md], [fcLayoutAlign.lt-lg], [fcLayoutAlign.lt-xl],
    [fcLayoutAlign.gt-xs], [fcLayoutAlign.gt-sm], [fcLayoutAlign.gt-md], [fcLayoutAlign.gt-lg]
  `,
            },] },
];
/** @nocollapse */
LayoutAlignDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Self }] }
];
LayoutAlignDirective.propDecorators = {
    align: [{ type: Input, args: ['fcLayoutAlign',] }],
    alignXs: [{ type: Input, args: ['fcLayoutAlign.xs',] }],
    alignSm: [{ type: Input, args: ['fcLayoutAlign.sm',] }],
    alignMd: [{ type: Input, args: ['fcLayoutAlign.md',] }],
    alignLg: [{ type: Input, args: ['fcLayoutAlign.lg',] }],
    alignXl: [{ type: Input, args: ['fcLayoutAlign.xl',] }],
    alignGtXs: [{ type: Input, args: ['fcLayoutAlign.gt-xs',] }],
    alignGtSm: [{ type: Input, args: ['fcLayoutAlign.gt-sm',] }],
    alignGtMd: [{ type: Input, args: ['fcLayoutAlign.gt-md',] }],
    alignGtLg: [{ type: Input, args: ['fcLayoutAlign.gt-lg',] }],
    alignLtSm: [{ type: Input, args: ['fcLayoutAlign.lt-sm',] }],
    alignLtMd: [{ type: Input, args: ['fcLayoutAlign.lt-md',] }],
    alignLtLg: [{ type: Input, args: ['fcLayoutAlign.lt-lg',] }],
    alignLtXl: [{ type: Input, args: ['fcLayoutAlign.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class LayoutGapDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.layout = layout;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set gap(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set gapLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            Object.keys(this.layoutValues).forEach(layoutBreakpoint => {
                classNames.push(this.service.addLayoutGap(this.layoutValues[layoutBreakpoint], layoutBreakpoint, this.fcValues[breakpoint], breakpoint));
            });
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints);
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.addClassName(this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get layoutValues() {
        return this.layout ? this.layout.fcValues : { 'all': '' };
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
LayoutGapDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcLayoutGap],
    [fcLayoutGap.xs], [fcLayoutGap.sm], [fcLayoutGap.md], [fcLayoutGap.lg], [fcLayoutGap.xl],
    [fcLayoutGap.lt-sm], [fcLayoutGap.lt-md], [fcLayoutGap.lt-lg], [fcLayoutGap.lt-xl],
    [fcLayoutGap.gt-xs], [fcLayoutGap.gt-sm], [fcLayoutGap.gt-md], [fcLayoutGap.gt-lg]
  `,
            },] },
];
/** @nocollapse */
LayoutGapDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Self }] }
];
LayoutGapDirective.propDecorators = {
    gap: [{ type: Input, args: ['fcLayoutGap',] }],
    gapXs: [{ type: Input, args: ['fcLayoutGap.xs',] }],
    gapSm: [{ type: Input, args: ['fcLayoutGap.sm',] }],
    gapMd: [{ type: Input, args: ['fcLayoutGap.md',] }],
    gapLg: [{ type: Input, args: ['fcLayoutGap.lg',] }],
    gapXl: [{ type: Input, args: ['fcLayoutGap.xl',] }],
    gapGtXs: [{ type: Input, args: ['fcLayoutGap.gt-xs',] }],
    gapGtSm: [{ type: Input, args: ['fcLayoutGap.gt-sm',] }],
    gapGtMd: [{ type: Input, args: ['fcLayoutGap.gt-md',] }],
    gapGtLg: [{ type: Input, args: ['fcLayoutGap.gt-lg',] }],
    gapLtSm: [{ type: Input, args: ['fcLayoutGap.lt-sm',] }],
    gapLtMd: [{ type: Input, args: ['fcLayoutGap.lt-md',] }],
    gapLtLg: [{ type: Input, args: ['fcLayoutGap.lt-lg',] }],
    gapLtXl: [{ type: Input, args: ['fcLayoutGap.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlexDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
        this.fcShrink = 1;
        this.fcGrow = 1;
        if (layout && layout.elementRef.nativeElement === this.parentElement) {
            this.layout = layout;
        }
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set flex(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set flexLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnParentLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            Object.keys(this.layoutValues).forEach(layoutBreakpoint => {
                classNames.push(this.service.addFlex(this.layoutValues[layoutBreakpoint], layoutBreakpoint, this.fcValues[breakpoint], breakpoint, this.fcGrow, this.fcShrink));
            });
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnParentLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints, 'row');
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.renderer.addClass(this.parentElement, this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get layoutValues() {
        return this.layout ? this.layout.fcValues : { 'all': '' };
    }
    /**
     * @return {?}
     */
    get parentElement() {
        return this.renderer.parentNode(this.elementRef.nativeElement);
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
FlexDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcFlex],
    [fcFlex.xs], [fcFlex.sm], [fcFlex.md], [fcFlex.lg], [fcFlex.xl],
    [fcFlex.lt-sm], [fcFlex.lt-md], [fcFlex.lt-lg], [fcFlex.lt-xl],
    [fcFlex.gt-xs], [fcFlex.gt-sm], [fcFlex.gt-md], [fcFlex.gt-lg],
  `,
            },] },
];
/** @nocollapse */
FlexDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }
];
FlexDirective.propDecorators = {
    fcShrink: [{ type: Input }],
    fcGrow: [{ type: Input }],
    flex: [{ type: Input, args: ['fcFlex',] }],
    flexXs: [{ type: Input, args: ['fcFlex.xs',] }],
    flexSm: [{ type: Input, args: ['fcFlex.sm',] }],
    flexMd: [{ type: Input, args: ['fcFlex.md',] }],
    flexLg: [{ type: Input, args: ['fcFlex.lg',] }],
    flexXl: [{ type: Input, args: ['fcFlex.xl',] }],
    flexGtXs: [{ type: Input, args: ['fcFlex.gt-xs',] }],
    flexGtSm: [{ type: Input, args: ['fcFlex.gt-sm',] }],
    flexGtMd: [{ type: Input, args: ['fcFlex.gt-md',] }],
    flexGtLg: [{ type: Input, args: ['fcFlex.gt-lg',] }],
    flexLtSm: [{ type: Input, args: ['fcFlex.lt-sm',] }],
    flexLtMd: [{ type: Input, args: ['fcFlex.lt-md',] }],
    flexLtLg: [{ type: Input, args: ['fcFlex.lt-lg',] }],
    flexLtXl: [{ type: Input, args: ['fcFlex.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlexAlignDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
        if (layout && layout.elementRef.nativeElement === this.parentElement) {
            this.layout = layout;
        }
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set align(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set alignLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnParentLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            classNames.push(this.service.addFlexAlign(this.fcValues[breakpoint], breakpoint));
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnParentLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints, 'row');
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.renderer.addClass(this.parentElement, this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get parentElement() {
        return this.renderer.parentNode(this.elementRef.nativeElement);
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
FlexAlignDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcFlexAlign],
    [fcFlexAlign.xs], [fcFlexAlign.sm], [fcFlexAlign.md], [fcFlexAlign.lg], [fcFlexAlign.xl],
    [fcFlexAlign.lt-sm], [fcFlexAlign.lt-md], [fcFlexAlign.lt-lg], [fcFlexAlign.lt-xl],
    [fcFlexAlign.gt-xs], [fcFlexAlign.gt-sm], [fcFlexAlign.gt-md], [fcFlexAlign.gt-lg]
  `,
            },] },
];
/** @nocollapse */
FlexAlignDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Host }] }
];
FlexAlignDirective.propDecorators = {
    align: [{ type: Input, args: ['fcFlexAlign',] }],
    alignXs: [{ type: Input, args: ['fcFlexAlign.xs',] }],
    alignSm: [{ type: Input, args: ['fcFlexAlign.sm',] }],
    alignMd: [{ type: Input, args: ['fcFlexAlign.md',] }],
    alignLg: [{ type: Input, args: ['fcFlexAlign.lg',] }],
    alignXl: [{ type: Input, args: ['fcFlexAlign.xl',] }],
    alignGtXs: [{ type: Input, args: ['fcFlexAlign.gt-xs',] }],
    alignGtSm: [{ type: Input, args: ['fcFlexAlign.gt-sm',] }],
    alignGtMd: [{ type: Input, args: ['fcFlexAlign.gt-md',] }],
    alignGtLg: [{ type: Input, args: ['fcFlexAlign.gt-lg',] }],
    alignLtSm: [{ type: Input, args: ['fcFlexAlign.lt-sm',] }],
    alignLtMd: [{ type: Input, args: ['fcFlexAlign.lt-md',] }],
    alignLtLg: [{ type: Input, args: ['fcFlexAlign.lt-lg',] }],
    alignLtXl: [{ type: Input, args: ['fcFlexAlign.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlexOrderDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
        if (layout && layout.elementRef.nativeElement === this.parentElement) {
            this.layout = layout;
        }
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set order(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set orderLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnParentLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            classNames.push(this.service.addFlexOrder(this.fcValues[breakpoint], breakpoint));
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnParentLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints, 'row');
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.renderer.addClass(this.parentElement, this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get parentElement() {
        return this.renderer.parentNode(this.elementRef.nativeElement);
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
FlexOrderDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcFlexOrder],
    [fcFlexOrder.xs], [fcFlexOrder.sm], [fcFlexOrder.md], [fcFlexOrder.lg], [fcFlexOrder.xl],
    [fcFlexOrder.lt-sm], [fcFlexOrder.lt-md], [fcFlexOrder.lt-lg], [fcFlexOrder.lt-xl],
    [fcFlexOrder.gt-xs], [fcFlexOrder.gt-sm], [fcFlexOrder.gt-md], [fcFlexOrder.gt-lg]
  `,
            },] },
];
/** @nocollapse */
FlexOrderDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }
];
FlexOrderDirective.propDecorators = {
    order: [{ type: Input, args: ['fcFlexOrder',] }],
    orderXs: [{ type: Input, args: ['fcFlexOrder.xs',] }],
    orderSm: [{ type: Input, args: ['fcFlexOrder.sm',] }],
    orderMd: [{ type: Input, args: ['fcFlexOrder.md',] }],
    orderLg: [{ type: Input, args: ['fcFlexOrder.lg',] }],
    orderXl: [{ type: Input, args: ['fcFlexOrder.xl',] }],
    orderGtXs: [{ type: Input, args: ['fcFlexOrder.gt-xs',] }],
    orderGtSm: [{ type: Input, args: ['fcFlexOrder.gt-sm',] }],
    orderGtMd: [{ type: Input, args: ['fcFlexOrder.gt-md',] }],
    orderGtLg: [{ type: Input, args: ['fcFlexOrder.gt-lg',] }],
    orderLtSm: [{ type: Input, args: ['fcFlexOrder.lt-sm',] }],
    orderLtMd: [{ type: Input, args: ['fcFlexOrder.lt-md',] }],
    orderLtLg: [{ type: Input, args: ['fcFlexOrder.lt-lg',] }],
    orderLtXl: [{ type: Input, args: ['fcFlexOrder.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlexOffsetDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
        if (layout && layout.elementRef.nativeElement === this.parentElement) {
            this.layout = layout;
        }
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set offset(val) { this.fcValues['all'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetXs(val) { this.fcValues['xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetSm(val) { this.fcValues['sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetMd(val) { this.fcValues['md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetLg(val) { this.fcValues['lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetXl(val) { this.fcValues['xl'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetGtXs(val) { this.fcValues['gt-xs'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetGtSm(val) { this.fcValues['gt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetGtMd(val) { this.fcValues['gt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetGtLg(val) { this.fcValues['gt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetLtSm(val) { this.fcValues['lt-sm'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetLtMd(val) { this.fcValues['lt-md'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetLtLg(val) { this.fcValues['lt-lg'] = val; }
    /**
     * @param {?} val
     * @return {?}
     */
    set offsetLtXl(val) { this.fcValues['lt-xl'] = val; }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnParentLayout();
    }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        this.breakpoints.forEach(breakpoint => {
            Object.keys(this.layoutValues).forEach(layoutBreakpoint => {
                classNames.push(this.service.addFlexOffset(this.layoutValues[layoutBreakpoint], layoutBreakpoint, this.fcValues[breakpoint], breakpoint));
            });
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    dependsOnParentLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(this.breakpoints, 'row');
        }
        else {
            this.breakpoints.forEach(breakpoint => {
                this.renderer.addClass(this.parentElement, this.service.addLayout('row', breakpoint));
            });
        }
    }
    /**
     * @return {?}
     */
    get parentElement() {
        return this.renderer.parentNode(this.elementRef.nativeElement);
    }
    /**
     * @return {?}
     */
    get layoutValues() {
        return this.layout ? this.layout.fcValues : { 'all': '' };
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
FlexOffsetDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcFlexOffset],
    [fcFlexOffset.xs], [fcFlexOffset.sm], [fcFlexOffset.md], [fcFlexOffset.lg], [fcFlexOffset.xl],
    [fcFlexOffset.lt-sm], [fcFlexOffset.lt-md], [fcFlexOffset.lt-lg], [fcFlexOffset.lt-xl],
    [fcFlexOffset.gt-xs], [fcFlexOffset.gt-sm], [fcFlexOffset.gt-md], [fcFlexOffset.gt-lg]
  `,
            },] },
];
/** @nocollapse */
FlexOffsetDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }
];
FlexOffsetDirective.propDecorators = {
    offset: [{ type: Input, args: ['fcFlexOffset',] }],
    offsetXs: [{ type: Input, args: ['fcFlexOffset.xs',] }],
    offsetSm: [{ type: Input, args: ['fcFlexOffset.sm',] }],
    offsetMd: [{ type: Input, args: ['fcFlexOffset.md',] }],
    offsetLg: [{ type: Input, args: ['fcFlexOffset.lg',] }],
    offsetXl: [{ type: Input, args: ['fcFlexOffset.xl',] }],
    offsetGtXs: [{ type: Input, args: ['fcFlexOffset.gt-xs',] }],
    offsetGtSm: [{ type: Input, args: ['fcFlexOffset.gt-sm',] }],
    offsetGtMd: [{ type: Input, args: ['fcFlexOffset.gt-md',] }],
    offsetGtLg: [{ type: Input, args: ['fcFlexOffset.gt-lg',] }],
    offsetLtSm: [{ type: Input, args: ['fcFlexOffset.lt-sm',] }],
    offsetLtMd: [{ type: Input, args: ['fcFlexOffset.lt-md',] }],
    offsetLtLg: [{ type: Input, args: ['fcFlexOffset.lt-lg',] }],
    offsetLtXl: [{ type: Input, args: ['fcFlexOffset.lt-xl',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
class FlexFillDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     */
    constructor(elementRef, renderer, service, layout) {
        super(elementRef, renderer);
        this.service = service;
        if (layout && layout.elementRef.nativeElement === this.parentElement) {
            this.layout = layout;
        }
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dependsOnParentLayout();
        this.service.addFlexFill();
    }
    /**
     * @return {?}
     */
    dependsOnParentLayout() {
        if (this.layout) {
            this.layout.addNewBreakpoints(['all'], 'row');
        }
        else {
            this.renderer.addClass(this.parentElement, this.service.addLayout('row', 'all'));
        }
    }
    /**
     * @return {?}
     */
    get parentElement() {
        return this.renderer.parentNode(this.elementRef.nativeElement);
    }
}
FlexFillDirective.decorators = [
    { type: Directive, args: [{
                selector: `
    [fcFill],
    [fcFlexFill]
  `,
            },] },
];
/** @nocollapse */
FlexFillDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Host }] }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
const /** @type {?} */ TRULY = ['true', true, 1];
/**
 * @param {?} value
 * @return {?}
 */
function isTrueValue(value) {
    return value === '' || TRULY.indexOf(value) >= 0;
}
class ShowHideDirective extends BaseDirective {
    /**
     * @param {?} elementRef
     * @param {?} renderer
     * @param {?} service
     * @param {?} layout
     * @param {?} platformId
     */
    constructor(elementRef, renderer, service, layout, platformId) {
        super(elementRef, renderer);
        this.service = service;
        this.layout = layout;
        this.platformId = platformId;
        this.fcValues = {};
        this.observer$ = new ReplaySubject(1);
    }
    /**
     * @param {?} val
     * @return {?}
     */
    set show(val) { this.fcValues['all'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showXs(val) { this.fcValues['xs'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showSm(val) { this.fcValues['sm'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showMd(val) { this.fcValues['md'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showLg(val) { this.fcValues['lg'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showXl(val) { this.fcValues['xl'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showLtSm(val) { this.fcValues['lt-sm'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showLtMd(val) { this.fcValues['lt-md'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showLtLg(val) { this.fcValues['lt-lg'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showLtXl(val) { this.fcValues['lt-xl'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showGtXs(val) { this.fcValues['gt-xs'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showGtSm(val) { this.fcValues['gt-sm'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showGtMd(val) { this.fcValues['gt-md'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set showGtLg(val) { this.fcValues['gt-lg'] = isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hide(val) { this.fcValues['all'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideXs(val) { this.fcValues['xs'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideSm(val) { this.fcValues['sm'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideMd(val) { this.fcValues['md'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideLg(val) { this.fcValues['lg'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideXl(val) { this.fcValues['xl'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideLtSm(val) { this.fcValues['lt-sm'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideLtMd(val) { this.fcValues['lt-md'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideLtLg(val) { this.fcValues['lt-lg'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideLtXl(val) { this.fcValues['lt-xl'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideGtXs(val) { this.fcValues['gt-xs'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideGtSm(val) { this.fcValues['gt-sm'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideGtMd(val) { this.fcValues['gt-md'] = !isTrueValue(val); }
    /**
     * @param {?} val
     * @return {?}
     */
    set hideGtLg(val) { this.fcValues['gt-lg'] = !isTrueValue(val); }
    /**
     * @return {?}
     */
    ngOnChanges() {
        this.reload();
    }
    /**
     * @return {?}
     */
    reload() {
        const /** @type {?} */ classNames = [];
        const /** @type {?} */ display = this.getDisplayStyle();
        this.breakpoints.forEach(breakpoint => {
            classNames.push(this.service.addShowHide(display, this.fcValues[breakpoint], breakpoint));
        });
        this.setClassNames(classNames);
        this.observer$.next(this.fcValues);
    }
    /**
     * @return {?}
     */
    getDisplayStyle() {
        return this.layout ? 'flex' : (this.getElementStyle(this.elementRef.nativeElement, 'display')
            || this.fcDisplayDefault
            || 'block');
    }
    /**
     * @param {?} element
     * @param {?} styleName
     * @return {?}
     */
    getElementStyle(element, styleName) {
        return (element ? element.style[styleName] || element.style.getPropertyValue(styleName) : '')
            || (isPlatformBrowser(this.platformId) ? getComputedStyle(element).getPropertyValue(styleName) : '');
    }
    /**
     * @return {?}
     */
    get breakpoints() {
        return Object.keys(this.fcValues);
    }
}
ShowHideDirective.decorators = [
    { type: Directive, args: [{
                selector: `
  [fcShow],
  [fcShow.xs], [fcShow.sm], [fcShow.md], [fcShow.lg], [fcShow.xl],
  [fcShow.lt-sm], [fcShow.lt-md], [fcShow.lt-lg], [fcShow.lt-xl],
  [fcShow.gt-xs], [fcShow.gt-sm], [fcShow.gt-md], [fcShow.gt-lg],
  [fcHide],
  [fcHide.xs], [fcHide.sm], [fcHide.md], [fcHide.lg], [fcHide.xl],
  [fcHide.lt-sm], [fcHide.lt-md], [fcHide.lt-lg], [fcHide.lt-xl],
  [fcHide.gt-xs], [fcHide.gt-sm], [fcHide.gt-md], [fcHide.gt-lg]
  `,
            },] },
];
/** @nocollapse */
ShowHideDirective.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 },
    { type: FlexCssService },
    { type: LayoutDirective, decorators: [{ type: Optional }, { type: Self }] },
    { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
];
ShowHideDirective.propDecorators = {
    fcDisplayDefault: [{ type: Input }],
    show: [{ type: Input, args: ['fcShow',] }],
    showXs: [{ type: Input, args: ['fcShow.xs',] }],
    showSm: [{ type: Input, args: ['fcShow.sm',] }],
    showMd: [{ type: Input, args: ['fcShow.md',] }],
    showLg: [{ type: Input, args: ['fcShow.lg',] }],
    showXl: [{ type: Input, args: ['fcShow.xl',] }],
    showLtSm: [{ type: Input, args: ['fcShow.lt-sm',] }],
    showLtMd: [{ type: Input, args: ['fcShow.lt-md',] }],
    showLtLg: [{ type: Input, args: ['fcShow.lt-lg',] }],
    showLtXl: [{ type: Input, args: ['fcShow.lt-xl',] }],
    showGtXs: [{ type: Input, args: ['fcShow.gt-xs',] }],
    showGtSm: [{ type: Input, args: ['fcShow.gt-sm',] }],
    showGtMd: [{ type: Input, args: ['fcShow.gt-md',] }],
    showGtLg: [{ type: Input, args: ['fcShow.gt-lg',] }],
    hide: [{ type: Input, args: ['fcHide',] }],
    hideXs: [{ type: Input, args: ['fcHide.xs',] }],
    hideSm: [{ type: Input, args: ['fcHide.sm',] }],
    hideMd: [{ type: Input, args: ['fcHide.md',] }],
    hideLg: [{ type: Input, args: ['fcHide.lg',] }],
    hideXl: [{ type: Input, args: ['fcHide.xl',] }],
    hideLtSm: [{ type: Input, args: ['fcHide.lt-sm',] }],
    hideLtMd: [{ type: Input, args: ['fcHide.lt-md',] }],
    hideLtLg: [{ type: Input, args: ['fcHide.lt-lg',] }],
    hideLtXl: [{ type: Input, args: ['fcHide.lt-xl',] }],
    hideGtXs: [{ type: Input, args: ['fcHide.gt-xs',] }],
    hideGtSm: [{ type: Input, args: ['fcHide.gt-sm',] }],
    hideGtMd: [{ type: Input, args: ['fcHide.gt-md',] }],
    hideGtLg: [{ type: Input, args: ['fcHide.gt-lg',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */
/**
 * @param {?} breakpoints
 * @return {?}
 */
function customizeBreakPoints(breakpoints) {
    if (typeof breakpoints === 'function') {
        breakpoints = breakpoints(FLEX_CSS_DEFAULT_BREAKPOINTS);
    }
    return breakpoints || FLEX_CSS_DEFAULT_BREAKPOINTS;
}
class FlexCssModule {
    /**
     * @param {?=} breakpoints
     * @return {?}
     */
    static forRoot(breakpoints) {
        return {
            ngModule: FlexCssModule,
            providers: [
                FlexCssService,
                {
                    provide: 'flex_css_module_breakpoints',
                    useValue: breakpoints,
                },
                {
                    provide: FLEX_CSS_BREAKPOINTS,
                    useFactory: customizeBreakPoints,
                    deps: ['flex_css_module_breakpoints']
                },
            ],
        };
    }
}
FlexCssModule.decorators = [
    { type: NgModule, args: [{
                declarations: [
                    LayoutDirective,
                    LayoutAlignDirective,
                    LayoutGapDirective,
                    FlexDirective,
                    FlexOrderDirective,
                    FlexOffsetDirective,
                    FlexAlignDirective,
                    FlexFillDirective,
                    ShowHideDirective,
                ],
                exports: [
                    LayoutDirective,
                    LayoutAlignDirective,
                    LayoutGapDirective,
                    FlexDirective,
                    FlexOrderDirective,
                    FlexOffsetDirective,
                    FlexAlignDirective,
                    FlexFillDirective,
                    ShowHideDirective,
                ],
            },] },
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes} checked by tsc
 */

export { LayoutDirective, LayoutAlignDirective, LayoutGapDirective, FlexDirective, FlexAlignDirective, FlexOrderDirective, FlexOffsetDirective, FlexFillDirective, customizeBreakPoints, FlexCssModule, BaseDirective as ɵa, FLEX_CSS_BREAKPOINTS as ɵb, FlexCssService as ɵc, ShowHideDirective as ɵd };

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JlZy1tZC1uZy1mbGV4LWNzcy1sYXlvdXQuanMubWFwIiwic291cmNlcyI6WyJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvYXV0by1wcmVmaXhlci50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9sYXlvdXQtdmFsaWRhdG9yLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2hlbHBlcnMudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvYmFzaXMtdmFsaWRhdG9yLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2ZsZXgtY3NzLnNlcnZpY2UudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvZGlyZWN0aXZlLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2xheW91dC5kaXJlY3RpdmUudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvbGF5b3V0LWFsaWduLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9sYXlvdXQtZ2FwLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LWFsaWduLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LW9yZGVyLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LW9mZnNldC5kaXJlY3RpdmUudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvZmxleC1maWxsLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9zaG93LWhpZGUuZGlyZWN0aXZlLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2ZsZXgtY3NzLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBBcHBsaWVzIENTUyBwcmVmaXhlcyB0byBhcHByb3ByaWF0ZSBzdHlsZSBrZXlzLlxuICpcbiAqIE5vdGU6IGAtbXMtYCwgYC1tb3pgIGFuZCBgLXdlYmtpdC1ib3hgIGFyZSBubyBsb25nZXIgc3VwcG9ydGVkLiBlLmcuXG4gKiAgICB7XG4gKiAgICAgIGRpc3BsYXk6IC13ZWJraXQtZmxleDsgICAgIE5FVyAtIFNhZmFyaSA2LjErLiBpT1MgNy4xKywgQkIxMFxuICogICAgICBkaXNwbGF5OiBmbGV4OyAgICAgICAgICAgICBORVcsIFNwZWMgLSBGaXJlZm94LCBDaHJvbWUsIE9wZXJhXG4gKiAgICAgIC8vIGRpc3BsYXk6IC13ZWJraXQtYm94OyAgIE9MRCAtIGlPUyA2LSwgU2FmYXJpIDMuMS02LCBCQjdcbiAqICAgICAgLy8gZGlzcGxheTogLW1zLWZsZXhib3g7ICAgVFdFRU5FUiAtIElFIDEwXG4gKiAgICAgIC8vIGRpc3BsYXk6IC1tb3otZmxleGJveDsgIE9MRCAtIEZpcmVmb3hcbiAqICAgIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5Q3NzUHJlZml4ZXModGFyZ2V0KSB7XG4gIE9iamVjdC5rZXlzKHRhcmdldCkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGxldCB2YWx1ZSA9IHRhcmdldFtrZXldIHx8ICcnO1xuXG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgJ2Rpc3BsYXknOlxuICAgICAgICBpZiAodmFsdWUgPT09ICdmbGV4Jykge1xuICAgICAgICAgIHRhcmdldFsnZGlzcGxheSddID0gW1xuICAgICAgICAgICAgJy13ZWJraXQtZmxleCcsXG4gICAgICAgICAgICAnZmxleCdcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnaW5saW5lLWZsZXgnKSB7XG4gICAgICAgICAgdGFyZ2V0WydkaXNwbGF5J10gPSBbXG4gICAgICAgICAgICAnLXdlYmtpdC1pbmxpbmUtZmxleCcsXG4gICAgICAgICAgICAnaW5saW5lLWZsZXgnXG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0YXJnZXRbJ2Rpc3BsYXknXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdhbGlnbi1pdGVtcyc6XG4gICAgICBjYXNlICdhbGlnbi1zZWxmJzpcbiAgICAgIGNhc2UgJ2FsaWduLWNvbnRlbnQnOlxuICAgICAgY2FzZSAnZmxleCc6XG4gICAgICBjYXNlICdmbGV4LWJhc2lzJzpcbiAgICAgIGNhc2UgJ2ZsZXgtZmxvdyc6XG4gICAgICBjYXNlICdmbGV4LWdyb3cnOlxuICAgICAgY2FzZSAnZmxleC1zaHJpbmsnOlxuICAgICAgY2FzZSAnZmxleC13cmFwJzpcbiAgICAgIGNhc2UgJ2p1c3RpZnktY29udGVudCc6XG4gICAgICAgIHRhcmdldFsnLXdlYmtpdC0nICsga2V5XSA9IHZhbHVlO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZmxleC1kaXJlY3Rpb24nOlxuICAgICAgICB2YWx1ZSA9IHZhbHVlIHx8ICdyb3cnO1xuICAgICAgICB0YXJnZXRbJy13ZWJraXQtZmxleC1kaXJlY3Rpb24nXSA9IHZhbHVlO1xuICAgICAgICB0YXJnZXRbJ2ZsZXgtZGlyZWN0aW9uJ10gPSB2YWx1ZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ29yZGVyJzpcbiAgICAgICAgdGFyZ2V0WydvcmRlciddID0gdGFyZ2V0Wyctd2Via2l0LScgKyBrZXldID0gaXNOYU4odmFsdWUpID8gJzAnIDogdmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuZXhwb3J0IGNvbnN0IElOTElORSA9ICdpbmxpbmUnO1xuZXhwb3J0IGNvbnN0IExBWU9VVF9WQUxVRVMgPSBbJ3JvdycsICdjb2x1bW4nLCAncm93LXJldmVyc2UnLCAnY29sdW1uLXJldmVyc2UnXTtcblxuLyoqXG4gKiBWYWxpZGF0ZSB0aGUgZGlyZWN0aW9ufCdkaXJlY3Rpb24gd3JhcCcgdmFsdWUgYW5kIHRoZW4gdXBkYXRlIHRoZSBob3N0J3MgaW5saW5lIGZsZXhib3ggc3R5bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZExheW91dENTUyh2YWx1ZTogc3RyaW5nKSB7XG4gIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUodmFsdWUpO1xuICByZXR1cm4gYnVpbGRDU1MoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgdGhlIHZhbHVlIHRvIGJlIG9uZSBvZiB0aGUgYWNjZXB0YWJsZSB2YWx1ZSBvcHRpb25zXG4gKiBVc2UgZGVmYXVsdCBmYWxsYmFjayBvZiAncm93J1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XG4gIHZhbHVlID0gdmFsdWUgPyB2YWx1ZS50b0xvd2VyQ2FzZSgpIDogJyc7XG4gIGxldCBbZGlyZWN0aW9uLCB3cmFwLCBpbmxpbmVdID0gdmFsdWUuc3BsaXQoJyAnKTtcblxuICAvLyBGaXJzdCB2YWx1ZSBtdXN0IGJlIHRoZSBgZmxleC1kaXJlY3Rpb25gXG4gIGlmICghTEFZT1VUX1ZBTFVFUy5maW5kKHggPT4geCA9PT0gZGlyZWN0aW9uKSkge1xuICAgIGRpcmVjdGlvbiA9IExBWU9VVF9WQUxVRVNbMF07XG4gIH1cblxuICBpZiAod3JhcCA9PT0gSU5MSU5FKSB7XG4gICAgd3JhcCA9IChpbmxpbmUgIT09IElOTElORSkgPyBpbmxpbmUgOiAnJztcbiAgICBpbmxpbmUgPSBJTkxJTkU7XG4gIH1cblxuICByZXR1cm4gW2RpcmVjdGlvbiwgdmFsaWRhdGVXcmFwVmFsdWUod3JhcCksICEhaW5saW5lXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdGhlIHZhbGlkYXRlZCwgZmxleC1kaXJlY3Rpb24gdmFsdWUgc3BlY2lmaWVzXG4gKiBhIGhvcml6b250YWwvcm93IGZsb3cuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Zsb3dIb3Jpem9udGFsKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgW2Zsb3csIF0gPSB2YWxpZGF0ZVZhbHVlKHZhbHVlKTtcbiAgcmV0dXJuIGZsb3cuaW5kZXhPZigncm93JykgPiAtMTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGxheW91dC13cmFwPSc8dmFsdWU+JyB0byBleHBlY3RlZCBmbGV4LXdyYXAgc3R5bGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlV3JhcFZhbHVlKHZhbHVlKSB7XG4gIGlmICghIXZhbHVlKSB7XG4gICAgc3dpdGNoICh2YWx1ZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICdyZXZlcnNlJzpcbiAgICAgIGNhc2UgJ3dyYXAtcmV2ZXJzZSc6XG4gICAgICBjYXNlICdyZXZlcnNlLXdyYXAnOlxuICAgICAgICB2YWx1ZSA9ICd3cmFwLXJldmVyc2UnO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbm8nOlxuICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICBjYXNlICdub3dyYXAnOlxuICAgICAgICB2YWx1ZSA9ICdub3dyYXAnO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gQWxsIG90aGVyIHZhbHVlcyBmYWxsYmFjayB0byAnd3JhcCdcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhbHVlID0gJ3dyYXAnO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBDU1MgdGhhdCBzaG91bGQgYmUgYXNzaWduZWQgdG8gdGhlIGVsZW1lbnQgaW5zdGFuY2VcbiAqIEJVRzpcbiAqICAgMSkgbWluLWhlaWdodCBvbiBhIGNvbHVtbiBmbGV4IGNvbnRhaW5lciB3b27DosKAwpl0IGFwcGx5IHRvIGl0cyBmbGV4IGl0ZW0gY2hpbGRyZW4gaW4gSUUgMTAtMTEuXG4gKiAgICAgIFVzZSBoZWlnaHQgaW5zdGVhZCBpZiBwb3NzaWJsZTsgaGVpZ2h0IDogPHh4eD52aDtcbiAqXG4gKiAgVGhpcyB3YXkgYW55IHBhZGRpbmcgb3IgYm9yZGVyIHNwZWNpZmllZCBvbiB0aGUgY2hpbGQgZWxlbWVudHMgYXJlXG4gKiAgbGFpZCBvdXQgYW5kIGRyYXduIGluc2lkZSB0aGF0IGVsZW1lbnQncyBzcGVjaWZpZWQgd2lkdGggYW5kIGhlaWdodC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ1NTKGRpcmVjdGlvbiwgd3JhcCA9IG51bGwsIGlubGluZSA9IGZhbHNlKSB7XG4gIHJldHVybiB7XG4gICAgJ2Rpc3BsYXknOiBpbmxpbmUgPyAnaW5saW5lLWZsZXgnIDogJ2ZsZXgnLFxuICAgICdib3gtc2l6aW5nJzogJ2JvcmRlci1ib3gnLFxuICAgICdmbGV4LWRpcmVjdGlvbic6IGRpcmVjdGlvbixcbiAgICAnZmxleC13cmFwJzogISF3cmFwID8gd3JhcCA6IG51bGxcbiAgfTtcbn1cbiIsImV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVMYXlvdXRBbGlnblZhbHVlKGFsaWduOiBzdHJpbmcpIHtcbiAgYWxpZ24gPSBhbGlnbiB8fCAnc3RhcnQgc3RyZXRjaCc7XG5cbiAgbGV0IFttYWluQXhpcywgY3Jvc3NBeGlzXSA9IGFsaWduLnNwbGl0KCcgJyk7XG5cbiAgc3dpdGNoIChtYWluQXhpcykge1xuICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgY2FzZSAnc3BhY2UtYXJvdW5kJzpcbiAgICBjYXNlICdzcGFjZS1iZXR3ZWVuJzpcbiAgICBjYXNlICdzcGFjZS1ldmVubHknOlxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZW5kJzpcbiAgICBjYXNlICdmbGV4LWVuZCc6XG4gICAgICBtYWluQXhpcyA9ICdmbGV4LWVuZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdzdGFydCc6XG4gICAgY2FzZSAnZmxleC1zdGFydCc6XG4gICAgZGVmYXVsdCA6XG4gICAgICBtYWluQXhpcyA9ICdmbGV4LXN0YXJ0JzsgIC8vIGRlZmF1bHQgbWFpbiBheGlzXG4gICAgICBicmVhaztcbiAgfVxuXG4gIHN3aXRjaCAoY3Jvc3NBeGlzKSB7XG4gICAgY2FzZSAnc3RhcnQnOlxuICAgIGNhc2UgJ2ZsZXgtc3RhcnQnOlxuICAgICAgY3Jvc3NBeGlzID0gJ2ZsZXgtc3RhcnQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZWxpbmUnOlxuICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICBjcm9zc0F4aXMgPSAnY2VudGVyJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2VuZCc6XG4gICAgY2FzZSAnZmxleC1lbmQnOlxuICAgICAgY3Jvc3NBeGlzID0gJ2ZsZXgtZW5kJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3N0cmV0Y2gnOlxuICAgIGRlZmF1bHQgOiAvLyAnc3RyZXRjaCdcbiAgICAgIGNyb3NzQXhpcyA9ICdzdHJldGNoJzsgICAvLyBkZWZhdWx0IGNyb3NzIGF4aXNcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIFttYWluQXhpcywgY3Jvc3NBeGlzXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbjogc3RyaW5nLCB3cmFwOiBzdHJpbmcsIGlzSW5saW5lOiBib29sZWFuLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgcmV0dXJuICdmY0xheW91dCdcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgZGlyZWN0aW9uICsgKHdyYXAgPyAnLScgKyB3cmFwIDogJycpICsgKGlzSW5saW5lID8gJy1pbmxpbmUnIDogJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVMYXlvdXRBbGlnbkNsYXNzTmFtZShtYWluQXhpczogc3RyaW5nLCBjcm9zc0F4aXM6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNMYXlvdXRBbGlnbidcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgbWFpbkF4aXMgKyAnLScgKyBjcm9zc0F4aXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUxheW91dEdhcENsYXNzTmFtZSh2YWx1ZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgcmV0dXJuICdmY0xheW91dEdhcCdcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgdmFsdWVUb0NsYXNzTmFtZSh2YWx1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUZsZXhDbGFzc05hbWUoZ3Jvdywgc2hyaW5rLCBiYXNpcywgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNGbGV4J1xuICAgICsgKGJyZWFrcG9pbnQgIT09ICdhbGwnID8gJy0tJyArIGJyZWFrcG9pbnQgOiAnJylcbiAgICArICctLScgKyB2YWx1ZVRvQ2xhc3NOYW1lKGdyb3cpICsgJy0nICsgdmFsdWVUb0NsYXNzTmFtZShzaHJpbmspICsgKGJhc2lzID8gJy0nICsgdmFsdWVUb0NsYXNzTmFtZShiYXNpcykgOiAnJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUZsZXhPcmRlckNsYXNzTmFtZShvcmRlciwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNGbGV4T3JkZXInXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIHZhbHVlVG9DbGFzc05hbWUob3JkZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVGbGV4T2Zmc2V0Q2xhc3NOYW1lKG9mZnNldCwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNGbGV4T2Zmc2V0J1xuICAgICsgKGJyZWFrcG9pbnQgIT09ICdhbGwnID8gJy0tJyArIGJyZWFrcG9pbnQgOiAnJylcbiAgICArICctLScgKyB2YWx1ZVRvQ2xhc3NOYW1lKG9mZnNldCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUZsZXhBbGlnbkNsYXNzTmFtZShhbGlnbiwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNGbGV4QWxpZ24nXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIHZhbHVlVG9DbGFzc05hbWUoYWxpZ24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVGbGV4RmlsbENsYXNzTmFtZSgpIHtcbiAgcmV0dXJuICdmY0ZsZXhGaWxsJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlRmxleFNob3dIaWRlQ2xhc3NOYW1lKGRpc3BsYXksIHNob3c6IGJvb2xlYW4sIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjU2hvdydcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgdmFsdWVUb0NsYXNzTmFtZShkaXNwbGF5KVxuICAgICsgJy0tJyArIChzaG93ID8gJ3Nob3cnIDogJ2hpZGUnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbHVlVG9DbGFzc05hbWUodmFsdWUpIHtcbiAgcmV0dXJuIFN0cmluZyh2YWx1ZSkucmVwbGFjZSgvW15hLXpBLVowLTktXS8sICctJyk7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBUaGUgZmxleCBBUEkgcGVybWl0cyAzIG9yIDEgcGFydHMgb2YgdGhlIHZhbHVlOlxuICogICAgLSBgZmxleC1ncm93IGZsZXgtc2hyaW5rIGZsZXgtYmFzaXNgLCBvclxuICogICAgLSBgZmxleC1iYXNpc2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQmFzaXMoYmFzaXM6IHN0cmluZywgZ3JvdyA9ICcxJywgc2hyaW5rID0gJzEnKTogc3RyaW5nW118bnVtYmVyW10ge1xuICBsZXQgcGFydHMgPSBbZ3Jvdywgc2hyaW5rLCBiYXNpc107XG5cbiAgY29uc3QgaiA9IGJhc2lzLmluZGV4T2YoJ2NhbGMnKTtcbiAgaWYgKGogPiAwKSB7XG4gICAgcGFydHNbMl0gPSBfdmFsaWRhdGVDYWxjVmFsdWUoYmFzaXMuc3Vic3RyaW5nKGopLnRyaW0oKSk7XG4gICAgY29uc3QgbWF0Y2hlcyA9IGJhc2lzLnN1YnN0cigwLCBqKS50cmltKCkuc3BsaXQoJyAnKTtcbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHBhcnRzWzBdID0gbWF0Y2hlc1swXTtcbiAgICAgIHBhcnRzWzFdID0gbWF0Y2hlc1sxXTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaiA9PT0gMCkge1xuICAgIHBhcnRzWzJdID0gX3ZhbGlkYXRlQ2FsY1ZhbHVlKGJhc2lzLnRyaW0oKSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IGJhc2lzLnNwbGl0KCcgJyk7XG4gICAgcGFydHMgPSAobWF0Y2hlcy5sZW5ndGggPT09IDMpID8gbWF0Y2hlcyA6IFtcbiAgICAgIGdyb3csIHNocmluaywgYmFzaXNcbiAgICBdO1xuICB9XG5cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG5cbi8qKlxuICogQ2FsYyBleHByZXNzaW9ucyByZXF1aXJlIHdoaXRlc3BhY2UgYmVmb3JlICYgYWZ0ZXIgYW55IGV4cHJlc3Npb24gb3BlcmF0b3JzXG4gKiBUaGlzIGlzIGEgc2ltcGxlLCBjcnVkZSB3aGl0ZXNwYWNlIHBhZGRpbmcgc29sdXRpb24uXG4gKiAgIC0gJzMgMyBjYWxjKDE1ZW0gKyAyMHB4KSdcbiAqICAgLSBjYWxjKDEwMCUgLyA3ICogMilcbiAqICAgLSAnY2FsYygxNWVtICsgMjBweCknXG4gKiAgIC0gJ2NhbGMoMTVlbSsyMHB4KSdcbiAqICAgLSAnMzdweCdcbiAqICAgPSAnNDMlJ1xuICovXG5mdW5jdGlvbiBfdmFsaWRhdGVDYWxjVmFsdWUoY2FsYzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGNhbGMucmVwbGFjZSgvW1xcc10vZywgJycpLnJlcGxhY2UoL1tcXC9cXCpcXCtcXC1dL2csICcgJCYgJyk7XG59XG4iLCJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QsIEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGFwcGx5Q3NzUHJlZml4ZXMgfSBmcm9tICcuL2F1dG8tcHJlZml4ZXInO1xuaW1wb3J0IHsgdmFsaWRhdGVWYWx1ZSwgYnVpbGRDU1MsIGlzRmxvd0hvcml6b250YWwgfSBmcm9tICcuL2xheW91dC12YWxpZGF0b3InO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUsIG5vcm1hbGl6ZUxheW91dEFsaWduVmFsdWUsIGdlbmVyYXRlTGF5b3V0QWxpZ25DbGFzc05hbWUsXG4gIGdlbmVyYXRlTGF5b3V0R2FwQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhDbGFzc05hbWUsIGdlbmVyYXRlRmxleE9yZGVyQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhPZmZzZXRDbGFzc05hbWUsXG4gIGdlbmVyYXRlRmxleEFsaWduQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhGaWxsQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhTaG93SGlkZUNsYXNzTmFtZVxufSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHsgdmFsaWRhdGVCYXNpcyB9IGZyb20gJy4vYmFzaXMtdmFsaWRhdG9yJztcblxuZXhwb3J0IGludGVyZmFjZSBCcmVha3BvaW50IHtcbiAgYWxpYXM6IHN0cmluZztcbiAgbWVkaWE6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfREVGQVVMVF9CUkVBS1BPSU5UUzogQnJlYWtwb2ludFtdID0gW1xuICB7IGFsaWFzOiAnZ3QteHMnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogNjAwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2x0LXhsJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3Qtc20nLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2x0LWxnJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDEyNzlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTI4MHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC1tZCcsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA5NTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC1zbScsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuICB7IGFsaWFzOiAneGwnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KScsICcobWF4LXdpZHRoOiA1MDAwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2xnJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDEyODBweCknLCAnKG1heC13aWR0aDogMTkxOXB4KSddIH0sXG4gIHsgYWxpYXM6ICdtZCcsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA5NjBweCknLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdzbScsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA2MDBweCknLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ3hzJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDU5OXB4KSddIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfQlJFQUtQT0lOVFNfU01BTExfVE9fTEFSR0U6IEJyZWFrcG9pbnRbXSA9IFtcbiAgeyBhbGlhczogJ2x0LXNtJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDU5OXB4KSddIH0sXG4gIHsgYWxpYXM6ICd4cycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QteHMnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogNjAwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ3NtJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDYwMHB4KScsICcobWF4LXdpZHRoOiA5NTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3Qtc20nLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdtZCcsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA5NjBweCknLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdndC1tZCcsIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxMjgwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQteGwnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogMTkxOXB4KSddIH0sXG4gIHsgYWxpYXM6ICdsZycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxMjgwcHgpJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KSddIH0sXG5cbiAgeyBhbGlhczogJ3hsJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDE5MjBweCknLCAnKG1heC13aWR0aDogNTAwMHB4KSddIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfQlJFQUtQT0lOVFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPignZmxleF9jc3NfYnJlYWtwb2ludHMnKTtcblxuZXhwb3J0IHR5cGUgU3R5bGVEZWZpbml0aW9uID0gc3RyaW5nIHwgeyBbcHJvcGVydHk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IG51bGwgfTtcblxuZXhwb3J0IGNsYXNzIEZsZXhDc3NTdHlsZUVsZW1lbnQge1xuICBwdWJsaWMgc3RvcmFnZTogeyBbcHJvcGVydHk6IHN0cmluZ106IHsgW3Byb3BlcnR5OiBzdHJpbmddOiBUZXh0IH0gfSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBzdHlsZTogSFRNTFN0eWxlRWxlbWVudCxcbiAgKSB7fVxufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRmxleENzc1NlcnZpY2Uge1xuICBwcml2YXRlIGxheW91dDogRmxleENzc1N0eWxlRWxlbWVudDtcblxuICBwcml2YXRlIGZsZXg6IEZsZXhDc3NTdHlsZUVsZW1lbnQ7XG5cbiAgcHJpdmF0ZSBmaWxsOiBGbGV4Q3NzU3R5bGVFbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jLFxuICAgIEBJbmplY3QoRkxFWF9DU1NfQlJFQUtQT0lOVFMpIHByaXZhdGUgYnJlYWtwb2ludHMsXG4gICkge1xuICAgIHRoaXMuaW5pdExheW91dCgpO1xuICAgIHRoaXMuaW5pdEZsZXgoKTtcbiAgICB0aGlzLmluaXRGaWxsKCk7XG4gIH1cblxuICBpbml0TGF5b3V0KCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgIHN0eWxlLmlkID0gJ2ZjLWxheW91dCc7XG5cbiAgICB0aGlzLmRvYy5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAgIHRoaXMubGF5b3V0ID0gbmV3IEZsZXhDc3NTdHlsZUVsZW1lbnQoc3R5bGUpO1xuICB9XG5cbiAgaW5pdEZsZXgoKSB7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmRvYy5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXG4gICAgc3R5bGUuaWQgPSAnZmMtZmxleCc7XG5cbiAgICB0aGlzLmRvYy5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAgIHRoaXMuZmxleCA9IG5ldyBGbGV4Q3NzU3R5bGVFbGVtZW50KHN0eWxlKTtcbiAgfVxuXG4gIGluaXRGaWxsKCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgIHN0eWxlLmlkID0gJ2ZjLWZpbGwnO1xuXG4gICAgdGhpcy5kb2MuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICB0aGlzLmZpbGwgPSBuZXcgRmxleENzc1N0eWxlRWxlbWVudChzdHlsZSk7XG4gIH1cblxuICBhZGRMYXlvdXQobGF5b3V0OiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUsIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IGJ1aWxkQ1NTKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUpO1xuXG4gICAgICB0aGlzLmFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkTGF5b3V0QWxpZ24obGF5b3V0OiBzdHJpbmcsIGxheW91dEJyZWFrcG9pbnQ6IHN0cmluZywgYWxpZ246IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBbbWFpbkF4aXMsIGNyb3NzQXhpc10gPSBub3JtYWxpemVMYXlvdXRBbGlnblZhbHVlKGFsaWduKTtcblxuICAgIGNvbnN0IGxheW91dEFsaWduQ2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRBbGlnbkNsYXNzTmFtZShtYWluQXhpcywgY3Jvc3NBeGlzLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkxheW91dFN0b3JhZ2UobGF5b3V0QWxpZ25DbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgJ2p1c3RpZnktY29udGVudCc6IG1haW5BeGlzLFxuICAgICAgfTtcblxuICAgICAgc3dpdGNoIChjcm9zc0F4aXMpIHtcbiAgICAgICAgY2FzZSAnYmFzZWxpbmUnOlxuICAgICAgICAgIHN0eWxlWydhbGlnbi1pdGVtcyddID0gY3Jvc3NBeGlzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHN0eWxlWydhbGlnbi1pdGVtcyddID0gc3R5bGVbJ2FsaWduLWNvbnRlbnQnXSA9IGNyb3NzQXhpcztcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZGRUb0xheW91dFN0b3JhZ2UobGF5b3V0QWxpZ25DbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICBpZiAoY3Jvc3NBeGlzID09PSAnc3RyZXRjaCcpIHtcbiAgICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGxheW91dEFsaWduQ2xhc3NOYW1lICsgJy4nICsgbGF5b3V0Q2xhc3NOYW1lO1xuXG4gICAgICBpZiAoIXRoaXMuaGFzSW5MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBpc0Zsb3dIb3Jpem9udGFsKGxheW91dCkgPyB7ICdtYXgtaGVpZ2h0JzogJzEwMCUnIH0gOiB7ICdtYXgtd2lkdGgnOiAnMTAwJScgfTtcblxuICAgICAgICB0aGlzLmFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsYXlvdXRBbGlnbkNsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZExheW91dEdhcChsYXlvdXQ6IHN0cmluZywgbGF5b3V0QnJlYWtwb2ludDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHZhbHVlID0gdmFsdWUgfHwgJzAnO1xuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBsYXlvdXRHYXBDbGFzc05hbWUgPSBnZW5lcmF0ZUxheW91dEdhcENsYXNzTmFtZSh2YWx1ZSwgYnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBsYXlvdXRHYXBDbGFzc05hbWUgKyAnLicgKyBsYXlvdXRDbGFzc05hbWUgKyAnID4gKjpub3QoOmxhc3QtY2hpbGQpJztcblxuICAgIGlmICghdGhpcy5oYXNJbkxheW91dFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSBpc0Zsb3dIb3Jpem9udGFsKGxheW91dCkgPyB7ICdtYXJnaW4tcmlnaHQnOiB2YWx1ZSB9IDogeyAnbWFyZ2luLWJvdHRvbSc6IHZhbHVlIH07XG5cbiAgICAgIHRoaXMuYWRkVG9MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIFtsYXlvdXRCcmVha3BvaW50XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxheW91dEdhcENsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXgobGF5b3V0OiBzdHJpbmcsIGxheW91dEJyZWFrcG9pbnQ6IHN0cmluZywgdmFsdWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nLCBncm93Pywgc2hyaW5rPykge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgnOycsICcnKTtcblxuICAgIGxldCBbdGhlR3JvdywgdGhlU2hyaW5rLCB0aGVCYXNpc10gPSB2YWxpZGF0ZUJhc2lzKHZhbHVlLCBncm93LCBzaHJpbmspO1xuXG4gICAgdGhlR3JvdyA9ICh0aGVHcm93ID09PSAnMCcpID8gMCA6IHRoZUdyb3c7XG4gICAgdGhlU2hyaW5rID0gKHRoZVNocmluayA9PT0gJzAnKSA/IDAgOiB0aGVTaHJpbms7XG5cbiAgICAvLyBmbGV4LWJhc2lzIGFsbG93cyB5b3UgdG8gc3BlY2lmeSB0aGUgaW5pdGlhbC9zdGFydGluZyBtYWluLWF4aXMgc2l6ZSBvZiB0aGUgZWxlbWVudCxcbiAgICAvLyBiZWZvcmUgYW55dGhpbmcgZWxzZSBpcyBjb21wdXRlZC4gSXQgY2FuIGVpdGhlciBiZSBhIHBlcmNlbnRhZ2Ugb3IgYW4gYWJzb2x1dGUgdmFsdWUuXG4gICAgLy8gSXQgaXMsIGhvd2V2ZXIsIG5vdCB0aGUgYnJlYWtpbmcgcG9pbnQgZm9yIGZsZXgtZ3Jvdy9zaHJpbmsgcHJvcGVydGllc1xuICAgIC8vXG4gICAgLy8gZmxleC1ncm93IGNhbiBiZSBzZWVuIGFzIHRoaXM6XG4gICAgLy8gICAwOiBEbyBub3Qgc3RyZXRjaC4gRWl0aGVyIHNpemUgdG8gZWxlbWVudCdzIGNvbnRlbnQgd2lkdGgsIG9yIG9iZXkgJ2ZsZXgtYmFzaXMnLlxuICAgIC8vICAgMTogKERlZmF1bHQgdmFsdWUpLiBTdHJldGNoOyB3aWxsIGJlIHRoZSBzYW1lIHNpemUgdG8gYWxsIG90aGVyIGZsZXggaXRlbXMgb25cbiAgICAvLyAgICAgICB0aGUgc2FtZSByb3cgc2luY2UgdGhleSBoYXZlIGEgZGVmYXVsdCB2YWx1ZSBvZiAxLlxuICAgIC8vICAgw6LCicKlMiAoaW50ZWdlciBuKTogU3RyZXRjaC4gV2lsbCBiZSBuIHRpbWVzIHRoZSBzaXplIG9mIG90aGVyIGVsZW1lbnRzXG4gICAgLy8gICAgICB3aXRoICdmbGV4LWdyb3c6IDEnIG9uIHRoZSBzYW1lIHJvdy5cblxuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgJ2JveC1zaXppbmcnOiAnYm9yZGVyLWJveCcsXG4gICAgfTtcblxuICAgIHN3aXRjaCAodGhlQmFzaXMgfHwgJycpIHtcbiAgICAgIGNhc2UgJyc6XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgJHt0aGVHcm93fSAke3RoZVNocmlua30gMC4wMDAwMDAwMDFweGA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5pdGlhbCc6ICAgLy8gZGVmYXVsdFxuICAgICAgY2FzZSAnbm9ncm93JzpcbiAgICAgICAgdGhlR3JvdyA9IDA7XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgMCAxIGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2dyb3cnOlxuICAgICAgICBzdHlsZVsnZmxleCddID0gYDEgMSAxMDAlYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdub3Nocmluayc6XG4gICAgICAgIHRoZVNocmluayA9IDA7XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgMSAwIGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2F1dG8nOlxuICAgICAgICBzdHlsZVsnZmxleCddID0gYCR7dGhlR3Jvd30gJHt0aGVTaHJpbmt9IGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICB0aGVHcm93ID0gMDtcbiAgICAgICAgdGhlU2hyaW5rID0gMDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgnXSA9IGAwIDAgYXV0b2A7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc3QgaXNDYWxjID0gU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdjYWxjJykgPiAtMTtcbiAgICAgICAgY29uc3QgaXNQZXJjZW50ID0gIWlzQ2FsYyAmJiBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJyUnKSA+IC0xO1xuXG4gICAgICAgIGNvbnN0IGlzVmFsdWUgPSBpc0NhbGMgfHwgaXNQZXJjZW50IHx8XG4gICAgICAgICAgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdweCcpID4gLTEgfHxcbiAgICAgICAgICBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ2VtJykgPiAtMSB8fFxuICAgICAgICAgIFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZigndncnKSA+IC0xIHx8XG4gICAgICAgICAgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCd2aCcpID4gLTE7XG5cbiAgICAgICAgLy8gRGVmYXVsdHMgdG8gcGVyY2VudGFnZSBzaXppbmcgdW5sZXNzIGBweGAgaXMgZXhwbGljaXRseSBzZXRcbiAgICAgICAgaWYgKCFpc1ZhbHVlICYmICFpc1BlcmNlbnQgJiYgIWlzTmFOKHRoZUJhc2lzIGFzIGFueSkpIHtcbiAgICAgICAgICB0aGVCYXNpcyA9IHRoZUJhc2lzICsgJyUnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoZUJhc2lzID09PSAnMHB4Jykge1xuICAgICAgICAgIHRoZUJhc2lzID0gJzAlJztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0eWxlWydmbGV4LWdyb3cnXSA9IGAke3RoZUdyb3d9YDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgtc2hyaW5rJ10gPSBgJHt0aGVTaHJpbmt9YDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgtYmFzaXMnXSA9IHN0eWxlWydtaW4td2lkdGgnXSA9IHN0eWxlWydtYXgtd2lkdGgnXSA9IGlzVmFsdWUgPyBgJHt0aGVCYXNpc31gIDogJzEwMCUnO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBmbGV4Q2xhc3NOYW1lID0gZ2VuZXJhdGVGbGV4Q2xhc3NOYW1lKHRoZUdyb3csIHRoZVNocmluaywgdGhlQmFzaXMsIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmxleFN0b3JhZ2UoZmxleENsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShmbGV4Q2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBmbGV4Q2xhc3NOYW1lICsgJy4nICsgbGF5b3V0Q2xhc3NOYW1lO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmxleFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3QgbWF4ID0gaXNGbG93SG9yaXpvbnRhbChkaXJlY3Rpb24pID8gJ21heC13aWR0aCcgOiAnbWF4LWhlaWdodCc7XG4gICAgICBjb25zdCBtaW4gPSBpc0Zsb3dIb3Jpem9udGFsKGRpcmVjdGlvbikgPyAnbWluLXdpZHRoJyA6ICdtaW4taGVpZ2h0JztcblxuICAgICAgY29uc3QgdXNpbmdDYWxjID0gKFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZignY2FsYycpID4gLTEpIHx8ICh0aGVCYXNpcyA9PT0gJ2F1dG8nKTtcbiAgICAgIGNvbnN0IGlzUHggPSBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ3B4JykgPiAtMSB8fCB1c2luZ0NhbGM7XG5cbiAgICAgIC8vIG1ha2UgYm94IGluZmxleGlibGUgd2hlbiBzaHJpbmsgYW5kIGdyb3cgYXJlIGJvdGggemVyb1xuICAgICAgLy8gc2hvdWxkIG5vdCBzZXQgYSBtaW4gd2hlbiB0aGUgZ3JvdyBpcyB6ZXJvXG4gICAgICAvLyBzaG91bGQgbm90IHNldCBhIG1heCB3aGVuIHRoZSBzaHJpbmsgaXMgemVyb1xuICAgICAgY29uc3QgaXNGaXhlZCA9ICF0aGVHcm93ICYmICF0aGVTaHJpbms7XG5cbiAgICAgIGNvbnN0IGxheW91dFN0eWxlID0ge307XG5cbiAgICAgIGxheW91dFN0eWxlW21pbl0gPSAodGhlQmFzaXMgPT09ICcwJScpID8gMCA6IGlzRml4ZWQgfHwgKGlzUHggJiYgdGhlR3JvdykgPyB0aGVCYXNpcyA6IG51bGw7XG4gICAgICBsYXlvdXRTdHlsZVttYXhdID0gKHRoZUJhc2lzID09PSAnMCUnKSA/IDAgOiBpc0ZpeGVkIHx8ICghdXNpbmdDYWxjICYmIHRoZVNocmluaykgPyB0aGVCYXNpcyA6IG51bGw7XG5cbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWUsIGxheW91dFN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgIH1cblxuICAgIHJldHVybiBmbGV4Q2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkRmxleE9yZGVyKG9yZGVyLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgICBvcmRlciA9IHBhcnNlSW50KG9yZGVyLCAxMCk7XG5cbiAgICBvcmRlciA9IGlzTmFOKG9yZGVyKSA/IDAgOiBvcmRlcjtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleE9yZGVyQ2xhc3NOYW1lKG9yZGVyLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0geydvcmRlcic6IG9yZGVyfTtcblxuICAgICAgdGhpcy5hZGRUb0ZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxuICBhZGRGbGV4T2Zmc2V0KGxheW91dDogc3RyaW5nLCBsYXlvdXRCcmVha3BvaW50OiBzdHJpbmcsIG9mZnNldCwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gICAgY29uc3QgaXNQZXJjZW50ID0gU3RyaW5nKG9mZnNldCkuaW5kZXhPZignJScpID4gLTE7XG4gICAgY29uc3QgaXNQeCA9IFN0cmluZyhvZmZzZXQpLmluZGV4T2YoJ3B4JykgPiAtMTtcblxuICAgIGlmICghaXNQeCAmJiAhaXNQZXJjZW50ICYmICFpc05hTihvZmZzZXQpKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgKyAnJSc7XG4gICAgfVxuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3Qgb2Zmc2V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVGbGV4T2Zmc2V0Q2xhc3NOYW1lKG9mZnNldCwgYnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBsYXlvdXRDbGFzc05hbWUgPSBnZW5lcmF0ZUxheW91dENsYXNzTmFtZShkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lLCBsYXlvdXRCcmVha3BvaW50KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IG9mZnNldENsYXNzTmFtZSArICcuJyArIGxheW91dENsYXNzTmFtZTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0gaXNGbG93SG9yaXpvbnRhbChkaXJlY3Rpb24pID8geydtYXJnaW4tbGVmdCc6IGAke29mZnNldH1gfSA6IHsnbWFyZ2luLXRvcCc6IGAke29mZnNldH1gfTtcblxuICAgICAgdGhpcy5hZGRUb0ZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIFtsYXlvdXRCcmVha3BvaW50XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldENsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXhBbGlnbihhbGlnbiwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gICAgYWxpZ24gPSBhbGlnbiB8fCAnc3RyZXRjaCc7XG5cbiAgICAvLyBDcm9zcy1heGlzXG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSAnc3RhcnQnOlxuICAgICAgICBhbGlnbiA9ICdmbGV4LXN0YXJ0JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdlbmQnOlxuICAgICAgICBhbGlnbiA9ICdmbGV4LWVuZCc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleEFsaWduQ2xhc3NOYW1lKGFsaWduLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0geydhbGlnbi1zZWxmJzogYWxpZ259O1xuXG4gICAgICB0aGlzLmFkZFRvRmxleFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXhGaWxsKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleEZpbGxDbGFzc05hbWUoKTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZpbGxTdG9yYWdlKGNsYXNzTmFtZSwgJ2FsbCcpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgJ21hcmdpbic6IDAsXG4gICAgICAgICd3aWR0aCc6ICcxMDAlJyxcbiAgICAgICAgJ2hlaWdodCc6ICcxMDAlJyxcbiAgICAgICAgJ21pbi13aWR0aCc6ICcxMDAlJyxcbiAgICAgICAgJ21pbi1oZWlnaHQnOiAnMTAwJScsXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmFkZFRvRmlsbFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgJ2FsbCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxuICBhZGRTaG93SGlkZShkaXNwbGF5OiBzdHJpbmcsIHNob3c6IGJvb2xlYW4sIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleFNob3dIaWRlQ2xhc3NOYW1lKGRpc3BsYXksIHNob3csIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmlsbFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgICdkaXNwbGF5Jzogc2hvdyA/IGRpc3BsYXkgfHwgJ2Jsb2NrJyA6ICdub25lJyxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuYWRkVG9GaWxsU3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNJbkxheW91dFN0b3JhZ2UoY2xhc3NOYW1lOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc0luU3RvcmFnZSh0aGlzLmxheW91dCwgY2xhc3NOYW1lLCBicmVha3BvaW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUb1N0b3JhZ2UodGhpcy5sYXlvdXQsIGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIGN1c3RvbUJyZWFrcG9pbnRzKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzSW5GbGV4U3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzSW5TdG9yYWdlKHRoaXMuZmxleCwgY2xhc3NOYW1lLCBicmVha3BvaW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgc3R5bGU6IFN0eWxlRGVmaW5pdGlvbiwgYnJlYWtwb2ludDogc3RyaW5nLCBjdXN0b21CcmVha3BvaW50cz86IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkVG9TdG9yYWdlKHRoaXMuZmxleCwgY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCwgY3VzdG9tQnJlYWtwb2ludHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNJbkZpbGxTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5oYXNJblN0b3JhZ2UodGhpcy5maWxsLCBjbGFzc05hbWUsIGJyZWFrcG9pbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRUb0ZpbGxTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUb1N0b3JhZ2UodGhpcy5maWxsLCBjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBjdXN0b21CcmVha3BvaW50cyk7XG4gIH1cblxuICBwcml2YXRlIGhhc0luU3RvcmFnZShzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEoc3R5bGVFbGVtZW50LnN0b3JhZ2VbYnJlYWtwb2ludF0gJiYgc3R5bGVFbGVtZW50LnN0b3JhZ2VbYnJlYWtwb2ludF1bY2xhc3NOYW1lXSk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRvU3RvcmFnZShcbiAgICBzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICBjdXN0b21CcmVha3BvaW50cyA9IGN1c3RvbUJyZWFrcG9pbnRzIHx8IFtdO1xuXG4gICAgY29uc3Qgc3R5bGVzID0gYXBwbHlDc3NQcmVmaXhlcyhzdHlsZSk7XG5cbiAgICBjb25zdCBjc3MgPSB0aGlzLmdlbmVyYXRlQ3NzKHN0eWxlcyk7XG5cbiAgICBpZiAoY3NzICE9PSAnJykge1xuICAgICAgY29uc3QgY2xhc3NDc3MgPSAnLicgKyBjbGFzc05hbWUgKyAnIHsgJyArIGNzcyArICcgfSc7XG5cbiAgICAgIGNvbnN0IGNzc0VsZW1lbnQgPSB0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh0aGlzLmFkZEJyZWFrcG9pbnRzKFticmVha3BvaW50XS5jb25jYXQoY3VzdG9tQnJlYWtwb2ludHMpLCBjbGFzc0NzcykpO1xuXG4gICAgICBpZiAoIXN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdKSB7XG4gICAgICAgIHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdID0ge307XG4gICAgICB9XG5cbiAgICAgIHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdW2NsYXNzTmFtZV0gPSBjc3NFbGVtZW50O1xuXG4gICAgICB0aGlzLnJlb3JkZXJUZXh0RWxlbWVudHMoc3R5bGVFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlb3JkZXJUZXh0RWxlbWVudHMoc3R5bGVFbGVtZW50OiBGbGV4Q3NzU3R5bGVFbGVtZW50KSB7XG4gICAgbGV0IHBvc2l0aW9uID0gdGhpcy5yZW9yZGVyQnJlYWtwb2ludEVsZW1lbnRzKHN0eWxlRWxlbWVudCwgJ2FsbCcpO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgcG9zaXRpb24gPSB0aGlzLnJlb3JkZXJCcmVha3BvaW50RWxlbWVudHMoc3R5bGVFbGVtZW50LCBicmVha3BvaW50LmFsaWFzLCBwb3NpdGlvbik7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVvcmRlckJyZWFrcG9pbnRFbGVtZW50cyhzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGJyZWFrcG9pbnQ6IHN0cmluZywgcG9zaXRpb246IG51bWJlciA9IDApIHtcbiAgICBjb25zdCBicmVha3BvaW50RWxlbWVudHMgPSBzdHlsZUVsZW1lbnQuc3RvcmFnZVticmVha3BvaW50XTtcblxuICAgIGlmICghYnJlYWtwb2ludEVsZW1lbnRzKSB7XG4gICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoYnJlYWtwb2ludEVsZW1lbnRzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICBzdHlsZUVsZW1lbnQuc3R5bGUuaW5zZXJ0QmVmb3JlKGJyZWFrcG9pbnRFbGVtZW50c1trZXldLCBzdHlsZUVsZW1lbnQuc3R5bGUuY2hpbGRyZW5bcG9zaXRpb25dKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0eWxlRWxlbWVudC5zdHlsZS5hcHBlbmRDaGlsZChicmVha3BvaW50RWxlbWVudHNba2V5XSk7XG4gICAgICB9XG5cbiAgICAgICsrcG9zaXRpb247XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcG9zaXRpb247XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlQ3NzKHN0eWxlczogT2JqZWN0KSB7XG4gICAgY29uc3QgY3NzID0gW107XG5cbiAgICBPYmplY3Qua2V5cyhzdHlsZXMpLnNvcnQoKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBBcnJheS5pc0FycmF5KHN0eWxlc1trZXldKSA/IHN0eWxlc1trZXldIDogW3N0eWxlc1trZXldXTtcblxuICAgICAgdmFsdWVzLnNvcnQoKTtcblxuICAgICAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgY3NzLnB1c2goa2V5ICsgJzogJyArIHZhbHVlICsgJzsnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3NzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQnJlYWtwb2ludHMoYnJlYWtwb2ludHNBbGlhc2VzOiBzdHJpbmdbXSwgY3NzOiBzdHJpbmcpIHtcbiAgICBicmVha3BvaW50c0FsaWFzZXMgPSBicmVha3BvaW50c0FsaWFzZXMuZmlsdGVyKGJyZWFrcG9pbnQgPT4gYnJlYWtwb2ludCAhPT0gJ2FsbCcpO1xuXG4gICAgaWYgKCFicmVha3BvaW50c0FsaWFzZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gY3NzO1xuICAgIH1cblxuICAgIGxldCB0aGVCcmVha3BvaW50cyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50c1xuICAgICAgLmZpbHRlcihicmVha3BvaW50ID0+IGJyZWFrcG9pbnRzQWxpYXNlcy5pbmRleE9mKGJyZWFrcG9pbnQuYWxpYXMpID49IDApXG4gICAgICAuZm9yRWFjaChicmVha3BvaW50ID0+IHRoZUJyZWFrcG9pbnRzID0gdGhlQnJlYWtwb2ludHMuY29uY2F0KGJyZWFrcG9pbnQubWVkaWEpKTtcblxuICAgIHRoZUJyZWFrcG9pbnRzID0gdGhlQnJlYWtwb2ludHMuZmlsdGVyKCh2YWx1ZSwgaW5kZXgsIHNlbGYpID0+IHNlbGYuaW5kZXhPZih2YWx1ZSkgPT09IGluZGV4KTtcblxuICAgIHJldHVybiAnQG1lZGlhICcgKyB0aGVCcmVha3BvaW50cy5qb2luKCcgYW5kICcpICsgJyB7ICcgKyBjc3MgKyAnIH0nO1xuICB9XG59XG4iLCJpbXBvcnQgeyBFbGVtZW50UmVmLCBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VEaXJlY3RpdmUge1xuICBwcml2YXRlIGNsYXNzTmFtZXM6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJvdGVjdGVkIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICkge1xuICB9XG5cbiAgc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzOiBzdHJpbmdbXSkge1xuICAgIGNsYXNzTmFtZXMgPSBjbGFzc05hbWVzLmZpbHRlcigodmFsdWUsIGluZGV4LCBzZWxmKSA9PiBzZWxmLmluZGV4T2YodmFsdWUpID09PSBpbmRleCk7XG5cbiAgICBjbGFzc05hbWVzLmZvckVhY2goY2xhc3NOYW1lID0+IHRoaXMuYWRkQ2xhc3NOYW1lKGNsYXNzTmFtZSkpO1xuXG4gICAgdGhpcy5jbGFzc05hbWVzXG4gICAgICAuZmlsdGVyKGNsYXNzTmFtZSA9PiBjbGFzc05hbWVzLmluZGV4T2YoY2xhc3NOYW1lKSA8IDApXG4gICAgICAuZm9yRWFjaChjbGFzc05hbWUgPT4gdGhpcy5yZW1vdmVDbGFzc05hbWUoY2xhc3NOYW1lKSk7XG5cbiAgICB0aGlzLmNsYXNzTmFtZXMgPSBjbGFzc05hbWVzO1xuICB9XG5cbiAgYWRkQ2xhc3NOYW1lKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgY2xhc3NOYW1lKTtcbiAgfVxuXG4gIHJlbW92ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIGNsYXNzTmFtZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIFJlbmRlcmVyMiwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogYFxuICAgIFtmY0xheW91dF0sXG4gICAgW2ZjTGF5b3V0LnhzXSwgW2ZjTGF5b3V0LnNtXSwgW2ZjTGF5b3V0Lm1kXSwgW2ZjTGF5b3V0LmxnXSwgW2ZjTGF5b3V0LnhsXSxcbiAgICBbZmNMYXlvdXQubHQtc21dLCBbZmNMYXlvdXQubHQtbWRdLCBbZmNMYXlvdXQubHQtbGddLCBbZmNMYXlvdXQubHQteGxdLFxuICAgIFtmY0xheW91dC5ndC14c10sIFtmY0xheW91dC5ndC1zbV0sIFtmY0xheW91dC5ndC1tZF0sIFtmY0xheW91dC5ndC1sZ11cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgTGF5b3V0RGlyZWN0aXZlIGV4dGVuZHMgQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIHJlYWRvbmx5IGZjVmFsdWVzID0ge307XG5cbiAgcmVhZG9ubHkgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgQElucHV0KCdmY0xheW91dCcpICAgICAgICBzZXQgbGF5b3V0KHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgbGF5b3V0KCkgICAgICAgIHsgcmV0dXJuIHRoaXMuZmNWYWx1ZXNbJ2FsbCddOyB9XG5cbiAgQElucHV0KCdmY0xheW91dC54cycpICAgICBzZXQgbGF5b3V0WHModmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0LnNtJykgICAgIHNldCBsYXlvdXRTbSh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQubWQnKSAgICAgc2V0IGxheW91dE1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5sZycpICAgICBzZXQgbGF5b3V0TGcodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0LnhsJykgICAgIHNldCBsYXlvdXRYbCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0xheW91dC5ndC14cycpICBzZXQgbGF5b3V0R3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0Lmd0LXNtJykgIHNldCBsYXlvdXRHdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQuZ3QtbWQnKSAgc2V0IGxheW91dEd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5ndC1sZycpICBzZXQgbGF5b3V0R3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNMYXlvdXQubHQtc20nKSAgc2V0IGxheW91dEx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5sdC1tZCcpICBzZXQgbGF5b3V0THRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0Lmx0LWxnJykgIHNldCBsYXlvdXRMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQubHQteGwnKSAgc2V0IGxheW91dEx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSB2YWw7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBjbGFzc05hbWVzLnB1c2godGhpcy5zZXJ2aWNlLmFkZExheW91dCh0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgYWRkTmV3QnJlYWtwb2ludHMoYnJlYWtwb2ludHM6IHN0cmluZ1tdLCBkZWZhdWx0VmFsdWU/KSB7XG4gICAgYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIGlmICghdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSkge1xuICAgICAgICB0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdID0gZGVmYXVsdFZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBJbnB1dCwgUmVuZGVyZXIyLCBPcHRpb25hbCwgU2VsZiwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNMYXlvdXRBbGlnbl0sXG4gICAgW2ZjTGF5b3V0QWxpZ24ueHNdLCBbZmNMYXlvdXRBbGlnbi5zbV0sIFtmY0xheW91dEFsaWduLm1kXSwgW2ZjTGF5b3V0QWxpZ24ubGddLFtmY0xheW91dEFsaWduLnhsXSxcbiAgICBbZmNMYXlvdXRBbGlnbi5sdC1zbV0sIFtmY0xheW91dEFsaWduLmx0LW1kXSwgW2ZjTGF5b3V0QWxpZ24ubHQtbGddLCBbZmNMYXlvdXRBbGlnbi5sdC14bF0sXG4gICAgW2ZjTGF5b3V0QWxpZ24uZ3QteHNdLCBbZmNMYXlvdXRBbGlnbi5ndC1zbV0sIFtmY0xheW91dEFsaWduLmd0LW1kXSwgW2ZjTGF5b3V0QWxpZ24uZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIExheW91dEFsaWduRGlyZWN0aXZlIGV4dGVuZHMgQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgZmNWYWx1ZXMgPSB7fTtcblxuICBvYnNlcnZlciQgPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24nKSAgICAgICBzZXQgYWxpZ24odmFsKSAgICAgeyB0aGlzLmZjVmFsdWVzWydhbGwnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24ueHMnKSAgICBzZXQgYWxpZ25Ycyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5zbScpICAgIHNldCBhbGlnblNtKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLm1kJykgICAgc2V0IGFsaWduTWQodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24ubGcnKSAgICBzZXQgYWxpZ25MZyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydsZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi54bCcpICAgIHNldCBhbGlnblhsKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24uZ3QteHMnKSBzZXQgYWxpZ25HdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5ndC1zbScpIHNldCBhbGlnbkd0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmd0LW1kJykgc2V0IGFsaWduR3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24uZ3QtbGcnKSBzZXQgYWxpZ25HdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmx0LXNtJykgc2V0IGFsaWduTHRTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24ubHQtbWQnKSBzZXQgYWxpZ25MdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5sdC1sZycpIHNldCBhbGlnbkx0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LWxnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmx0LXhsJykgc2V0IGFsaWduTHRYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQteGwnXSA9IHZhbDsgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHNlcnZpY2U6IEZsZXhDc3NTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBTZWxmKCkgcHJpdmF0ZSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZSxcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5kZXBlbmRzT25MYXlvdXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICByZWxvYWQoKSB7XG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgT2JqZWN0LmtleXModGhpcy5sYXlvdXRWYWx1ZXMpLmZvckVhY2gobGF5b3V0QnJlYWtwb2ludCA9PiB7XG4gICAgICAgIGNsYXNzTmFtZXMucHVzaChcbiAgICAgICAgICB0aGlzLnNlcnZpY2UuYWRkTGF5b3V0QWxpZ24odGhpcy5sYXlvdXRWYWx1ZXNbbGF5b3V0QnJlYWtwb2ludF0sIGxheW91dEJyZWFrcG9pbnQsIHRoaXMuZmNWYWx1ZXNbYnJlYWtwb2ludF0sIGJyZWFrcG9pbnQpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKTtcblxuICAgIHRoaXMub2JzZXJ2ZXIkLm5leHQodGhpcy5mY1ZhbHVlcyk7XG4gIH1cblxuICBkZXBlbmRzT25MYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyh0aGlzLmJyZWFrcG9pbnRzLCAncm93Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgICAgdGhpcy5hZGRDbGFzc05hbWUodGhpcy5zZXJ2aWNlLmFkZExheW91dCgncm93JywgYnJlYWtwb2ludCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGxheW91dFZhbHVlcygpIHtcbiAgICByZXR1cm4gdGhpcy5sYXlvdXQgPyB0aGlzLmxheW91dC5mY1ZhbHVlcyA6IHsgJ2FsbCc6ICcnIH07XG4gIH1cblxuICBnZXQgYnJlYWtwb2ludHMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZmNWYWx1ZXMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgSW5wdXQsIFJlbmRlcmVyMiwgT3B0aW9uYWwsIFNlbGYsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjTGF5b3V0R2FwXSxcbiAgICBbZmNMYXlvdXRHYXAueHNdLCBbZmNMYXlvdXRHYXAuc21dLCBbZmNMYXlvdXRHYXAubWRdLCBbZmNMYXlvdXRHYXAubGddLCBbZmNMYXlvdXRHYXAueGxdLFxuICAgIFtmY0xheW91dEdhcC5sdC1zbV0sIFtmY0xheW91dEdhcC5sdC1tZF0sIFtmY0xheW91dEdhcC5sdC1sZ10sIFtmY0xheW91dEdhcC5sdC14bF0sXG4gICAgW2ZjTGF5b3V0R2FwLmd0LXhzXSwgW2ZjTGF5b3V0R2FwLmd0LXNtXSwgW2ZjTGF5b3V0R2FwLmd0LW1kXSwgW2ZjTGF5b3V0R2FwLmd0LWxnXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBMYXlvdXRHYXBEaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBmY1ZhbHVlcyA9IHt9O1xuXG4gIG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAnKSAgICAgICBzZXQgZ2FwKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydhbGwnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLnhzJykgICAgc2V0IGdhcFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWyd4cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAuc20nKSAgICBzZXQgZ2FwU20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5tZCcpICAgIHNldCBnYXBNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmxnJykgICAgc2V0IGdhcExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAueGwnKSAgICBzZXQgZ2FwWGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmd0LXhzJykgc2V0IGdhcEd0WHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXhzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5ndC1zbScpIHNldCBnYXBHdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAuZ3QtbWQnKSBzZXQgZ2FwR3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmd0LWxnJykgc2V0IGdhcEd0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LWxnJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmx0LXNtJykgc2V0IGdhcEx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5sdC1tZCcpIHNldCBnYXBMdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAubHQtbGcnKSBzZXQgZ2FwTHRMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmx0LXhsJykgc2V0IGdhcEx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSB2YWw7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGVwZW5kc09uTGF5b3V0KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMubGF5b3V0VmFsdWVzKS5mb3JFYWNoKGxheW91dEJyZWFrcG9pbnQgPT4ge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goXG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLmFkZExheW91dEdhcCh0aGlzLmxheW91dFZhbHVlc1tsYXlvdXRCcmVha3BvaW50XSwgbGF5b3V0QnJlYWtwb2ludCwgdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuXG4gICAgdGhpcy5vYnNlcnZlciQubmV4dCh0aGlzLmZjVmFsdWVzKTtcbiAgfVxuXG4gIGRlcGVuZHNPbkxheW91dCgpIHtcbiAgICBpZiAodGhpcy5sYXlvdXQpIHtcbiAgICAgIHRoaXMubGF5b3V0LmFkZE5ld0JyZWFrcG9pbnRzKHRoaXMuYnJlYWtwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICAgIHRoaXMuYWRkQ2xhc3NOYW1lKHRoaXMuc2VydmljZS5hZGRMYXlvdXQoJ3JvdycsIGJyZWFrcG9pbnQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBsYXlvdXRWYWx1ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5b3V0ID8gdGhpcy5sYXlvdXQuZmNWYWx1ZXMgOiB7ICdhbGwnOiAnJyB9O1xuICB9XG5cbiAgZ2V0IGJyZWFrcG9pbnRzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZjVmFsdWVzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkluaXQsIElucHV0LCBSZW5kZXJlcjIsIE9wdGlvbmFsLCBIb3N0LCBPbkNoYW5nZXMsIFNraXBTZWxmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNGbGV4XSxcbiAgICBbZmNGbGV4LnhzXSwgW2ZjRmxleC5zbV0sIFtmY0ZsZXgubWRdLCBbZmNGbGV4LmxnXSwgW2ZjRmxleC54bF0sXG4gICAgW2ZjRmxleC5sdC1zbV0sIFtmY0ZsZXgubHQtbWRdLCBbZmNGbGV4Lmx0LWxnXSwgW2ZjRmxleC5sdC14bF0sXG4gICAgW2ZjRmxleC5ndC14c10sIFtmY0ZsZXguZ3Qtc21dLCBbZmNGbGV4Lmd0LW1kXSwgW2ZjRmxleC5ndC1sZ10sXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEZsZXhEaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBmY1ZhbHVlcyA9IHt9O1xuXG4gIG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmU7XG5cbiAgQElucHV0KCkgZmNTaHJpbmsgPSAxO1xuICBASW5wdXQoKSBmY0dyb3cgPSAxO1xuXG4gIEBJbnB1dCgnZmNGbGV4JykgICAgICAgc2V0IGZsZXgodmFsKSAgICAgeyB0aGlzLmZjVmFsdWVzWydhbGwnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC54cycpICAgIHNldCBmbGV4WHModmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5zbScpICAgIHNldCBmbGV4U20odmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5tZCcpICAgIHNldCBmbGV4TWQodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5sZycpICAgIHNldCBmbGV4TGcodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC54bCcpICAgIHNldCBmbGV4WGwodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneGwnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNGbGV4Lmd0LXhzJykgc2V0IGZsZXhHdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmd0LXNtJykgc2V0IGZsZXhHdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmd0LW1kJykgc2V0IGZsZXhHdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmd0LWxnJykgc2V0IGZsZXhHdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0ZsZXgubHQtc20nKSBzZXQgZmxleEx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgubHQtbWQnKSBzZXQgZmxleEx0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgubHQtbGcnKSBzZXQgZmxleEx0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LWxnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgubHQteGwnKSBzZXQgZmxleEx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSB2YWw7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIEBTa2lwU2VsZigpIGxheW91dDogTGF5b3V0RGlyZWN0aXZlLFxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCByZW5kZXJlcik7XG5cbiAgICBpZiAobGF5b3V0ICYmIGxheW91dC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgPT09IHRoaXMucGFyZW50RWxlbWVudCkge1xuICAgICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5kZXBlbmRzT25QYXJlbnRMYXlvdXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICByZWxvYWQoKSB7XG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgT2JqZWN0LmtleXModGhpcy5sYXlvdXRWYWx1ZXMpLmZvckVhY2gobGF5b3V0QnJlYWtwb2ludCA9PiB7XG4gICAgICAgIGNsYXNzTmFtZXMucHVzaChcbiAgICAgICAgICB0aGlzLnNlcnZpY2UuYWRkRmxleChcbiAgICAgICAgICAgIHRoaXMubGF5b3V0VmFsdWVzW2xheW91dEJyZWFrcG9pbnRdLCBsYXlvdXRCcmVha3BvaW50LCB0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50LCB0aGlzLmZjR3JvdywgdGhpcy5mY1Nocmlua1xuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuXG4gICAgdGhpcy5vYnNlcnZlciQubmV4dCh0aGlzLmZjVmFsdWVzKTtcbiAgfVxuXG4gIGRlcGVuZHNPblBhcmVudExheW91dCgpIHtcbiAgICBpZiAodGhpcy5sYXlvdXQpIHtcbiAgICAgIHRoaXMubGF5b3V0LmFkZE5ld0JyZWFrcG9pbnRzKHRoaXMuYnJlYWtwb2ludHMsICdyb3cnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMucGFyZW50RWxlbWVudCwgdGhpcy5zZXJ2aWNlLmFkZExheW91dCgncm93JywgYnJlYWtwb2ludCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGxheW91dFZhbHVlcygpIHtcbiAgICByZXR1cm4gdGhpcy5sYXlvdXQgPyB0aGlzLmxheW91dC5mY1ZhbHVlcyA6IHsgJ2FsbCc6ICcnIH07XG4gIH1cblxuICBnZXQgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBJbnB1dCwgUmVuZGVyZXIyLCBPcHRpb25hbCwgSG9zdCwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNGbGV4QWxpZ25dLFxuICAgIFtmY0ZsZXhBbGlnbi54c10sIFtmY0ZsZXhBbGlnbi5zbV0sIFtmY0ZsZXhBbGlnbi5tZF0sIFtmY0ZsZXhBbGlnbi5sZ10sIFtmY0ZsZXhBbGlnbi54bF0sXG4gICAgW2ZjRmxleEFsaWduLmx0LXNtXSwgW2ZjRmxleEFsaWduLmx0LW1kXSwgW2ZjRmxleEFsaWduLmx0LWxnXSwgW2ZjRmxleEFsaWduLmx0LXhsXSxcbiAgICBbZmNGbGV4QWxpZ24uZ3QteHNdLCBbZmNGbGV4QWxpZ24uZ3Qtc21dLCBbZmNGbGV4QWxpZ24uZ3QtbWRdLCBbZmNGbGV4QWxpZ24uZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEZsZXhBbGlnbkRpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIGZjVmFsdWVzID0ge307XG5cbiAgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgcHJpdmF0ZSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZTtcblxuICBASW5wdXQoJ2ZjRmxleEFsaWduJykgICAgICAgc2V0IGFsaWduKHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi54cycpICAgIHNldCBhbGlnblhzKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5zbScpICAgIHNldCBhbGlnblNtKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5tZCcpICAgIHNldCBhbGlnbk1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5sZycpICAgIHNldCBhbGlnbkxnKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi54bCcpICAgIHNldCBhbGlnblhsKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmd0LXhzJykgc2V0IGFsaWduR3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmd0LXNtJykgc2V0IGFsaWduR3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmd0LW1kJykgc2V0IGFsaWduR3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmd0LWxnJykgc2V0IGFsaWduR3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubHQtc20nKSBzZXQgYWxpZ25MdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubHQtbWQnKSBzZXQgYWxpZ25MdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubHQtbGcnKSBzZXQgYWxpZ25MdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubHQteGwnKSBzZXQgYWxpZ25MdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gdmFsOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgQEhvc3QoKSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZSxcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuXG4gICAgaWYgKGxheW91dCAmJiBsYXlvdXQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ID09PSB0aGlzLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGVwZW5kc09uUGFyZW50TGF5b3V0KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaChcbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFkZEZsZXhBbGlnbih0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKTtcblxuICAgIHRoaXMub2JzZXJ2ZXIkLm5leHQodGhpcy5mY1ZhbHVlcyk7XG4gIH1cblxuICBkZXBlbmRzT25QYXJlbnRMYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyh0aGlzLmJyZWFrcG9pbnRzLCAncm93Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLnBhcmVudEVsZW1lbnQsIHRoaXMuc2VydmljZS5hZGRMYXlvdXQoJ3JvdycsIGJyZWFrcG9pbnQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBwYXJlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLnBhcmVudE5vZGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0IGJyZWFrcG9pbnRzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZjVmFsdWVzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkluaXQsIElucHV0LCBSZW5kZXJlcjIsIE9wdGlvbmFsLCBIb3N0LCBPbkNoYW5nZXMsIFNraXBTZWxmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNGbGV4T3JkZXJdLFxuICAgIFtmY0ZsZXhPcmRlci54c10sIFtmY0ZsZXhPcmRlci5zbV0sIFtmY0ZsZXhPcmRlci5tZF0sIFtmY0ZsZXhPcmRlci5sZ10sIFtmY0ZsZXhPcmRlci54bF0sXG4gICAgW2ZjRmxleE9yZGVyLmx0LXNtXSwgW2ZjRmxleE9yZGVyLmx0LW1kXSwgW2ZjRmxleE9yZGVyLmx0LWxnXSwgW2ZjRmxleE9yZGVyLmx0LXhsXSxcbiAgICBbZmNGbGV4T3JkZXIuZ3QteHNdLCBbZmNGbGV4T3JkZXIuZ3Qtc21dLCBbZmNGbGV4T3JkZXIuZ3QtbWRdLCBbZmNGbGV4T3JkZXIuZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEZsZXhPcmRlckRpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIGZjVmFsdWVzID0ge307XG5cbiAgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgcHJpdmF0ZSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZTtcblxuICBASW5wdXQoJ2ZjRmxleE9yZGVyJykgICAgICAgc2V0IG9yZGVyKHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci54cycpICAgIHNldCBvcmRlclhzKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5zbScpICAgIHNldCBvcmRlclNtKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5tZCcpICAgIHNldCBvcmRlck1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5sZycpICAgIHNldCBvcmRlckxnKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci54bCcpICAgIHNldCBvcmRlclhsKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmd0LXhzJykgc2V0IG9yZGVyR3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmd0LXNtJykgc2V0IG9yZGVyR3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmd0LW1kJykgc2V0IG9yZGVyR3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmd0LWxnJykgc2V0IG9yZGVyR3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubHQtc20nKSBzZXQgb3JkZXJMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubHQtbWQnKSBzZXQgb3JkZXJMdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubHQtbGcnKSBzZXQgb3JkZXJMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubHQteGwnKSBzZXQgb3JkZXJMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gdmFsOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgQEhvc3QoKSBAU2tpcFNlbGYoKSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZSxcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuXG4gICAgaWYgKGxheW91dCAmJiBsYXlvdXQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ID09PSB0aGlzLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGVwZW5kc09uUGFyZW50TGF5b3V0KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaChcbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFkZEZsZXhPcmRlcih0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKTtcblxuICAgIHRoaXMub2JzZXJ2ZXIkLm5leHQodGhpcy5mY1ZhbHVlcyk7XG4gIH1cblxuICBkZXBlbmRzT25QYXJlbnRMYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyh0aGlzLmJyZWFrcG9pbnRzLCAncm93Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLnBhcmVudEVsZW1lbnQsIHRoaXMuc2VydmljZS5hZGRMYXlvdXQoJ3JvdycsIGJyZWFrcG9pbnQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBwYXJlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLnBhcmVudE5vZGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0IGJyZWFrcG9pbnRzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZjVmFsdWVzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkluaXQsIElucHV0LCBSZW5kZXJlcjIsIE9wdGlvbmFsLCBIb3N0LCBPbkNoYW5nZXMsIFNraXBTZWxmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNGbGV4T2Zmc2V0XSxcbiAgICBbZmNGbGV4T2Zmc2V0LnhzXSwgW2ZjRmxleE9mZnNldC5zbV0sIFtmY0ZsZXhPZmZzZXQubWRdLCBbZmNGbGV4T2Zmc2V0LmxnXSwgW2ZjRmxleE9mZnNldC54bF0sXG4gICAgW2ZjRmxleE9mZnNldC5sdC1zbV0sIFtmY0ZsZXhPZmZzZXQubHQtbWRdLCBbZmNGbGV4T2Zmc2V0Lmx0LWxnXSwgW2ZjRmxleE9mZnNldC5sdC14bF0sXG4gICAgW2ZjRmxleE9mZnNldC5ndC14c10sIFtmY0ZsZXhPZmZzZXQuZ3Qtc21dLCBbZmNGbGV4T2Zmc2V0Lmd0LW1kXSwgW2ZjRmxleE9mZnNldC5ndC1sZ11cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgRmxleE9mZnNldERpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIGZjVmFsdWVzID0ge307XG5cbiAgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgcHJpdmF0ZSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZTtcblxuICBASW5wdXQoJ2ZjRmxleE9mZnNldCcpICAgICAgIHNldCBvZmZzZXQodmFsKSAgICAgeyB0aGlzLmZjVmFsdWVzWydhbGwnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC54cycpICAgIHNldCBvZmZzZXRYcyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0LnNtJykgICAgc2V0IG9mZnNldFNtKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQubWQnKSAgICBzZXQgb2Zmc2V0TWQodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5sZycpICAgIHNldCBvZmZzZXRMZyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydsZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0LnhsJykgICAgc2V0IG9mZnNldFhsKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5ndC14cycpIHNldCBvZmZzZXRHdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lmd0LXNtJykgc2V0IG9mZnNldEd0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQuZ3QtbWQnKSBzZXQgb2Zmc2V0R3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5ndC1sZycpIHNldCBvZmZzZXRHdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQubHQtc20nKSBzZXQgb2Zmc2V0THRTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5sdC1tZCcpIHNldCBvZmZzZXRMdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lmx0LWxnJykgc2V0IG9mZnNldEx0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LWxnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQubHQteGwnKSBzZXQgb2Zmc2V0THRYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQteGwnXSA9IHZhbDsgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHNlcnZpY2U6IEZsZXhDc3NTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgQFNraXBTZWxmKCkgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcblxuICAgIGlmIChsYXlvdXQgJiYgbGF5b3V0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCA9PT0gdGhpcy5wYXJlbnRFbGVtZW50KSB7XG4gICAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmRlcGVuZHNPblBhcmVudExheW91dCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBPYmplY3Qua2V5cyh0aGlzLmxheW91dFZhbHVlcykuZm9yRWFjaChsYXlvdXRCcmVha3BvaW50ID0+IHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKFxuICAgICAgICAgIHRoaXMuc2VydmljZS5hZGRGbGV4T2Zmc2V0KHRoaXMubGF5b3V0VmFsdWVzW2xheW91dEJyZWFrcG9pbnRdLCBsYXlvdXRCcmVha3BvaW50LCB0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgZGVwZW5kc09uUGFyZW50TGF5b3V0KCkge1xuICAgIGlmICh0aGlzLmxheW91dCkge1xuICAgICAgdGhpcy5sYXlvdXQuYWRkTmV3QnJlYWtwb2ludHModGhpcy5icmVha3BvaW50cywgJ3JvdycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5wYXJlbnRFbGVtZW50LCB0aGlzLnNlcnZpY2UuYWRkTGF5b3V0KCdyb3cnLCBicmVha3BvaW50KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIGdldCBsYXlvdXRWYWx1ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5b3V0ID8gdGhpcy5sYXlvdXQuZmNWYWx1ZXMgOiB7ICdhbGwnOiAnJyB9O1xuICB9XG5cbiAgZ2V0IGJyZWFrcG9pbnRzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZjVmFsdWVzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkluaXQsIFJlbmRlcmVyMiwgT3B0aW9uYWwsIEhvc3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgRmxleENzc1NlcnZpY2UgfSBmcm9tICcuL2ZsZXgtY3NzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlJztcbmltcG9ydCB7IExheW91dERpcmVjdGl2ZSB9IGZyb20gJy4vbGF5b3V0LmRpcmVjdGl2ZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogYFxuICAgIFtmY0ZpbGxdLFxuICAgIFtmY0ZsZXhGaWxsXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBGbGV4RmlsbERpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGxheW91dDogTGF5b3V0RGlyZWN0aXZlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHNlcnZpY2U6IEZsZXhDc3NTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcblxuICAgIGlmIChsYXlvdXQgJiYgbGF5b3V0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCA9PT0gdGhpcy5wYXJlbnRFbGVtZW50KSB7XG4gICAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmRlcGVuZHNPblBhcmVudExheW91dCgpO1xuXG4gICAgdGhpcy5zZXJ2aWNlLmFkZEZsZXhGaWxsKCk7XG4gIH1cblxuICBkZXBlbmRzT25QYXJlbnRMYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyhbJ2FsbCddLCAncm93Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5wYXJlbnRFbGVtZW50LCB0aGlzLnNlcnZpY2UuYWRkTGF5b3V0KCdyb3cnLCAnYWxsJykpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBwYXJlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLnBhcmVudE5vZGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBSZW5kZXJlcjIsIE9uQ2hhbmdlcywgT3B0aW9uYWwsIFNlbGYsIEluamVjdCwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgRmxleENzc1NlcnZpY2UgfSBmcm9tICcuL2ZsZXgtY3NzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlJztcbmltcG9ydCB7IExheW91dERpcmVjdGl2ZSB9IGZyb20gJy4vbGF5b3V0LmRpcmVjdGl2ZSc7XG5cbmNvbnN0IFRSVUxZID0gWyd0cnVlJywgdHJ1ZSwgMV07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RydWVWYWx1ZSh2YWx1ZTogYW55KSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gJycgfHwgVFJVTFkuaW5kZXhPZih2YWx1ZSkgPj0gMDtcbn1cblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gIFtmY1Nob3ddLFxuICBbZmNTaG93LnhzXSwgW2ZjU2hvdy5zbV0sIFtmY1Nob3cubWRdLCBbZmNTaG93LmxnXSwgW2ZjU2hvdy54bF0sXG4gIFtmY1Nob3cubHQtc21dLCBbZmNTaG93Lmx0LW1kXSwgW2ZjU2hvdy5sdC1sZ10sIFtmY1Nob3cubHQteGxdLFxuICBbZmNTaG93Lmd0LXhzXSwgW2ZjU2hvdy5ndC1zbV0sIFtmY1Nob3cuZ3QtbWRdLCBbZmNTaG93Lmd0LWxnXSxcbiAgW2ZjSGlkZV0sXG4gIFtmY0hpZGUueHNdLCBbZmNIaWRlLnNtXSwgW2ZjSGlkZS5tZF0sIFtmY0hpZGUubGddLCBbZmNIaWRlLnhsXSxcbiAgW2ZjSGlkZS5sdC1zbV0sIFtmY0hpZGUubHQtbWRdLCBbZmNIaWRlLmx0LWxnXSwgW2ZjSGlkZS5sdC14bF0sXG4gIFtmY0hpZGUuZ3QteHNdLCBbZmNIaWRlLmd0LXNtXSwgW2ZjSGlkZS5ndC1tZF0sIFtmY0hpZGUuZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNob3dIaWRlRGlyZWN0aXZlIGV4dGVuZHMgQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIHJlYWRvbmx5IGZjVmFsdWVzID0ge307XG5cbiAgcmVhZG9ubHkgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgQElucHV0KCkgZmNEaXNwbGF5RGVmYXVsdDtcblxuICBASW5wdXQoJ2ZjU2hvdycpICAgICAgIHNldCBzaG93KHZhbCkgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93LnhzJykgICAgc2V0IHNob3dYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cuc20nKSAgICBzZXQgc2hvd1NtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5tZCcpICAgIHNldCBzaG93TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93LmxnJykgICAgc2V0IHNob3dMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cueGwnKSAgICBzZXQgc2hvd1hsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuXG4gIEBJbnB1dCgnZmNTaG93Lmx0LXNtJykgc2V0IHNob3dMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5sdC1tZCcpIHNldCBzaG93THRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cubHQtbGcnKSBzZXQgc2hvd0x0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LWxnJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93Lmx0LXhsJykgc2V0IHNob3dMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuXG4gIEBJbnB1dCgnZmNTaG93Lmd0LXhzJykgc2V0IHNob3dHdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5ndC1zbScpIHNldCBzaG93R3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cuZ3QtbWQnKSBzZXQgc2hvd0d0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93Lmd0LWxnJykgc2V0IHNob3dHdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuXG4gIEBJbnB1dCgnZmNIaWRlJykgICAgICAgc2V0IGhpZGUodmFsKSAgeyB0aGlzLmZjVmFsdWVzWydhbGwnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLnhzJykgICAgc2V0IGhpZGVYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLnNtJykgICAgc2V0IGhpZGVTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snc20nXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLm1kJykgICAgc2V0IGhpZGVNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbWQnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLmxnJykgICAgc2V0IGhpZGVMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLnhsJykgICAgc2V0IGhpZGVYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1sneGwnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG5cbiAgQElucHV0KCdmY0hpZGUubHQtc20nKSBzZXQgaGlkZUx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5sdC1tZCcpIHNldCBoaWRlTHRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLmx0LWxnJykgc2V0IGhpZGVMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY0hpZGUubHQteGwnKSBzZXQgaGlkZUx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuXG4gIEBJbnB1dCgnZmNIaWRlLmd0LXhzJykgc2V0IGhpZGVHdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY0hpZGUuZ3Qtc20nKSBzZXQgaGlkZUd0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5ndC1tZCcpIHNldCBoaWRlR3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLmd0LWxnJykgc2V0IGhpZGVHdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJvdGVjdGVkIHBsYXRmb3JtSWQ6IE9iamVjdFxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCByZW5kZXJlcik7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIGNvbnN0IGRpc3BsYXkgPSB0aGlzLmdldERpc3BsYXlTdHlsZSgpO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKHRoaXMuc2VydmljZS5hZGRTaG93SGlkZShkaXNwbGF5LCB0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgZ2V0RGlzcGxheVN0eWxlKCkge1xuICAgIHJldHVybiB0aGlzLmxheW91dCA/ICdmbGV4JyA6IChcbiAgICAgIHRoaXMuZ2V0RWxlbWVudFN0eWxlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnZGlzcGxheScpXG4gICAgICB8fCB0aGlzLmZjRGlzcGxheURlZmF1bHRcbiAgICAgIHx8ICdibG9jaydcbiAgICApO1xuICB9XG5cbiAgZ2V0RWxlbWVudFN0eWxlKGVsZW1lbnQsIHN0eWxlTmFtZSkge1xuICAgIHJldHVybiAoZWxlbWVudCA/IGVsZW1lbnQuc3R5bGVbc3R5bGVOYW1lXSB8fCBlbGVtZW50LnN0eWxlLmdldFByb3BlcnR5VmFsdWUoc3R5bGVOYW1lKSA6ICcnKVxuICAgICAgfHwgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkgPyBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoc3R5bGVOYW1lKSA6ICcnKTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE5nTW9kdWxlLCBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlLCBGTEVYX0NTU19CUkVBS1BPSU5UUywgRkxFWF9DU1NfREVGQVVMVF9CUkVBS1BPSU5UUywgQnJlYWtwb2ludCB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5cbmltcG9ydCB7IExheW91dERpcmVjdGl2ZSB9IGZyb20gJy4vbGF5b3V0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXRBbGlnbkRpcmVjdGl2ZSB9IGZyb20gJy4vbGF5b3V0LWFsaWduLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXRHYXBEaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC1nYXAuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsZXhEaXJlY3RpdmUgfSBmcm9tICcuL2ZsZXguZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsZXhPcmRlckRpcmVjdGl2ZSB9IGZyb20gJy4vZmxleC1vcmRlci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRmxleE9mZnNldERpcmVjdGl2ZSB9IGZyb20gJy4vZmxleC1vZmZzZXQuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsZXhBbGlnbkRpcmVjdGl2ZSB9IGZyb20gJy4vZmxleC1hbGlnbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRmxleEZpbGxEaXJlY3RpdmUgfSBmcm9tICcuL2ZsZXgtZmlsbC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgU2hvd0hpZGVEaXJlY3RpdmUgfSBmcm9tICcuL3Nob3ctaGlkZS5kaXJlY3RpdmUnO1xuXG5leHBvcnQgdHlwZSBCcmVha3BvaW50c0ZuID0gKGRlZmF1bHRCcmVha3BvaW50czogQnJlYWtwb2ludFtdKSA9PiBCcmVha3BvaW50W107XG5cbmV4cG9ydCBmdW5jdGlvbiBjdXN0b21pemVCcmVha1BvaW50cyhicmVha3BvaW50czogQnJlYWtwb2ludFtdfEJyZWFrcG9pbnRzRm4pIHtcbiAgaWYgKHR5cGVvZiBicmVha3BvaW50cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGJyZWFrcG9pbnRzID0gYnJlYWtwb2ludHMoRkxFWF9DU1NfREVGQVVMVF9CUkVBS1BPSU5UUyk7XG4gIH1cblxuICByZXR1cm4gYnJlYWtwb2ludHMgfHwgRkxFWF9DU1NfREVGQVVMVF9CUkVBS1BPSU5UUztcbn1cblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgTGF5b3V0RGlyZWN0aXZlLFxuICAgIExheW91dEFsaWduRGlyZWN0aXZlLFxuICAgIExheW91dEdhcERpcmVjdGl2ZSxcblxuICAgIEZsZXhEaXJlY3RpdmUsXG4gICAgRmxleE9yZGVyRGlyZWN0aXZlLFxuICAgIEZsZXhPZmZzZXREaXJlY3RpdmUsXG4gICAgRmxleEFsaWduRGlyZWN0aXZlLFxuXG4gICAgRmxleEZpbGxEaXJlY3RpdmUsXG4gICAgU2hvd0hpZGVEaXJlY3RpdmUsXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBMYXlvdXREaXJlY3RpdmUsXG4gICAgTGF5b3V0QWxpZ25EaXJlY3RpdmUsXG4gICAgTGF5b3V0R2FwRGlyZWN0aXZlLFxuXG4gICAgRmxleERpcmVjdGl2ZSxcbiAgICBGbGV4T3JkZXJEaXJlY3RpdmUsXG4gICAgRmxleE9mZnNldERpcmVjdGl2ZSxcbiAgICBGbGV4QWxpZ25EaXJlY3RpdmUsXG5cbiAgICBGbGV4RmlsbERpcmVjdGl2ZSxcbiAgICBTaG93SGlkZURpcmVjdGl2ZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRmxleENzc01vZHVsZSB7XG4gIHN0YXRpYyBmb3JSb290KGJyZWFrcG9pbnRzPzogQnJlYWtwb2ludFtdfEJyZWFrcG9pbnRzRm4pOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IEZsZXhDc3NNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgRmxleENzc1NlcnZpY2UsXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiAnZmxleF9jc3NfbW9kdWxlX2JyZWFrcG9pbnRzJyxcbiAgICAgICAgICB1c2VWYWx1ZTogYnJlYWtwb2ludHMsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiBGTEVYX0NTU19CUkVBS1BPSU5UUyxcbiAgICAgICAgICB1c2VGYWN0b3J5OiBjdXN0b21pemVCcmVha1BvaW50cyxcbiAgICAgICAgICBkZXBzOiBbJ2ZsZXhfY3NzX21vZHVsZV9icmVha3BvaW50cyddXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQSwwQkFBaUMsTUFBTTtJQUNyQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHO1FBQzdCLHFCQUFJLEtBQUssR0FBRyxNQUFNLENB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eEUsSUFBMkIsTUFBTSxDQUFDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUN2RSxJQUEyQixNQUFNLENBQUMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBQ3ZFLElBQTJCLE1BQU0sQ0FBQyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFDdkUsSUFBMkIsTUFBTSxDQUFDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUN2RSxJQUEyQixNQUFNLENBQUMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBRXZFLElBQTJCLFFBQVEsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFDMUUsSUFBMkIsUUFBUSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUMxRSxJQUEyQixRQUFRLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBQzFFLElBQTJCLFFBQVEsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFFMUUsSUFBMkIsUUFBUSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUMxRSxJQUEyQixRQUFRLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxR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QUU7Ozs7O0lBQy9FLElBQWlDLFFBQVEsQ0FBQyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFDL0UsSUFBaUMsUUFBUSxDQUFDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUMvRSxJQUFpQyxRQUFRLENBQUMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBQy9FLElBQWlDLFFBQVEsQ0FBQyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFFL0UsSUFBaUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUNsRixJQUFpQyxVQUFVLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBQ2xGLElBQWlDLFVBQVUsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFDbEYsSUFBaUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7OztJQUVsRixJQUFpQyxVQUFVLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7Ozs7O0lBQ2xGLElBQWlDLFVBQVUsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7Ozs7SUFDbEYsSUFBaUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxJ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