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.

3,241 lines 286 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common'), require('@angular/core'), require('rxjs')) :
    typeof define === 'function' && define.amd ? define('@greg-md/ng-flex-css-layout', ['exports', '@angular/common', '@angular/core', 'rxjs'], factory) :
    (factory((global['greg-md'] = global['greg-md'] || {}, global['greg-md']['ng-flex-css-layout'] = {}),global.ng.common,global.ng.core,global.rxjs));
}(this, (function (exports,common,core,rxjs) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b)
            if (b.hasOwnProperty(p))
                d[p] = b[p]; };
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m)
            return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                ar.push(r.value);
        }
        catch (error) {
            e = { error: error };
        }
        finally {
            try {
                if (r && !r.done && (m = i["return"]))
                    m.call(i);
            }
            finally {
                if (e)
                    throw e.error;
            }
        }
        return ar;
    }

    /**
     * @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(function (key) {
            var /** @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
     */
    var /** @type {?} */ INLINE = 'inline';
    var /** @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() : '';
        var _a = __read(value.split(' '), 3), direction = _a[0], wrap = _a[1], inline = _a[2];
        // First value must be the `flex-direction`
        if (!LAYOUT_VALUES.find(function (x) { return 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) {
        var _a = __read(validateValue(value), 1), flow = _a[0];
        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, inline) {
        if (wrap === void 0) {
            wrap = null;
        }
        if (inline === void 0) {
            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';
        var _a = __read(align.split(' '), 2), mainAxis = _a[0], crossAxis = _a[1];
        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, shrink) {
        if (grow === void 0) {
            grow = '1';
        }
        if (shrink === void 0) {
            shrink = '1';
        }
        var /** @type {?} */ parts = [grow, shrink, basis];
        var /** @type {?} */ j = basis.indexOf('calc');
        if (j > 0) {
            parts[2] = _validateCalcValue(basis.substring(j).trim());
            var /** @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 {
            var /** @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
     */
    var /** @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)'] },
    ];
    var /** @type {?} */ FLEX_CSS_BREAKPOINTS = new core.InjectionToken('flex_css_breakpoints');
    var FlexCssStyleElement = (function () {
        function FlexCssStyleElement(style) {
            this.style = style;
            this.storage = {};
        }
        return FlexCssStyleElement;
    }());
    var FlexCssService = (function () {
        function FlexCssService(doc, breakpoints) {
            this.doc = doc;
            this.breakpoints = breakpoints;
            this.initLayout();
            this.initFlex();
            this.initFill();
        }
        /**
         * @return {?}
         */
        FlexCssService.prototype.initLayout = /**
         * @return {?}
         */
            function () {
                var /** @type {?} */ style = this.doc.createElement('style');
                style.id = 'fc-layout';
                this.doc.head.appendChild(style);
                this.layout = new FlexCssStyleElement(style);
            };
        /**
         * @return {?}
         */
        FlexCssService.prototype.initFlex = /**
         * @return {?}
         */
            function () {
                var /** @type {?} */ style = this.doc.createElement('style');
                style.id = 'fc-flex';
                this.doc.head.appendChild(style);
                this.flex = new FlexCssStyleElement(style);
            };
        /**
         * @return {?}
         */
        FlexCssService.prototype.initFill = /**
         * @return {?}
         */
            function () {
                var /** @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 {?}
         */
        FlexCssService.prototype.addLayout = /**
         * @param {?} layout
         * @param {?} breakpoint
         * @return {?}
         */
            function (layout, breakpoint) {
                var _a = __read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
                var /** @type {?} */ className = generateLayoutClassName(direction, wrap, isInline, breakpoint);
                if (!this.hasInLayoutStorage(className, breakpoint)) {
                    var /** @type {?} */ style = buildCSS(direction, wrap, isInline);
                    this.addToLayoutStorage(className, style, breakpoint);
                }
                return className;
            };
        /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} align
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.addLayoutAlign = /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} align
         * @param {?} breakpoint
         * @return {?}
         */
            function (layout, layoutBreakpoint, align, breakpoint) {
                var _a = __read(normalizeLayoutAlignValue(align), 2), mainAxis = _a[0], crossAxis = _a[1];
                var /** @type {?} */ layoutAlignClassName = generateLayoutAlignClassName(mainAxis, crossAxis, breakpoint);
                if (!this.hasInLayoutStorage(layoutAlignClassName, breakpoint)) {
                    var /** @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') {
                    var _b = __read(validateValue(layout), 3), direction = _b[0], wrap = _b[1], isInline = _b[2];
                    var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
                    var /** @type {?} */ className = layoutAlignClassName + '.' + layoutClassName;
                    if (!this.hasInLayoutStorage(className, breakpoint)) {
                        var /** @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 {?}
         */
        FlexCssService.prototype.addLayoutGap = /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} value
         * @param {?} breakpoint
         * @return {?}
         */
            function (layout, layoutBreakpoint, value, breakpoint) {
                value = value || '0';
                var _a = __read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
                var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
                var /** @type {?} */ layoutGapClassName = generateLayoutGapClassName(value, breakpoint);
                var /** @type {?} */ className = layoutGapClassName + '.' + layoutClassName + ' > *:not(:last-child)';
                if (!this.hasInLayoutStorage(className, breakpoint)) {
                    var /** @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 {?}
         */
        FlexCssService.prototype.addFlex = /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} value
         * @param {?} breakpoint
         * @param {?=} grow
         * @param {?=} shrink
         * @return {?}
         */
            function (layout, layoutBreakpoint, value, breakpoint, grow, shrink) {
                value = value.replace(';', '');
                var _a = __read(validateBasis(value, grow, shrink), 3), theGrow = _a[0], theShrink = _a[1], theBasis = _a[2];
                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.
                var /** @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:
                        var /** @type {?} */ isCalc = String(theBasis).indexOf('calc') > -1;
                        var /** @type {?} */ isPercent = !isCalc && String(theBasis).indexOf('%') > -1;
                        var /** @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;
                }
                var /** @type {?} */ flexClassName = generateFlexClassName(theGrow, theShrink, theBasis, breakpoint);
                if (!this.hasInFlexStorage(flexClassName, breakpoint)) {
                    this.addToFlexStorage(flexClassName, style, breakpoint);
                }
                var _b = __read(validateValue(layout), 3), direction = _b[0], wrap = _b[1], isInline = _b[2];
                var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
                var /** @type {?} */ className = flexClassName + '.' + layoutClassName;
                if (!this.hasInFlexStorage(className, breakpoint)) {
                    var /** @type {?} */ max = isFlowHorizontal(direction) ? 'max-width' : 'max-height';
                    var /** @type {?} */ min = isFlowHorizontal(direction) ? 'min-width' : 'min-height';
                    var /** @type {?} */ usingCalc = (String(theBasis).indexOf('calc') > -1) || (theBasis === 'auto');
                    var /** @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
                    var /** @type {?} */ isFixed = !theGrow && !theShrink;
                    var /** @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 {?}
         */
        FlexCssService.prototype.addFlexOrder = /**
         * @param {?} order
         * @param {?} breakpoint
         * @return {?}
         */
            function (order, breakpoint) {
                order = parseInt(order, 10);
                order = isNaN(order) ? 0 : order;
                var /** @type {?} */ className = generateFlexOrderClassName(order, breakpoint);
                if (!this.hasInFlexStorage(className, breakpoint)) {
                    var /** @type {?} */ style = { 'order': order };
                    this.addToFlexStorage(className, style, breakpoint);
                }
                return className;
            };
        /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} offset
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.addFlexOffset = /**
         * @param {?} layout
         * @param {?} layoutBreakpoint
         * @param {?} offset
         * @param {?} breakpoint
         * @return {?}
         */
            function (layout, layoutBreakpoint, offset, breakpoint) {
                var /** @type {?} */ isPercent = String(offset).indexOf('%') > -1;
                var /** @type {?} */ isPx = String(offset).indexOf('px') > -1;
                if (!isPx && !isPercent && !isNaN(offset)) {
                    offset = offset + '%';
                }
                var _a = __read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
                var /** @type {?} */ offsetClassName = generateFlexOffsetClassName(offset, breakpoint);
                var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
                var /** @type {?} */ className = offsetClassName + '.' + layoutClassName;
                if (!this.hasInFlexStorage(className, breakpoint)) {
                    var /** @type {?} */ style = isFlowHorizontal(direction) ? { 'margin-left': "" + offset } : { 'margin-top': "" + offset };
                    this.addToFlexStorage(className, style, breakpoint, [layoutBreakpoint]);
                }
                return offsetClassName;
            };
        /**
         * @param {?} align
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.addFlexAlign = /**
         * @param {?} align
         * @param {?} breakpoint
         * @return {?}
         */
            function (align, breakpoint) {
                align = align || 'stretch';
                // Cross-axis
                switch (align) {
                    case 'start':
                        align = 'flex-start';
                        break;
                    case 'end':
                        align = 'flex-end';
                        break;
                }
                var /** @type {?} */ className = generateFlexAlignClassName(align, breakpoint);
                if (!this.hasInFlexStorage(className, breakpoint)) {
                    var /** @type {?} */ style = { 'align-self': align };
                    this.addToFlexStorage(className, style, breakpoint);
                }
                return className;
            };
        /**
         * @return {?}
         */
        FlexCssService.prototype.addFlexFill = /**
         * @return {?}
         */
            function () {
                var /** @type {?} */ className = generateFlexFillClassName();
                if (!this.hasInFillStorage(className, 'all')) {
                    var /** @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 {?}
         */
        FlexCssService.prototype.addShowHide = /**
         * @param {?} display
         * @param {?} show
         * @param {?} breakpoint
         * @return {?}
         */
            function (display, show, breakpoint) {
                var /** @type {?} */ className = generateFlexShowHideClassName(display, show, breakpoint);
                if (!this.hasInFillStorage(className, breakpoint)) {
                    var /** @type {?} */ style = {
                        'display': show ? display || 'block' : 'none',
                    };
                    this.addToFillStorage(className, style, breakpoint);
                }
                return className;
            };
        /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.hasInLayoutStorage = /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
            function (className, breakpoint) {
                return this.hasInStorage(this.layout, className, breakpoint);
            };
        /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
        FlexCssService.prototype.addToLayoutStorage = /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
            function (className, style, breakpoint, customBreakpoints) {
                return this.addToStorage(this.layout, className, style, breakpoint, customBreakpoints);
            };
        /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.hasInFlexStorage = /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
            function (className, breakpoint) {
                return this.hasInStorage(this.flex, className, breakpoint);
            };
        /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
        FlexCssService.prototype.addToFlexStorage = /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
            function (className, style, breakpoint, customBreakpoints) {
                return this.addToStorage(this.flex, className, style, breakpoint, customBreakpoints);
            };
        /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.hasInFillStorage = /**
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
            function (className, breakpoint) {
                return this.hasInStorage(this.fill, className, breakpoint);
            };
        /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
        FlexCssService.prototype.addToFillStorage = /**
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
            function (className, style, breakpoint, customBreakpoints) {
                return this.addToStorage(this.fill, className, style, breakpoint, customBreakpoints);
            };
        /**
         * @param {?} styleElement
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
        FlexCssService.prototype.hasInStorage = /**
         * @param {?} styleElement
         * @param {?} className
         * @param {?} breakpoint
         * @return {?}
         */
            function (styleElement, className, breakpoint) {
                return !!(styleElement.storage[breakpoint] && styleElement.storage[breakpoint][className]);
            };
        /**
         * @param {?} styleElement
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
        FlexCssService.prototype.addToStorage = /**
         * @param {?} styleElement
         * @param {?} className
         * @param {?} style
         * @param {?} breakpoint
         * @param {?=} customBreakpoints
         * @return {?}
         */
            function (styleElement, className, style, breakpoint, customBreakpoints) {
                customBreakpoints = customBreakpoints || [];
                var /** @type {?} */ styles = applyCssPrefixes(style);
                var /** @type {?} */ css = this.generateCss(styles);
                if (css !== '') {
                    var /** @type {?} */ classCss = '.' + className + ' { ' + css + ' }';
                    var /** @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 {?}
         */
        FlexCssService.prototype.reorderTextElements = /**
         * @param {?} styleElement
         * @return {?}
         */
            function (styleElement) {
                var _this = this;
                var /** @type {?} */ position = this.reorderBreakpointElements(styleElement, 'all');
                this.breakpoints.forEach(function (breakpoint) {
                    position = _this.reorderBreakpointElements(styleElement, breakpoint.alias, position);
                });
            };
        /**
         * @param {?} styleElement
         * @param {?} breakpoint
         * @param {?=} position
         * @return {?}
         */
        FlexCssService.prototype.reorderBreakpointElements = /**
         * @param {?} styleElement
         * @param {?} breakpoint
         * @param {?=} position
         * @return {?}
         */
            function (styleElement, breakpoint, position) {
                if (position === void 0) {
                    position = 0;
                }
                var /** @type {?} */ breakpointElements = styleElement.storage[breakpoint];
                if (!breakpointElements) {
                    return position;
                }
                Object.keys(breakpointElements).forEach(function (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 {?}
         */
        FlexCssService.prototype.generateCss = /**
         * @param {?} styles
         * @return {?}
         */
            function (styles) {
                var /** @type {?} */ css = [];
                Object.keys(styles).sort().forEach(function (key) {
                    var /** @type {?} */ values = Array.isArray(styles[key]) ? styles[key] : [styles[key]];
                    values.sort();
                    values.forEach(function (value) {
                        if (value !== null && value !== '') {
                            css.push(key + ': ' + value + ';');
                        }
                    });
                });
                return css.join(' ');
            };
        /**
         * @param {?} breakpointsAliases
         * @param {?} css
         * @return {?}
         */
        FlexCssService.prototype.addBreakpoints = /**
         * @param {?} breakpointsAliases
         * @param {?} css
         * @return {?}
         */
            function (breakpointsAliases, css) {
                breakpointsAliases = breakpointsAliases.filter(function (breakpoint) { return breakpoint !== 'all'; });
                if (!breakpointsAliases.length) {
                    return css;
                }
                var /** @type {?} */ theBreakpoints = [];
                this.breakpoints
                    .filter(function (breakpoint) { return breakpointsAliases.indexOf(breakpoint.alias) >= 0; })
                    .forEach(function (breakpoint) { return theBreakpoints = theBreakpoints.concat(breakpoint.media); });
                theBreakpoints = theBreakpoints.filter(function (value, index, self) { return self.indexOf(value) === index; });
                return '@media ' + theBreakpoints.join(' and ') + ' { ' + css + ' }';
            };
        FlexCssService.decorators = [
            { type: core.Injectable },
        ];
        /** @nocollapse */
        FlexCssService.ctorParameters = function () {
            return [
                { type: undefined, decorators: [{ type: core.Inject, args: [common.DOCUMENT,] }] },
                { type: undefined, decorators: [{ type: core.Inject, args: [FLEX_CSS_BREAKPOINTS,] }] }
            ];
        };
        return FlexCssService;
    }());

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

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes} checked by tsc
     */
    var LayoutDirective = (function (_super) {
        __extends(LayoutDirective, _super);
        function LayoutDirective(elementRef, renderer, service) {
            var _this = _super.call(this, elementRef, renderer) || this;
            _this.service = service;
            _this.fcValues = {};
            _this.observer$ = new rxjs.ReplaySubject(1);
            return _this;
        }
        Object.defineProperty(LayoutDirective.prototype, "layout", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['all'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutXs", {
            // get layout()        { return this.fcValues['all']; }
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['xs'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutXl", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['xl'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutGtXs", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-xs'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutGtSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutGtMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutGtLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutLtSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutLtMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutLtLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LayoutDirective.prototype, "layoutLtXl", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-xl'] = val; },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        LayoutDirective.prototype.ngOnChanges = /**
         * @return {?}
         */
            function () {
                this.reload();
            };
        /**
         * @return {?}
         */
        LayoutDirective.prototype.reload = /**
         * @return {?}
         */
            function () {
                var _this = this;
                var /** @type {?} */ classNames = [];
                this.breakpoints.forEach(function (breakpoint) {
                    classNames.push(_this.service.addLayout(_this.fcValues[breakpoint], breakpoint));
                });
                this.setClassNames(classNames);
                this.observer$.next(this.fcValues);
            };
        /**
         * @param {?} breakpoints
         * @param {?=} defaultValue
         * @return {?}
         */
        LayoutDirective.prototype.addNewBreakpoints = /**
         * @param {?} breakpoints
         * @param {?=} defaultValue
         * @return {?}
         */
            function (breakpoints, defaultValue) {
                var _this = this;
                breakpoints.forEach(function (breakpoint) {
                    if (!_this.fcValues[breakpoint]) {
                        _this.fcValues[breakpoint] = defaultValue;
                    }
                });
                this.reload();
            };
        Object.defineProperty(LayoutDirective.prototype, "breakpoints", {
            get: /**
             * @return {?}
             */ function () {
                return Object.keys(this.fcValues);
            },
            enumerable: true,
            configurable: true
        });
        LayoutDirective.decorators = [
            { type: core.Directive, args: [{
                        selector: "\n    [fcLayout],\n    [fcLayout.xs], [fcLayout.sm], [fcLayout.md], [fcLayout.lg], [fcLayout.xl],\n    [fcLayout.lt-sm], [fcLayout.lt-md], [fcLayout.lt-lg], [fcLayout.lt-xl],\n    [fcLayout.gt-xs], [fcLayout.gt-sm], [fcLayout.gt-md], [fcLayout.gt-lg]\n  ",
                    },] },
        ];
        /** @nocollapse */
        LayoutDirective.ctorParameters = function () {
            return [
                { type: core.ElementRef },
                { type: core.Renderer2 },
                { type: FlexCssService }
            ];
        };
        LayoutDirective.propDecorators = {
            layout: [{ type: core.Input, args: ['fcLayout',] }],
            layoutXs: [{ type: core.Input, args: ['fcLayout.xs',] }],
            layoutSm: [{ type: core.Input, args: ['fcLayout.sm',] }],
            layoutMd: [{ type: core.Input, args: ['fcLayout.md',] }],
            layoutLg: [{ type: core.Input, args: ['fcLayout.lg',] }],
            layoutXl: [{ type: core.Input, args: ['fcLayout.xl',] }],
            layoutGtXs: [{ type: core.Input, args: ['fcLayout.gt-xs',] }],
            layoutGtSm: [{ type: core.Input, args: ['fcLayout.gt-sm',] }],
            layoutGtMd: [{ type: core.Input, args: ['fcLayout.gt-md',] }],
            layoutGtLg: [{ type: core.Input, args: ['fcLayout.gt-lg',] }],
            layoutLtSm: [{ type: core.Input, args: ['fcLayout.lt-sm',] }],
            layoutLtMd: [{ type: core.Input, args: ['fcLayout.lt-md',] }],
            layoutLtLg: [{ type: core.Input, args: ['fcLayout.lt-lg',] }],
            layoutLtXl: [{ type: core.Input, args: ['fcLayout.lt-xl',] }]
        };
        return LayoutDirective;
    }(BaseDirective));

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

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

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes} checked by tsc
     */
    var FlexDirective = (function (_super) {
        __extends(FlexDirective, _super);
        function FlexDirective(elementRef, renderer, service, layout) {
            var _this = _super.call(this, elementRef, renderer) || this;
            _this.service = service;
            _this.fcValues = {};
            _this.observer$ = new rxjs.ReplaySubject(1);
            _this.fcShrink = 1;
            _this.fcGrow = 1;
            if (layout && layout.elementRef.nativeElement === _this.parentElement) {
                _this.layout = layout;
            }
            return _this;
        }
        Object.defineProperty(FlexDirective.prototype, "flex", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['all'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexXs", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['xs'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexXl", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['xl'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexGtXs", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-xs'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexGtSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexGtMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexGtLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['gt-lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexLtSm", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-sm'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexLtMd", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-md'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexLtLg", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-lg'] = val; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "flexLtXl", {
            set: /**
             * @param {?} val
             * @return {?}
             */ function (val) { this.fcValues['lt-xl'] = val; },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        FlexDirective.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                this.dependsOnParentLayout();
            };
        /**
         * @return {?}
         */
        FlexDirective.prototype.ngOnChanges = /**
         * @return {?}
         */
            function () {
                this.reload();
            };
        /**
         * @return {?}
         */
        FlexDirective.prototype.reload = /**
         * @return {?}
         */
            function () {
                var _this = this;
                var /** @type {?} */ classNames = [];
                this.breakpoints.forEach(function (breakpoint) {
                    Object.keys(_this.layoutValues).forEach(function (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 {?}
         */
        FlexDirective.prototype.dependsOnParentLayout = /**
         * @return {?}
         */
            function () {
                var _this = this;
                if (this.layout) {
                    this.layout.addNewBreakpoints(this.breakpoints, 'row');
                }
                else {
                    this.breakpoints.forEach(function (breakpoint) {
                        _this.renderer.addClass(_this.parentElement, _this.service.addLayout('row', breakpoint));
                    });
                }
            };
        Object.defineProperty(FlexDirective.prototype, "layoutValues", {
            get: /**
             * @return {?}
             */ function () {
                return this.layout ? this.layout.fcValues : { 'all': '' };
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "parentElement", {
            get: /**
             * @return {?}
             */ function () {
                return this.renderer.parentNode(this.elementRef.nativeElement);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FlexDirective.prototype, "breakpoints", {
            get: /**
             * @return {?}
             */ function () {
                return Object.keys(this.fcValues);
            },
            enumerable: true,
            configurable: true
        });
        FlexDirective.decorators = [
            { type: core.Directive, args: [{
                        selector: "\n    [fcFlex],\n    [fcFlex.xs], [fcFlex.sm], [fcFlex.md], [fcFlex.lg], [fcFlex.xl],\n    [fcFlex.lt-sm], [fcFlex.lt-md], [fcFlex.lt-lg], [fcFlex.lt-xl],\n    [fcFlex.gt-xs], [fcFlex.gt-sm], [fcFlex.gt-md], [fcFlex.gt-lg],\n  ",
                    },] },
        ];
        /** @nocollapse */
        FlexDirective.ctorParameters = function () {
            return [
                { type: core.ElementRef },
                { type: core.Renderer2 },
                { type: FlexCssService },
                { type: LayoutDirective, decorators: [{ type: core.Optional }, { type: core.Host }, { type: core.SkipSelf }] }
            ];
        };
        FlexDirective.propDecorators = {
            fcShrink: [{ type: core.Input }],
            fcGrow: [{ type: core.Input }],
            flex: [{ type: core.Input, args: ['fcFlex',] }],
            flexXs: [{ type: core.Input, args: ['fcFlex.xs',] }],
            flexSm: [{ type: core.Input, args: ['fcFlex.sm',] }],
            flexMd: [{ type: core.Input, args: ['fcFlex.md',] }],
            flexLg: [{ type: core.Input, args: ['fcFlex.lg',] }],
            flexXl: [{ type: core.Input, args: ['fcFlex.xl',] }],
            flexGtXs: [{ type: core.Input, args: ['fcFlex.gt-xs',] }],
            flexGtSm: [{ type: core.Input, args: ['fcFlex.gt-sm',] }],
            flexGtMd: [{ type: core.Input, args: ['fcFlex.gt-md',] }],
            flexGtLg: [{ type: core.Input, args: ['fcFlex.gt-lg',] }],
            flexLtSm: [{ type: core.Input, args: ['fcFlex.lt-sm',] }],
            flexLtMd: [{ type: core.Input, args: ['fcFlex.lt-md',] }],
            flexLtLg: [{ type: core.Input, args: ['fcFlex.lt-lg',] }],
            flexLtXl: [{ type: core.Input, args: ['fcFlex.lt-xl',] }]
        };
        return FlexDirective;
    }(BaseDirective));

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

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

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

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes} checked by tsc
     */
    var FlexFillDirective = (function (_super) {
        __extends(FlexFillDirective, _super);
        function FlexFillDirective(elementRef, renderer, service, layout) {
            var _this = _super.call(this, elementRef, renderer) || this;
            _this.service = service;
            if (layout && layout.elementRef.nativeElement === _this.parentElement) {
                _this.layout = layout;
            }
            return _this;
        }
        /**
         * @return {?}
         */
        FlexFillDirective.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                this.dependsOnParentLayout();
                this.service.addFlexFill();
            };
        /**
         * @return {?}
         */
        FlexFillDirective.prototype.dependsOnParentLayout = /**
         * @return {?}
         */
            function () {
                if (this.layout) {
                    this.layout.addNewBreakpoints(['all'], 'row');
                }
                else {
                    this.renderer.addClass(this.parentElement, this.service.addLayout('row', 'all'));
                }
            };
        Object.defineProperty(FlexFillDirective.prototype, "parentElement", {
            get: /**
             * @return {?}
             */ function () {
                return this.renderer.parentNode(this.elementRef.nativeElement);
            },
            enumerable: true,
            configurable: true
        });
        FlexFillDirective.decorators = [
            { type: core.Directive, args: [{
                        selector: "\n    [fcFill],\n    [fcFlexFill]\n  ",
                    },] },
        ];
        /** @nocollapse */
        FlexFillDirective.ctorParameters = function () {
            return [
                { type: core.ElementRef },
                { type: core.Renderer2 },
                { type: FlexCssService },
                { type: LayoutDirective, decorators: [{ type: core.Optional }, { type: core.Host }] }
            ];
        };
        return FlexFillDirective;
    }(BaseDirective));

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

    /**
     * @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;
    }
    var FlexCssModule = (function () {
        function FlexCssModule() {
        }
        /**
         * @param {?=} breakpoints
         * @return {?}
         */
        FlexCssModule.forRoot = /**
         * @param {?=} breakpoints
         * @return {?}
         */
            function (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: core.NgModule, args: [{
                        declarations: [
                            LayoutDirective,
                            LayoutAlignDirective,
                            LayoutGapDirective,
                            FlexDirective,
                            FlexOrderDirective,
                            FlexOffsetDirective,
                            FlexAlignDirective,
                            FlexFillDirective,
                            ShowHideDirective,
                        ],
                        exports: [
                            LayoutDirective,
                            LayoutAlignDirective,
                            LayoutGapDirective,
                            FlexDirective,
                            FlexOrderDirective,
                            FlexOffsetDirective,
                            FlexAlignDirective,
                            FlexFillDirective,
                            ShowHideDirective,
                        ],
                    },] },
        ];
        return FlexCssModule;
    }());

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

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

    exports.LayoutDirective = LayoutDirective;
    exports.LayoutAlignDirective = LayoutAlignDirective;
    exports.LayoutGapDirective = LayoutGapDirective;
    exports.FlexDirective = FlexDirective;
    exports.FlexAlignDirective = FlexAlignDirective;
    exports.FlexOrderDirective = FlexOrderDirective;
    exports.FlexOffsetDirective = FlexOffsetDirective;
    exports.FlexFillDirective = FlexFillDirective;
    exports.customizeBreakPoints = customizeBreakPoints;
    exports.FlexCssModule = FlexCssModule;
    exports.ɵa = BaseDirective;
    exports.ɵb = FLEX_CSS_BREAKPOINTS;
    exports.ɵc = FlexCssService;
    exports.ɵd = ShowHideDirective;

    Object.defineProperty(exports, '__esModule', { value: true });

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JlZy1tZC1uZy1mbGV4LWNzcy1sYXlvdXQudW1kLmpzLm1hcCIsInNvdXJjZXMiOltudWxsLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvYXV0by1wcmVmaXhlci50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9sYXlvdXQtdmFsaWRhdG9yLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2hlbHBlcnMudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvYmFzaXMtdmFsaWRhdG9yLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2ZsZXgtY3NzLnNlcnZpY2UudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvZGlyZWN0aXZlLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2xheW91dC5kaXJlY3RpdmUudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvbGF5b3V0LWFsaWduLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9sYXlvdXQtZ2FwLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LWFsaWduLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LW9yZGVyLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9mbGV4LW9mZnNldC5kaXJlY3RpdmUudHMiLCJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC9saWIvZmxleC1maWxsLmRpcmVjdGl2ZS50cyIsIm5nOi8vQGdyZWctbWQvbmctZmxleC1jc3MtbGF5b3V0L2xpYi9zaG93LWhpZGUuZGlyZWN0aXZlLnRzIiwibmc6Ly9AZ3JlZy1tZC9uZy1mbGV4LWNzcy1sYXlvdXQvbGliL2ZsZXgtY3NzLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxyXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxyXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXHJcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXHJcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXHJcblxyXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcclxuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMClcclxuICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBleHBvcnRzKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmICghZXhwb3J0cy5oYXNPd25Qcm9wZXJ0eShwKSkgZXhwb3J0c1twXSA9IG1bcF07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl0sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcclxuICAgIHJlc3VsdC5kZWZhdWx0ID0gbW9kO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8qKlxuICogQXBwbGllcyBDU1MgcHJlZml4ZXMgdG8gYXBwcm9wcmlhdGUgc3R5bGUga2V5cy5cbiAqXG4gKiBOb3RlOiBgLW1zLWAsIGAtbW96YCBhbmQgYC13ZWJraXQtYm94YCBhcmUgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gZS5nLlxuICogICAge1xuICogICAgICBkaXNwbGF5OiAtd2Via2l0LWZsZXg7ICAgICBORVcgLSBTYWZhcmkgNi4xKy4gaU9TIDcuMSssIEJCMTBcbiAqICAgICAgZGlzcGxheTogZmxleDsgICAgICAgICAgICAgTkVXLCBTcGVjIC0gRmlyZWZveCwgQ2hyb21lLCBPcGVyYVxuICogICAgICAvLyBkaXNwbGF5OiAtd2Via2l0LWJveDsgICBPTEQgLSBpT1MgNi0sIFNhZmFyaSAzLjEtNiwgQkI3XG4gKiAgICAgIC8vIGRpc3BsYXk6IC1tcy1mbGV4Ym94OyAgIFRXRUVORVIgLSBJRSAxMFxuICogICAgICAvLyBkaXNwbGF5OiAtbW96LWZsZXhib3g7ICBPTEQgLSBGaXJlZm94XG4gKiAgICB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUNzc1ByZWZpeGVzKHRhcmdldCkge1xuICBPYmplY3Qua2V5cyh0YXJnZXQpLmZvckVhY2goa2V5ID0+IHtcbiAgICBsZXQgdmFsdWUgPSB0YXJnZXRba2V5XSB8fCAnJztcblxuICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICBjYXNlICdkaXNwbGF5JzpcbiAgICAgICAgaWYgKHZhbHVlID09PSAnZmxleCcpIHtcbiAgICAgICAgICB0YXJnZXRbJ2Rpc3BsYXknXSA9IFtcbiAgICAgICAgICAgICctd2Via2l0LWZsZXgnLFxuICAgICAgICAgICAgJ2ZsZXgnXG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ2lubGluZS1mbGV4Jykge1xuICAgICAgICAgIHRhcmdldFsnZGlzcGxheSddID0gW1xuICAgICAgICAgICAgJy13ZWJraXQtaW5saW5lLWZsZXgnLFxuICAgICAgICAgICAgJ2lubGluZS1mbGV4J1xuICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGFyZ2V0WydkaXNwbGF5J10gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYWxpZ24taXRlbXMnOlxuICAgICAgY2FzZSAnYWxpZ24tc2VsZic6XG4gICAgICBjYXNlICdhbGlnbi1jb250ZW50JzpcbiAgICAgIGNhc2UgJ2ZsZXgnOlxuICAgICAgY2FzZSAnZmxleC1iYXNpcyc6XG4gICAgICBjYXNlICdmbGV4LWZsb3cnOlxuICAgICAgY2FzZSAnZmxleC1ncm93JzpcbiAgICAgIGNhc2UgJ2ZsZXgtc2hyaW5rJzpcbiAgICAgIGNhc2UgJ2ZsZXgtd3JhcCc6XG4gICAgICBjYXNlICdqdXN0aWZ5LWNvbnRlbnQnOlxuICAgICAgICB0YXJnZXRbJy13ZWJraXQtJyArIGtleV0gPSB2YWx1ZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2ZsZXgtZGlyZWN0aW9uJzpcbiAgICAgICAgdmFsdWUgPSB2YWx1ZSB8fCAncm93JztcbiAgICAgICAgdGFyZ2V0Wyctd2Via2l0LWZsZXgtZGlyZWN0aW9uJ10gPSB2YWx1ZTtcbiAgICAgICAgdGFyZ2V0WydmbGV4LWRpcmVjdGlvbiddID0gdmFsdWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdvcmRlcic6XG4gICAgICAgIHRhcmdldFsnb3JkZXInXSA9IHRhcmdldFsnLXdlYmtpdC0nICsga2V5XSA9IGlzTmFOKHZhbHVlKSA/ICcwJyA6IHZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB0YXJnZXQ7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cbmV4cG9ydCBjb25zdCBJTkxJTkUgPSAnaW5saW5lJztcbmV4cG9ydCBjb25zdCBMQVlPVVRfVkFMVUVTID0gWydyb3cnLCAnY29sdW1uJywgJ3Jvdy1yZXZlcnNlJywgJ2NvbHVtbi1yZXZlcnNlJ107XG5cbi8qKlxuICogVmFsaWRhdGUgdGhlIGRpcmVjdGlvbnwnZGlyZWN0aW9uIHdyYXAnIHZhbHVlIGFuZCB0aGVuIHVwZGF0ZSB0aGUgaG9zdCdzIGlubGluZSBmbGV4Ym94IHN0eWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRMYXlvdXRDU1ModmFsdWU6IHN0cmluZykge1xuICBjb25zdCBbZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZV0gPSB2YWxpZGF0ZVZhbHVlKHZhbHVlKTtcbiAgcmV0dXJuIGJ1aWxkQ1NTKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUpO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHRoZSB2YWx1ZSB0byBiZSBvbmUgb2YgdGhlIGFjY2VwdGFibGUgdmFsdWUgb3B0aW9uc1xuICogVXNlIGRlZmF1bHQgZmFsbGJhY2sgb2YgJ3JvdydcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlVmFsdWUodmFsdWU6IHN0cmluZykge1xuICB2YWx1ZSA9IHZhbHVlID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6ICcnO1xuICBsZXQgW2RpcmVjdGlvbiwgd3JhcCwgaW5saW5lXSA9IHZhbHVlLnNwbGl0KCcgJyk7XG5cbiAgLy8gRmlyc3QgdmFsdWUgbXVzdCBiZSB0aGUgYGZsZXgtZGlyZWN0aW9uYFxuICBpZiAoIUxBWU9VVF9WQUxVRVMuZmluZCh4ID0+IHggPT09IGRpcmVjdGlvbikpIHtcbiAgICBkaXJlY3Rpb24gPSBMQVlPVVRfVkFMVUVTWzBdO1xuICB9XG5cbiAgaWYgKHdyYXAgPT09IElOTElORSkge1xuICAgIHdyYXAgPSAoaW5saW5lICE9PSBJTkxJTkUpID8gaW5saW5lIDogJyc7XG4gICAgaW5saW5lID0gSU5MSU5FO1xuICB9XG5cbiAgcmV0dXJuIFtkaXJlY3Rpb24sIHZhbGlkYXRlV3JhcFZhbHVlKHdyYXApLCAhIWlubGluZV07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIHRoZSB2YWxpZGF0ZWQsIGZsZXgtZGlyZWN0aW9uIHZhbHVlIHNwZWNpZmllc1xuICogYSBob3Jpem9udGFsL3JvdyBmbG93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGbG93SG9yaXpvbnRhbCh2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IFtmbG93LCBdID0gdmFsaWRhdGVWYWx1ZSh2YWx1ZSk7XG4gIHJldHVybiBmbG93LmluZGV4T2YoJ3JvdycpID4gLTE7XG59XG5cbi8qKlxuICogQ29udmVydCBsYXlvdXQtd3JhcD0nPHZhbHVlPicgdG8gZXhwZWN0ZWQgZmxleC13cmFwIHN0eWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVdyYXBWYWx1ZSh2YWx1ZSkge1xuICBpZiAoISF2YWx1ZSkge1xuICAgIHN3aXRjaCAodmFsdWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAncmV2ZXJzZSc6XG4gICAgICBjYXNlICd3cmFwLXJldmVyc2UnOlxuICAgICAgY2FzZSAncmV2ZXJzZS13cmFwJzpcbiAgICAgICAgdmFsdWUgPSAnd3JhcC1yZXZlcnNlJztcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ25vJzpcbiAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgY2FzZSAnbm93cmFwJzpcbiAgICAgICAgdmFsdWUgPSAnbm93cmFwJztcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIC8vIEFsbCBvdGhlciB2YWx1ZXMgZmFsbGJhY2sgdG8gJ3dyYXAnXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB2YWx1ZSA9ICd3cmFwJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgQ1NTIHRoYXQgc2hvdWxkIGJlIGFzc2lnbmVkIHRvIHRoZSBlbGVtZW50IGluc3RhbmNlXG4gKiBCVUc6XG4gKiAgIDEpIG1pbi1oZWlnaHQgb24gYSBjb2x1bW4gZmxleCBjb250YWluZXIgd29uw6LCgMKZdCBhcHBseSB0byBpdHMgZmxleCBpdGVtIGNoaWxkcmVuIGluIElFIDEwLTExLlxuICogICAgICBVc2UgaGVpZ2h0IGluc3RlYWQgaWYgcG9zc2libGU7IGhlaWdodCA6IDx4eHg+dmg7XG4gKlxuICogIFRoaXMgd2F5IGFueSBwYWRkaW5nIG9yIGJvcmRlciBzcGVjaWZpZWQgb24gdGhlIGNoaWxkIGVsZW1lbnRzIGFyZVxuICogIGxhaWQgb3V0IGFuZCBkcmF3biBpbnNpZGUgdGhhdCBlbGVtZW50J3Mgc3BlY2lmaWVkIHdpZHRoIGFuZCBoZWlnaHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENTUyhkaXJlY3Rpb24sIHdyYXAgPSBudWxsLCBpbmxpbmUgPSBmYWxzZSkge1xuICByZXR1cm4ge1xuICAgICdkaXNwbGF5JzogaW5saW5lID8gJ2lubGluZS1mbGV4JyA6ICdmbGV4JyxcbiAgICAnYm94LXNpemluZyc6ICdib3JkZXItYm94JyxcbiAgICAnZmxleC1kaXJlY3Rpb24nOiBkaXJlY3Rpb24sXG4gICAgJ2ZsZXgtd3JhcCc6ICEhd3JhcCA/IHdyYXAgOiBudWxsXG4gIH07XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplTGF5b3V0QWxpZ25WYWx1ZShhbGlnbjogc3RyaW5nKSB7XG4gIGFsaWduID0gYWxpZ24gfHwgJ3N0YXJ0IHN0cmV0Y2gnO1xuXG4gIGxldCBbbWFpbkF4aXMsIGNyb3NzQXhpc10gPSBhbGlnbi5zcGxpdCgnICcpO1xuXG4gIHN3aXRjaCAobWFpbkF4aXMpIHtcbiAgICBjYXNlICdjZW50ZXInOlxuICAgIGNhc2UgJ3NwYWNlLWFyb3VuZCc6XG4gICAgY2FzZSAnc3BhY2UtYmV0d2Vlbic6XG4gICAgY2FzZSAnc3BhY2UtZXZlbmx5JzpcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2VuZCc6XG4gICAgY2FzZSAnZmxleC1lbmQnOlxuICAgICAgbWFpbkF4aXMgPSAnZmxleC1lbmQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc3RhcnQnOlxuICAgIGNhc2UgJ2ZsZXgtc3RhcnQnOlxuICAgIGRlZmF1bHQgOlxuICAgICAgbWFpbkF4aXMgPSAnZmxleC1zdGFydCc7ICAvLyBkZWZhdWx0IG1haW4gYXhpc1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBzd2l0Y2ggKGNyb3NzQXhpcykge1xuICAgIGNhc2UgJ3N0YXJ0JzpcbiAgICBjYXNlICdmbGV4LXN0YXJ0JzpcbiAgICAgIGNyb3NzQXhpcyA9ICdmbGV4LXN0YXJ0JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2VsaW5lJzpcbiAgICBjYXNlICdjZW50ZXInOlxuICAgICAgY3Jvc3NBeGlzID0gJ2NlbnRlcic7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdlbmQnOlxuICAgIGNhc2UgJ2ZsZXgtZW5kJzpcbiAgICAgIGNyb3NzQXhpcyA9ICdmbGV4LWVuZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdzdHJldGNoJzpcbiAgICBkZWZhdWx0IDogLy8gJ3N0cmV0Y2gnXG4gICAgICBjcm9zc0F4aXMgPSAnc3RyZXRjaCc7ICAgLy8gZGVmYXVsdCBjcm9zcyBheGlzXG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBbbWFpbkF4aXMsIGNyb3NzQXhpc107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUxheW91dENsYXNzTmFtZShkaXJlY3Rpb246IHN0cmluZywgd3JhcDogc3RyaW5nLCBpc0lubGluZTogYm9vbGVhbiwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNMYXlvdXQnXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIGRpcmVjdGlvbiArICh3cmFwID8gJy0nICsgd3JhcCA6ICcnKSArIChpc0lubGluZSA/ICctaW5saW5lJyA6ICcnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlTGF5b3V0QWxpZ25DbGFzc05hbWUobWFpbkF4aXM6IHN0cmluZywgY3Jvc3NBeGlzOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjTGF5b3V0QWxpZ24nXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIG1haW5BeGlzICsgJy0nICsgY3Jvc3NBeGlzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVMYXlvdXRHYXBDbGFzc05hbWUodmFsdWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiAnZmNMYXlvdXRHYXAnXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIHZhbHVlVG9DbGFzc05hbWUodmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVGbGV4Q2xhc3NOYW1lKGdyb3csIHNocmluaywgYmFzaXMsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjRmxleCdcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgdmFsdWVUb0NsYXNzTmFtZShncm93KSArICctJyArIHZhbHVlVG9DbGFzc05hbWUoc2hyaW5rKSArIChiYXNpcyA/ICctJyArIHZhbHVlVG9DbGFzc05hbWUoYmFzaXMpIDogJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVGbGV4T3JkZXJDbGFzc05hbWUob3JkZXIsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjRmxleE9yZGVyJ1xuICAgICsgKGJyZWFrcG9pbnQgIT09ICdhbGwnID8gJy0tJyArIGJyZWFrcG9pbnQgOiAnJylcbiAgICArICctLScgKyB2YWx1ZVRvQ2xhc3NOYW1lKG9yZGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlRmxleE9mZnNldENsYXNzTmFtZShvZmZzZXQsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjRmxleE9mZnNldCdcbiAgICArIChicmVha3BvaW50ICE9PSAnYWxsJyA/ICctLScgKyBicmVha3BvaW50IDogJycpXG4gICAgKyAnLS0nICsgdmFsdWVUb0NsYXNzTmFtZShvZmZzZXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVGbGV4QWxpZ25DbGFzc05hbWUoYWxpZ24sIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICByZXR1cm4gJ2ZjRmxleEFsaWduJ1xuICAgICsgKGJyZWFrcG9pbnQgIT09ICdhbGwnID8gJy0tJyArIGJyZWFrcG9pbnQgOiAnJylcbiAgICArICctLScgKyB2YWx1ZVRvQ2xhc3NOYW1lKGFsaWduKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlRmxleEZpbGxDbGFzc05hbWUoKSB7XG4gIHJldHVybiAnZmNGbGV4RmlsbCc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUZsZXhTaG93SGlkZUNsYXNzTmFtZShkaXNwbGF5LCBzaG93OiBib29sZWFuLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgcmV0dXJuICdmY1Nob3cnXG4gICAgKyAoYnJlYWtwb2ludCAhPT0gJ2FsbCcgPyAnLS0nICsgYnJlYWtwb2ludCA6ICcnKVxuICAgICsgJy0tJyArIHZhbHVlVG9DbGFzc05hbWUoZGlzcGxheSlcbiAgICArICctLScgKyAoc2hvdyA/ICdzaG93JyA6ICdoaWRlJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZVRvQ2xhc3NOYW1lKHZhbHVlKSB7XG4gIHJldHVybiBTdHJpbmcodmFsdWUpLnJlcGxhY2UoL1teYS16QS1aMC05LV0vLCAnLScpO1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8qKlxuICogVGhlIGZsZXggQVBJIHBlcm1pdHMgMyBvciAxIHBhcnRzIG9mIHRoZSB2YWx1ZTpcbiAqICAgIC0gYGZsZXgtZ3JvdyBmbGV4LXNocmluayBmbGV4LWJhc2lzYCwgb3JcbiAqICAgIC0gYGZsZXgtYmFzaXNgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUJhc2lzKGJhc2lzOiBzdHJpbmcsIGdyb3cgPSAnMScsIHNocmluayA9ICcxJyk6IHN0cmluZ1tdfG51bWJlcltdIHtcbiAgbGV0IHBhcnRzID0gW2dyb3csIHNocmluaywgYmFzaXNdO1xuXG4gIGNvbnN0IGogPSBiYXNpcy5pbmRleE9mKCdjYWxjJyk7XG4gIGlmIChqID4gMCkge1xuICAgIHBhcnRzWzJdID0gX3ZhbGlkYXRlQ2FsY1ZhbHVlKGJhc2lzLnN1YnN0cmluZyhqKS50cmltKCkpO1xuICAgIGNvbnN0IG1hdGNoZXMgPSBiYXNpcy5zdWJzdHIoMCwgaikudHJpbSgpLnNwbGl0KCcgJyk7XG4gICAgaWYgKG1hdGNoZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICBwYXJ0c1swXSA9IG1hdGNoZXNbMF07XG4gICAgICBwYXJ0c1sxXSA9IG1hdGNoZXNbMV07XG4gICAgfVxuICB9IGVsc2UgaWYgKGogPT09IDApIHtcbiAgICBwYXJ0c1syXSA9IF92YWxpZGF0ZUNhbGNWYWx1ZShiYXNpcy50cmltKCkpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBiYXNpcy5zcGxpdCgnICcpO1xuICAgIHBhcnRzID0gKG1hdGNoZXMubGVuZ3RoID09PSAzKSA/IG1hdGNoZXMgOiBbXG4gICAgICBncm93LCBzaHJpbmssIGJhc2lzXG4gICAgXTtcbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuXG4vKipcbiAqIENhbGMgZXhwcmVzc2lvbnMgcmVxdWlyZSB3aGl0ZXNwYWNlIGJlZm9yZSAmIGFmdGVyIGFueSBleHByZXNzaW9uIG9wZXJhdG9yc1xuICogVGhpcyBpcyBhIHNpbXBsZSwgY3J1ZGUgd2hpdGVzcGFjZSBwYWRkaW5nIHNvbHV0aW9uLlxuICogICAtICczIDMgY2FsYygxNWVtICsgMjBweCknXG4gKiAgIC0gY2FsYygxMDAlIC8gNyAqIDIpXG4gKiAgIC0gJ2NhbGMoMTVlbSArIDIwcHgpJ1xuICogICAtICdjYWxjKDE1ZW0rMjBweCknXG4gKiAgIC0gJzM3cHgnXG4gKiAgID0gJzQzJSdcbiAqL1xuZnVuY3Rpb24gX3ZhbGlkYXRlQ2FsY1ZhbHVlKGNhbGM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjYWxjLnJlcGxhY2UoL1tcXHNdL2csICcnKS5yZXBsYWNlKC9bXFwvXFwqXFwrXFwtXS9nLCAnICQmICcpO1xufVxuIiwiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0LCBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBhcHBseUNzc1ByZWZpeGVzIH0gZnJvbSAnLi9hdXRvLXByZWZpeGVyJztcbmltcG9ydCB7IHZhbGlkYXRlVmFsdWUsIGJ1aWxkQ1NTLCBpc0Zsb3dIb3Jpem9udGFsIH0gZnJvbSAnLi9sYXlvdXQtdmFsaWRhdG9yJztcbmltcG9ydCB7XG4gIGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lLCBub3JtYWxpemVMYXlvdXRBbGlnblZhbHVlLCBnZW5lcmF0ZUxheW91dEFsaWduQ2xhc3NOYW1lLFxuICBnZW5lcmF0ZUxheW91dEdhcENsYXNzTmFtZSwgZ2VuZXJhdGVGbGV4Q2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhPcmRlckNsYXNzTmFtZSwgZ2VuZXJhdGVGbGV4T2Zmc2V0Q2xhc3NOYW1lLFxuICBnZW5lcmF0ZUZsZXhBbGlnbkNsYXNzTmFtZSwgZ2VuZXJhdGVGbGV4RmlsbENsYXNzTmFtZSwgZ2VuZXJhdGVGbGV4U2hvd0hpZGVDbGFzc05hbWVcbn0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7IHZhbGlkYXRlQmFzaXMgfSBmcm9tICcuL2Jhc2lzLXZhbGlkYXRvcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJlYWtwb2ludCB7XG4gIGFsaWFzOiBzdHJpbmc7XG4gIG1lZGlhOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNvbnN0IEZMRVhfQ1NTX0RFRkFVTFRfQlJFQUtQT0lOVFM6IEJyZWFrcG9pbnRbXSA9IFtcbiAgeyBhbGlhczogJ2d0LXhzJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDYwMHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC14bCcsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiAxOTE5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LXNtJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDk2MHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC1sZycsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiAxMjc5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LW1kJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDEyODBweCknXSB9LFxuICB7IGFsaWFzOiAnbHQtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LWxnJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDE5MjBweCknXSB9LFxuICB7IGFsaWFzOiAnbHQtc20nLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogNTk5cHgpJ10gfSxcbiAgeyBhbGlhczogJ3hsJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDE5MjBweCknLCAnKG1heC13aWR0aDogNTAwMHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsZycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxMjgwcHgpJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnbWQnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJywgJyhtYXgtd2lkdGg6IDEyNzlweCknXSB9LFxuICB7IGFsaWFzOiAnc20nLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogNjAwcHgpJywgJyhtYXgtd2lkdGg6IDk1OXB4KSddIH0sXG4gIHsgYWxpYXM6ICd4cycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEZMRVhfQ1NTX0JSRUFLUE9JTlRTX1NNQUxMX1RPX0xBUkdFOiBCcmVha3BvaW50W10gPSBbXG4gIHsgYWxpYXM6ICdsdC1zbScsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuICB7IGFsaWFzOiAneHMnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogNTk5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LXhzJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDYwMHB4KSddIH0sXG5cbiAgeyBhbGlhczogJ2x0LW1kJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDk1OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdzbScsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA2MDBweCknLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LXNtJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDk2MHB4KSddIH0sXG5cbiAgeyBhbGlhczogJ2x0LWxnJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDEyNzlweCknXSB9LFxuICB7IGFsaWFzOiAnbWQnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJywgJyhtYXgtd2lkdGg6IDEyNzlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTI4MHB4KSddIH0sXG5cbiAgeyBhbGlhczogJ2x0LXhsJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnbGcnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTI4MHB4KScsICcobWF4LXdpZHRoOiAxOTE5cHgpJ10gfSxcbiAgeyBhbGlhczogJ2d0LWxnJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDE5MjBweCknXSB9LFxuXG4gIHsgYWxpYXM6ICd4bCcsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxOTIwcHgpJywgJyhtYXgtd2lkdGg6IDUwMDBweCknXSB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEZMRVhfQ1NTX0JSRUFLUE9JTlRTID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oJ2ZsZXhfY3NzX2JyZWFrcG9pbnRzJyk7XG5cbmV4cG9ydCB0eXBlIFN0eWxlRGVmaW5pdGlvbiA9IHN0cmluZyB8IHsgW3Byb3BlcnR5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBudWxsIH07XG5cbmV4cG9ydCBjbGFzcyBGbGV4Q3NzU3R5bGVFbGVtZW50IHtcbiAgcHVibGljIHN0b3JhZ2U6IHsgW3Byb3BlcnR5OiBzdHJpbmddOiB7IFtwcm9wZXJ0eTogc3RyaW5nXTogVGV4dCB9IH0gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc3R5bGU6IEhUTUxTdHlsZUVsZW1lbnQsXG4gICkge31cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZsZXhDc3NTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBsYXlvdXQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQ7XG5cbiAgcHJpdmF0ZSBmbGV4OiBGbGV4Q3NzU3R5bGVFbGVtZW50O1xuXG4gIHByaXZhdGUgZmlsbDogRmxleENzc1N0eWxlRWxlbWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYyxcbiAgICBASW5qZWN0KEZMRVhfQ1NTX0JSRUFLUE9JTlRTKSBwcml2YXRlIGJyZWFrcG9pbnRzLFxuICApIHtcbiAgICB0aGlzLmluaXRMYXlvdXQoKTtcbiAgICB0aGlzLmluaXRGbGV4KCk7XG4gICAgdGhpcy5pbml0RmlsbCgpO1xuICB9XG5cbiAgaW5pdExheW91dCgpIHtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG5cbiAgICBzdHlsZS5pZCA9ICdmYy1sYXlvdXQnO1xuXG4gICAgdGhpcy5kb2MuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICB0aGlzLmxheW91dCA9IG5ldyBGbGV4Q3NzU3R5bGVFbGVtZW50KHN0eWxlKTtcbiAgfVxuXG4gIGluaXRGbGV4KCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgIHN0eWxlLmlkID0gJ2ZjLWZsZXgnO1xuXG4gICAgdGhpcy5kb2MuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICB0aGlzLmZsZXggPSBuZXcgRmxleENzc1N0eWxlRWxlbWVudChzdHlsZSk7XG4gIH1cblxuICBpbml0RmlsbCgpIHtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG5cbiAgICBzdHlsZS5pZCA9ICdmYy1maWxsJztcblxuICAgIHRoaXMuZG9jLmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuXG4gICAgdGhpcy5maWxsID0gbmV3IEZsZXhDc3NTdHlsZUVsZW1lbnQoc3R5bGUpO1xuICB9XG5cbiAgYWRkTGF5b3V0KGxheW91dDogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgICBjb25zdCBbZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZV0gPSB2YWxpZGF0ZVZhbHVlKGxheW91dCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBnZW5lcmF0ZUxheW91dENsYXNzTmFtZShkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkxheW91dFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSBidWlsZENTUyhkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lKTtcblxuICAgICAgdGhpcy5hZGRUb0xheW91dFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZExheW91dEFsaWduKGxheW91dDogc3RyaW5nLCBsYXlvdXRCcmVha3BvaW50OiBzdHJpbmcsIGFsaWduOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgW21haW5BeGlzLCBjcm9zc0F4aXNdID0gbm9ybWFsaXplTGF5b3V0QWxpZ25WYWx1ZShhbGlnbik7XG5cbiAgICBjb25zdCBsYXlvdXRBbGlnbkNsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0QWxpZ25DbGFzc05hbWUobWFpbkF4aXMsIGNyb3NzQXhpcywgYnJlYWtwb2ludCk7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5MYXlvdXRTdG9yYWdlKGxheW91dEFsaWduQ2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgICdqdXN0aWZ5LWNvbnRlbnQnOiBtYWluQXhpcyxcbiAgICAgIH07XG5cbiAgICAgIHN3aXRjaCAoY3Jvc3NBeGlzKSB7XG4gICAgICAgIGNhc2UgJ2Jhc2VsaW5lJzpcbiAgICAgICAgICBzdHlsZVsnYWxpZ24taXRlbXMnXSA9IGNyb3NzQXhpcztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBzdHlsZVsnYWxpZ24taXRlbXMnXSA9IHN0eWxlWydhbGlnbi1jb250ZW50J10gPSBjcm9zc0F4aXM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWRkVG9MYXlvdXRTdG9yYWdlKGxheW91dEFsaWduQ2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgaWYgKGNyb3NzQXhpcyA9PT0gJ3N0cmV0Y2gnKSB7XG4gICAgICBjb25zdCBbZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZV0gPSB2YWxpZGF0ZVZhbHVlKGxheW91dCk7XG5cbiAgICAgIGNvbnN0IGxheW91dENsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUsIGxheW91dEJyZWFrcG9pbnQpO1xuXG4gICAgICBjb25zdCBjbGFzc05hbWUgPSBsYXlvdXRBbGlnbkNsYXNzTmFtZSArICcuJyArIGxheW91dENsYXNzTmFtZTtcblxuICAgICAgaWYgKCF0aGlzLmhhc0luTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlID0gaXNGbG93SG9yaXpvbnRhbChsYXlvdXQpID8geyAnbWF4LWhlaWdodCc6ICcxMDAlJyB9IDogeyAnbWF4LXdpZHRoJzogJzEwMCUnIH07XG5cbiAgICAgICAgdGhpcy5hZGRUb0xheW91dFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCwgW2xheW91dEJyZWFrcG9pbnRdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGF5b3V0QWxpZ25DbGFzc05hbWU7XG4gIH1cblxuICBhZGRMYXlvdXRHYXAobGF5b3V0OiBzdHJpbmcsIGxheW91dEJyZWFrcG9pbnQ6IHN0cmluZywgdmFsdWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICB2YWx1ZSA9IHZhbHVlIHx8ICcwJztcblxuICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgIGNvbnN0IGxheW91dENsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUsIGxheW91dEJyZWFrcG9pbnQpO1xuXG4gICAgY29uc3QgbGF5b3V0R2FwQ2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRHYXBDbGFzc05hbWUodmFsdWUsIGJyZWFrcG9pbnQpO1xuXG4gICAgY29uc3QgY2xhc3NOYW1lID0gbGF5b3V0R2FwQ2xhc3NOYW1lICsgJy4nICsgbGF5b3V0Q2xhc3NOYW1lICsgJyA+ICo6bm90KDpsYXN0LWNoaWxkKSc7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0gaXNGbG93SG9yaXpvbnRhbChsYXlvdXQpID8geyAnbWFyZ2luLXJpZ2h0JzogdmFsdWUgfSA6IHsgJ21hcmdpbi1ib3R0b20nOiB2YWx1ZSB9O1xuXG4gICAgICB0aGlzLmFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgIH1cblxuICAgIHJldHVybiBsYXlvdXRHYXBDbGFzc05hbWU7XG4gIH1cblxuICBhZGRGbGV4KGxheW91dDogc3RyaW5nLCBsYXlvdXRCcmVha3BvaW50OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZywgZ3Jvdz8sIHNocmluaz8pIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoJzsnLCAnJyk7XG5cbiAgICBsZXQgW3RoZUdyb3csIHRoZVNocmluaywgdGhlQmFzaXNdID0gdmFsaWRhdGVCYXNpcyh2YWx1ZSwgZ3Jvdywgc2hyaW5rKTtcblxuICAgIHRoZUdyb3cgPSAodGhlR3JvdyA9PT0gJzAnKSA/IDAgOiB0aGVHcm93O1xuICAgIHRoZVNocmluayA9ICh0aGVTaHJpbmsgPT09ICcwJykgPyAwIDogdGhlU2hyaW5rO1xuXG4gICAgLy8gZmxleC1iYXNpcyBhbGxvd3MgeW91IHRvIHNwZWNpZnkgdGhlIGluaXRpYWwvc3RhcnRpbmcgbWFpbi1heGlzIHNpemUgb2YgdGhlIGVsZW1lbnQsXG4gICAgLy8gYmVmb3JlIGFueXRoaW5nIGVsc2UgaXMgY29tcHV0ZWQuIEl0IGNhbiBlaXRoZXIgYmUgYSBwZXJjZW50YWdlIG9yIGFuIGFic29sdXRlIHZhbHVlLlxuICAgIC8vIEl0IGlzLCBob3dldmVyLCBub3QgdGhlIGJyZWFraW5nIHBvaW50IGZvciBmbGV4LWdyb3cvc2hyaW5rIHByb3BlcnRpZXNcbiAgICAvL1xuICAgIC8vIGZsZXgtZ3JvdyBjYW4gYmUgc2VlbiBhcyB0aGlzOlxuICAgIC8vICAgMDogRG8gbm90IHN0cmV0Y2guIEVpdGhlciBzaXplIHRvIGVsZW1lbnQncyBjb250ZW50IHdpZHRoLCBvciBvYmV5ICdmbGV4LWJhc2lzJy5cbiAgICAvLyAgIDE6IChEZWZhdWx0IHZhbHVlKS4gU3RyZXRjaDsgd2lsbCBiZSB0aGUgc2FtZSBzaXplIHRvIGFsbCBvdGhlciBmbGV4IGl0ZW1zIG9uXG4gICAgLy8gICAgICAgdGhlIHNhbWUgcm93IHNpbmNlIHRoZXkgaGF2ZSBhIGRlZmF1bHQgdmFsdWUgb2YgMS5cbiAgICAvLyAgIMOiwonCpTIgKGludGVnZXIgbik6IFN0cmV0Y2guIFdpbGwgYmUgbiB0aW1lcyB0aGUgc2l6ZSBvZiBvdGhlciBlbGVtZW50c1xuICAgIC8vICAgICAgd2l0aCAnZmxleC1ncm93OiAxJyBvbiB0aGUgc2FtZSByb3cuXG5cbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICdib3gtc2l6aW5nJzogJ2JvcmRlci1ib3gnLFxuICAgIH07XG5cbiAgICBzd2l0Y2ggKHRoZUJhc2lzIHx8ICcnKSB7XG4gICAgICBjYXNlICcnOlxuICAgICAgICBzdHlsZVsnZmxleCddID0gYCR7dGhlR3Jvd30gJHt0aGVTaHJpbmt9IDAuMDAwMDAwMDAxcHhgO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2luaXRpYWwnOiAgIC8vIGRlZmF1bHRcbiAgICAgIGNhc2UgJ25vZ3Jvdyc6XG4gICAgICAgIHRoZUdyb3cgPSAwO1xuICAgICAgICBzdHlsZVsnZmxleCddID0gYDAgMSBhdXRvYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdncm93JzpcbiAgICAgICAgc3R5bGVbJ2ZsZXgnXSA9IGAxIDEgMTAwJWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbm9zaHJpbmsnOlxuICAgICAgICB0aGVTaHJpbmsgPSAwO1xuICAgICAgICBzdHlsZVsnZmxleCddID0gYDEgMCBhdXRvYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhdXRvJzpcbiAgICAgICAgc3R5bGVbJ2ZsZXgnXSA9IGAke3RoZUdyb3d9ICR7dGhlU2hyaW5rfSBhdXRvYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdub25lJzpcbiAgICAgICAgdGhlR3JvdyA9IDA7XG4gICAgICAgIHRoZVNocmluayA9IDA7XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgMCAwIGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnN0IGlzQ2FsYyA9IFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZignY2FsYycpID4gLTE7XG4gICAgICAgIGNvbnN0IGlzUGVyY2VudCA9ICFpc0NhbGMgJiYgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCclJykgPiAtMTtcblxuICAgICAgICBjb25zdCBpc1ZhbHVlID0gaXNDYWxjIHx8IGlzUGVyY2VudCB8fFxuICAgICAgICAgIFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZigncHgnKSA+IC0xIHx8XG4gICAgICAgICAgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdlbScpID4gLTEgfHxcbiAgICAgICAgICBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ3Z3JykgPiAtMSB8fFxuICAgICAgICAgIFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZigndmgnKSA+IC0xO1xuXG4gICAgICAgIC8vIERlZmF1bHRzIHRvIHBlcmNlbnRhZ2Ugc2l6aW5nIHVubGVzcyBgcHhgIGlzIGV4cGxpY2l0bHkgc2V0XG4gICAgICAgIGlmICghaXNWYWx1ZSAmJiAhaXNQZXJjZW50ICYmICFpc05hTih0aGVCYXNpcyBhcyBhbnkpKSB7XG4gICAgICAgICAgdGhlQmFzaXMgPSB0aGVCYXNpcyArICclJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGVCYXNpcyA9PT0gJzBweCcpIHtcbiAgICAgICAgICB0aGVCYXNpcyA9ICcwJSc7XG4gICAgICAgIH1cblxuICAgICAgICBzdHlsZVsnZmxleC1ncm93J10gPSBgJHt0aGVHcm93fWA7XG4gICAgICAgIHN0eWxlWydmbGV4LXNocmluayddID0gYCR7dGhlU2hyaW5rfWA7XG4gICAgICAgIHN0eWxlWydmbGV4LWJhc2lzJ10gPSBzdHlsZVsnbWluLXdpZHRoJ10gPSBzdHlsZVsnbWF4LXdpZHRoJ10gPSBpc1ZhbHVlID8gYCR7dGhlQmFzaXN9YCA6ICcxMDAlJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY29uc3QgZmxleENsYXNzTmFtZSA9IGdlbmVyYXRlRmxleENsYXNzTmFtZSh0aGVHcm93LCB0aGVTaHJpbmssIHRoZUJhc2lzLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGZsZXhDbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICB0aGlzLmFkZFRvRmxleFN0b3JhZ2UoZmxleENsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQpO1xuICAgIH1cblxuICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgIGNvbnN0IGxheW91dENsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUsIGxheW91dEJyZWFrcG9pbnQpO1xuXG4gICAgY29uc3QgY2xhc3NOYW1lID0gZmxleENsYXNzTmFtZSArICcuJyArIGxheW91dENsYXNzTmFtZTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IG1heCA9IGlzRmxvd0hvcml6b250YWwoZGlyZWN0aW9uKSA/ICdtYXgtd2lkdGgnIDogJ21heC1oZWlnaHQnO1xuICAgICAgY29uc3QgbWluID0gaXNGbG93SG9yaXpvbnRhbChkaXJlY3Rpb24pID8gJ21pbi13aWR0aCcgOiAnbWluLWhlaWdodCc7XG5cbiAgICAgIGNvbnN0IHVzaW5nQ2FsYyA9IChTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ2NhbGMnKSA+IC0xKSB8fCAodGhlQmFzaXMgPT09ICdhdXRvJyk7XG4gICAgICBjb25zdCBpc1B4ID0gU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdweCcpID4gLTEgfHwgdXNpbmdDYWxjO1xuXG4gICAgICAvLyBtYWtlIGJveCBpbmZsZXhpYmxlIHdoZW4gc2hyaW5rIGFuZCBncm93IGFyZSBib3RoIHplcm9cbiAgICAgIC8vIHNob3VsZCBub3Qgc2V0IGEgbWluIHdoZW4gdGhlIGdyb3cgaXMgemVyb1xuICAgICAgLy8gc2hvdWxkIG5vdCBzZXQgYSBtYXggd2hlbiB0aGUgc2hyaW5rIGlzIHplcm9cbiAgICAgIGNvbnN0IGlzRml4ZWQgPSAhdGhlR3JvdyAmJiAhdGhlU2hyaW5rO1xuXG4gICAgICBjb25zdCBsYXlvdXRTdHlsZSA9IHt9O1xuXG4gICAgICBsYXlvdXRTdHlsZVttaW5dID0gKHRoZUJhc2lzID09PSAnMCUnKSA/IDAgOiBpc0ZpeGVkIHx8IChpc1B4ICYmIHRoZUdyb3cpID8gdGhlQmFzaXMgOiBudWxsO1xuICAgICAgbGF5b3V0U3R5bGVbbWF4XSA9ICh0aGVCYXNpcyA9PT0gJzAlJykgPyAwIDogaXNGaXhlZCB8fCAoIXVzaW5nQ2FsYyAmJiB0aGVTaHJpbmspID8gdGhlQmFzaXMgOiBudWxsO1xuXG4gICAgICB0aGlzLmFkZFRvRmxleFN0b3JhZ2UoY2xhc3NOYW1lLCBsYXlvdXRTdHlsZSwgYnJlYWtwb2ludCwgW2xheW91dEJyZWFrcG9pbnRdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmxleENsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXhPcmRlcihvcmRlciwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gICAgb3JkZXIgPSBwYXJzZUludChvcmRlciwgMTApO1xuXG4gICAgb3JkZXIgPSBpc05hTihvcmRlcikgPyAwIDogb3JkZXI7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBnZW5lcmF0ZUZsZXhPcmRlckNsYXNzTmFtZShvcmRlciwgYnJlYWtwb2ludCk7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5GbGV4U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHsnb3JkZXInOiBvcmRlcn07XG5cbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkRmxleE9mZnNldChsYXlvdXQ6IHN0cmluZywgbGF5b3V0QnJlYWtwb2ludDogc3RyaW5nLCBvZmZzZXQsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IGlzUGVyY2VudCA9IFN0cmluZyhvZmZzZXQpLmluZGV4T2YoJyUnKSA+IC0xO1xuICAgIGNvbnN0IGlzUHggPSBTdHJpbmcob2Zmc2V0KS5pbmRleE9mKCdweCcpID4gLTE7XG5cbiAgICBpZiAoIWlzUHggJiYgIWlzUGVyY2VudCAmJiAhaXNOYU4ob2Zmc2V0KSkge1xuICAgICAgb2Zmc2V0ID0gb2Zmc2V0ICsgJyUnO1xuICAgIH1cblxuICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgIGNvbnN0IG9mZnNldENsYXNzTmFtZSA9IGdlbmVyYXRlRmxleE9mZnNldENsYXNzTmFtZShvZmZzZXQsIGJyZWFrcG9pbnQpO1xuXG4gICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBvZmZzZXRDbGFzc05hbWUgKyAnLicgKyBsYXlvdXRDbGFzc05hbWU7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5GbGV4U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IGlzRmxvd0hvcml6b250YWwoZGlyZWN0aW9uKSA/IHsnbWFyZ2luLWxlZnQnOiBgJHtvZmZzZXR9YH0gOiB7J21hcmdpbi10b3AnOiBgJHtvZmZzZXR9YH07XG5cbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXRDbGFzc05hbWU7XG4gIH1cblxuICBhZGRGbGV4QWxpZ24oYWxpZ24sIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGFsaWduID0gYWxpZ24gfHwgJ3N0cmV0Y2gnO1xuXG4gICAgLy8gQ3Jvc3MtYXhpc1xuICAgIHN3aXRjaCAoYWxpZ24pIHtcbiAgICAgIGNhc2UgJ3N0YXJ0JzpcbiAgICAgICAgYWxpZ24gPSAnZmxleC1zdGFydCc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZW5kJzpcbiAgICAgICAgYWxpZ24gPSAnZmxleC1lbmQnO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBnZW5lcmF0ZUZsZXhBbGlnbkNsYXNzTmFtZShhbGlnbiwgYnJlYWtwb2ludCk7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5GbGV4U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHsnYWxpZ24tc2VsZic6IGFsaWdufTtcblxuICAgICAgdGhpcy5hZGRUb0ZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxuICBhZGRGbGV4RmlsbCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBnZW5lcmF0ZUZsZXhGaWxsQ2xhc3NOYW1lKCk7XG5cbiAgICBpZiAoIXRoaXMuaGFzSW5GaWxsU3RvcmFnZShjbGFzc05hbWUsICdhbGwnKSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgICdtYXJnaW4nOiAwLFxuICAgICAgICAnd2lkdGgnOiAnMTAwJScsXG4gICAgICAgICdoZWlnaHQnOiAnMTAwJScsXG4gICAgICAgICdtaW4td2lkdGgnOiAnMTAwJScsXG4gICAgICAgICdtaW4taGVpZ2h0JzogJzEwMCUnLFxuICAgICAgfTtcblxuICAgICAgdGhpcy5hZGRUb0ZpbGxTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsICdhbGwnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkU2hvd0hpZGUoZGlzcGxheTogc3RyaW5nLCBzaG93OiBib29sZWFuLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBnZW5lcmF0ZUZsZXhTaG93SGlkZUNsYXNzTmFtZShkaXNwbGF5LCBzaG93LCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZpbGxTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgICAnZGlzcGxheSc6IHNob3cgPyBkaXNwbGF5IHx8ICdibG9jaycgOiAnbm9uZScsXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmFkZFRvRmlsbFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzSW5MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5oYXNJblN0b3JhZ2UodGhpcy5sYXlvdXQsIGNsYXNzTmFtZSwgYnJlYWtwb2ludCk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgc3R5bGU6IFN0eWxlRGVmaW5pdGlvbiwgYnJlYWtwb2ludDogc3RyaW5nLCBjdXN0b21CcmVha3BvaW50cz86IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkVG9TdG9yYWdlKHRoaXMubGF5b3V0LCBjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBjdXN0b21CcmVha3BvaW50cyk7XG4gIH1cblxuICBwcml2YXRlIGhhc0luRmxleFN0b3JhZ2UoY2xhc3NOYW1lOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc0luU3RvcmFnZSh0aGlzLmZsZXgsIGNsYXNzTmFtZSwgYnJlYWtwb2ludCk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRvRmxleFN0b3JhZ2UoY2xhc3NOYW1lOiBzdHJpbmcsIHN0eWxlOiBTdHlsZURlZmluaXRpb24sIGJyZWFrcG9pbnQ6IHN0cmluZywgY3VzdG9tQnJlYWtwb2ludHM/OiBzdHJpbmdbXSkge1xuICAgIHJldHVybiB0aGlzLmFkZFRvU3RvcmFnZSh0aGlzLmZsZXgsIGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIGN1c3RvbUJyZWFrcG9pbnRzKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzSW5GaWxsU3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzSW5TdG9yYWdlKHRoaXMuZmlsbCwgY2xhc3NOYW1lLCBicmVha3BvaW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9GaWxsU3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgc3R5bGU6IFN0eWxlRGVmaW5pdGlvbiwgYnJlYWtwb2ludDogc3RyaW5nLCBjdXN0b21CcmVha3BvaW50cz86IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkVG9TdG9yYWdlKHRoaXMuZmlsbCwgY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCwgY3VzdG9tQnJlYWtwb2ludHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNJblN0b3JhZ2Uoc3R5bGVFbGVtZW50OiBGbGV4Q3NzU3R5bGVFbGVtZW50LCBjbGFzc05hbWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhKHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdICYmIHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdW2NsYXNzTmFtZV0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRUb1N0b3JhZ2UoXG4gICAgc3R5bGVFbGVtZW50OiBGbGV4Q3NzU3R5bGVFbGVtZW50LCBjbGFzc05hbWU6IHN0cmluZywgc3R5bGU6IFN0eWxlRGVmaW5pdGlvbiwgYnJlYWtwb2ludDogc3RyaW5nLCBjdXN0b21CcmVha3BvaW50cz86IHN0cmluZ1tdKSB7XG4gICAgY3VzdG9tQnJlYWtwb2ludHMgPSBjdXN0b21CcmVha3BvaW50cyB8fCBbXTtcblxuICAgIGNvbnN0IHN0eWxlcyA9IGFwcGx5Q3NzUHJlZml4ZXMoc3R5bGUpO1xuXG4gICAgY29uc3QgY3NzID0gdGhpcy5nZW5lcmF0ZUNzcyhzdHlsZXMpO1xuXG4gICAgaWYgKGNzcyAhPT0gJycpIHtcbiAgICAgIGNvbnN0IGNsYXNzQ3NzID0gJy4nICsgY2xhc3NOYW1lICsgJyB7ICcgKyBjc3MgKyAnIH0nO1xuXG4gICAgICBjb25zdCBjc3NFbGVtZW50ID0gdGhpcy5kb2MuY3JlYXRlVGV4dE5vZGUodGhpcy5hZGRCcmVha3BvaW50cyhbYnJlYWtwb2ludF0uY29uY2F0KGN1c3RvbUJyZWFrcG9pbnRzKSwgY2xhc3NDc3MpKTtcblxuICAgICAgaWYgKCFzdHlsZUVsZW1lbnQuc3RvcmFnZVticmVha3BvaW50XSkge1xuICAgICAgICBzdHlsZUVsZW1lbnQuc3RvcmFnZVticmVha3BvaW50XSA9IHt9O1xuICAgICAgfVxuXG4gICAgICBzdHlsZUVsZW1lbnQuc3RvcmFnZVticmVha3BvaW50XVtjbGFzc05hbWVdID0gY3NzRWxlbWVudDtcblxuICAgICAgdGhpcy5yZW9yZGVyVGV4dEVsZW1lbnRzKHN0eWxlRWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW9yZGVyVGV4dEVsZW1lbnRzKHN0eWxlRWxlbWVudDogRmxleENzc1N0eWxlRWxlbWVudCkge1xuICAgIGxldCBwb3NpdGlvbiA9IHRoaXMucmVvcmRlckJyZWFrcG9pbnRFbGVtZW50cyhzdHlsZUVsZW1lbnQsICdhbGwnKTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIHBvc2l0aW9uID0gdGhpcy5yZW9yZGVyQnJlYWtwb2ludEVsZW1lbnRzKHN0eWxlRWxlbWVudCwgYnJlYWtwb2ludC5hbGlhcywgcG9zaXRpb24pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlb3JkZXJCcmVha3BvaW50RWxlbWVudHMoc3R5bGVFbGVtZW50OiBGbGV4Q3NzU3R5bGVFbGVtZW50LCBicmVha3BvaW50OiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIgPSAwKSB7XG4gICAgY29uc3QgYnJlYWtwb2ludEVsZW1lbnRzID0gc3R5bGVFbGVtZW50LnN0b3JhZ2VbYnJlYWtwb2ludF07XG5cbiAgICBpZiAoIWJyZWFrcG9pbnRFbGVtZW50cykge1xuICAgICAgcmV0dXJuIHBvc2l0aW9uO1xuICAgIH1cblxuICAgIE9iamVjdC5rZXlzKGJyZWFrcG9pbnRFbGVtZW50cykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgaWYgKHN0eWxlRWxlbWVudC5zdHlsZS5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgc3R5bGVFbGVtZW50LnN0eWxlLmluc2VydEJlZm9yZShicmVha3BvaW50RWxlbWVudHNba2V5XSwgc3R5bGVFbGVtZW50LnN0eWxlLmNoaWxkcmVuW3Bvc2l0aW9uXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHlsZUVsZW1lbnQuc3R5bGUuYXBwZW5kQ2hpbGQoYnJlYWtwb2ludEVsZW1lbnRzW2tleV0pO1xuICAgICAgfVxuXG4gICAgICArK3Bvc2l0aW9uO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBvc2l0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZUNzcyhzdHlsZXM6IE9iamVjdCkge1xuICAgIGNvbnN0IGNzcyA9IFtdO1xuXG4gICAgT2JqZWN0LmtleXMoc3R5bGVzKS5zb3J0KCkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gQXJyYXkuaXNBcnJheShzdHlsZXNba2V5XSkgPyBzdHlsZXNba2V5XSA6IFtzdHlsZXNba2V5XV07XG5cbiAgICAgIHZhbHVlcy5zb3J0KCk7XG5cbiAgICAgIHZhbHVlcy5mb3JFYWNoKHZhbHVlID0+IHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSAnJykge1xuICAgICAgICAgIGNzcy5wdXNoKGtleSArICc6ICcgKyB2YWx1ZSArICc7Jyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNzcy5qb2luKCcgJyk7XG4gIH1cblxuICBwcml2YXRlIGFkZEJyZWFrcG9pbnRzKGJyZWFrcG9pbnRzQWxpYXNlczogc3RyaW5nW10sIGNzczogc3RyaW5nKSB7XG4gICAgYnJlYWtwb2ludHNBbGlhc2VzID0gYnJlYWtwb2ludHNBbGlhc2VzLmZpbHRlcihicmVha3BvaW50ID0+IGJyZWFrcG9pbnQgIT09ICdhbGwnKTtcblxuICAgIGlmICghYnJlYWtwb2ludHNBbGlhc2VzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGNzcztcbiAgICB9XG5cbiAgICBsZXQgdGhlQnJlYWtwb2ludHMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHNcbiAgICAgIC5maWx0ZXIoYnJlYWtwb2ludCA9PiBicmVha3BvaW50c0FsaWFzZXMuaW5kZXhPZihicmVha3BvaW50LmFsaWFzKSA+PSAwKVxuICAgICAgLmZvckVhY2goYnJlYWtwb2ludCA9PiB0aGVCcmVha3BvaW50cyA9IHRoZUJyZWFrcG9pbnRzLmNvbmNhdChicmVha3BvaW50Lm1lZGlhKSk7XG5cbiAgICB0aGVCcmVha3BvaW50cyA9IHRoZUJyZWFrcG9pbnRzLmZpbHRlcigodmFsdWUsIGluZGV4LCBzZWxmKSA9PiBzZWxmLmluZGV4T2YodmFsdWUpID09PSBpbmRleCk7XG5cbiAgICByZXR1cm4gJ0BtZWRpYSAnICsgdGhlQnJlYWtwb2ludHMuam9pbignIGFuZCAnKSArICcgeyAnICsgY3NzICsgJyB9JztcbiAgfVxufVxuIiwiaW1wb3J0IHsgRWxlbWVudFJlZiwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlRGlyZWN0aXZlIHtcbiAgcHJpdmF0ZSBjbGFzc05hbWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByb3RlY3RlZCByZW5kZXJlcjogUmVuZGVyZXIyLFxuICApIHtcbiAgfVxuXG4gIHNldENsYXNzTmFtZXMoY2xhc3NOYW1lczogc3RyaW5nW10pIHtcbiAgICBjbGFzc05hbWVzID0gY2xhc3NOYW1lcy5maWx0ZXIoKHZhbHVlLCBpbmRleCwgc2VsZikgPT4gc2VsZi5pbmRleE9mKHZhbHVlKSA9PT0gaW5kZXgpO1xuXG4gICAgY2xhc3NOYW1lcy5mb3JFYWNoKGNsYXNzTmFtZSA9PiB0aGlzLmFkZENsYXNzTmFtZShjbGFzc05hbWUpKTtcblxuICAgIHRoaXMuY2xhc3NOYW1lc1xuICAgICAgLmZpbHRlcihjbGFzc05hbWUgPT4gY2xhc3NOYW1lcy5pbmRleE9mKGNsYXNzTmFtZSkgPCAwKVxuICAgICAgLmZvckVhY2goY2xhc3NOYW1lID0+IHRoaXMucmVtb3ZlQ2xhc3NOYW1lKGNsYXNzTmFtZSkpO1xuXG4gICAgdGhpcy5jbGFzc05hbWVzID0gY2xhc3NOYW1lcztcbiAgfVxuXG4gIGFkZENsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIGNsYXNzTmFtZSk7XG4gIH1cblxuICByZW1vdmVDbGFzc05hbWUoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBjbGFzc05hbWUpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBSZW5kZXJlcjIsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNMYXlvdXRdLFxuICAgIFtmY0xheW91dC54c10sIFtmY0xheW91dC5zbV0sIFtmY0xheW91dC5tZF0sIFtmY0xheW91dC5sZ10sIFtmY0xheW91dC54bF0sXG4gICAgW2ZjTGF5b3V0Lmx0LXNtXSwgW2ZjTGF5b3V0Lmx0LW1kXSwgW2ZjTGF5b3V0Lmx0LWxnXSwgW2ZjTGF5b3V0Lmx0LXhsXSxcbiAgICBbZmNMYXlvdXQuZ3QteHNdLCBbZmNMYXlvdXQuZ3Qtc21dLCBbZmNMYXlvdXQuZ3QtbWRdLCBbZmNMYXlvdXQuZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIExheW91dERpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICByZWFkb25seSBmY1ZhbHVlcyA9IHt9O1xuXG4gIHJlYWRvbmx5IG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIEBJbnB1dCgnZmNMYXlvdXQnKSAgICAgICAgc2V0IGxheW91dCh2YWwpICAgICB7IHRoaXMuZmNWYWx1ZXNbJ2FsbCddID0gdmFsOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IGxheW91dCgpICAgICAgICB7IHJldHVybiB0aGlzLmZjVmFsdWVzWydhbGwnXTsgfVxuXG4gIEBJbnB1dCgnZmNMYXlvdXQueHMnKSAgICAgc2V0IGxheW91dFhzKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5zbScpICAgICBzZXQgbGF5b3V0U20odmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0Lm1kJykgICAgIHNldCBsYXlvdXRNZCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydtZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQubGcnKSAgICAgc2V0IGxheW91dExnKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC54bCcpICAgICBzZXQgbGF5b3V0WGwodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneGwnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNMYXlvdXQuZ3QteHMnKSAgc2V0IGxheW91dEd0WHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXhzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5ndC1zbScpICBzZXQgbGF5b3V0R3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0Lmd0LW1kJykgIHNldCBsYXlvdXRHdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQuZ3QtbGcnKSAgc2V0IGxheW91dEd0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LWxnJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjTGF5b3V0Lmx0LXNtJykgIHNldCBsYXlvdXRMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXQubHQtbWQnKSAgc2V0IGxheW91dEx0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dC5sdC1sZycpICBzZXQgbGF5b3V0THRMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0Lmx0LXhsJykgIHNldCBsYXlvdXRMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gdmFsOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICByZWxvYWQoKSB7XG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKHRoaXMuc2VydmljZS5hZGRMYXlvdXQodGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludCkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuXG4gICAgdGhpcy5vYnNlcnZlciQubmV4dCh0aGlzLmZjVmFsdWVzKTtcbiAgfVxuXG4gIGFkZE5ld0JyZWFrcG9pbnRzKGJyZWFrcG9pbnRzOiBzdHJpbmdbXSwgZGVmYXVsdFZhbHVlPykge1xuICAgIGJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBpZiAoIXRoaXMuZmNWYWx1ZXNbYnJlYWtwb2ludF0pIHtcbiAgICAgICAgdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICBnZXQgYnJlYWtwb2ludHMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZmNWYWx1ZXMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgSW5wdXQsIFJlbmRlcmVyMiwgT3B0aW9uYWwsIFNlbGYsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjTGF5b3V0QWxpZ25dLFxuICAgIFtmY0xheW91dEFsaWduLnhzXSwgW2ZjTGF5b3V0QWxpZ24uc21dLCBbZmNMYXlvdXRBbGlnbi5tZF0sIFtmY0xheW91dEFsaWduLmxnXSxbZmNMYXlvdXRBbGlnbi54bF0sXG4gICAgW2ZjTGF5b3V0QWxpZ24ubHQtc21dLCBbZmNMYXlvdXRBbGlnbi5sdC1tZF0sIFtmY0xheW91dEFsaWduLmx0LWxnXSwgW2ZjTGF5b3V0QWxpZ24ubHQteGxdLFxuICAgIFtmY0xheW91dEFsaWduLmd0LXhzXSwgW2ZjTGF5b3V0QWxpZ24uZ3Qtc21dLCBbZmNMYXlvdXRBbGlnbi5ndC1tZF0sIFtmY0xheW91dEFsaWduLmd0LWxnXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBMYXlvdXRBbGlnbkRpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIGZjVmFsdWVzID0ge307XG5cbiAgb2JzZXJ2ZXIkID0gbmV3IFJlcGxheVN1YmplY3QoMSk7XG5cbiAgQElucHV0KCdmY0xheW91dEFsaWduJykgICAgICAgc2V0IGFsaWduKHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLnhzJykgICAgc2V0IGFsaWduWHModmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24uc20nKSAgICBzZXQgYWxpZ25TbSh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5tZCcpICAgIHNldCBhbGlnbk1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmxnJykgICAgc2V0IGFsaWduTGcodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24ueGwnKSAgICBzZXQgYWxpZ25YbCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmd0LXhzJykgc2V0IGFsaWduR3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24uZ3Qtc20nKSBzZXQgYWxpZ25HdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5ndC1tZCcpIHNldCBhbGlnbkd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmd0LWxnJykgc2V0IGFsaWduR3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5sdC1zbScpIHNldCBhbGlnbkx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEFsaWduLmx0LW1kJykgc2V0IGFsaWduTHRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0QWxpZ24ubHQtbGcnKSBzZXQgYWxpZ25MdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRBbGlnbi5sdC14bCcpIHNldCBhbGlnbkx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSB2YWw7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGVwZW5kc09uTGF5b3V0KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMubGF5b3V0VmFsdWVzKS5mb3JFYWNoKGxheW91dEJyZWFrcG9pbnQgPT4ge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goXG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLmFkZExheW91dEFsaWduKHRoaXMubGF5b3V0VmFsdWVzW2xheW91dEJyZWFrcG9pbnRdLCBsYXlvdXRCcmVha3BvaW50LCB0aGlzLmZjVmFsdWVzW2JyZWFrcG9pbnRdLCBicmVha3BvaW50KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgZGVwZW5kc09uTGF5b3V0KCkge1xuICAgIGlmICh0aGlzLmxheW91dCkge1xuICAgICAgdGhpcy5sYXlvdXQuYWRkTmV3QnJlYWtwb2ludHModGhpcy5icmVha3BvaW50cywgJ3JvdycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICAgIHRoaXMuYWRkQ2xhc3NOYW1lKHRoaXMuc2VydmljZS5hZGRMYXlvdXQoJ3JvdycsIGJyZWFrcG9pbnQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBsYXlvdXRWYWx1ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5b3V0ID8gdGhpcy5sYXlvdXQuZmNWYWx1ZXMgOiB7ICdhbGwnOiAnJyB9O1xuICB9XG5cbiAgZ2V0IGJyZWFrcG9pbnRzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmZjVmFsdWVzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkluaXQsIElucHV0LCBSZW5kZXJlcjIsIE9wdGlvbmFsLCBTZWxmLCBPbkNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgRmxleENzc1NlcnZpY2UgfSBmcm9tICcuL2ZsZXgtY3NzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlJztcbmltcG9ydCB7IExheW91dERpcmVjdGl2ZSB9IGZyb20gJy4vbGF5b3V0LmRpcmVjdGl2ZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogYFxuICAgIFtmY0xheW91dEdhcF0sXG4gICAgW2ZjTGF5b3V0R2FwLnhzXSwgW2ZjTGF5b3V0R2FwLnNtXSwgW2ZjTGF5b3V0R2FwLm1kXSwgW2ZjTGF5b3V0R2FwLmxnXSwgW2ZjTGF5b3V0R2FwLnhsXSxcbiAgICBbZmNMYXlvdXRHYXAubHQtc21dLCBbZmNMYXlvdXRHYXAubHQtbWRdLCBbZmNMYXlvdXRHYXAubHQtbGddLCBbZmNMYXlvdXRHYXAubHQteGxdLFxuICAgIFtmY0xheW91dEdhcC5ndC14c10sIFtmY0xheW91dEdhcC5ndC1zbV0sIFtmY0xheW91dEdhcC5ndC1tZF0sIFtmY0xheW91dEdhcC5ndC1sZ11cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgTGF5b3V0R2FwRGlyZWN0aXZlIGV4dGVuZHMgQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgZmNWYWx1ZXMgPSB7fTtcblxuICBvYnNlcnZlciQgPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwJykgICAgICAgc2V0IGdhcCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC54cycpICAgIHNldCBnYXBYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLnNtJykgICAgc2V0IGdhcFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAubWQnKSAgICBzZXQgZ2FwTWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5sZycpICAgIHNldCBnYXBMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLnhsJykgICAgc2V0IGdhcFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0xheW91dEdhcC5ndC14cycpIHNldCBnYXBHdFhzKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC14cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAuZ3Qtc20nKSBzZXQgZ2FwR3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmd0LW1kJykgc2V0IGdhcEd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5ndC1sZycpIHNldCBnYXBHdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1sZyddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0xheW91dEdhcC5sdC1zbScpIHNldCBnYXBMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNMYXlvdXRHYXAubHQtbWQnKSBzZXQgZ2FwTHRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjTGF5b3V0R2FwLmx0LWxnJykgc2V0IGdhcEx0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LWxnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0xheW91dEdhcC5sdC14bCcpIHNldCBnYXBMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gdmFsOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBwcml2YXRlIGxheW91dDogTGF5b3V0RGlyZWN0aXZlLFxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCByZW5kZXJlcik7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmRlcGVuZHNPbkxheW91dCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBPYmplY3Qua2V5cyh0aGlzLmxheW91dFZhbHVlcykuZm9yRWFjaChsYXlvdXRCcmVha3BvaW50ID0+IHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKFxuICAgICAgICAgIHRoaXMuc2VydmljZS5hZGRMYXlvdXRHYXAodGhpcy5sYXlvdXRWYWx1ZXNbbGF5b3V0QnJlYWtwb2ludF0sIGxheW91dEJyZWFrcG9pbnQsIHRoaXMuZmNWYWx1ZXNbYnJlYWtwb2ludF0sIGJyZWFrcG9pbnQpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKTtcblxuICAgIHRoaXMub2JzZXJ2ZXIkLm5leHQodGhpcy5mY1ZhbHVlcyk7XG4gIH1cblxuICBkZXBlbmRzT25MYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyh0aGlzLmJyZWFrcG9pbnRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgICB0aGlzLmFkZENsYXNzTmFtZSh0aGlzLnNlcnZpY2UuYWRkTGF5b3V0KCdyb3cnLCBicmVha3BvaW50KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgbGF5b3V0VmFsdWVzKCkge1xuICAgIHJldHVybiB0aGlzLmxheW91dCA/IHRoaXMubGF5b3V0LmZjVmFsdWVzIDogeyAnYWxsJzogJycgfTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBJbnB1dCwgUmVuZGVyZXIyLCBPcHRpb25hbCwgSG9zdCwgT25DaGFuZ2VzLCBTa2lwU2VsZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjRmxleF0sXG4gICAgW2ZjRmxleC54c10sIFtmY0ZsZXguc21dLCBbZmNGbGV4Lm1kXSwgW2ZjRmxleC5sZ10sIFtmY0ZsZXgueGxdLFxuICAgIFtmY0ZsZXgubHQtc21dLCBbZmNGbGV4Lmx0LW1kXSwgW2ZjRmxleC5sdC1sZ10sIFtmY0ZsZXgubHQteGxdLFxuICAgIFtmY0ZsZXguZ3QteHNdLCBbZmNGbGV4Lmd0LXNtXSwgW2ZjRmxleC5ndC1tZF0sIFtmY0ZsZXguZ3QtbGddLFxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBGbGV4RGlyZWN0aXZlIGV4dGVuZHMgQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgZmNWYWx1ZXMgPSB7fTtcblxuICBvYnNlcnZlciQgPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuICBwcml2YXRlIGxheW91dDogTGF5b3V0RGlyZWN0aXZlO1xuXG4gIEBJbnB1dCgpIGZjU2hyaW5rID0gMTtcbiAgQElucHV0KCkgZmNHcm93ID0gMTtcblxuICBASW5wdXQoJ2ZjRmxleCcpICAgICAgIHNldCBmbGV4KHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgueHMnKSAgICBzZXQgZmxleFhzKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXguc20nKSAgICBzZXQgZmxleFNtKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgubWQnKSAgICBzZXQgZmxleE1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgubGcnKSAgICBzZXQgZmxleExnKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXgueGwnKSAgICBzZXQgZmxleFhsKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleC5ndC14cycpIHNldCBmbGV4R3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5ndC1zbScpIHNldCBmbGV4R3RTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3Qtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5ndC1tZCcpIHNldCBmbGV4R3RNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleC5ndC1sZycpIHNldCBmbGV4R3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNGbGV4Lmx0LXNtJykgc2V0IGZsZXhMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmx0LW1kJykgc2V0IGZsZXhMdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1tZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmx0LWxnJykgc2V0IGZsZXhMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4Lmx0LXhsJykgc2V0IGZsZXhMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gdmFsOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgQEhvc3QoKSBAU2tpcFNlbGYoKSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZSxcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuXG4gICAgaWYgKGxheW91dCAmJiBsYXlvdXQuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ID09PSB0aGlzLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGVwZW5kc09uUGFyZW50TGF5b3V0KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbXTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMubGF5b3V0VmFsdWVzKS5mb3JFYWNoKGxheW91dEJyZWFrcG9pbnQgPT4ge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goXG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLmFkZEZsZXgoXG4gICAgICAgICAgICB0aGlzLmxheW91dFZhbHVlc1tsYXlvdXRCcmVha3BvaW50XSwgbGF5b3V0QnJlYWtwb2ludCwgdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludCwgdGhpcy5mY0dyb3csIHRoaXMuZmNTaHJpbmtcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKTtcblxuICAgIHRoaXMub2JzZXJ2ZXIkLm5leHQodGhpcy5mY1ZhbHVlcyk7XG4gIH1cblxuICBkZXBlbmRzT25QYXJlbnRMYXlvdXQoKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxheW91dC5hZGROZXdCcmVha3BvaW50cyh0aGlzLmJyZWFrcG9pbnRzLCAncm93Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLnBhcmVudEVsZW1lbnQsIHRoaXMuc2VydmljZS5hZGRMYXlvdXQoJ3JvdycsIGJyZWFrcG9pbnQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldCBsYXlvdXRWYWx1ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5b3V0ID8gdGhpcy5sYXlvdXQuZmNWYWx1ZXMgOiB7ICdhbGwnOiAnJyB9O1xuICB9XG5cbiAgZ2V0IHBhcmVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIucGFyZW50Tm9kZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XG4gIH1cblxuICBnZXQgYnJlYWtwb2ludHMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZmNWYWx1ZXMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIE9uSW5pdCwgSW5wdXQsIFJlbmRlcmVyMiwgT3B0aW9uYWwsIEhvc3QsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjRmxleEFsaWduXSxcbiAgICBbZmNGbGV4QWxpZ24ueHNdLCBbZmNGbGV4QWxpZ24uc21dLCBbZmNGbGV4QWxpZ24ubWRdLCBbZmNGbGV4QWxpZ24ubGddLCBbZmNGbGV4QWxpZ24ueGxdLFxuICAgIFtmY0ZsZXhBbGlnbi5sdC1zbV0sIFtmY0ZsZXhBbGlnbi5sdC1tZF0sIFtmY0ZsZXhBbGlnbi5sdC1sZ10sIFtmY0ZsZXhBbGlnbi5sdC14bF0sXG4gICAgW2ZjRmxleEFsaWduLmd0LXhzXSwgW2ZjRmxleEFsaWduLmd0LXNtXSwgW2ZjRmxleEFsaWduLmd0LW1kXSwgW2ZjRmxleEFsaWduLmd0LWxnXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBGbGV4QWxpZ25EaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBmY1ZhbHVlcyA9IHt9O1xuXG4gIG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmU7XG5cbiAgQElucHV0KCdmY0ZsZXhBbGlnbicpICAgICAgIHNldCBhbGlnbih2YWwpICAgICB7IHRoaXMuZmNWYWx1ZXNbJ2FsbCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ueHMnKSAgICBzZXQgYWxpZ25Ycyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24uc20nKSAgICBzZXQgYWxpZ25TbSh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubWQnKSAgICBzZXQgYWxpZ25NZCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydtZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ubGcnKSAgICBzZXQgYWxpZ25MZyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydsZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4QWxpZ24ueGwnKSAgICBzZXQgYWxpZ25YbCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5ndC14cycpIHNldCBhbGlnbkd0WHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXhzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5ndC1zbScpIHNldCBhbGlnbkd0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5ndC1tZCcpIHNldCBhbGlnbkd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhBbGlnbi5ndC1sZycpIHNldCBhbGlnbkd0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LWxnJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmx0LXNtJykgc2V0IGFsaWduTHRTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmx0LW1kJykgc2V0IGFsaWduTHRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmx0LWxnJykgc2V0IGFsaWduTHRMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleEFsaWduLmx0LXhsJykgc2V0IGFsaWduTHRYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQteGwnXSA9IHZhbDsgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHNlcnZpY2U6IEZsZXhDc3NTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcblxuICAgIGlmIChsYXlvdXQgJiYgbGF5b3V0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCA9PT0gdGhpcy5wYXJlbnRFbGVtZW50KSB7XG4gICAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmRlcGVuZHNPblBhcmVudExheW91dCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goXG4gICAgICAgIHRoaXMuc2VydmljZS5hZGRGbGV4QWxpZ24odGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludClcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgZGVwZW5kc09uUGFyZW50TGF5b3V0KCkge1xuICAgIGlmICh0aGlzLmxheW91dCkge1xuICAgICAgdGhpcy5sYXlvdXQuYWRkTmV3QnJlYWtwb2ludHModGhpcy5icmVha3BvaW50cywgJ3JvdycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5wYXJlbnRFbGVtZW50LCB0aGlzLnNlcnZpY2UuYWRkTGF5b3V0KCdyb3cnLCBicmVha3BvaW50KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBJbnB1dCwgUmVuZGVyZXIyLCBPcHRpb25hbCwgSG9zdCwgT25DaGFuZ2VzLCBTa2lwU2VsZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjRmxleE9yZGVyXSxcbiAgICBbZmNGbGV4T3JkZXIueHNdLCBbZmNGbGV4T3JkZXIuc21dLCBbZmNGbGV4T3JkZXIubWRdLCBbZmNGbGV4T3JkZXIubGddLCBbZmNGbGV4T3JkZXIueGxdLFxuICAgIFtmY0ZsZXhPcmRlci5sdC1zbV0sIFtmY0ZsZXhPcmRlci5sdC1tZF0sIFtmY0ZsZXhPcmRlci5sdC1sZ10sIFtmY0ZsZXhPcmRlci5sdC14bF0sXG4gICAgW2ZjRmxleE9yZGVyLmd0LXhzXSwgW2ZjRmxleE9yZGVyLmd0LXNtXSwgW2ZjRmxleE9yZGVyLmd0LW1kXSwgW2ZjRmxleE9yZGVyLmd0LWxnXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBGbGV4T3JkZXJEaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBmY1ZhbHVlcyA9IHt9O1xuXG4gIG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmU7XG5cbiAgQElucHV0KCdmY0ZsZXhPcmRlcicpICAgICAgIHNldCBvcmRlcih2YWwpICAgICB7IHRoaXMuZmNWYWx1ZXNbJ2FsbCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIueHMnKSAgICBzZXQgb3JkZXJYcyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4cyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIuc20nKSAgICBzZXQgb3JkZXJTbSh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubWQnKSAgICBzZXQgb3JkZXJNZCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydtZCddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIubGcnKSAgICBzZXQgb3JkZXJMZyh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydsZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T3JkZXIueGwnKSAgICBzZXQgb3JkZXJYbCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5ndC14cycpIHNldCBvcmRlckd0WHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXhzJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5ndC1zbScpIHNldCBvcmRlckd0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5ndC1tZCcpIHNldCBvcmRlckd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPcmRlci5ndC1sZycpIHNldCBvcmRlckd0TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LWxnJ10gPSB2YWw7IH1cblxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmx0LXNtJykgc2V0IG9yZGVyTHRTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtc20nXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmx0LW1kJykgc2V0IG9yZGVyTHRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmx0LWxnJykgc2V0IG9yZGVyTHRMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9yZGVyLmx0LXhsJykgc2V0IG9yZGVyTHRYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQteGwnXSA9IHZhbDsgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHNlcnZpY2U6IEZsZXhDc3NTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgQFNraXBTZWxmKCkgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmUsXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHJlbmRlcmVyKTtcblxuICAgIGlmIChsYXlvdXQgJiYgbGF5b3V0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCA9PT0gdGhpcy5wYXJlbnRFbGVtZW50KSB7XG4gICAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmRlcGVuZHNPblBhcmVudExheW91dCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goXG4gICAgICAgIHRoaXMuc2VydmljZS5hZGRGbGV4T3JkZXIodGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludClcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG5cbiAgICB0aGlzLm9ic2VydmVyJC5uZXh0KHRoaXMuZmNWYWx1ZXMpO1xuICB9XG5cbiAgZGVwZW5kc09uUGFyZW50TGF5b3V0KCkge1xuICAgIGlmICh0aGlzLmxheW91dCkge1xuICAgICAgdGhpcy5sYXlvdXQuYWRkTmV3QnJlYWtwb2ludHModGhpcy5icmVha3BvaW50cywgJ3JvdycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRzLmZvckVhY2goYnJlYWtwb2ludCA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5wYXJlbnRFbGVtZW50LCB0aGlzLnNlcnZpY2UuYWRkTGF5b3V0KCdyb3cnLCBicmVha3BvaW50KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBJbnB1dCwgUmVuZGVyZXIyLCBPcHRpb25hbCwgSG9zdCwgT25DaGFuZ2VzLCBTa2lwU2VsZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSB9IGZyb20gJy4vZmxleC1jc3Muc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0RGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQuZGlyZWN0aXZlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgXG4gICAgW2ZjRmxleE9mZnNldF0sXG4gICAgW2ZjRmxleE9mZnNldC54c10sIFtmY0ZsZXhPZmZzZXQuc21dLCBbZmNGbGV4T2Zmc2V0Lm1kXSwgW2ZjRmxleE9mZnNldC5sZ10sIFtmY0ZsZXhPZmZzZXQueGxdLFxuICAgIFtmY0ZsZXhPZmZzZXQubHQtc21dLCBbZmNGbGV4T2Zmc2V0Lmx0LW1kXSwgW2ZjRmxleE9mZnNldC5sdC1sZ10sIFtmY0ZsZXhPZmZzZXQubHQteGxdLFxuICAgIFtmY0ZsZXhPZmZzZXQuZ3QteHNdLCBbZmNGbGV4T2Zmc2V0Lmd0LXNtXSwgW2ZjRmxleE9mZnNldC5ndC1tZF0sIFtmY0ZsZXhPZmZzZXQuZ3QtbGddXG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEZsZXhPZmZzZXREaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBmY1ZhbHVlcyA9IHt9O1xuXG4gIG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIHByaXZhdGUgbGF5b3V0OiBMYXlvdXREaXJlY3RpdmU7XG5cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQnKSAgICAgICBzZXQgb2Zmc2V0KHZhbCkgICAgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQueHMnKSAgICBzZXQgb2Zmc2V0WHModmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1sneHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5zbScpICAgIHNldCBvZmZzZXRTbSh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWydzbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lm1kJykgICAgc2V0IG9mZnNldE1kKHZhbCkgICB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQubGcnKSAgICBzZXQgb2Zmc2V0TGcodmFsKSAgIHsgdGhpcy5mY1ZhbHVlc1snbGcnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC54bCcpICAgIHNldCBvZmZzZXRYbCh2YWwpICAgeyB0aGlzLmZjVmFsdWVzWyd4bCddID0gdmFsOyB9XG5cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQuZ3QteHMnKSBzZXQgb2Zmc2V0R3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5ndC1zbScpIHNldCBvZmZzZXRHdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lmd0LW1kJykgc2V0IG9mZnNldEd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQuZ3QtbGcnKSBzZXQgb2Zmc2V0R3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IHZhbDsgfVxuXG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lmx0LXNtJykgc2V0IG9mZnNldEx0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXNtJ10gPSB2YWw7IH1cbiAgQElucHV0KCdmY0ZsZXhPZmZzZXQubHQtbWQnKSBzZXQgb2Zmc2V0THRNZCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbWQnXSA9IHZhbDsgfVxuICBASW5wdXQoJ2ZjRmxleE9mZnNldC5sdC1sZycpIHNldCBvZmZzZXRMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gdmFsOyB9XG4gIEBJbnB1dCgnZmNGbGV4T2Zmc2V0Lmx0LXhsJykgc2V0IG9mZnNldEx0WGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LXhsJ10gPSB2YWw7IH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIEBTa2lwU2VsZigpIGxheW91dDogTGF5b3V0RGlyZWN0aXZlLFxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCByZW5kZXJlcik7XG5cbiAgICBpZiAobGF5b3V0ICYmIGxheW91dC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgPT09IHRoaXMucGFyZW50RWxlbWVudCkge1xuICAgICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5kZXBlbmRzT25QYXJlbnRMYXlvdXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICByZWxvYWQoKSB7XG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgT2JqZWN0LmtleXModGhpcy5sYXlvdXRWYWx1ZXMpLmZvckVhY2gobGF5b3V0QnJlYWtwb2ludCA9PiB7XG4gICAgICAgIGNsYXNzTmFtZXMucHVzaChcbiAgICAgICAgICB0aGlzLnNlcnZpY2UuYWRkRmxleE9mZnNldCh0aGlzLmxheW91dFZhbHVlc1tsYXlvdXRCcmVha3BvaW50XSwgbGF5b3V0QnJlYWtwb2ludCwgdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuXG4gICAgdGhpcy5vYnNlcnZlciQubmV4dCh0aGlzLmZjVmFsdWVzKTtcbiAgfVxuXG4gIGRlcGVuZHNPblBhcmVudExheW91dCgpIHtcbiAgICBpZiAodGhpcy5sYXlvdXQpIHtcbiAgICAgIHRoaXMubGF5b3V0LmFkZE5ld0JyZWFrcG9pbnRzKHRoaXMuYnJlYWtwb2ludHMsICdyb3cnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMucGFyZW50RWxlbWVudCwgdGhpcy5zZXJ2aWNlLmFkZExheW91dCgncm93JywgYnJlYWtwb2ludCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHBhcmVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXIucGFyZW50Tm9kZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XG4gIH1cblxuICBnZXQgbGF5b3V0VmFsdWVzKCkge1xuICAgIHJldHVybiB0aGlzLmxheW91dCA/IHRoaXMubGF5b3V0LmZjVmFsdWVzIDogeyAnYWxsJzogJycgfTtcbiAgfVxuXG4gIGdldCBicmVha3BvaW50cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5mY1ZhbHVlcyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25Jbml0LCBSZW5kZXJlcjIsIE9wdGlvbmFsLCBIb3N0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBbZmNGaWxsXSxcbiAgICBbZmNGbGV4RmlsbF1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgRmxleEZpbGxEaXJlY3RpdmUgZXh0ZW5kcyBCYXNlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSBsYXlvdXQ6IExheW91dERpcmVjdGl2ZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlOiBGbGV4Q3NzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIGxheW91dDogTGF5b3V0RGlyZWN0aXZlLFxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCByZW5kZXJlcik7XG5cbiAgICBpZiAobGF5b3V0ICYmIGxheW91dC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgPT09IHRoaXMucGFyZW50RWxlbWVudCkge1xuICAgICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5kZXBlbmRzT25QYXJlbnRMYXlvdXQoKTtcblxuICAgIHRoaXMuc2VydmljZS5hZGRGbGV4RmlsbCgpO1xuICB9XG5cbiAgZGVwZW5kc09uUGFyZW50TGF5b3V0KCkge1xuICAgIGlmICh0aGlzLmxheW91dCkge1xuICAgICAgdGhpcy5sYXlvdXQuYWRkTmV3QnJlYWtwb2ludHMoWydhbGwnXSwgJ3JvdycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMucGFyZW50RWxlbWVudCwgdGhpcy5zZXJ2aWNlLmFkZExheW91dCgncm93JywgJ2FsbCcpKTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBJbnB1dCwgUmVuZGVyZXIyLCBPbkNoYW5nZXMsIE9wdGlvbmFsLCBTZWxmLCBJbmplY3QsIFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZsZXhDc3NTZXJ2aWNlIH0gZnJvbSAnLi9mbGV4LWNzcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuXG5jb25zdCBUUlVMWSA9IFsndHJ1ZScsIHRydWUsIDFdO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNUcnVlVmFsdWUodmFsdWU6IGFueSkge1xuICByZXR1cm4gdmFsdWUgPT09ICcnIHx8IFRSVUxZLmluZGV4T2YodmFsdWUpID49IDA7XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogYFxuICBbZmNTaG93XSxcbiAgW2ZjU2hvdy54c10sIFtmY1Nob3cuc21dLCBbZmNTaG93Lm1kXSwgW2ZjU2hvdy5sZ10sIFtmY1Nob3cueGxdLFxuICBbZmNTaG93Lmx0LXNtXSwgW2ZjU2hvdy5sdC1tZF0sIFtmY1Nob3cubHQtbGddLCBbZmNTaG93Lmx0LXhsXSxcbiAgW2ZjU2hvdy5ndC14c10sIFtmY1Nob3cuZ3Qtc21dLCBbZmNTaG93Lmd0LW1kXSwgW2ZjU2hvdy5ndC1sZ10sXG4gIFtmY0hpZGVdLFxuICBbZmNIaWRlLnhzXSwgW2ZjSGlkZS5zbV0sIFtmY0hpZGUubWRdLCBbZmNIaWRlLmxnXSwgW2ZjSGlkZS54bF0sXG4gIFtmY0hpZGUubHQtc21dLCBbZmNIaWRlLmx0LW1kXSwgW2ZjSGlkZS5sdC1sZ10sIFtmY0hpZGUubHQteGxdLFxuICBbZmNIaWRlLmd0LXhzXSwgW2ZjSGlkZS5ndC1zbV0sIFtmY0hpZGUuZ3QtbWRdLCBbZmNIaWRlLmd0LWxnXVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBTaG93SGlkZURpcmVjdGl2ZSBleHRlbmRzIEJhc2VEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICByZWFkb25seSBmY1ZhbHVlcyA9IHt9O1xuXG4gIHJlYWRvbmx5IG9ic2VydmVyJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXG4gIEBJbnB1dCgpIGZjRGlzcGxheURlZmF1bHQ7XG5cbiAgQElucHV0KCdmY1Nob3cnKSAgICAgICBzZXQgc2hvdyh2YWwpICB7IHRoaXMuZmNWYWx1ZXNbJ2FsbCddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy54cycpICAgIHNldCBzaG93WHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93LnNtJykgICAgc2V0IHNob3dTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snc20nXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cubWQnKSAgICBzZXQgc2hvd01kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydtZCddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5sZycpICAgIHNldCBzaG93TGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93LnhsJykgICAgc2V0IHNob3dYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1sneGwnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cblxuICBASW5wdXQoJ2ZjU2hvdy5sdC1zbScpIHNldCBzaG93THRTbSh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtc20nXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cubHQtbWQnKSBzZXQgc2hvd0x0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LW1kJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93Lmx0LWxnJykgc2V0IHNob3dMdExnKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1sZyddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5sdC14bCcpIHNldCBzaG93THRYbCh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQteGwnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cblxuICBASW5wdXQoJ2ZjU2hvdy5ndC14cycpIHNldCBzaG93R3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY1Nob3cuZ3Qtc20nKSBzZXQgc2hvd0d0U20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LXNtJ10gPSBpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNTaG93Lmd0LW1kJykgc2V0IHNob3dHdE1kKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1tZCddID0gaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjU2hvdy5ndC1sZycpIHNldCBzaG93R3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9IGlzVHJ1ZVZhbHVlKHZhbCk7IH1cblxuICBASW5wdXQoJ2ZjSGlkZScpICAgICAgIHNldCBoaWRlKHZhbCkgIHsgdGhpcy5mY1ZhbHVlc1snYWxsJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS54cycpICAgIHNldCBoaWRlWHModmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3hzJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5zbScpICAgIHNldCBoaWRlU20odmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3NtJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5tZCcpICAgIHNldCBoaWRlTWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ21kJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5sZycpICAgIHNldCBoaWRlTGcodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2xnJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS54bCcpICAgIHNldCBoaWRlWGwodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ3hsJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuXG4gIEBJbnB1dCgnZmNIaWRlLmx0LXNtJykgc2V0IGhpZGVMdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC1zbSddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY0hpZGUubHQtbWQnKSBzZXQgaGlkZUx0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2x0LW1kJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5sdC1sZycpIHNldCBoaWRlTHRMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snbHQtbGcnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLmx0LXhsJykgc2V0IGhpZGVMdFhsKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydsdC14bCddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cblxuICBASW5wdXQoJ2ZjSGlkZS5ndC14cycpIHNldCBoaWRlR3RYcyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QteHMnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG4gIEBJbnB1dCgnZmNIaWRlLmd0LXNtJykgc2V0IGhpZGVHdFNtKHZhbCkgeyB0aGlzLmZjVmFsdWVzWydndC1zbSddID0gIWlzVHJ1ZVZhbHVlKHZhbCk7IH1cbiAgQElucHV0KCdmY0hpZGUuZ3QtbWQnKSBzZXQgaGlkZUd0TWQodmFsKSB7IHRoaXMuZmNWYWx1ZXNbJ2d0LW1kJ10gPSAhaXNUcnVlVmFsdWUodmFsKTsgfVxuICBASW5wdXQoJ2ZjSGlkZS5ndC1sZycpIHNldCBoaWRlR3RMZyh2YWwpIHsgdGhpcy5mY1ZhbHVlc1snZ3QtbGcnXSA9ICFpc1RydWVWYWx1ZSh2YWwpOyB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2VydmljZTogRmxleENzc1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBwcml2YXRlIGxheW91dDogTGF5b3V0RGlyZWN0aXZlLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByb3RlY3RlZCBwbGF0Zm9ybUlkOiBPYmplY3RcbiAgKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgcmVuZGVyZXIpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5yZWxvYWQoKTtcbiAgfVxuXG4gIHJlbG9hZCgpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gW107XG5cbiAgICBjb25zdCBkaXNwbGF5ID0gdGhpcy5nZXREaXNwbGF5U3R5bGUoKTtcblxuICAgIHRoaXMuYnJlYWtwb2ludHMuZm9yRWFjaChicmVha3BvaW50ID0+IHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCh0aGlzLnNlcnZpY2UuYWRkU2hvd0hpZGUoZGlzcGxheSwgdGhpcy5mY1ZhbHVlc1ticmVha3BvaW50XSwgYnJlYWtwb2ludCkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuXG4gICAgdGhpcy5vYnNlcnZlciQubmV4dCh0aGlzLmZjVmFsdWVzKTtcbiAgfVxuXG4gIGdldERpc3BsYXlTdHlsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5sYXlvdXQgPyAnZmxleCcgOiAoXG4gICAgICB0aGlzLmdldEVsZW1lbnRTdHlsZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2Rpc3BsYXknKVxuICAgICAgfHwgdGhpcy5mY0Rpc3BsYXlEZWZhdWx0XG4gICAgICB8fCAnYmxvY2snXG4gICAgKTtcbiAgfVxuXG4gIGdldEVsZW1lbnRTdHlsZShlbGVtZW50LCBzdHlsZU5hbWUpIHtcbiAgICByZXR1cm4gKGVsZW1lbnQgPyBlbGVtZW50LnN0eWxlW3N0eWxlTmFtZV0gfHwgZWxlbWVudC5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlTmFtZSkgOiAnJylcbiAgICAgIHx8IChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpID8gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlTmFtZSkgOiAnJyk7XG4gIH1cblxuICBnZXQgYnJlYWtwb2ludHMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZmNWYWx1ZXMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSwgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBGbGV4Q3NzU2VydmljZSwgRkxFWF9DU1NfQlJFQUtQT0lOVFMsIEZMRVhfQ1NTX0RFRkFVTFRfQlJFQUtQT0lOVFMsIEJyZWFrcG9pbnQgfSBmcm9tICcuL2ZsZXgtY3NzLnNlcnZpY2UnO1xuXG5pbXBvcnQgeyBMYXlvdXREaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0QWxpZ25EaXJlY3RpdmUgfSBmcm9tICcuL2xheW91dC1hbGlnbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTGF5b3V0R2FwRGlyZWN0aXZlIH0gZnJvbSAnLi9sYXlvdXQtZ2FwLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBGbGV4RGlyZWN0aXZlIH0gZnJvbSAnLi9mbGV4LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBGbGV4T3JkZXJEaXJlY3RpdmUgfSBmcm9tICcuL2ZsZXgtb3JkZXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsZXhPZmZzZXREaXJlY3RpdmUgfSBmcm9tICcuL2ZsZXgtb2Zmc2V0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBGbGV4QWxpZ25EaXJlY3RpdmUgfSBmcm9tICcuL2ZsZXgtYWxpZ24uZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsZXhGaWxsRGlyZWN0aXZlIH0gZnJvbSAnLi9mbGV4LWZpbGwuZGlyZWN0aXZlJztcbmltcG9ydCB7IFNob3dIaWRlRGlyZWN0aXZlIH0gZnJvbSAnLi9zaG93LWhpZGUuZGlyZWN0aXZlJztcblxuZXhwb3J0IHR5cGUgQnJlYWtwb2ludHNGbiA9IChkZWZhdWx0QnJlYWtwb2ludHM6IEJyZWFrcG9pbnRbXSkgPT4gQnJlYWtwb2ludFtdO1xuXG5leHBvcnQgZnVuY3Rpb24gY3VzdG9taXplQnJlYWtQb2ludHMoYnJlYWtwb2ludHM6IEJyZWFrcG9pbnRbXXxCcmVha3BvaW50c0ZuKSB7XG4gIGlmICh0eXBlb2YgYnJlYWtwb2ludHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBicmVha3BvaW50cyA9IGJyZWFrcG9pbnRzKEZMRVhfQ1NTX0RFRkFVTFRfQlJFQUtQT0lOVFMpO1xuICB9XG5cbiAgcmV0dXJuIGJyZWFrcG9pbnRzIHx8IEZMRVhfQ1NTX0RFRkFVTFRfQlJFQUtQT0lOVFM7XG59XG5cbkBOZ01vZHVsZSh7XG4gIGRlY2xhcmF0aW9uczogW1xuICAgIExheW91dERpcmVjdGl2ZSxcbiAgICBMYXlvdXRBbGlnbkRpcmVjdGl2ZSxcbiAgICBMYXlvdXRHYXBEaXJlY3RpdmUsXG5cbiAgICBGbGV4RGlyZWN0aXZlLFxuICAgIEZsZXhPcmRlckRpcmVjdGl2ZSxcbiAgICBGbGV4T2Zmc2V0RGlyZWN0aXZlLFxuICAgIEZsZXhBbGlnbkRpcmVjdGl2ZSxcblxuICAgIEZsZXhGaWxsRGlyZWN0aXZlLFxuICAgIFNob3dIaWRlRGlyZWN0aXZlLFxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgTGF5b3V0RGlyZWN0aXZlLFxuICAgIExheW91dEFsaWduRGlyZWN0aXZlLFxuICAgIExheW91dEdhcERpcmVjdGl2ZSxcblxuICAgIEZsZXhEaXJlY3RpdmUsXG4gICAgRmxleE9yZGVyRGlyZWN0aXZlLFxuICAgIEZsZXhPZmZzZXREaXJlY3RpdmUsXG4gICAgRmxleEFsaWduRGlyZWN0aXZlLFxuXG4gICAgRmxleEZpbGxEaXJlY3RpdmUsXG4gICAgU2hvd0hpZGVEaXJlY3RpdmUsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEZsZXhDc3NNb2R1bGUge1xuICBzdGF0aWMgZm9yUm9vdChicmVha3BvaW50cz86IEJyZWFrcG9pbnRbXXxCcmVha3BvaW50c0ZuKTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nTW9kdWxlOiBGbGV4Q3NzTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIEZsZXhDc3NTZXJ2aWNlLFxuICAgICAgICB7XG4gICAgICAgICAgcHJvdmlkZTogJ2ZsZXhfY3NzX21vZHVsZV9icmVha3BvaW50cycsXG4gICAgICAgICAgdXNlVmFsdWU6IGJyZWFrcG9pbnRzLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcHJvdmlkZTogRkxFWF9DU1NfQlJFQUtQT0lOVFMsXG4gICAgICAgICAgdXNlRmFjdG9yeTogY3VzdG9taXplQnJlYWtQb2ludHMsXG4gICAgICAgICAgZGVwczogWydmbGV4X2Nzc19tb2R1bGVfYnJlYWtwb2ludHMnXVxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG59XG4iXSwibmFtZXMiOlsiSW5qZWN0aW9uVG9rZW4iLCJJbmplY3RhYmxlIiwiSW5qZWN0IiwiRE9DVU1FTlQiLCJ0c2xpYl8xLl9fZXh0ZW5kcyIsIlJlcGxheVN1YmplY3QiLCJEaXJlY3RpdmUiLCJFbGVtZW50UmVmIiwiUmVuZGVyZXIyIiwiSW5wdXQiLCJPcHRpb25hbCIsIlNlbGYiLCJIb3N0IiwiU2tpcFNlbGYiLCJpc1BsYXRmb3JtQnJvd3NlciIsIlBMQVRGT1JNX0lEIiwiTmdNb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUFBOzs7Ozs7Ozs7Ozs7OztJQWNBO0lBRUEsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLGNBQWM7U0FDcEMsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLFlBQVksS0FBSyxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUUsVUFBVSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQztZQUFFLElBQUksQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7Z0JBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFFL0UsdUJBQTBCLENBQUMsRUFBRSxDQUFDO1FBQzFCLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEIsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUU7UUFDdkMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6RixDQUFDO0FBRUQsb0JBcUZ1QixDQUFDLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsR0FBRyxPQUFPLE1BQU0sS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLElBQUk7WUFDQSxPQUFPLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJO2dCQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzlFO1FBQ0QsT0FBTyxLQUFLLEVBQUU7WUFBRSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7U0FBRTtnQkFDL0I7WUFDSixJQUFJO2dCQUNBLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDcEQ7b0JBQ087Z0JBQUUsSUFBSSxDQUFDO29CQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQzthQUFFO1NBQ3BDO1FBQ0QsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxR0QsOEJBQWlDLE1BQU07UUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxHQUFHO1lBQzdCLHFCQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBRTlCLFFBQVEsR0FBRztnQkFDVCxLQUFLLFNBQVM7b0JBQ1osSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFO3dCQUNwQixNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUc7NEJBQ2xCLGNBQWM7NEJBQ2QsTUFBTTt5QkFDUCxDQUFDO3FCQUNIO3lCQUFNLElBQUksS0FBSyxLQUFLLGFBQWEsRUFBRTt3QkFDbEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHOzRCQUNsQixxQkFBcUI7NEJBQ3JCLGFBQWE7eUJBQ2QsQ0FBQztxQkFDSDt5QkFBTTt3QkFDTCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO3FCQUMzQjtvQkFDRCxNQUFNO2dCQUVSLEtBQUssYUFBYSxDQUFDO2dCQUNuQixLQUFLLFlBQVksQ0FBQztnQkFDbEIsS0FBSyxlQUFlLENBQUM7Z0JBQ3JCLEtBQUssTUFBTSxDQUFDO2dCQUNaLEtBQUssWUFBWSxDQUFDO2dCQUNsQixLQUFLLFdBQVcsQ0FBQztnQkFDakIsS0FBSyxXQUFXLENBQUM7Z0JBQ2pCLEtBQUssYUFBYSxDQUFDO2dCQUNuQixLQUFLLFdBQVcsQ0FBQztnQkFDakIsS0FBSyxpQkFBaUI7b0JBQ3BCLE1BQU0sQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO29CQUNqQyxNQUFNO2dCQUVSLEtBQUssZ0JBQWdCO29CQUNuQixLQUFLLEdBQUcsS0FBSyxJQUFJLEtBQUssQ0FBQztvQkFDdkIsTUFBTSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsS0FBSyxDQUFDO29CQUN6QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxLQUFLLENBQUM7b0JBQ2pDLE1BQU07Z0JBRVIsS0FBSyxPQUFPO29CQUNWLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDO29CQUN4RSxNQUFNO2FBQ1Q7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztLQUNmOzs7Ozs7Ozs7Ozs7O0FDNURELElBQU8scUJBQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQztBQUMvQixJQUFPLHFCQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Ozs7Ozs7QUFjaEYsMkJBQThCLEtBQWE7UUFDekMsS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ3pDLHNDQUFLLGlCQUFTLEVBQUUsWUFBSSxFQUFFLGNBQU0sQ0FBcUI7O1FBR2pELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxLQUFLLFNBQVMsR0FBQSxDQUFDLEVBQUU7WUFDN0MsU0FBUyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUM5QjtRQUVELElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRTtZQUNuQixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDekMsTUFBTSxHQUFHLE1BQU0sQ0FBQztTQUNqQjtRQUVELE9BQU8sQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ3ZEOzs7Ozs7O0FBTUQsOEJBQWlDLEtBQWE7UUFDNUMsMENBQU8sWUFBSSxDQUEyQjtRQUN0QyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7S0FDakM7Ozs7OztBQUtELCtCQUFrQyxLQUFLO1FBQ3JDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtZQUNYLFFBQVEsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQkFDekIsS0FBSyxTQUFTLENBQUM7Z0JBQ2YsS0FBSyxjQUFjLENBQUM7Z0JBQ3BCLEtBQUssY0FBYztvQkFDakIsS0FBSyxHQUFHLGNBQWMsQ0FBQztvQkFDdkIsTUFBTTtnQkFFUixLQUFLLElBQUksQ0FBQztnQkFDVixLQUFLLE1BQU0sQ0FBQztnQkFDWixLQUFLLFFBQVE7b0JBQ1gsS0FBSyxHQUFHLFFBQVEsQ0FBQztvQkFDakIsTUFBTTs7Z0JBR1I7b0JBQ0UsS0FBSyxHQUFHLE1BQU0sQ0FBQztvQkFDZixNQUFNO2FBQ1Q7U0FDRjtRQUNELE9BQU8sS0FBSyxDQUFDO0tBQ2Q7Ozs7Ozs7Ozs7Ozs7O0FBV0Qsc0JBQXlCLFNBQVMsRUFBRSxJQUFXLEVBQUUsTUFBYztRQUEzQixxQkFBQTtZQUFBLFdBQVc7O1FBQUUsdUJBQUE7WUFBQSxjQUFjOztRQUM3RCxPQUFPO1lBQ0wsU0FBUyxFQUFFLE1BQU0sR0FBRyxhQUFhLEdBQUcsTUFBTTtZQUMxQyxZQUFZLEVBQUUsWUFBWTtZQUMxQixnQkFBZ0IsRUFBRSxTQUFTO1lBQzNCLFdBQVcsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJO1NBQ2xDLENBQUM7S0FDSDs7Ozs7Ozs7OztBQzNGRCx1Q0FBMEMsS0FBYTtRQUNyRCxLQUFLLEdBQUcsS0FBSyxJQUFJLGVBQWUsQ0FBQztRQUVqQyxzQ0FBSyxnQkFBUSxFQUFFLGlCQUFTLENBQXFCO1FBRTdDLFFBQVEsUUFBUTtZQUNkLEtBQUssUUFBUSxDQUFDO1lBQ2QsS0FBSyxjQUFjLENBQUM7WUFDcEIsS0FBSyxlQUFlLENBQUM7WUFDckIsS0FBSyxjQUFjO2dCQUNqQixNQUFNO1lBQ1IsS0FBSyxLQUFLLENBQUM7WUFDWCxLQUFLLFVBQVU7Z0JBQ2IsUUFBUSxHQUFHLFVBQVUsQ0FBQztnQkFDdEIsTUFBTTtZQUNSLEtBQUssT0FBTyxDQUFDO1lBQ2IsS0FBSyxZQUFZLENBQUM7WUFDbEI7Z0JBQ0UsUUFBUSxHQUFHLFlBQVksQ0FBQztnQkFDeEIsTUFBTTtTQUNUO1FBRUQsUUFBUSxTQUFTO1lBQ2YsS0FBSyxPQUFPLENBQUM7WUFDYixLQUFLLFlBQVk7Z0JBQ2YsU0FBUyxHQUFHLFlBQVksQ0FBQztnQkFDekIsTUFBTTtZQUNSLEtBQUssVUFBVSxDQUFDO1lBQ2hCLEtBQUssUUFBUTtnQkFDWCxTQUFTLEdBQUcsUUFBUSxDQUFDO2dCQUNyQixNQUFNO1lBQ1IsS0FBSyxLQUFLLENBQUM7WUFDWCxLQUFLLFVBQVU7Z0JBQ2IsU0FBUyxHQUFHLFVBQVUsQ0FBQztnQkFDdkIsTUFBTTtZQUNSLEtBQUssU0FBUyxDQUFDO1lBQ2Y7O2dCQUNFLFNBQVMsR0FBRyxTQUFTLENBQUM7Z0JBQ3RCLE1BQU07U0FDVDtRQUVELE9BQU8sQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7S0FDOUI7Ozs7Ozs7O0FBRUQscUNBQXdDLFNBQWlCLEVBQUUsSUFBWSxFQUFFLFFBQWlCLEVBQUUsVUFBa0I7UUFDNUcsT0FBTyxVQUFVO2VBQ1osVUFBVSxLQUFLLEtBQUssR0FBRyxJQUFJLEdBQUcsVUFBVSxHQUFHLEVBQUUsQ0FBQztjQUMvQyxJQUFJLEdBQUcsU0FBUyxJQUFJLElBQUksR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQyxJQUFJLFFBQVEsR0FBRyxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7S0FDL0U7Ozs7Ozs7QUFFRCwwQ0FBNkMsUUFBZ0IsRUFBRSxTQUFpQixFQUFFLFVBQWtCO1FBQ2xHLE9BQU8sZUFBZTtlQUNqQixVQUFVLEtBQUssS0FBSyxHQUFHLElBQUksR0FBRyxVQUFVLEdBQUcsRUFBRSxDQUFDO2NBQy9DLElBQUksR0FBRyxRQUFRLEdBQUcsR0FBRyxHQUFHLFNBQVMsQ0FBQztLQUN2Qzs7Ozs7O0FBRUQsd0NBQTJDLEtBQWEsRUFBRSxVQUFrQjtRQUMxRSxPQUFPLGFBQWE7ZUFDZixVQUFVLEtBQUssS0FBSyxHQUFHLElBQUksR0FBRyxVQUFVLEdBQUcsRUFBRSxDQUFDO2NBQy9DLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNwQzs7Ozs7Ozs7QUFFRCxtQ0FBc0MsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsVUFBa0I7UUFDM0UsT0FBTyxRQUFRO2VBQ1YsVUFBVSxLQUFLLEtBQUssR0FBRyxJQUFJLEdBQUcsVUFBVSxHQUFHLEVBQUUsQ0FBQztjQUMvQyxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssR0FBRyxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7S0FDbkg7Ozs7OztBQUVELHdDQUEyQyxLQUFLLEVBQUUsVUFBa0I7UUFDbEUsT0FBTyxhQUFhO2VBQ2YsVUFBVSxLQUFLLEtBQUssR0FBRyxJQUFJLEdBQUcsVUFBVSxHQUFHLEVBQUUsQ0FBQztjQUMvQyxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDcEM7Ozs7OztBQUVELHlDQUE0QyxNQUFNLEVBQUUsVUFBa0I7UUFDcEUsT0FBTyxjQUFjO2VBQ2hCLFVBQVUsS0FBSyxLQUFLLEdBQUcsSUFBSSxHQUFHLFVBQVUsR0FBRyxFQUFFLENBQUM7Y0FDL0MsSUFBSSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ3JDOzs7Ozs7QUFFRCx3Q0FBMkMsS0FBSyxFQUFFLFVBQWtCO1FBQ2xFLE9BQU8sYUFBYTtlQUNmLFVBQVUsS0FBSyxLQUFLLEdBQUcsSUFBSSxHQUFHLFVBQVUsR0FBRyxFQUFFLENBQUM7Y0FDL0MsSUFBSSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3BDOzs7O0FBRUQ7UUFDRSxPQUFPLFlBQVksQ0FBQztLQUNyQjs7Ozs7OztBQUVELDJDQUE4QyxPQUFPLEVBQUUsSUFBYSxFQUFFLFVBQWtCO1FBQ3RGLE9BQU8sUUFBUTtlQUNWLFVBQVUsS0FBSyxLQUFLLEdBQUcsSUFBSSxHQUFHLFVBQVUsR0FBRyxFQUFFLENBQUM7Y0FDL0MsSUFBSSxHQUFHLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztjQUNoQyxJQUFJLElBQUksSUFBSSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQztLQUNyQzs7Ozs7QUFFRCw4QkFBaUMsS0FBSztRQUNwQyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ3BEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdEZELDJCQUE4QixLQUFhLEVBQUUsSUFBVSxFQUFFLE1BQVk7UUFBeEIscUJBQUE7WUFBQSxVQUFVOztRQUFFLHVCQUFBO1lBQUEsWUFBWTs7UUFDbkUscUJBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVsQyxxQkFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVCxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELHFCQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckQsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDeEIsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEIsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN2QjtTQUNGO2FBQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2xCLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUM3QzthQUFNO1lBQ0wscUJBQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakMsS0FBSyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksT0FBTyxHQUFHO2dCQUN6QyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUs7YUFDcEIsQ0FBQztTQUNIO1FBRUQsT0FBTyxLQUFLLENBQUM7S0FDZDs7Ozs7Ozs7Ozs7OztJQWFELDRCQUE0QixJQUFZO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztLQUNqRTs7Ozs7O0lDaENNLHFCQUFNLDRCQUE0QixHQUFpQjtRQUN4RCxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLG9CQUFvQixDQUFDLEVBQUU7UUFDM0QsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxxQkFBcUIsQ0FBQyxFQUFFO1FBQzVELEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLENBQUMsRUFBRTtRQUMzRCxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLEVBQUU7UUFDNUQsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxxQkFBcUIsQ0FBQyxFQUFFO1FBQzVELEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLENBQUMsRUFBRTtRQUMzRCxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLEVBQUU7UUFDNUQsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxvQkFBb0IsQ0FBQyxFQUFFO1FBQzNELEVBQUUsS0FBSyxFQUFFLElBQUksRUFBSyxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLENBQUMsRUFBRTtRQUNuRixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUssS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLHFCQUFxQixFQUFFLHFCQUFxQixDQUFDLEVBQUU7UUFDbkYsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFLLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxvQkFBb0IsRUFBRSxxQkFBcUIsQ0FBQyxFQUFFO1FBQ2xGLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBSyxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLENBQUMsRUFBRTtRQUNqRixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUssS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLG9CQUFvQixDQUFDLEVBQUU7S0FDNUQsQ0FBQztBQUVGLHlCQW9CYSxvQkFBb0IsR0FBRyxJQUFJQSxtQkFBYyxDQUFTLHNCQUFzQixDQUFDLENBQUM7SUFJdkYsSUFBQTtRQUdFLDZCQUNTO1lBQUEsVUFBSyxHQUFMLEtBQUs7MkJBSHlELEVBQUU7U0FJckU7a0NBOUROO1FBK0RDLENBQUE7QUFORDtRQWdCRSx3QkFDNEIsR0FBRyxFQUNTLFdBQVc7WUFEdkIsUUFBRyxHQUFILEdBQUcsQ0FBQTtZQUNTLGdCQUFXLEdBQVgsV0FBVyxDQUFBO1lBRWpELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ2pCOzs7O1FBRUQsbUNBQVU7OztZQUFWO2dCQUNFLHFCQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFOUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxXQUFXLENBQUM7Z0JBRXZCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzlDOzs7O1FBRUQsaUNBQVE7OztZQUFSO2dCQUNFLHFCQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFOUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUM7Z0JBRXJCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFakMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzVDOzs7O1FBRUQsaUNBQVE7OztZQUFSO2dCQUNFLHFCQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFOUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUM7Z0JBRXJCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFakMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzVDOzs7Ozs7UUFFRCxrQ0FBUzs7Ozs7WUFBVCxVQUFVLE1BQWMsRUFBRSxVQUFrQjtnQkFDMUMsMkNBQU8saUJBQVMsRUFBRSxZQUFJLEVBQUUsZ0JBQVEsQ0FBMEI7Z0JBRTFELHFCQUFNLFNBQVMsR0FBRyx1QkFBdUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFakYsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ25ELHFCQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztvQkFFbEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7aUJBQ3ZEO2dCQUVELE9BQU8sU0FBUyxDQUFDO2FBQ2xCOzs7Ozs7OztRQUVELHVDQUFjOzs7Ozs7O1lBQWQsVUFBZSxNQUFjLEVBQUUsZ0JBQXdCLEVBQUUsS0FBYSxFQUFFLFVBQWtCO2dCQUN4RixzREFBTyxnQkFBUSxFQUFFLGlCQUFTLENBQXFDO2dCQUUvRCxxQkFBTSxvQkFBb0IsR0FBRyw0QkFBNEIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUUzRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG9CQUFvQixFQUFFLFVBQVUsQ0FBQyxFQUFFO29CQUM5RCxxQkFBTSxLQUFLLEdBQUc7d0JBQ1osaUJBQWlCLEVBQUUsUUFBUTtxQkFDNUIsQ0FBQztvQkFFRixRQUFRLFNBQVM7d0JBQ2YsS0FBSyxVQUFVOzRCQUNiLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxTQUFTLENBQUM7NEJBQ2pDLE1BQU07d0JBQ1I7NEJBQ0UsS0FBSyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsR0FBRyxTQUFTLENBQUM7NEJBQzFELE1BQU07cUJBQ1Q7b0JBRUQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG9CQUFvQixFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztpQkFDbEU7Z0JBRUQsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFO29CQUMzQiwyQ0FBTyxpQkFBUyxFQUFFLFlBQUksRUFBRSxnQkFBUSxDQUEwQjtvQkFFMUQscUJBQU0sZUFBZSxHQUFHLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixDQUFDLENBQUM7b0JBRTdGLHFCQUFNLFNBQVMsR0FBRyxvQkFBb0IsR0FBRyxHQUFHLEdBQUcsZUFBZSxDQUFDO29CQUUvRCxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsRUFBRTt3QkFDbkQscUJBQU0sS0FBSyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDO3dCQUU1RixJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7cUJBQzNFO2lCQUNGO2dCQUVELE9BQU8sb0JBQW9CLENBQUM7YUFDN0I7Ozs7Ozs7O1FBRUQscUNBQVk7Ozs7Ozs7WUFBWixVQUFhLE1BQWMsRUFBRSxnQkFBd0IsRUFBRSxLQUFhLEVBQUUsVUFBa0I7Z0JBQ3RGLEtBQUssR0FBRyxLQUFLLElBQUksR0FBRyxDQUFDO2dCQUVyQiwyQ0FBTyxpQkFBUyxFQUFFLFlBQUksRUFBRSxnQkFBUSxDQUEwQjtnQkFFMUQscUJBQU0sZUFBZSxHQUFHLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBRTdGLHFCQUFNLGtCQUFrQixHQUFHLDBCQUEwQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFekUscUJBQU0sU0FBUyxHQUFHLGtCQUFrQixHQUFHLEdBQUcsR0FBRyxlQUFlLEdBQUcsdUJBQXVCLENBQUM7Z0JBRXZGLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxFQUFFO29CQUNuRCxxQkFBTSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLENBQUM7b0JBRWhHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztpQkFDM0U7Z0JBRUQsT0FBTyxrQkFBa0IsQ0FBQzthQUMzQjs7Ozs7Ozs7OztRQUVELGdDQUFPOzs7Ozs7Ozs7WUFBUCxVQUFRLE1BQWMsRUFBRSxnQkFBd0IsRUFBRSxLQUFhLEVBQUUsVUFBa0IsRUFBRSxJQUFLLEVBQUUsTUFBTztnQkFDakcsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUUvQix3REFBSyxlQUFPLEVBQUUsaUJBQVMsRUFBRSxnQkFBUSxDQUF1QztnQkFFeEUsT0FBTyxHQUFHLENBQUMsT0FBTyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDO2dCQUMxQyxTQUFTLEdBQUcsQ0FBQyxTQUFTLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUM7Ozs7Ozs7Ozs7O2dCQWFoRCxxQkFBTSxLQUFLLEdBQUc7b0JBQ1osWUFBWSxFQUFFLFlBQVk7aUJBQzNCLENBQUM7Z0JBRUYsUUFBUSxRQUFRLElBQUksRUFBRTtvQkFDcEIsS0FBSyxFQUFFO3dCQUNMLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBTSxPQUFPLFNBQUksU0FBUyxtQkFBZ0IsQ0FBQzt3QkFDeEQsTUFBTTtvQkFDUixLQUFLLFNBQVMsQ0FBQztvQkFDZixLQUFLLFFBQVE7d0JBQ1gsT0FBTyxHQUFHLENBQUMsQ0FBQzt3QkFDWixLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDO3dCQUMzQixNQUFNO29CQUNSLEtBQUssTUFBTTt3QkFDVCxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDO3dCQUMzQixNQUFNO29CQUNSLEtBQUssVUFBVTt3QkFDYixTQUFTLEdBQUcsQ0FBQyxDQUFDO3dCQUNkLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUM7d0JBQzNCLE1BQU07b0JBQ1IsS0FBSyxNQUFNO3dCQUNULEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBTSxPQUFPLFNBQUksU0FBUyxVQUFPLENBQUM7d0JBQy9DLE1BQU07b0JBQ1IsS0FBSyxNQUFNO3dCQUNULE9BQU8sR0FBRyxDQUFDLENBQUM7d0JBQ1osU0FBUyxHQUFHLENBQUMsQ0FBQzt3QkFDZCxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDO3dCQUMzQixNQUFNO29CQUNSO3dCQUNFLHFCQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3dCQUNyRCxxQkFBTSxTQUFTLEdBQUcsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFFaEUscUJBQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxTQUFTOzRCQUNqQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzs0QkFDbkMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7NEJBQ25DLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRCQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDOzt3QkFHdEMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLEtBQUssbUJBQUMsUUFBZSxFQUFDLEVBQUU7NEJBQ3JELFFBQVEsR0FBRyxRQUFRLEdBQUcsR0FBRyxDQUFDO3lCQUMzQjt3QkFFRCxJQUFJLFFBQVEsS0FBSyxLQUFLLEVBQUU7NEJBQ3RCLFFBQVEsR0FBRyxJQUFJLENBQUM7eUJBQ2pCO3dCQUVELEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxLQUFHLE9BQVMsQ0FBQzt3QkFDbEMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEtBQUcsU0FBVyxDQUFDO3dCQUN0QyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxPQUFPLEdBQUcsS0FBRyxRQUFVLEdBQUcsTUFBTSxDQUFDO3dCQUNqRyxNQUFNO2lCQUNUO2dCQUVELHFCQUFNLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFdEYsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ3JELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2lCQUN6RDtnQkFFRCwyQ0FBTyxpQkFBUyxFQUFFLFlBQUksRUFBRSxnQkFBUSxDQUEwQjtnQkFFMUQscUJBQU0sZUFBZSxHQUFHLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBRTdGLHFCQUFNLFNBQVMsR0FBRyxhQUFhLEdBQUcsR0FBRyxHQUFHLGVBQWUsQ0FBQztnQkFFeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ2pELHFCQUFNLEdBQUcsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxXQUFXLEdBQUcsWUFBWSxDQUFDO29CQUNyRSxxQkFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEdBQUcsV0FBVyxHQUFHLFlBQVksQ0FBQztvQkFFckUscUJBQU0sU0FBUyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxRQUFRLEtBQUssTUFBTSxDQUFDLENBQUM7b0JBQ25GLHFCQUFNLElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQzs7OztvQkFLOUQscUJBQU0sT0FBTyxHQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUV2QyxxQkFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDO29CQUV2QixXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLENBQUMsR0FBRyxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sQ0FBQyxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUM7b0JBQzVGLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksQ0FBQyxHQUFHLE9BQU8sS0FBSyxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsR0FBRyxRQUFRLEdBQUcsSUFBSSxDQUFDO29CQUVwRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7aUJBQy9FO2dCQUVELE9BQU8sYUFBYSxDQUFDO2FBQ3RCOzs7Ozs7UUFFRCxxQ0FBWTs7Ozs7WUFBWixVQUFhLEtBQUssRUFBRSxVQUFrQjtnQkFDcEMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBRTVCLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztnQkFFakMscUJBQU0sU0FBUyxHQUFHLDBCQUEwQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ2pELHFCQUFNLEtBQUssR0FBRyxFQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUMsQ0FBQztvQkFFL0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7aUJBQ3JEO2dCQUVELE9BQU8sU0FBUyxDQUFDO2FBQ2xCOzs7Ozs7OztRQUVELHNDQUFhOzs7Ozs7O1lBQWIsVUFBYyxNQUFjLEVBQUUsZ0JBQXdCLEVBQUUsTUFBTSxFQUFFLFVBQWtCO2dCQUNoRixxQkFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbkQscUJBQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBRS9DLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7b0JBQ3pDLE1BQU0sR0FBRyxNQUFNLEdBQUcsR0FBRyxDQUFDO2lCQUN2QjtnQkFFRCwyQ0FBTyxpQkFBUyxFQUFFLFlBQUksRUFBRSxnQkFBUSxDQUEwQjtnQkFFMUQscUJBQU0sZUFBZSxHQUFHLDJCQUEyQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFeEUscUJBQU0sZUFBZSxHQUFHLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBRTdGLHFCQUFNLFNBQVMsR0FBRyxlQUFlLEdBQUcsR0FBRyxHQUFHLGVBQWUsQ0FBQztnQkFFMUQsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ2pELHFCQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFDLGFBQWEsRUFBRSxLQUFHLE1BQVEsRUFBQyxHQUFHLEVBQUMsWUFBWSxFQUFFLEtBQUcsTUFBUSxFQUFDLENBQUM7b0JBRXZHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztpQkFDekU7Z0JBRUQsT0FBTyxlQUFlLENBQUM7YUFDeEI7Ozs7OztRQUVELHFDQUFZOzs7OztZQUFaLFVBQWEsS0FBSyxFQUFFLFVBQWtCO2dCQUNwQyxLQUFLLEdBQUcsS0FBSyxJQUFJLFNBQVMsQ0FBQzs7Z0JBRzNCLFFBQVEsS0FBSztvQkFDWCxLQUFLLE9BQU87d0JBQ1YsS0FBSyxHQUFHLFlBQVksQ0FBQzt3QkFDckIsTUFBTTtvQkFDUixLQUFLLEtBQUs7d0JBQ1IsS0FBSyxHQUFHLFVBQVUsQ0FBQzt3QkFDbkIsTUFBTTtpQkFDVDtnQkFFRCxxQkFBTSxTQUFTLEdBQUcsMEJBQTBCLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUVoRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsRUFBRTtvQkFDakQscUJBQU0sS0FBSyxHQUFHLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBQyxDQUFDO29CQUVwQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztpQkFDckQ7Z0JBRUQsT0FBTyxTQUFTLENBQUM7YUFDbEI7Ozs7UUFFRCxvQ0FBVzs7O1lBQVg7Z0JBQ0UscUJBQU0sU0FBUyxHQUFHLHlCQUF5QixFQUFFLENBQUM7Z0JBRTlDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUM1QyxxQkFBTSxLQUFLLEdBQUc7d0JBQ1osUUFBUSxFQUFFLENBQUM7d0JBQ1gsT0FBTyxFQUFFLE1BQU07d0JBQ2YsUUFBUSxFQUFFLE1BQU07d0JBQ2hCLFdBQVcsRUFBRSxNQUFNO3dCQUNuQixZQUFZLEVBQUUsTUFBTTtxQkFDckIsQ0FBQztvQkFFRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFDaEQ7Z0JBRUQsT0FBTyxTQUFTLENBQUM7YUFDbEI7Ozs7Ozs7UUFFRCxvQ0FBVzs7Ozs7O1lBQVgsVUFBWSxPQUFlLEVBQUUsSUFBYSxFQUFFLFVBQWtCO2dCQUM1RCxxQkFBTSxTQUFTLEdBQUcsNkJBQTZCLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFFM0UsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEVBQUU7b0JBQ2pELHFCQUFNLEtBQUssR0FBRzt3QkFDWixTQUFTLEVBQUUsSUFBSSxHQUFHLE9BQU8sSUFBSSxPQUFPLEdBQUcsTUFBTTtxQkFDOUMsQ0FBQztvQkFFRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztpQkFDckQ7Z0JBRUQsT0FBTyxTQUFTLENBQUM7YUFDbEI7Ozs7OztRQUVPLDJDQUFrQjs7Ozs7c0JBQUMsU0FBaUIsRUFBRSxVQUFrQjtnQkFDOUQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDOzs7Ozs7Ozs7UUFHdkQsMkNBQWtCOzs7Ozs7O3NCQUFDLFNBQWlCLEVBQUUsS0FBc0IsRUFBRSxVQUFrQixFQUFFLGlCQUE0QjtnQkFDcEgsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsaUJBQWlCLENBQUMsQ0FBQzs7Ozs7OztRQUdqRix5Q0FBZ0I7Ozs7O3NCQUFDLFNBQWlCLEVBQUUsVUFBa0I7Z0JBQzVELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQzs7Ozs7Ozs7O1FBR3JELHlDQUFnQjs7Ozs7OztzQkFBQyxTQUFpQixFQUFFLEtBQXNCLEVBQUUsVUFBa0IsRUFBRSxpQkFBNEI7Z0JBQ2xILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixDQUFDLENBQUM7Ozs7Ozs7UUFHL0UseUNBQWdCOzs7OztzQkFBQyxTQUFpQixFQUFFLFVBQWtCO2dCQUM1RCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7Ozs7Ozs7OztRQUdyRCx5Q0FBZ0I7Ozs7Ozs7c0JBQUMsU0FBaUIsRUFBRSxLQUFzQixFQUFFLFVBQWtCLEVBQUUsaUJBQTRCO2dCQUNsSCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDOzs7Ozs7OztRQUcvRSxxQ0FBWTs7Ozs7O3NCQUFDLFlBQWlDLEVBQUUsU0FBaUIsRUFBRSxVQUFrQjtnQkFDM0YsT0FBTyxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7Ozs7UUFHckYscUNBQVk7Ozs7Ozs7O3NCQUNsQixZQUFpQyxFQUFFLFNBQWlCLEVBQUUsS0FBc0IsRUFBRSxVQUFrQixFQUFFLGlCQUE0QjtnQkFDOUgsaUJBQWlCLEdBQUcsaUJBQWlCLElBQUksRUFBRSxDQUFDO2dCQUU1QyxxQkFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRXZDLHFCQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUVyQyxJQUFJLEdBQUcsS0FBSyxFQUFFLEVBQUU7b0JBQ2QscUJBQU0sUUFBUSxHQUFHLEdBQUcsR0FBRyxTQUFTLEdBQUcsS0FBSyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7b0JBRXRELHFCQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztvQkFFbEgsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7d0JBQ3JDLFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDO3FCQUN2QztvQkFFRCxZQUFZLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztvQkFFekQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN4Qzs7Ozs7O1FBR0ssNENBQW1COzs7O3NCQUFDLFlBQWlDOztnQkFDM0QscUJBQUksUUFBUSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBRW5FLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQUEsVUFBVTtvQkFDakMsUUFBUSxHQUFHLEtBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztpQkFDckYsQ0FBQyxDQUFDOzs7Ozs7OztRQUdLLGtEQUF5Qjs7Ozs7O1lBQW5DLFVBQW9DLFlBQWlDLEVBQUUsVUFBa0IsRUFBRSxRQUFvQjtnQkFBcEIseUJBQUE7b0JBQUEsWUFBb0I7O2dCQUM3RyxxQkFBTSxrQkFBa0IsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUU1RCxJQUFJLENBQUMsa0JBQWtCLEVBQUU7b0JBQ3ZCLE9BQU8sUUFBUSxDQUFDO2lCQUNqQjtnQkFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUEsR0FBRztvQkFDekMsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7d0JBQ3RDLFlBQVksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7cUJBQ2pHO3lCQUFNO3dCQUNMLFlBQVksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQ3pEO29CQUVELEVBQUUsUUFBUSxDQUFDO2lCQUNaLENBQUMsQ0FBQztnQkFFSCxPQUFPLFFBQVEsQ0FBQzthQUNqQjs7Ozs7UUFFTyxvQ0FBVzs7OztzQkFBQyxNQUFjO2dCQUNoQyxxQkFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUVmLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUEsR0FBRztvQkFDcEMscUJBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBRXhFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFFZCxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQUEsS0FBSzt3QkFDbEIsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUU7NEJBQ2xDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7eUJBQ3BDO3FCQUNGLENBQUMsQ0FBQztpQkFDSixDQUFDLENBQUM7Z0JBRUgsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzs7Ozs7O1FBR2YsdUNBQWM7Ozs7O3NCQUFDLGtCQUE0QixFQUFFLEdBQVc7Z0JBQzlELGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxVQUFBLFVBQVUsSUFBSSxPQUFBLFVBQVUsS0FBSyxLQUFLLEdBQUEsQ0FBQyxDQUFDO2dCQUVuRixJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFO29CQUM5QixPQUFPLEdBQUcsQ0FBQztpQkFDWjtnQkFFRCxxQkFBSSxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUV4QixJQUFJLENBQUMsV0FBVztxQkFDYixNQUFNLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBQSxDQUFDO3FCQUN2RSxPQUFPLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxjQUFjLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUEsQ0FBQyxDQUFDO2dCQUVuRixjQUFjLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxVQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFLLE9BQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEdBQUEsQ0FBQyxDQUFDO2dCQUU5RixPQUFPLFNBQVMsR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDOzs7b0JBcGJ4RUMsZUFBVTs7Ozs7d0RBU05DLFdBQU0sU0FBQ0MsZUFBUTt3REFDZkQsV0FBTSxTQUFDLG9CQUFvQjs7OzZCQTNFaEM7Ozs7Ozs7Ozs7QUNFQTs7UUFBQTtRQUdFLHVCQUNTLFlBQ0csUUFBbUI7WUFEdEIsZUFBVSxHQUFWLFVBQVU7WUFDUCxhQUFRLEdBQVIsUUFBUSxDQUFXOzhCQUpBLEVBQUU7U0FNaEM7Ozs7O1FBRUQscUNBQWE7Ozs7WUFBYixVQUFjLFVBQW9CO2dCQUFsQyxpQkFVQztnQkFUQyxVQUFVLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFLLE9BQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEdBQUEsQ0FBQyxDQUFDO2dCQUV0RixVQUFVLENBQUMsT0FBTyxDQUFDLFVBQUEsU0FBUyxJQUFJLE9BQUEsS0FBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsR0FBQSxDQUFDLENBQUM7Z0JBRTlELElBQUksQ0FBQyxVQUFVO3FCQUNaLE1BQU0sQ0FBQyxVQUFBLFNBQVMsSUFBSSxPQUFBLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFBLENBQUM7cUJBQ3RELE9BQU8sQ0FBQyxVQUFBLFNBQVMsSUFBSSxPQUFBLEtBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUEsQ0FBQyxDQUFDO2dCQUV6RCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQzthQUM5Qjs7Ozs7UUFFRCxvQ0FBWTs7OztZQUFaLFVBQWEsU0FBaUI7Z0JBQzVCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ2xFOzs7OztRQUVELHVDQUFlOzs7O1lBQWYsVUFBZ0IsU0FBaUI7Z0JBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3JFOzRCQTdCSDtRQThCQzs7Ozs7OztRQ2hCb0NFLG1DQUFhO1FBd0JoRCx5QkFDRSxVQUFzQixFQUN0QixRQUFtQixFQUNYO1lBSFYsWUFLRSxrQkFBTSxVQUFVLEVBQUUsUUFBUSxDQUFDLFNBQzVCO1lBSFMsYUFBTyxHQUFQLE9BQU87NkJBMUJHLEVBQUU7OEJBRUQsSUFBSUMsa0JBQWEsQ0FBQyxDQUFDLENBQUM7O1NBMkJ4QztRQXpCRCxzQkFBOEIsbUNBQU07Ozs7Z0JBQXBDLFVBQXFDLEdBQUcsSUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUc3RSxzQkFBOEIscUNBQVE7Ozs7O2dCQUF0QyxVQUF1QyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDNUUsc0JBQThCLHFDQUFROzs7O2dCQUF0QyxVQUF1QyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDNUUsc0JBQThCLHFDQUFROzs7O2dCQUF0QyxVQUF1QyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDNUUsc0JBQThCLHFDQUFROzs7O2dCQUF0QyxVQUF1QyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDNUUsc0JBQThCLHFDQUFROzs7O2dCQUF0QyxVQUF1QyxHQUFHLElBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFFNUUsc0JBQThCLHVDQUFVOzs7O2dCQUF4QyxVQUF5QyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDL0Usc0JBQThCLHVDQUFVOzs7O2dCQUF4QyxVQUF5QyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7UUFDL0Usc0JBQThCLHVDQUFVOzs7O2dCQUF4QyxVQUF5QyxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTs7O1dBQUE7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QUU7OztXQUFBO1FBQ3pFLHNCQUFnQyxxQ0FBSzs7OztnQkFBckMsVUFBc0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ3pFLHNCQUFnQyxxQ0FBSzs7OztnQkFBckMsVUFBc0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ3pFLHNCQUFnQyxxQ0FBSzs7OztnQkFBckMsVUFBc0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ3pFLHNCQUFnQyxxQ0FBSzs7OztnQkFBckMsVUFBc0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBRXpFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBRTlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQzlFLHNCQUFnQyx1Q0FBTzs7OztnQkFBdkMsVUFBd0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBOzs7O1FBVzlFLHFDQUFROzs7WUFBUjtnQkFDRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDeEI7Ozs7UUFFRCx3Q0FBVzs7O1lBQVg7Z0JBQ0UsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2FBQ2Y7Ozs7UUFFRCxtQ0FBTTs7O1lBQU47Z0JBQUEsaUJBY0M7Z0JBYkMscUJBQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQztnQkFFdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBQSxVQUFVO29CQUNqQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxnQkFBZ0I7d0JBQ3JELFVBQVUsQ0FBQyxJQUFJLENBQ2IsS0FBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQ3hILENBQUM7cUJBQ0gsQ0FBQyxDQUFDO2lCQUNKLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUUvQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDcEM7Ozs7UUFFRCw0Q0FBZTs7O1lBQWY7Z0JBQUEsaUJBUUM7Z0JBUEMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO29CQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2lCQUNqRDtxQkFBTTtvQkFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFBLFVBQVU7d0JBQ2pDLEtBQUksQ0FBQyxZQUFZLENBQUMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7cUJBQzlELENBQUMsQ0FBQztpQkFDSjthQUNGO1FBRUQsc0JBQUksNENBQVk7OztnQkFBaEI7Z0JBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDO2FBQzNEOzs7V0FBQTtRQUVELHNCQUFJLDJDQUFXOzs7Z0JBQWY7Z0JBQ0UsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNuQzs7O1dBQUE7O29CQS9FRkMsY0FBUyxTQUFDO3dCQUNULFFBQVEsRUFBRSwwU0FLVDtxQkFDRjs7Ozs7d0JBZG1CQyxlQUFVO3dCQUFpQkMsY0FBUzt3QkFHL0MsY0FBYzt3QkFFZCxlQUFlLHVCQW9DbkJFLGFBQVEsWUFBSUMsU0FBSTs7OzswQkFyQmxCRixVQUFLLFNBQUMsYUFBYTs0QkFDbkJBLFVBQUssU0FBQyxnQkFBZ0I7NEJBQ3RCQSxVQUFLLFNBQUMsZ0JBQWdCOzRCQUN0QkEsVUFBSyxTQUFDLGdCQUFnQjs0QkFDdEJBLFVBQUssU0FBQyxnQkFBZ0I7NEJBQ3RCQSxVQUFLLFNBQUMsZ0JBQWdCOzhCQUV0QkEsVUFBSyxTQUFDLG1CQUFtQjs4QkFDekJBLFVBQUssU0FBQyxtQkFBbUI7OEJBQ3pCQSxVQUFLLFNBQUMsbUJBQW1COzhCQUN6QkEsVUFBSyxTQUFDLG1CQUFtQjs4QkFFekJBLFVBQUssU0FBQyxtQkFBbUI7OEJBQ3pCQSxVQUFLLFNBQUMsbUJBQW1COzhCQUN6QkEsVUFBSyxTQUFDLG1CQUFtQjs4QkFDekJBLFVBQUssU0FBQyxtQkFBbUI7O2lDQW5DNUI7TUFld0MsYUFBYTs7Ozs7OztRQ0FsQkwsaUNBQWE7UUEyQjlDLHVCQUNFLFVBQXNCLEVBQ3RCLFFBQW1CLEVBQ1gsU0FDd0IsTUFBdUI7WUFKekQsWUFNRSxrQkFBTSxVQUFVLEVBQUUsUUFBUSxDQUFDLFNBSzVCO1lBUlMsYUFBTyxHQUFQLE9BQU87NkJBN0JOLEVBQUU7OEJBRUQsSUFBSUMsa0JBQWEsQ0FBQyxDQUFDLENBQUM7NkJBSVosQ0FBQzsyQkFDSCxDQUFDO1lBMkJqQixJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLGFBQWEsS0FBSyxLQUFJLENBQUMsYUFBYSxFQUFFO2dCQUNwRSxLQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzthQUN0Qjs7U0FDRjtRQTVCRCxzQkFBMkIsK0JBQUk7Ozs7Z0JBQS9CLFVBQWdDLEdBQUcsSUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUN4RSxzQkFBMkIsaUNBQU07Ozs7Z0JBQWpDLFVBQWtDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUN2RSxzQkFBMkIsaUNBQU07Ozs7Z0JBQWpDLFVBQWtDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUN2RSxzQkFBMkIsaUNBQU07Ozs7Z0JBQWpDLFVBQWtDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUN2RSxzQkFBMkIsaUNBQU07Ozs7Z0JBQWpDLFVBQWtDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUN2RSxzQkFBMkIsaUNBQU07Ozs7Z0JBQWpDLFVBQWtDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUV2RSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUMxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUMxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUMxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUUxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUMxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUMxRSxzQkFBMkIsbUNBQVE7Ozs7Z0JBQW5DLFVBQW9DLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7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UUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUM3RSxzQkFBZ0MsdUNBQU87Ozs7Z0JBQXZDLFVBQXdDLEdBQUcsSUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUU3RSxzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUVoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFOzs7V0FBQTtRQUNoRixzQkFBZ0MseUNBQVM7Ozs7Z0JBQXpDLFVBQTBDLEdB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SSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQy9FLHNCQUFpQyx5Q0FBUTs7OztnQkFBekMsVUFBMEMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQy9FLHNCQUFpQyx5Q0FBUTs7OztnQkFBekMsVUFBMEMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQy9FLHNCQUFpQyx5Q0FBUTs7OztnQkFBekMsVUFBMEMsR0FBRyxJQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBRS9FLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBRWxGLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUFpQywyQ0FBVTs7OztnQkFBM0MsVUFBNEMsR0FBRyxJQUFJLElBQUks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QkFBakMsVUFBa0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUEyQixxQ0FBTTs7OztnQkFBakMsVUFBa0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUEyQixxQ0FBTTs7OztnQkFBakMsVUFBa0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ2xGLHNCQUEyQixxQ0FBTTs7OztnQkFBakMsVUFBa0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBRWxGLHNCQUEyQix1Q0FBUTs7OztnQkFBbkMsVUFBb0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ3ZGLHNCQUEyQix1Q0FBUTs7OztnQkFBbkMsVUFBb0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ3ZGLHNCQUEyQix1Q0FBUTs7OztnQkFBbkMsVUFBb0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7OztXQUFBO1FBQ3ZGLHNCQUEyQix1Q0FBUTs7OztnQkFBbkMsVUFBb0MsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFD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