UNPKG

ng-cw-v12

Version:

Angular UI component library

841 lines 118 kB
import { isPlatformBrowser } from '@angular/common';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime, throttleTime } from 'rxjs/operators';
import * as i0 from "@angular/core";
export class NcCommonService {
    constructor(platformId, rendererFactory) {
        this.platformId = platformId;
        this.rendererFactory = rendererFactory;
        // ---------------------经纬度---------------------
        this.x_PI = 3.14159265358979324 * 3000.0 / 180.0;
        this.PI = 3.1415926535897932384626;
        this.a = 6378245.0;
        this.ee = 0.00669342162296594323;
        // ---------------------节流、防抖---------------------
        this.debounceTasks = new Map();
        this.throttleTasks = new Map();
        // ---------------------消息提示---------------------
        this.fullLoadingElement = null;
        this.fullLoadingKeyframesStyle = null;
        // ---------------------调试---------------------
        /**
        * 美化控制台打印(log info error warning success)
        */
        this.console = {
            log: (textOrTitle, content) => {
                const title = !content ? 'Log' : textOrTitle;
                const text = !content ? textOrTitle : content;
                this.prettyPrint(title, text, '#909399');
            },
            info: (textOrTitle, content) => {
                const title = !content ? 'Info' : textOrTitle;
                const text = !content ? textOrTitle : content;
                this.prettyPrint(title, text, '#40a9ff');
            },
            error: (textOrTitle, content) => {
                const title = !content ? 'Error' : textOrTitle;
                const text = !content ? textOrTitle : content;
                this.prettyPrint(title, text, '#F56C6C');
            },
            warning: (textOrTitle, content) => {
                const title = !content ? 'Warning' : textOrTitle;
                const text = !content ? textOrTitle : content;
                this.prettyPrint(title, text, '#E6A23C');
            },
            success: (textOrTitle, content) => {
                const title = !content ? 'Success' : textOrTitle;
                const text = !content ? textOrTitle : content;
                this.prettyPrint(title, text, '#67C23A');
            }
        };
        // 性能计时器
        this.timers = {};
        this.isBrowser = isPlatformBrowser(this.platformId);
        this.renderer = this.rendererFactory.createRenderer(null, null);
    }
    // ---------------------数字类---------------------
    /**
     * 精确加法
     * @param value1 第一个加数
     * @param value2 第二个加数
     * @returns 两数之和
     */
    mathAdd(value1, value2) {
        // 将浮点数转换为字符串
        let aStr = value1.toString();
        let bStr = value2.toString();
        // 找到小数点后的位置
        let aDecimals = (aStr.split('.')[1] || '').length;
        let bDecimals = (bStr.split('.')[1] || '').length;
        // 找到最大的小数位数
        let maxDecimals = Math.max(aDecimals, bDecimals);
        // 将浮点数转换为整数
        let aInt = Math.round(value1 * Math.pow(10, maxDecimals));
        let bInt = Math.round(value2 * Math.pow(10, maxDecimals));
        // 进行整数加法
        let resultInt = aInt + bInt;
        // 将结果转换回浮点数
        return resultInt / Math.pow(10, maxDecimals);
    }
    /**
     * 精确减法
     * @param value1 被减数
     * @param value2 减数
     * @returns 两数之差
     */
    mathSubtract(value1, value2) {
        // 将浮点数转换为字符串
        let aStr = value1.toString();
        let bStr = value2.toString();
        // 找到小数点后的位置
        let aDecimals = (aStr.split('.')[1] || '').length;
        let bDecimals = (bStr.split('.')[1] || '').length;
        // 找到最大的小数位数
        let maxDecimals = Math.max(aDecimals, bDecimals);
        // 将浮点数转换为整数
        let aInt = Math.round(value1 * Math.pow(10, maxDecimals));
        let bInt = Math.round(value2 * Math.pow(10, maxDecimals));
        // 进行整数减法
        let resultInt = aInt - bInt;
        // 将结果转换回浮点数
        return resultInt / Math.pow(10, maxDecimals);
    }
    /**
     * 精确乘法
     * @param value1 第一个乘数
     * @param value2 第二个乘数
     * @returns 两数之积
     */
    mathMultiply(value1, value2) {
        // 将浮点数转换为字符串
        let aStr = value1.toString();
        let bStr = value2.toString();
        // 找到小数点后的位置
        let aDecimals = (aStr.split('.')[1] || '').length;
        let bDecimals = (bStr.split('.')[1] || '').length;
        // 将浮点数转换为整数
        let aInt = parseInt(aStr.replace('.', ''));
        let bInt = parseInt(bStr.replace('.', ''));
        // 进行整数乘法
        let resultInt = aInt * bInt;
        // 计算最终的小数位数
        let totalDecimals = aDecimals + bDecimals;
        // 将结果转换回浮点数
        return resultInt / Math.pow(10, totalDecimals);
    }
    /**
     * 精确除法
     * @param value1 被除数
     * @param value2 除数
     * @returns 两数之商
     */
    mathDivide(value1, value2) {
        // 将浮点数转换为字符串
        let aStr = value1.toString();
        let bStr = value2.toString();
        // 找到小数点后的位置
        let aDecimals = (aStr.split('.')[1] || '').length;
        let bDecimals = (bStr.split('.')[1] || '').length;
        // 找到最大的小数位数
        let maxDecimals = Math.max(aDecimals, bDecimals);
        // 将浮点数转换为整数
        let aInt = Math.round(value1 * Math.pow(10, maxDecimals));
        let bInt = Math.round(value2 * Math.pow(10, maxDecimals));
        // 进行整数除法并直接返回结果
        return aInt / bInt;
    }
    /**
     * 保留指定小数位数
     * @param num 需要处理的数值
     * @param len 要保留的小数位数
     * @returns 处理后的数值,保留指定小数位数
     */
    retainDecimal(num, len) {
        const n = Math.pow(10, len);
        return Math.round(num * n) / n;
    }
    /**
     * 保留指定小数位数的百分比
     * @param num 需要处理的数值
     * @param len 要保留的小数位数
     * @returns 处理后的百分比值,保留指定小数位数
     */
    retainPercentDecimal(num, len) {
        const n = Math.pow(10, len + 2);
        return this.mathMultiply(Math.round(num * n) / n, 100);
    }
    // ---------------------存储---------------------
    /**
     * 设置Cookie
     * @param key Cookie的键
     * @param value Cookie的值
     * @param ttl Cookie的生存时间(毫秒)
     */
    setCookie(key, value, ttl) {
        const expires = new Date(Date.now() + ttl).toUTCString();
        document.cookie = `${key}=${encodeURIComponent(value)};expires=${expires};path=/`;
    }
    /**
     * 获取Cookie
     * @param key Cookie的键
     * @returns Cookie的值,如果不存在则返回null
     */
    getCookie(key) {
        const match = document.cookie.match(new RegExp('(^| )' + key + '=([^;]+)'));
        return match ? decodeURIComponent(match[2]) : null;
    }
    /**
     * 删除指定的Cookie
     * @param key 要删除的Cookie的键
     */
    removeCookie(key) {
        document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
    }
    /**
     * 清除所有Cookie
     */
    clearCookie() {
        document.cookie.split(";").forEach(c => {
            document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/");
        });
    }
    /**
     * 设置LocalStorage项
     * @param key LocalStorage的键
     * @param value LocalStorage的值
     * @param ttl 可选的生存时间(毫秒)
     */
    setLocalStorage(key, value, ttl) {
        const item = { value, expiry: ttl ? Date.now() + ttl : null };
        localStorage.setItem(key, JSON.stringify(item));
    }
    /**
     * 获取LocalStorage项
     * @param key LocalStorage的键
     * @returns LocalStorage的值,如果不存在或已过期则返回null
     */
    getLocalStorage(key) {
        const itemStr = localStorage.getItem(key);
        if (!itemStr)
            return null;
        const item = JSON.parse(itemStr);
        if (item.expiry && Date.now() > item.expiry) {
            localStorage.removeItem(key);
            return null;
        }
        return item.value;
    }
    /**
     * 删除指定的LocalStorage项
     * @param key 要删除的LocalStorage项的键
     */
    removeLocalStorage(key) {
        localStorage.removeItem(key);
    }
    /**
     * 清除所有LocalStorage项
     */
    clearLocalStorage() {
        localStorage.clear();
    }
    /**
     * 设置SessionStorage项
     * @param key SessionStorage的键
     * @param value SessionStorage的值
     */
    setSessionStorage(key, value) {
        sessionStorage.setItem(key, JSON.stringify(value));
    }
    /**
     * 获取SessionStorage项
     * @param key SessionStorage的键
     * @returns SessionStorage的值,如果不存在则返回null
     */
    getSessionStorage(key) {
        const item = sessionStorage.getItem(key);
        return item ? JSON.parse(item) : null;
    }
    /**
     * 删除指定的SessionStorage项
     * @param key 要删除的SessionStorage项的键
     */
    removeSessionStorage(key) {
        sessionStorage.removeItem(key);
    }
    /**
     * 清除所有SessionStorage项
     */
    clearSessionStorage() {
        sessionStorage.clear();
    }
    // ---------------------日期类---------------------
    /**
     * 格式化时间
     * @param format 格式化模板,如 'yyyy-MM-dd HH:mm:ss',注意MM为月份、mm为分钟
     * @param dateInput 可选。要格式化的日期,可以是Date对象、时间戳(number)或日期字符串,默认为当前时间
     * @returns 格式化后的日期字符串
     */
    formatDate(format, dateInput) {
        if (!format) {
            return '';
        }
        let date;
        if (!dateInput) {
            date = new Date();
        }
        else if (dateInput instanceof Date) {
            date = dateInput;
        }
        else {
            date = new Date(dateInput);
        }
        // 验证日期是否有效
        if (isNaN(date.getTime())) {
            console.warn('Invalid date input provided to formatDate');
            return '';
        }
        const year = date.getFullYear().toString();
        const month = (date.getMonth() + 1).toString().padStart(2, '0');
        const day = (date.getDate()).toString().padStart(2, '0');
        const hours = (date.getHours()).toString().padStart(2, '0');
        const minutes = (date.getMinutes()).toString().padStart(2, '0');
        const seconds = (date.getSeconds()).toString().padStart(2, '0');
        return format
            .replace('yyyy', year)
            .replace('MM', month)
            .replace('dd', day)
            .replace('HH', hours)
            .replace('mm', minutes)
            .replace('ss', seconds);
    }
    /**
     * 获取两日期间的所有日期
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @returns 日期数组
     */
    getRangeDate(startDate, endDate) {
        let datesArray = [];
        let currentDate = new Date(startDate);
        while (currentDate <= endDate) {
            datesArray.push(new Date(currentDate));
            currentDate.setDate(currentDate.getDate() + 1);
        }
        return datesArray;
    }
    /**
    * 获取两日期间的天数
    * @param startDate 开始日期
    * @param endDate 结束日期
    * @returns 天数
    */
    getDaysBetween(startDate, endDate) {
        const oneDay = 24 * 60 * 60 * 1000;
        return Math.round(Math.abs((startDate.getTime() - endDate.getTime()) / oneDay));
    }
    // ---------------------数组、对象---------------------
    /**
     * 数组去重
     * @param array 要去重的数组
     * @param keyFn 可选的函数,用于从每个数组项中提取用于比较的键,例如:item => item.id
     * @returns T[]
     */
    uniqueArray(array, keyFn) {
        if (!keyFn) {
            return Array.from(new Set(array));
        }
        const seen = new Set();
        return array.filter(item => {
            const key = keyFn(item);
            if (seen.has(key)) {
                return false;
            }
            seen.add(key);
            return true;
        });
    }
    /**
     * 数组排序
     * @param array 要排序的数组
     * @param order 指定排序顺序,'asc' 为升序,'desc' 为降序
     * @param keyFn 可选。可以是对象的键名或一个函数,用于从数组项中提取排序值,例如:'age'或 item => item.name.length
     * @returns T[]
     */
    sortArray(array, order, key) {
        return [...array].sort((a, b) => {
            let valueA;
            let valueB;
            if (typeof key === 'function') {
                valueA = key(a);
                valueB = key(b);
            }
            else if (key) {
                valueA = a[key];
                valueB = b[key];
            }
            else {
                valueA = a;
                valueB = b;
            }
            if (valueA === valueB)
                return 0;
            if (typeof valueA === 'string' && typeof valueB === 'string') {
                return order === 'asc'
                    ? valueA.localeCompare(valueB)
                    : valueB.localeCompare(valueA);
            }
            return order === 'asc'
                ? (valueA < valueB ? -1 : 1)
                : (valueB < valueA ? -1 : 1);
        });
    }
    /**
     * 判断对象是否为空
     * @param obj
     * @returns boolean
     */
    isObjectEmpty(obj) {
        return Object.keys(obj).length === 0;
    }
    /**
     * 百度坐标系 (BD-09) 与火星坐标系 (GCJ-02) 的转换
     * 即百度 转 谷歌、高德
     * @param lng 经度
     * @param lat 纬度
     * @returns [lng, lat]
     */
    bd09togcj02(lng, lat) {
        var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        var x = lng - 0.0065;
        var y = lat - 0.006;
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        var gg_lng = z * Math.cos(theta);
        var gg_lat = z * Math.sin(theta);
        return [gg_lng, gg_lat];
    }
    /**
     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
     * 即谷歌、高德 转 百度
     * @param lng 经度
     * @param lat 纬度
     * @returns [lng, lat]
     */
    gcj02tobd09(lng, lat) {
        var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * this.x_PI);
        var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * this.x_PI);
        var bd_lng = z * Math.cos(theta) + 0.0065;
        var bd_lat = z * Math.sin(theta) + 0.006;
        return [bd_lng, bd_lat];
    }
    /**
     * WGS84转火星坐标系 (GCJ-02)
     * 即WGS84 转 谷歌、高德
     * @param lng 经度
     * @param lat 纬度
     * @returns [lng, lat]
     */
    wgs84togcj02(lng, lat) {
        if (this.out_of_china(lng, lat)) {
            return [lng, lat];
        }
        else {
            var dlat = this.transformlat(lng - 105.0, lat - 35.0);
            var dlng = this.transformlng(lng - 105.0, lat - 35.0);
            var radlat = lat / 180.0 * this.PI;
            var magic = Math.sin(radlat);
            magic = 1 - this.ee * magic * magic;
            var sqrtmagic = Math.sqrt(magic);
            dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
            dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
            var mglat = lat + dlat;
            var mglng = lng + dlng;
            return [mglng, mglat];
        }
    }
    /**
     * 火星坐标系 (GCJ-02)转WGS84
     * 即谷歌、高德 转 WGS84
     * @param lng 经度
     * @param lat 纬度
     * @returns [lng, lat]
     */
    gcj02towgs84(lng, lat) {
        if (this.out_of_china(lng, lat)) {
            return [lng, lat];
        }
        else {
            var dlat = this.transformlat(lng - 105.0, lat - 35.0);
            var dlng = this.transformlng(lng - 105.0, lat - 35.0);
            var radlat = lat / 180.0 * this.PI;
            var magic = Math.sin(radlat);
            magic = 1 - this.ee * magic * magic;
            var sqrtmagic = Math.sqrt(magic);
            dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI);
            dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI);
            let mglat = lat + dlat;
            let mglng = lng + dlng;
            return [lng * 2 - mglng, lat * 2 - mglat];
        }
    }
    transformlat(lng, lat) {
        var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * this.PI) + 40.0 * Math.sin(lat / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lat / 12.0 * this.PI) + 320 * Math.sin(lat * this.PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }
    transformlng(lng, lat) {
        var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lng * this.PI) + 40.0 * Math.sin(lng / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lng / 12.0 * this.PI) + 300.0 * Math.sin(lng / 30.0 * this.PI)) * 2.0 / 3.0;
        return ret;
    }
    /**
     * 判断是否在国内,不在国内则不做偏移
     */
    out_of_china(lng, lat) {
        return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
    }
    /**
    * 小数形式经纬度转度分秒形式(秒保留3位小数)
    * @param digital  109.86330555555556
    * @returns degrees '109°51′47.9″'
    */
    digitalToDegrees(digital) {
        let digitalString = digital.toString();
        let index1 = digitalString.indexOf('.');
        let du = index1 < 0 ? Number(digitalString) : Number(digitalString.substring(0, index1)); //109
        let fen = 0;
        let miao = 0;
        if (index1 > 0) {
            let strFen = Number("0" + digitalString.substring(index1)); //0.86330555555556
            let strFenString = (strFen * 60).toString(); //'51.7983333333336'
            let index2 = strFenString.indexOf('.');
            if (index2 > 0) {
                fen = Number(strFenString.substring(0, index2)); //51
                let strMiao = Number("0" + strFenString.substring(index2)); //0.7983333333336
                miao = Number((strMiao * 60).toFixed(3)); //47.900000000016  47.9
            }
            else {
                fen = Number(strFenString);
            }
        }
        return `${du}°${fen}′${miao}″`;
    }
    /**
     * 度分秒形式经纬度转小数形式
     * @param degrees  '109°51′47.900000000016″'
     * @returns digital 109.86330555555556
     */
    degreesToDigital(degrees) {
        let temp1 = degrees.split('°');
        let temp2 = temp1[1].split('′');
        let du = temp1[0];
        let fen = temp2[0];
        let miao = temp2[1].substring(0, temp2[1].length - 1);
        return Number(du) + Number(fen) / 60 + Number(miao) / 3600;
    }
    /**
     * 防抖(Debounce):适用于避免短时间内多次触发的场景,只有在事件停止触发后的一段时间才会执行。例如:搜索框输入,避免频繁的API请求。
     * @param key 用于标识Subject的唯一键,不同防抖任务应使用不同的key,相同key的任务会共享首次设置的delay时间
     * @param delay 防抖延迟时间(毫秒)
     * @param fn 要防抖的函数
     */
    debounce(key, delay, fn) {
        let subject = this.debounceTasks.get(key);
        if (!subject) {
            subject = new Subject();
            subject.pipe(debounceTime(delay)).subscribe(fnToExecute => {
                fnToExecute();
            });
            this.debounceTasks.set(key, subject);
        }
        subject.next(fn);
    }
    /**
    * 节流(Throttle):适用于限制事件在固定时间间隔内执行的场景,确保事件不会过于频繁地触发。例如:滚动页面时的事件处理,避免频繁的计算和渲染。
    * @param key 用于标识Subject的唯一键,不同节流任务应使用不同的key,相同key的任务会共享首次设置的delay时间
    * @param delay 节流延迟时间(毫秒)
    * @param fn 要节流的函数
    */
    throttle(key, delay, fn) {
        let subject = this.throttleTasks.get(key);
        if (!subject) {
            subject = new Subject();
            subject.pipe(throttleTime(delay)).subscribe(fnToExecute => {
                fnToExecute();
            });
            this.throttleTasks.set(key, subject);
        }
        subject.next(fn);
    }
    /**
     * 显示全屏加载中(全屏蒙版)
     *  @param content 可选。提示内容,默认:'加载中,请稍后...'
     */
    showFullLoading(content = '加载中,请稍后...') {
        if (this.fullLoadingElement) {
            return;
        }
        this.fullLoadingElement = this.renderer.createElement('div');
        this.renderer.addClass(this.fullLoadingElement, 'full-loading-container');
        this.renderer.setStyle(this.fullLoadingElement, 'position', 'fixed');
        this.renderer.setStyle(this.fullLoadingElement, 'top', '0');
        this.renderer.setStyle(this.fullLoadingElement, 'left', '0');
        this.renderer.setStyle(this.fullLoadingElement, 'width', '100%');
        this.renderer.setStyle(this.fullLoadingElement, 'height', '100%');
        this.renderer.setStyle(this.fullLoadingElement, 'background-color', 'rgba(0,0,0,0.5)');
        this.renderer.setStyle(this.fullLoadingElement, 'display', 'flex');
        this.renderer.setStyle(this.fullLoadingElement, 'flex-direction', 'column');
        this.renderer.setStyle(this.fullLoadingElement, 'justify-content', 'center');
        this.renderer.setStyle(this.fullLoadingElement, 'align-items', 'center');
        this.renderer.setStyle(this.fullLoadingElement, 'z-index', '9999');
        const spinner = this.renderer.createElement('div');
        this.renderer.addClass(spinner, 'full-loading-spinner');
        this.renderer.setStyle(spinner, 'border', '4px solid #f3f3f3');
        this.renderer.setStyle(spinner, 'border-top', '4px solid #3498db');
        this.renderer.setStyle(spinner, 'border-radius', '50%');
        this.renderer.setStyle(spinner, 'width', '50px');
        this.renderer.setStyle(spinner, 'height', '50px');
        this.renderer.setStyle(spinner, 'animation', 'fullSpin 1s linear infinite');
        const loadingText = this.renderer.createElement('div');
        this.renderer.addClass(loadingText, 'full-loading-text');
        this.renderer.setStyle(loadingText, 'color', 'white');
        this.renderer.setStyle(loadingText, 'margin-top', '20px');
        this.renderer.setStyle(loadingText, 'font-size', '18px');
        this.renderer.setStyle(loadingText, 'letter-spacing', '1.5px');
        this.renderer.appendChild(loadingText, this.renderer.createText(content));
        const keyframes = `
            @keyframes fullSpin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
        `;
        this.fullLoadingKeyframesStyle = this.renderer.createElement('style');
        this.renderer.appendChild(this.fullLoadingKeyframesStyle, this.renderer.createText(keyframes));
        this.renderer.appendChild(document.body, this.fullLoadingKeyframesStyle);
        this.renderer.appendChild(this.fullLoadingElement, spinner);
        if (content) {
            this.renderer.appendChild(this.fullLoadingElement, loadingText);
        }
        this.renderer.appendChild(document.body, this.fullLoadingElement);
    }
    /**
    * 移除全屏加载中(全屏蒙版)
    */
    removeFullLoading() {
        if (this.fullLoadingElement) {
            this.renderer.removeChild(document.body, this.fullLoadingElement);
            this.fullLoadingElement = null;
        }
        if (this.fullLoadingKeyframesStyle) {
            this.renderer.removeChild(document.body, this.fullLoadingKeyframesStyle);
            this.fullLoadingKeyframesStyle = null;
        }
    }
    //美化打印
    prettyPrint(title, content, color) {
        console.log(`%c ${title} %c ${typeof content == 'object' ? '👇' : content} %c`, `background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`, `border:1px solid ${color}; border-radius: 0 2px 2px 0; color: ${color};padding: 1px;`, 'background:transparent');
        if (typeof content == 'object') {
            console.table(content);
        }
    }
    ;
    /**
     * 开始性能计时器
     * @param timerName 计时器名称
     */
    startTimer(timerName) {
        this.timers[timerName] = performance.now();
    }
    /**
     * 结束性能计时器并返回持续时间
     * @param timerName 计时器名称
     * @returns 计时器持续时间(毫秒)
     */
    endTimer(timerName) {
        if (!this.timers[timerName]) {
            console.warn(`计时器 "${timerName}" 不存在。`);
            return 0;
        }
        const duration = performance.now() - this.timers[timerName];
        delete this.timers[timerName];
        return duration;
    }
    // ---------------------其他---------------------
    /**
    * 深克隆
    * @param obj 被克隆对象
    * @returns 克隆对象
    */
    deepClone(obj, seen = new Map()) {
        // Handle immutable types and functions
        if (obj === null || typeof obj !== 'object') {
            return obj;
        }
        // Handle circular references
        if (seen.has(obj)) {
            return seen.get(obj);
        }
        // Handle Date
        if (obj instanceof Date) {
            return new Date(obj.getTime());
        }
        // Handle RegExp
        if (obj instanceof RegExp) {
            const regExpClone = new RegExp(obj.source, obj.flags);
            regExpClone.lastIndex = obj.lastIndex; // Preserve the lastIndex property
            return regExpClone;
        }
        // Handle Array
        if (Array.isArray(obj)) {
            const arrClone = [];
            seen.set(obj, arrClone);
            for (const item of obj) {
                arrClone.push(this.deepClone(item, seen));
            }
            return arrClone;
        }
        // Handle Set
        if (obj instanceof Set) {
            const setClone = new Set();
            seen.set(obj, setClone);
            for (const item of obj) {
                setClone.add(this.deepClone(item, seen));
            }
            return setClone;
        }
        // Handle Map
        if (obj instanceof Map) {
            const mapClone = new Map();
            seen.set(obj, mapClone);
            for (const [key, value] of obj) {
                mapClone.set(this.deepClone(key, seen), this.deepClone(value, seen));
            }
            return mapClone;
        }
        // Handle Object
        const objClone = Object.create(Object.getPrototypeOf(obj));
        seen.set(obj, objClone);
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                objClone[key] = this.deepClone(obj[key], seen);
            }
        }
        return objClone;
    }
    /**
     * 获取文件后缀
     * @param filename string 文件名
     * @returns extension
     */
    getFileExtension(filename) {
        if (!filename) {
            return '';
        }
        const filenameArr = filename.split('.');
        if (filenameArr.length == 0) {
            return '';
        }
        else {
            const extension = filenameArr.pop();
            return extension.toLowerCase();
        }
    }
    /**
     * jsonp封装
     * @param obj \{url: '', success: ()=> {}}
     */
    jsonpFunction(obj) {
        // 创建一个script标签;
        var script = document.createElement("script");
        // 给函数起名字,定义为全局函数;
        var fnName = "jsonp" + new Date().getTime();
        // window.aaa就是把aaa设置为全局变量!
        window[fnName] = obj.success;
        // 改变src,添加到head中
        if (obj.url.includes('?')) {
            script.src = obj.url + "&callback=" + fnName;
        }
        else {
            script.src = obj.url + "?callback=" + fnName;
        }
        // 把script标签添加到head标签中,就会发送src的请求了
        document.head.appendChild(script);
        // 代码执行完毕,把script标签删除
        script.onload = function () {
            document.head.removeChild(script);
            window[fnName] = undefined;
        };
    }
    /**
     * 生成随机颜色
     * @returns HEX
     */
    generateRandomColor() {
        return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
    }
    /**
    * 生成UUID
    * @returns UUID
    */
    generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }
    /**
     * 验证密码强度(必须包含大、小写字母、数字、特殊字符至少三类,长度8-16位)
     * @param password 待验证的密码
     * @returns 密码是否符合要求
     */
    passwordValidate(password) {
        // 检查密码长度是否在8到16位之间
        if (password.length < 8 || password.length > 16) {
            return false;
        }
        // 定义正则表达式规则
        let rC = {
            lW: '[a-z]',
            uW: '[A-Z]',
            nW: '[0-9]',
            sW: '[`~!@$%\^\&\(\)\-_\+=\{\}\[\]|\\:;\"\'<>,\.\?\/_]' // 特殊字符
        };
        /**
         * 检查字符串是否匹配正则表达式
         * @param str 待检查的字符串
         * @param rStr 正则表达式字符串
         * @returns 是否匹配
         */
        function Reg(str, rStr) {
            let reg = new RegExp(rStr);
            return reg.test(str);
        }
        // 检查密码是否包含各种字符类型
        let tR = {
            l: Reg(password, rC.lW),
            u: Reg(password, rC.uW),
            n: Reg(password, rC.nW),
            s: Reg(password, rC.sW) // 是否包含特殊字符
        };
        // 密码必须包含以下四种组合之一:
        // 1. 小写字母 + 大写字母 + 数字
        // 2. 小写字母 + 大写字母 + 特殊字符
        // 3. 特殊字符 + 大写字母 + 数字
        // 4. 特殊字符 + 小写字母 + 数字
        return (tR.l && tR.u && tR.n) || (tR.l && tR.u && tR.s) || (tR.s && tR.u && tR.n) || (tR.s && tR.l && tR.n);
    }
}
NcCommonService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService, deps: [{ token: PLATFORM_ID }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
NcCommonService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: Object, decorators: [{
                    type: Inject,
                    args: [PLATFORM_ID]
                }] }, { type: i0.RendererFactory2 }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2NvbW1vbi1zZXJ2aWNlL2NvbW1vbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBK0IsTUFBTSxlQUFlLENBQUM7QUFDN0YsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQW9DNUQsTUFBTSxPQUFPLGVBQWU7SUFHeEIsWUFBeUMsVUFBa0IsRUFBVSxlQUFpQztRQUE3RCxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWtCO1FBZ1p0RyxnREFBZ0Q7UUFFeEMsU0FBSSxHQUFHLG1CQUFtQixHQUFHLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDNUMsT0FBRSxHQUFHLHdCQUF3QixDQUFDO1FBQzlCLE1BQUMsR0FBRyxTQUFTLENBQUM7UUFDZCxPQUFFLEdBQUcsc0JBQXNCLENBQUM7UUF3SnBDLGtEQUFrRDtRQUUxQyxrQkFBYSxHQUFtQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFELGtCQUFhLEdBQW1DLElBQUksR0FBRyxFQUFFLENBQUM7UUF5Q2xFLGlEQUFpRDtRQUV6Qyx1QkFBa0IsR0FBdUIsSUFBSSxDQUFDO1FBQzlDLDhCQUF5QixHQUF1QixJQUFJLENBQUM7UUEwRTdELCtDQUErQztRQUUvQzs7VUFFRTtRQUNGLFlBQU8sR0FBa0I7WUFDckIsR0FBRyxFQUFFLENBQUMsV0FBZ0IsRUFBRSxPQUFZLEVBQUUsRUFBRTtnQkFDcEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxD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QUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFBO1NBQzVDO0lBQ0wsQ0FBQztJQUVPLFlBQVksQ0FBQyxHQUFXLEVBQUUsR0FBVztRQUN6QyxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzlHLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNqRyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUMzRixHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDbkcsT0FBTyxHQUFHLENBQUE7SUFDZCxDQUFDO0lBRU8sWUFBWSxDQUFDLEdBQVcsRUFBRSxHQUFXO1FBQ3pDLElBQUksR0FBRyxHQUFHLEtBQUssR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdkcsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2pHLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQzNGLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNyRyxPQUFPLEdBQUcsQ0FBQTtJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNLLFlBQVksQ0FBQyxHQUFXLEVBQUUsR0FBVztRQUN6QyxPQUFPLENBQUMsR0FBRyxHQUFHLE1BQU0sSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxNQUFNLElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFRDs7OztNQUlFO0lBQ0YsZ0JBQWdCLENBQUMsT0FBZTtRQUM1QixJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDdkMsSUFBSSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QyxJQUFJLEVBQUUsR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUEsS0FBSztRQUM5RixJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDWixJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7UUFDYixJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDWixJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBLGtCQUFrQjtZQUM3RSxJQUFJLFlBQVksR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBLG9CQUFvQjtZQUNoRSxJQUFJLE1BQU0sR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDWixHQUFHLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQSxJQUFJO2dCQUNwRCxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBLGlCQUFpQjtnQkFDNUUsSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLHVCQUF1QjthQUNuRTtpQkFBTTtnQkFDSCxHQUFHLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQzlCO1NBQ0o7UUFFRCxPQUFPLEdBQUcsRUFBRSxJQUFJLEdBQUcsSUFBSSxJQUFJLEdBQUcsQ0FBQTtJQUNsQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdCQUFnQixDQUFDLE9BQWU7UUFDNUIsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkIsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUV0RCxPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7SUFDL0QsQ0FBQztJQU1EOzs7OztPQUtHO0lBQ0gsUUFBUSxDQUFDLEdBQVcsRUFBRSxLQUFhLEVBQUUsRUFBWTtRQUM3QyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUxQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1YsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFZLENBQUM7WUFDbEMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQ3RELFdBQVcsRUFBRSxDQUFDO1lBQ2xCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQ3hDO1FBRUQsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7O01BS0U7SUFDRixRQUFRLENBQUMsR0FBVyxFQUFFLEtBQWEsRUFBRSxFQUFZO1FBQzdDLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTFDLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDVixPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQVksQ0FBQztZQUNsQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDdEQsV0FBVyxFQUFFLENBQUM7WUFDbEIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDeEM7UUFFRCxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFPRDs7O09BR0c7SUFDSCxlQUFlLENBQUMsVUFBa0IsWUFBWTtRQUMxQyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUN6QixPQUFPO1NBQ1Y7UUFFRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3ZGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFbkUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFFNUUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRTFFLE1BQU0sU0FBUyxHQUFHOzs7OztTQUtqQixDQUFDO1FBQ0YsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9GLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFekUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVELElBQUksT0FBTyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1NBQ25FO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7O01BRUU7SUFDRixpQkFBaUI7UUFDYixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7U0FDbEM7UUFFRCxJQUFJLElBQUksQ0FBQyx5QkFBeUIsRUFBRTtZQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQ3pFLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUM7U0FDekM7SUFDTCxDQUFDO0lBbUNELE1BQU07SUFDRSxXQUFXLENBQUMsS0FBYSxFQUFFLE9BQVksRUFBRSxLQUFhO1FBQzFELE9BQU8sQ0FBQyxHQUFHLENBQ1AsTUFBTSxLQUFLLE9BQU8sT0FBTyxPQUFPLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxFQUNsRSxjQUFjLEtBQUsscUJBQXFCLEtBQUssMERBQTBELEVBQ3ZHLG9CQUFvQixLQUFLLHdDQUF3QyxLQUFLLGdCQUFnQixFQUN0Rix3QkFBd0IsQ0FDM0IsQ0FBQztRQUNGLElBQUksT0FBTyxPQUFPLElBQUksUUFBUSxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBQUEsQ0FBQztJQUtGOzs7T0FHRztJQUNILFVBQVUsQ0FBQyxTQUFpQjtRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxTQUFpQjtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUN6QixPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsU0FBUyxRQUFRLENBQUMsQ0FBQztZQUN4QyxPQUFPLENBQUMsQ0FBQztTQUNaO1FBQ0QsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlCLE9BQU8sUUFBUSxDQUFDO0lBQ3BCLENBQUM7SUFFRCwrQ0FBK0M7SUFFL0M7Ozs7TUFJRTtJQUNGLFNBQVMsQ0FBSSxHQUFNLEVBQUUsSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFO1FBQ2pDLHVDQUF1QztRQUN2QyxJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFO1lBQ3pDLE9BQU8sR0FBRyxDQUFDO1NBQ2Q7UUFFRCw2QkFBNkI7UUFDN0IsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2YsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3hCO1FBRUQsY0FBYztRQUNkLElBQUksR0FBRyxZQUFZLElBQUksRUFBRTtZQUNyQixPQUFPLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBUSxDQUFDO1NBQ3pDO1FBRUQsZ0JBQWdCO1FBQ2hCLElBQUksR0FBRyxZQUFZLE1BQU0sRUFBRTtZQUN2QixNQUFNLFdBQVcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxrQ0FBa0M7WUFDekUsT0FBTyxXQUFrQixDQUFDO1NBQzdCO1FBRUQsZUFBZTtRQUNmLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNwQixNQUFNLFFBQVEsR0FBVSxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDeEIsS0FBSyxNQUFNLElBQUksSUFBSSxHQUFHLEVBQUU7Z0JBQ3BCLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUM3QztZQUNELE9BQU8sUUFBZSxDQUFDO1NBQzFCO1FBRUQsYUFBYTtRQUNiLElBQUksR0FBRyxZQUFZLEdBQUcsRUFBRTtZQUNwQixNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3hCLEtBQUssTUFBTSxJQUFJLElBQUksR0FBRyxFQUFFO2dCQUNwQixRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDNUM7WUFDRCxPQUFPLFFBQWUsQ0FBQztTQUMxQjtRQUVELGFBQWE7UUFDYixJQUFJLEdBQUcsWUFBWSxHQUFHLEVBQUU7WUFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN4QixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxFQUFFO2dCQUM1QixRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDeEU7WUFDRCxPQUFPLFFBQWUsQ0FBQztTQUMxQjtRQUVELGdCQUFnQjtRQUNoQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4QixLQUFLLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBRTtZQUNuQixJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ2hELFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFFLEdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUMzRDtTQUNKO1FBQ0QsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxnQkFBZ0IsQ0FBQyxRQUFnQjtRQUM3QixJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ1gsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUNELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsSUFBSSxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtZQUN6QixPQUFPLEVBQUUsQ0FBQztTQUNiO2FBQU07WUFDSCxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFHLENBQUM7WUFDckMsT0FBTyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDbEM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLEdBQVE7UUFDbEIsZ0JBQWdCO1FBQ2hCLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUMsa0JBQWtCO1FBQ2xCLElBQUksTUFBTSxHQUFRLE9BQU8sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pELDJCQUEyQjtRQUMzQixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztRQUM3QixpQkFBaUI7UUFDakIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN2QixNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsWUFBWSxHQUFHLE1BQU0sQ0FBQztTQUNoRDthQUFNO1lBQ0gsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLFlBQVksR0FBRyxNQUFNLENBQUM7U0FDaEQ7UUFDRCxrQ0FBa0M7UUFDbEMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMscUJBQXFCO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLEdBQUc7WUFDWixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNqQyxNQUFNLENBQUMsTUFBTSxDQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3hDLENBQUMsQ0FBQTtJQUNMLENBQUM7SUFPRDs7O09BR0c7SUFDSCxtQkFBbUI7UUFDZixPQUFPLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQ7OztNQUdFO0lBQ0YsWUFBWTtRQUNSLE9BQU8sc0NBQXNDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2pFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNuRSxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdCQUFnQixDQUFDLFFBQWdCO1FBQzdCLG1CQUFtQjtRQUNuQixJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFO1lBQzdDLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBRUQsWUFBWTtRQUNaLElBQUksRUFBRSxHQUFHO1lBQ0wsRUFBRSxFQUFFLE9BQU87WUFDWCxFQUFFLEVBQUUsT0FBTztZQUNYLEVBQUUsRUFBRSxPQUFPO1lBQ1gsRUFBRSxFQUFFLG1EQUFtRCxDQUFFLE9BQU87U0FDbkUsQ0FBQztRQUVGOzs7OztXQUtHO1FBQ0gsU0FBUyxHQUFHLENBQUMsR0FBVyxFQUFFLElBQVk7WUFDbEMsSUFBSSxHQUFHLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFFRCxpQkFBaUI7UUFDakIsSUFBSSxFQUFFLEdBQUc7WUFDTCxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLENBQUMsRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDdkIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN2QixDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUcsV0FBVztTQUN4QyxDQUFDO1FBRUYsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0Qix3QkFBd0I7UUFDeEIsc0JBQXNCO1FBQ3RCLHNCQUFzQjtRQUN0QixPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoSCxDQUFDOzs0R0F4NkJRLGVBQWUsa0JBR0osV0FBVztnSEFIdEIsZUFBZTsyRkFBZixlQUFlO2tCQUQzQixVQUFVOzBEQUk4QyxNQUFNOzBCQUE5QyxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgUExBVEZPUk1fSUQsIFJlbmRlcmVyMiwgUmVuZGVyZXJGYWN0b3J5MiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgdGhyb3R0bGVUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW50ZXJmYWNlIHByZXR0eUNvbnNvbGUge1xyXG4gICAgLyoqXHJcbiAgICAqIGxvZ+aJk+WNsFxyXG4gICAgKiBAcGFyYW0gdGV4dE9yVGl0bGUg5qCH6aKY5oiW5YaF5a65XHJcbiAgICAqIEBwYXJhbSBjb250ZW50IOWGheWuuVxyXG4gICAgKi9cclxuICAgIGxvZzogRnVuY3Rpb247XHJcbiAgICAvKipcclxuICAgICogaW5mb+aJk+WNsFxyXG4gICAgKiBAcGFyYW0gdGV4dE9yVGl0bGUg5qCH6aKY5oiW5YaF5a65XHJcbiAgICAqIEBwYXJhbSBjb250ZW50IOWGheWuuVxyXG4gICAgKi9cclxuICAgIGluZm86IEZ1bmN0aW9uO1xyXG4gICAgLyoqXHJcbiAgICAqIGVycm9y5omT5Y2wXHJcbiAgICAqIEBwYXJhbSB0ZXh0T3JUaXRsZSDmoIfpopjmiJblhoXlrrlcclxuICAgICogQHBhcmFtIGNvbnRlbnQg5YaF5a65XHJcbiAgICAqL1xyXG4gICAgZXJyb3I6IEZ1bmN0aW9uO1xyXG4gICAgLyoqXHJcbiAgICAqIHdhcm5pbmfmiZPljbBcclxuICAgICogQHBhcmFtIHRleHRPclRpdGxlIOagh+mimOaIluWGheWuuVxyXG4gICAgKiBAcGFyYW0gY29udGVudCDlhoXlrrlcclxuICAgICovXHJcbiAgICB3YXJuaW5nOiBGdW5jdGlvbjtcclxuICAgIC8qKlxyXG4gICAgKiBzdWNjZXNz5omT5Y2wXHJcbiAgICAqIEBwYXJhbSB0ZXh0T3JUaXRsZSDmoIfpopjmiJblhoXlrrlcclxuICAgICogQHBhcmFtIGNvbnRlbnQg5YaF5a65XHJcbiAgICAqL1xyXG4gICAgc3VjY2VzczogRnVuY3Rpb247XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE5jQ29tbW9uU2VydmljZSB7XHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjI7XHJcblxyXG4gICAgY29uc3RydWN0b3IoQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3QsIHByaXZhdGUgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyKSB7XHJcbiAgICAgICAgdGhpcy5pc0Jyb3dzZXIgPSBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSB0aGlzLnJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS3mlbDlrZfnsbstLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOeyvuehruWKoOazlVxyXG4gICAgICogQHBhcmFtIHZhbHVlMSDnrKzkuIDkuKrliqDmlbBcclxuICAgICAqIEBwYXJhbSB2YWx1ZTIg56ys5LqM5Liq5Yqg5pWwXHJcbiAgICAgKiBAcmV0dXJucyDkuKTmlbDkuYvlkoxcclxuICAgICAqL1xyXG4gICAgbWF0aEFkZCh2YWx1ZTE6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuWtl+espuS4slxyXG4gICAgICAgIGxldCBhU3RyID0gdmFsdWUxLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbGV0IGJTdHIgPSB2YWx1ZTIudG9TdHJpbmcoKTtcclxuXHJcbiAgICAgICAgLy8g5om+5Yiw5bCP5pWw54K55ZCO55qE5L2N572uXHJcbiAgICAgICAgbGV0IGFEZWNpbWFscyA9IChhU3RyLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcclxuICAgICAgICBsZXQgYkRlY2ltYWxzID0gKGJTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG5cclxuICAgICAgICAvLyDmib7liLDmnIDlpKfnmoTlsI/mlbDkvY3mlbBcclxuICAgICAgICBsZXQgbWF4RGVjaW1hbHMgPSBNYXRoLm1heChhRGVjaW1hbHMsIGJEZWNpbWFscyk7XHJcblxyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuaVtOaVsFxyXG4gICAgICAgIGxldCBhSW50ID0gTWF0aC5yb3VuZCh2YWx1ZTEgKiBNYXRoLnBvdygxMCwgbWF4RGVjaW1hbHMpKTtcclxuICAgICAgICBsZXQgYkludCA9IE1hdGgucm91bmQodmFsdWUyICogTWF0aC5wb3coMTAsIG1heERlY2ltYWxzKSk7XHJcblxyXG4gICAgICAgIC8vIOi/m+ihjOaVtOaVsOWKoOazlVxyXG4gICAgICAgIGxldCByZXN1bHRJbnQgPSBhSW50ICsgYkludDtcclxuXHJcbiAgICAgICAgLy8g5bCG57uT5p6c6L2s5o2i5Zue5rWu54K55pWwXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdEludCAvIE1hdGgucG93KDEwLCBtYXhEZWNpbWFscyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDnsr7noa7lh4/ms5VcclxuICAgICAqIEBwYXJhbSB2YWx1ZTEg6KKr5YeP5pWwXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUyIOWHj+aVsFxyXG4gICAgICogQHJldHVybnMg5Lik5pWw5LmL5beuXHJcbiAgICAgKi9cclxuICAgIG1hdGhTdWJ0cmFjdCh2YWx1ZTE6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuWtl+espuS4slxyXG4gICAgICAgIGxldCBhU3RyID0gdmFsdWUxLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbGV0IGJTdHIgPSB2YWx1ZTIudG9TdHJpbmcoKTtcclxuXHJcbiAgICAgICAgLy8g5om+5Yiw5bCP5pWw54K55ZCO55qE5L2N572uXHJcbiAgICAgICAgbGV0IGFEZWNpbWFscyA9IChhU3RyLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcclxuICAgICAgICBsZXQgYkRlY2ltYWxzID0gKGJTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG5cclxuICAgICAgICAvLyDmib7liLDmnIDlpKfnmoTlsI/mlbDkvY3mlbBcclxuICAgICAgICBsZXQgbWF4RGVjaW1hbHMgPSBNYXRoLm1heChhRGVjaW1hbHMsIGJEZWNpbWFscyk7XHJcblxyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuaVtOaVsFxyXG4gICAgICAgIGxldCBhSW50ID0gTWF0aC5yb3VuZCh2YWx1ZTEgKiBNYXRoLnBvdygxMCwgbWF4RGVjaW1hbHMpKTtcclxuICAgICAgICBsZXQgYkludCA9IE1hdGgucm91bmQodmFsdWUyICogTWF0aC5wb3coMTAsIG1heERlY2ltYWxzKSk7XHJcblxyXG4gICAgICAgIC8vIOi/m+ihjOaVtOaVsOWHj+azlVxyXG4gICAgICAgIGxldCByZXN1bHRJbnQgPSBhSW50IC0gYkludDtcclxuXHJcbiAgICAgICAgLy8g5bCG57uT5p6c6L2s5o2i5Zue5rWu54K55pWwXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdEludCAvIE1hdGgucG93KDEwLCBtYXhEZWNpbWFscyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDnsr7noa7kuZjms5VcclxuICAgICAqIEBwYXJhbSB2YWx1ZTEg56ys5LiA5Liq5LmY5pWwXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUyIOesrOS6jOS4quS5mOaVsFxyXG4gICAgICogQHJldHVybnMg5Lik5pWw5LmL56evXHJcbiAgICAgKi9cclxuICAgIG1hdGhNdWx0aXBseSh2YWx1ZTE6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIOWwhua1rueCueaVsOi9rOaNouS4uuWtl+espuS4slxyXG4gICAgICAgIGxldCBhU3RyID0gdmFsdWUxLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgbGV0IGJTdHIgPSB2YWx1ZTIudG9TdHJpbmcoKTtcclxuXHJcbiAgICAgICAgLy8g5om+5Yiw5bCP5pWw54K55ZCO55qE5L2N572uXHJcbiAgICAgICAgbGV0IGFEZWNpbWFscyA9IChhU3RyLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcclxuICAgICAgICBsZXQgYkRlY2ltYWxzID0gKGJTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG5cclxuICAgICAgICAvLyDlsIbmta7ngrnmlbDovazmjaLkuLrmlbTmlbBcclxuICAgICAgICBsZXQgYUludCA9IHBhcnNlSW50KGFTdHIucmVwbGFjZSgnLicsICcnKSk7XHJcbiAgICAgICAgbGV0IGJJbnQgPSBwYXJzZUludChiU3RyLnJlcGxhY2UoJy4nLCAnJykpO1xyXG5cclxuICAgICAgICAvLyDov5vooYzmlbTmlbDkuZjms5VcclxuICAgICAgICBsZXQgcmVzdWx0SW50ID0gYUludCAqIGJJbnQ7XHJcblxyXG4gICAgICAgIC8vIOiuoeeul+acgOe7iOeahOWwj+aVsOS9jeaVsFxyXG4gICAgICAgIGxldCB0b3RhbERlY2ltYWxzID0gYURlY2ltYWxzICsgYkRlY2ltYWxzO1xyXG5cclxuICAgICAgICAvLyDlsIbnu5PmnpzovazmjaLlm57mta7ngrnmlbBcclxuICAgICAgICByZXR1cm4gcmVzdWx0SW50IC8gTWF0aC5wb3coMTAsIHRvdGFsRGVjaW1hbHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog57K+56Gu6Zmk5rOVXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUxIOiiq+mZpOaVsFxyXG4gICAgICogQHBhcmFtIHZhbHVlMiDpmaTmlbBcclxuICAgICAqIEByZXR1cm5zIOS4pOaVsOS5i+WVhlxyXG4gICAgICovXHJcbiAgICBtYXRoRGl2aWRlKHZhbHVlMTogbnVtYmVyLCB2YWx1ZTI6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgLy8g5bCG5rWu54K55pWw6L2s5o2i5Li65a2X56ym5LiyXHJcbiAgICAgICAgbGV0IGFTdHIgPSB2YWx1ZTEudG9TdHJpbmcoKTtcclxuICAgICAgICBsZXQgYlN0ciA9IHZhbHVlMi50b1N0cmluZygpO1xyXG5cclxuICAgICAgICAvLyDmib7liLDlsI/mlbDngrnlkI7nmoTkvY3nva5cclxuICAgICAgICBsZXQgYURlY2ltYWxzID0gKGFTdHIuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xyXG4gICAgICAgIGxldCBiRGVjaW1hbHMgPSAoYlN0ci5zcGxpdCgnLicpWzFdIHx8ICcnKS5sZW5ndGg7XHJcblxyXG4gICAgICAgIC8vIOaJvuWIsOacgOWkp+eahOWwj+aVsOS9jeaVsFxyXG4gICAgICAgIGxldCBtYXhEZWNpbWFscyA9IE1hdGgubWF4KGFEZWNpbWFscywgYkRlY2ltYWxzKTtcclxuXHJcbiAgICAgICAgLy8g5bCG5rWu54K55pWw6L2s5o2i5Li65pW05pWwXHJcbiAgICAgICAgbGV0IGFJbnQgPSBNYXRoLnJvdW5kKHZhbHVlMSAqIE1hdGgucG93KDEwLCBtYXhEZWNpbWFscykpO1xyXG4gICAgICAgIGxldCBiSW50ID0gTWF0aC5yb3VuZCh2YWx1ZTIgKiBNYXRoLnBvdygxMCwgbWF4RGVjaW1hbHMpKTtcclxuXHJcbiAgICAgICAgLy8g6L+b6KGM5pW05pWw6Zmk5rOV5bm255u05o6l6L+U5Zue57uT5p6cXHJcbiAgICAgICAgcmV0dXJuIGFJbnQgLyBiSW50O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5L+d55WZ5oyH5a6a5bCP5pWw5L2N5pWwXHJcbiAgICAgKiBAcGFyYW0gbnVtIOmcgOimgeWkhOeQhueahOaVsOWAvFxyXG4gICAgICogQHBhcmFtIGxlbiDopoHkv53nlZnnmoTlsI/mlbDkvY3mlbBcclxuICAgICAqIEByZXR1cm5zIOWkhOeQhuWQjueahOaVsOWAvO+8jOS/neeVmeaMh+WumuWwj+aVsOS9jeaVsFxyXG4gICAgICovXHJcbiAgICByZXRhaW5EZWNpbWFsKG51bTogbnVtYmVyLCBsZW46IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3QgbiA9IE1hdGgucG93KDEwLCBsZW4pO1xyXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bSAqIG4pIC8gbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOS/neeVmeaMh+WumuWwj+aVsOS9jeaVsOeahOeZvuWIhuavlFxyXG4gICAgICogQHBhcmFtIG51bSDpnIDopoHlpITnkIbnmoTmlbDlgLxcclxuICAgICAqIEBwYXJhbSBsZW4g6KaB5L+d55WZ55qE5bCP5pWw5L2N5pWwXHJcbiAgICAgKiBAcmV0dXJucyDlpITnkIblkI7nmoTnmb7liIbmr5TlgLzvvIzkv53nlZnmjIflrprlsI/mlbDkvY3mlbBcclxuICAgICAqL1xyXG4gICAgcmV0YWluUGVyY2VudERlY2ltYWwobnVtOiBudW1iZXIsIGxlbjogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICBjb25zdCBuID0gTWF0aC5wb3coMTAsIGxlbiArIDIpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1hdGhNdWx0aXBseShNYXRoLnJvdW5kKG51bSAqIG4pIC8gbiwgMTAwKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS3lrZjlgqgtLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOiuvue9rkNvb2tpZVxyXG4gICAgICogQHBhcmFtIGtleSBDb29raWXnmoTplK5cclxuICAgICAqIEBwYXJhbSB2YWx1ZSBDb29raWXnmoTlgLxcclxuICAgICAqIEBwYXJhbSB0dGwgQ29va2ll55qE55Sf5a2Y5pe26Ze077yI5q+r56eS77yJXHJcbiAgICAgKi9cclxuICAgIHNldENvb2tpZShrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZywgdHRsOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHBpcmVzID0gbmV3IERhdGUoRGF0ZS5ub3coKSArIHR0bCkudG9VVENTdHJpbmcoKTtcclxuICAgICAgICBkb2N1bWVudC5jb29raWUgPSBgJHtrZXl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKX07ZXhwaXJlcz0ke2V4cGlyZXN9O3BhdGg9L2A7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDojrflj5ZDb29raWVcclxuICAgICAqIEBwYXJhbSBrZXkgQ29va2ll55qE6ZSuXHJcbiAgICAgKiBAcmV0dXJucyBDb29raWXnmoTlgLzvvIzlpoLmnpzkuI3lrZjlnKjliJnov5Tlm55udWxsXHJcbiAgICAgKi9cclxuICAgIGdldENvb2tpZShrZXk6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefCApJyArIGtleSArICc9KFteO10rKScpKTtcclxuICAgICAgICByZXR1cm4gbWF0Y2ggPyBkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbMl0pIDogbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOWIoOmZpOaMh+WumueahENvb2tpZVxyXG4gICAgICogQHBhcmFtIGtleSDopoHliKDpmaTnmoRDb29raWXnmoTplK5cclxuICAgICAqL1xyXG4gICAgcmVtb3ZlQ29va2llKGtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgZG9jdW1lbnQuY29va2llID0gYCR7a2V5fT07ZXhwaXJlcz1UaHUsIDAxIEphbiAxOTcwIDAwOjAwOjAwIEdNVDtwYXRoPS9gO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5riF6Zmk5omA5pyJQ29va2llXHJcbiAgICAgKi9cclxuICAgIGNsZWFyQ29va2llKCk6IHZvaWQge1xyXG4gICAgICAgIGRvY3VtZW50LmNvb2tpZS5zcGxpdChcIjtcIikuZm9yRWFjaChjID0+IHtcclxuICAgICAgICAgICAgZG9jdW1lbnQuY29va2llID0gYy5yZXBsYWNlKC9eICsvLCBcIlwiKS5yZXBsYWNlKC89LiovLCBcIj07ZXhwaXJlcz1UaHUsIDAxIEphbiAxOTcwIDAwOjAwOjAwIEdNVDtwYXRoPS9cIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDorr7nva5Mb2NhbFN0b3JhZ2XpoblcclxuICAgICAqIEBwYXJhbSBrZXkgTG9jYWxTdG9yYWdl55qE6ZSuXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgTG9jYWxTdG9yYWdl55qE5YC8XHJcbiAgICAgKiBAcGFyYW0gdHRsIOWPr+mAieeahOeUn+WtmOaXtumXtO+8iOavq+enku+8iVxyXG4gICAgICovXHJcbiAgICBzZXRMb2NhbFN0b3JhZ2Uoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnksIHR0bD86IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGl0ZW0gPSB7IHZhbHVlLCBleHBpcnk6IHR0bCA/IERhdGUubm93KCkgKyB0dGwgOiBudWxsIH07XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oa2V5LCBKU09OLnN0cmluZ2lmeShpdGVtKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDojrflj5ZMb2NhbFN0b3JhZ2XpoblcclxuICAgICAqIEBwYXJhbSBrZXkgTG9jYWxTdG9yYWdl55qE6ZSuXHJcbiAgICAgKiBAcmV0dXJucyBMb2NhbFN0b3JhZ2XnmoTlgLzvvIzlpoLmnpzkuI3lrZjlnKjmiJblt7Lov4fmnJ/liJnov5Tlm55udWxsXHJcbiAgICAgKi9cclxuICAgIGdldExvY2FsU3RvcmFnZShrZXk6IHN0cmluZyk6IGFueSB7XHJcbiAgICAgICAgY29uc3QgaXRlbVN0ciA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKGtleSk7XHJcbiAgICAgICAgaWYgKCFpdGVtU3RyKSByZXR1cm4gbnVsbDtcclxuICAgICAgICBjb25zdCBpdGVtID0gSlNPTi5wYXJzZShpdGVtU3RyKTtcclxuICAgICAgICBpZiAoaXRlbS5leHBpcnkgJiYgRGF0ZS5ub3coKSA+IGl0ZW0uZXhwaXJ5KSB7XHJcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXRlbS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOWIoOmZpOaMh+WumueahExvY2FsU3RvcmFnZemhuVxyXG4gICAgICogQHBhcmFtIGtleSDopoHliKDpmaTnmoRMb2NhbFN0b3JhZ2XpobnnmoTplK5cclxuICAgICAqL1xyXG4gICAgcmVtb3ZlTG9jYWxTdG9yYWdlKGtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOa4hemZpOaJgOaciUxvY2FsU3RvcmFnZemhuVxyXG4gICAgICovXHJcbiAgICBjbGVhckxvY2FsU3RvcmFnZSgpOiB2b2lkIHtcclxuICAgICAgICBsb2NhbFN0b3JhZ2UuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOiuvue9rlNlc3Npb25TdG9yYWdl6aG5XHJcbiAgICAgKiBAcGFyYW0ga2V5IFNlc3Npb25TdG9yYWdl55qE6ZSuXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgU2Vzc2lvblN0b3JhZ2XnmoTlgLxcclxuICAgICAqL1xyXG4gICAgc2V0U2Vzc2lvblN0b3JhZ2Uoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOiOt+WPllNlc3Npb25TdG9yYWdl6aG5XHJcbiAgICAgKiBAcGFyYW0ga2V5IFNlc3Npb25TdG9yYWdl55qE6ZSuXHJcbiAgICAgKiBAcmV0dXJucyBTZXNzaW9uU3RvcmFnZeeahOWAvO+8jOWmguaenOS4jeWtmOWcqOWImei/lOWbnm51bGxcclxuICAgICAqL1xyXG4gICAgZ2V0U2Vzc2lvblN0b3JhZ2Uoa2V5OiBzdHJpbmcpOiBhbnkge1xyXG4gICAgICAgIGNvbnN0IGl0ZW0gPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKGtleSk7XHJcbiAgICAgICAgcmV0dXJuIGl0ZW0gPyBKU09OLnBhcnNlKGl0ZW0pIDogbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOWIoOmZpOaMh+WumueahFNlc3Npb25TdG9yYWdl6aG5XHJcbiAgICAgKiBAcGFyYW0ga2V5IOimgeWIoOmZpOeahFNlc3Npb25TdG9yYWdl6aG555qE6ZSuXHJcbiAgICAgKi9cclxuICAgIHJlbW92ZVNlc3Npb25TdG9yYWdlKGtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShrZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5riF6Zmk5omA5pyJU2Vzc2lvblN0b3JhZ2XpoblcclxuICAgICAqL1xyXG4gICAgY2xlYXJTZXNzaW9uU3RvcmFnZSgpOiB2b2lkIHtcclxuICAgICAgICBzZXNzaW9uU3RvcmFnZS5jbGVhcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLeaXpeacn+exuy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5qC85byP5YyW5pe26Ze0XHJcbiAgICAgKiBAcGFyYW0gZm9ybWF0IOagvOW8j+WMluaooeadv++8jOWmgiAneXl5eS1NTS1kZCBISDptbTpzcyfvvIzms6jmhI9NTeS4uuaciOS7veOAgW1t5Li65YiG6ZKfXHJcbiAgICAgKiBAcGFyYW0gZGF0ZUlucHV0IOWPr+mAieOAguimgeagvOW8j+WMlueahOaXpeacn++8jOWPr+S7peaYr0RhdGXlr7nosaHjgIHml7bpl7TmiLMobnVtYmVyKeaIluaXpeacn+Wtl+espuS4su+8jOm7mOiupOS4uuW9k+WJjeaXtumXtFxyXG4gICAgICogQHJldHVybnMg5qC85byP5YyW5ZCO55qE5pel5pyf5a2X56ym5LiyXHJcbiAgICAgKi9cclxuICAgIGZvcm1hdERhdGUoZm9ybWF0OiBzdHJpbmcsIGRhdGVJbnB1dD86IERhdGUgfCBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghZm9ybWF0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgbGV0IGRhdGU6IERhdGU7XHJcbiAgICAgICAgaWYgKCFkYXRlSW5wdXQpIHtcclxuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChkYXRlSW5wdXQgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgIGRhdGUgPSBkYXRlSW5wdXQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKGRhdGVJbnB1dCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIOmqjOivgeaXpeacn+aYr+WQpuacieaViFxyXG4gICAgICAgIGlmIChpc05hTihkYXRlLmdldFRpbWUoKSkpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdJbnZhbGlkIGRhdGUgaW5wdXQgcHJvdmlkZWQgdG8gZm9ybWF0RGF0ZScpO1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCkudG9TdHJpbmcoKTtcclxuICAgICAgICBjb25zdCBtb250aCA9IChkYXRlLmdldE1vbnRoKCkgKyAxKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICAgICAgY29uc3QgZGF5ID0gKGRhdGUuZ2V0RGF0ZSgpKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICAgICAgY29uc3QgaG91cnMgPSAoZGF0ZS5nZXRIb3VycygpKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICAgICAgY29uc3QgbWludXRlcyA9IChkYXRlLmdldE1pbnV0ZXMoKSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xyXG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSAoZGF0ZS5nZXRTZWNvbmRzKCkpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZvcm1hdFxyXG4gICAgICAgICAgICAucmVwbGFjZSgneXl5eScsIHllYXIpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCdNTScsIG1vbnRoKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnZGQnLCBkYXkpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCdISCcsIGhvdXJzKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnbW0nLCBtaW51dGVzKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnc3MnLCBzZWNvbmRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOiOt+WPluS4pOaXpeacn+mXtOeahOaJgOacieaXpeacn1xyXG4gICAgICogQHBhcmFtIHN0YXJ0RGF0ZSDlvIDlp4vml6XmnJ9cclxuICAgICAqIEBwYXJhbSBlbmREYXRlIOe7k+adn+aXpeacn1xyXG4gICAgICogQHJldHVybnMg5pel5pyf5pWw57uEXHJcbiAgICAgKi9cclxuICAgIGdldFJhbmdlRGF0ZShzdGFydERhdGU6IERhdGUsIGVuZERhdGU6IERhdGUpOiBEYXRlW10ge1xyXG4gICAgICAgIGxldCBkYXRlc0FycmF5ID0gW107XHJcbiAgICAgICAgbGV0IGN1cnJlbnREYXRlID0gbmV3IERhdGUoc3RhcnREYXRlKTtcclxuXHJcbiAgICAgICAgd2hpbGUgKGN1cnJlbnREYXRlIDw9IGVuZERhdGUpIHtcclxuICAgICAgICAgICAgZGF0ZXNBcnJheS5wdXNoKG5ldyBEYXRlKGN1cnJlbnREYXRlKSk7XHJcbiAgICAgICAgICAgIGN1cnJlbnREYXRlLnNldERhdGUoY3VycmVudERhdGUuZ2V0RGF0ZSgpICsgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBkYXRlc0FycmF5O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgKiDojrflj5bkuKTml6XmnJ/pl7TnmoTlpKnmlbBcclxuICAgICogQHBhcmFtIHN0YXJ0RGF0ZSDlvIDlp4vml6XmnJ9cclxuICAgICogQHBhcmFtIGVuZERhdGUg57uT5p2f5pel5pyfXHJcbiAgICAqIEByZXR1cm5zIOWkqeaVsFxyXG4gICAgKi9cclxuICAgIGdldERheXNCZXR3ZWVuKHN0YXJ0RGF0ZTogRGF0ZSwgZW5kRGF0ZTogRGF0ZSk6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3Qgb25lRGF5ID0gMjQgKiA2MCAqIDYwICogMTAwMDtcclxuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChNYXRoLmFicygoc3RhcnREYXRlLmdldFRpbWUoKSAtIGVuZERhdGUuZ2V0VGltZSgpKSAvIG9uZURheSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLeaVsOe7hOOAgeWvueixoS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5pWw57uE5Y676YeNXHJcbiAgICAgKiBAcGFyYW0gYXJyYXkg6KaB5Y676YeN55qE5pWw57uEXHJcbiAgICAgKiBAcGFyYW0ga2V5Rm4g5Y+v6YCJ55qE5Ye95pWw77yM55So5LqO5LuO5q+P5Liq5pWw57uE6aG55Lit5o+Q5Y+W55So5LqO5q+U6L6D55qE6ZSu77yM5L6L5aaC77yaaXRlbSA9PiBpdGVtLmlkXHJcbiAgICAgKiBAcmV0dXJucyBUW11cclxuICAgICAqL1xyXG4gICAgdW5pcXVlQXJyYXk8VD4oYXJyYXk6IFRbXSwga2V5Rm4/OiAoaXRlbTogVCkgPT4gYW55KTogVFtdIHtcclxuICAgICAgICBpZiAoIWtleUZuKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoYXJyYXkpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0KCk7XHJcbiAgICAgICAgcmV0dXJuIGFycmF5LmZpbHRlcihpdGVtID0+IHtcclxuICAgICAgICAgICAgY29uc3Qga2V5ID0ga2V5Rm4oaXRlbSk7XHJcbiAgICAgICAgICAgIGlmIChzZWVuLmhhcyhrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2Vlbi5hZGQoa2V5KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDmlbDnu4TmjpLluo9cclxuICAgICAqIEBwYXJhbSBhcnJheSDopoHmjpLluo/nmoTmlbDnu4RcclxuICAgICAqIEBwYXJhbSBvcmRlciDmjIflrprmjpLluo/pobrluo/vvIwnYXNjJyDkuLrljYfluo/vvIwnZGVzYycg5Li66ZmN5bqPXHJcbiAgICAgKiBAcGFyYW0ga2V5Rm4g5Y+v6YCJ44CC5Y+v5Lul5piv5a+56LGh55qE6ZSu5ZCN5oiW5LiA5Liq5Ye95pWw77yM55So5LqO5LuO5pWw57uE6aG55Lit5o+Q5Y+W5o6S5bqP5YC877yM5L6L5aaC77yaJ2FnZSfmiJYgaXRlbSA9PiBpdGVtLm5hbWUubGVuZ3RoXHJcbiAgICAgKiBAcmV0dXJucyBUW11cclxuICAgICAqL1xyXG4gICAgc29ydEFycmF5PFQ+KGFycmF5OiBUW10sIG9yZGVyOiAnYXNjJyB8ICdkZXNjJywga2V5Pzoga2V5b2YgVCB8ICgoaXRlbTogVCkgPT4gYW55KSk6IFRbXSB7XHJcbiAgICAgICAgcmV0dXJuIFsuLi5hcnJheV0uc29ydCgoYSwgYikgPT4ge1xyXG4gICAgICAgICAgICBsZXQgdmFsdWVBOiBhbnk7XHJcbiAgICAgICAgICAgIGxldCB2YWx1ZUI6IGFueTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZUEgPSBrZXkoYSk7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZUIgPSBrZXkoYik7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZUEgPSBhW2tleV07XHJcbiAgICAgICAgICAgICAgICB2YWx1ZUIgPSBiW2tleV07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZUEgPSBhO1xyXG4gICAgICAgICAgICAgICAgdmFsdWVCID0gYjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHZhbHVlQSA9PT0gdmFsdWVCKSByZXR1cm4gMDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWVBID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgdmFsdWVCID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyID09PSAnYXNjJ1xyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVBLmxvY2FsZUNvbXBhcmUodmFsdWVCKVxyXG4gICAgICAgICAgICAgICAgICAgIDogdmFsdWVCLmxvY2FsZUNvbXBhcmUodmFsdWVBKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG9yZGVyID09PSAnYXNjJ1xyXG4gICAgICAgICAgICAgICAgPyAodmFsdWVBIDwgdmFsdWVCID8gLTEgOiAxKVxyXG4gICAgICAgICAgICAgICAgOiAodmFsdWVCIDwgdmFsdWVBID8gLTEgOiAxKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOWIpOaWreWvueixoeaYr+WQpuS4uuepulxyXG4gICAgICogQHBhcmFtIG9ialxyXG4gICAgICogQHJldHVybnMgYm9vbGVhblxyXG4gICAgICovXHJcbiAgICBpc09iamVjdEVtcHR5KG9iajogb2JqZWN0KTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID09PSAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLee7j+e6rOW6pi0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIHByaXZhdGUgeF9QSSA9IDMuMTQxNTkyNjUzNTg5NzkzMjQgKiAzMDAwLjAgLyAxODAuMDtcclxuICAgIHByaXZhdGUgUEkgPSAzLjE0MTU5MjY1MzU4OTc5MzIzODQ2MjY7XHJcbiAgICBwcml2YXRlIGEgPSA2Mzc4MjQ1LjA7XHJcbiAgICBwcml2YXRlIGVlID0gMC4wMDY2OTM0MjE2MjI5NjU5NDMyMztcclxuXHJcbiAgICAvKipcclxuICAgICAqIOeZvuW6puWdkOagh+ezuyAoQkQtMDkpIOS4jueBq+aYn+WdkOagh+ezuyAoR0NKLTAyKSDnmoTovazmjaJcclxuICAgICAqIOWNs+eZvuW6piDovawg6LC35q2M44CB6auY5b63XHJcbiAgICAgKiBAcGFyYW0gbG5nIOe7j+W6plxyXG4gICAgICogQHBhcmFtIGxhdCDnuqzluqZcclxuICAgICAqIEByZXR1cm5zIFtsbmcsIGxhdF1cclxuICAgICAqL1xyXG4gICAgYmQwOXRvZ2NqMDIobG5nOiBudW1iZXIsIGxhdDogbnVtYmVyKTogbnVtYmVyW10ge1xyXG4gICAgICAgIHZhciB4X3BpID0gMy4xNDE1OTI2NTM1ODk3OTMyNCAqIDMwMDAuMCAvIDE4MC4wO1xyXG4gICAgICAgIHZhciB4ID0gbG5nIC0gMC4wMDY1O1xyXG4gICAgICAgIHZhciB5ID0gbGF0IC0gMC4wMDY7XHJcbiAgICAgICAgdmFyIHogPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSkgLSAwLjAwMDAyICogTWF0aC5zaW4oeSAqIHhfcGkpO1xyXG4gICAgICAgIHZhciB0aGV0YSA9IE1hdGguYXRhbjIoeSwgeCkgLSAwLjAwMDAwMyAqIE1hdGguY29zKHggKiB4X3BpKTtcclxuICAgICAgICB2YXIgZ2dfbG5nID0geiAqIE1hdGguY29zKHRoZXRhKTtcclxuICAgICAgICB2YXIgZ2dfbGF0ID0geiAqIE1hdGguc2luKHRoZXRhKTtcclxuICAgICAgICByZXR1cm4gW2dnX2xuZywgZ2dfbGF0XVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog54Gr5pif5Z2Q5qCH57O7IChHQ0otMDIpIOS4jueZvuW6puWdkOagh+ezuyAoQkQtMDkpIOeahOi9rOaNolxyXG4gICAgICog5Y2z6LC35q2M44CB6auY5b63IOi9rCDnmb7luqZcclxuICAgICAqIEBwYXJhbSBsbmcg57uP5bqmXHJcbiAgICAgKiBAcGFyYW0gbGF0IOe6rOW6plxyXG4gICAgICogQHJldHVybnMgW2xuZywgbGF0XVxyXG4gICAgICovXHJcbiAgICBnY2owMnRvYmQwOShsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpOiBudW1iZXJbXSB7XHJcbiAgICAgICAgdmFyIHogPSBNYXRoLnNxcnQobG5nICogbG5nICsgbGF0ICogbGF0KSArIDAuMDAwMDIgKiBNYXRoLnNpbihsYXQgKiB0aGlzLnhfUEkpO1xyXG4gICAgICAgIHZhciB0aGV0YSA9IE1hdGguYXRhbjIobGF0LCBsbmcpICsgMC4wMDAwMDMgKiBNYXRoLmNvcyhsbmcgKiB0aGlzLnhfUEkpO1xyXG4gICAgICAgIHZhciBiZF9sbmcgPSB6ICogTWF0aC5jb3ModGhldGEpICsgMC4wMDY1O1xyXG4gICAgICAgIHZhciBiZF9sYXQgPSB6ICogTWF0aC5zaW4odGhldGEpICsgMC4wMDY7XHJcbiAgICAgICAgcmV0dXJuIFtiZF9sbmcsIGJkX2xhdF1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdHUzg06L2s54Gr5pif5Z2Q5qCH57O7IChHQ0otMDIpXHJcbiAgICAgKiDljbNXR1M4NCDovawg6LC35q2M44CB6auY5b63XHJcbiAgICAgKiBAcGFyYW0gbG5nIOe7j+W6plxyXG4gICAgICogQHBhcmFtIGxhdCDnuqzluqZcclxuICAgICAqIEByZXR1cm5zIFtsbmcsIGxhdF1cclxuICAgICAqL1xyXG4gICAgd2dzODR0b2djajAyKGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcik6IG51bWJlcltdIHtcclxuICAgICAgICBpZiAodGhpcy5vdXRfb2ZfY2hpbmEobG5nLCBsYXQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbbG5nLCBsYXRdXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgZGxhdCA9IHRoaXMudHJhbnNmb3JtbGF0KGxuZyAtIDEwNS4wLCBsYXQgLSAzNS4wKTtcclxuICAgICAgICAgICAgdmFyIGRsbmcgPSB0aGlzLnRyYW5zZm9ybWxuZyhsbmcgLSAxMDUuMCwgbGF0IC0gMzUuMCk7XHJcbiAgICAgICAgICAgIHZhciByYWRsYXQgPSBsYXQgLyAxODAuMCAqIHRoaXMuUEk7XHJcbiAgICAgICAgICAgIHZhciBtYWdpYyA9IE1hdGguc2luKHJhZGxhdCk7XHJcbiAgICAgICAgICAgIG1hZ2ljID0gMSAtIHRoaXMuZWUgKiBtYWdpYyAqIG1hZ2ljO1xyXG4gICAgICAgICAgICB2YXIgc3FydG1hZ2ljID0gTWF0aC5zcXJ0KG1hZ2ljKTtcclxuICAgICAgICAgICAgZGxhdCA9IChkbGF0ICogMTgwLjApIC8gKCh0aGlzLmEgKiAoMSAtIHRoaXMuZWUpKSAvIChtYWdpYyAqIHNxcnRtYWdpYykgKiB0aGlzLlBJKTtcclxuICAgICAgICAgICAgZGxuZyA9IChkbG5nICogMTgwLjApIC8gKHRoaXMuYSAvIHNxcnRtYWdpYyAqIE1hdGguY29zKHJhZGxhdCkgKiB0aGlzLlBJKTtcclxuICAgICAgICAgICAgdmFyIG1nbGF0ID0gbGF0ICsgZGxhdDtcclxuICAgICAgICAgICAgdmFyIG1nbG5nID0gbG5nICsgZGxuZztcclxuICAgICAgICAgICAgcmV0dXJuIFttZ2xuZywgbWdsYXRdXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog54Gr5pif5Z2Q5qCH57O7IChHQ0otMDIp6L2sV0dTODRcclxuICAgICAqIOWNs+iwt+atjOOAgemrmOW+tyDovawgV0dTODRcclxuICAgICAqIEBwYXJhbSBsbmcg57uP5bqmXHJcbiAgICAgKiBAcGFyYW0gbGF0IOe6rOW6plxyXG4gICAgICogQHJldHVybnMgW2xuZywgbGF0XVxyXG4gICAgICovXHJcbiAgICBnY2owMnRvd2dzODQobG5nOiBudW1iZXIsIGxhdDogbnVtYmVyKTogbnVtYmVyW10ge1xyXG4gICAgICAgIGlmICh0aGlzLm91dF9vZl9jaGluYShsbmcsIGxhdCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtsbmcsIGxhdF1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBkbGF0ID0gdGhpcy50cmFuc2Zvcm1sYXQobG5nIC0gMTA1LjAsIGxhdCAtIDM1LjApO1xyXG4gICAgICAgICAgICB2YXIgZGxuZyA9IHRoaXMudHJhbnNmb3JtbG5nKGxuZyAtIDEwNS4wLCBsYXQgLSAzNS4wKTtcclxuICAgICAgICAgICAgdmFyIHJhZGxhdCA9IGxhdCAvIDE4MC4wICogdGhpcy5QSTtcclxuICAgICAgICAgICAgdmFyIG1hZ2ljID0gTWF0aC5zaW4ocmFkbGF0KTtcclxuICAgICAgICAgICAgbWFnaWMgPSAxIC0gdGhpcy5lZSAqIG1hZ2ljICogbWFnaWM7XHJcbiAgICAgICAgICAgIHZhciBzcXJ0bWFnaWMgPSBNYXRoLnNxcnQobWFnaWMpO1xyXG4gICAgICAgICAgICBkbGF0ID0gKGRsYXQgKiAxODAuMCkgLyAoKHRoaXMuYSAqICgxIC0gdGhpcy5lZSkpIC8gKG1hZ2ljICogc3FydG1hZ2ljKSAqIHRoaXMuUEkpO1xyXG4gICAgICAgICAgICBkbG5nID0gKGRsbmcgKiAxODAuMCkgLyAodGhpcy5hIC8gc3FydG1hZ2ljICogTWF0aC5jb3MocmFkbGF0KSAqIHRoaXMuUEkpO1xyXG4gICAgICAgICAgICBsZXQgbWdsYXQgPSBsYXQgKyBkbGF0O1xyXG4gICAgICAgICAgICBsZXQgbWdsbmcgPSBsbmcgKyBkbG5nO1xyXG4gICAgICAgICAgICByZXR1cm4gW2xuZyAqIDIgLSBtZ2xuZywgbGF0ICogMiAtIG1nbGF0XVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHRyYW5zZm9ybWxhdChsbmc6IG51bWJlciwgbGF0OiBudW1iZXIpIHtcclxuICAgICAgICB2YXIgcmV0ID0gLTEwMC4wICsgMi4wICogbG5nICsgMy4wICogbGF0ICsgMC4yICogbGF0ICogbGF0ICsgMC4xICogbG5nICogbGF0ICsgMC4yICogTWF0aC5zcXJ0KE1hdGguYWJzKGxuZykpO1xyXG4gICAgICAgIHJldCArPSAoMjAuMCAqIE1hdGguc2luKDYuMCAqIGxuZyAqIHRoaXMuUEkpICsgMjAuMCAqIE1hdGguc2luKDIuMCAqIGxuZyAqIHRoaXMuUEkpKSAqIDIuMCAvIDMuMDtcclxuICAgICAgICByZXQgKz0gKDIwLjAgKiBNYXRoLnNpbihsYXQgKiB0aGlzLlBJKSArIDQwLjAgKiBNYXRoLnNpbihsYXQgLyAzLjAgKiB0aGlzLlBJKSkgKiAyLjAgLyAzLjA7XHJcbiAgICAgICAgcmV0ICs9ICgxNjAuMCAqIE1hdGguc2luKGxhdCAvIDEyLjAgKiB0aGlzLlBJKSArIDMyMCAqIE1hdGguc2luKGxhdCAqIHRoaXMuUEkgLyAzMC4wKSkgKiAyLjAgLyAzLjA7XHJcbiAgICAgICAgcmV0dXJuIHJldFxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdHJhbnNmb3JtbG5nKGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcikge1xyXG4gICAgICAgIHZhciByZXQgPSAzMDAuMCArIGxuZyArIDIuMCAqIGxhdCArIDAuMSAqIGxuZyAqIGxuZyArIDAuMSAqIGxuZyAqIGxhdCArIDAuMSAqIE1hdGguc3FydChNYXRoLmFicyhsbmcpKTtcclxuICAgICAgICByZXQgKz0gKDIwLjAgKiBNYXRoLnNpbig2LjAgKiBsbmcgKiB0aGlzLlBJKSArIDIwLjAgKiBNYXRoLnNpbigyLjAgKiBsbmcgKiB0aGlzLlBJKSkgKiAyLjAgLyAzLjA7XHJcbiAgICAgICAgcmV0ICs9ICgyMC4wICogTWF0aC5zaW4obG5nICogdGhpcy5QSSkgKyA0MC4wICogTWF0aC5zaW4obG5nIC8gMy4wICogdGhpcy5QSSkpICogMi4wIC8gMy4wO1xyXG4gICAgICAgIHJldCArPSAoMTUwLjAgKiBNYXRoLnNpbihsbmcgLyAxMi4wICogdGhpcy5QSSkgKyAzMDAuMCAqIE1hdGguc2luKGxuZyAvIDMwLjAgKiB0aGlzLlBJKSkgKiAyLjAgLyAzLjA7XHJcbiAgICAgICAgcmV0dXJuIHJldFxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5Yik5pat5piv5ZCm5Zyo5Zu95YaF77yM5LiN5Zyo5Zu95YaF5YiZ5LiN5YGa5YGP56e7XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgb3V0X29mX2NoaW5hKGxuZzogbnVtYmVyLCBsYXQ6IG51bWJlcikge1xyXG4gICAgICAgIHJldHVybiAobG5nIDwgNzIuMDA0IHx8IGxuZyA+IDEzNy44MzQ3KSB8fCAoKGxhdCA8IDAuODI5MyB8fCBsYXQgPiA1NS44MjcxKSB8fCBmYWxzZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAqIOWwj+aVsOW9ouW8j+e7j+e6rOW6pui9rOW6puWIhuenkuW9ouW8jyjnp5Lkv53nlZkz5L2N5bCP5pWwKVxyXG4gICAgKiBAcGFyYW0gZGlnaXRhbCAgMTA5Ljg2MzMwNTU1NTU1NTU2XHJcbiAgICAqIEByZXR1cm5zIGRlZ3JlZXMgJzEwOcKwNTHigLI0Ny454oCzJ1xyXG4gICAgKi9cclxuICAgIGRpZ2l0YWxUb0RlZ3JlZXMoZGlnaXRhbDogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgZGlnaXRhbFN0cmluZyA9IGRpZ2l0YWwudG9TdHJpbmcoKTtcclxuICAgICAgICBsZXQgaW5kZXgxID0gZGlnaXRhbFN0cmluZy5pbmRleE9mKCcuJyk7XHJcbiAgICAgICAgbGV0IGR1ID0gaW5kZXgxIDwgMCA/IE51bWJlcihkaWdpdGFsU3RyaW5nKSA6IE51bWJlcihkaWdpdGFsU3RyaW5nLnN1YnN0cmluZygwLCBpbmRleDEpKTsvLzEwOVxyXG4gICAgICAgIGxldCBmZW4gPSAwO1xyXG4gICAgICAgIGxldCBtaWFvID0gMDtcclxuICAgICAgICBpZiAoaW5kZXgxID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgc3RyRmVuID0gTnVtYmVyKFwiMFwiICsgZGlnaXRhbFN0cmluZy5zdWJzdHJpbmcoaW5kZXgxKSk7Ly8wLjg2MzMwNTU1NTU1NTU2XHJcbiAgICAgICAgICAgIGxldCBzdHJGZW5TdHJpbmcgPSAoc3RyRmVuICogNjApLnRvU3RyaW5nKCk7Ly8nNTEuNzk4MzMzMzMzMzMzNidcclxuICAgICAgICAgICAgbGV0IGluZGV4MiA9IHN0ckZlblN0cmluZy5pbmRleE9mKCcuJyk7XHJcbiAgICAgICAgICAgIGlmIChpbmRleDIgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBmZW4gPSBOdW1iZXIoc3RyRmVuU3RyaW5nLnN1YnN0cmluZygwLCBpbmRleDIpKTsvLzUxXHJcbiAgICAgICAgICAgICAgICBsZXQgc3RyTWlhbyA9IE51bWJlcihcIjBcIiArIHN0ckZlblN0cmluZy5zdWJzdHJpbmcoaW5kZXgyKSk7Ly8wLjc5ODMzMzMzMzMzMzZcclxuICAgICAgICAgICAgICAgIG1pYW8gPSBOdW1iZXIoKHN0ck1pYW8gKiA2MCkudG9GaXhlZCgzKSk7Ly80Ny45MDAwMDAwMDAwMTYgIDQ3LjlcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZlbiA9IE51bWJlcihzdHJGZW5TdHJpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYCR7ZHV9wrAke2Zlbn3igLIke21pYW994oCzYFxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog5bqm5YiG56eS5b2i5byP57uP57qs5bqm6L2s5bCP5pWw5b2i5byPXHJcbiAgICAgKiBAcGFyYW0gZGVncmVlcyAgJzEwOcKwNTHigLI0Ny45MDAwMDAwMDAwMTbigLMnXHJcbiAgICAgKiBAcmV0dXJucyBkaWdpdGFsIDEwOS44NjMzMDU1NTU1NTU1NlxyXG4gICAgICovXHJcbiAgICBkZWdyZWVzVG9EaWdpdGFsKGRlZ3JlZXM6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IHRlbXAxID0gZGVncmVlcy5zcGxpdCgnwrAnKTtcclxuICAgICAgICBsZXQgdGVtcDIgPSB0ZW1wMVsxXS5zcGxpdCgn4oCyJyk7XHJcbiAgICAgICAgbGV0IGR1ID0gdGVtcDFbMF07XHJcbiAgICAgICAgbGV0IGZlbiA9IHRlbXAyWzBdO1xyXG4gICAgICAgIGxldCBtaWFvID0gdGVtcDJbMV0uc3Vic3RyaW5nKDAsIHRlbXAyWzFdLmxlbmd0aCAtIDEpO1xyXG5cclxuICAgICAgICByZXR1cm4gTnVtYmVyKGR1KSArIE51bWJlcihmZW4pIC8gNjAgKyBOdW1iZXIobWlhbykgLyAzNjAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLeiKgua1geOAgemYsuaKli0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIHByaXZhdGUgZGVib3VuY2VUYXNrczogTWFwPHN0cmluZywgU3ViamVjdDxGdW5jdGlvbj4+ID0gbmV3IE1hcCgpO1xyXG4gICAgcHJpdmF0ZSB0aHJvdHRsZVRhc2tzOiBNYXA8c3RyaW5nLCBTdWJqZWN0PEZ1bmN0aW9uPj4gPSBuZXcgTWFwKCk7XHJcbiAgICAvKipcclxuICAgICAqIOmYsuaKlu+8iERlYm91bmNl77yJ77ya6YCC55So5LqO6YG/5YWN55+t5pe26Ze05YaF5aSa5qyh6Kem5Y+R55qE5Zy65pmv77yM5Y+q5pyJ5Zyo5LqL5Lu25YGc5q2i6Kem5Y+R5ZCO55qE5LiA5q615pe26Ze05omN5Lya5omn6KGM44CC5L6L5aaC77ya5pCc57Si5qGG6L6T5YWl77yM6YG/5YWN6aKR57mB55qEQVBJ6K+35rGC44CCXHJcbiAgICAgKiBAcGFyYW0ga2V5IOeUqOS6juagh+ivhlN1YmplY3TnmoTllK/kuIDplK7vvIzkuI3lkIzpmLLmipbku7vliqHlupTkvb/nlKjkuI3lkIznmoRrZXnvvIznm7jlkIxrZXnnmoTku7vliqHkvJrlhbHkuqvpppbmrKHorr7nva7nmoRkZWxheeaXtumXtFxyXG4gICAgICogQHBhcmFtIGRlbGF5IOmYsuaKluW7tui/n+aXtumXtO+8iOavq+enku+8iVxyXG4gICAgICogQHBhcmFtIGZuIOimgemYsuaKlueahOWHveaVsFxyXG4gICAgICovXHJcbiAgICBkZWJvdW5jZShrZXk6IHN0cmluZywgZGVsYXk6IG51bWJlciwgZm46IEZ1bmN0aW9uKTogdm9pZCB7XHJcbiAgICAgICAgbGV0IHN1YmplY3QgPSB0aGlzLmRlYm91bmNlVGFza3MuZ2V0KGtleSk7XHJcblxyXG4gICAgICAgIGlmICghc3ViamVjdCkge1xyXG4gICAgICAgICAgICBzdWJqZWN0ID0gbmV3IFN1YmplY3Q8RnVuY3Rpb24+KCk7XHJcbiAgICAgICAgICAgIHN1YmplY3QucGlwZShkZWJvdW5jZVRpbWUoZGVsYXkpKS5zdWJzY3JpYmUoZm5Ub0V4ZWN1dGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgZm5Ub0V4ZWN1dGUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2VUYXNrcy5zZXQoa2V5LCBzdWJqZWN0KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN1YmplY3QubmV4dChmbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAqIOiKgua1ge+8iFRocm90dGxl77yJ77ya6YCC55So5LqO6ZmQ5Yi25LqL5Lu25Zyo5Zu65a6a5pe26Ze06Ze06ZqU5YaF5omn6KGM55qE5Zy65pmv77yM56Gu5L+d5LqL5Lu25LiN5Lya6L+H5LqO6aKR57mB5Zyw6Kem5Y+R44CC5L6L5aaC77ya5rua5Yqo6aG16Z2i5pe255qE5LqL5Lu25aSE55CG77yM6YG/5YWN6aKR57mB55qE6K6h566X5ZKM5riy5p+T44CCXHJcbiAgICAqIEBwYXJhbSBrZXkg55So5LqO5qCH6K+GU3ViamVjdOeahOWUr+S4gOmUru+8jOS4jeWQjOiKgua1geS7u+WKoeW6lOS9v+eUqOS4jeWQjOeahGtlee+8jOebuOWQjGtleeeahOS7u+WKoeS8muWFseS6q+mmluasoeiuvue9rueahGRlbGF55pe26Ze0XHJcbiAgICAqIEBwYXJhbSBkZWxheSDoioLmtYHlu7bov5/ml7bpl7TvvIjmr6vnp5LvvIlcclxuICAgICogQHBhcmFtIGZuIOimgeiKgua1geeahOWHveaVsFxyXG4gICAgKi9cclxuICAgIHRocm90dGxlKGtleTogc3RyaW5nLCBkZWxheTogbnVtYmVyLCBmbjogRnVuY3Rpb24pOiB2b2lkIHtcclxuICAgICAgICBsZXQgc3ViamVjdCA9IHRoaXMudGhyb3R0bGVUYXNrcy5nZXQoa2V5KTtcclxuXHJcbiAgICAgICAgaWYgKCFzdWJqZWN0KSB7XHJcbiAgICAgICAgICAgIHN1YmplY3QgPSBuZXcgU3ViamVjdDxGdW5jdGlvbj4oKTtcclxuICAgICAgICAgICAgc3ViamVjdC5waXBlKHRocm90dGxlVGltZShkZWxheSkpLnN1YnNjcmliZShmblRvRXhlY3V0ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBmblRvRXhlY3V0ZSgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy50aHJvdHRsZVRhc2tzLnNldChrZXksIHN1YmplY3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3ViamVjdC5uZXh0KGZuKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS3mtojmga/mj5DnpLotLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICBwcml2YXRlIGZ1bGxMb2FkaW5nRWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuICAgIHByaXZhdGUgZnVsbExvYWRpbmdLZXlmcmFtZXNTdHlsZTogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIOaYvuekuuWFqOWxj+WKoOi9veS4re+8iOWFqOWxj+iSmeeJiO+8iVxyXG4gICAgICogIEBwYXJhbSBjb250ZW50IOWPr+mAieOAguaPkOekuuWGheWuue+8jOm7mOiupO+8mifliqDovb3kuK3vvIzor7fnqI3lkI4uLi4nXHJcbiAgICAgKi9cclxuICAgIHNob3dGdWxsTG9hZGluZyhjb250ZW50OiBzdHJpbmcgPSAn5Yqg6L295Lit77yM6K+356iN5ZCOLi4uJykge1xyXG4gICAgICAgIGlmICh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgJ2Z1bGwtbG9hZGluZy1jb250YWluZXInKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAncG9zaXRpb24nLCAnZml4ZWQnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAndG9wJywgJzAnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAnbGVmdCcsICcwJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgJ3dpZHRoJywgJzEwMCUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAnaGVpZ2h0JywgJzEwMCUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAnYmFja2dyb3VuZC1jb2xvcicsICdyZ2JhKDAsMCwwLDAuNSknKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50LCAnZGlzcGxheScsICdmbGV4Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgJ2ZsZXgtZGlyZWN0aW9uJywgJ2NvbHVtbicpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5mdWxsTG9hZGluZ0VsZW1lbnQsICdqdXN0aWZ5LWNvbnRlbnQnLCAnY2VudGVyJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgJ2FsaWduLWl0ZW1zJywgJ2NlbnRlcicpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5mdWxsTG9hZGluZ0VsZW1lbnQsICd6LWluZGV4JywgJzk5OTknKTtcclxuXHJcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhzcGlubmVyLCAnZnVsbC1sb2FkaW5nLXNwaW5uZXInKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHNwaW5uZXIsICdib3JkZXInLCAnNHB4IHNvbGlkICNmM2YzZjMnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHNwaW5uZXIsICdib3JkZXItdG9wJywgJzRweCBzb2xpZCAjMzQ5OGRiJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShzcGlubmVyLCAnYm9yZGVyLXJhZGl1cycsICc1MCUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHNwaW5uZXIsICd3aWR0aCcsICc1MHB4Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShzcGlubmVyLCAnaGVpZ2h0JywgJzUwcHgnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHNwaW5uZXIsICdhbmltYXRpb24nLCAnZnVsbFNwaW4gMXMgbGluZWFyIGluZmluaXRlJyk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxvYWRpbmdUZXh0ID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKGxvYWRpbmdUZXh0LCAnZnVsbC1sb2FkaW5nLXRleHQnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGxvYWRpbmdUZXh0LCAnY29sb3InLCAnd2hpdGUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGxvYWRpbmdUZXh0LCAnbWFyZ2luLXRvcCcsICcyMHB4Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShsb2FkaW5nVGV4dCwgJ2ZvbnQtc2l6ZScsICcxOHB4Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShsb2FkaW5nVGV4dCwgJ2xldHRlci1zcGFjaW5nJywgJzEuNXB4Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChsb2FkaW5nVGV4dCwgdGhpcy5yZW5kZXJlci5jcmVhdGVUZXh0KGNvbnRlbnQpKTtcclxuXHJcbiAgICAgICAgY29uc3Qga2V5ZnJhbWVzID0gYFxyXG4gICAgICAgICAgICBAa2V5ZnJhbWVzIGZ1bGxTcGluIHtcclxuICAgICAgICAgICAgICAgIDAlIHsgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7IH1cclxuICAgICAgICAgICAgICAgIDEwMCUgeyB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBgO1xyXG4gICAgICAgIHRoaXMuZnVsbExvYWRpbmdLZXlmcmFtZXNTdHlsZSA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuZnVsbExvYWRpbmdLZXlmcmFtZXNTdHlsZSwgdGhpcy5yZW5kZXJlci5jcmVhdGVUZXh0KGtleWZyYW1lcykpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuYm9keSwgdGhpcy5mdWxsTG9hZGluZ0tleWZyYW1lc1N0eWxlKTtcclxuXHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgc3Bpbm5lcik7XHJcbiAgICAgICAgaWYgKGNvbnRlbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCwgbG9hZGluZ1RleHQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKGRvY3VtZW50LmJvZHksIHRoaXMuZnVsbExvYWRpbmdFbGVtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICog56e76Zmk5YWo5bGP5Yqg6L295Lit77yI5YWo5bGP6JKZ54mI77yJXHJcbiAgICAqL1xyXG4gICAgcmVtb3ZlRnVsbExvYWRpbmcoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnVsbExvYWRpbmdFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQoZG9jdW1lbnQuYm9keSwgdGhpcy5mdWxsTG9hZGluZ0VsZW1lbnQpO1xyXG4gICAgICAgICAgICB0aGlzLmZ1bGxMb2FkaW5nRWxlbWVudCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5mdWxsTG9hZGluZ0tleWZyYW1lc1N0eWxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQoZG9jdW1lbnQuYm9keSwgdGhpcy5mdWxsTG9hZGluZ0tleWZyYW1lc1N0eWxlKTtcclxuICAgICAgICAgICAgdGhpcy5mdWxsTG9hZGluZ0tleWZyYW1lc1N0eWxlID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t6LCD6K+VLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgLyoqXHJcbiAgICAqIOe+juWMluaOp+WItuWPsOaJk+WNsO+8iGxvZyBpbmZvIGVycm9yIHdhcm5pbmcgc3VjY2Vzc++8iVxyXG4gICAgKi9cclxuICAgIGNvbnNvbGU6IHByZXR0eUNvbnNvbGUgPSB7XHJcbiAgICAgICAgbG9nOiAodGV4dE9yVGl0bGU6IGFueSwgY29udGVudDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gIWNvbnRlbnQgPyAnTG9nJyA6IHRleHRPclRpdGxlO1xyXG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gIWNvbnRlbnQgPyB0ZXh0T3JUaXRsZSA6IGNvbnRlbnQ7XHJcbiAgICAgICAgICAgIHRoaXMucHJldHR5UHJpbnQodGl0bGUsIHRleHQsICcjOTA5Mzk5Jyk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBpbmZvOiAodGV4dE9yVGl0bGU6IGFueSwgY29udGVudDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gIWNvbnRlbnQgPyAnSW5mbycgOiB0ZXh0T3JUaXRsZTtcclxuICAgICAgICAgICAgY29uc3QgdGV4dCA9ICFjb250ZW50ID8gdGV4dE9yVGl0bGUgOiBjb250ZW50O1xyXG4gICAgICAgICAgICB0aGlzLnByZXR0eVByaW50KHRpdGxlLCB0ZXh0LCAnIzQwYTlmZicpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXJyb3I6ICh0ZXh0T3JUaXRsZTogYW55LCBjb250ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgdGl0bGUgPSAhY29udGVudCA/ICdFcnJvcicgOiB0ZXh0T3JUaXRsZTtcclxuICAgICAgICAgICAgY29uc3QgdGV4dCA9ICFjb250ZW50ID8gdGV4dE9yVGl0bGUgOiBjb250ZW50O1xyXG4gICAgICAgICAgICB0aGlzLnByZXR0eVByaW50KHRpdGxlLCB0ZXh0LCAnI0Y1NkM2QycpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgd2FybmluZzogKHRleHRPclRpdGxlOiBhbnksIGNvbnRlbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCB0aXRsZSA9ICFjb250ZW50ID8gJ1dhcm5pbmcnIDogdGV4dE9yVGl0bGU7XHJcbiAgICAgICAgICAgIGNvbnN0IHRleHQgPSAhY29udGVudCA/IHRleHRPclRpdGxlIDogY29udGVudDtcclxuICAgICAgICAgICAgdGhpcy5wcmV0dHlQcmludCh0aXRsZSwgdGV4dCwgJyNFNkEyM0MnKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN1Y2Nlc3M6ICh0ZXh0T3JUaXRsZTogYW55LCBjb250ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgdGl0bGUgPSAhY29udGVudCA/ICdTdWNjZXNzJyA6IHRleHRPclRpdGxlO1xyXG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gIWNvbnRlbnQgPyB0ZXh0T3JUaXRsZSA6IGNvbnRlbnQ7XHJcbiAgICAgICAgICAgIHRoaXMucHJldHR5UHJpbnQodGl0bGUsIHRleHQsICcjNjdDMjNBJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8v576O5YyW5omT5Y2wXHJcbiAgICBwcml2YXRlIHByZXR0eVByaW50KHRpdGxlOiBzdHJpbmcsIGNvbnRlbnQ6IGFueSwgY29sb3I6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICAgICAgICBgJWMgJHt0aXRsZX0gJWMgJHt0eXBlb2YgY29udGVudCA9PSAnb2JqZWN0JyA/ICfwn5GHJyA6IGNvbnRlbnR9ICVjYCxcclxuICAgICAgICAgICAgYGJhY2tncm91bmQ6JHtjb2xvcn07Ym9yZGVyOjFweCBzb2xpZCAke2NvbG9yfTsgcGFkZGluZzogMXB4OyBib3JkZXItcmFkaXVzOiAycHggMCAwIDJweDsgY29sb3I6ICNmZmY7YCxcclxuICAgICAgICAgICAgYGJvcmRlcjoxcHggc29saWQgJHtjb2xvcn07IGJvcmRlci1yYWRpdXM6IDAgMnB4IDJweCAwOyBjb2xvcjogJHtjb2xvcn07cGFkZGluZzogMXB4O2AsXHJcbiAgICAgICAgICAgICdiYWNrZ3JvdW5kOnRyYW5zcGFyZW50J1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjb250ZW50ID09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUudGFibGUoY29udGVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyDmgKfog73orqHml7blmahcclxuICAgIHByaXZhdGUgdGltZXJzOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDlvIDlp4vmgKfog73orqHml7blmahcclxuICAgICAqIEBwYXJhbSB0aW1lck5hbWUg6K6h5pe25Zmo5ZCN56ewXHJcbiAgICAgKi9cclxuICAgIHN0YXJ0VGltZXIodGltZXJOYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRpbWVyc1t0aW1lck5hbWVdID0gcGVyZm9ybWFuY2Uubm93KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDnu5PmnZ/mgKfog73orqHml7blmajlubbov5Tlm57mjIHnu63ml7bpl7RcclxuICAgICAqIEBwYXJhbSB0aW1lck5hbWUg6K6h5pe25Zmo5ZCN56ewXHJcbiAgICAgKiBAcmV0dXJucyDorqHml7blmajmjIHnu63ml7bpl7TvvIjmr6vnp5LvvIlcclxuICAgICAqL1xyXG4gICAgZW5kVGltZXIodGltZXJOYW1lOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgICAgIGlmICghdGhpcy50aW1lcnNbdGltZXJOYW1lXSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYOiuoeaXtuWZqCBcIiR7dGltZXJOYW1lfVwiIOS4jeWtmOWcqOOAgmApO1xyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSBwZXJmb3JtYW5jZS5ub3coKSAtIHRoaXMudGltZXJzW3RpbWVyTmFtZV07XHJcbiAgICAgICAgZGVsZXRlIHRoaXMudGltZXJzW3RpbWVyTmFtZV07XHJcbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLeWFtuS7li0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgKiDmt7HlhYvpmoZcclxuICAgICogQHBhcmFtIG9iaiDooqvlhYvpmoblr7nosaFcclxuICAgICogQHJldHVybnMg5YWL6ZqG5a+56LGhXHJcbiAgICAqL1xyXG4gICAgZGVlcENsb25lPFQ+KG9iajogVCwgc2VlbiA9IG5ldyBNYXAoKSk6IFQge1xyXG4gICAgICAgIC8vIEhhbmRsZSBpbW11dGFibGUgdHlwZXMgYW5kIGZ1bmN0aW9uc1xyXG4gICAgICAgIGlmIChvYmogPT09IG51bGwgfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBjaXJjdWxhciByZWZlcmVuY2VzXHJcbiAgICAgICAgaWYgKHNlZW4uaGFzKG9iaikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHNlZW4uZ2V0KG9iaik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBIYW5kbGUgRGF0ZVxyXG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShvYmouZ2V0VGltZSgpKSBhcyBhbnk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBIYW5kbGUgUmVnRXhwXHJcbiAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFJlZ0V4cCkge1xyXG4gICAgICAgICAgICBjb25zdCByZWdFeHBDbG9uZSA9IG5ldyBSZWdFeHAob2JqLnNvdXJjZSwgb2JqLmZsYWdzKTtcclxuICAgICAgICAgICAgcmVnRXhwQ2xvbmUubGFzdEluZGV4ID0gb2JqLmxhc3RJbmRleDsgLy8gUHJlc2VydmUgdGhlIGxhc3RJbmRleCBwcm9wZXJ0eVxyXG4gICAgICAgICAgICByZXR1cm4gcmVnRXhwQ2xvbmUgYXMgYW55O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSGFuZGxlIEFycmF5XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xyXG4gICAgICAgICAgICBjb25zdCBhcnJDbG9uZTogYW55W10gPSBbXTtcclxuICAgICAgICAgICAgc2Vlbi5zZXQob2JqLCBhcnJDbG9uZSk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBvYmopIHtcclxuICAgICAgICAgICAgICAgIGFyckNsb25lLnB1c2godGhpcy5kZWVwQ2xvbmUoaXRlbSwgc2VlbikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhcnJDbG9uZSBhcyBhbnk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBIYW5kbGUgU2V0XHJcbiAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFNldCkge1xyXG4gICAgICAgICAgICBjb25zdCBzZXRDbG9uZSA9IG5ldyBTZXQoKTtcclxuICAgICAgICAgICAgc2Vlbi5zZXQob2JqLCBzZXRDbG9uZSk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBvYmopIHtcclxuICAgICAgICAgICAgICAgIHNldENsb25lLmFkZCh0aGlzLmRlZXBDbG9uZShpdGVtLCBzZWVuKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHNldENsb25lIGFzIGFueTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBNYXBcclxuICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgTWFwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1hcENsb25lID0gbmV3IE1hcCgpO1xyXG4gICAgICAgICAgICBzZWVuLnNldChvYmosIG1hcENsb25lKTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2Ygb2JqKSB7XHJcbiAgICAgICAgICAgICAgICBtYXBDbG9uZS5zZXQodGhpcy5kZWVwQ2xvbmUoa2V5LCBzZWVuKSwgdGhpcy5kZWVwQ2xvbmUodmFsdWUsIHNlZW4pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbWFwQ2xvbmUgYXMgYW55O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSGFuZGxlIE9iamVjdFxyXG4gICAgICAgIGNvbnN0IG9iakNsb25lID0gT2JqZWN0LmNyZWF0ZShPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSk7XHJcbiAgICAgICAgc2Vlbi5zZXQob2JqLCBvYmpDbG9uZSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBvYmpDbG9uZVtrZXldID0gdGhpcy5kZWVwQ2xvbmUoKG9iaiBhcyBhbnkpW2tleV0sIHNlZW4pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvYmpDbG9uZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOiOt+WPluaWh+S7tuWQjue8gFxyXG4gICAgICogQHBhcmFtIGZpbGVuYW1lIHN0cmluZyDmlofku7blkI1cclxuICAgICAqIEByZXR1cm5zIGV4dGVuc2lvblxyXG4gICAgICovXHJcbiAgICBnZXRGaWxlRXh0ZW5zaW9uKGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghZmlsZW5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBmaWxlbmFtZUFyciA9IGZpbGVuYW1lLnNwbGl0KCcuJyk7XHJcbiAgICAgICAgaWYgKGZpbGVuYW1lQXJyLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSBmaWxlbmFtZUFyci5wb3AoKSE7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb24udG9Mb3dlckNhc2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBqc29ucOWwgeijhVxyXG4gICAgICogQHBhcmFtIG9iaiBcXHt1cmw6ICcnLCBzdWNjZXNzOiAoKT0+IHt9fVxyXG4gICAgICovXHJcbiAgICBqc29ucEZ1bmN0aW9uKG9iajogYW55KSB7XHJcbiAgICAgICAgLy8g5Yib5bu65LiA5Liqc2NyaXB05qCH562+O1xyXG4gICAgICAgIHZhciBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xyXG4gICAgICAgIC8vIOe7meWHveaVsOi1t+WQjeWtl++8jOWumuS5ieS4uuWFqOWxgOWHveaVsO+8m1xyXG4gICAgICAgIHZhciBmbk5hbWU6IGFueSA9IFwianNvbnBcIiArIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICAgIC8vIHdpbmRvdy5hYWHlsLHmmK/miophYWHorr7nva7kuLrlhajlsYDlj5jph4/vvIFcclxuICAgICAgICB3aW5kb3dbZm5OYW1lXSA9IG9iai5zdWNjZXNzO1xyXG4gICAgICAgIC8vIOaUueWPmHNyYyzmt7vliqDliLBoZWFk5LitXHJcbiAgICAgICAgaWYgKG9iai51cmwuaW5jbHVkZXMoJz8nKSkge1xyXG4gICAgICAgICAgICBzY3JpcHQuc3JjID0gb2JqLnVybCArIFwiJmNhbGxiYWNrPVwiICsgZm5OYW1lO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgPSBvYmoudXJsICsgXCI/Y2FsbGJhY2s9XCIgKyBmbk5hbWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOaKinNjcmlwdOagh+etvua3u+WKoOWIsGhlYWTmoIfnrb7kuK3vvIzlsLHkvJrlj5HpgIFzcmPnmoTor7fmsYLkuoZcclxuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XHJcbiAgICAgICAgLy8g5Luj56CB5omn6KGM5a6M5q+V77yM5oqKc2NyaXB05qCH562+5Yig6ZmkXHJcbiAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpO1xyXG4gICAgICAgICAgICAod2luZG93W2ZuTmFtZV0gYXMgYW55KSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDmmK/lkKblrqLmiLfnq69cclxuICAgICAqL1xyXG4gICAgaXNCcm93c2VyOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICog55Sf5oiQ6ZqP5py66aKc6ImyXHJcbiAgICAgKiBAcmV0dXJucyBIRVhcclxuICAgICAqL1xyXG4gICAgZ2VuZXJhdGVSYW5kb21Db2xvcigpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiAnIycgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxNjc3NzIxNSkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDYsICcwJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAqIOeUn+aIkFVVSURcclxuICAgICogQHJldHVybnMgVVVJRFxyXG4gICAgKi9cclxuICAgIGdlbmVyYXRlVVVJRCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIChjKSA9PiB7XHJcbiAgICAgICAgICAgIHZhciByID0gTWF0aC5yYW5kb20oKSAqIDE2IHwgMCwgdiA9IGMgPT0gJ3gnID8gciA6IChyICYgMHgzIHwgMHg4KTtcclxuICAgICAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog6aqM6K+B5a+G56CB5by65bqm77yI5b+F6aG75YyF5ZCr5aSn44CB5bCP5YaZ5a2X5q+N44CB5pWw5a2X44CB54m55q6K5a2X56ym6Iez5bCR5LiJ57G777yM6ZW/5bqmOC0xNuS9je+8iVxyXG4gICAgICogQHBhcmFtIHBhc3N3b3JkIOW+hemqjOivgeeahOWvhueggVxyXG4gICAgICogQHJldHVybnMg5a+G56CB5piv5ZCm56ym5ZCI6KaB5rGCXHJcbiAgICAgKi9cclxuICAgIHBhc3N3b3JkVmFsaWRhdGUocGFzc3dvcmQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIOajgOafpeWvhueggemVv+W6puaYr+WQpuWcqDjliLAxNuS9jeS5i+mXtFxyXG4gICAgICAgIGlmIChwYXNzd29yZC5sZW5ndGggPCA4IHx8IHBhc3N3b3JkLmxlbmd0aCA+IDE2KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICAvLyDlrprkuYnmraPliJnooajovr7lvI/op4TliJlcclxuICAgICAgICBsZXQgckMgPSB7XHJcbiAgICAgICAgICAgIGxXOiAnW2Etel0nLCAgLy8g5bCP5YaZ5a2X5q+NXHJcbiAgICAgICAgICAgIHVXOiAnW0EtWl0nLCAgLy8g5aSn5YaZ5a2X5q+NXHJcbiAgICAgICAgICAgIG5XOiAnWzAtOV0nLCAgLy8g5pWw5a2XXHJcbiAgICAgICAgICAgIHNXOiAnW2B+IUAkJVxcXlxcJlxcKFxcKVxcLV9cXCs9XFx7XFx9XFxbXFxdfFxcXFw6O1xcXCJcXCc8PixcXC5cXD9cXC9fXScgIC8vIOeJueauiuWtl+esplxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIOajgOafpeWtl+espuS4suaYr+WQpuWMuemFjeato+WImeihqOi+vuW8j1xyXG4gICAgICAgICAqIEBwYXJhbSBzdHIg5b6F5qOA5p+l55qE5a2X56ym5LiyXHJcbiAgICAgICAgICogQHBhcmFtIHJTdHIg5q2j5YiZ6KGo6L6+5byP5a2X56ym5LiyXHJcbiAgICAgICAgICogQHJldHVybnMg5piv5ZCm5Yy56YWNXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gUmVnKHN0cjogc3RyaW5nLCByU3RyOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICAgICAgbGV0IHJlZyA9IG5ldyBSZWdFeHAoclN0cik7XHJcbiAgICAgICAgICAgIHJldHVybiByZWcudGVzdChzdHIpO1xyXG4gICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgIC8vIOajgOafpeWvhueggeaYr+WQpuWMheWQq+WQhOenjeWtl+espuexu+Wei1xyXG4gICAgICAgIGxldCB0UiA9IHtcclxuICAgICAgICAgICAgbDogUmVnKHBhc3N3b3JkLCByQy5sVyksICAvLyDmmK/lkKbljIXlkKvlsI/lhpnlrZfmr41cclxuICAgICAgICAgICAgdTogUmVnKHBhc3N3b3JkLCByQy51VyksICAvLyDmmK/lkKbljIXlkKvlpKflhpnlrZfmr41cclxuICAgICAgICAgICAgbjogUmVnKHBhc3N3b3JkLCByQy5uVyksICAvLyDmmK/lkKbljIXlkKvmlbDlrZdcclxuICAgICAgICAgICAgczogUmVnKHBhc3N3b3JkLCByQy5zVykgICAvLyDmmK/lkKbljIXlkKvnibnmrorlrZfnrKZcclxuICAgICAgICB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIOWvhueggeW/hemhu+WMheWQq+S7peS4i+Wbm+enjee7hOWQiOS5i+S4gO+8mlxyXG4gICAgICAgIC8vIDEuIOWwj+WGmeWtl+avjSArIOWkp+WGmeWtl+avjSArIOaVsOWtl1xyXG4gICAgICAgIC8vIDIuIOWwj+WGmeWtl+avjSArIOWkp+WGmeWtl+avjSArIOeJueauiuWtl+esplxyXG4gICAgICAgIC8vIDMuIOeJueauiuWtl+espiArIOWkp+WGmeWtl+avjSArIOaVsOWtl1xyXG4gICAgICAgIC8vIDQuIOeJueauiuWtl+espiArIOWwj+WGmeWtl+avjSArIOaVsOWtl1xyXG4gICAgICAgIHJldHVybiAodFIubCAmJiB0Ui51ICYmIHRSLm4pIHx8ICh0Ui5sICYmIHRSLnUgJiYgdFIucykgfHwgKHRSLnMgJiYgdFIudSAmJiB0Ui5uKSB8fCAodFIucyAmJiB0Ui5sICYmIHRSLm4pO1xyXG4gICAgfVxyXG59XHJcblxyXG4iXX0=