UNPKG

ng-voice-inputs

Version:

This library provides Voice Recognition service to fill the form input fields (text, datepicker, textarea, button-click) for Angular application.

535 lines 44.3 kB
/** * @fileoverview added by tsickle * Generated from: lib/ng-voice-inputs.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import * as moment_ from 'moment/moment'; import * as i0 from "@angular/core"; /** @type {?} */ const moment = moment_; import { Subject } from 'rxjs'; /** @type {?} */ const UNIT = { zero: 0, first: 1, one: 1, second: 2, two: 2, third: 3, thirteenth: 13, thirteen: 13, three: 3, fourth: 4, fourteenth: 14, fourteen: 14, four: 4, fifteenth: 15, fifteen: 15, fifth: 5, five: 5, sixth: 6, sixteenth: 16, sixteen: 16, six: 6, seventeenth: 17, seventeen: 17, seventh: 7, seven: 7, eighteenth: 18, eighteen: 18, eighth: 8, eight: 8, nineteenth: 19, nineteen: 19, ninth: 9, nine: 9, tenth: 10, ten: 10, eleventh: 11, eleven: 11, twelfth: 12, twelve: 12, a: 1, }; /** @type {?} */ const TWOS = { ten: 10, eleven: 11, twelve: 12, thirteen: 13, fourteen: 14, fifteen: 15, sixteen: 16, seventeen: 17, eighteen: 18, nineteen: 19 }; /** @type {?} */ const TEN = { twenty: 20, twentieth: 20, thirty: 30, thirtieth: 30, forty: 40, fortieth: 40, fifty: 50, fiftieth: 50, sixty: 60, sixtieth: 60, seventy: 70, seventieth: 70, eighty: 80, eightieth: 80, ninety: 90, ninetieth: 90, }; /** @type {?} */ const MAGNITUDE = { hundred: 100, hundredth: 100, thousand: 1000, million: 1000000, billion: 1000000000, trillion: 1000000000000, quadrillion: 1000000000000000, quintillion: 1000000000000000000, sextillion: 1000000000000000000000, septillion: 1000000000000000000000000, octillion: 1000000000000000000000000000, nonillion: 1000000000000000000000000000000, decillion: 1000000000000000000000000000000000, }; /** @type {?} */ const NUMBER = Object.assign({}, UNIT, TEN, MAGNITUDE); /** @type {?} */ const SUFFIXES = ['st', 'nd', 'rd', 'th']; /** @type {?} */ const MONTHS = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"]; /** @type {?} */ const KEY_WORDS_FWD_NAV = ['forward', 'next']; /** @type {?} */ const KEY_WORDS_BCK_NAV = ['back', 'backward', 'previous']; /** @type {?} */ const KEY_WORDS_CLEAR = ['clear', 'clean', 'delete', 'remove']; /** @type {?} */ const KEY_WORDS_CLICK = ['click', 'submit', 'expand', 'open', 'show']; /** @type {?} */ const KEY_WORDS_STOP = ['stop', 'end', 'done']; /** @type {?} */ const KEY_WORDS_SCROLL_UP = ['scroll up', 'go up', 'up']; /** @type {?} */ const KEY_WORDS_SCROLL_DOWN = ['scroll down', 'go down', 'down']; /** @type {?} */ const KEY_WORDS_SCROLL_RIGHT = ['scroll right', 'go right', 'right']; /** @type {?} */ const KEY_WORDS_SCROLL_LEFT = ['scroll left', 'go left', 'left']; /** @type {?} */ const KEY_WORDS_SCROLL_TOP = ['scroll top', 'go top', 'top']; /** @type {?} */ const KEY_WORDS_SCROLL_BOTTOM = ['scroll bottom', 'go bottom', 'bottom']; /** @type {?} */ const KEY_WORDS_SCROLL_CONTINUE = ['keep scrolling', 'scroll', 'scrolling', 'continue scrolling']; /** @type {?} */ const KEY_WORDS_SCROLL = [ ...KEY_WORDS_SCROLL_UP, ...KEY_WORDS_SCROLL_DOWN, ...KEY_WORDS_SCROLL_RIGHT, ...KEY_WORDS_SCROLL_LEFT, ...KEY_WORDS_SCROLL_TOP, ...KEY_WORDS_SCROLL_BOTTOM, ...KEY_WORDS_SCROLL_CONTINUE ]; /** @type {?} */ const KEY_WORDS_INST = ['goto', 'switch', 'go', ...KEY_WORDS_CLEAR, ...KEY_WORDS_CLICK, ...KEY_WORDS_SCROLL]; // Instruction types /** @type {?} */ const KEY_WORDS_NAV = [ ...KEY_WORDS_FWD_NAV, ...KEY_WORDS_BCK_NAV, ...KEY_WORDS_STOP, ...KEY_WORDS_SCROLL, 'first', 'last', ]; // Navigation types /** @type {?} */ const KEY_WORDS = [...KEY_WORDS_INST, ...KEY_WORDS_NAV]; /** @type {?} */ const INST_MAPPINGS = { next: KEY_WORDS_FWD_NAV, previous: KEY_WORDS_BCK_NAV, first: ['first'], last: ['last'], clear: KEY_WORDS_CLEAR, click: KEY_WORDS_CLICK, stop: KEY_WORDS_STOP, scrollUp: KEY_WORDS_SCROLL_UP, scrollDown: KEY_WORDS_SCROLL_DOWN, scrollLeft: KEY_WORDS_SCROLL_LEFT, scrollRight: KEY_WORDS_SCROLL_RIGHT, scrollTop: KEY_WORDS_SCROLL_TOP, scrollBottom: KEY_WORDS_SCROLL_BOTTOM, scrollContinue: KEY_WORDS_SCROLL_CONTINUE }; export class VuiVoiceRecognitionService { constructor() { this.response = new Subject(); this.inputRefs = []; this.currentRef = 0; } /** * @param {?} speechKeys * @param {?} inputType * @return {?} */ isInputSwitch(speechKeys, inputType) { if (inputType == 'address' && !speechKeys.some((/** * @param {?} key * @return {?} */ key => KEY_WORDS_INST.includes(key)))) { return false; } if (speechKeys.some((/** * @param {?} key * @return {?} */ key => KEY_WORDS.includes(key)))) { return true; } return false; } /** * @param {?} speechText * @param {?} inputType * @return {?} */ findInstructionType(speechText, inputType) { /** @type {?} */ let type = ''; speechText = speechText.trim().toLocaleLowerCase(); /** @type {?} */ let speechKeys = speechText.trim().toLocaleLowerCase().split(' '); if (this.isInputSwitch(speechKeys, inputType)) { /** @type {?} */ const foundKey = Object.keys(INST_MAPPINGS).find((/** * @param {?} instType * @return {?} */ (instType) => speechKeys.some((/** * @param {?} key * @return {?} */ key => INST_MAPPINGS[instType].includes(key))))); type = foundKey ? `COMMAND_${foundKey.toUpperCase()}` : ''; } else { type = 'INPUT'; } return type; } /** * @param {?} speechText * @param {?} inputType * @return {?} */ interpretSpeech(speechText, inputType) { /** @type {?} */ let instType = this.findInstructionType(speechText, inputType); if (instType != 'INPUT') { return instType; } if (inputType == 'text' || inputType == 'address') { return speechText; } if (inputType == 'number') { return this.wordsToNumber(speechText); } if (inputType == 'date') { speechText = speechText.replace('from', ''); /** @type {?} */ let dates = speechText.trim().split('to '); /** @type {?} */ let parsedDates = []; dates.forEach((/** * @param {?} dateStr * @return {?} */ (dateStr) => { parsedDates.push(this.dateParser(dateStr)); })); if (parsedDates[0].isValid()) { return parsedDates; } } return null; } /** * @param {?} dateStr * @return {?} */ dateParser(dateStr) { /** @type {?} */ let parsedDate; /** @type {?} */ let cleanDateStr = dateStr; /** @type {?} */ let dateParts = dateStr.trim().split(' '); /** @type {?} */ let datePartObj = {}; /** @type {?} */ let isPureNumber = false; /** @type {?} */ let cleanDateParts = []; if (dateParts.length == 3) { cleanDateParts = dateParts.map((/** * @param {?} dateStr * @return {?} */ (dateStr) => this.eliminateString(dateStr))); isPureNumber = cleanDateParts.every((/** * @param {?} dateStr * @return {?} */ (dateStr) => Number.isInteger(dateStr))); } if (isPureNumber) { cleanDateStr = cleanDateParts.join('-'); } else { /** @type {?} */ const currentDate = moment(); dateParts.forEach((/** * @param {?} dateStr * @return {?} */ (dateStr) => { datePartObj = this.parseDatePart(dateStr, datePartObj); })); /** @type {?} */ const availableKeys = Object.keys(datePartObj).join('-'); switch (availableKeys) { case 'date': datePartObj.month = currentDate.format('MM'); case 'date-month': datePartObj.year = currentDate.format('YYYY'); break; case 'year': datePartObj.month = '01'; case 'month-year': datePartObj.date = '01'; break; case 'month': datePartObj.year = currentDate.format('YYYY'); datePartObj.date = '01'; } cleanDateStr = this.dateBuilder(datePartObj); } parsedDate = moment(cleanDateStr).toDate(); return parsedDate; } /** * @param {?} datePartObj * @return {?} */ dateBuilder(datePartObj) { /** @type {?} */ let dateStr = ''; dateStr = `${datePartObj.year}-${datePartObj.month}-${datePartObj.date}`; return dateStr; } /** * * @param {?} datePart Incomplete date part eg, '21st' is the date part for the date '21st July 2020' * @param {?} datePartObj // Inherited from caller & updated with parsed object. Can be year, month or date * @return {?} */ parseDatePart(datePart, datePartObj) { if (this.isYearType(datePart)) { /** @type {?} */ const year = this.wordsToNumber(datePart); datePartObj.year = year; } else if (this.isDateType(datePart)) { /** @type {?} */ const date = this.wordsToNumber(datePart); datePartObj.date = date; } else if (this.isMonthType(datePart)) { /** @type {?} */ const month = MONTHS.indexOf(datePart.toUpperCase()) + 1; datePartObj.month = month < 10 ? '0' + month : month; } return datePartObj; } /** * @param {?} datePart * @return {?} */ isDateType(datePart) { /** @type {?} */ let isDatePart = false; isDatePart = (/\d/.test(datePart) && SUFFIXES.includes(datePart.substr(datePart.length - 2))); if (!isDatePart) { /** @type {?} */ const number = this.wordsToNumber(datePart); if (number > 0 && number <= 31) { isDatePart = true; } } return isDatePart; } /** * @param {?} datePart * @param {?} datePartObj * @return {?} */ parseDateVal(datePart, datePartObj) { /** @type {?} */ let isDatePart = false; /** @type {?} */ let convertedNum = 0; isDatePart = SUFFIXES.some((/** * @param {?} key * @return {?} */ (key) => { return datePart.includes(key); })); if (!isDatePart) { convertedNum = this.wordsToNumber(datePart); if (convertedNum > 0 && convertedNum <= 31) { isDatePart = true; } } if (isDatePart) { datePartObj.date = convertedNum; } } /** * @param {?} datePart * @return {?} */ isMonthType(datePart) { /** @type {?} */ const month = MONTHS.indexOf(datePart.toUpperCase()); return month > -1; } /** * @param {?} datePart * @param {?} datePartObj * @return {?} */ parseMonthVal(datePart, datePartObj) { /** @type {?} */ const month = MONTHS.indexOf(datePart.toUpperCase()); if (month > -1) { datePartObj.month = month < 10 ? '0' + month : month; } } /** * @param {?} datePart * @return {?} */ isYearType(datePart) { /** @type {?} */ let year = this.wordsToNumber(datePart); return year > 1000; } /** * @param {?} datePart * @param {?} datePartObj * @return {?} */ parseYearVal(datePart, datePartObj) { /** @type {?} */ const year = this.wordsToNumber(datePart); if (year > 1000) { datePartObj.year = year; } } /** * @param {?} word * @return {?} */ wordsToNumber(word) { // Returning integer if it is not actual word if (!Number.isNaN(parseInt(word))) { return parseInt(word); } word = word.replace(/and/g, ''); // Replace joiners // Replace joiners /** @type {?} */ let words = word.toLowerCase().trim().split(' '); /** @type {?} */ let num = 0; /** @type {?} */ let numStr = ''; /** @type {?} */ let tens = 0; words = this.parseColloquialWords(words); words.forEach((/** * @param {?} wordStr * @return {?} */ wordStr => { wordStr = this.eliminateString(wordStr); if (typeof wordStr == 'number') { num = wordStr; } else { if (UNIT[wordStr]) { num = num + NUMBER[wordStr]; } else if (TEN[wordStr]) { num = num + TEN[wordStr]; } else if (MAGNITUDE[wordStr]) { num = num * MAGNITUDE[wordStr]; } } })); return num; } /** * @param {?} wordsArr * @return {?} */ parseColloquialWords(wordsArr) { if (wordsArr.length == 2) { if (TEN[wordsArr[0]] && (TEN[wordsArr[1]] || TWOS[wordsArr[1]])) { wordsArr.splice(1, 0, 'hundred'); } } if (MAGNITUDE[wordsArr[0]]) { wordsArr.splice(0, 0, 'one'); } return wordsArr; } /** * @param {?} word * @return {?} */ eliminateString(word) { if (/\d/.test(word) && SUFFIXES.includes(word.substr(word.length - 2))) { word = word.substr(0, word.length - 2); // Remove last suffixes such as 'st', 'th' from 1st, 10th word = parseInt(word); } return word; } } VuiVoiceRecognitionService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ VuiVoiceRecognitionService.ngInjectableDef = i0.defineInjectable({ factory: function VuiVoiceRecognitionService_Factory() { return new VuiVoiceRecognitionService(); }, token: VuiVoiceRecognitionService, providedIn: "root" }); if (false) { /** @type {?} */ VuiVoiceRecognitionService.prototype.response; /** @type {?} */ VuiVoiceRecognitionService.prototype.inputRefs; /** @type {?} */ VuiVoiceRecognitionService.prototype.currentRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdm9pY2UtaW5wdXRzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy12b2ljZS1pbnB1dHMvIiwic291cmNlcyI6WyJsaWIvbmctdm9pY2UtaW5wdXRzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQWMsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZELE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDOzs7TUFDbkMsTUFBTSxHQUFHLE9BQU87QUFDdEIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7TUFHekIsSUFBSSxHQUFHO0lBQ1gsSUFBSSxFQUFFLENBQUM7SUFDUCxLQUFLLEVBQUUsQ0FBQztJQUNSLEdBQUcsRUFBRSxDQUFDO0lBQ04sTUFBTSxFQUFFLENBQUM7SUFDVCxHQUFHLEVBQUUsQ0FBQztJQUNOLEtBQUssRUFBRSxDQUFDO0lBQ1IsVUFBVSxFQUFFLEVBQUU7SUFDZCxRQUFRLEVBQUUsRUFBRTtJQUNaLEtBQUssRUFBRSxDQUFDO0lBQ1IsTUFBTSxFQUFFLENBQUM7SUFDVCxVQUFVLEVBQUUsRUFBRTtJQUNkLFFBQVEsRUFBRSxFQUFFO0lBQ1osSUFBSSxFQUFFLENBQUM7SUFDUCxTQUFTLEVBQUUsRUFBRTtJQUNiLE9BQU8sRUFBRSxFQUFFO0lBQ1gsS0FBSyxFQUFFLENBQUM7SUFDUixJQUFJLEVBQUUsQ0FBQztJQUNQLEtBQUssRUFBRSxDQUFDO0lBQ1IsU0FBUyxFQUFFLEVBQUU7SUFDYixPQUFPLEVBQUUsRUFBRTtJQUNYLEdBQUcsRUFBRSxDQUFDO0lBQ04sV0FBVyxFQUFFLEVBQUU7SUFDZixTQUFTLEVBQUUsRUFBRTtJQUNiLE9BQU8sRUFBRSxDQUFDO0lBQ1YsS0FBSyxFQUFFLENBQUM7SUFDUixVQUFVLEVBQUUsRUFBRTtJQUNkLFFBQVEsRUFBRSxFQUFFO0lBQ1osTUFBTSxFQUFFLENBQUM7SUFDVCxLQUFLLEVBQUUsQ0FBQztJQUNS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bWVudFJlZiwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgbW9tZW50XyBmcm9tICdtb21lbnQvbW9tZW50JztcbmNvbnN0IG1vbWVudCA9IG1vbWVudF87XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgVnVpUmVzcG9uc2UgZnJvbSAnLi92dWktcmVzcG9uc2UnO1xuXG5jb25zdCBVTklUID0ge1xuICB6ZXJvOiAwLFxuICBmaXJzdDogMSxcbiAgb25lOiAxLFxuICBzZWNvbmQ6IDIsXG4gIHR3bzogMixcbiAgdGhpcmQ6IDMsXG4gIHRoaXJ0ZWVudGg6IDEzLFxuICB0aGlydGVlbjogMTMsXG4gIHRocmVlOiAzLFxuICBmb3VydGg6IDQsXG4gIGZvdXJ0ZWVudGg6IDE0LFxuICBmb3VydGVlbjogMTQsXG4gIGZvdXI6IDQsXG4gIGZpZnRlZW50aDogMTUsXG4gIGZpZnRlZW46IDE1LFxuICBmaWZ0aDogNSxcbiAgZml2ZTogNSxcbiAgc2l4dGg6IDYsXG4gIHNpeHRlZW50aDogMTYsXG4gIHNpeHRlZW46IDE2LFxuICBzaXg6IDYsXG4gIHNldmVudGVlbnRoOiAxNyxcbiAgc2V2ZW50ZWVuOiAxNyxcbiAgc2V2ZW50aDogNyxcbiAgc2V2ZW46IDcsXG4gIGVpZ2h0ZWVudGg6IDE4LFxuICBlaWdodGVlbjogMTgsXG4gIGVpZ2h0aDogOCxcbiAgZWlnaHQ6IDgsXG4gIG5pbmV0ZWVudGg6IDE5LFxuICBuaW5ldGVlbjogMTksXG4gIG5pbnRoOiA5LFxuICBuaW5lOiA5LFxuICB0ZW50aDogMTAsXG4gIHRlbjogMTAsXG4gIGVsZXZlbnRoOiAxMSxcbiAgZWxldmVuOiAxMSxcbiAgdHdlbGZ0aDogMTIsXG4gIHR3ZWx2ZTogMTIsXG4gIGE6IDEsXG59O1xuXG5jb25zdCBUV09TID0ge1xuICB0ZW46IDEwLFxuICBlbGV2ZW46IDExLCBcbiAgdHdlbHZlOiAxMiwgXG4gIHRoaXJ0ZWVuOiAxMywgXG4gIGZvdXJ0ZWVuOiAxNCwgXG4gIGZpZnRlZW46IDE1LCBcbiAgc2l4dGVlbjogMTYsIFxuICBzZXZlbnRlZW46IDE3LFxuICBlaWdodGVlbjogMTgsXG4gIG5pbmV0ZWVuOiAxOVxufVxuXG5jb25zdCBURU4gPSB7XG4gIHR3ZW50eTogMjAsXG4gIHR3ZW50aWV0aDogMjAsXG4gIHRoaXJ0eTogMzAsXG4gIHRoaXJ0aWV0aDogMzAsXG4gIGZvcnR5OiA0MCxcbiAgZm9ydGlldGg6IDQwLFxuICBmaWZ0eTogNTAsXG4gIGZpZnRpZXRoOiA1MCxcbiAgc2l4dHk6IDYwLFxuICBzaXh0aWV0aDogNjAsXG4gIHNldmVudHk6IDcwLFxuICBzZXZlbnRpZXRoOiA3MCxcbiAgZWlnaHR5OiA4MCxcbiAgZWlnaHRpZXRoOiA4MCxcbiAgbmluZXR5OiA5MCxcbiAgbmluZXRpZXRoOiA5MCxcbn07XG5cbmNvbnN0IE1BR05JVFVERSA9IHtcbiAgaHVuZHJlZDogMTAwLFxuICBodW5kcmVkdGg6IDEwMCxcbiAgdGhvdXNhbmQ6IDEwMDAsXG4gIG1pbGxpb246IDEwMDAwMDAsXG4gIGJpbGxpb246IDEwMDAwMDAwMDAsXG4gIHRyaWxsaW9uOiAxMDAwMDAwMDAwMDAwLFxuICBxdWFkcmlsbGlvbjogMTAwMDAwMDAwMDAwMDAwMCxcbiAgcXVpbnRpbGxpb246IDEwMDAwMDAwMDAwMDAwMDAwMDAsXG4gIHNleHRpbGxpb246IDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAsXG4gIHNlcHRpbGxpb246IDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAsXG4gIG9jdGlsbGlvbjogMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCxcbiAgbm9uaWxsaW9uOiAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLFxuICBkZWNpbGxpb246IDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAsXG59O1xuXG5jb25zdCBOVU1CRVIgPSB7IC4uLlVOSVQsIC4uLlRFTiwgLi4uTUFHTklUVURFIH07XG5jb25zdCBTVUZGSVhFUyA9IFsnc3QnLCAnbmQnLCAncmQnLCAndGgnXTtcblxuY29uc3QgTU9OVEhTID0gW1wiSkFOVUFSWVwiLCBcIkZFQlJVQVJZXCIsIFwiTUFSQ0hcIiwgXCJBUFJJTFwiLCBcIk1BWVwiLCBcIkpVTkVcIiwgXCJKVUxZXCIsIFwiQVVHVVNUXCIsIFwiU0VQVEVNQkVSXCIsIFwiT0NUT0JFUlwiLCBcIk5PVkVNQkVSXCIsIFwiREVDRU1CRVJcIl07XG5cbmNvbnN0IEtFWV9XT1JEU19GV0RfTkFWID0gWydmb3J3YXJkJywgJ25leHQnXTtcbmNvbnN0IEtFWV9XT1JEU19CQ0tfTkFWID0gWydiYWNrJywgJ2JhY2t3YXJkJywgJ3ByZXZpb3VzJ107XG5jb25zdCBLRVlfV09SRFNfQ0xFQVIgPSBbJ2NsZWFyJywgJ2NsZWFuJywgJ2RlbGV0ZScsICdyZW1vdmUnXTtcbmNvbnN0IEtFWV9XT1JEU19DTElDSyA9IFsnY2xpY2snLCAnc3VibWl0JywgJ2V4cGFuZCcsICdvcGVuJywgJ3Nob3cnXTtcbmNvbnN0IEtFWV9XT1JEU19TVE9QID0gWydzdG9wJywgJ2VuZCcsICdkb25lJ107XG5jb25zdCBLRVlfV09SRFNfU0NST0xMX1VQID0gWydzY3JvbGwgdXAnLCAnZ28gdXAnLCAndXAnXTtcbmNvbnN0IEtFWV9XT1JEU19TQ1JPTExfRE9XTiA9IFsnc2Nyb2xsIGRvd24nLCAnZ28gZG93bicsICdkb3duJ107XG5jb25zdCBLRVlfV09SRFNfU0NST0xMX1JJR0hUID0gWydzY3JvbGwgcmlnaHQnLCAnZ28gcmlnaHQnLCAncmlnaHQnXTtcbmNvbnN0IEtFWV9XT1JEU19TQ1JPTExfTEVGVCA9IFsnc2Nyb2xsIGxlZnQnLCAnZ28gbGVmdCcsICdsZWZ0J107XG5jb25zdCBLRVlfV09SRFNfU0NST0xMX1RPUCA9IFsnc2Nyb2xsIHRvcCcsICdnbyB0b3AnLCAndG9wJ107XG5jb25zdCBLRVlfV09SRFNfU0NST0xMX0JPVFRPTSA9IFsnc2Nyb2xsIGJvdHRvbScsICdnbyBib3R0b20nLCAnYm90dG9tJ107XG5jb25zdCBLRVlfV09SRFNfU0NST0xMX0NPTlRJTlVFID0gWydrZWVwIHNjcm9sbGluZycsICdzY3JvbGwnLCAnc2Nyb2xsaW5nJywgJ2NvbnRpbnVlIHNjcm9sbGluZyddXG5jb25zdCBLRVlfV09SRFNfU0NST0xMID0gW1xuICAuLi5LRVlfV09SRFNfU0NST0xMX1VQLFxuICAuLi5LRVlfV09SRFNfU0NST0xMX0RPV04sXG4gIC4uLktFWV9XT1JEU19TQ1JPTExfUklHSFQsXG4gIC4uLktFWV9XT1JEU19TQ1JPTExfTEVGVCxcbiAgLi4uS0VZX1dPUkRTX1NDUk9MTF9UT1AsXG4gIC4uLktFWV9XT1JEU19TQ1JPTExfQk9UVE9NLFxuICAuLi5LRVlfV09SRFNfU0NST0xMX0NPTlRJTlVFXG5dO1xuXG5jb25zdCBLRVlfV09SRFNfSU5TVCA9IFsnZ290bycsICdzd2l0Y2gnLCAnZ28nLCAuLi5LRVlfV09SRFNfQ0xFQVIsIC4uLktFWV9XT1JEU19DTElDSywgLi4uS0VZX1dPUkRTX1NDUk9MTF07IC8vIEluc3RydWN0aW9uIHR5cGVzXG5jb25zdCBLRVlfV09SRFNfTkFWID0gW1xuICAuLi5LRVlfV09SRFNfRldEX05BVixcbiAgLi4uS0VZX1dPUkRTX0JDS19OQVYsXG4gIC4uLktFWV9XT1JEU19TVE9QLFxuICAuLi5LRVlfV09SRFNfU0NST0xMXG4gICwgJ2ZpcnN0JywgJ2xhc3QnLFxuXTsgLy8gTmF2aWdhdGlvbiB0eXBlc1xuXG5jb25zdCBLRVlfV09SRFMgPSBbLi4uS0VZX1dPUkRTX0lOU1QsIC4uLktFWV9XT1JEU19OQVZdO1xuXG5jb25zdCBJTlNUX01BUFBJTkdTID0ge1xuICBuZXh0OiBLRVlfV09SRFNfRldEX05BVixcbiAgcHJldmlvdXM6IEtFWV9XT1JEU19CQ0tfTkFWLFxuICBmaXJzdDogWydmaXJzdCddLFxuICBsYXN0OiBbJ2xhc3QnXSxcbiAgY2xlYXI6IEtFWV9XT1JEU19DTEVBUixcbiAgY2xpY2s6IEtFWV9XT1JEU19DTElDSyxcbiAgc3RvcDogS0VZX1dPUkRTX1NUT1AsXG4gIHNjcm9sbFVwOiBLRVlfV09SRFNfU0NST0xMX1VQLFxuICBzY3JvbGxEb3duOiBLRVlfV09SRFNfU0NST0xMX0RPV04sXG4gIHNjcm9sbExlZnQ6IEtFWV9XT1JEU19TQ1JPTExfTEVGVCxcbiAgc2Nyb2xsUmlnaHQ6IEtFWV9XT1JEU19TQ1JPTExfUklHSFQsXG4gIHNjcm9sbFRvcDogS0VZX1dPUkRTX1NDUk9MTF9UT1AsXG4gIHNjcm9sbEJvdHRvbTogS0VZX1dPUkRTX1NDUk9MTF9CT1RUT00sXG4gIHNjcm9sbENvbnRpbnVlOiBLRVlfV09SRFNfU0NST0xMX0NPTlRJTlVFXG59XG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBWdWlWb2ljZVJlY29nbml0aW9uU2VydmljZSB7XG4gIHJlc3BvbnNlOiBTdWJqZWN0PFZ1aVJlc3BvbnNlPiA9IG5ldyBTdWJqZWN0PFZ1aVJlc3BvbnNlPigpO1xuXG4gIGlucHV0UmVmczogQXJyYXk8RWxlbWVudFJlZj4gPSBbXTtcbiAgY3VycmVudFJlZjogbnVtYmVyID0gMDtcblxuICBpc0lucHV0U3dpdGNoKHNwZWVjaEtleXM6IGFueVtdLCBpbnB1dFR5cGU6IHN0cmluZykge1xuICAgIGlmIChpbnB1dFR5cGUgPT0gJ2FkZHJlc3MnICYmICFzcGVlY2hLZXlzLnNvbWUoa2V5ID0+IEtFWV9XT1JEU19JTlNULmluY2x1ZGVzKGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChzcGVlY2hLZXlzLnNvbWUoa2V5ID0+IEtFWV9XT1JEUy5pbmNsdWRlcyhrZXkpKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZpbmRJbnN0cnVjdGlvblR5cGUoc3BlZWNoVGV4dDogc3RyaW5nLCBpbnB1dFR5cGU6IHN0cmluZykge1xuICAgIGxldCB0eXBlID0gJyc7XG4gICAgc3BlZWNoVGV4dCA9IHNwZWVjaFRleHQudHJpbSgpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgbGV0IHNwZWVjaEtleXMgPSBzcGVlY2hUZXh0LnRyaW0oKS50b0xvY2FsZUxvd2VyQ2FzZSgpLnNwbGl0KCcgJyk7XG4gICAgaWYgKHRoaXMuaXNJbnB1dFN3aXRjaChzcGVlY2hLZXlzLCBpbnB1dFR5cGUpKSB7XG4gICAgICBjb25zdCBmb3VuZEtleSA9IE9iamVjdC5rZXlzKElOU1RfTUFQUElOR1MpLmZpbmQoKGluc3RUeXBlOiBzdHJpbmcpID0+IHNwZWVjaEtleXMuc29tZShrZXkgPT4gSU5TVF9NQVBQSU5HU1tpbnN0VHlwZV0uaW5jbHVkZXMoa2V5KSkpO1xuICAgICAgdHlwZSA9IGZvdW5kS2V5ID8gYENPTU1BTkRfJHtmb3VuZEtleS50b1VwcGVyQ2FzZSgpfWAgOiAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZSA9ICdJTlBVVCc7XG4gICAgfVxuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgaW50ZXJwcmV0U3BlZWNoKHNwZWVjaFRleHQ6IHN0cmluZywgaW5wdXRUeXBlOiBzdHJpbmcpIHtcbiAgICBsZXQgaW5zdFR5cGUgPSB0aGlzLmZpbmRJbnN0cnVjdGlvblR5cGUoc3BlZWNoVGV4dCwgaW5wdXRUeXBlKTtcbiAgICBpZiAoaW5zdFR5cGUgIT0gJ0lOUFVUJykge1xuICAgICAgcmV0dXJuIGluc3RUeXBlO1xuICAgIH1cblxuICAgIGlmIChpbnB1dFR5cGUgPT0gJ3RleHQnIHx8IGlucHV0VHlwZSA9PSAnYWRkcmVzcycpIHtcbiAgICAgIHJldHVybiBzcGVlY2hUZXh0O1xuICAgIH1cblxuICAgIGlmIChpbnB1dFR5cGUgPT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiB0aGlzLndvcmRzVG9OdW1iZXIoc3BlZWNoVGV4dCk7XG4gICAgfVxuXG4gICAgaWYgKGlucHV0VHlwZSA9PSAnZGF0ZScpIHtcbiAgICAgIHNwZWVjaFRleHQgPSBzcGVlY2hUZXh0LnJlcGxhY2UoJ2Zyb20nLCAnJyk7XG4gICAgICBsZXQgZGF0ZXMgPSAgc3BlZWNoVGV4dC50cmltKCkuc3BsaXQoJ3RvICcpO1xuICAgICAgbGV0IHBhcnNlZERhdGVzOiBBcnJheTxhbnk+ID0gW107XG4gICAgICBkYXRlcy5mb3JFYWNoKChkYXRlU3RyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgcGFyc2VkRGF0ZXMucHVzaCh0aGlzLmRhdGVQYXJzZXIoZGF0ZVN0cikpO1xuICAgICAgfSk7XG4gIFxuICAgICAgaWYgKHBhcnNlZERhdGVzWzBdLmlzVmFsaWQoKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VkRGF0ZXM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZGF0ZVBhcnNlcihkYXRlU3RyOiBzdHJpbmcpOiBEYXRlIHtcbiAgICBsZXQgcGFyc2VkRGF0ZTogRGF0ZTtcbiAgICBsZXQgY2xlYW5EYXRlU3RyID0gZGF0ZVN0cjtcbiAgICBsZXQgZGF0ZVBhcnRzID0gZGF0ZVN0ci50cmltKCkuc3BsaXQoJyAnKTtcbiAgICBsZXQgZGF0ZVBhcnRPYmo6IGFueSA9IHt9O1xuICAgIGxldCBpc1B1cmVOdW1iZXIgPSBmYWxzZTtcbiAgICBsZXQgY2xlYW5EYXRlUGFydHMgPSBbXTtcblxuICAgIGlmIChkYXRlUGFydHMubGVuZ3RoID09IDMpIHtcbiAgICAgIGNsZWFuRGF0ZVBhcnRzID0gZGF0ZVBhcnRzLm1hcCgoZGF0ZVN0cikgPT4gdGhpcy5lbGltaW5hdGVTdHJpbmcoZGF0ZVN0cikpO1xuICAgICAgaXNQdXJlTnVtYmVyID0gY2xlYW5EYXRlUGFydHMuZXZlcnkoKGRhdGVTdHIpID0+IE51bWJlci5pc0ludGVnZXIoZGF0ZVN0cikpO1xuICAgIH1cblxuICAgIGlmIChpc1B1cmVOdW1iZXIpIHtcbiAgICAgIGNsZWFuRGF0ZVN0ciA9IGNsZWFuRGF0ZVBhcnRzLmpvaW4oJy0nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY3VycmVudERhdGUgPSBtb21lbnQoKTtcbiAgICAgIGRhdGVQYXJ0cy5mb3JFYWNoKChkYXRlU3RyKSA9PiB7XG4gICAgICAgIGRhdGVQYXJ0T2JqID0gdGhpcy5wYXJzZURhdGVQYXJ0KGRhdGVTdHIsIGRhdGVQYXJ0T2JqKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhdmFpbGFibGVLZXlzID0gT2JqZWN0LmtleXMoZGF0ZVBhcnRPYmopLmpvaW4oJy0nKTtcbiAgICAgXG4gICAgICBzd2l0Y2ggKGF2YWlsYWJsZUtleXMpIHtcbiAgICAgICAgY2FzZSAnZGF0ZSc6IFxuICAgICAgICAgIGRhdGVQYXJ0T2JqLm1vbnRoID0gY3VycmVudERhdGUuZm9ybWF0KCdNTScpO1xuICAgICAgICBjYXNlICdkYXRlLW1vbnRoJzpcbiAgICAgICAgICBkYXRlUGFydE9iai55ZWFyID0gY3VycmVudERhdGUuZm9ybWF0KCdZWVlZJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgICAgIGRhdGVQYXJ0T2JqLm1vbnRoID0gJzAxJztcbiAgICAgICAgY2FzZSAnbW9udGgteWVhcic6XG4gICAgICAgICAgZGF0ZVBhcnRPYmouZGF0ZSA9ICcwMSc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICBkYXRlUGFydE9iai55ZWFyID0gY3VycmVudERhdGUuZm9ybWF0KCdZWVlZJyk7XG4gICAgICAgICAgZGF0ZVBhcnRPYmouZGF0ZSA9ICcwMSc7XG4gICAgICB9XG4gICAgICBjbGVhbkRhdGVTdHIgPSB0aGlzLmRhdGVCdWlsZGVyKGRhdGVQYXJ0T2JqKTtcbiAgICB9XG4gICAgcGFyc2VkRGF0ZSA9IG1vbWVudChjbGVhbkRhdGVTdHIpLnRvRGF0ZSgpO1xuICAgIHJldHVybiBwYXJzZWREYXRlO1xuICB9XG5cbiAgZGF0ZUJ1aWxkZXIoZGF0ZVBhcnRPYmo6IGFueSk6IHN0cmluZyB7XG4gICAgbGV0IGRhdGVTdHIgPSAnJztcbiAgICBkYXRlU3RyID0gYCR7ZGF0ZVBhcnRPYmoueWVhcn0tJHtkYXRlUGFydE9iai5tb250aH0tJHtkYXRlUGFydE9iai5kYXRlfWA7XG4gICAgcmV0dXJuIGRhdGVTdHI7XG4gIH1cblxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSBkYXRlUGFydCBJbmNvbXBsZXRlIGRhdGUgcGFydCBlZywgJzIxc3QnIGlzIHRoZSBkYXRlIHBhcnQgZm9yIHRoZSBkYXRlICcyMXN0IEp1bHkgMjAyMCdcbiAgICogQHBhcmFtIGRhdGVQYXJ0T2JqIC8vIEluaGVyaXRlZCBmcm9tIGNhbGxlciAmIHVwZGF0ZWQgd2l0aCBwYXJzZWQgb2JqZWN0LiBDYW4gYmUgeWVhciwgbW9udGggb3IgZGF0ZVxuICAgKi9cbiAgcGFyc2VEYXRlUGFydChkYXRlUGFydDogc3RyaW5nLCBkYXRlUGFydE9iajogYW55KTogYW55IHtcbiAgICBpZiAodGhpcy5pc1llYXJUeXBlKGRhdGVQYXJ0KSkge1xuICAgICAgY29uc3QgeWVhciA9IHRoaXMud29yZHNUb051bWJlcihkYXRlUGFydCk7XG4gICAgICBkYXRlUGFydE9iai55ZWFyID0geWVhcjtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRlVHlwZShkYXRlUGFydCkpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLndvcmRzVG9OdW1iZXIoZGF0ZVBhcnQpO1xuICAgICAgZGF0ZVBhcnRPYmouZGF0ZSA9IGRhdGU7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzTW9udGhUeXBlKGRhdGVQYXJ0KSkge1xuICAgICAgY29uc3QgbW9udGggPSBNT05USFMuaW5kZXhPZihkYXRlUGFydC50b1VwcGVyQ2FzZSgpKSArIDE7XG4gICAgICBkYXRlUGFydE9iai5tb250aCA9IG1vbnRoIDwgMTAgPyAnMCcgKyBtb250aCA6IG1vbnRoO1xuICAgIH1cbiAgICByZXR1cm4gZGF0ZVBhcnRPYmo7XG4gIH1cblxuICBpc0RhdGVUeXBlKGRhdGVQYXJ0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBsZXQgaXNEYXRlUGFydCA9IGZhbHNlO1xuICAgIGlzRGF0ZVBhcnQgPSAoL1xcZC8udGVzdChkYXRlUGFydCkgJiYgU1VGRklYRVMuaW5jbHVkZXMoZGF0ZVBhcnQuc3Vic3RyKCBkYXRlUGFydC5sZW5ndGggLSAyKSkpO1xuXG4gICAgaWYgKCFpc0RhdGVQYXJ0KSB7XG4gICAgICBjb25zdCBudW1iZXIgPSB0aGlzLndvcmRzVG9OdW1iZXIoZGF0ZVBhcnQpO1xuICAgICAgaWYgKG51bWJlciA+IDAgJiYgbnVtYmVyIDw9IDMxKSB7XG4gICAgICAgIGlzRGF0ZVBhcnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNEYXRlUGFydDtcbiAgfVxuXG4gIHBhcnNlRGF0ZVZhbChkYXRlUGFydCwgZGF0ZVBhcnRPYmopIHtcbiAgICBsZXQgaXNEYXRlUGFydCA9IGZhbHNlO1xuICAgIGxldCBjb252ZXJ0ZWROdW0gPSAwO1xuICAgIGlzRGF0ZVBhcnQgPSBTVUZGSVhFUy5zb21lKChrZXkpID0+IHtcbiAgICAgIHJldHVybiBkYXRlUGFydC5pbmNsdWRlcyhrZXkpO1xuICAgIH0pO1xuXG4gICAgaWYgKCFpc0RhdGVQYXJ0KSB7XG4gICAgICBjb252ZXJ0ZWROdW0gPSB0aGlzLndvcmRzVG9OdW1iZXIoZGF0ZVBhcnQpO1xuICAgICAgaWYgKGNvbnZlcnRlZE51bSA+IDAgJiYgY29udmVydGVkTnVtIDw9IDMxKSB7XG4gICAgICAgIGlzRGF0ZVBhcnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0RhdGVQYXJ0KSB7XG4gICAgICBkYXRlUGFydE9iai5kYXRlID0gY29udmVydGVkTnVtO1xuICAgIH1cbiAgfVxuXG4gIGlzTW9udGhUeXBlKGRhdGVQYXJ0KSB7XG4gICAgY29uc3QgbW9udGggPSBNT05USFMuaW5kZXhPZihkYXRlUGFydC50b1VwcGVyQ2FzZSgpKTtcbiAgICByZXR1cm4gbW9udGggPiAtMTtcbiAgfVxuXG4gIHBhcnNlTW9udGhWYWwoZGF0ZVBhcnQsIGRhdGVQYXJ0T2JqKSB7XG4gICAgY29uc3QgbW9udGggPSBNT05USFMuaW5kZXhPZihkYXRlUGFydC50b1VwcGVyQ2FzZSgpKTtcbiAgICBpZiAobW9udGggPiAtMSkge1xuICAgICAgZGF0ZVBhcnRPYmoubW9udGggPSBtb250aCA8IDEwID8gJzAnICsgbW9udGggOiBtb250aDtcbiAgICB9XG4gIH1cblxuICBpc1llYXJUeXBlKGRhdGVQYXJ0KSB7XG4gICAgbGV0IHllYXIgPSB0aGlzLndvcmRzVG9OdW1iZXIoZGF0ZVBhcnQpO1xuICAgIHJldHVybiB5ZWFyID4gMTAwMDtcbiAgfVxuXG4gIHBhcnNlWWVhclZhbChkYXRlUGFydCwgZGF0ZVBhcnRPYmopIHtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy53b3Jkc1RvTnVtYmVyKGRhdGVQYXJ0KTtcbiAgICBpZiAoeWVhciA+IDEwMDApIHtcbiAgICAgIGRhdGVQYXJ0T2JqLnllYXIgPSB5ZWFyO1xuICAgIH1cbiAgfVxuXG4gIHdvcmRzVG9OdW1iZXIod29yZCkge1xuICAgIFxuICAgIC8vIFJldHVybmluZyBpbnRlZ2VyIGlmIGl0IGlzIG5vdCBhY3R1YWwgd29yZFxuICAgIGlmICghTnVtYmVyLmlzTmFOKHBhcnNlSW50KHdvcmQpKSkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHdvcmQpO1xuICAgIH1cblxuICAgIHdvcmQgPSB3b3JkLnJlcGxhY2UoL2FuZC9nLCAnJyk7IC8vIFJlcGxhY2Ugam9pbmVyc1xuICAgIGxldCB3b3JkcyA9IHdvcmQudG9Mb3dlckNhc2UoKS50cmltKCkuc3BsaXQoJyAnKTtcbiAgICBsZXQgbnVtID0gMDtcbiAgICBsZXQgbnVtU3RyID0gJyc7XG4gICAgbGV0IHRlbnMgPSAwO1xuICAgIFxuICAgIHdvcmRzID0gdGhpcy5wYXJzZUNvbGxvcXVpYWxXb3Jkcyh3b3Jkcyk7XG4gICAgIFxuICAgIHdvcmRzLmZvckVhY2god29yZFN0ciA9PiB7XG4gICAgICB3b3JkU3RyID0gdGhpcy5lbGltaW5hdGVTdHJpbmcod29yZFN0cik7XG4gICAgICBpZiAodHlwZW9mIHdvcmRTdHIgPT0gJ251bWJlcicpIHtcbiAgICAgICAgbnVtID0gd29yZFN0cjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChVTklUW3dvcmRTdHJdKSB7XG4gICAgICAgICAgbnVtID0gbnVtICsgIE5VTUJFUlt3b3JkU3RyXTtcbiAgICAgICAgfSBlbHNlIGlmIChURU5bd29yZFN0cl0pIHtcbiAgICAgICAgICBudW0gPSBudW0gKyBURU5bd29yZFN0cl07XG4gICAgICAgIH0gZWxzZSBpZiAoTUFHTklUVURFW3dvcmRTdHJdKSB7IFxuICAgICAgICAgIG51bSA9IG51bSAqIE1BR05JVFVERVt3b3JkU3RyXTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgfSk7XG4gICAgcmV0dXJuIG51bTtcbiAgfVxuXG4gIHBhcnNlQ29sbG9xdWlhbFdvcmRzKHdvcmRzQXJyKSB7XG4gICAgaWYgKHdvcmRzQXJyLmxlbmd0aCA9PSAyKSB7XG4gICAgICBpZiAoVEVOW3dvcmRzQXJyWzBdXSAmJiAoVEVOW3dvcmRzQXJyWzFdXSB8fCBUV09TW3dvcmRzQXJyWzFdXSkpIHtcbiAgICAgICAgd29yZHNBcnIuc3BsaWNlKDEsIDAsICdodW5kcmVkJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChNQUdOSVRVREVbd29yZHNBcnJbMF1dKSB7XG4gICAgICB3b3Jkc0Fyci5zcGxpY2UoMCwgMCwgJ29uZScpO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gd29yZHNBcnI7XG4gIH1cblxuICBlbGltaW5hdGVTdHJpbmcod29yZCkge1xuICAgIGlmICgvXFxkLy50ZXN0KHdvcmQpICYmIFNVRkZJWEVTLmluY2x1ZGVzKHdvcmQuc3Vic3RyKCB3b3JkLmxlbmd0aCAtIDIpKSkge1xuICAgICAgd29yZCA9IHdvcmQuc3Vic3RyKDAsIHdvcmQubGVuZ3RoIC0gMik7IC8vIFJlbW92ZSBsYXN0IHN1ZmZpeGVzIHN1Y2ggYXMgJ3N0JywgJ3RoJyBmcm9tIDFzdCwgMTB0aFxuICAgICAgd29yZCA9IHBhcnNlSW50KHdvcmQpO1xuICAgIH1cbiAgICByZXR1cm4gd29yZDtcbiAgfVxufVxuIl19