@darkeyedevelopers/natural-cron.js
Version:
Pure JavaScript library for converting natural English phrases into Cron expressions
1,044 lines (972 loc) • 92.4 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.getCronString = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict';
const regexString = require('./maps').regexString;
var defaultFlags = require('./maps').defaultFlags;
var defaultResultCron = require('./maps').defaultResultCron;
var flags = require('./maps').flags;
var resultCron = require('./maps').resultCron;
const tokenizeInput = require('./tokens').tokenizeInput;
const getClockTime = require('./states/clocktime').getClockTime;
const getDay = require('./states/day').getDay;
const getFrequencyOnly = require('./states/frequency').getFrequencyOnly;
const getFrequencyWith = require('./states/frequency').getFrequencyWith;
const getHour = require('./states/hour').getHour;
const getMonth = require('./states/month').getMonth;
const getMinute = require('./states/minute').getMinute;
const rangeStartState = require('./states/range').rangeStartState;
const rangeEndState = require('./states/range').rangeEndState;
const getYear = require('./states/year').getYear;
/*callState function to match and call curresponding state function*/
function callState(token,stack,error) {
let stateName = decideState(token);
switch(stateName) {
case "frequencyWith" : {
return getFrequencyWith(token,stack,error);
}
break;
case "frequencyOnly" : {
return getFrequencyOnly(token,stack,error);
}
break;
case "clockTime" : {
return getClockTime(token,stack,error);
}
break;
case "day" : {
return getDay(token,stack,error);
}
break;
case "minute" : {
return getMinute(token,stack,error);
}
break;
case "hour" : {
return getHour(token,stack,error);
}
break;
case "month" : {
return getMonth(token,stack,error);
}
break;
case "year" : {
return getYear(token,stack,error);
}
break;
case "rangeStart" : {
return rangeStartState(token,stack,error);
}
break;
case "rangeEnd" : {
return rangeEndState(token,stack,error);
}
break;
}
return true;
}
/*decideState function to decide next state*/
function decideState(token) {
let isFound = "decideState";
for(let key in regexString) {
// TO DO: check for group
let regBuilder = new RegExp(regexString[key].regextest,'ig');
if(regBuilder.test(token)) {
isFound = key;
break;
}
}
return isFound;
}
/*getCronString fucntion to convert human readable input string to cron string*/
module.exports = function getCronString(inputString, syntaxString) {
//Set default syntax string
syntaxString = typeof(syntaxString) !== 'undefined' ? syntaxString : "MIN HOR DOM MON WEK YER";
//resetting map values to default
flags.isRangeForDay = defaultFlags.isRangeForDay;
flags.isRangeForMonth = defaultFlags.isRangeForMonth;
flags.isRangeForYear = defaultFlags.isRangeForYear;
flags.isRangeForHour = defaultFlags.isRangeForHour;
flags.isRangeForMin = defaultFlags.isRangeForMin;
resultCron.min = defaultResultCron.min;
resultCron.hour = defaultResultCron.hour;
resultCron.day_of_month = defaultResultCron.day_of_month;
resultCron.month = defaultResultCron.month;
resultCron.day_of_week = defaultResultCron.day_of_week;
resultCron.year = defaultResultCron.year;
//Stack to store temperory states' data
let stack = [];
let error = "";
let tokens = tokenizeInput(inputString);
if(tokens == null) {
error+="Please enter human readable rules !\n";
}
let notEndState = true;
for(let i=0; notEndState && i<tokens.length;i++) {
notEndState = callState(tokens[i],stack,error);
}
if(notEndState == false) {
return "ERROR:"+error + "\t\t" + syntaxString.replace("MIN",resultCron.min).replace("HOR",resultCron.hour).replace("DOM",resultCron.day_of_month).replace("MON",resultCron.month).replace("WEK",resultCron.day_of_week).replace("YER",resultCron.year);
}
else {
return syntaxString.replace("MIN",resultCron.min).replace("HOR",resultCron.hour).replace("DOM",resultCron.day_of_month).replace("MON",resultCron.month).replace("WEK",resultCron.day_of_week).replace("YER",resultCron.year);
}
}
},{"./maps":2,"./states/clocktime":3,"./states/day":4,"./states/frequency":5,"./states/hour":6,"./states/minute":7,"./states/month":8,"./states/range":9,"./states/year":10,"./tokens":11}],2:[function(require,module,exports){
'use strict';
//regexString json
var regexString = {
every : {
"regextest" : "^(every|each|all|entire)$"
},
clockTime : {
//https://regexr.com/3qqbn
"regextest" : "^([0-9]+:)?[0-9]+ *(AM|PM)$|^([0-9]+:[0-9]+)$|(noon|midnight)",
//https://regexr.com/3qqbt
"regexexec" : [
"^[0-9]+",
":[0-9]+",
"pm",
"am",
"(noon|midnight)"
]
},
year : {
"regextest" : "((years|year)|([0-9]{4}[0-9]*(( ?and)?,? ?))+)",
"regexexec" : [
"^(years|year)$",
"[0-9]*",
"^[0-9]{4}$"
]
},
frequencyWith : {
"regextest" : "^[0-9]+(th|nd|rd|st)$"
},
frequencyOnly : {
"regextest" : "^[0-9]+$",
"regexexec" : "^[0-9]+"
},
minute : {
"regextest" : "(minutes|minute|mins|min)",
"regexexec" : [
"^(minutes|minute|mins|min)$"
]
},
hour : {
"regextest" : "(hour|hrs|hours)",
"regexexec" : [
"^(hour|hrs|hours)$"
]
},
day : {
//https://regexr.com/3qqc3
"regextest" : "^((days|day)|(((monday|tuesday|wednesday|thursday|friday|saturday|sunday|WEEKEND|MON|TUE|WED|THU|FRI|SAT|SUN)( ?and)?,? ?)+))$",
"regexexec" : [
"^(day|days)$",
"(MON|TUE|WED|THU|FRI|SAT|SUN|WEEKEND)"
]
},
month : {
//https://regexr.com/3r1na
"regextest" : "^((months|month)|(((january|february|march|april|may|june|july|august|september|october|november|december|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)( ?and)?,? ?)+))$",
"regexexec" : [
"^(month|months)$",
"(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)"
]
},
rangeStart : {
"regextest" : "(between|starting|start)" ,
},
rangeEnd : {
"regextest" : "(to|through|ending|end|and)" ,
},
tokenising : {
"regexexec" : "(hour|hrs|hours)|(minutes|minute|mins|min)|((months|month)|(((january|february|march|april|may|june|july|august|september|october|november|december|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)( ?and)?,? ?)+))|[0-9]+(th|nd|rd|st)|(([0-9]+:)?[0-9]+( +)?(AM|PM))|([0-9]+:[0-9]+)|(noon|midnight)|((days|day)|(((monday|tuesday|wednesday|thursday|friday|saturday|sunday|WEEKEND|MON|TUE|WED|THU|FRI|SAT|SUN)( ?and)?,? ?)+))|(([0-9]{4}[0-9]*(( ?and)?,? ?))+)|([0-9]+)|(to|through|ending|end|and)|(between|starting|start)"
}
}
var defaultFlags = {
"isRangeForDay" : false,
"isRangeForMonth" : false,
"isRangeForYear" : false,
"isRangeForHour" : false,
"isRangeForMin" : false
};
var defaultResultCron = {
"min" : "*",
"hour" : "*",
"day_of_month" : "*",
"month" : "*",
"day_of_week" : "?",
"year" : "*"
};
var flags = {
"isRangeForDay" : defaultFlags.isRangeForDay,
"isRangeForMonth" : defaultFlags.isRangeForMonth,
"isRangeForYear" : defaultFlags.isRangeForYear,
"isRangeForHour" : defaultFlags.isRangeForHour,
"isRangeForMin" : defaultFlags.isRangeForMin
};
var resultCron = {
"min" : defaultResultCron.min,
"hour" : defaultResultCron.hour,
"day_of_month" : defaultResultCron.day_of_month,
"month" : defaultResultCron.month,
"day_of_week" : defaultResultCron.day_of_week,
"year" : defaultResultCron.year
};
module.exports = {
regexString,
defaultFlags,
defaultResultCron,
flags,
resultCron
}
},{}],3:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*clockTime function to parse and store frequency value without nth*/
function getClockTime(token,stack,error) {
//retrive hours from clocktime
let regBuilder = new RegExp(regexString.clockTime.regexexec[0]);
let str = token.match(regBuilder);
let hour,min;
if(str != null && str.length > 0) {
hour = parseInt(str[0]);
} else {
hour = 0;
}
//retrive minutes from clockTime
regBuilder = new RegExp(regexString.clockTime.regexexec[1]);
str = regBuilder.exec(token);
if(str != null && str.length > 0) {
if(str[0].indexOf(':')!=-1) {
min = parseInt(str[0].slice(str[0].indexOf(':')+1));
if(min >= 60) {
error +=" please enter correct minutes !";
return false;
}
} else {
min = 0;
}
} else {
min = 0;
}
//check for increment of hour by 12 for PM
let regBuilderPM = new RegExp(regexString.clockTime.regexexec[2],'ig');
let regBuilderAM = new RegExp(regexString.clockTime.regexexec[3],'ig');
if(regBuilderPM.test(token)) {
if(hour < 12) {
hour+=12;
} else if(hour > 12 ){
error +=" please correct the time before PM !";
return false;
}
} else if(regBuilderAM.test(token)){
if(hour == 12) {
hour = 0;
} else if(hour > 12 ){
error +=" please correct the time before AM !";
return false;
}
}
regBuilder = new RegExp(regexString.clockTime.regexexec[4],'ig');
if(regBuilder.test(token)) {
str = token.match(regBuilder);
if(str == "noon") {
hour = 12;
min = 0;
} else {
hour = 0;
min = 0;
}
}
// TO DO: checked=>Test==?
let topElement = stack[stack.length-1];
if(topElement != null) {
//Check if already a range is defined
if(flags.isRangeForHour == true || flags.isRangeForMin == true) {
error +=" already set for range expressions, seperate into two crons!";
return false;
}
if(topElement.ownerState == "rangeStart") {
topElement.hour.start = hour;
topElement.min.start = min;
stack.pop();
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
if(topElement.hour == hour) {
topElement.min.end = min;
resultCron.min = topElement.min.start + "-"+topElement.min.end;
//flags.isRangeForHour = true;
return true;
} else {
topElement.hour.end = hour;
resultCron.hour = topElement.hour.start + "-"+topElement.hour.end;
//flags.isRangeForMin = true;
return true;
}
stack.pop();
return true;
}
}
let stackElement = {
"ownerState" : "clockTime",
"hour" : hour,
"min" : min
};
resultCron.min = min;
if(resultCron.hour != "*" && resultCron.hour != "")
resultCron.hour += ","+hour;
else
resultCron.hour = hour;
stack.push(stackElement);
return true;
}
module.exports = {
getClockTime
};
},{"../maps":2}],4:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*getDay function to parse days*/
function getDay(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.day.regexexec[0],"ig");
let value = "";
// check for word day,days
if(regBuilder.test(token)) {
let topElement = stack[stack.length-1];
resultCron.day_of_week = "?";
if(topElement == null) {
topElement = {
'frequency' : "*"
};
} else if(topElement.ownerState == "frequencyOnly") {
resultCron.day_of_month = "0/"+topElement.frequency;
stack.pop();
} else if(topElement.ownerState == "frequencyWith") {
resultCron.day_of_month = ""+topElement.frequency;
stack.pop();
} else {
resultCron.day_of_month = "*";
}
}
// check for values of days between [MON-SUN]
else {
regBuilder = new RegExp(regexString.day.regexexec[1],"ig");
let matches = token.match(regBuilder);
if(matches!=null && matches.length != 0) {
resultCron.day_of_week = "";
for(let i=0; i<matches.length; i++) {
matches[i] = matches[i].toUpperCase();
}
// TO DO: check
let topElement = stack[stack.length-1];
if(matches.length == 1 && topElement != null) {
//Check if already a range is defined
if(flags.isRangeForDay == true) {
error +=" already set for range expressions, seperate into two crons!";
return false;
}
stack.pop();
if(topElement.ownerState == "rangeStart") {
topElement.day.start = matches[0];
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
topElement.day.end = matches[0];
resultCron.day_of_week = topElement.day.start + "-"+topElement.day.end;
resultCron.day_of_month = "?";
//flags.isRangeForDay = true;
return true;
}
}
if(matches.includes('MON') && !resultCron.day_of_week.includes('MON'))
resultCron.day_of_week += "MON,";
if(matches.includes('TUE') && !resultCron.day_of_week.includes('TUE'))
resultCron.day_of_week += "TUE,";
if(matches.includes('WED') && !resultCron.day_of_week.includes('WED'))
resultCron.day_of_week += "WED,";
if(matches.includes('THU') && !resultCron.day_of_week.includes('THU'))
resultCron.day_of_week += "THU,";
if(matches.includes('FRI') && !resultCron.day_of_week.includes('FRI'))
resultCron.day_of_week += "FRI,";
if(matches.includes('SAT') && !resultCron.day_of_week.includes('SAT'))
resultCron.day_of_week += "SAT,";
if(matches.includes('SUN') && !resultCron.day_of_week.includes('SUN'))
resultCron.day_of_week += "SUN,";
if(matches.includes('WEEKEND') && !resultCron.day_of_week.includes('SAT'))
resultCron.day_of_week += "SAT,";
if(matches.includes('WEEKEND') && !resultCron.day_of_week.includes('SUN'))
resultCron.day_of_week += "SUN,";
// removed extra comma
resultCron.day_of_week = resultCron.day_of_week.slice(0,-1);
resultCron.day_of_month = "?";
value = ""+resultCron.day_of_week;
} else {
// TO DO: provide in future. but for NOW error
error +=" In unresolved state at 2;Day !";
return false;
}
}
let stackElement = {
"ownerState" : "day",
"day_of_week" : resultCron.day_of_week,
"day_of_month" : resultCron.day_of_month
};
stack.push(stackElement);
return true;
}
module.exports = {
getDay
};
},{"../maps":2}],5:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*frequencyOnly function to parse and store frequency value without nth*/
function getFrequencyOnly(token,stack,error) {
let freq = parseInt(token);
if(isNaN(token)) {
error +=" token is not number in frequency only !";
return false;
}
if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeEnd") {
let topElement = stack[stack.length - 1];
stack.pop();
topElement.frequency.end = freq;
stack.push(topElement);
return true;
}
else if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeStart") {
let topElement = stack[stack.length - 1];
stack.pop();
topElement.frequency.start = freq;
stack.push(topElement);
return true;
}
let stackElement = {
"ownerState" : "frequencyOnly",
"frequency" : freq
};
stack.push(stackElement);
return true;
}
/*frequencyWith function to parse and store frequency value with nth*/
function getFrequencyWith(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.frequencyOnly.regexexec,"ig");
let freq = regBuilder.exec(token);
let value = parseInt(freq);
if(isNaN(value)) {
error +=" token is not number in frequency with !";
return false;
}
if(stack.length!=0 && stack[stack.length - 1].ownerState=="rangeEnd") {
let topElement = stack[stack.length - 1];
stack.pop();
topElement.frequency.end = ""+value;
stack.push(topElement);
return true;
}
else if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeStart") {
let topElement = stack[stack.length - 1];
stack.pop();
topElement.frequency.start = ""+value;
stack.push(topElement);
return true;
}
let stackElement = {
"ownerState" : "frequencyWith",
"frequency" : value
};
stack.push(stackElement);
return true;
}
module.exports = {
getFrequencyOnly,
getFrequencyWith
};
},{"../maps":2}],6:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*getHour function to parse Hours*/
function getHour(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.hour.regexexec[0],"ig");
let value;
// check for word hours
if(regBuilder.test(token)) {
let topElement = stack[stack.length-1];
if(topElement == null) {
topElement = {
'frequency' : "*"
};
} else if(topElement.ownerState == "frequencyOnly") {
value = topElement.frequency;
resultCron.hour = "0/"+topElement.frequency;
stack.pop();
} else if(topElement.ownerState == "frequencyWith") {
//hour already set
if(resultCron.hour != "*" && resultCron.hour != "")
resultCron.hour += ","+topElement.frequency;
else
resultCron.hour = ""+topElement.frequency;
value = resultCron.hour;
stack.pop();
} else {
if(flags.isRangeForHour == true) {
error +=" already set for range expressions, seperate into two crons!";
return false;
}
else if(topElement.ownerState == "rangeStart") {
topElement.hour.start = topElement.frequency.start;
topElement.frequency.start = "";
stack.pop();
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
stack.pop();
topElement.hour.start = topElement.frequency.start;
topElement.hour.end = topElement.frequency.end;
topElement.frequency.end = "";
resultCron.hour = topElement.hour.start + "-"+topElement.hour.end;
//flags.isRangeForHour = true;
return true;
}
}
}
let stackElement = {
"ownerState" : "hour",
"hour" : value
};
stack.push(stackElement);
return true;
}
module.exports = {
getHour
};
},{"../maps":2}],7:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*getMinute function to parse minutes*/
function getMinute(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.minute.regexexec[0],"ig");
let value;
// check for word minute,minutes
if(regBuilder.test(token)) {
let topElement = stack[stack.length-1];
if(topElement == null) {
topElement = {
'frequency' : "*"
};
} else if(topElement.ownerState == "frequencyOnly") {
value = topElement.frequency;
resultCron.min = "0/"+topElement.frequency;
stack.pop();
} else if(topElement.ownerState == "frequencyWith") {
value = topElement.frequency;
resultCron.min = ""+topElement.frequency;
stack.pop();
} else {
if(flags.isRangeForMinute == true) {
error +=" already set for range expressions, seperate into two crons!";
return false;
}
else if(topElement.ownerState == "rangeStart") {
topElement.min.start = topElement.frequency.start;
topElement.frequency.start = "";
stack.pop();
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
stack.pop();
topElement.min.start = topElement.frequency.start;
topElement.min.end = topElement.frequency.end;
topElement.frequency.end = "";
resultCron.min = topElement.min.start + "-"+topElement.min.end;
//flags.isRangeForMin = true;
return true;
}
}
}
let stackElement = {
"ownerState" : "minute",
"min" : value
};
stack.push(stackElement);
return true;
}
module.exports = {
getMinute
};
},{"../maps":2}],8:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*getMonth function to parse months*/
function getMonth(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.month.regexexec[0],"ig");
let value = "";
// check for word month,months
if(regBuilder.test(token)) {
let topElement = stack[stack.length-1];
if(topElement == null) {
topElement = {
'frequency' : "*"
};
}
if(topElement.ownerState == "frequencyOnly") {
resultCron.month = "0/"+topElement.frequency;
stack.pop();
} else if(topElement.ownerState == "frequencyWith") {
resultCron.month = ""+topElement.frequency;
stack.pop();
} else {
resultCron.month = "*";
}
}
// check for values of months between [JAN-DEC]
else {
// TO DO: check for group
regBuilder = new RegExp(regexString.month.regexexec[1],"ig");
let matches = token.match(regBuilder);
if(matches!=null && matches.length != 0) {
resultCron.month = "";
for(let i=0; i<matches.length; i++) {
matches[i] = matches[i].toUpperCase();
}
// TO DO: check
let topElement = stack[stack.length-1];
if(matches.length == 1 && topElement != null) {
//Check if already a range is defined
if(flags.isRangeForMonth == true) {
error +=" already set for range expressions, seperate into two crons!";
return false;
}
stack.pop();
if(topElement.ownerState == "frequencyOnly") {
resultCron.day_of_month = topElement.frequency;
} else if(topElement.ownerState == "frequencyWith") {
resultCron.day_of_month = topElement.frequency;
} else if(topElement.ownerState == "rangeStart") {
topElement.month.start = matches[0];
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
if(topElement.frequency.end != "") {
resultCron.day_of_week = "?";
resultCron.day_of_month = topElement.frequency.start + "-" + topElement.frequency.end;
}
topElement.month.end = matches[0];
resultCron.month = topElement.month.start + "-"+topElement.month.end;
//flags.isRangeForMonth = true;
return true;
}
}
if(matches.includes('JAN') && !resultCron.month.includes('JAN'))
resultCron.month += "JAN,";
if(matches.includes('FEB') && !resultCron.month.includes('FEB'))
resultCron.month += "FEB,";
if(matches.includes('MAR') && !resultCron.month.includes('MAR'))
resultCron.month += "MAR,";
if(matches.includes('APR') && !resultCron.month.includes('APR'))
resultCron.month += "APR,";
if(matches.includes('MAY') && !resultCron.month.includes('MAY'))
resultCron.month += "MAY,";
if(matches.includes('JUN') && !resultCron.month.includes('JUN'))
resultCron.month += "JUN,";
if(matches.includes('JUL') && !resultCron.month.includes('JUL'))
resultCron.month += "JUL,";
if(matches.includes('AUG') && !resultCron.month.includes('AUG'))
resultCron.month += "AUG,";
if(matches.includes('SEPT') && !resultCron.month.includes('SEPT'))
resultCron.month += "SEPT,";
if(matches.includes('OCT') && !resultCron.month.includes('OCT'))
resultCron.month += "OCT,";
if(matches.includes('NOV') && !resultCron.month.includes('NOV'))
resultCron.month += "NOV,";
if(matches.includes('DEC') && !resultCron.month.includes('DEC'))
resultCron.month += "DEC,";
// removed extra comma
resultCron.month = resultCron.month.slice(0,-1);
value = ""+resultCron.month;
} else {
// TO DO: provide in future. but for NOW error
error +=" In unresolved state at 2;Month !";
return false;
}
}
let stackElement = {
"ownerState" : "month",
"month" : resultCron.month,
};
stack.push(stackElement);
return true;
}
module.exports = {
getMonth
};
},{"../maps":2}],9:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*rangeStartState function for range input*/
function rangeStartState(token,stack,error) {
if(flags.isRangeForDay || flags.isRangeForMin || flags.isRangeForMonth || flags.isRangeForYear || flags.isRangeForHour) {
error +=" already range expressions !";
return false;
}
let stackElement = {
"ownerState" : "rangeStart",
"min": {
"start" : "",
"end" : ""
},
"hour" : {
"start" : "",
"end" : ""
},
"day" : {
"start" : "",
"end" : ""
},
"month" : {
"start" : "",
"end" : ""
},
"year" : {
"start" : "",
"end" : ""
},
"frequency" : {
"start" : "",
"end" : ""
}
};
stack.push(stackElement);
return true;
}
/*rangeEndState function for range input*/
function rangeEndState(token,stack,error) {
let stackElement = {
"ownerState" : "rangeEnd",
"min": {
"start" : "",
"end" : ""
},
"hour" : {
"start" : "",
"end" : ""
},
"day" : {
"start" : "",
"end" : ""
},
"month" : {
"start" : "",
"end" : ""
},
"year" : {
"start" : "",
"end" : ""
},
"frequency" : {
"start" : "",
"end" : ""
}
};
let topElement = stack[stack.length-1];
if(topElement!=null) {
switch(topElement.ownerState) {
case "frequencyWith" :
case "frequencyOnly" :
{
stack.pop();
stackElement.frequency.start = topElement.frequency;
stackElement.ownerState = "rangeEnd";
stack.push(stackElement)
}
break;
case "clockTime" :
{
stack.pop();
stackElement.hour.start = topElement.hour;
stackElement.min.start = topElement.min;
stackElement.ownerState = "rangeEnd";
stack.push(stackElement)
}
break;
case "rangeStart" :
{
stack.pop();
topElement.ownerState = "rangeEnd";
stack.push(topElement);
}
break;
case "month" :
{
stack.pop();
stackElement.ownerState = "rangeEnd";
stackElement.month.start = topElement.month;
stack.push(stackElement);
}
break;
case "minute" :
{
stack.pop();
stackElement.ownerState = "rangeEnd";
stackElement.frequency.start = stackElement.min.start = topElement.min;
stack.push(stackElement);
}
break;
case "hour" :
{
stack.pop();
stackElement.ownerState = "rangeEnd";
stackElement.frequency.start = stackElement.hour.start = topElement.hour;
stack.push(stackElement);
}
break;
case "day" :
{
stack.pop();
stackElement.ownerState = "rangeEnd";
stackElement.day.start = topElement.day_of_week;
stack.push(stackElement);
}
break;
case "year" :
{
stack.pop();
stackElement.ownerState = "rangeEnd";
stackElement.year.start = topElement.year;
stack.push(stackElement);
}
break;
}
}
return true;
}
module.exports = {
rangeStartState,
rangeEndState
};
},{"../maps":2}],10:[function(require,module,exports){
'use strict';
const regexString = require('../maps').regexString;
var flags = require('../maps').flags;
var resultCron = require('../maps').resultCron;
/*getYear function to parse year*/
function getYear(token,stack,error) {
// TO DO: check for group
let regBuilder = new RegExp(regexString.year.regexexec[0],"ig");
let value = "";
// check for word year,years
if(regBuilder.test(token)) {
let topElement = stack[stack.length-1];
resultCron.year = "?";
if(topElement == null) {
topElement = {
'frequency' : "*"
};
} else if(topElement.ownerState == "frequencyOnly") {
resultCron.year = "0/"+topElement.frequency;
stack.pop();
} else if(topElement.ownerState == "frequencyWith") {
resultCron.year = ""+topElement.frequency;
stack.pop();
} else {
resultCron.year = "*";
}
}
// check for values of years
else {
regBuilder = new RegExp(regexString.year.regexexec[1],"ig");
let regBuilder2 = new RegExp(regexString.year.regexexec[2],"ig")
let matches = token.match(regBuilder);
let exactMatches = new Set();
for(let i=0; i<matches.length; i++) {
if(regBuilder2.test(matches[i])) {
exactMatches.add(matches[i].match(regBuilder2)[0]);
}
}
// TO DO: check
let topElement = stack[stack.length-1];
if(exactMatches.size == 1 && topElement != null) {
//Check if already a range is defined
if(flags.isRangeForYear == true) {
error +=" Cannot handle multiple range expressions, seperate into two crons!";
return false;
}
if(topElement.ownerState == "rangeStart") {
topElement.year.start = Array.from(exactMatches)[0];
stack.pop();
stack.push(topElement);
return true;
} else if(topElement.ownerState == "rangeEnd") {
topElement.year.end = Array.from(exactMatches)[0];
stack.pop();
resultCron.year = topElement.year.start + "-"+topElement.year.end;
//flags.isRangeForYear = true;
return true;
}
}
if(exactMatches.size != 0) {
resultCron.year = "";
exactMatches.forEach(function(yr){
resultCron.year += yr+",";
});
// removed extra comma
resultCron.year = resultCron.year.slice(0,-1);
value = ""+resultCron.year;
} else {
// TO DO: provide in future. but for NOW error
error +=" In unresolved state at 2;year !";
return false;
}
}
let stackElement = {
"ownerState" : "year",
"year" : resultCron.year
};
stack.push(stackElement);
return true;
}
module.exports = {
getYear
};
},{"../maps":2}],11:[function(require,module,exports){
'use strict';
const regexString = require('./maps').regexString;
var flags = require('./maps').flags;
var resultCron = require('./maps').resultCron;
//tokenizeInput function to seperate out all tokens
module.exports = {
tokenizeInput : function(inputString){
let regBuilder = new RegExp(regexString.tokenising.regexexec,"ig");
let matches = inputString.match(regBuilder);
if(matches == null || matches.length == 0 ) {
return [];
}
for(let i=0;i<matches.length;i++) {
matches[i] = (matches[i]+"").trim();
}
return matches;
}
};
},{"./maps":2}]},{},[1])(1)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMTkuMC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImluZGV4LmpzIiwibWFwcy5qcyIsInN0YXRlcy9jbG9ja3RpbWUuanMiLCJzdGF0ZXMvZGF5LmpzIiwic3RhdGVzL2ZyZXF1ZW5jeS5qcyIsInN0YXRlcy9ob3VyLmpzIiwic3RhdGVzL21pbnV0ZS5qcyIsInN0YXRlcy9tb250aC5qcyIsInN0YXRlcy9yYW5nZS5qcyIsInN0YXRlcy95ZWFyLmpzIiwidG9rZW5zLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCc7XG5jb25zdCByZWdleFN0cmluZyA9IHJlcXVpcmUoJy4vbWFwcycpLnJlZ2V4U3RyaW5nO1xudmFyIGRlZmF1bHRGbGFncyA9IHJlcXVpcmUoJy4vbWFwcycpLmRlZmF1bHRGbGFncztcbnZhciBkZWZhdWx0UmVzdWx0Q3JvbiA9IHJlcXVpcmUoJy4vbWFwcycpLmRlZmF1bHRSZXN1bHRDcm9uO1xudmFyIGZsYWdzID0gcmVxdWlyZSgnLi9tYXBzJykuZmxhZ3M7XG52YXIgcmVzdWx0Q3JvbiA9IHJlcXVpcmUoJy4vbWFwcycpLnJlc3VsdENyb247XG5cbmNvbnN0IHRva2VuaXplSW5wdXQgID0gcmVxdWlyZSgnLi90b2tlbnMnKS50b2tlbml6ZUlucHV0O1xuY29uc3QgZ2V0Q2xvY2tUaW1lICA9IHJlcXVpcmUoJy4vc3RhdGVzL2Nsb2NrdGltZScpLmdldENsb2NrVGltZTtcbmNvbnN0IGdldERheSAgPSByZXF1aXJlKCcuL3N0YXRlcy9kYXknKS5nZXREYXk7XG5jb25zdCBnZXRGcmVxdWVuY3lPbmx5ICA9IHJlcXVpcmUoJy4vc3RhdGVzL2ZyZXF1ZW5jeScpLmdldEZyZXF1ZW5jeU9ubHk7XG5jb25zdCBnZXRGcmVxdWVuY3lXaXRoICA9IHJlcXVpcmUoJy4vc3RhdGVzL2ZyZXF1ZW5jeScpLmdldEZyZXF1ZW5jeVdpdGg7XG5jb25zdCBnZXRIb3VyICA9IHJlcXVpcmUoJy4vc3RhdGVzL2hvdXInKS5nZXRIb3VyO1xuY29uc3QgZ2V0TW9udGggID0gcmVxdWlyZSgnLi9zdGF0ZXMvbW9udGgnKS5nZXRNb250aDtcbmNvbnN0IGdldE1pbnV0ZSAgPSByZXF1aXJlKCcuL3N0YXRlcy9taW51dGUnKS5nZXRNaW51dGU7XG5jb25zdCByYW5nZVN0YXJ0U3RhdGUgID0gcmVxdWlyZSgnLi9zdGF0ZXMvcmFuZ2UnKS5yYW5nZVN0YXJ0U3RhdGU7XG5jb25zdCByYW5nZUVuZFN0YXRlICA9IHJlcXVpcmUoJy4vc3RhdGVzL3JhbmdlJykucmFuZ2VFbmRTdGF0ZTtcbmNvbnN0IGdldFllYXIgID0gcmVxdWlyZSgnLi9zdGF0ZXMveWVhcicpLmdldFllYXI7XG5cbi8qY2FsbFN0YXRlIGZ1bmN0aW9uIHRvIG1hdGNoIGFuZCBjYWxsIGN1cnJlc3BvbmRpbmcgc3RhdGUgZnVuY3Rpb24qL1xuZnVuY3Rpb24gY2FsbFN0YXRlKHRva2VuLHN0YWNrLGVycm9yKSB7XG4gICAgbGV0IHN0YXRlTmFtZSA9IGRlY2lkZVN0YXRlKHRva2VuKTtcblxuICAgIHN3aXRjaChzdGF0ZU5hbWUpIHtcbiAgICAgICAgY2FzZSBcImZyZXF1ZW5jeVdpdGhcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lXaXRoKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImZyZXF1ZW5jeU9ubHlcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lPbmx5KHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImNsb2NrVGltZVwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIGdldENsb2NrVGltZSh0b2tlbixzdGFjayxlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkYXlcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXREYXkodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwibWludXRlXCIgOiB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0TWludXRlKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImhvdXJcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRIb3VyKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIm1vbnRoXCIgOiB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0TW9udGgodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwieWVhclwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIGdldFllYXIodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwicmFuZ2VTdGFydFwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIHJhbmdlU3RhcnRTdGF0ZSh0b2tlbixzdGFjayxlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJyYW5nZUVuZFwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIHJhbmdlRW5kU3RhdGUodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLypkZWNpZGVTdGF0ZSBmdW5jdGlvbiB0byBkZWNpZGUgbmV4dCBzdGF0ZSovXG5mdW5jdGlvbiBkZWNpZGVTdGF0ZSh0b2tlbikge1xuICAgIGxldCBpc0ZvdW5kID0gXCJkZWNpZGVTdGF0ZVwiO1xuICAgIGZvcihsZXQga2V5IGluIHJlZ2V4U3RyaW5nKSB7XG4gICAgICAgIC8vIFRPIERPOiBjaGVjayBmb3IgZ3JvdXBcbiAgICAgICAgbGV0IHJlZ0J1aWxkZXIgPSBuZXcgUmVnRXhwKHJlZ2V4U3RyaW5nW2tleV0ucmVnZXh0ZXN0LCdpZycpO1xuICAgICAgICBpZihyZWdCdWlsZGVyLnRlc3QodG9rZW4pKSB7XG4gICAgICAgICAgICBpc0ZvdW5kID0ga2V5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzRm91bmQ7XG59XG5cbi8qZ2V0Q3JvblN0cmluZyBmdWNudGlvbiB0byBjb252ZXJ0IGh1bWFuIHJlYWRhYmxlIGlucHV0IHN0cmluZyB0byBjcm9uIHN0cmluZyovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldENyb25TdHJpbmcoaW5wdXRTdHJpbmcsIHN5bnRheFN0cmluZykge1xuICAgIC8vU2V0IGRlZmF1bHQgc3ludGF4IHN0cmluZ1xuICAgIHN5bnRheFN0cmluZyA9IHR5cGVvZihzeW50YXhTdHJpbmcpICE9PSAndW5kZWZpbmVkJyA/IHN5bnRheFN0cmluZyA6IFwiTUlOIEhPUiBET00gTU9OIFdFSyBZRVJcIjtcblxuICAgIC8vcmVzZXR0aW5nIG1hcCB2YWx1ZXMgdG8gZGVmYXVsdFxuICAgIGZsYWdzLmlzUmFuZ2VGb3JEYXkgPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvckRheTtcbiAgICBmbGFncy5pc1JhbmdlRm9yTW9udGggPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvck1vbnRoO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JZZWFyID0gZGVmYXVsdEZsYWdzLmlzUmFuZ2VGb3JZZWFyO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JIb3VyID0gZGVmYXVsdEZsYWdzLmlzUmFuZ2VGb3JIb3VyO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JNaW4gPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvck1pbjtcblxuICAgIHJlc3VsdENyb24ubWluID0gZGVmYXVsdFJlc3VsdENyb24ubWluO1xuICAgIHJlc3VsdENyb24uaG91ciA9IGRlZmF1bHRSZXN1bHRDcm9uLmhvdXI7XG4gICAgcmVzdWx0Q3Jvbi5kYXlfb2ZfbW9udGggPSBkZWZhdWx0UmVzdWx0Q3Jvbi5kYXlfb2ZfbW9udGg7XG4gICAgcmVzdWx0Q3Jvbi5tb250aCA9IGRlZmF1bHRSZXN1bHRDcm9uLm1vbnRoO1xuICAgIHJlc3VsdENyb24uZGF5X29mX3dlZWsgPSBkZWZhdWx0UmVzdWx0Q3Jvbi5kYXlfb2Zfd2VlaztcbiAgICByZXN1bHRDcm9uLnllYXIgPSBkZWZhdWx0UmVzdWx0Q3Jvbi55ZWFyO1xuXG4gICAgLy9TdGFjayB0byBzdG9yZSB0ZW1wZXJvcnkgc3RhdGVzJyBkYXRhXG4gICAgbGV0IHN0YWNrID0gW107XG4gICAgbGV0IGVycm9yID0gXCJcIjtcbiAgICBsZXQgdG9rZW5zID0gdG9rZW5pemVJbnB1dChpbnB1dFN0cmluZyk7XG5cbiAgICBpZih0b2tlbnMgPT0gbnVsbCkge1xuICAgICAgICBlcnJvcis9XCJQbGVhc2UgZW50ZXIgaHVtYW4gcmVhZGFibGUgcnVsZXMgIVxcblwiO1xuICAgIH1cbiAgICBsZXQgbm90RW5kU3RhdGUgPSB0cnVlO1xuICAgIGZvcihsZXQgaT0wOyBub3RFbmRTdGF0ZSAmJiBpPHRva2Vucy5sZW5ndGg7aSsrKSB7XG4gICAgICAgIG5vdEVuZFN0YXRlID0gY2FsbFN0YXRlKHRva2Vuc1tpXSxzdGFjayxlcnJvcik7XG4gICAgfVxuICAgIGlmKG5vdEVuZFN0YXRlID09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBcIkVSUk9SOlwiK2Vycm9yICsgXCJcXHRcXHRcIiArIHN5bnRheFN0cmluZy5yZXBsYWNlKFwiTUlOXCIscmVzdWx0Q3Jvbi5taW4pLnJlcGxhY2UoXCJIT1JcIixyZXN1bHRDcm9uLmhvdXIpLnJlcGxhY2UoXCJET01cIixyZXN1bHRDcm9uLmRheV9vZl9tb250aCkucmVwbGFjZShcIk1PTlwiLHJlc3VsdENyb24ubW9udGgpLnJlcGxhY2UoXCJXRUtcIixyZXN1bHRDcm9uLmRheV9vZl93ZWVrKS5yZXBsYWNlKFwiWUVSXCIscmVzdWx0Q3Jvbi55ZWFyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBzeW50YXhTdHJpbmcucmVwbGFjZShcIk1JTlwiLHJlc3VsdENyb24ubWluKS5yZXBsYWNlKFwiSE9SXCIscmVzdWx0Q3Jvbi5ob3VyKS5yZXBsYWNlKFwiRE9NXCIscmVzdWx0Q3Jvbi