Skip to content

Instantly share code, notes, and snippets.

@justrhysism
Created July 31, 2017 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justrhysism/9bab0deee3069e6222315eebe6e91aa5 to your computer and use it in GitHub Desktop.
Save justrhysism/9bab0deee3069e6222315eebe6e91aa5 to your computer and use it in GitHub Desktop.
requirebin sketch
// Welcome! require() some modules from npm (like you were using browserify)
// and then hit Run Code to run your code on the right side.
// Modules get downloaded from browserify-cdn and bundled in your browser.
const padStart = require('lodash/padStart');
const dateFns = require('date-fns')
const displayValue = "44/1/1";
convertDateDisplayToDateArray = (dateDisplay) => {
return dateDisplay.split('/').reverse().map(item => padStart(item, 2, 0));
}
convertDateDisplayToISO = (dateDisplay) => {
return convertDateDisplayToDateArray(dateDisplay).join('-');
}
convertDateDisplayToDateObject = (dateDisplay) => {
return new Date(...convertDateDisplayToDateArray(dateDisplay));
}
console.log(convertDateDisplayToDateArray(displayValue));
console.log(convertDateDisplayToDateObject(displayValue));
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Add the specified number of days to the given date.
*
* @description
* Add the specified number of days to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of days to be added
* @returns {Date} the new date with the days added
*
* @example
* // Add 10 days to 1 September 2014:
* var result = addDays(new Date(2014, 8, 1), 10)
* //=> Thu Sep 11 2014 00:00:00
*/
function addDays (dirtyDate, dirtyAmount) {
var date = parse(dirtyDate)
var amount = Number(dirtyAmount)
date.setDate(date.getDate() + amount)
return date
}
module.exports = addDays
},{"../parse/index.js":122}],2:[function(require,module,exports){
var addMilliseconds = require('../add_milliseconds/index.js')
var MILLISECONDS_IN_HOUR = 3600000
/**
* @category Hour Helpers
* @summary Add the specified number of hours to the given date.
*
* @description
* Add the specified number of hours to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of hours to be added
* @returns {Date} the new date with the hours added
*
* @example
* // Add 2 hours to 10 July 2014 23:00:00:
* var result = addHours(new Date(2014, 6, 10, 23, 0), 2)
* //=> Fri Jul 11 2014 01:00:00
*/
function addHours (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_HOUR)
}
module.exports = addHours
},{"../add_milliseconds/index.js":4}],3:[function(require,module,exports){
var getISOYear = require('../get_iso_year/index.js')
var setISOYear = require('../set_iso_year/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Add the specified number of ISO week-numbering years to the given date.
*
* @description
* Add the specified number of ISO week-numbering years to the given date.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of ISO week-numbering years to be added
* @returns {Date} the new date with the ISO week-numbering years added
*
* @example
* // Add 5 ISO week-numbering years to 2 July 2010:
* var result = addISOYears(new Date(2010, 6, 2), 5)
* //=> Fri Jun 26 2015 00:00:00
*/
function addISOYears (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return setISOYear(dirtyDate, getISOYear(dirtyDate) + amount)
}
module.exports = addISOYears
},{"../get_iso_year/index.js":60,"../set_iso_year/index.js":129}],4:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Millisecond Helpers
* @summary Add the specified number of milliseconds to the given date.
*
* @description
* Add the specified number of milliseconds to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of milliseconds to be added
* @returns {Date} the new date with the milliseconds added
*
* @example
* // Add 750 milliseconds to 10 July 2014 12:45:30.000:
* var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
* //=> Thu Jul 10 2014 12:45:30.750
*/
function addMilliseconds (dirtyDate, dirtyAmount) {
var timestamp = parse(dirtyDate).getTime()
var amount = Number(dirtyAmount)
return new Date(timestamp + amount)
}
module.exports = addMilliseconds
},{"../parse/index.js":122}],5:[function(require,module,exports){
var addMilliseconds = require('../add_milliseconds/index.js')
var MILLISECONDS_IN_MINUTE = 60000
/**
* @category Minute Helpers
* @summary Add the specified number of minutes to the given date.
*
* @description
* Add the specified number of minutes to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of minutes to be added
* @returns {Date} the new date with the minutes added
*
* @example
* // Add 30 minutes to 10 July 2014 12:00:00:
* var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30)
* //=> Thu Jul 10 2014 12:30:00
*/
function addMinutes (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE)
}
module.exports = addMinutes
},{"../add_milliseconds/index.js":4}],6:[function(require,module,exports){
var parse = require('../parse/index.js')
var getDaysInMonth = require('../get_days_in_month/index.js')
/**
* @category Month Helpers
* @summary Add the specified number of months to the given date.
*
* @description
* Add the specified number of months to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of months to be added
* @returns {Date} the new date with the months added
*
* @example
* // Add 5 months to 1 September 2014:
* var result = addMonths(new Date(2014, 8, 1), 5)
* //=> Sun Feb 01 2015 00:00:00
*/
function addMonths (dirtyDate, dirtyAmount) {
var date = parse(dirtyDate)
var amount = Number(dirtyAmount)
var desiredMonth = date.getMonth() + amount
var dateWithDesiredMonth = new Date(0)
dateWithDesiredMonth.setFullYear(date.getFullYear(), desiredMonth, 1)
dateWithDesiredMonth.setHours(0, 0, 0, 0)
var daysInMonth = getDaysInMonth(dateWithDesiredMonth)
// Set the last day of the new month
// if the original date was the last day of the longer month
date.setMonth(desiredMonth, Math.min(daysInMonth, date.getDate()))
return date
}
module.exports = addMonths
},{"../get_days_in_month/index.js":54,"../parse/index.js":122}],7:[function(require,module,exports){
var addMonths = require('../add_months/index.js')
/**
* @category Quarter Helpers
* @summary Add the specified number of year quarters to the given date.
*
* @description
* Add the specified number of year quarters to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of quarters to be added
* @returns {Date} the new date with the quarters added
*
* @example
* // Add 1 quarter to 1 September 2014:
* var result = addQuarters(new Date(2014, 8, 1), 1)
* //=> Mon Dec 01 2014 00:00:00
*/
function addQuarters (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
var months = amount * 3
return addMonths(dirtyDate, months)
}
module.exports = addQuarters
},{"../add_months/index.js":6}],8:[function(require,module,exports){
var addMilliseconds = require('../add_milliseconds/index.js')
/**
* @category Second Helpers
* @summary Add the specified number of seconds to the given date.
*
* @description
* Add the specified number of seconds to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of seconds to be added
* @returns {Date} the new date with the seconds added
*
* @example
* // Add 30 seconds to 10 July 2014 12:45:00:
* var result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)
* //=> Thu Jul 10 2014 12:45:30
*/
function addSeconds (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMilliseconds(dirtyDate, amount * 1000)
}
module.exports = addSeconds
},{"../add_milliseconds/index.js":4}],9:[function(require,module,exports){
var addDays = require('../add_days/index.js')
/**
* @category Week Helpers
* @summary Add the specified number of weeks to the given date.
*
* @description
* Add the specified number of week to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of weeks to be added
* @returns {Date} the new date with the weeks added
*
* @example
* // Add 4 weeks to 1 September 2014:
* var result = addWeeks(new Date(2014, 8, 1), 4)
* //=> Mon Sep 29 2014 00:00:00
*/
function addWeeks (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
var days = amount * 7
return addDays(dirtyDate, days)
}
module.exports = addWeeks
},{"../add_days/index.js":1}],10:[function(require,module,exports){
var addMonths = require('../add_months/index.js')
/**
* @category Year Helpers
* @summary Add the specified number of years to the given date.
*
* @description
* Add the specified number of years to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of years to be added
* @returns {Date} the new date with the years added
*
* @example
* // Add 5 years to 1 September 2014:
* var result = addYears(new Date(2014, 8, 1), 5)
* //=> Sun Sep 01 2019 00:00:00
*/
function addYears (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMonths(dirtyDate, amount * 12)
}
module.exports = addYears
},{"../add_months/index.js":6}],11:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Range Helpers
* @summary Is the given date range overlapping with another date range?
*
* @description
* Is the given date range overlapping with another date range?
*
* @param {Date|String|Number} initialRangeStartDate - the start of the initial range
* @param {Date|String|Number} initialRangeEndDate - the end of the initial range
* @param {Date|String|Number} comparedRangeStartDate - the start of the range to compare it with
* @param {Date|String|Number} comparedRangeEndDate - the end of the range to compare it with
* @returns {Boolean} whether the date ranges are overlapping
* @throws {Error} startDate of a date range cannot be after its endDate
*
* @example
* // For overlapping date ranges:
* areRangesOverlapping(
* new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 17), new Date(2014, 0, 21)
* )
* //=> true
*
* @example
* // For non-overlapping date ranges:
* areRangesOverlapping(
* new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 21), new Date(2014, 0, 22)
* )
* //=> false
*/
function areRangesOverlapping (dirtyInitialRangeStartDate, dirtyInitialRangeEndDate, dirtyComparedRangeStartDate, dirtyComparedRangeEndDate) {
var initialStartTime = parse(dirtyInitialRangeStartDate).getTime()
var initialEndTime = parse(dirtyInitialRangeEndDate).getTime()
var comparedStartTime = parse(dirtyComparedRangeStartDate).getTime()
var comparedEndTime = parse(dirtyComparedRangeEndDate).getTime()
if (initialStartTime > initialEndTime || comparedStartTime > comparedEndTime) {
throw new Error('The start of the range cannot be after the end of the range')
}
return initialStartTime < comparedEndTime && comparedStartTime < initialEndTime
}
module.exports = areRangesOverlapping
},{"../parse/index.js":122}],12:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Return an index of the closest date from the array comparing to the given date.
*
* @description
* Return an index of the closest date from the array comparing to the given date.
*
* @param {Date|String|Number} dateToCompare - the date to compare with
* @param {Date[]|String[]|Number[]} datesArray - the array to search
* @returns {Number} an index of the date closest to the given date
* @throws {TypeError} the second argument must be an instance of Array
*
* @example
* // Which date is closer to 6 September 2015?
* var dateToCompare = new Date(2015, 8, 6)
* var datesArray = [
* new Date(2015, 0, 1),
* new Date(2016, 0, 1),
* new Date(2017, 0, 1)
* ]
* var result = closestIndexTo(dateToCompare, datesArray)
* //=> 1
*/
function closestIndexTo (dirtyDateToCompare, dirtyDatesArray) {
if (!(dirtyDatesArray instanceof Array)) {
throw new TypeError(toString.call(dirtyDatesArray) + ' is not an instance of Array')
}
var dateToCompare = parse(dirtyDateToCompare)
var timeToCompare = dateToCompare.getTime()
var result
var minDistance
dirtyDatesArray.forEach(function (dirtyDate, index) {
var currentDate = parse(dirtyDate)
var distance = Math.abs(timeToCompare - currentDate.getTime())
if (result === undefined || distance < minDistance) {
result = index
minDistance = distance
}
})
return result
}
module.exports = closestIndexTo
},{"../parse/index.js":122}],13:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Return a date from the array closest to the given date.
*
* @description
* Return a date from the array closest to the given date.
*
* @param {Date|String|Number} dateToCompare - the date to compare with
* @param {Date[]|String[]|Number[]} datesArray - the array to search
* @returns {Date} the date from the array closest to the given date
* @throws {TypeError} the second argument must be an instance of Array
*
* @example
* // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030?
* var dateToCompare = new Date(2015, 8, 6)
* var result = closestTo(dateToCompare, [
* new Date(2000, 0, 1),
* new Date(2030, 0, 1)
* ])
* //=> Tue Jan 01 2030 00:00:00
*/
function closestTo (dirtyDateToCompare, dirtyDatesArray) {
if (!(dirtyDatesArray instanceof Array)) {
throw new TypeError(toString.call(dirtyDatesArray) + ' is not an instance of Array')
}
var dateToCompare = parse(dirtyDateToCompare)
var timeToCompare = dateToCompare.getTime()
var result
var minDistance
dirtyDatesArray.forEach(function (dirtyDate) {
var currentDate = parse(dirtyDate)
var distance = Math.abs(timeToCompare - currentDate.getTime())
if (result === undefined || distance < minDistance) {
result = currentDate
minDistance = distance
}
})
return result
}
module.exports = closestTo
},{"../parse/index.js":122}],14:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Compare the two dates and return -1, 0 or 1.
*
* @description
* Compare the two dates and return 1 if the first date is after the second,
* -1 if the first date is before the second or 0 if dates are equal.
*
* @param {Date|String|Number} dateLeft - the first date to compare
* @param {Date|String|Number} dateRight - the second date to compare
* @returns {Number} the result of the comparison
*
* @example
* // Compare 11 February 1987 and 10 July 1989:
* var result = compareAsc(
* new Date(1987, 1, 11),
* new Date(1989, 6, 10)
* )
* //=> -1
*
* @example
* // Sort the array of dates:
* var result = [
* new Date(1995, 6, 2),
* new Date(1987, 1, 11),
* new Date(1989, 6, 10)
* ].sort(compareAsc)
* //=> [
* // Wed Feb 11 1987 00:00:00,
* // Mon Jul 10 1989 00:00:00,
* // Sun Jul 02 1995 00:00:00
* // ]
*/
function compareAsc (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var timeLeft = dateLeft.getTime()
var dateRight = parse(dirtyDateRight)
var timeRight = dateRight.getTime()
if (timeLeft < timeRight) {
return -1
} else if (timeLeft > timeRight) {
return 1
} else {
return 0
}
}
module.exports = compareAsc
},{"../parse/index.js":122}],15:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Compare the two dates reverse chronologically and return -1, 0 or 1.
*
* @description
* Compare the two dates and return -1 if the first date is after the second,
* 1 if the first date is before the second or 0 if dates are equal.
*
* @param {Date|String|Number} dateLeft - the first date to compare
* @param {Date|String|Number} dateRight - the second date to compare
* @returns {Number} the result of the comparison
*
* @example
* // Compare 11 February 1987 and 10 July 1989 reverse chronologically:
* var result = compareDesc(
* new Date(1987, 1, 11),
* new Date(1989, 6, 10)
* )
* //=> 1
*
* @example
* // Sort the array of dates in reverse chronological order:
* var result = [
* new Date(1995, 6, 2),
* new Date(1987, 1, 11),
* new Date(1989, 6, 10)
* ].sort(compareDesc)
* //=> [
* // Sun Jul 02 1995 00:00:00,
* // Mon Jul 10 1989 00:00:00,
* // Wed Feb 11 1987 00:00:00
* // ]
*/
function compareDesc (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var timeLeft = dateLeft.getTime()
var dateRight = parse(dirtyDateRight)
var timeRight = dateRight.getTime()
if (timeLeft > timeRight) {
return -1
} else if (timeLeft < timeRight) {
return 1
} else {
return 0
}
}
module.exports = compareDesc
},{"../parse/index.js":122}],16:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
var MILLISECONDS_IN_MINUTE = 60000
var MILLISECONDS_IN_DAY = 86400000
/**
* @category Day Helpers
* @summary Get the number of calendar days between the given dates.
*
* @description
* Get the number of calendar days between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar days
*
* @example
* // How many calendar days are between
* // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
* var result = differenceInCalendarDays(
* new Date(2012, 6, 2, 0, 0),
* new Date(2011, 6, 2, 23, 0)
* )
* //=> 366
*/
function differenceInCalendarDays (dirtyDateLeft, dirtyDateRight) {
var startOfDayLeft = startOfDay(dirtyDateLeft)
var startOfDayRight = startOfDay(dirtyDateRight)
var timestampLeft = startOfDayLeft.getTime() -
startOfDayLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
var timestampRight = startOfDayRight.getTime() -
startOfDayRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
// Round the number of days to the nearest integer
// because the number of milliseconds in a day is not constant
// (e.g. it's different in the day of the daylight saving time clock shift)
return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY)
}
module.exports = differenceInCalendarDays
},{"../start_of_day/index.js":136}],17:[function(require,module,exports){
var startOfISOWeek = require('../start_of_iso_week/index.js')
var MILLISECONDS_IN_MINUTE = 60000
var MILLISECONDS_IN_WEEK = 604800000
/**
* @category ISO Week Helpers
* @summary Get the number of calendar ISO weeks between the given dates.
*
* @description
* Get the number of calendar ISO weeks between the given dates.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar ISO weeks
*
* @example
* // How many calendar ISO weeks are between 6 July 2014 and 21 July 2014?
* var result = differenceInCalendarISOWeeks(
* new Date(2014, 6, 21),
* new Date(2014, 6, 6)
* )
* //=> 3
*/
function differenceInCalendarISOWeeks (dirtyDateLeft, dirtyDateRight) {
var startOfISOWeekLeft = startOfISOWeek(dirtyDateLeft)
var startOfISOWeekRight = startOfISOWeek(dirtyDateRight)
var timestampLeft = startOfISOWeekLeft.getTime() -
startOfISOWeekLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
var timestampRight = startOfISOWeekRight.getTime() -
startOfISOWeekRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
// Round the number of days to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK)
}
module.exports = differenceInCalendarISOWeeks
},{"../start_of_iso_week/index.js":138}],18:[function(require,module,exports){
var getISOYear = require('../get_iso_year/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Get the number of calendar ISO week-numbering years between the given dates.
*
* @description
* Get the number of calendar ISO week-numbering years between the given dates.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar ISO week-numbering years
*
* @example
* // How many calendar ISO week-numbering years are 1 January 2010 and 1 January 2012?
* var result = differenceInCalendarISOYears(
* new Date(2012, 0, 1),
* new Date(2010, 0, 1)
* )
* //=> 2
*/
function differenceInCalendarISOYears (dirtyDateLeft, dirtyDateRight) {
return getISOYear(dirtyDateLeft) - getISOYear(dirtyDateRight)
}
module.exports = differenceInCalendarISOYears
},{"../get_iso_year/index.js":60}],19:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Get the number of calendar months between the given dates.
*
* @description
* Get the number of calendar months between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar months
*
* @example
* // How many calendar months are between 31 January 2014 and 1 September 2014?
* var result = differenceInCalendarMonths(
* new Date(2014, 8, 1),
* new Date(2014, 0, 31)
* )
* //=> 8
*/
function differenceInCalendarMonths (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear()
var monthDiff = dateLeft.getMonth() - dateRight.getMonth()
return yearDiff * 12 + monthDiff
}
module.exports = differenceInCalendarMonths
},{"../parse/index.js":122}],20:[function(require,module,exports){
var getQuarter = require('../get_quarter/index.js')
var parse = require('../parse/index.js')
/**
* @category Quarter Helpers
* @summary Get the number of calendar quarters between the given dates.
*
* @description
* Get the number of calendar quarters between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar quarters
*
* @example
* // How many calendar quarters are between 31 December 2013 and 2 July 2014?
* var result = differenceInCalendarQuarters(
* new Date(2014, 6, 2),
* new Date(2013, 11, 31)
* )
* //=> 3
*/
function differenceInCalendarQuarters (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var yearDiff = dateLeft.getFullYear() - dateRight.getFullYear()
var quarterDiff = getQuarter(dateLeft) - getQuarter(dateRight)
return yearDiff * 4 + quarterDiff
}
module.exports = differenceInCalendarQuarters
},{"../get_quarter/index.js":65,"../parse/index.js":122}],21:[function(require,module,exports){
var startOfWeek = require('../start_of_week/index.js')
var MILLISECONDS_IN_MINUTE = 60000
var MILLISECONDS_IN_WEEK = 604800000
/**
* @category Week Helpers
* @summary Get the number of calendar weeks between the given dates.
*
* @description
* Get the number of calendar weeks between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Number} the number of calendar weeks
*
* @example
* // How many calendar weeks are between 5 July 2014 and 20 July 2014?
* var result = differenceInCalendarWeeks(
* new Date(2014, 6, 20),
* new Date(2014, 6, 5)
* )
* //=> 3
*
* @example
* // If the week starts on Monday,
* // how many calendar weeks are between 5 July 2014 and 20 July 2014?
* var result = differenceInCalendarWeeks(
* new Date(2014, 6, 20),
* new Date(2014, 6, 5),
* {weekStartsOn: 1}
* )
* //=> 2
*/
function differenceInCalendarWeeks (dirtyDateLeft, dirtyDateRight, dirtyOptions) {
var startOfWeekLeft = startOfWeek(dirtyDateLeft, dirtyOptions)
var startOfWeekRight = startOfWeek(dirtyDateRight, dirtyOptions)
var timestampLeft = startOfWeekLeft.getTime() -
startOfWeekLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
var timestampRight = startOfWeekRight.getTime() -
startOfWeekRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE
// Round the number of days to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_WEEK)
}
module.exports = differenceInCalendarWeeks
},{"../start_of_week/index.js":146}],22:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Get the number of calendar years between the given dates.
*
* @description
* Get the number of calendar years between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of calendar years
*
* @example
* // How many calendar years are between 31 December 2013 and 11 February 2015?
* var result = differenceInCalendarYears(
* new Date(2015, 1, 11),
* new Date(2013, 11, 31)
* )
* //=> 2
*/
function differenceInCalendarYears (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
return dateLeft.getFullYear() - dateRight.getFullYear()
}
module.exports = differenceInCalendarYears
},{"../parse/index.js":122}],23:[function(require,module,exports){
var parse = require('../parse/index.js')
var differenceInCalendarDays = require('../difference_in_calendar_days/index.js')
var compareAsc = require('../compare_asc/index.js')
/**
* @category Day Helpers
* @summary Get the number of full days between the given dates.
*
* @description
* Get the number of full days between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full days
*
* @example
* // How many full days are between
* // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
* var result = differenceInDays(
* new Date(2012, 6, 2, 0, 0),
* new Date(2011, 6, 2, 23, 0)
* )
* //=> 365
*/
function differenceInDays (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var sign = compareAsc(dateLeft, dateRight)
var difference = Math.abs(differenceInCalendarDays(dateLeft, dateRight))
dateLeft.setDate(dateLeft.getDate() - sign * difference)
// Math.abs(diff in full days - diff in calendar days) === 1 if last calendar day is not full
// If so, result must be decreased by 1 in absolute value
var isLastDayNotFull = compareAsc(dateLeft, dateRight) === -sign
return sign * (difference - isLastDayNotFull)
}
module.exports = differenceInDays
},{"../compare_asc/index.js":14,"../difference_in_calendar_days/index.js":16,"../parse/index.js":122}],24:[function(require,module,exports){
var differenceInMilliseconds = require('../difference_in_milliseconds/index.js')
var MILLISECONDS_IN_HOUR = 3600000
/**
* @category Hour Helpers
* @summary Get the number of hours between the given dates.
*
* @description
* Get the number of hours between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of hours
*
* @example
* // How many hours are between 2 July 2014 06:50:00 and 2 July 2014 19:00:00?
* var result = differenceInHours(
* new Date(2014, 6, 2, 19, 0),
* new Date(2014, 6, 2, 6, 50)
* )
* //=> 12
*/
function differenceInHours (dirtyDateLeft, dirtyDateRight) {
var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_HOUR
return diff > 0 ? Math.floor(diff) : Math.ceil(diff)
}
module.exports = differenceInHours
},{"../difference_in_milliseconds/index.js":26}],25:[function(require,module,exports){
var parse = require('../parse/index.js')
var differenceInCalendarISOYears = require('../difference_in_calendar_iso_years/index.js')
var compareAsc = require('../compare_asc/index.js')
var subISOYears = require('../sub_iso_years/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Get the number of full ISO week-numbering years between the given dates.
*
* @description
* Get the number of full ISO week-numbering years between the given dates.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full ISO week-numbering years
*
* @example
* // How many full ISO week-numbering years are between 1 January 2010 and 1 January 2012?
* var result = differenceInISOYears(
* new Date(2012, 0, 1),
* new Date(2010, 0, 1)
* )
* //=> 1
*/
function differenceInISOYears (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var sign = compareAsc(dateLeft, dateRight)
var difference = Math.abs(differenceInCalendarISOYears(dateLeft, dateRight))
dateLeft = subISOYears(dateLeft, sign * difference)
// Math.abs(diff in full ISO years - diff in calendar ISO years) === 1
// if last calendar ISO year is not full
// If so, result must be decreased by 1 in absolute value
var isLastISOYearNotFull = compareAsc(dateLeft, dateRight) === -sign
return sign * (difference - isLastISOYearNotFull)
}
module.exports = differenceInISOYears
},{"../compare_asc/index.js":14,"../difference_in_calendar_iso_years/index.js":18,"../parse/index.js":122,"../sub_iso_years/index.js":151}],26:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Millisecond Helpers
* @summary Get the number of milliseconds between the given dates.
*
* @description
* Get the number of milliseconds between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of milliseconds
*
* @example
* // How many milliseconds are between
* // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?
* var result = differenceInMilliseconds(
* new Date(2014, 6, 2, 12, 30, 21, 700),
* new Date(2014, 6, 2, 12, 30, 20, 600)
* )
* //=> 1100
*/
function differenceInMilliseconds (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
return dateLeft.getTime() - dateRight.getTime()
}
module.exports = differenceInMilliseconds
},{"../parse/index.js":122}],27:[function(require,module,exports){
var differenceInMilliseconds = require('../difference_in_milliseconds/index.js')
var MILLISECONDS_IN_MINUTE = 60000
/**
* @category Minute Helpers
* @summary Get the number of minutes between the given dates.
*
* @description
* Get the number of minutes between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of minutes
*
* @example
* // How many minutes are between 2 July 2014 12:07:59 and 2 July 2014 12:20:00?
* var result = differenceInMinutes(
* new Date(2014, 6, 2, 12, 20, 0),
* new Date(2014, 6, 2, 12, 7, 59)
* )
* //=> 12
*/
function differenceInMinutes (dirtyDateLeft, dirtyDateRight) {
var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / MILLISECONDS_IN_MINUTE
return diff > 0 ? Math.floor(diff) : Math.ceil(diff)
}
module.exports = differenceInMinutes
},{"../difference_in_milliseconds/index.js":26}],28:[function(require,module,exports){
var parse = require('../parse/index.js')
var differenceInCalendarMonths = require('../difference_in_calendar_months/index.js')
var compareAsc = require('../compare_asc/index.js')
/**
* @category Month Helpers
* @summary Get the number of full months between the given dates.
*
* @description
* Get the number of full months between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full months
*
* @example
* // How many full months are between 31 January 2014 and 1 September 2014?
* var result = differenceInMonths(
* new Date(2014, 8, 1),
* new Date(2014, 0, 31)
* )
* //=> 7
*/
function differenceInMonths (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var sign = compareAsc(dateLeft, dateRight)
var difference = Math.abs(differenceInCalendarMonths(dateLeft, dateRight))
dateLeft.setMonth(dateLeft.getMonth() - sign * difference)
// Math.abs(diff in full months - diff in calendar months) === 1 if last calendar month is not full
// If so, result must be decreased by 1 in absolute value
var isLastMonthNotFull = compareAsc(dateLeft, dateRight) === -sign
return sign * (difference - isLastMonthNotFull)
}
module.exports = differenceInMonths
},{"../compare_asc/index.js":14,"../difference_in_calendar_months/index.js":19,"../parse/index.js":122}],29:[function(require,module,exports){
var differenceInMonths = require('../difference_in_months/index.js')
/**
* @category Quarter Helpers
* @summary Get the number of full quarters between the given dates.
*
* @description
* Get the number of full quarters between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full quarters
*
* @example
* // How many full quarters are between 31 December 2013 and 2 July 2014?
* var result = differenceInQuarters(
* new Date(2014, 6, 2),
* new Date(2013, 11, 31)
* )
* //=> 2
*/
function differenceInQuarters (dirtyDateLeft, dirtyDateRight) {
var diff = differenceInMonths(dirtyDateLeft, dirtyDateRight) / 3
return diff > 0 ? Math.floor(diff) : Math.ceil(diff)
}
module.exports = differenceInQuarters
},{"../difference_in_months/index.js":28}],30:[function(require,module,exports){
var differenceInMilliseconds = require('../difference_in_milliseconds/index.js')
/**
* @category Second Helpers
* @summary Get the number of seconds between the given dates.
*
* @description
* Get the number of seconds between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of seconds
*
* @example
* // How many seconds are between
* // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?
* var result = differenceInSeconds(
* new Date(2014, 6, 2, 12, 30, 20, 0),
* new Date(2014, 6, 2, 12, 30, 7, 999)
* )
* //=> 12
*/
function differenceInSeconds (dirtyDateLeft, dirtyDateRight) {
var diff = differenceInMilliseconds(dirtyDateLeft, dirtyDateRight) / 1000
return diff > 0 ? Math.floor(diff) : Math.ceil(diff)
}
module.exports = differenceInSeconds
},{"../difference_in_milliseconds/index.js":26}],31:[function(require,module,exports){
var differenceInDays = require('../difference_in_days/index.js')
/**
* @category Week Helpers
* @summary Get the number of full weeks between the given dates.
*
* @description
* Get the number of full weeks between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full weeks
*
* @example
* // How many full weeks are between 5 July 2014 and 20 July 2014?
* var result = differenceInWeeks(
* new Date(2014, 6, 20),
* new Date(2014, 6, 5)
* )
* //=> 2
*/
function differenceInWeeks (dirtyDateLeft, dirtyDateRight) {
var diff = differenceInDays(dirtyDateLeft, dirtyDateRight) / 7
return diff > 0 ? Math.floor(diff) : Math.ceil(diff)
}
module.exports = differenceInWeeks
},{"../difference_in_days/index.js":23}],32:[function(require,module,exports){
var parse = require('../parse/index.js')
var differenceInCalendarYears = require('../difference_in_calendar_years/index.js')
var compareAsc = require('../compare_asc/index.js')
/**
* @category Year Helpers
* @summary Get the number of full years between the given dates.
*
* @description
* Get the number of full years between the given dates.
*
* @param {Date|String|Number} dateLeft - the later date
* @param {Date|String|Number} dateRight - the earlier date
* @returns {Number} the number of full years
*
* @example
* // How many full years are between 31 December 2013 and 11 February 2015?
* var result = differenceInYears(
* new Date(2015, 1, 11),
* new Date(2013, 11, 31)
* )
* //=> 1
*/
function differenceInYears (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
var sign = compareAsc(dateLeft, dateRight)
var difference = Math.abs(differenceInCalendarYears(dateLeft, dateRight))
dateLeft.setFullYear(dateLeft.getFullYear() - sign * difference)
// Math.abs(diff in full years - diff in calendar years) === 1 if last calendar year is not full
// If so, result must be decreased by 1 in absolute value
var isLastYearNotFull = compareAsc(dateLeft, dateRight) === -sign
return sign * (difference - isLastYearNotFull)
}
module.exports = differenceInYears
},{"../compare_asc/index.js":14,"../difference_in_calendar_years/index.js":22,"../parse/index.js":122}],33:[function(require,module,exports){
var compareDesc = require('../compare_desc/index.js')
var parse = require('../parse/index.js')
var differenceInSeconds = require('../difference_in_seconds/index.js')
var differenceInMonths = require('../difference_in_months/index.js')
var enLocale = require('../locale/en/index.js')
var MINUTES_IN_DAY = 1440
var MINUTES_IN_ALMOST_TWO_DAYS = 2520
var MINUTES_IN_MONTH = 43200
var MINUTES_IN_TWO_MONTHS = 86400
/**
* @category Common Helpers
* @summary Return the distance between the given dates in words.
*
* @description
* Return the distance between the given dates in words.
*
* | Distance between dates | Result |
* |-------------------------------------------------------------------|---------------------|
* | 0 ... 30 secs | less than a minute |
* | 30 secs ... 1 min 30 secs | 1 minute |
* | 1 min 30 secs ... 44 mins 30 secs | [2..44] minutes |
* | 44 mins ... 30 secs ... 89 mins 30 secs | about 1 hour |
* | 89 mins 30 secs ... 23 hrs 59 mins 30 secs | about [2..24] hours |
* | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs | 1 day |
* | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs | [2..30] days |
* | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month |
* | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months |
* | 59 days 23 hrs 59 mins 30 secs ... 1 yr | [2..12] months |
* | 1 yr ... 1 yr 3 months | about 1 year |
* | 1 yr 3 months ... 1 yr 9 month s | over 1 year |
* | 1 yr 9 months ... 2 yrs | almost 2 years |
* | N yrs ... N yrs 3 months | about N years |
* | N yrs 3 months ... N yrs 9 months | over N years |
* | N yrs 9 months ... N+1 yrs | almost N+1 years |
*
* With `options.includeSeconds == true`:
* | Distance between dates | Result |
* |------------------------|----------------------|
* | 0 secs ... 5 secs | less than 5 seconds |
* | 5 secs ... 10 secs | less than 10 seconds |
* | 10 secs ... 20 secs | less than 20 seconds |
* | 20 secs ... 40 secs | half a minute |
* | 40 secs ... 60 secs | less than a minute |
* | 60 secs ... 90 secs | 1 minute |
*
* @param {Date|String|Number} dateToCompare - the date to compare with
* @param {Date|String|Number} date - the other date
* @param {Object} [options] - the object with options
* @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed
* @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first
* @param {Object} [options.locale=enLocale] - the locale object
* @returns {String} the distance in words
*
* @example
* // What is the distance between 2 July 2014 and 1 January 2015?
* var result = distanceInWords(
* new Date(2014, 6, 2),
* new Date(2015, 0, 1)
* )
* //=> '6 months'
*
* @example
* // What is the distance between 1 January 2015 00:00:15
* // and 1 January 2015 00:00:00, including seconds?
* var result = distanceInWords(
* new Date(2015, 0, 1, 0, 0, 15),
* new Date(2015, 0, 1, 0, 0, 0),
* {includeSeconds: true}
* )
* //=> 'less than 20 seconds'
*
* @example
* // What is the distance from 1 January 2016
* // to 1 January 2015, with a suffix?
* var result = distanceInWords(
* new Date(2016, 0, 1),
* new Date(2015, 0, 1),
* {addSuffix: true}
* )
* //=> 'about 1 year ago'
*
* @example
* // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
* var eoLocale = require('date-fns/locale/eo')
* var result = distanceInWords(
* new Date(2016, 7, 1),
* new Date(2015, 0, 1),
* {locale: eoLocale}
* )
* //=> 'pli ol 1 jaro'
*/
function distanceInWords (dirtyDateToCompare, dirtyDate, dirtyOptions) {
var options = dirtyOptions || {}
var comparison = compareDesc(dirtyDateToCompare, dirtyDate)
var locale = options.locale
var localize = enLocale.distanceInWords.localize
if (locale && locale.distanceInWords && locale.distanceInWords.localize) {
localize = locale.distanceInWords.localize
}
var localizeOptions = {
addSuffix: Boolean(options.addSuffix),
comparison: comparison
}
var dateLeft, dateRight
if (comparison > 0) {
dateLeft = parse(dirtyDateToCompare)
dateRight = parse(dirtyDate)
} else {
dateLeft = parse(dirtyDate)
dateRight = parse(dirtyDateToCompare)
}
var seconds = differenceInSeconds(dateRight, dateLeft)
var offset = dateRight.getTimezoneOffset() - dateLeft.getTimezoneOffset()
var minutes = Math.round(seconds / 60) - offset
var months
// 0 up to 2 mins
if (minutes < 2) {
if (options.includeSeconds) {
if (seconds < 5) {
return localize('lessThanXSeconds', 5, localizeOptions)
} else if (seconds < 10) {
return localize('lessThanXSeconds', 10, localizeOptions)
} else if (seconds < 20) {
return localize('lessThanXSeconds', 20, localizeOptions)
} else if (seconds < 40) {
return localize('halfAMinute', null, localizeOptions)
} else if (seconds < 60) {
return localize('lessThanXMinutes', 1, localizeOptions)
} else {
return localize('xMinutes', 1, localizeOptions)
}
} else {
if (minutes === 0) {
return localize('lessThanXMinutes', 1, localizeOptions)
} else {
return localize('xMinutes', minutes, localizeOptions)
}
}
// 2 mins up to 0.75 hrs
} else if (minutes < 45) {
return localize('xMinutes', minutes, localizeOptions)
// 0.75 hrs up to 1.5 hrs
} else if (minutes < 90) {
return localize('aboutXHours', 1, localizeOptions)
// 1.5 hrs up to 24 hrs
} else if (minutes < MINUTES_IN_DAY) {
var hours = Math.round(minutes / 60)
return localize('aboutXHours', hours, localizeOptions)
// 1 day up to 1.75 days
} else if (minutes < MINUTES_IN_ALMOST_TWO_DAYS) {
return localize('xDays', 1, localizeOptions)
// 1.75 days up to 30 days
} else if (minutes < MINUTES_IN_MONTH) {
var days = Math.round(minutes / MINUTES_IN_DAY)
return localize('xDays', days, localizeOptions)
// 1 month up to 2 months
} else if (minutes < MINUTES_IN_TWO_MONTHS) {
months = Math.round(minutes / MINUTES_IN_MONTH)
return localize('aboutXMonths', months, localizeOptions)
}
months = differenceInMonths(dateRight, dateLeft)
// 2 months up to 12 months
if (months < 12) {
var nearestMonth = Math.round(minutes / MINUTES_IN_MONTH)
return localize('xMonths', nearestMonth, localizeOptions)
// 1 year up to max Date
} else {
var monthsSinceStartOfYear = months % 12
var years = Math.floor(months / 12)
// N years up to 1 years 3 months
if (monthsSinceStartOfYear < 3) {
return localize('aboutXYears', years, localizeOptions)
// N years 3 months up to N years 9 months
} else if (monthsSinceStartOfYear < 9) {
return localize('overXYears', years, localizeOptions)
// N years 9 months up to N year 12 months
} else {
return localize('almostXYears', years + 1, localizeOptions)
}
}
}
module.exports = distanceInWords
},{"../compare_desc/index.js":15,"../difference_in_months/index.js":28,"../difference_in_seconds/index.js":30,"../locale/en/index.js":119,"../parse/index.js":122}],34:[function(require,module,exports){
var compareDesc = require('../compare_desc/index.js')
var parse = require('../parse/index.js')
var differenceInSeconds = require('../difference_in_seconds/index.js')
var enLocale = require('../locale/en/index.js')
var MINUTES_IN_DAY = 1440
var MINUTES_IN_MONTH = 43200
var MINUTES_IN_YEAR = 525600
/**
* @category Common Helpers
* @summary Return the distance between the given dates in words.
*
* @description
* Return the distance between the given dates in words, using strict units.
* This is like `distanceInWords`, but does not use helpers like 'almost', 'over',
* 'less than' and the like.
*
* | Distance between dates | Result |
* |------------------------|---------------------|
* | 0 ... 59 secs | [0..59] seconds |
* | 1 ... 59 mins | [1..59] minutes |
* | 1 ... 23 hrs | [1..23] hours |
* | 1 ... 29 days | [1..29] days |
* | 1 ... 11 months | [1..11] months |
* | 1 ... N years | [1..N] years |
*
* @param {Date|String|Number} dateToCompare - the date to compare with
* @param {Date|String|Number} date - the other date
* @param {Object} [options] - the object with options
* @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first
* @param {'s'|'m'|'h'|'d'|'M'|'Y'} [options.unit] - if specified, will force a unit
* @param {'floor'|'ceil'|'round'} [options.partialMethod='floor'] - which way to round partial units
* @param {Object} [options.locale=enLocale] - the locale object
* @returns {String} the distance in words
*
* @example
* // What is the distance between 2 July 2014 and 1 January 2015?
* var result = distanceInWordsStrict(
* new Date(2014, 6, 2),
* new Date(2015, 0, 2)
* )
* //=> '6 months'
*
* @example
* // What is the distance between 1 January 2015 00:00:15
* // and 1 January 2015 00:00:00?
* var result = distanceInWordsStrict(
* new Date(2015, 0, 1, 0, 0, 15),
* new Date(2015, 0, 1, 0, 0, 0),
* )
* //=> '15 seconds'
*
* @example
* // What is the distance from 1 January 2016
* // to 1 January 2015, with a suffix?
* var result = distanceInWordsStrict(
* new Date(2016, 0, 1),
* new Date(2015, 0, 1),
* {addSuffix: true}
* )
* //=> '1 year ago'
*
* @example
* // What is the distance from 1 January 2016
* // to 1 January 2015, in minutes?
* var result = distanceInWordsStrict(
* new Date(2016, 0, 1),
* new Date(2015, 0, 1),
* {unit: 'm'}
* )
* //=> '525600 minutes'
*
* @example
* // What is the distance from 1 January 2016
* // to 28 January 2015, in months, rounded up?
* var result = distanceInWordsStrict(
* new Date(2015, 0, 28),
* new Date(2015, 0, 1),
* {unit: 'M', partialMethod: 'ceil'}
* )
* //=> '1 month'
*
* @example
* // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
* var eoLocale = require('date-fns/locale/eo')
* var result = distanceInWordsStrict(
* new Date(2016, 7, 1),
* new Date(2015, 0, 1),
* {locale: eoLocale}
* )
* //=> '1 jaro'
*/
function distanceInWordsStrict (dirtyDateToCompare, dirtyDate, dirtyOptions) {
var options = dirtyOptions || {}
var comparison = compareDesc(dirtyDateToCompare, dirtyDate)
var locale = options.locale
var localize = enLocale.distanceInWords.localize
if (locale && locale.distanceInWords && locale.distanceInWords.localize) {
localize = locale.distanceInWords.localize
}
var localizeOptions = {
addSuffix: Boolean(options.addSuffix),
comparison: comparison
}
var dateLeft, dateRight
if (comparison > 0) {
dateLeft = parse(dirtyDateToCompare)
dateRight = parse(dirtyDate)
} else {
dateLeft = parse(dirtyDate)
dateRight = parse(dirtyDateToCompare)
}
var unit
var mathPartial = Math[options.partialMethod ? String(options.partialMethod) : 'floor']
var seconds = differenceInSeconds(dateRight, dateLeft)
var offset = dateRight.getTimezoneOffset() - dateLeft.getTimezoneOffset()
var minutes = mathPartial(seconds / 60) - offset
var hours, days, months, years
if (options.unit) {
unit = String(options.unit)
} else {
if (minutes < 1) {
unit = 's'
} else if (minutes < 60) {
unit = 'm'
} else if (minutes < MINUTES_IN_DAY) {
unit = 'h'
} else if (minutes < MINUTES_IN_MONTH) {
unit = 'd'
} else if (minutes < MINUTES_IN_YEAR) {
unit = 'M'
} else {
unit = 'Y'
}
}
// 0 up to 60 seconds
if (unit === 's') {
return localize('xSeconds', seconds, localizeOptions)
// 1 up to 60 mins
} else if (unit === 'm') {
return localize('xMinutes', minutes, localizeOptions)
// 1 up to 24 hours
} else if (unit === 'h') {
hours = mathPartial(minutes / 60)
return localize('xHours', hours, localizeOptions)
// 1 up to 30 days
} else if (unit === 'd') {
days = mathPartial(minutes / MINUTES_IN_DAY)
return localize('xDays', days, localizeOptions)
// 1 up to 12 months
} else if (unit === 'M') {
months = mathPartial(minutes / MINUTES_IN_MONTH)
return localize('xMonths', months, localizeOptions)
// 1 year up to max Date
} else if (unit === 'Y') {
years = mathPartial(minutes / MINUTES_IN_YEAR)
return localize('xYears', years, localizeOptions)
}
throw new Error('Unknown unit: ' + unit)
}
module.exports = distanceInWordsStrict
},{"../compare_desc/index.js":15,"../difference_in_seconds/index.js":30,"../locale/en/index.js":119,"../parse/index.js":122}],35:[function(require,module,exports){
var distanceInWords = require('../distance_in_words/index.js')
/**
* @category Common Helpers
* @summary Return the distance between the given date and now in words.
*
* @description
* Return the distance between the given date and now in words.
*
* | Distance to now | Result |
* |-------------------------------------------------------------------|---------------------|
* | 0 ... 30 secs | less than a minute |
* | 30 secs ... 1 min 30 secs | 1 minute |
* | 1 min 30 secs ... 44 mins 30 secs | [2..44] minutes |
* | 44 mins ... 30 secs ... 89 mins 30 secs | about 1 hour |
* | 89 mins 30 secs ... 23 hrs 59 mins 30 secs | about [2..24] hours |
* | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs | 1 day |
* | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs | [2..30] days |
* | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month |
* | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months |
* | 59 days 23 hrs 59 mins 30 secs ... 1 yr | [2..12] months |
* | 1 yr ... 1 yr 3 months | about 1 year |
* | 1 yr 3 months ... 1 yr 9 month s | over 1 year |
* | 1 yr 9 months ... 2 yrs | almost 2 years |
* | N yrs ... N yrs 3 months | about N years |
* | N yrs 3 months ... N yrs 9 months | over N years |
* | N yrs 9 months ... N+1 yrs | almost N+1 years |
*
* With `options.includeSeconds == true`:
* | Distance to now | Result |
* |---------------------|----------------------|
* | 0 secs ... 5 secs | less than 5 seconds |
* | 5 secs ... 10 secs | less than 10 seconds |
* | 10 secs ... 20 secs | less than 20 seconds |
* | 20 secs ... 40 secs | half a minute |
* | 40 secs ... 60 secs | less than a minute |
* | 60 secs ... 90 secs | 1 minute |
*
* @param {Date|String|Number} date - the given date
* @param {Object} [options] - the object with options
* @param {Boolean} [options.includeSeconds=false] - distances less than a minute are more detailed
* @param {Boolean} [options.addSuffix=false] - result specifies if the second date is earlier or later than the first
* @param {Object} [options.locale=enLocale] - the locale object
* @returns {String} the distance in words
*
* @example
* // If today is 1 January 2015, what is the distance to 2 July 2014?
* var result = distanceInWordsToNow(
* new Date(2014, 6, 2)
* )
* //=> '6 months'
*
* @example
* // If now is 1 January 2015 00:00:00,
* // what is the distance to 1 January 2015 00:00:15, including seconds?
* var result = distanceInWordsToNow(
* new Date(2015, 0, 1, 0, 0, 15),
* {includeSeconds: true}
* )
* //=> 'less than 20 seconds'
*
* @example
* // If today is 1 January 2015,
* // what is the distance to 1 January 2016, with a suffix?
* var result = distanceInWordsToNow(
* new Date(2016, 0, 1),
* {addSuffix: true}
* )
* //=> 'in about 1 year'
*
* @example
* // If today is 1 January 2015,
* // what is the distance to 1 August 2016 in Esperanto?
* var eoLocale = require('date-fns/locale/eo')
* var result = distanceInWordsToNow(
* new Date(2016, 7, 1),
* {locale: eoLocale}
* )
* //=> 'pli ol 1 jaro'
*/
function distanceInWordsToNow (dirtyDate, dirtyOptions) {
return distanceInWords(Date.now(), dirtyDate, dirtyOptions)
}
module.exports = distanceInWordsToNow
},{"../distance_in_words/index.js":33}],36:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Return the array of dates within the specified range.
*
* @description
* Return the array of dates within the specified range.
*
* @param {Date|String|Number} startDate - the first date
* @param {Date|String|Number} endDate - the last date
* @returns {Date[]} the array with starts of days from the day of startDate to the day of endDate
* @throws {Error} startDate cannot be after endDate
*
* @example
* // Each day between 6 October 2014 and 10 October 2014:
* var result = eachDay(
* new Date(2014, 9, 6),
* new Date(2014, 9, 10)
* )
* //=> [
* // Mon Oct 06 2014 00:00:00,
* // Tue Oct 07 2014 00:00:00,
* // Wed Oct 08 2014 00:00:00,
* // Thu Oct 09 2014 00:00:00,
* // Fri Oct 10 2014 00:00:00
* // ]
*/
function eachDay (dirtyStartDate, dirtyEndDate) {
var startDate = parse(dirtyStartDate)
var endDate = parse(dirtyEndDate)
var endTime = endDate.getTime()
if (startDate.getTime() > endTime) {
throw new Error('The first date cannot be after the second date')
}
var dates = []
var currentDate = startDate
currentDate.setHours(0, 0, 0, 0)
while (currentDate.getTime() <= endTime) {
dates.push(parse(currentDate))
currentDate.setDate(currentDate.getDate() + 1)
}
return dates
}
module.exports = eachDay
},{"../parse/index.js":122}],37:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Return the end of a day for the given date.
*
* @description
* Return the end of a day for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a day
*
* @example
* // The end of a day for 2 September 2014 11:55:00:
* var result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 02 2014 23:59:59.999
*/
function endOfDay (dirtyDate) {
var date = parse(dirtyDate)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfDay
},{"../parse/index.js":122}],38:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Hour Helpers
* @summary Return the end of an hour for the given date.
*
* @description
* Return the end of an hour for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of an hour
*
* @example
* // The end of an hour for 2 September 2014 11:55:00:
* var result = endOfHour(new Date(2014, 8, 2, 11, 55))
* //=> Tue Sep 02 2014 11:59:59.999
*/
function endOfHour (dirtyDate) {
var date = parse(dirtyDate)
date.setMinutes(59, 59, 999)
return date
}
module.exports = endOfHour
},{"../parse/index.js":122}],39:[function(require,module,exports){
var endOfWeek = require('../end_of_week/index.js')
/**
* @category ISO Week Helpers
* @summary Return the end of an ISO week for the given date.
*
* @description
* Return the end of an ISO week for the given date.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of an ISO week
*
* @example
* // The end of an ISO week for 2 September 2014 11:55:00:
* var result = endOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sun Sep 07 2014 23:59:59.999
*/
function endOfISOWeek (dirtyDate) {
return endOfWeek(dirtyDate, {weekStartsOn: 1})
}
module.exports = endOfISOWeek
},{"../end_of_week/index.js":47}],40:[function(require,module,exports){
var getISOYear = require('../get_iso_year/index.js')
var startOfISOWeek = require('../start_of_iso_week/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Return the end of an ISO week-numbering year for the given date.
*
* @description
* Return the end of an ISO week-numbering year,
* which always starts 3 days before the year's first Thursday.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of an ISO week-numbering year
*
* @example
* // The end of an ISO week-numbering year for 2 July 2005:
* var result = endOfISOYear(new Date(2005, 6, 2))
* //=> Sun Jan 01 2006 23:59:59.999
*/
function endOfISOYear (dirtyDate) {
var year = getISOYear(dirtyDate)
var fourthOfJanuaryOfNextYear = new Date(0)
fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4)
fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0)
var date = startOfISOWeek(fourthOfJanuaryOfNextYear)
date.setMilliseconds(date.getMilliseconds() - 1)
return date
}
module.exports = endOfISOYear
},{"../get_iso_year/index.js":60,"../start_of_iso_week/index.js":138}],41:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Minute Helpers
* @summary Return the end of a minute for the given date.
*
* @description
* Return the end of a minute for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a minute
*
* @example
* // The end of a minute for 1 December 2014 22:15:45.400:
* var result = endOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))
* //=> Mon Dec 01 2014 22:15:59.999
*/
function endOfMinute (dirtyDate) {
var date = parse(dirtyDate)
date.setSeconds(59, 999)
return date
}
module.exports = endOfMinute
},{"../parse/index.js":122}],42:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Return the end of a month for the given date.
*
* @description
* Return the end of a month for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a month
*
* @example
* // The end of a month for 2 September 2014 11:55:00:
* var result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 23:59:59.999
*/
function endOfMonth (dirtyDate) {
var date = parse(dirtyDate)
var month = date.getMonth()
date.setFullYear(date.getFullYear(), month + 1, 0)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfMonth
},{"../parse/index.js":122}],43:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Quarter Helpers
* @summary Return the end of a year quarter for the given date.
*
* @description
* Return the end of a year quarter for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a quarter
*
* @example
* // The end of a quarter for 2 September 2014 11:55:00:
* var result = endOfQuarter(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 23:59:59.999
*/
function endOfQuarter (dirtyDate) {
var date = parse(dirtyDate)
var currentMonth = date.getMonth()
var month = currentMonth - currentMonth % 3 + 3
date.setMonth(month, 0)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfQuarter
},{"../parse/index.js":122}],44:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Second Helpers
* @summary Return the end of a second for the given date.
*
* @description
* Return the end of a second for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a second
*
* @example
* // The end of a second for 1 December 2014 22:15:45.400:
* var result = endOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))
* //=> Mon Dec 01 2014 22:15:45.999
*/
function endOfSecond (dirtyDate) {
var date = parse(dirtyDate)
date.setMilliseconds(999)
return date
}
module.exports = endOfSecond
},{"../parse/index.js":122}],45:[function(require,module,exports){
var endOfDay = require('../end_of_day/index.js')
/**
* @category Day Helpers
* @summary Return the end of today.
*
* @description
* Return the end of today.
*
* @returns {Date} the end of today
*
* @example
* // If today is 6 October 2014:
* var result = endOfToday()
* //=> Mon Oct 6 2014 23:59:59.999
*/
function endOfToday () {
return endOfDay(new Date())
}
module.exports = endOfToday
},{"../end_of_day/index.js":37}],46:[function(require,module,exports){
/**
* @category Day Helpers
* @summary Return the end of tomorrow.
*
* @description
* Return the end of tomorrow.
*
* @returns {Date} the end of tomorrow
*
* @example
* // If today is 6 October 2014:
* var result = endOfTomorrow()
* //=> Tue Oct 7 2014 23:59:59.999
*/
function endOfTomorrow () {
var now = new Date()
var year = now.getFullYear()
var month = now.getMonth()
var day = now.getDate()
var date = new Date(0)
date.setFullYear(year, month, day + 1)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfTomorrow
},{}],47:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Week Helpers
* @summary Return the end of a week for the given date.
*
* @description
* Return the end of a week for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Date} the end of a week
*
* @example
* // The end of a week for 2 September 2014 11:55:00:
* var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sat Sep 06 2014 23:59:59.999
*
* @example
* // If the week starts on Monday, the end of the week for 2 September 2014 11:55:00:
* var result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0), {weekStartsOn: 1})
* //=> Sun Sep 07 2014 23:59:59.999
*/
function endOfWeek (dirtyDate, dirtyOptions) {
var weekStartsOn = dirtyOptions ? (Number(dirtyOptions.weekStartsOn) || 0) : 0
var date = parse(dirtyDate)
var day = date.getDay()
var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn)
date.setDate(date.getDate() + diff)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfWeek
},{"../parse/index.js":122}],48:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Return the end of a year for the given date.
*
* @description
* Return the end of a year for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of a year
*
* @example
* // The end of a year for 2 September 2014 11:55:00:
* var result = endOfYear(new Date(2014, 8, 2, 11, 55, 00))
* //=> Wed Dec 31 2014 23:59:59.999
*/
function endOfYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
date.setFullYear(year + 1, 0, 0)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfYear
},{"../parse/index.js":122}],49:[function(require,module,exports){
/**
* @category Day Helpers
* @summary Return the end of yesterday.
*
* @description
* Return the end of yesterday.
*
* @returns {Date} the end of yesterday
*
* @example
* // If today is 6 October 2014:
* var result = endOfYesterday()
* //=> Sun Oct 5 2014 23:59:59.999
*/
function endOfYesterday () {
var now = new Date()
var year = now.getFullYear()
var month = now.getMonth()
var day = now.getDate()
var date = new Date(0)
date.setFullYear(year, month, day - 1)
date.setHours(23, 59, 59, 999)
return date
}
module.exports = endOfYesterday
},{}],50:[function(require,module,exports){
var getDayOfYear = require('../get_day_of_year/index.js')
var getISOWeek = require('../get_iso_week/index.js')
var getISOYear = require('../get_iso_year/index.js')
var parse = require('../parse/index.js')
var isValid = require('../is_valid/index.js')
var enLocale = require('../locale/en/index.js')
/**
* @category Common Helpers
* @summary Format the date.
*
* @description
* Return the formatted date string in the given format.
*
* Accepted tokens:
* | Unit | Token | Result examples |
* |-------------------------|-------|----------------------------------|
* | Month | M | 1, 2, ..., 12 |
* | | Mo | 1st, 2nd, ..., 12th |
* | | MM | 01, 02, ..., 12 |
* | | MMM | Jan, Feb, ..., Dec |
* | | MMMM | January, February, ..., December |
* | Quarter | Q | 1, 2, 3, 4 |
* | | Qo | 1st, 2nd, 3rd, 4th |
* | Day of month | D | 1, 2, ..., 31 |
* | | Do | 1st, 2nd, ..., 31st |
* | | DD | 01, 02, ..., 31 |
* | Day of year | DDD | 1, 2, ..., 366 |
* | | DDDo | 1st, 2nd, ..., 366th |
* | | DDDD | 001, 002, ..., 366 |
* | Day of week | d | 0, 1, ..., 6 |
* | | do | 0th, 1st, ..., 6th |
* | | dd | Su, Mo, ..., Sa |
* | | ddd | Sun, Mon, ..., Sat |
* | | dddd | Sunday, Monday, ..., Saturday |
* | Day of ISO week | E | 1, 2, ..., 7 |
* | ISO week | W | 1, 2, ..., 53 |
* | | Wo | 1st, 2nd, ..., 53rd |
* | | WW | 01, 02, ..., 53 |
* | Year | YY | 00, 01, ..., 99 |
* | | YYYY | 1900, 1901, ..., 2099 |
* | ISO week-numbering year | GG | 00, 01, ..., 99 |
* | | GGGG | 1900, 1901, ..., 2099 |
* | AM/PM | A | AM, PM |
* | | a | am, pm |
* | | aa | a.m., p.m. |
* | Hour | H | 0, 1, ... 23 |
* | | HH | 00, 01, ... 23 |
* | | h | 1, 2, ..., 12 |
* | | hh | 01, 02, ..., 12 |
* | Minute | m | 0, 1, ..., 59 |
* | | mm | 00, 01, ..., 59 |
* | Second | s | 0, 1, ..., 59 |
* | | ss | 00, 01, ..., 59 |
* | 1/10 of second | S | 0, 1, ..., 9 |
* | 1/100 of second | SS | 00, 01, ..., 99 |
* | Millisecond | SSS | 000, 001, ..., 999 |
* | Timezone | Z | -01:00, +00:00, ... +12:00 |
* | | ZZ | -0100, +0000, ..., +1200 |
* | Seconds timestamp | X | 512969520 |
* | Milliseconds timestamp | x | 512969520900 |
*
* The characters wrapped in square brackets are escaped.
*
* The result may vary by locale.
*
* @param {Date|String|Number} date - the original date
* @param {String} [format='YYYY-MM-DDTHH:mm:ss.SSSZ'] - the string of tokens
* @param {Object} [options] - the object with options
* @param {Object} [options.locale=enLocale] - the locale object
* @returns {String} the formatted date string
*
* @example
* // Represent 11 February 2014 in middle-endian format:
* var result = format(
* new Date(2014, 1, 11),
* 'MM/DD/YYYY'
* )
* //=> '02/11/2014'
*
* @example
* // Represent 2 July 2014 in Esperanto:
* var eoLocale = require('date-fns/locale/eo')
* var result = format(
* new Date(2014, 6, 2),
* 'Do [de] MMMM YYYY',
* {locale: eoLocale}
* )
* //=> '2-a de julio 2014'
*/
function format (dirtyDate, dirtyFormatStr, dirtyOptions) {
var formatStr = dirtyFormatStr ? String(dirtyFormatStr) : 'YYYY-MM-DDTHH:mm:ss.SSSZ'
var options = dirtyOptions || {}
var locale = options.locale
var localeFormatters = enLocale.format.formatters
var formattingTokensRegExp = enLocale.format.formattingTokensRegExp
if (locale && locale.format && locale.format.formatters) {
localeFormatters = locale.format.formatters
if (locale.format.formattingTokensRegExp) {
formattingTokensRegExp = locale.format.formattingTokensRegExp
}
}
var date = parse(dirtyDate)
if (!isValid(date)) {
return 'Invalid Date'
}
var formatFn = buildFormatFn(formatStr, localeFormatters, formattingTokensRegExp)
return formatFn(date)
}
var formatters = {
// Month: 1, 2, ..., 12
'M': function (date) {
return date.getMonth() + 1
},
// Month: 01, 02, ..., 12
'MM': function (date) {
return addLeadingZeros(date.getMonth() + 1, 2)
},
// Quarter: 1, 2, 3, 4
'Q': function (date) {
return Math.ceil((date.getMonth() + 1) / 3)
},
// Day of month: 1, 2, ..., 31
'D': function (date) {
return date.getDate()
},
// Day of month: 01, 02, ..., 31
'DD': function (date) {
return addLeadingZeros(date.getDate(), 2)
},
// Day of year: 1, 2, ..., 366
'DDD': function (date) {
return getDayOfYear(date)
},
// Day of year: 001, 002, ..., 366
'DDDD': function (date) {
return addLeadingZeros(getDayOfYear(date), 3)
},
// Day of week: 0, 1, ..., 6
'd': function (date) {
return date.getDay()
},
// Day of ISO week: 1, 2, ..., 7
'E': function (date) {
return date.getDay() || 7
},
// ISO week: 1, 2, ..., 53
'W': function (date) {
return getISOWeek(date)
},
// ISO week: 01, 02, ..., 53
'WW': function (date) {
return addLeadingZeros(getISOWeek(date), 2)
},
// Year: 00, 01, ..., 99
'YY': function (date) {
return addLeadingZeros(date.getFullYear(), 4).substr(2)
},
// Year: 1900, 1901, ..., 2099
'YYYY': function (date) {
return addLeadingZeros(date.getFullYear(), 4)
},
// ISO week-numbering year: 00, 01, ..., 99
'GG': function (date) {
return String(getISOYear(date)).substr(2)
},
// ISO week-numbering year: 1900, 1901, ..., 2099
'GGGG': function (date) {
return getISOYear(date)
},
// Hour: 0, 1, ... 23
'H': function (date) {
return date.getHours()
},
// Hour: 00, 01, ..., 23
'HH': function (date) {
return addLeadingZeros(date.getHours(), 2)
},
// Hour: 1, 2, ..., 12
'h': function (date) {
var hours = date.getHours()
if (hours === 0) {
return 12
} else if (hours > 12) {
return hours % 12
} else {
return hours
}
},
// Hour: 01, 02, ..., 12
'hh': function (date) {
return addLeadingZeros(formatters['h'](date), 2)
},
// Minute: 0, 1, ..., 59
'm': function (date) {
return date.getMinutes()
},
// Minute: 00, 01, ..., 59
'mm': function (date) {
return addLeadingZeros(date.getMinutes(), 2)
},
// Second: 0, 1, ..., 59
's': function (date) {
return date.getSeconds()
},
// Second: 00, 01, ..., 59
'ss': function (date) {
return addLeadingZeros(date.getSeconds(), 2)
},
// 1/10 of second: 0, 1, ..., 9
'S': function (date) {
return Math.floor(date.getMilliseconds() / 100)
},
// 1/100 of second: 00, 01, ..., 99
'SS': function (date) {
return addLeadingZeros(Math.floor(date.getMilliseconds() / 10), 2)
},
// Millisecond: 000, 001, ..., 999
'SSS': function (date) {
return addLeadingZeros(date.getMilliseconds(), 3)
},
// Timezone: -01:00, +00:00, ... +12:00
'Z': function (date) {
return formatTimezone(date.getTimezoneOffset(), ':')
},
// Timezone: -0100, +0000, ... +1200
'ZZ': function (date) {
return formatTimezone(date.getTimezoneOffset())
},
// Seconds timestamp: 512969520
'X': function (date) {
return Math.floor(date.getTime() / 1000)
},
// Milliseconds timestamp: 512969520900
'x': function (date) {
return date.getTime()
}
}
function buildFormatFn (formatStr, localeFormatters, formattingTokensRegExp) {
var array = formatStr.match(formattingTokensRegExp)
var length = array.length
var i
var formatter
for (i = 0; i < length; i++) {
formatter = localeFormatters[array[i]] || formatters[array[i]]
if (formatter) {
array[i] = formatter
} else {
array[i] = removeFormattingTokens(array[i])
}
}
return function (date) {
var output = ''
for (var i = 0; i < length; i++) {
if (array[i] instanceof Function) {
output += array[i](date, formatters)
} else {
output += array[i]
}
}
return output
}
}
function removeFormattingTokens (input) {
if (input.match(/\[[\s\S]/)) {
return input.replace(/^\[|]$/g, '')
}
return input.replace(/\\/g, '')
}
function formatTimezone (offset, delimeter) {
delimeter = delimeter || ''
var sign = offset > 0 ? '-' : '+'
var absOffset = Math.abs(offset)
var hours = Math.floor(absOffset / 60)
var minutes = absOffset % 60
return sign + addLeadingZeros(hours, 2) + delimeter + addLeadingZeros(minutes, 2)
}
function addLeadingZeros (number, targetLength) {
var output = Math.abs(number).toString()
while (output.length < targetLength) {
output = '0' + output
}
return output
}
module.exports = format
},{"../get_day_of_year/index.js":53,"../get_iso_week/index.js":58,"../get_iso_year/index.js":60,"../is_valid/index.js":105,"../locale/en/index.js":119,"../parse/index.js":122}],51:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Get the day of the month of the given date.
*
* @description
* Get the day of the month of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the day of month
*
* @example
* // Which day of the month is 29 February 2012?
* var result = getDate(new Date(2012, 1, 29))
* //=> 29
*/
function getDate (dirtyDate) {
var date = parse(dirtyDate)
var dayOfMonth = date.getDate()
return dayOfMonth
}
module.exports = getDate
},{"../parse/index.js":122}],52:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Get the day of the week of the given date.
*
* @description
* Get the day of the week of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the day of week
*
* @example
* // Which day of the week is 29 February 2012?
* var result = getDay(new Date(2012, 1, 29))
* //=> 3
*/
function getDay (dirtyDate) {
var date = parse(dirtyDate)
var day = date.getDay()
return day
}
module.exports = getDay
},{"../parse/index.js":122}],53:[function(require,module,exports){
var parse = require('../parse/index.js')
var startOfYear = require('../start_of_year/index.js')
var differenceInCalendarDays = require('../difference_in_calendar_days/index.js')
/**
* @category Day Helpers
* @summary Get the day of the year of the given date.
*
* @description
* Get the day of the year of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the day of year
*
* @example
* // Which day of the year is 2 July 2014?
* var result = getDayOfYear(new Date(2014, 6, 2))
* //=> 183
*/
function getDayOfYear (dirtyDate) {
var date = parse(dirtyDate)
var diff = differenceInCalendarDays(date, startOfYear(date))
var dayOfYear = diff + 1
return dayOfYear
}
module.exports = getDayOfYear
},{"../difference_in_calendar_days/index.js":16,"../parse/index.js":122,"../start_of_year/index.js":147}],54:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Get the number of days in a month of the given date.
*
* @description
* Get the number of days in a month of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the number of days in a month
*
* @example
* // How many days are in February 2000?
* var result = getDaysInMonth(new Date(2000, 1))
* //=> 29
*/
function getDaysInMonth (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
var monthIndex = date.getMonth()
var lastDayOfMonth = new Date(0)
lastDayOfMonth.setFullYear(year, monthIndex + 1, 0)
lastDayOfMonth.setHours(0, 0, 0, 0)
return lastDayOfMonth.getDate()
}
module.exports = getDaysInMonth
},{"../parse/index.js":122}],55:[function(require,module,exports){
var isLeapYear = require('../is_leap_year/index.js')
/**
* @category Year Helpers
* @summary Get the number of days in a year of the given date.
*
* @description
* Get the number of days in a year of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the number of days in a year
*
* @example
* // How many days are in 2012?
* var result = getDaysInYear(new Date(2012, 0, 1))
* //=> 366
*/
function getDaysInYear (dirtyDate) {
return isLeapYear(dirtyDate) ? 366 : 365
}
module.exports = getDaysInYear
},{"../is_leap_year/index.js":77}],56:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Hour Helpers
* @summary Get the hours of the given date.
*
* @description
* Get the hours of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the hours
*
* @example
* // Get the hours of 29 February 2012 11:45:00:
* var result = getHours(new Date(2012, 1, 29, 11, 45))
* //=> 11
*/
function getHours (dirtyDate) {
var date = parse(dirtyDate)
var hours = date.getHours()
return hours
}
module.exports = getHours
},{"../parse/index.js":122}],57:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Get the day of the ISO week of the given date.
*
* @description
* Get the day of the ISO week of the given date,
* which is 7 for Sunday, 1 for Monday etc.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the day of ISO week
*
* @example
* // Which day of the ISO week is 26 February 2012?
* var result = getISODay(new Date(2012, 1, 26))
* //=> 7
*/
function getISODay (dirtyDate) {
var date = parse(dirtyDate)
var day = date.getDay()
if (day === 0) {
day = 7
}
return day
}
module.exports = getISODay
},{"../parse/index.js":122}],58:[function(require,module,exports){
var parse = require('../parse/index.js')
var startOfISOWeek = require('../start_of_iso_week/index.js')
var startOfISOYear = require('../start_of_iso_year/index.js')
var MILLISECONDS_IN_WEEK = 604800000
/**
* @category ISO Week Helpers
* @summary Get the ISO week of the given date.
*
* @description
* Get the ISO week of the given date.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the ISO week
*
* @example
* // Which week of the ISO-week numbering year is 2 January 2005?
* var result = getISOWeek(new Date(2005, 0, 2))
* //=> 53
*/
function getISOWeek (dirtyDate) {
var date = parse(dirtyDate)
var diff = startOfISOWeek(date).getTime() - startOfISOYear(date).getTime()
// Round the number of days to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round(diff / MILLISECONDS_IN_WEEK) + 1
}
module.exports = getISOWeek
},{"../parse/index.js":122,"../start_of_iso_week/index.js":138,"../start_of_iso_year/index.js":139}],59:[function(require,module,exports){
var startOfISOYear = require('../start_of_iso_year/index.js')
var addWeeks = require('../add_weeks/index.js')
var MILLISECONDS_IN_WEEK = 604800000
/**
* @category ISO Week-Numbering Year Helpers
* @summary Get the number of weeks in an ISO week-numbering year of the given date.
*
* @description
* Get the number of weeks in an ISO week-numbering year of the given date.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the number of ISO weeks in a year
*
* @example
* // How many weeks are in ISO week-numbering year 2015?
* var result = getISOWeeksInYear(new Date(2015, 1, 11))
* //=> 53
*/
function getISOWeeksInYear (dirtyDate) {
var thisYear = startOfISOYear(dirtyDate)
var nextYear = startOfISOYear(addWeeks(thisYear, 60))
var diff = nextYear.valueOf() - thisYear.valueOf()
// Round the number of weeks to the nearest integer
// because the number of milliseconds in a week is not constant
// (e.g. it's different in the week of the daylight saving time clock shift)
return Math.round(diff / MILLISECONDS_IN_WEEK)
}
module.exports = getISOWeeksInYear
},{"../add_weeks/index.js":9,"../start_of_iso_year/index.js":139}],60:[function(require,module,exports){
var parse = require('../parse/index.js')
var startOfISOWeek = require('../start_of_iso_week/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Get the ISO week-numbering year of the given date.
*
* @description
* Get the ISO week-numbering year of the given date,
* which always starts 3 days before the year's first Thursday.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the ISO week-numbering year
*
* @example
* // Which ISO-week numbering year is 2 January 2005?
* var result = getISOYear(new Date(2005, 0, 2))
* //=> 2004
*/
function getISOYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
var fourthOfJanuaryOfNextYear = new Date(0)
fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4)
fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0)
var startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear)
var fourthOfJanuaryOfThisYear = new Date(0)
fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4)
fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0)
var startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear)
if (date.getTime() >= startOfNextYear.getTime()) {
return year + 1
} else if (date.getTime() >= startOfThisYear.getTime()) {
return year
} else {
return year - 1
}
}
module.exports = getISOYear
},{"../parse/index.js":122,"../start_of_iso_week/index.js":138}],61:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Millisecond Helpers
* @summary Get the milliseconds of the given date.
*
* @description
* Get the milliseconds of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the milliseconds
*
* @example
* // Get the milliseconds of 29 February 2012 11:45:05.123:
* var result = getMilliseconds(new Date(2012, 1, 29, 11, 45, 5, 123))
* //=> 123
*/
function getMilliseconds (dirtyDate) {
var date = parse(dirtyDate)
var milliseconds = date.getMilliseconds()
return milliseconds
}
module.exports = getMilliseconds
},{"../parse/index.js":122}],62:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Minute Helpers
* @summary Get the minutes of the given date.
*
* @description
* Get the minutes of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the minutes
*
* @example
* // Get the minutes of 29 February 2012 11:45:05:
* var result = getMinutes(new Date(2012, 1, 29, 11, 45, 5))
* //=> 45
*/
function getMinutes (dirtyDate) {
var date = parse(dirtyDate)
var minutes = date.getMinutes()
return minutes
}
module.exports = getMinutes
},{"../parse/index.js":122}],63:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Get the month of the given date.
*
* @description
* Get the month of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the month
*
* @example
* // Which month is 29 February 2012?
* var result = getMonth(new Date(2012, 1, 29))
* //=> 1
*/
function getMonth (dirtyDate) {
var date = parse(dirtyDate)
var month = date.getMonth()
return month
}
module.exports = getMonth
},{"../parse/index.js":122}],64:[function(require,module,exports){
var parse = require('../parse/index.js')
var MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000
/**
* @category Range Helpers
* @summary Get the number of days that overlap in two date ranges
*
* @description
* Get the number of days that overlap in two date ranges
*
* @param {Date|String|Number} initialRangeStartDate - the start of the initial range
* @param {Date|String|Number} initialRangeEndDate - the end of the initial range
* @param {Date|String|Number} comparedRangeStartDate - the start of the range to compare it with
* @param {Date|String|Number} comparedRangeEndDate - the end of the range to compare it with
* @returns {Number} the number of days that overlap in two date ranges
* @throws {Error} startDate of a date range cannot be after its endDate
*
* @example
* // For overlapping date ranges adds 1 for each started overlapping day:
* getOverlappingDaysInRanges(
* new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 17), new Date(2014, 0, 21)
* )
* //=> 3
*
* @example
* // For non-overlapping date ranges returns 0:
* getOverlappingDaysInRanges(
* new Date(2014, 0, 10), new Date(2014, 0, 20), new Date(2014, 0, 21), new Date(2014, 0, 22)
* )
* //=> 0
*/
function getOverlappingDaysInRanges (dirtyInitialRangeStartDate, dirtyInitialRangeEndDate, dirtyComparedRangeStartDate, dirtyComparedRangeEndDate) {
var initialStartTime = parse(dirtyInitialRangeStartDate).getTime()
var initialEndTime = parse(dirtyInitialRangeEndDate).getTime()
var comparedStartTime = parse(dirtyComparedRangeStartDate).getTime()
var comparedEndTime = parse(dirtyComparedRangeEndDate).getTime()
if (initialStartTime > initialEndTime || comparedStartTime > comparedEndTime) {
throw new Error('The start of the range cannot be after the end of the range')
}
var isOverlapping = initialStartTime < comparedEndTime && comparedStartTime < initialEndTime
if (!isOverlapping) {
return 0
}
var overlapStartDate = comparedStartTime < initialStartTime
? initialStartTime
: comparedStartTime
var overlapEndDate = comparedEndTime > initialEndTime
? initialEndTime
: comparedEndTime
var differenceInMs = overlapEndDate - overlapStartDate
return Math.ceil(differenceInMs / MILLISECONDS_IN_DAY)
}
module.exports = getOverlappingDaysInRanges
},{"../parse/index.js":122}],65:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Quarter Helpers
* @summary Get the year quarter of the given date.
*
* @description
* Get the year quarter of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the quarter
*
* @example
* // Which quarter is 2 July 2014?
* var result = getQuarter(new Date(2014, 6, 2))
* //=> 3
*/
function getQuarter (dirtyDate) {
var date = parse(dirtyDate)
var quarter = Math.floor(date.getMonth() / 3) + 1
return quarter
}
module.exports = getQuarter
},{"../parse/index.js":122}],66:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Second Helpers
* @summary Get the seconds of the given date.
*
* @description
* Get the seconds of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the seconds
*
* @example
* // Get the seconds of 29 February 2012 11:45:05.123:
* var result = getSeconds(new Date(2012, 1, 29, 11, 45, 5, 123))
* //=> 5
*/
function getSeconds (dirtyDate) {
var date = parse(dirtyDate)
var seconds = date.getSeconds()
return seconds
}
module.exports = getSeconds
},{"../parse/index.js":122}],67:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Timestamp Helpers
* @summary Get the milliseconds timestamp of the given date.
*
* @description
* Get the milliseconds timestamp of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the timestamp
*
* @example
* // Get the timestamp of 29 February 2012 11:45:05.123:
* var result = getTime(new Date(2012, 1, 29, 11, 45, 5, 123))
* //=> 1330515905123
*/
function getTime (dirtyDate) {
var date = parse(dirtyDate)
var timestamp = date.getTime()
return timestamp
}
module.exports = getTime
},{"../parse/index.js":122}],68:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Get the year of the given date.
*
* @description
* Get the year of the given date.
*
* @param {Date|String|Number} date - the given date
* @returns {Number} the year
*
* @example
* // Which year is 2 July 2014?
* var result = getYear(new Date(2014, 6, 2))
* //=> 2014
*/
function getYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
return year
}
module.exports = getYear
},{"../parse/index.js":122}],69:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Is the first date after the second one?
*
* @description
* Is the first date after the second one?
*
* @param {Date|String|Number} date - the date that should be after the other one to return true
* @param {Date|String|Number} dateToCompare - the date to compare with
* @returns {Boolean} the first date is after the second date
*
* @example
* // Is 10 July 1989 after 11 February 1987?
* var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11))
* //=> true
*/
function isAfter (dirtyDate, dirtyDateToCompare) {
var date = parse(dirtyDate)
var dateToCompare = parse(dirtyDateToCompare)
return date.getTime() > dateToCompare.getTime()
}
module.exports = isAfter
},{"../parse/index.js":122}],70:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Is the first date before the second one?
*
* @description
* Is the first date before the second one?
*
* @param {Date|String|Number} date - the date that should be before the other one to return true
* @param {Date|String|Number} dateToCompare - the date to compare with
* @returns {Boolean} the first date is before the second date
*
* @example
* // Is 10 July 1989 before 11 February 1987?
* var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))
* //=> false
*/
function isBefore (dirtyDate, dirtyDateToCompare) {
var date = parse(dirtyDate)
var dateToCompare = parse(dirtyDateToCompare)
return date.getTime() < dateToCompare.getTime()
}
module.exports = isBefore
},{"../parse/index.js":122}],71:[function(require,module,exports){
/**
* @category Common Helpers
* @summary Is the given argument an instance of Date?
*
* @description
* Is the given argument an instance of Date?
*
* @param {*} argument - the argument to check
* @returns {Boolean} the given argument is an instance of Date
*
* @example
* // Is 'mayonnaise' a Date?
* var result = isDate('mayonnaise')
* //=> false
*/
function isDate (argument) {
return argument instanceof Date
}
module.exports = isDate
},{}],72:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Are the given dates equal?
*
* @description
* Are the given dates equal?
*
* @param {Date|String|Number} dateLeft - the first date to compare
* @param {Date|String|Number} dateRight - the second date to compare
* @returns {Boolean} the dates are equal
*
* @example
* // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal?
* var result = isEqual(
* new Date(2014, 6, 2, 6, 30, 45, 0)
* new Date(2014, 6, 2, 6, 30, 45, 500)
* )
* //=> false
*/
function isEqual (dirtyLeftDate, dirtyRightDate) {
var dateLeft = parse(dirtyLeftDate)
var dateRight = parse(dirtyRightDate)
return dateLeft.getTime() === dateRight.getTime()
}
module.exports = isEqual
},{"../parse/index.js":122}],73:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Is the given date the first day of a month?
*
* @description
* Is the given date the first day of a month?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is the first day of a month
*
* @example
* // Is 1 September 2014 the first day of a month?
* var result = isFirstDayOfMonth(new Date(2014, 8, 1))
* //=> true
*/
function isFirstDayOfMonth (dirtyDate) {
return parse(dirtyDate).getDate() === 1
}
module.exports = isFirstDayOfMonth
},{"../parse/index.js":122}],74:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Friday?
*
* @description
* Is the given date Friday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Friday
*
* @example
* // Is 26 September 2014 Friday?
* var result = isFriday(new Date(2014, 8, 26))
* //=> true
*/
function isFriday (dirtyDate) {
return parse(dirtyDate).getDay() === 5
}
module.exports = isFriday
},{"../parse/index.js":122}],75:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Is the given date in the future?
*
* @description
* Is the given date in the future?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in the future
*
* @example
* // If today is 6 October 2014, is 31 December 2014 in the future?
* var result = isFuture(new Date(2014, 11, 31))
* //=> true
*/
function isFuture (dirtyDate) {
return parse(dirtyDate).getTime() > new Date().getTime()
}
module.exports = isFuture
},{"../parse/index.js":122}],76:[function(require,module,exports){
var parse = require('../parse/index.js')
var endOfDay = require('../end_of_day/index.js')
var endOfMonth = require('../end_of_month/index.js')
/**
* @category Month Helpers
* @summary Is the given date the last day of a month?
*
* @description
* Is the given date the last day of a month?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is the last day of a month
*
* @example
* // Is 28 February 2014 the last day of a month?
* var result = isLastDayOfMonth(new Date(2014, 1, 28))
* //=> true
*/
function isLastDayOfMonth (dirtyDate) {
var date = parse(dirtyDate)
return endOfDay(date).getTime() === endOfMonth(date).getTime()
}
module.exports = isLastDayOfMonth
},{"../end_of_day/index.js":37,"../end_of_month/index.js":42,"../parse/index.js":122}],77:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Is the given date in the leap year?
*
* @description
* Is the given date in the leap year?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in the leap year
*
* @example
* // Is 1 September 2012 in the leap year?
* var result = isLeapYear(new Date(2012, 8, 1))
* //=> true
*/
function isLeapYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0
}
module.exports = isLeapYear
},{"../parse/index.js":122}],78:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Monday?
*
* @description
* Is the given date Monday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Monday
*
* @example
* // Is 22 September 2014 Monday?
* var result = isMonday(new Date(2014, 8, 22))
* //=> true
*/
function isMonday (dirtyDate) {
return parse(dirtyDate).getDay() === 1
}
module.exports = isMonday
},{"../parse/index.js":122}],79:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Is the given date in the past?
*
* @description
* Is the given date in the past?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in the past
*
* @example
* // If today is 6 October 2014, is 2 July 2014 in the past?
* var result = isPast(new Date(2014, 6, 2))
* //=> true
*/
function isPast (dirtyDate) {
return parse(dirtyDate).getTime() < new Date().getTime()
}
module.exports = isPast
},{"../parse/index.js":122}],80:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
/**
* @category Day Helpers
* @summary Are the given dates in the same day?
*
* @description
* Are the given dates in the same day?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same day
*
* @example
* // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?
* var result = isSameDay(
* new Date(2014, 8, 4, 6, 0),
* new Date(2014, 8, 4, 18, 0)
* )
* //=> true
*/
function isSameDay (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfDay = startOfDay(dirtyDateLeft)
var dateRightStartOfDay = startOfDay(dirtyDateRight)
return dateLeftStartOfDay.getTime() === dateRightStartOfDay.getTime()
}
module.exports = isSameDay
},{"../start_of_day/index.js":136}],81:[function(require,module,exports){
var startOfHour = require('../start_of_hour/index.js')
/**
* @category Hour Helpers
* @summary Are the given dates in the same hour?
*
* @description
* Are the given dates in the same hour?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same hour
*
* @example
* // Are 4 September 2014 06:00:00 and 4 September 06:30:00 in the same hour?
* var result = isSameHour(
* new Date(2014, 8, 4, 6, 0),
* new Date(2014, 8, 4, 6, 30)
* )
* //=> true
*/
function isSameHour (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfHour = startOfHour(dirtyDateLeft)
var dateRightStartOfHour = startOfHour(dirtyDateRight)
return dateLeftStartOfHour.getTime() === dateRightStartOfHour.getTime()
}
module.exports = isSameHour
},{"../start_of_hour/index.js":137}],82:[function(require,module,exports){
var isSameWeek = require('../is_same_week/index.js')
/**
* @category ISO Week Helpers
* @summary Are the given dates in the same ISO week?
*
* @description
* Are the given dates in the same ISO week?
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same ISO week
*
* @example
* // Are 1 September 2014 and 7 September 2014 in the same ISO week?
* var result = isSameISOWeek(
* new Date(2014, 8, 1),
* new Date(2014, 8, 7)
* )
* //=> true
*/
function isSameISOWeek (dirtyDateLeft, dirtyDateRight) {
return isSameWeek(dirtyDateLeft, dirtyDateRight, {weekStartsOn: 1})
}
module.exports = isSameISOWeek
},{"../is_same_week/index.js":88}],83:[function(require,module,exports){
var startOfISOYear = require('../start_of_iso_year/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Are the given dates in the same ISO week-numbering year?
*
* @description
* Are the given dates in the same ISO week-numbering year?
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same ISO week-numbering year
*
* @example
* // Are 29 December 2003 and 2 January 2005 in the same ISO week-numbering year?
* var result = isSameISOYear(
* new Date(2003, 11, 29),
* new Date(2005, 0, 2)
* )
* //=> true
*/
function isSameISOYear (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfYear = startOfISOYear(dirtyDateLeft)
var dateRightStartOfYear = startOfISOYear(dirtyDateRight)
return dateLeftStartOfYear.getTime() === dateRightStartOfYear.getTime()
}
module.exports = isSameISOYear
},{"../start_of_iso_year/index.js":139}],84:[function(require,module,exports){
var startOfMinute = require('../start_of_minute/index.js')
/**
* @category Minute Helpers
* @summary Are the given dates in the same minute?
*
* @description
* Are the given dates in the same minute?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same minute
*
* @example
* // Are 4 September 2014 06:30:00 and 4 September 2014 06:30:15
* // in the same minute?
* var result = isSameMinute(
* new Date(2014, 8, 4, 6, 30),
* new Date(2014, 8, 4, 6, 30, 15)
* )
* //=> true
*/
function isSameMinute (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfMinute = startOfMinute(dirtyDateLeft)
var dateRightStartOfMinute = startOfMinute(dirtyDateRight)
return dateLeftStartOfMinute.getTime() === dateRightStartOfMinute.getTime()
}
module.exports = isSameMinute
},{"../start_of_minute/index.js":140}],85:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Are the given dates in the same month?
*
* @description
* Are the given dates in the same month?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same month
*
* @example
* // Are 2 September 2014 and 25 September 2014 in the same month?
* var result = isSameMonth(
* new Date(2014, 8, 2),
* new Date(2014, 8, 25)
* )
* //=> true
*/
function isSameMonth (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
return dateLeft.getFullYear() === dateRight.getFullYear() &&
dateLeft.getMonth() === dateRight.getMonth()
}
module.exports = isSameMonth
},{"../parse/index.js":122}],86:[function(require,module,exports){
var startOfQuarter = require('../start_of_quarter/index.js')
/**
* @category Quarter Helpers
* @summary Are the given dates in the same year quarter?
*
* @description
* Are the given dates in the same year quarter?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same quarter
*
* @example
* // Are 1 January 2014 and 8 March 2014 in the same quarter?
* var result = isSameQuarter(
* new Date(2014, 0, 1),
* new Date(2014, 2, 8)
* )
* //=> true
*/
function isSameQuarter (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfQuarter = startOfQuarter(dirtyDateLeft)
var dateRightStartOfQuarter = startOfQuarter(dirtyDateRight)
return dateLeftStartOfQuarter.getTime() === dateRightStartOfQuarter.getTime()
}
module.exports = isSameQuarter
},{"../start_of_quarter/index.js":142}],87:[function(require,module,exports){
var startOfSecond = require('../start_of_second/index.js')
/**
* @category Second Helpers
* @summary Are the given dates in the same second?
*
* @description
* Are the given dates in the same second?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same second
*
* @example
* // Are 4 September 2014 06:30:15.000 and 4 September 2014 06:30.15.500
* // in the same second?
* var result = isSameSecond(
* new Date(2014, 8, 4, 6, 30, 15),
* new Date(2014, 8, 4, 6, 30, 15, 500)
* )
* //=> true
*/
function isSameSecond (dirtyDateLeft, dirtyDateRight) {
var dateLeftStartOfSecond = startOfSecond(dirtyDateLeft)
var dateRightStartOfSecond = startOfSecond(dirtyDateRight)
return dateLeftStartOfSecond.getTime() === dateRightStartOfSecond.getTime()
}
module.exports = isSameSecond
},{"../start_of_second/index.js":143}],88:[function(require,module,exports){
var startOfWeek = require('../start_of_week/index.js')
/**
* @category Week Helpers
* @summary Are the given dates in the same week?
*
* @description
* Are the given dates in the same week?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Boolean} the dates are in the same week
*
* @example
* // Are 31 August 2014 and 4 September 2014 in the same week?
* var result = isSameWeek(
* new Date(2014, 7, 31),
* new Date(2014, 8, 4)
* )
* //=> true
*
* @example
* // If week starts with Monday,
* // are 31 August 2014 and 4 September 2014 in the same week?
* var result = isSameWeek(
* new Date(2014, 7, 31),
* new Date(2014, 8, 4),
* {weekStartsOn: 1}
* )
* //=> false
*/
function isSameWeek (dirtyDateLeft, dirtyDateRight, dirtyOptions) {
var dateLeftStartOfWeek = startOfWeek(dirtyDateLeft, dirtyOptions)
var dateRightStartOfWeek = startOfWeek(dirtyDateRight, dirtyOptions)
return dateLeftStartOfWeek.getTime() === dateRightStartOfWeek.getTime()
}
module.exports = isSameWeek
},{"../start_of_week/index.js":146}],89:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Are the given dates in the same year?
*
* @description
* Are the given dates in the same year?
*
* @param {Date|String|Number} dateLeft - the first date to check
* @param {Date|String|Number} dateRight - the second date to check
* @returns {Boolean} the dates are in the same year
*
* @example
* // Are 2 September 2014 and 25 September 2014 in the same year?
* var result = isSameYear(
* new Date(2014, 8, 2),
* new Date(2014, 8, 25)
* )
* //=> true
*/
function isSameYear (dirtyDateLeft, dirtyDateRight) {
var dateLeft = parse(dirtyDateLeft)
var dateRight = parse(dirtyDateRight)
return dateLeft.getFullYear() === dateRight.getFullYear()
}
module.exports = isSameYear
},{"../parse/index.js":122}],90:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Saturday?
*
* @description
* Is the given date Saturday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Saturday
*
* @example
* // Is 27 September 2014 Saturday?
* var result = isSaturday(new Date(2014, 8, 27))
* //=> true
*/
function isSaturday (dirtyDate) {
return parse(dirtyDate).getDay() === 6
}
module.exports = isSaturday
},{"../parse/index.js":122}],91:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Sunday?
*
* @description
* Is the given date Sunday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Sunday
*
* @example
* // Is 21 September 2014 Sunday?
* var result = isSunday(new Date(2014, 8, 21))
* //=> true
*/
function isSunday (dirtyDate) {
return parse(dirtyDate).getDay() === 0
}
module.exports = isSunday
},{"../parse/index.js":122}],92:[function(require,module,exports){
var isSameHour = require('../is_same_hour/index.js')
/**
* @category Hour Helpers
* @summary Is the given date in the same hour as the current date?
*
* @description
* Is the given date in the same hour as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this hour
*
* @example
* // If now is 25 September 2014 18:30:15.500,
* // is 25 September 2014 18:00:00 in this hour?
* var result = isThisHour(new Date(2014, 8, 25, 18))
* //=> true
*/
function isThisHour (dirtyDate) {
return isSameHour(new Date(), dirtyDate)
}
module.exports = isThisHour
},{"../is_same_hour/index.js":81}],93:[function(require,module,exports){
var isSameISOWeek = require('../is_same_iso_week/index.js')
/**
* @category ISO Week Helpers
* @summary Is the given date in the same ISO week as the current date?
*
* @description
* Is the given date in the same ISO week as the current date?
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this ISO week
*
* @example
* // If today is 25 September 2014, is 22 September 2014 in this ISO week?
* var result = isThisISOWeek(new Date(2014, 8, 22))
* //=> true
*/
function isThisISOWeek (dirtyDate) {
return isSameISOWeek(new Date(), dirtyDate)
}
module.exports = isThisISOWeek
},{"../is_same_iso_week/index.js":82}],94:[function(require,module,exports){
var isSameISOYear = require('../is_same_iso_year/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Is the given date in the same ISO week-numbering year as the current date?
*
* @description
* Is the given date in the same ISO week-numbering year as the current date?
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this ISO week-numbering year
*
* @example
* // If today is 25 September 2014,
* // is 30 December 2013 in this ISO week-numbering year?
* var result = isThisISOYear(new Date(2013, 11, 30))
* //=> true
*/
function isThisISOYear (dirtyDate) {
return isSameISOYear(new Date(), dirtyDate)
}
module.exports = isThisISOYear
},{"../is_same_iso_year/index.js":83}],95:[function(require,module,exports){
var isSameMinute = require('../is_same_minute/index.js')
/**
* @category Minute Helpers
* @summary Is the given date in the same minute as the current date?
*
* @description
* Is the given date in the same minute as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this minute
*
* @example
* // If now is 25 September 2014 18:30:15.500,
* // is 25 September 2014 18:30:00 in this minute?
* var result = isThisMinute(new Date(2014, 8, 25, 18, 30))
* //=> true
*/
function isThisMinute (dirtyDate) {
return isSameMinute(new Date(), dirtyDate)
}
module.exports = isThisMinute
},{"../is_same_minute/index.js":84}],96:[function(require,module,exports){
var isSameMonth = require('../is_same_month/index.js')
/**
* @category Month Helpers
* @summary Is the given date in the same month as the current date?
*
* @description
* Is the given date in the same month as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this month
*
* @example
* // If today is 25 September 2014, is 15 September 2014 in this month?
* var result = isThisMonth(new Date(2014, 8, 15))
* //=> true
*/
function isThisMonth (dirtyDate) {
return isSameMonth(new Date(), dirtyDate)
}
module.exports = isThisMonth
},{"../is_same_month/index.js":85}],97:[function(require,module,exports){
var isSameQuarter = require('../is_same_quarter/index.js')
/**
* @category Quarter Helpers
* @summary Is the given date in the same quarter as the current date?
*
* @description
* Is the given date in the same quarter as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this quarter
*
* @example
* // If today is 25 September 2014, is 2 July 2014 in this quarter?
* var result = isThisQuarter(new Date(2014, 6, 2))
* //=> true
*/
function isThisQuarter (dirtyDate) {
return isSameQuarter(new Date(), dirtyDate)
}
module.exports = isThisQuarter
},{"../is_same_quarter/index.js":86}],98:[function(require,module,exports){
var isSameSecond = require('../is_same_second/index.js')
/**
* @category Second Helpers
* @summary Is the given date in the same second as the current date?
*
* @description
* Is the given date in the same second as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this second
*
* @example
* // If now is 25 September 2014 18:30:15.500,
* // is 25 September 2014 18:30:15.000 in this second?
* var result = isThisSecond(new Date(2014, 8, 25, 18, 30, 15))
* //=> true
*/
function isThisSecond (dirtyDate) {
return isSameSecond(new Date(), dirtyDate)
}
module.exports = isThisSecond
},{"../is_same_second/index.js":87}],99:[function(require,module,exports){
var isSameWeek = require('../is_same_week/index.js')
/**
* @category Week Helpers
* @summary Is the given date in the same week as the current date?
*
* @description
* Is the given date in the same week as the current date?
*
* @param {Date|String|Number} date - the date to check
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Boolean} the date is in this week
*
* @example
* // If today is 25 September 2014, is 21 September 2014 in this week?
* var result = isThisWeek(new Date(2014, 8, 21))
* //=> true
*
* @example
* // If today is 25 September 2014 and week starts with Monday
* // is 21 September 2014 in this week?
* var result = isThisWeek(new Date(2014, 8, 21), {weekStartsOn: 1})
* //=> false
*/
function isThisWeek (dirtyDate, dirtyOptions) {
return isSameWeek(new Date(), dirtyDate, dirtyOptions)
}
module.exports = isThisWeek
},{"../is_same_week/index.js":88}],100:[function(require,module,exports){
var isSameYear = require('../is_same_year/index.js')
/**
* @category Year Helpers
* @summary Is the given date in the same year as the current date?
*
* @description
* Is the given date in the same year as the current date?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is in this year
*
* @example
* // If today is 25 September 2014, is 2 July 2014 in this year?
* var result = isThisYear(new Date(2014, 6, 2))
* //=> true
*/
function isThisYear (dirtyDate) {
return isSameYear(new Date(), dirtyDate)
}
module.exports = isThisYear
},{"../is_same_year/index.js":89}],101:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Thursday?
*
* @description
* Is the given date Thursday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Thursday
*
* @example
* // Is 25 September 2014 Thursday?
* var result = isThursday(new Date(2014, 8, 25))
* //=> true
*/
function isThursday (dirtyDate) {
return parse(dirtyDate).getDay() === 4
}
module.exports = isThursday
},{"../parse/index.js":122}],102:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
/**
* @category Day Helpers
* @summary Is the given date today?
*
* @description
* Is the given date today?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is today
*
* @example
* // If today is 6 October 2014, is 6 October 14:00:00 today?
* var result = isToday(new Date(2014, 9, 6, 14, 0))
* //=> true
*/
function isToday (dirtyDate) {
return startOfDay(dirtyDate).getTime() === startOfDay(new Date()).getTime()
}
module.exports = isToday
},{"../start_of_day/index.js":136}],103:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
/**
* @category Day Helpers
* @summary Is the given date tomorrow?
*
* @description
* Is the given date tomorrow?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is tomorrow
*
* @example
* // If today is 6 October 2014, is 7 October 14:00:00 tomorrow?
* var result = isTomorrow(new Date(2014, 9, 7, 14, 0))
* //=> true
*/
function isTomorrow (dirtyDate) {
var tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
return startOfDay(dirtyDate).getTime() === startOfDay(tomorrow).getTime()
}
module.exports = isTomorrow
},{"../start_of_day/index.js":136}],104:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Tuesday?
*
* @description
* Is the given date Tuesday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Tuesday
*
* @example
* // Is 23 September 2014 Tuesday?
* var result = isTuesday(new Date(2014, 8, 23))
* //=> true
*/
function isTuesday (dirtyDate) {
return parse(dirtyDate).getDay() === 2
}
module.exports = isTuesday
},{"../parse/index.js":122}],105:[function(require,module,exports){
var isDate = require('../is_date/index.js')
/**
* @category Common Helpers
* @summary Is the given date valid?
*
* @description
* Returns false if argument is Invalid Date and true otherwise.
* Invalid Date is a Date, whose time value is NaN.
*
* Time value of Date: http://es5.github.io/#x15.9.1.1
*
* @param {Date} date - the date to check
* @returns {Boolean} the date is valid
* @throws {TypeError} argument must be an instance of Date
*
* @example
* // For the valid date:
* var result = isValid(new Date(2014, 1, 31))
* //=> true
*
* @example
* // For the invalid date:
* var result = isValid(new Date(''))
* //=> false
*/
function isValid (dirtyDate) {
if (isDate(dirtyDate)) {
return !isNaN(dirtyDate)
} else {
throw new TypeError(toString.call(dirtyDate) + ' is not an instance of Date')
}
}
module.exports = isValid
},{"../is_date/index.js":71}],106:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Is the given date Wednesday?
*
* @description
* Is the given date Wednesday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is Wednesday
*
* @example
* // Is 24 September 2014 Wednesday?
* var result = isWednesday(new Date(2014, 8, 24))
* //=> true
*/
function isWednesday (dirtyDate) {
return parse(dirtyDate).getDay() === 3
}
module.exports = isWednesday
},{"../parse/index.js":122}],107:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Weekday Helpers
* @summary Does the given date fall on a weekend?
*
* @description
* Does the given date fall on a weekend?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date falls on a weekend
*
* @example
* // Does 5 October 2014 fall on a weekend?
* var result = isWeekend(new Date(2014, 9, 5))
* //=> true
*/
function isWeekend (dirtyDate) {
var date = parse(dirtyDate)
var day = date.getDay()
return day === 0 || day === 6
}
module.exports = isWeekend
},{"../parse/index.js":122}],108:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Range Helpers
* @summary Is the given date within the range?
*
* @description
* Is the given date within the range?
*
* @param {Date|String|Number} date - the date to check
* @param {Date|String|Number} startDate - the start of range
* @param {Date|String|Number} endDate - the end of range
* @returns {Boolean} the date is within the range
* @throws {Error} startDate cannot be after endDate
*
* @example
* // For the date within the range:
* isWithinRange(
* new Date(2014, 0, 3), new Date(2014, 0, 1), new Date(2014, 0, 7)
* )
* //=> true
*
* @example
* // For the date outside of the range:
* isWithinRange(
* new Date(2014, 0, 10), new Date(2014, 0, 1), new Date(2014, 0, 7)
* )
* //=> false
*/
function isWithinRange (dirtyDate, dirtyStartDate, dirtyEndDate) {
var time = parse(dirtyDate).getTime()
var startTime = parse(dirtyStartDate).getTime()
var endTime = parse(dirtyEndDate).getTime()
if (startTime > endTime) {
throw new Error('The start of the range cannot be after the end of the range')
}
return time >= startTime && time <= endTime
}
module.exports = isWithinRange
},{"../parse/index.js":122}],109:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
/**
* @category Day Helpers
* @summary Is the given date yesterday?
*
* @description
* Is the given date yesterday?
*
* @param {Date|String|Number} date - the date to check
* @returns {Boolean} the date is yesterday
*
* @example
* // If today is 6 October 2014, is 5 October 14:00:00 yesterday?
* var result = isYesterday(new Date(2014, 9, 5, 14, 0))
* //=> true
*/
function isYesterday (dirtyDate) {
var yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
return startOfDay(dirtyDate).getTime() === startOfDay(yesterday).getTime()
}
module.exports = isYesterday
},{"../start_of_day/index.js":136}],110:[function(require,module,exports){
var lastDayOfWeek = require('../last_day_of_week/index.js')
/**
* @category ISO Week Helpers
* @summary Return the last day of an ISO week for the given date.
*
* @description
* Return the last day of an ISO week for the given date.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the last day of an ISO week
*
* @example
* // The last day of an ISO week for 2 September 2014 11:55:00:
* var result = lastDayOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sun Sep 07 2014 00:00:00
*/
function lastDayOfISOWeek (dirtyDate) {
return lastDayOfWeek(dirtyDate, {weekStartsOn: 1})
}
module.exports = lastDayOfISOWeek
},{"../last_day_of_week/index.js":114}],111:[function(require,module,exports){
var getISOYear = require('../get_iso_year/index.js')
var startOfISOWeek = require('../start_of_iso_week/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Return the last day of an ISO week-numbering year for the given date.
*
* @description
* Return the last day of an ISO week-numbering year,
* which always starts 3 days before the year's first Thursday.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the end of an ISO week-numbering year
*
* @example
* // The last day of an ISO week-numbering year for 2 July 2005:
* var result = lastDayOfISOYear(new Date(2005, 6, 2))
* //=> Sun Jan 01 2006 00:00:00
*/
function lastDayOfISOYear (dirtyDate) {
var year = getISOYear(dirtyDate)
var fourthOfJanuary = new Date(0)
fourthOfJanuary.setFullYear(year + 1, 0, 4)
fourthOfJanuary.setHours(0, 0, 0, 0)
var date = startOfISOWeek(fourthOfJanuary)
date.setDate(date.getDate() - 1)
return date
}
module.exports = lastDayOfISOYear
},{"../get_iso_year/index.js":60,"../start_of_iso_week/index.js":138}],112:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Return the last day of a month for the given date.
*
* @description
* Return the last day of a month for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the last day of a month
*
* @example
* // The last day of a month for 2 September 2014 11:55:00:
* var result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 00:00:00
*/
function lastDayOfMonth (dirtyDate) {
var date = parse(dirtyDate)
var month = date.getMonth()
date.setFullYear(date.getFullYear(), month + 1, 0)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = lastDayOfMonth
},{"../parse/index.js":122}],113:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Quarter Helpers
* @summary Return the last day of a year quarter for the given date.
*
* @description
* Return the last day of a year quarter for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the last day of a quarter
*
* @example
* // The last day of a quarter for 2 September 2014 11:55:00:
* var result = lastDayOfQuarter(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 00:00:00
*/
function lastDayOfQuarter (dirtyDate) {
var date = parse(dirtyDate)
var currentMonth = date.getMonth()
var month = currentMonth - currentMonth % 3 + 3
date.setMonth(month, 0)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = lastDayOfQuarter
},{"../parse/index.js":122}],114:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Week Helpers
* @summary Return the last day of a week for the given date.
*
* @description
* Return the last day of a week for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Date} the last day of a week
*
* @example
* // The last day of a week for 2 September 2014 11:55:00:
* var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sat Sep 06 2014 00:00:00
*
* @example
* // If the week starts on Monday, the last day of the week for 2 September 2014 11:55:00:
* var result = lastDayOfWeek(new Date(2014, 8, 2, 11, 55, 0), {weekStartsOn: 1})
* //=> Sun Sep 07 2014 00:00:00
*/
function lastDayOfWeek (dirtyDate, dirtyOptions) {
var weekStartsOn = dirtyOptions ? (Number(dirtyOptions.weekStartsOn) || 0) : 0
var date = parse(dirtyDate)
var day = date.getDay()
var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn)
date.setHours(0, 0, 0, 0)
date.setDate(date.getDate() + diff)
return date
}
module.exports = lastDayOfWeek
},{"../parse/index.js":122}],115:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Return the last day of a year for the given date.
*
* @description
* Return the last day of a year for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the last day of a year
*
* @example
* // The last day of a year for 2 September 2014 11:55:00:
* var result = lastDayOfYear(new Date(2014, 8, 2, 11, 55, 00))
* //=> Wed Dec 31 2014 00:00:00
*/
function lastDayOfYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
date.setFullYear(year + 1, 0, 0)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = lastDayOfYear
},{"../parse/index.js":122}],116:[function(require,module,exports){
var commonFormatterKeys = [
'M', 'MM', 'Q', 'D', 'DD', 'DDD', 'DDDD', 'd',
'E', 'W', 'WW', 'YY', 'YYYY', 'GG', 'GGGG',
'H', 'HH', 'h', 'hh', 'm', 'mm',
's', 'ss', 'S', 'SS', 'SSS',
'Z', 'ZZ', 'X', 'x'
]
function buildFormattingTokensRegExp (formatters) {
var formatterKeys = []
for (var key in formatters) {
if (formatters.hasOwnProperty(key)) {
formatterKeys.push(key)
}
}
var formattingTokens = commonFormatterKeys
.concat(formatterKeys)
.sort()
.reverse()
var formattingTokensRegExp = new RegExp(
'(\\[[^\\[]*\\])|(\\\\)?' + '(' + formattingTokens.join('|') + '|.)', 'g'
)
return formattingTokensRegExp
}
module.exports = buildFormattingTokensRegExp
},{}],117:[function(require,module,exports){
function buildDistanceInWordsLocale () {
var distanceInWordsLocale = {
lessThanXSeconds: {
one: 'less than a second',
other: 'less than {{count}} seconds'
},
xSeconds: {
one: '1 second',
other: '{{count}} seconds'
},
halfAMinute: 'half a minute',
lessThanXMinutes: {
one: 'less than a minute',
other: 'less than {{count}} minutes'
},
xMinutes: {
one: '1 minute',
other: '{{count}} minutes'
},
aboutXHours: {
one: 'about 1 hour',
other: 'about {{count}} hours'
},
xHours: {
one: '1 hour',
other: '{{count}} hours'
},
xDays: {
one: '1 day',
other: '{{count}} days'
},
aboutXMonths: {
one: 'about 1 month',
other: 'about {{count}} months'
},
xMonths: {
one: '1 month',
other: '{{count}} months'
},
aboutXYears: {
one: 'about 1 year',
other: 'about {{count}} years'
},
xYears: {
one: '1 year',
other: '{{count}} years'
},
overXYears: {
one: 'over 1 year',
other: 'over {{count}} years'
},
almostXYears: {
one: 'almost 1 year',
other: 'almost {{count}} years'
}
}
function localize (token, count, options) {
options = options || {}
var result
if (typeof distanceInWordsLocale[token] === 'string') {
result = distanceInWordsLocale[token]
} else if (count === 1) {
result = distanceInWordsLocale[token].one
} else {
result = distanceInWordsLocale[token].other.replace('{{count}}', count)
}
if (options.addSuffix) {
if (options.comparison > 0) {
return 'in ' + result
} else {
return result + ' ago'
}
}
return result
}
return {
localize: localize
}
}
module.exports = buildDistanceInWordsLocale
},{}],118:[function(require,module,exports){
var buildFormattingTokensRegExp = require('../../_lib/build_formatting_tokens_reg_exp/index.js')
function buildFormatLocale () {
// Note: in English, the names of days of the week and months are capitalized.
// If you are making a new locale based on this one, check if the same is true for the language you're working on.
// Generally, formatted dates should look like they are in the middle of a sentence,
// e.g. in Spanish language the weekdays and months should be in the lowercase.
var months3char = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
var monthsFull = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var weekdays2char = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
var weekdays3char = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
var weekdaysFull = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
var meridiemUppercase = ['AM', 'PM']
var meridiemLowercase = ['am', 'pm']
var meridiemFull = ['a.m.', 'p.m.']
var formatters = {
// Month: Jan, Feb, ..., Dec
'MMM': function (date) {
return months3char[date.getMonth()]
},
// Month: January, February, ..., December
'MMMM': function (date) {
return monthsFull[date.getMonth()]
},
// Day of week: Su, Mo, ..., Sa
'dd': function (date) {
return weekdays2char[date.getDay()]
},
// Day of week: Sun, Mon, ..., Sat
'ddd': function (date) {
return weekdays3char[date.getDay()]
},
// Day of week: Sunday, Monday, ..., Saturday
'dddd': function (date) {
return weekdaysFull[date.getDay()]
},
// AM, PM
'A': function (date) {
return (date.getHours() / 12) >= 1 ? meridiemUppercase[1] : meridiemUppercase[0]
},
// am, pm
'a': function (date) {
return (date.getHours() / 12) >= 1 ? meridiemLowercase[1] : meridiemLowercase[0]
},
// a.m., p.m.
'aa': function (date) {
return (date.getHours() / 12) >= 1 ? meridiemFull[1] : meridiemFull[0]
}
}
// Generate ordinal version of formatters: M -> Mo, D -> Do, etc.
var ordinalFormatters = ['M', 'D', 'DDD', 'd', 'Q', 'W']
ordinalFormatters.forEach(function (formatterToken) {
formatters[formatterToken + 'o'] = function (date, formatters) {
return ordinal(formatters[formatterToken](date))
}
})
return {
formatters: formatters,
formattingTokensRegExp: buildFormattingTokensRegExp(formatters)
}
}
function ordinal (number) {
var rem100 = number % 100
if (rem100 > 20 || rem100 < 10) {
switch (rem100 % 10) {
case 1:
return number + 'st'
case 2:
return number + 'nd'
case 3:
return number + 'rd'
}
}
return number + 'th'
}
module.exports = buildFormatLocale
},{"../../_lib/build_formatting_tokens_reg_exp/index.js":116}],119:[function(require,module,exports){
var buildDistanceInWordsLocale = require('./build_distance_in_words_locale/index.js')
var buildFormatLocale = require('./build_format_locale/index.js')
/**
* @category Locales
* @summary English locale.
*/
module.exports = {
distanceInWords: buildDistanceInWordsLocale(),
format: buildFormatLocale()
}
},{"./build_distance_in_words_locale/index.js":117,"./build_format_locale/index.js":118}],120:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Return the latest of the given dates.
*
* @description
* Return the latest of the given dates.
*
* @param {...(Date|String|Number)} dates - the dates to compare
* @returns {Date} the latest of the dates
*
* @example
* // Which of these dates is the latest?
* var result = max(
* new Date(1989, 6, 10),
* new Date(1987, 1, 11),
* new Date(1995, 6, 2),
* new Date(1990, 0, 1)
* )
* //=> Sun Jul 02 1995 00:00:00
*/
function max () {
var dirtyDates = Array.prototype.slice.call(arguments)
var dates = dirtyDates.map(function (dirtyDate) {
return parse(dirtyDate)
})
var latestTimestamp = Math.max.apply(null, dates)
return new Date(latestTimestamp)
}
module.exports = max
},{"../parse/index.js":122}],121:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Common Helpers
* @summary Return the earliest of the given dates.
*
* @description
* Return the earliest of the given dates.
*
* @param {...(Date|String|Number)} dates - the dates to compare
* @returns {Date} the earliest of the dates
*
* @example
* // Which of these dates is the earliest?
* var result = min(
* new Date(1989, 6, 10),
* new Date(1987, 1, 11),
* new Date(1995, 6, 2),
* new Date(1990, 0, 1)
* )
* //=> Wed Feb 11 1987 00:00:00
*/
function min () {
var dirtyDates = Array.prototype.slice.call(arguments)
var dates = dirtyDates.map(function (dirtyDate) {
return parse(dirtyDate)
})
var earliestTimestamp = Math.min.apply(null, dates)
return new Date(earliestTimestamp)
}
module.exports = min
},{"../parse/index.js":122}],122:[function(require,module,exports){
var isDate = require('../is_date/index.js')
var MILLISECONDS_IN_HOUR = 3600000
var MILLISECONDS_IN_MINUTE = 60000
var DEFAULT_ADDITIONAL_DIGITS = 2
var parseTokenDateTimeDelimeter = /[T ]/
var parseTokenPlainTime = /:/
// year tokens
var parseTokenYY = /^(\d{2})$/
var parseTokensYYY = [
/^([+-]\d{2})$/, // 0 additional digits
/^([+-]\d{3})$/, // 1 additional digit
/^([+-]\d{4})$/ // 2 additional digits
]
var parseTokenYYYY = /^(\d{4})/
var parseTokensYYYYY = [
/^([+-]\d{4})/, // 0 additional digits
/^([+-]\d{5})/, // 1 additional digit
/^([+-]\d{6})/ // 2 additional digits
]
// date tokens
var parseTokenMM = /^-(\d{2})$/
var parseTokenDDD = /^-?(\d{3})$/
var parseTokenMMDD = /^-?(\d{2})-?(\d{2})$/
var parseTokenWww = /^-?W(\d{2})$/
var parseTokenWwwD = /^-?W(\d{2})-?(\d{1})$/
// time tokens
var parseTokenHH = /^(\d{2}([.,]\d*)?)$/
var parseTokenHHMM = /^(\d{2}):?(\d{2}([.,]\d*)?)$/
var parseTokenHHMMSS = /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/
// timezone tokens
var parseTokenTimezone = /([Z+-].*)$/
var parseTokenTimezoneZ = /^(Z)$/
var parseTokenTimezoneHH = /^([+-])(\d{2})$/
var parseTokenTimezoneHHMM = /^([+-])(\d{2}):?(\d{2})$/
/**
* @category Common Helpers
* @summary Convert the given argument to an instance of Date.
*
* @description
* Convert the given argument to an instance of Date.
*
* If the argument is an instance of Date, the function returns its clone.
*
* If the argument is a number, it is treated as a timestamp.
*
* If an argument is a string, the function tries to parse it.
* Function accepts complete ISO 8601 formats as well as partial implementations.
* ISO 8601: http://en.wikipedia.org/wiki/ISO_8601
*
* If all above fails, the function passes the given argument to Date constructor.
*
* @param {Date|String|Number} argument - the value to convert
* @param {Object} [options] - the object with options
* @param {0 | 1 | 2} [options.additionalDigits=2] - the additional number of digits in the extended year format
* @returns {Date} the parsed date in the local time zone
*
* @example
* // Convert string '2014-02-11T11:30:30' to date:
* var result = parse('2014-02-11T11:30:30')
* //=> Tue Feb 11 2014 11:30:30
*
* @example
* // Parse string '+02014101',
* // if the additional number of digits in the extended year format is 1:
* var result = parse('+02014101', {additionalDigits: 1})
* //=> Fri Apr 11 2014 00:00:00
*/
function parse (argument, dirtyOptions) {
if (isDate(argument)) {
// Prevent the date to lose the milliseconds when passed to new Date() in IE10
return new Date(argument.getTime())
} else if (typeof argument !== 'string') {
return new Date(argument)
}
var options = dirtyOptions || {}
var additionalDigits = options.additionalDigits
if (additionalDigits == null) {
additionalDigits = DEFAULT_ADDITIONAL_DIGITS
} else {
additionalDigits = Number(additionalDigits)
}
var dateStrings = splitDateString(argument)
var parseYearResult = parseYear(dateStrings.date, additionalDigits)
var year = parseYearResult.year
var restDateString = parseYearResult.restDateString
var date = parseDate(restDateString, year)
if (date) {
var timestamp = date.getTime()
var time = 0
var offset
if (dateStrings.time) {
time = parseTime(dateStrings.time)
}
if (dateStrings.timezone) {
offset = parseTimezone(dateStrings.timezone)
} else {
// get offset accurate to hour in timezones that change offset
offset = new Date(timestamp + time).getTimezoneOffset()
offset = new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE).getTimezoneOffset()
}
return new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE)
} else {
return new Date(argument)
}
}
function splitDateString (dateString) {
var dateStrings = {}
var array = dateString.split(parseTokenDateTimeDelimeter)
var timeString
if (parseTokenPlainTime.test(array[0])) {
dateStrings.date = null
timeString = array[0]
} else {
dateStrings.date = array[0]
timeString = array[1]
}
if (timeString) {
var token = parseTokenTimezone.exec(timeString)
if (token) {
dateStrings.time = timeString.replace(token[1], '')
dateStrings.timezone = token[1]
} else {
dateStrings.time = timeString
}
}
return dateStrings
}
function parseYear (dateString, additionalDigits) {
var parseTokenYYY = parseTokensYYY[additionalDigits]
var parseTokenYYYYY = parseTokensYYYYY[additionalDigits]
var token
// YYYY or ±YYYYY
token = parseTokenYYYY.exec(dateString) || parseTokenYYYYY.exec(dateString)
if (token) {
var yearString = token[1]
return {
year: parseInt(yearString, 10),
restDateString: dateString.slice(yearString.length)
}
}
// YY or ±YYY
token = parseTokenYY.exec(dateString) || parseTokenYYY.exec(dateString)
if (token) {
var centuryString = token[1]
return {
year: parseInt(centuryString, 10) * 100,
restDateString: dateString.slice(centuryString.length)
}
}
// Invalid ISO-formatted year
return {
year: null
}
}
function parseDate (dateString, year) {
// Invalid ISO-formatted year
if (year === null) {
return null
}
var token
var date
var month
var week
// YYYY
if (dateString.length === 0) {
date = new Date(0)
date.setUTCFullYear(year)
return date
}
// YYYY-MM
token = parseTokenMM.exec(dateString)
if (token) {
date = new Date(0)
month = parseInt(token[1], 10) - 1
date.setUTCFullYear(year, month)
return date
}
// YYYY-DDD or YYYYDDD
token = parseTokenDDD.exec(dateString)
if (token) {
date = new Date(0)
var dayOfYear = parseInt(token[1], 10)
date.setUTCFullYear(year, 0, dayOfYear)
return date
}
// YYYY-MM-DD or YYYYMMDD
token = parseTokenMMDD.exec(dateString)
if (token) {
date = new Date(0)
month = parseInt(token[1], 10) - 1
var day = parseInt(token[2], 10)
date.setUTCFullYear(year, month, day)
return date
}
// YYYY-Www or YYYYWww
token = parseTokenWww.exec(dateString)
if (token) {
week = parseInt(token[1], 10) - 1
return dayOfISOYear(year, week)
}
// YYYY-Www-D or YYYYWwwD
token = parseTokenWwwD.exec(dateString)
if (token) {
week = parseInt(token[1], 10) - 1
var dayOfWeek = parseInt(token[2], 10) - 1
return dayOfISOYear(year, week, dayOfWeek)
}
// Invalid ISO-formatted date
return null
}
function parseTime (timeString) {
var token
var hours
var minutes
// hh
token = parseTokenHH.exec(timeString)
if (token) {
hours = parseFloat(token[1].replace(',', '.'))
return (hours % 24) * MILLISECONDS_IN_HOUR
}
// hh:mm or hhmm
token = parseTokenHHMM.exec(timeString)
if (token) {
hours = parseInt(token[1], 10)
minutes = parseFloat(token[2].replace(',', '.'))
return (hours % 24) * MILLISECONDS_IN_HOUR +
minutes * MILLISECONDS_IN_MINUTE
}
// hh:mm:ss or hhmmss
token = parseTokenHHMMSS.exec(timeString)
if (token) {
hours = parseInt(token[1], 10)
minutes = parseInt(token[2], 10)
var seconds = parseFloat(token[3].replace(',', '.'))
return (hours % 24) * MILLISECONDS_IN_HOUR +
minutes * MILLISECONDS_IN_MINUTE +
seconds * 1000
}
// Invalid ISO-formatted time
return null
}
function parseTimezone (timezoneString) {
var token
var absoluteOffset
// Z
token = parseTokenTimezoneZ.exec(timezoneString)
if (token) {
return 0
}
// ±hh
token = parseTokenTimezoneHH.exec(timezoneString)
if (token) {
absoluteOffset = parseInt(token[2], 10) * 60
return (token[1] === '+') ? -absoluteOffset : absoluteOffset
}
// ±hh:mm or ±hhmm
token = parseTokenTimezoneHHMM.exec(timezoneString)
if (token) {
absoluteOffset = parseInt(token[2], 10) * 60 + parseInt(token[3], 10)
return (token[1] === '+') ? -absoluteOffset : absoluteOffset
}
return 0
}
function dayOfISOYear (isoYear, week, day) {
week = week || 0
day = day || 0
var date = new Date(0)
date.setUTCFullYear(isoYear, 0, 4)
var fourthOfJanuaryDay = date.getUTCDay() || 7
var diff = week * 7 + day + 1 - fourthOfJanuaryDay
date.setUTCDate(date.getUTCDate() + diff)
return date
}
module.exports = parse
},{"../is_date/index.js":71}],123:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Set the day of the month to the given date.
*
* @description
* Set the day of the month to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} dayOfMonth - the day of the month of the new date
* @returns {Date} the new date with the day of the month setted
*
* @example
* // Set the 30th day of the month to 1 September 2014:
* var result = setDate(new Date(2014, 8, 1), 30)
* //=> Tue Sep 30 2014 00:00:00
*/
function setDate (dirtyDate, dirtyDayOfMonth) {
var date = parse(dirtyDate)
var dayOfMonth = Number(dirtyDayOfMonth)
date.setDate(dayOfMonth)
return date
}
module.exports = setDate
},{"../parse/index.js":122}],124:[function(require,module,exports){
var parse = require('../parse/index.js')
var addDays = require('../add_days/index.js')
/**
* @category Weekday Helpers
* @summary Set the day of the week to the given date.
*
* @description
* Set the day of the week to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} day - the day of the week of the new date
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Date} the new date with the day of the week setted
*
* @example
* // Set Sunday to 1 September 2014:
* var result = setDay(new Date(2014, 8, 1), 0)
* //=> Sun Aug 31 2014 00:00:00
*
* @example
* // If week starts with Monday, set Sunday to 1 September 2014:
* var result = setDay(new Date(2014, 8, 1), 0, {weekStartsOn: 1})
* //=> Sun Sep 07 2014 00:00:00
*/
function setDay (dirtyDate, dirtyDay, dirtyOptions) {
var weekStartsOn = dirtyOptions ? (Number(dirtyOptions.weekStartsOn) || 0) : 0
var date = parse(dirtyDate)
var day = Number(dirtyDay)
var currentDay = date.getDay()
var remainder = day % 7
var dayIndex = (remainder + 7) % 7
var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay
return addDays(date, diff)
}
module.exports = setDay
},{"../add_days/index.js":1,"../parse/index.js":122}],125:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Set the day of the year to the given date.
*
* @description
* Set the day of the year to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} dayOfYear - the day of the year of the new date
* @returns {Date} the new date with the day of the year setted
*
* @example
* // Set the 2nd day of the year to 2 July 2014:
* var result = setDayOfYear(new Date(2014, 6, 2), 2)
* //=> Thu Jan 02 2014 00:00:00
*/
function setDayOfYear (dirtyDate, dirtyDayOfYear) {
var date = parse(dirtyDate)
var dayOfYear = Number(dirtyDayOfYear)
date.setMonth(0)
date.setDate(dayOfYear)
return date
}
module.exports = setDayOfYear
},{"../parse/index.js":122}],126:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Hour Helpers
* @summary Set the hours to the given date.
*
* @description
* Set the hours to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} hours - the hours of the new date
* @returns {Date} the new date with the hours setted
*
* @example
* // Set 4 hours to 1 September 2014 11:30:00:
* var result = setHours(new Date(2014, 8, 1, 11, 30), 4)
* //=> Mon Sep 01 2014 04:30:00
*/
function setHours (dirtyDate, dirtyHours) {
var date = parse(dirtyDate)
var hours = Number(dirtyHours)
date.setHours(hours)
return date
}
module.exports = setHours
},{"../parse/index.js":122}],127:[function(require,module,exports){
var parse = require('../parse/index.js')
var addDays = require('../add_days/index.js')
var getISODay = require('../get_iso_day/index.js')
/**
* @category Weekday Helpers
* @summary Set the day of the ISO week to the given date.
*
* @description
* Set the day of the ISO week to the given date.
* ISO week starts with Monday.
* 7 is the index of Sunday, 1 is the index of Monday etc.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} day - the day of the ISO week of the new date
* @returns {Date} the new date with the day of the ISO week setted
*
* @example
* // Set Sunday to 1 September 2014:
* var result = setISODay(new Date(2014, 8, 1), 7)
* //=> Sun Sep 07 2014 00:00:00
*/
function setISODay (dirtyDate, dirtyDay) {
var date = parse(dirtyDate)
var day = Number(dirtyDay)
var currentDay = getISODay(date)
var diff = day - currentDay
return addDays(date, diff)
}
module.exports = setISODay
},{"../add_days/index.js":1,"../get_iso_day/index.js":57,"../parse/index.js":122}],128:[function(require,module,exports){
var parse = require('../parse/index.js')
var getISOWeek = require('../get_iso_week/index.js')
/**
* @category ISO Week Helpers
* @summary Set the ISO week to the given date.
*
* @description
* Set the ISO week to the given date, saving the weekday number.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} isoWeek - the ISO week of the new date
* @returns {Date} the new date with the ISO week setted
*
* @example
* // Set the 53rd ISO week to 7 August 2004:
* var result = setISOWeek(new Date(2004, 7, 7), 53)
* //=> Sat Jan 01 2005 00:00:00
*/
function setISOWeek (dirtyDate, dirtyISOWeek) {
var date = parse(dirtyDate)
var isoWeek = Number(dirtyISOWeek)
var diff = getISOWeek(date) - isoWeek
date.setDate(date.getDate() - diff * 7)
return date
}
module.exports = setISOWeek
},{"../get_iso_week/index.js":58,"../parse/index.js":122}],129:[function(require,module,exports){
var parse = require('../parse/index.js')
var startOfISOYear = require('../start_of_iso_year/index.js')
var differenceInCalendarDays = require('../difference_in_calendar_days/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Set the ISO week-numbering year to the given date.
*
* @description
* Set the ISO week-numbering year to the given date,
* saving the week number and the weekday number.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} isoYear - the ISO week-numbering year of the new date
* @returns {Date} the new date with the ISO week-numbering year setted
*
* @example
* // Set ISO week-numbering year 2007 to 29 December 2008:
* var result = setISOYear(new Date(2008, 11, 29), 2007)
* //=> Mon Jan 01 2007 00:00:00
*/
function setISOYear (dirtyDate, dirtyISOYear) {
var date = parse(dirtyDate)
var isoYear = Number(dirtyISOYear)
var diff = differenceInCalendarDays(date, startOfISOYear(date))
var fourthOfJanuary = new Date(0)
fourthOfJanuary.setFullYear(isoYear, 0, 4)
fourthOfJanuary.setHours(0, 0, 0, 0)
date = startOfISOYear(fourthOfJanuary)
date.setDate(date.getDate() + diff)
return date
}
module.exports = setISOYear
},{"../difference_in_calendar_days/index.js":16,"../parse/index.js":122,"../start_of_iso_year/index.js":139}],130:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Millisecond Helpers
* @summary Set the milliseconds to the given date.
*
* @description
* Set the milliseconds to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} milliseconds - the milliseconds of the new date
* @returns {Date} the new date with the milliseconds setted
*
* @example
* // Set 300 milliseconds to 1 September 2014 11:30:40.500:
* var result = setMilliseconds(new Date(2014, 8, 1, 11, 30, 40, 500), 300)
* //=> Mon Sep 01 2014 11:30:40.300
*/
function setMilliseconds (dirtyDate, dirtyMilliseconds) {
var date = parse(dirtyDate)
var milliseconds = Number(dirtyMilliseconds)
date.setMilliseconds(milliseconds)
return date
}
module.exports = setMilliseconds
},{"../parse/index.js":122}],131:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Minute Helpers
* @summary Set the minutes to the given date.
*
* @description
* Set the minutes to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} minutes - the minutes of the new date
* @returns {Date} the new date with the minutes setted
*
* @example
* // Set 45 minutes to 1 September 2014 11:30:40:
* var result = setMinutes(new Date(2014, 8, 1, 11, 30, 40), 45)
* //=> Mon Sep 01 2014 11:45:40
*/
function setMinutes (dirtyDate, dirtyMinutes) {
var date = parse(dirtyDate)
var minutes = Number(dirtyMinutes)
date.setMinutes(minutes)
return date
}
module.exports = setMinutes
},{"../parse/index.js":122}],132:[function(require,module,exports){
var parse = require('../parse/index.js')
var getDaysInMonth = require('../get_days_in_month/index.js')
/**
* @category Month Helpers
* @summary Set the month to the given date.
*
* @description
* Set the month to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} month - the month of the new date
* @returns {Date} the new date with the month setted
*
* @example
* // Set February to 1 September 2014:
* var result = setMonth(new Date(2014, 8, 1), 1)
* //=> Sat Feb 01 2014 00:00:00
*/
function setMonth (dirtyDate, dirtyMonth) {
var date = parse(dirtyDate)
var month = Number(dirtyMonth)
var year = date.getFullYear()
var day = date.getDate()
var dateWithDesiredMonth = new Date(0)
dateWithDesiredMonth.setFullYear(year, month, 15)
dateWithDesiredMonth.setHours(0, 0, 0, 0)
var daysInMonth = getDaysInMonth(dateWithDesiredMonth)
// Set the last day of the new month
// if the original date was the last day of the longer month
date.setMonth(month, Math.min(day, daysInMonth))
return date
}
module.exports = setMonth
},{"../get_days_in_month/index.js":54,"../parse/index.js":122}],133:[function(require,module,exports){
var parse = require('../parse/index.js')
var setMonth = require('../set_month/index.js')
/**
* @category Quarter Helpers
* @summary Set the year quarter to the given date.
*
* @description
* Set the year quarter to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} quarter - the quarter of the new date
* @returns {Date} the new date with the quarter setted
*
* @example
* // Set the 2nd quarter to 2 July 2014:
* var result = setQuarter(new Date(2014, 6, 2), 2)
* //=> Wed Apr 02 2014 00:00:00
*/
function setQuarter (dirtyDate, dirtyQuarter) {
var date = parse(dirtyDate)
var quarter = Number(dirtyQuarter)
var oldQuarter = Math.floor(date.getMonth() / 3) + 1
var diff = quarter - oldQuarter
return setMonth(date, date.getMonth() + diff * 3)
}
module.exports = setQuarter
},{"../parse/index.js":122,"../set_month/index.js":132}],134:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Second Helpers
* @summary Set the seconds to the given date.
*
* @description
* Set the seconds to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} seconds - the seconds of the new date
* @returns {Date} the new date with the seconds setted
*
* @example
* // Set 45 seconds to 1 September 2014 11:30:40:
* var result = setSeconds(new Date(2014, 8, 1, 11, 30, 40), 45)
* //=> Mon Sep 01 2014 11:30:45
*/
function setSeconds (dirtyDate, dirtySeconds) {
var date = parse(dirtyDate)
var seconds = Number(dirtySeconds)
date.setSeconds(seconds)
return date
}
module.exports = setSeconds
},{"../parse/index.js":122}],135:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Set the year to the given date.
*
* @description
* Set the year to the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} year - the year of the new date
* @returns {Date} the new date with the year setted
*
* @example
* // Set year 2013 to 1 September 2014:
* var result = setYear(new Date(2014, 8, 1), 2013)
* //=> Sun Sep 01 2013 00:00:00
*/
function setYear (dirtyDate, dirtyYear) {
var date = parse(dirtyDate)
var year = Number(dirtyYear)
date.setFullYear(year)
return date
}
module.exports = setYear
},{"../parse/index.js":122}],136:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Day Helpers
* @summary Return the start of a day for the given date.
*
* @description
* Return the start of a day for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a day
*
* @example
* // The start of a day for 2 September 2014 11:55:00:
* var result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 02 2014 00:00:00
*/
function startOfDay (dirtyDate) {
var date = parse(dirtyDate)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfDay
},{"../parse/index.js":122}],137:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Hour Helpers
* @summary Return the start of an hour for the given date.
*
* @description
* Return the start of an hour for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of an hour
*
* @example
* // The start of an hour for 2 September 2014 11:55:00:
* var result = startOfHour(new Date(2014, 8, 2, 11, 55))
* //=> Tue Sep 02 2014 11:00:00
*/
function startOfHour (dirtyDate) {
var date = parse(dirtyDate)
date.setMinutes(0, 0, 0)
return date
}
module.exports = startOfHour
},{"../parse/index.js":122}],138:[function(require,module,exports){
var startOfWeek = require('../start_of_week/index.js')
/**
* @category ISO Week Helpers
* @summary Return the start of an ISO week for the given date.
*
* @description
* Return the start of an ISO week for the given date.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of an ISO week
*
* @example
* // The start of an ISO week for 2 September 2014 11:55:00:
* var result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfISOWeek (dirtyDate) {
return startOfWeek(dirtyDate, {weekStartsOn: 1})
}
module.exports = startOfISOWeek
},{"../start_of_week/index.js":146}],139:[function(require,module,exports){
var getISOYear = require('../get_iso_year/index.js')
var startOfISOWeek = require('../start_of_iso_week/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Return the start of an ISO week-numbering year for the given date.
*
* @description
* Return the start of an ISO week-numbering year,
* which always starts 3 days before the year's first Thursday.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of an ISO year
*
* @example
* // The start of an ISO week-numbering year for 2 July 2005:
* var result = startOfISOYear(new Date(2005, 6, 2))
* //=> Mon Jan 03 2005 00:00:00
*/
function startOfISOYear (dirtyDate) {
var year = getISOYear(dirtyDate)
var fourthOfJanuary = new Date(0)
fourthOfJanuary.setFullYear(year, 0, 4)
fourthOfJanuary.setHours(0, 0, 0, 0)
var date = startOfISOWeek(fourthOfJanuary)
return date
}
module.exports = startOfISOYear
},{"../get_iso_year/index.js":60,"../start_of_iso_week/index.js":138}],140:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Minute Helpers
* @summary Return the start of a minute for the given date.
*
* @description
* Return the start of a minute for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a minute
*
* @example
* // The start of a minute for 1 December 2014 22:15:45.400:
* var result = startOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))
* //=> Mon Dec 01 2014 22:15:00
*/
function startOfMinute (dirtyDate) {
var date = parse(dirtyDate)
date.setSeconds(0, 0)
return date
}
module.exports = startOfMinute
},{"../parse/index.js":122}],141:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Month Helpers
* @summary Return the start of a month for the given date.
*
* @description
* Return the start of a month for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a month
*
* @example
* // The start of a month for 2 September 2014 11:55:00:
* var result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfMonth (dirtyDate) {
var date = parse(dirtyDate)
date.setDate(1)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfMonth
},{"../parse/index.js":122}],142:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Quarter Helpers
* @summary Return the start of a year quarter for the given date.
*
* @description
* Return the start of a year quarter for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a quarter
*
* @example
* // The start of a quarter for 2 September 2014 11:55:00:
* var result = startOfQuarter(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Jul 01 2014 00:00:00
*/
function startOfQuarter (dirtyDate) {
var date = parse(dirtyDate)
var currentMonth = date.getMonth()
var month = currentMonth - currentMonth % 3
date.setMonth(month, 1)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfQuarter
},{"../parse/index.js":122}],143:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Second Helpers
* @summary Return the start of a second for the given date.
*
* @description
* Return the start of a second for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a second
*
* @example
* // The start of a second for 1 December 2014 22:15:45.400:
* var result = startOfSecond(new Date(2014, 11, 1, 22, 15, 45, 400))
* //=> Mon Dec 01 2014 22:15:45.000
*/
function startOfSecond (dirtyDate) {
var date = parse(dirtyDate)
date.setMilliseconds(0)
return date
}
module.exports = startOfSecond
},{"../parse/index.js":122}],144:[function(require,module,exports){
var startOfDay = require('../start_of_day/index.js')
/**
* @category Day Helpers
* @summary Return the start of today.
*
* @description
* Return the start of today.
*
* @returns {Date} the start of today
*
* @example
* // If today is 6 October 2014:
* var result = startOfToday()
* //=> Mon Oct 6 2014 00:00:00
*/
function startOfToday () {
return startOfDay(new Date())
}
module.exports = startOfToday
},{"../start_of_day/index.js":136}],145:[function(require,module,exports){
/**
* @category Day Helpers
* @summary Return the start of tomorrow.
*
* @description
* Return the start of tomorrow.
*
* @returns {Date} the start of tomorrow
*
* @example
* // If today is 6 October 2014:
* var result = startOfTomorrow()
* //=> Tue Oct 7 2014 00:00:00
*/
function startOfTomorrow () {
var now = new Date()
var year = now.getFullYear()
var month = now.getMonth()
var day = now.getDate()
var date = new Date(0)
date.setFullYear(year, month, day + 1)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfTomorrow
},{}],146:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Week Helpers
* @summary Return the start of a week for the given date.
*
* @description
* Return the start of a week for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @param {Object} [options] - the object with options
* @param {Number} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
* @returns {Date} the start of a week
*
* @example
* // The start of a week for 2 September 2014 11:55:00:
* var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sun Aug 31 2014 00:00:00
*
* @example
* // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
* var result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), {weekStartsOn: 1})
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfWeek (dirtyDate, dirtyOptions) {
var weekStartsOn = dirtyOptions ? (Number(dirtyOptions.weekStartsOn) || 0) : 0
var date = parse(dirtyDate)
var day = date.getDay()
var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn
date.setDate(date.getDate() - diff)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfWeek
},{"../parse/index.js":122}],147:[function(require,module,exports){
var parse = require('../parse/index.js')
/**
* @category Year Helpers
* @summary Return the start of a year for the given date.
*
* @description
* Return the start of a year for the given date.
* The result will be in the local timezone.
*
* @param {Date|String|Number} date - the original date
* @returns {Date} the start of a year
*
* @example
* // The start of a year for 2 September 2014 11:55:00:
* var result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))
* //=> Wed Jan 01 2014 00:00:00
*/
function startOfYear (dirtyDate) {
var cleanDate = parse(dirtyDate)
var date = new Date(0)
date.setFullYear(cleanDate.getFullYear(), 0, 1)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfYear
},{"../parse/index.js":122}],148:[function(require,module,exports){
/**
* @category Day Helpers
* @summary Return the start of yesterday.
*
* @description
* Return the start of yesterday.
*
* @returns {Date} the start of yesterday
*
* @example
* // If today is 6 October 2014:
* var result = startOfYesterday()
* //=> Sun Oct 5 2014 00:00:00
*/
function startOfYesterday () {
var now = new Date()
var year = now.getFullYear()
var month = now.getMonth()
var day = now.getDate()
var date = new Date(0)
date.setFullYear(year, month, day - 1)
date.setHours(0, 0, 0, 0)
return date
}
module.exports = startOfYesterday
},{}],149:[function(require,module,exports){
var addDays = require('../add_days/index.js')
/**
* @category Day Helpers
* @summary Subtract the specified number of days from the given date.
*
* @description
* Subtract the specified number of days from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of days to be subtracted
* @returns {Date} the new date with the days subtracted
*
* @example
* // Subtract 10 days from 1 September 2014:
* var result = subDays(new Date(2014, 8, 1), 10)
* //=> Fri Aug 22 2014 00:00:00
*/
function subDays (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addDays(dirtyDate, -amount)
}
module.exports = subDays
},{"../add_days/index.js":1}],150:[function(require,module,exports){
var addHours = require('../add_hours/index.js')
/**
* @category Hour Helpers
* @summary Subtract the specified number of hours from the given date.
*
* @description
* Subtract the specified number of hours from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of hours to be subtracted
* @returns {Date} the new date with the hours subtracted
*
* @example
* // Subtract 2 hours from 11 July 2014 01:00:00:
* var result = subHours(new Date(2014, 6, 11, 1, 0), 2)
* //=> Thu Jul 10 2014 23:00:00
*/
function subHours (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addHours(dirtyDate, -amount)
}
module.exports = subHours
},{"../add_hours/index.js":2}],151:[function(require,module,exports){
var addISOYears = require('../add_iso_years/index.js')
/**
* @category ISO Week-Numbering Year Helpers
* @summary Subtract the specified number of ISO week-numbering years from the given date.
*
* @description
* Subtract the specified number of ISO week-numbering years from the given date.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of ISO week-numbering years to be subtracted
* @returns {Date} the new date with the ISO week-numbering years subtracted
*
* @example
* // Subtract 5 ISO week-numbering years from 1 September 2014:
* var result = subISOYears(new Date(2014, 8, 1), 5)
* //=> Mon Aug 31 2009 00:00:00
*/
function subISOYears (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addISOYears(dirtyDate, -amount)
}
module.exports = subISOYears
},{"../add_iso_years/index.js":3}],152:[function(require,module,exports){
var addMilliseconds = require('../add_milliseconds/index.js')
/**
* @category Millisecond Helpers
* @summary Subtract the specified number of milliseconds from the given date.
*
* @description
* Subtract the specified number of milliseconds from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of milliseconds to be subtracted
* @returns {Date} the new date with the milliseconds subtracted
*
* @example
* // Subtract 750 milliseconds from 10 July 2014 12:45:30.000:
* var result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750)
* //=> Thu Jul 10 2014 12:45:29.250
*/
function subMilliseconds (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMilliseconds(dirtyDate, -amount)
}
module.exports = subMilliseconds
},{"../add_milliseconds/index.js":4}],153:[function(require,module,exports){
var addMinutes = require('../add_minutes/index.js')
/**
* @category Minute Helpers
* @summary Subtract the specified number of minutes from the given date.
*
* @description
* Subtract the specified number of minutes from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of minutes to be subtracted
* @returns {Date} the new date with the mintues subtracted
*
* @example
* // Subtract 30 minutes from 10 July 2014 12:00:00:
* var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30)
* //=> Thu Jul 10 2014 11:30:00
*/
function subMinutes (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMinutes(dirtyDate, -amount)
}
module.exports = subMinutes
},{"../add_minutes/index.js":5}],154:[function(require,module,exports){
var addMonths = require('../add_months/index.js')
/**
* @category Month Helpers
* @summary Subtract the specified number of months from the given date.
*
* @description
* Subtract the specified number of months from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of months to be subtracted
* @returns {Date} the new date with the months subtracted
*
* @example
* // Subtract 5 months from 1 February 2015:
* var result = subMonths(new Date(2015, 1, 1), 5)
* //=> Mon Sep 01 2014 00:00:00
*/
function subMonths (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addMonths(dirtyDate, -amount)
}
module.exports = subMonths
},{"../add_months/index.js":6}],155:[function(require,module,exports){
var addQuarters = require('../add_quarters/index.js')
/**
* @category Quarter Helpers
* @summary Subtract the specified number of year quarters from the given date.
*
* @description
* Subtract the specified number of year quarters from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of quarters to be subtracted
* @returns {Date} the new date with the quarters subtracted
*
* @example
* // Subtract 3 quarters from 1 September 2014:
* var result = subQuarters(new Date(2014, 8, 1), 3)
* //=> Sun Dec 01 2013 00:00:00
*/
function subQuarters (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addQuarters(dirtyDate, -amount)
}
module.exports = subQuarters
},{"../add_quarters/index.js":7}],156:[function(require,module,exports){
var addSeconds = require('../add_seconds/index.js')
/**
* @category Second Helpers
* @summary Subtract the specified number of seconds from the given date.
*
* @description
* Subtract the specified number of seconds from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of seconds to be subtracted
* @returns {Date} the new date with the seconds subtracted
*
* @example
* // Subtract 30 seconds from 10 July 2014 12:45:00:
* var result = subSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)
* //=> Thu Jul 10 2014 12:44:30
*/
function subSeconds (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addSeconds(dirtyDate, -amount)
}
module.exports = subSeconds
},{"../add_seconds/index.js":8}],157:[function(require,module,exports){
var addWeeks = require('../add_weeks/index.js')
/**
* @category Week Helpers
* @summary Subtract the specified number of weeks from the given date.
*
* @description
* Subtract the specified number of weeks from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of weeks to be subtracted
* @returns {Date} the new date with the weeks subtracted
*
* @example
* // Subtract 4 weeks from 1 September 2014:
* var result = subWeeks(new Date(2014, 8, 1), 4)
* //=> Mon Aug 04 2014 00:00:00
*/
function subWeeks (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addWeeks(dirtyDate, -amount)
}
module.exports = subWeeks
},{"../add_weeks/index.js":9}],158:[function(require,module,exports){
var addYears = require('../add_years/index.js')
/**
* @category Year Helpers
* @summary Subtract the specified number of years from the given date.
*
* @description
* Subtract the specified number of years from the given date.
*
* @param {Date|String|Number} date - the date to be changed
* @param {Number} amount - the amount of years to be subtracted
* @returns {Date} the new date with the years subtracted
*
* @example
* // Subtract 5 years from 1 September 2014:
* var result = subYears(new Date(2014, 8, 1), 5)
* //=> Tue Sep 01 2009 00:00:00
*/
function subYears (dirtyDate, dirtyAmount) {
var amount = Number(dirtyAmount)
return addYears(dirtyDate, -amount)
}
module.exports = subYears
},{"../add_years/index.js":10}],"date-fns":[function(require,module,exports){
module.exports = {
addDays: require('./add_days/index.js'),
addHours: require('./add_hours/index.js'),
addISOYears: require('./add_iso_years/index.js'),
addMilliseconds: require('./add_milliseconds/index.js'),
addMinutes: require('./add_minutes/index.js'),
addMonths: require('./add_months/index.js'),
addQuarters: require('./add_quarters/index.js'),
addSeconds: require('./add_seconds/index.js'),
addWeeks: require('./add_weeks/index.js'),
addYears: require('./add_years/index.js'),
areRangesOverlapping: require('./are_ranges_overlapping/index.js'),
closestIndexTo: require('./closest_index_to/index.js'),
closestTo: require('./closest_to/index.js'),
compareAsc: require('./compare_asc/index.js'),
compareDesc: require('./compare_desc/index.js'),
differenceInCalendarDays: require('./difference_in_calendar_days/index.js'),
differenceInCalendarISOWeeks: require('./difference_in_calendar_iso_weeks/index.js'),
differenceInCalendarISOYears: require('./difference_in_calendar_iso_years/index.js'),
differenceInCalendarMonths: require('./difference_in_calendar_months/index.js'),
differenceInCalendarQuarters: require('./difference_in_calendar_quarters/index.js'),
differenceInCalendarWeeks: require('./difference_in_calendar_weeks/index.js'),
differenceInCalendarYears: require('./difference_in_calendar_years/index.js'),
differenceInDays: require('./difference_in_days/index.js'),
differenceInHours: require('./difference_in_hours/index.js'),
differenceInISOYears: require('./difference_in_iso_years/index.js'),
differenceInMilliseconds: require('./difference_in_milliseconds/index.js'),
differenceInMinutes: require('./difference_in_minutes/index.js'),
differenceInMonths: require('./difference_in_months/index.js'),
differenceInQuarters: require('./difference_in_quarters/index.js'),
differenceInSeconds: require('./difference_in_seconds/index.js'),
differenceInWeeks: require('./difference_in_weeks/index.js'),
differenceInYears: require('./difference_in_years/index.js'),
distanceInWords: require('./distance_in_words/index.js'),
distanceInWordsStrict: require('./distance_in_words_strict/index.js'),
distanceInWordsToNow: require('./distance_in_words_to_now/index.js'),
eachDay: require('./each_day/index.js'),
endOfDay: require('./end_of_day/index.js'),
endOfHour: require('./end_of_hour/index.js'),
endOfISOWeek: require('./end_of_iso_week/index.js'),
endOfISOYear: require('./end_of_iso_year/index.js'),
endOfMinute: require('./end_of_minute/index.js'),
endOfMonth: require('./end_of_month/index.js'),
endOfQuarter: require('./end_of_quarter/index.js'),
endOfSecond: require('./end_of_second/index.js'),
endOfToday: require('./end_of_today/index.js'),
endOfTomorrow: require('./end_of_tomorrow/index.js'),
endOfWeek: require('./end_of_week/index.js'),
endOfYear: require('./end_of_year/index.js'),
endOfYesterday: require('./end_of_yesterday/index.js'),
format: require('./format/index.js'),
getDate: require('./get_date/index.js'),
getDay: require('./get_day/index.js'),
getDayOfYear: require('./get_day_of_year/index.js'),
getDaysInMonth: require('./get_days_in_month/index.js'),
getDaysInYear: require('./get_days_in_year/index.js'),
getHours: require('./get_hours/index.js'),
getISODay: require('./get_iso_day/index.js'),
getISOWeek: require('./get_iso_week/index.js'),
getISOWeeksInYear: require('./get_iso_weeks_in_year/index.js'),
getISOYear: require('./get_iso_year/index.js'),
getMilliseconds: require('./get_milliseconds/index.js'),
getMinutes: require('./get_minutes/index.js'),
getMonth: require('./get_month/index.js'),
getOverlappingDaysInRanges: require('./get_overlapping_days_in_ranges/index.js'),
getQuarter: require('./get_quarter/index.js'),
getSeconds: require('./get_seconds/index.js'),
getTime: require('./get_time/index.js'),
getYear: require('./get_year/index.js'),
isAfter: require('./is_after/index.js'),
isBefore: require('./is_before/index.js'),
isDate: require('./is_date/index.js'),
isEqual: require('./is_equal/index.js'),
isFirstDayOfMonth: require('./is_first_day_of_month/index.js'),
isFriday: require('./is_friday/index.js'),
isFuture: require('./is_future/index.js'),
isLastDayOfMonth: require('./is_last_day_of_month/index.js'),
isLeapYear: require('./is_leap_year/index.js'),
isMonday: require('./is_monday/index.js'),
isPast: require('./is_past/index.js'),
isSameDay: require('./is_same_day/index.js'),
isSameHour: require('./is_same_hour/index.js'),
isSameISOWeek: require('./is_same_iso_week/index.js'),
isSameISOYear: require('./is_same_iso_year/index.js'),
isSameMinute: require('./is_same_minute/index.js'),
isSameMonth: require('./is_same_month/index.js'),
isSameQuarter: require('./is_same_quarter/index.js'),
isSameSecond: require('./is_same_second/index.js'),
isSameWeek: require('./is_same_week/index.js'),
isSameYear: require('./is_same_year/index.js'),
isSaturday: require('./is_saturday/index.js'),
isSunday: require('./is_sunday/index.js'),
isThisHour: require('./is_this_hour/index.js'),
isThisISOWeek: require('./is_this_iso_week/index.js'),
isThisISOYear: require('./is_this_iso_year/index.js'),
isThisMinute: require('./is_this_minute/index.js'),
isThisMonth: require('./is_this_month/index.js'),
isThisQuarter: require('./is_this_quarter/index.js'),
isThisSecond: require('./is_this_second/index.js'),
isThisWeek: require('./is_this_week/index.js'),
isThisYear: require('./is_this_year/index.js'),
isThursday: require('./is_thursday/index.js'),
isToday: require('./is_today/index.js'),
isTomorrow: require('./is_tomorrow/index.js'),
isTuesday: require('./is_tuesday/index.js'),
isValid: require('./is_valid/index.js'),
isWednesday: require('./is_wednesday/index.js'),
isWeekend: require('./is_weekend/index.js'),
isWithinRange: require('./is_within_range/index.js'),
isYesterday: require('./is_yesterday/index.js'),
lastDayOfISOWeek: require('./last_day_of_iso_week/index.js'),
lastDayOfISOYear: require('./last_day_of_iso_year/index.js'),
lastDayOfMonth: require('./last_day_of_month/index.js'),
lastDayOfQuarter: require('./last_day_of_quarter/index.js'),
lastDayOfWeek: require('./last_day_of_week/index.js'),
lastDayOfYear: require('./last_day_of_year/index.js'),
max: require('./max/index.js'),
min: require('./min/index.js'),
parse: require('./parse/index.js'),
setDate: require('./set_date/index.js'),
setDay: require('./set_day/index.js'),
setDayOfYear: require('./set_day_of_year/index.js'),
setHours: require('./set_hours/index.js'),
setISODay: require('./set_iso_day/index.js'),
setISOWeek: require('./set_iso_week/index.js'),
setISOYear: require('./set_iso_year/index.js'),
setMilliseconds: require('./set_milliseconds/index.js'),
setMinutes: require('./set_minutes/index.js'),
setMonth: require('./set_month/index.js'),
setQuarter: require('./set_quarter/index.js'),
setSeconds: require('./set_seconds/index.js'),
setYear: require('./set_year/index.js'),
startOfDay: require('./start_of_day/index.js'),
startOfHour: require('./start_of_hour/index.js'),
startOfISOWeek: require('./start_of_iso_week/index.js'),
startOfISOYear: require('./start_of_iso_year/index.js'),
startOfMinute: require('./start_of_minute/index.js'),
startOfMonth: require('./start_of_month/index.js'),
startOfQuarter: require('./start_of_quarter/index.js'),
startOfSecond: require('./start_of_second/index.js'),
startOfToday: require('./start_of_today/index.js'),
startOfTomorrow: require('./start_of_tomorrow/index.js'),
startOfWeek: require('./start_of_week/index.js'),
startOfYear: require('./start_of_year/index.js'),
startOfYesterday: require('./start_of_yesterday/index.js'),
subDays: require('./sub_days/index.js'),
subHours: require('./sub_hours/index.js'),
subISOYears: require('./sub_iso_years/index.js'),
subMilliseconds: require('./sub_milliseconds/index.js'),
subMinutes: require('./sub_minutes/index.js'),
subMonths: require('./sub_months/index.js'),
subQuarters: require('./sub_quarters/index.js'),
subSeconds: require('./sub_seconds/index.js'),
subWeeks: require('./sub_weeks/index.js'),
subYears: require('./sub_years/index.js')
}
},{"./add_days/index.js":1,"./add_hours/index.js":2,"./add_iso_years/index.js":3,"./add_milliseconds/index.js":4,"./add_minutes/index.js":5,"./add_months/index.js":6,"./add_quarters/index.js":7,"./add_seconds/index.js":8,"./add_weeks/index.js":9,"./add_years/index.js":10,"./are_ranges_overlapping/index.js":11,"./closest_index_to/index.js":12,"./closest_to/index.js":13,"./compare_asc/index.js":14,"./compare_desc/index.js":15,"./difference_in_calendar_days/index.js":16,"./difference_in_calendar_iso_weeks/index.js":17,"./difference_in_calendar_iso_years/index.js":18,"./difference_in_calendar_months/index.js":19,"./difference_in_calendar_quarters/index.js":20,"./difference_in_calendar_weeks/index.js":21,"./difference_in_calendar_years/index.js":22,"./difference_in_days/index.js":23,"./difference_in_hours/index.js":24,"./difference_in_iso_years/index.js":25,"./difference_in_milliseconds/index.js":26,"./difference_in_minutes/index.js":27,"./difference_in_months/index.js":28,"./difference_in_quarters/index.js":29,"./difference_in_seconds/index.js":30,"./difference_in_weeks/index.js":31,"./difference_in_years/index.js":32,"./distance_in_words/index.js":33,"./distance_in_words_strict/index.js":34,"./distance_in_words_to_now/index.js":35,"./each_day/index.js":36,"./end_of_day/index.js":37,"./end_of_hour/index.js":38,"./end_of_iso_week/index.js":39,"./end_of_iso_year/index.js":40,"./end_of_minute/index.js":41,"./end_of_month/index.js":42,"./end_of_quarter/index.js":43,"./end_of_second/index.js":44,"./end_of_today/index.js":45,"./end_of_tomorrow/index.js":46,"./end_of_week/index.js":47,"./end_of_year/index.js":48,"./end_of_yesterday/index.js":49,"./format/index.js":50,"./get_date/index.js":51,"./get_day/index.js":52,"./get_day_of_year/index.js":53,"./get_days_in_month/index.js":54,"./get_days_in_year/index.js":55,"./get_hours/index.js":56,"./get_iso_day/index.js":57,"./get_iso_week/index.js":58,"./get_iso_weeks_in_year/index.js":59,"./get_iso_year/index.js":60,"./get_milliseconds/index.js":61,"./get_minutes/index.js":62,"./get_month/index.js":63,"./get_overlapping_days_in_ranges/index.js":64,"./get_quarter/index.js":65,"./get_seconds/index.js":66,"./get_time/index.js":67,"./get_year/index.js":68,"./is_after/index.js":69,"./is_before/index.js":70,"./is_date/index.js":71,"./is_equal/index.js":72,"./is_first_day_of_month/index.js":73,"./is_friday/index.js":74,"./is_future/index.js":75,"./is_last_day_of_month/index.js":76,"./is_leap_year/index.js":77,"./is_monday/index.js":78,"./is_past/index.js":79,"./is_same_day/index.js":80,"./is_same_hour/index.js":81,"./is_same_iso_week/index.js":82,"./is_same_iso_year/index.js":83,"./is_same_minute/index.js":84,"./is_same_month/index.js":85,"./is_same_quarter/index.js":86,"./is_same_second/index.js":87,"./is_same_week/index.js":88,"./is_same_year/index.js":89,"./is_saturday/index.js":90,"./is_sunday/index.js":91,"./is_this_hour/index.js":92,"./is_this_iso_week/index.js":93,"./is_this_iso_year/index.js":94,"./is_this_minute/index.js":95,"./is_this_month/index.js":96,"./is_this_quarter/index.js":97,"./is_this_second/index.js":98,"./is_this_week/index.js":99,"./is_this_year/index.js":100,"./is_thursday/index.js":101,"./is_today/index.js":102,"./is_tomorrow/index.js":103,"./is_tuesday/index.js":104,"./is_valid/index.js":105,"./is_wednesday/index.js":106,"./is_weekend/index.js":107,"./is_within_range/index.js":108,"./is_yesterday/index.js":109,"./last_day_of_iso_week/index.js":110,"./last_day_of_iso_year/index.js":111,"./last_day_of_month/index.js":112,"./last_day_of_quarter/index.js":113,"./last_day_of_week/index.js":114,"./last_day_of_year/index.js":115,"./max/index.js":120,"./min/index.js":121,"./parse/index.js":122,"./set_date/index.js":123,"./set_day/index.js":124,"./set_day_of_year/index.js":125,"./set_hours/index.js":126,"./set_iso_day/index.js":127,"./set_iso_week/index.js":128,"./set_iso_year/index.js":129,"./set_milliseconds/index.js":130,"./set_minutes/index.js":131,"./set_month/index.js":132,"./set_quarter/index.js":133,"./set_seconds/index.js":134,"./set_year/index.js":135,"./start_of_day/index.js":136,"./start_of_hour/index.js":137,"./start_of_iso_week/index.js":138,"./start_of_iso_year/index.js":139,"./start_of_minute/index.js":140,"./start_of_month/index.js":141,"./start_of_quarter/index.js":142,"./start_of_second/index.js":143,"./start_of_today/index.js":144,"./start_of_tomorrow/index.js":145,"./start_of_week/index.js":146,"./start_of_year/index.js":147,"./start_of_yesterday/index.js":148,"./sub_days/index.js":149,"./sub_hours/index.js":150,"./sub_iso_years/index.js":151,"./sub_milliseconds/index.js":152,"./sub_minutes/index.js":153,"./sub_months/index.js":154,"./sub_quarters/index.js":155,"./sub_seconds/index.js":156,"./sub_weeks/index.js":157,"./sub_years/index.js":158}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImFkZF9kYXlzL2luZGV4LmpzIiwiYWRkX2hvdXJzL2luZGV4LmpzIiwiYWRkX2lzb195ZWFycy9pbmRleC5qcyIsImFkZF9taWxsaXNlY29uZHMvaW5kZXguanMiLCJhZGRfbWludXRlcy9pbmRleC5qcyIsImFkZF9tb250aHMvaW5kZXguanMiLCJhZGRfcXVhcnRlcnMvaW5kZXguanMiLCJhZGRfc2Vjb25kcy9pbmRleC5qcyIsImFkZF93ZWVrcy9pbmRleC5qcyIsImFkZF95ZWFycy9pbmRleC5qcyIsImFyZV9yYW5nZXNfb3ZlcmxhcHBpbmcvaW5kZXguanMiLCJjbG9zZXN0X2luZGV4X3RvL2luZGV4LmpzIiwiY2xvc2VzdF90by9pbmRleC5qcyIsImNvbXBhcmVfYXNjL2luZGV4LmpzIiwiY29tcGFyZV9kZXNjL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9kYXlzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9pc29fd2Vla3MvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX2NhbGVuZGFyX2lzb195ZWFycy9pbmRleC5qcyIsImRpZmZlcmVuY2VfaW5fY2FsZW5kYXJfbW9udGhzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9xdWFydGVycy9pbmRleC5qcyIsImRpZmZlcmVuY2VfaW5fY2FsZW5kYXJfd2Vla3MvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX2NhbGVuZGFyX3llYXJzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9kYXlzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9ob3Vycy9pbmRleC5qcyIsImRpZmZlcmVuY2VfaW5faXNvX3llYXJzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl9taWxsaXNlY29uZHMvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX21pbnV0ZXMvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX21vbnRocy9pbmRleC5qcyIsImRpZmZlcmVuY2VfaW5fcXVhcnRlcnMvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX3NlY29uZHMvaW5kZXguanMiLCJkaWZmZXJlbmNlX2luX3dlZWtzL2luZGV4LmpzIiwiZGlmZmVyZW5jZV9pbl95ZWFycy9pbmRleC5qcyIsImRpc3RhbmNlX2luX3dvcmRzL2luZGV4LmpzIiwiZGlzdGFuY2VfaW5fd29yZHNfc3RyaWN0L2luZGV4LmpzIiwiZGlzdGFuY2VfaW5fd29yZHNfdG9fbm93L2luZGV4LmpzIiwiZWFjaF9kYXkvaW5kZXguanMiLCJlbmRfb2ZfZGF5L2luZGV4LmpzIiwiZW5kX29mX2hvdXIvaW5kZXguanMiLCJlbmRfb2ZfaXNvX3dlZWsvaW5kZXguanMiLCJlbmRfb2ZfaXNvX3llYXIvaW5kZXguanMiLCJlbmRfb2ZfbWludXRlL2luZGV4LmpzIiwiZW5kX29mX21vbnRoL2luZGV4LmpzIiwiZW5kX29mX3F1YXJ0ZXIvaW5kZXguanMiLCJlbmRfb2Zfc2Vjb25kL2luZGV4LmpzIiwiZW5kX29mX3RvZGF5L2luZGV4LmpzIiwiZW5kX29mX3RvbW9ycm93L2luZGV4LmpzIiwiZW5kX29mX3dlZWsvaW5kZXguanMiLCJlbmRfb2ZfeWVhci9pbmRleC5qcyIsImVuZF9vZl95ZXN0ZXJkYXkvaW5kZXguanMiLCJmb3JtYXQvaW5kZXguanMiLCJnZXRfZGF0ZS9pbmRleC5qcyIsImdldF9kYXkvaW5kZXguanMiLCJnZXRfZGF5X29mX3llYXIvaW5kZXguanMiLCJnZXRfZGF5c19pbl9tb250aC9pbmRleC5qcyIsImdldF9kYXlzX2luX3llYXIvaW5kZXguanMiLCJnZXRfaG91cnMvaW5kZXguanMiLCJnZXRfaXNvX2RheS9pbmRleC5qcyIsImdldF9pc29fd2Vlay9pbmRleC5qcyIsImdldF9pc29fd2Vla3NfaW5feWVhci9pbmRleC5qcyIsImdldF9pc29feWVhci9pbmRleC5qcyIsImdldF9taWxsaXNlY29uZHMvaW5kZXguanMiLCJnZXRfbWludXRlcy9pbmRleC5qcyIsImdldF9tb250aC9pbmRleC5qcyIsImdldF9vdmVybGFwcGluZ19kYXlzX2luX3Jhbmdlcy9pbmRleC5qcyIsImdldF9xdWFydGVyL2luZGV4LmpzIiwiZ2V0X3NlY29uZHMvaW5kZXguanMiLCJnZXRfdGltZS9pbmRleC5qcyIsImdldF95ZWFyL2luZGV4LmpzIiwiaXNfYWZ0ZXIvaW5kZXguanMiLCJpc19iZWZvcmUvaW5kZXguanMiLCJpc19kYXRlL2luZGV4LmpzIiwiaXNfZXF1YWwvaW5kZXguanMiLCJpc19maXJzdF9kYXlfb2ZfbW9udGgvaW5kZXguanMiLCJpc19mcmlkYXkvaW5kZXguanMiLCJpc19mdXR1cmUvaW5kZXguanMiLCJpc19sYXN0X2RheV9vZl9tb250aC9pbmRleC5qcyIsImlzX2xlYXBfeWVhci9pbmRleC5qcyIsImlzX21vbmRheS9pbmRleC5qcyIsImlzX3Bhc3QvaW5kZXguanMiLCJpc19zYW1lX2RheS9pbmRleC5qcyIsImlzX3NhbWVfaG91ci9pbmRleC5qcyIsImlzX3NhbWVfaXNvX3dlZWsvaW5kZXguanMiLCJpc19zYW1lX2lzb195ZWFyL2luZGV4LmpzIiwiaXNfc2FtZV9taW51dGUvaW5kZXguanMiLCJpc19zYW1lX21vbnRoL2luZGV4LmpzIiwiaXNfc2FtZV9xdWFydGVyL2luZGV4LmpzIiwiaXNfc2FtZV9zZWNvbmQvaW5kZXguanMiLCJpc19zYW1lX3dlZWsvaW5kZXguanMiLCJpc19zYW1lX3llYXIvaW5kZXguanMiLCJpc19zYXR1cmRheS9pbmRleC5qcyIsImlzX3N1bmRheS9pbmRleC5qcyIsImlzX3RoaXNfaG91ci9pbmRleC5qcyIsImlzX3RoaXNfaXNvX3dlZWsvaW5kZXguanMiLCJpc190aGlzX2lzb195ZWFyL2luZGV4LmpzIiwiaXNfdGhpc19taW51dGUvaW5kZXguanMiLCJpc190aGlzX21vbnRoL2luZGV4LmpzIiwiaXNfdGhpc19xdWFydGVyL2luZGV4LmpzIiwiaXNfdGhpc19zZWNvbmQvaW5kZXguanMiLCJpc190aGlzX3dlZWsvaW5kZXguanMiLCJpc190aGlzX3llYXIvaW5kZXguanMiLCJpc190aHVyc2RheS9pbmRleC5qcyIsImlzX3RvZGF5L2luZGV4LmpzIiwiaXNfdG9tb3Jyb3cvaW5kZXguanMiLCJpc190dWVzZGF5L2luZGV4LmpzIiwiaXNfdmFsaWQvaW5kZXguanMiLCJpc193ZWRuZXNkYXkvaW5kZXguanMiLCJpc193ZWVrZW5kL2luZGV4LmpzIiwiaXNfd2l0aGluX3JhbmdlL2luZGV4LmpzIiwiaXNfeWVzdGVyZGF5L2luZGV4LmpzIiwibGFzdF9kYXlfb2ZfaXNvX3dlZWsvaW5kZXguanMiLCJsYXN0X2RheV9vZl9pc29feWVhci9pbmRleC5qcyIsImxhc3RfZGF5X29mX21vbnRoL2luZGV4LmpzIiwibGFzdF9kYXlfb2ZfcXVhcnRlci9pbmRleC5qcyIsImxhc3RfZGF5X29mX3dlZWsvaW5kZXguanMiLCJsYXN0X2RheV9vZl95ZWFyL2luZGV4LmpzIiwibG9jYWxlL19saWIvYnVpbGRfZm9ybWF0dGluZ190b2tlbnNfcmVnX2V4cC9pbmRleC5qcyIsImxvY2FsZS9lbi9idWlsZF9kaXN0YW5jZV9pbl93b3Jkc19sb2NhbGUvaW5kZXguanMiLCJsb2NhbGUvZW4vYnVpbGRfZm9ybWF0X2xvY2FsZS9pbmRleC5qcyIsImxvY2FsZS9lbi9pbmRleC5qcyIsIm1heC9pbmRleC5qcyIsIm1pbi9pbmRleC5qcyIsInBhcnNlL2luZGV4LmpzIiwic2V0X2RhdGUvaW5kZXguanMiLCJzZXRfZGF5L2luZGV4LmpzIiwic2V0X2RheV9vZl95ZWFyL2luZGV4LmpzIiwic2V0X2hvdXJzL2luZGV4LmpzIiwic2V0X2lzb19kYXkvaW5kZXguanMiLCJzZXRfaXNvX3dlZWsvaW5kZXguanMiLCJzZXRfaXNvX3llYXIvaW5kZXguanMiLCJzZXRfbWlsbGlzZWNvbmRzL2luZGV4LmpzIiwic2V0X21pbnV0ZXMvaW5kZXguanMiLCJzZXRfbW9udGgvaW5kZXguanMiLCJzZXRfcXVhcnRlci9pbmRleC5qcyIsInNldF9zZWNvbmRzL2luZGV4LmpzIiwic2V0X3llYXIvaW5kZXguanMiLCJzdGFydF9vZl9kYXkvaW5kZXguanMiLCJzdGFydF9vZl9ob3VyL2luZGV4LmpzIiwic3RhcnRfb2ZfaXNvX3dlZWsvaW5kZXguanMiLCJzdGFydF9vZl9pc29feWVhci9pbmRleC5qcyIsInN0YXJ0X29mX21pbnV0ZS9pbmRleC5qcyIsInN0YXJ0X29mX21vbnRoL2luZGV4LmpzIiwic3RhcnRfb2ZfcXVhcnRlci9pbmRleC5qcyIsInN0YXJ0X29mX3NlY29uZC9pbmRleC5qcyIsInN0YXJ0X29mX3RvZGF5L2luZGV4LmpzIiwic3RhcnRfb2ZfdG9tb3Jyb3cvaW5kZXguanMiLCJzdGFydF9vZl93ZWVrL2luZGV4LmpzIiwic3RhcnRfb2ZfeWVhci9pbmRleC5qcyIsInN0YXJ0X29mX3llc3RlcmRheS9pbmRleC5qcyIsInN1Yl9kYXlzL2luZGV4LmpzIiwic3ViX2hvdXJzL2luZGV4LmpzIiwic3ViX2lzb195ZWFycy9pbmRleC5qcyIsInN1Yl9taWxsaXNlY29uZHMvaW5kZXguanMiLCJzdWJfbWludXRlcy9pbmRleC5qcyIsInN1Yl9tb250aHMvaW5kZXguanMiLCJzdWJfcXVhcnRlcnMvaW5kZXguanMiLCJzdWJfc2Vjb25kcy9pbmRleC5qcyIsInN1Yl93ZWVrcy9pbmRleC5qcyIsInN1Yl95ZWFycy9pbmRleC5qcyIsImRhdGUtZm5zIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgRGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFkZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBkYXlzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGRheXMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBkYXlzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIGRheXMgYWRkZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQWRkIDEwIGRheXMgdG8gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBhZGREYXlzKG5ldyBEYXRlKDIwMTQsIDgsIDEpLCAxMClcbiAqIC8vPT4gVGh1IFNlcCAxMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZERheXMgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIGFtb3VudClcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhZGREYXlzXG4iLCJ2YXIgYWRkTWlsbGlzZWNvbmRzID0gcmVxdWlyZSgnLi4vYWRkX21pbGxpc2Vjb25kcy9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fSE9VUiA9IDM2MDAwMDBcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSG91ciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgaG91cnMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgaG91cnMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBob3VycyB0byBiZSBhZGRlZFxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBob3VycyBhZGRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBZGQgMiBob3VycyB0byAxMCBKdWx5IDIwMTQgMjM6MDA6MDA6XG4gKiB2YXIgcmVzdWx0ID0gYWRkSG91cnMobmV3IERhdGUoMjAxNCwgNiwgMTAsIDIzLCAwKSwgMilcbiAqIC8vPT4gRnJpIEp1bCAxMSAyMDE0IDAxOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZEhvdXJzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRNaWxsaXNlY29uZHMoZGlydHlEYXRlLCBhbW91bnQgKiBNSUxMSVNFQ09ORFNfSU5fSE9VUilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhZGRIb3Vyc1xuIiwidmFyIGdldElTT1llYXIgPSByZXF1aXJlKCcuLi9nZXRfaXNvX3llYXIvaW5kZXguanMnKVxudmFyIHNldElTT1llYXIgPSByZXF1aXJlKCcuLi9zZXRfaXNvX3llYXIvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2Vlay1OdW1iZXJpbmcgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFycyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnMgdG8gYmUgYWRkZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIGFkZGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFkZCA1IElTTyB3ZWVrLW51bWJlcmluZyB5ZWFycyB0byAyIEp1bHkgMjAxMDpcbiAqIHZhciByZXN1bHQgPSBhZGRJU09ZZWFycyhuZXcgRGF0ZSgyMDEwLCA2LCAyKSwgNSlcbiAqIC8vPT4gRnJpIEp1biAyNiAyMDE1IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZElTT1llYXJzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBzZXRJU09ZZWFyKGRpcnR5RGF0ZSwgZ2V0SVNPWWVhcihkaXJ0eURhdGUpICsgYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFkZElTT1llYXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbGxpc2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFkZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgb2YgbWlsbGlzZWNvbmRzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIG1pbGxpc2Vjb25kcyBhZGRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBZGQgNzUwIG1pbGxpc2Vjb25kcyB0byAxMCBKdWx5IDIwMTQgMTI6NDU6MzAuMDAwOlxuICogdmFyIHJlc3VsdCA9IGFkZE1pbGxpc2Vjb25kcyhuZXcgRGF0ZSgyMDE0LCA2LCAxMCwgMTIsIDQ1LCAzMCwgMCksIDc1MClcbiAqIC8vPT4gVGh1IEp1bCAxMCAyMDE0IDEyOjQ1OjMwLjc1MFxuICovXG5mdW5jdGlvbiBhZGRNaWxsaXNlY29uZHMgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIHRpbWVzdGFtcCA9IHBhcnNlKGRpcnR5RGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBuZXcgRGF0ZSh0aW1lc3RhbXAgKyBhbW91bnQpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYWRkTWlsbGlzZWNvbmRzXG4iLCJ2YXIgYWRkTWlsbGlzZWNvbmRzID0gcmVxdWlyZSgnLi4vYWRkX21pbGxpc2Vjb25kcy9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFID0gNjAwMDBcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTWludXRlIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFkZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaW51dGVzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIG1pbnV0ZXMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBtaW51dGVzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIG1pbnV0ZXMgYWRkZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQWRkIDMwIG1pbnV0ZXMgdG8gMTAgSnVseSAyMDE0IDEyOjAwOjAwOlxuICogdmFyIHJlc3VsdCA9IGFkZE1pbnV0ZXMobmV3IERhdGUoMjAxNCwgNiwgMTAsIDEyLCAwKSwgMzApXG4gKiAvLz0+IFRodSBKdWwgMTAgMjAxNCAxMjozMDowMFxuICovXG5mdW5jdGlvbiBhZGRNaW51dGVzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRNaWxsaXNlY29uZHMoZGlydHlEYXRlLCBhbW91bnQgKiBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFkZE1pbnV0ZXNcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBnZXREYXlzSW5Nb250aCA9IHJlcXVpcmUoJy4uL2dldF9kYXlzX2luX21vbnRoL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTW9udGggSGVscGVyc1xuICogQHN1bW1hcnkgQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIG1vbnRocyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEFkZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtb250aHMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBtb250aHMgdG8gYmUgYWRkZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgbW9udGhzIGFkZGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFkZCA1IG1vbnRocyB0byAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IGFkZE1vbnRocyhuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgNSlcbiAqIC8vPT4gU3VuIEZlYiAwMSAyMDE1IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZE1vbnRocyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGFtb3VudCA9IE51bWJlcihkaXJ0eUFtb3VudClcbiAgdmFyIGRlc2lyZWRNb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIGFtb3VudFxuICB2YXIgZGF0ZVdpdGhEZXNpcmVkTW9udGggPSBuZXcgRGF0ZSgwKVxuICBkYXRlV2l0aERlc2lyZWRNb250aC5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCksIGRlc2lyZWRNb250aCwgMSlcbiAgZGF0ZVdpdGhEZXNpcmVkTW9udGguc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgdmFyIGRheXNJbk1vbnRoID0gZ2V0RGF5c0luTW9udGgoZGF0ZVdpdGhEZXNpcmVkTW9udGgpXG4gIC8vIFNldCB0aGUgbGFzdCBkYXkgb2YgdGhlIG5ldyBtb250aFxuICAvLyBpZiB0aGUgb3JpZ2luYWwgZGF0ZSB3YXMgdGhlIGxhc3QgZGF5IG9mIHRoZSBsb25nZXIgbW9udGhcbiAgZGF0ZS5zZXRNb250aChkZXNpcmVkTW9udGgsIE1hdGgubWluKGRheXNJbk1vbnRoLCBkYXRlLmdldERhdGUoKSkpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYWRkTW9udGhzXG4iLCJ2YXIgYWRkTW9udGhzID0gcmVxdWlyZSgnLi4vYWRkX21vbnRocy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFF1YXJ0ZXIgSGVscGVyc1xuICogQHN1bW1hcnkgQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHllYXIgcXVhcnRlcnMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgeWVhciBxdWFydGVycyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBhbW91bnQgLSB0aGUgYW1vdW50IG9mIHF1YXJ0ZXJzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIHF1YXJ0ZXJzIGFkZGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFkZCAxIHF1YXJ0ZXIgdG8gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBhZGRRdWFydGVycyhuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgMSlcbiAqIC8vPT4gTW9uIERlYyAwMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZFF1YXJ0ZXJzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHZhciBtb250aHMgPSBhbW91bnQgKiAzXG4gIHJldHVybiBhZGRNb250aHMoZGlydHlEYXRlLCBtb250aHMpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYWRkUXVhcnRlcnNcbiIsInZhciBhZGRNaWxsaXNlY29uZHMgPSByZXF1aXJlKCcuLi9hZGRfbWlsbGlzZWNvbmRzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgU2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFkZCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzZWNvbmRzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHNlY29uZHMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBzZWNvbmRzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIHNlY29uZHMgYWRkZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQWRkIDMwIHNlY29uZHMgdG8gMTAgSnVseSAyMDE0IDEyOjQ1OjAwOlxuICogdmFyIHJlc3VsdCA9IGFkZFNlY29uZHMobmV3IERhdGUoMjAxNCwgNiwgMTAsIDEyLCA0NSwgMCksIDMwKVxuICogLy89PiBUaHUgSnVsIDEwIDIwMTQgMTI6NDU6MzBcbiAqL1xuZnVuY3Rpb24gYWRkU2Vjb25kcyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgYW1vdW50ID0gTnVtYmVyKGRpcnR5QW1vdW50KVxuICByZXR1cm4gYWRkTWlsbGlzZWNvbmRzKGRpcnR5RGF0ZSwgYW1vdW50ICogMTAwMClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhZGRTZWNvbmRzXG4iLCJ2YXIgYWRkRGF5cyA9IHJlcXVpcmUoJy4uL2FkZF9kYXlzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2Ygd2Vla3MgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBZGQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2Ygd2VlayB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBhbW91bnQgLSB0aGUgYW1vdW50IG9mIHdlZWtzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIHdlZWtzIGFkZGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFkZCA0IHdlZWtzIHRvIDEgU2VwdGVtYmVyIDIwMTQ6XG4gKiB2YXIgcmVzdWx0ID0gYWRkV2Vla3MobmV3IERhdGUoMjAxNCwgOCwgMSksIDQpXG4gKiAvLz0+IE1vbiBTZXAgMjkgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBhZGRXZWVrcyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgYW1vdW50ID0gTnVtYmVyKGRpcnR5QW1vdW50KVxuICB2YXIgZGF5cyA9IGFtb3VudCAqIDdcbiAgcmV0dXJuIGFkZERheXMoZGlydHlEYXRlLCBkYXlzKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFkZFdlZWtzXG4iLCJ2YXIgYWRkTW9udGhzID0gcmVxdWlyZSgnLi4vYWRkX21vbnRocy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHllYXJzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQWRkIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHllYXJzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgb2YgeWVhcnMgdG8gYmUgYWRkZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgeWVhcnMgYWRkZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQWRkIDUgeWVhcnMgdG8gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBhZGRZZWFycyhuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgNSlcbiAqIC8vPT4gU3VuIFNlcCAwMSAyMDE5IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGFkZFllYXJzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRNb250aHMoZGlydHlEYXRlLCBhbW91bnQgKiAxMilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhZGRZZWFyc1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBSYW5nZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSByYW5nZSBvdmVybGFwcGluZyB3aXRoIGFub3RoZXIgZGF0ZSByYW5nZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIHJhbmdlIG92ZXJsYXBwaW5nIHdpdGggYW5vdGhlciBkYXRlIHJhbmdlP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBpbml0aWFsUmFuZ2VTdGFydERhdGUgLSB0aGUgc3RhcnQgb2YgdGhlIGluaXRpYWwgcmFuZ2VcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBpbml0aWFsUmFuZ2VFbmREYXRlIC0gdGhlIGVuZCBvZiB0aGUgaW5pdGlhbCByYW5nZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGNvbXBhcmVkUmFuZ2VTdGFydERhdGUgLSB0aGUgc3RhcnQgb2YgdGhlIHJhbmdlIHRvIGNvbXBhcmUgaXQgd2l0aFxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGNvbXBhcmVkUmFuZ2VFbmREYXRlIC0gdGhlIGVuZCBvZiB0aGUgcmFuZ2UgdG8gY29tcGFyZSBpdCB3aXRoXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gd2hldGhlciB0aGUgZGF0ZSByYW5nZXMgYXJlIG92ZXJsYXBwaW5nXG4gKiBAdGhyb3dzIHtFcnJvcn0gc3RhcnREYXRlIG9mIGEgZGF0ZSByYW5nZSBjYW5ub3QgYmUgYWZ0ZXIgaXRzIGVuZERhdGVcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRm9yIG92ZXJsYXBwaW5nIGRhdGUgcmFuZ2VzOlxuICogYXJlUmFuZ2VzT3ZlcmxhcHBpbmcoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDAsIDEwKSwgbmV3IERhdGUoMjAxNCwgMCwgMjApLCBuZXcgRGF0ZSgyMDE0LCAwLCAxNyksIG5ldyBEYXRlKDIwMTQsIDAsIDIxKVxuICogKVxuICogLy89PiB0cnVlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZvciBub24tb3ZlcmxhcHBpbmcgZGF0ZSByYW5nZXM6XG4gKiBhcmVSYW5nZXNPdmVybGFwcGluZyhcbiAqICAgbmV3IERhdGUoMjAxNCwgMCwgMTApLCBuZXcgRGF0ZSgyMDE0LCAwLCAyMCksIG5ldyBEYXRlKDIwMTQsIDAsIDIxKSwgbmV3IERhdGUoMjAxNCwgMCwgMjIpXG4gKiApXG4gKiAvLz0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGFyZVJhbmdlc092ZXJsYXBwaW5nIChkaXJ0eUluaXRpYWxSYW5nZVN0YXJ0RGF0ZSwgZGlydHlJbml0aWFsUmFuZ2VFbmREYXRlLCBkaXJ0eUNvbXBhcmVkUmFuZ2VTdGFydERhdGUsIGRpcnR5Q29tcGFyZWRSYW5nZUVuZERhdGUpIHtcbiAgdmFyIGluaXRpYWxTdGFydFRpbWUgPSBwYXJzZShkaXJ0eUluaXRpYWxSYW5nZVN0YXJ0RGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBpbml0aWFsRW5kVGltZSA9IHBhcnNlKGRpcnR5SW5pdGlhbFJhbmdlRW5kRGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBjb21wYXJlZFN0YXJ0VGltZSA9IHBhcnNlKGRpcnR5Q29tcGFyZWRSYW5nZVN0YXJ0RGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBjb21wYXJlZEVuZFRpbWUgPSBwYXJzZShkaXJ0eUNvbXBhcmVkUmFuZ2VFbmREYXRlKS5nZXRUaW1lKClcblxuICBpZiAoaW5pdGlhbFN0YXJ0VGltZSA+IGluaXRpYWxFbmRUaW1lIHx8IGNvbXBhcmVkU3RhcnRUaW1lID4gY29tcGFyZWRFbmRUaW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc3RhcnQgb2YgdGhlIHJhbmdlIGNhbm5vdCBiZSBhZnRlciB0aGUgZW5kIG9mIHRoZSByYW5nZScpXG4gIH1cblxuICByZXR1cm4gaW5pdGlhbFN0YXJ0VGltZSA8IGNvbXBhcmVkRW5kVGltZSAmJiBjb21wYXJlZFN0YXJ0VGltZSA8IGluaXRpYWxFbmRUaW1lXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJlUmFuZ2VzT3ZlcmxhcHBpbmdcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgQ29tbW9uIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiBhbiBpbmRleCBvZiB0aGUgY2xvc2VzdCBkYXRlIGZyb20gdGhlIGFycmF5IGNvbXBhcmluZyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiBhbiBpbmRleCBvZiB0aGUgY2xvc2VzdCBkYXRlIGZyb20gdGhlIGFycmF5IGNvbXBhcmluZyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVRvQ29tcGFyZSAtIHRoZSBkYXRlIHRvIGNvbXBhcmUgd2l0aFxuICogQHBhcmFtIHtEYXRlW118U3RyaW5nW118TnVtYmVyW119IGRhdGVzQXJyYXkgLSB0aGUgYXJyYXkgdG8gc2VhcmNoXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBhbiBpbmRleCBvZiB0aGUgZGF0ZSBjbG9zZXN0IHRvIHRoZSBnaXZlbiBkYXRlXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHRoZSBzZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBBcnJheVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGljaCBkYXRlIGlzIGNsb3NlciB0byA2IFNlcHRlbWJlciAyMDE1P1xuICogdmFyIGRhdGVUb0NvbXBhcmUgPSBuZXcgRGF0ZSgyMDE1LCA4LCA2KVxuICogdmFyIGRhdGVzQXJyYXkgPSBbXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDEpLFxuICogICBuZXcgRGF0ZSgyMDE2LCAwLCAxKSxcbiAqICAgbmV3IERhdGUoMjAxNywgMCwgMSlcbiAqIF1cbiAqIHZhciByZXN1bHQgPSBjbG9zZXN0SW5kZXhUbyhkYXRlVG9Db21wYXJlLCBkYXRlc0FycmF5KVxuICogLy89PiAxXG4gKi9cbmZ1bmN0aW9uIGNsb3Nlc3RJbmRleFRvIChkaXJ0eURhdGVUb0NvbXBhcmUsIGRpcnR5RGF0ZXNBcnJheSkge1xuICBpZiAoIShkaXJ0eURhdGVzQXJyYXkgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHRvU3RyaW5nLmNhbGwoZGlydHlEYXRlc0FycmF5KSArICcgaXMgbm90IGFuIGluc3RhbmNlIG9mIEFycmF5JylcbiAgfVxuXG4gIHZhciBkYXRlVG9Db21wYXJlID0gcGFyc2UoZGlydHlEYXRlVG9Db21wYXJlKVxuICB2YXIgdGltZVRvQ29tcGFyZSA9IGRhdGVUb0NvbXBhcmUuZ2V0VGltZSgpXG5cbiAgdmFyIHJlc3VsdFxuICB2YXIgbWluRGlzdGFuY2VcblxuICBkaXJ0eURhdGVzQXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZGlydHlEYXRlLCBpbmRleCkge1xuICAgIHZhciBjdXJyZW50RGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgICB2YXIgZGlzdGFuY2UgPSBNYXRoLmFicyh0aW1lVG9Db21wYXJlIC0gY3VycmVudERhdGUuZ2V0VGltZSgpKVxuICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCB8fCBkaXN0YW5jZSA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICByZXN1bHQgPSBpbmRleFxuICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gcmVzdWx0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvc2VzdEluZGV4VG9cbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgQ29tbW9uIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiBhIGRhdGUgZnJvbSB0aGUgYXJyYXkgY2xvc2VzdCB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiBhIGRhdGUgZnJvbSB0aGUgYXJyYXkgY2xvc2VzdCB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVRvQ29tcGFyZSAtIHRoZSBkYXRlIHRvIGNvbXBhcmUgd2l0aFxuICogQHBhcmFtIHtEYXRlW118U3RyaW5nW118TnVtYmVyW119IGRhdGVzQXJyYXkgLSB0aGUgYXJyYXkgdG8gc2VhcmNoXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGRhdGUgZnJvbSB0aGUgYXJyYXkgY2xvc2VzdCB0byB0aGUgZ2l2ZW4gZGF0ZVxuICogQHRocm93cyB7VHlwZUVycm9yfSB0aGUgc2Vjb25kIGFyZ3VtZW50IG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgQXJyYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hpY2ggZGF0ZSBpcyBjbG9zZXIgdG8gNiBTZXB0ZW1iZXIgMjAxNTogMSBKYW51YXJ5IDIwMDAgb3IgMSBKYW51YXJ5IDIwMzA/XG4gKiB2YXIgZGF0ZVRvQ29tcGFyZSA9IG5ldyBEYXRlKDIwMTUsIDgsIDYpXG4gKiB2YXIgcmVzdWx0ID0gY2xvc2VzdFRvKGRhdGVUb0NvbXBhcmUsIFtcbiAqICAgbmV3IERhdGUoMjAwMCwgMCwgMSksXG4gKiAgIG5ldyBEYXRlKDIwMzAsIDAsIDEpXG4gKiBdKVxuICogLy89PiBUdWUgSmFuIDAxIDIwMzAgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gY2xvc2VzdFRvIChkaXJ0eURhdGVUb0NvbXBhcmUsIGRpcnR5RGF0ZXNBcnJheSkge1xuICBpZiAoIShkaXJ0eURhdGVzQXJyYXkgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHRvU3RyaW5nLmNhbGwoZGlydHlEYXRlc0FycmF5KSArICcgaXMgbm90IGFuIGluc3RhbmNlIG9mIEFycmF5JylcbiAgfVxuXG4gIHZhciBkYXRlVG9Db21wYXJlID0gcGFyc2UoZGlydHlEYXRlVG9Db21wYXJlKVxuICB2YXIgdGltZVRvQ29tcGFyZSA9IGRhdGVUb0NvbXBhcmUuZ2V0VGltZSgpXG5cbiAgdmFyIHJlc3VsdFxuICB2YXIgbWluRGlzdGFuY2VcblxuICBkaXJ0eURhdGVzQXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZGlydHlEYXRlKSB7XG4gICAgdmFyIGN1cnJlbnREYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICAgIHZhciBkaXN0YW5jZSA9IE1hdGguYWJzKHRpbWVUb0NvbXBhcmUgLSBjdXJyZW50RGF0ZS5nZXRUaW1lKCkpXG4gICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGRpc3RhbmNlIDwgbWluRGlzdGFuY2UpIHtcbiAgICAgIHJlc3VsdCA9IGN1cnJlbnREYXRlXG4gICAgICBtaW5EaXN0YW5jZSA9IGRpc3RhbmNlXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9zZXN0VG9cbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgQ29tbW9uIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IENvbXBhcmUgdGhlIHR3byBkYXRlcyBhbmQgcmV0dXJuIC0xLCAwIG9yIDEuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBDb21wYXJlIHRoZSB0d28gZGF0ZXMgYW5kIHJldHVybiAxIGlmIHRoZSBmaXJzdCBkYXRlIGlzIGFmdGVyIHRoZSBzZWNvbmQsXG4gKiAtMSBpZiB0aGUgZmlyc3QgZGF0ZSBpcyBiZWZvcmUgdGhlIHNlY29uZCBvciAwIGlmIGRhdGVzIGFyZSBlcXVhbC5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgZmlyc3QgZGF0ZSB0byBjb21wYXJlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIHNlY29uZCBkYXRlIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSByZXN1bHQgb2YgdGhlIGNvbXBhcmlzb25cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ29tcGFyZSAxMSBGZWJydWFyeSAxOTg3IGFuZCAxMCBKdWx5IDE5ODk6XG4gKiB2YXIgcmVzdWx0ID0gY29tcGFyZUFzYyhcbiAqICAgbmV3IERhdGUoMTk4NywgMSwgMTEpLFxuICogICBuZXcgRGF0ZSgxOTg5LCA2LCAxMClcbiAqIClcbiAqIC8vPT4gLTFcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU29ydCB0aGUgYXJyYXkgb2YgZGF0ZXM6XG4gKiB2YXIgcmVzdWx0ID0gW1xuICogICBuZXcgRGF0ZSgxOTk1LCA2LCAyKSxcbiAqICAgbmV3IERhdGUoMTk4NywgMSwgMTEpLFxuICogICBuZXcgRGF0ZSgxOTg5LCA2LCAxMClcbiAqIF0uc29ydChjb21wYXJlQXNjKVxuICogLy89PiBbXG4gKiAvLyAgIFdlZCBGZWIgMTEgMTk4NyAwMDowMDowMCxcbiAqIC8vICAgTW9uIEp1bCAxMCAxOTg5IDAwOjAwOjAwLFxuICogLy8gICBTdW4gSnVsIDAyIDE5OTUgMDA6MDA6MDBcbiAqIC8vIF1cbiAqL1xuZnVuY3Rpb24gY29tcGFyZUFzYyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIHRpbWVMZWZ0ID0gZGF0ZUxlZnQuZ2V0VGltZSgpXG4gIHZhciBkYXRlUmlnaHQgPSBwYXJzZShkaXJ0eURhdGVSaWdodClcbiAgdmFyIHRpbWVSaWdodCA9IGRhdGVSaWdodC5nZXRUaW1lKClcblxuICBpZiAodGltZUxlZnQgPCB0aW1lUmlnaHQpIHtcbiAgICByZXR1cm4gLTFcbiAgfSBlbHNlIGlmICh0aW1lTGVmdCA+IHRpbWVSaWdodCkge1xuICAgIHJldHVybiAxXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDBcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBhcmVBc2NcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgQ29tbW9uIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IENvbXBhcmUgdGhlIHR3byBkYXRlcyByZXZlcnNlIGNocm9ub2xvZ2ljYWxseSBhbmQgcmV0dXJuIC0xLCAwIG9yIDEuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBDb21wYXJlIHRoZSB0d28gZGF0ZXMgYW5kIHJldHVybiAtMSBpZiB0aGUgZmlyc3QgZGF0ZSBpcyBhZnRlciB0aGUgc2Vjb25kLFxuICogMSBpZiB0aGUgZmlyc3QgZGF0ZSBpcyBiZWZvcmUgdGhlIHNlY29uZCBvciAwIGlmIGRhdGVzIGFyZSBlcXVhbC5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgZmlyc3QgZGF0ZSB0byBjb21wYXJlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIHNlY29uZCBkYXRlIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSByZXN1bHQgb2YgdGhlIGNvbXBhcmlzb25cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ29tcGFyZSAxMSBGZWJydWFyeSAxOTg3IGFuZCAxMCBKdWx5IDE5ODkgcmV2ZXJzZSBjaHJvbm9sb2dpY2FsbHk6XG4gKiB2YXIgcmVzdWx0ID0gY29tcGFyZURlc2MoXG4gKiAgIG5ldyBEYXRlKDE5ODcsIDEsIDExKSxcbiAqICAgbmV3IERhdGUoMTk4OSwgNiwgMTApXG4gKiApXG4gKiAvLz0+IDFcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU29ydCB0aGUgYXJyYXkgb2YgZGF0ZXMgaW4gcmV2ZXJzZSBjaHJvbm9sb2dpY2FsIG9yZGVyOlxuICogdmFyIHJlc3VsdCA9IFtcbiAqICAgbmV3IERhdGUoMTk5NSwgNiwgMiksXG4gKiAgIG5ldyBEYXRlKDE5ODcsIDEsIDExKSxcbiAqICAgbmV3IERhdGUoMTk4OSwgNiwgMTApXG4gKiBdLnNvcnQoY29tcGFyZURlc2MpXG4gKiAvLz0+IFtcbiAqIC8vICAgU3VuIEp1bCAwMiAxOTk1IDAwOjAwOjAwLFxuICogLy8gICBNb24gSnVsIDEwIDE5ODkgMDA6MDA6MDAsXG4gKiAvLyAgIFdlZCBGZWIgMTEgMTk4NyAwMDowMDowMFxuICogLy8gXVxuICovXG5mdW5jdGlvbiBjb21wYXJlRGVzYyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIHRpbWVMZWZ0ID0gZGF0ZUxlZnQuZ2V0VGltZSgpXG4gIHZhciBkYXRlUmlnaHQgPSBwYXJzZShkaXJ0eURhdGVSaWdodClcbiAgdmFyIHRpbWVSaWdodCA9IGRhdGVSaWdodC5nZXRUaW1lKClcblxuICBpZiAodGltZUxlZnQgPiB0aW1lUmlnaHQpIHtcbiAgICByZXR1cm4gLTFcbiAgfSBlbHNlIGlmICh0aW1lTGVmdCA8IHRpbWVSaWdodCkge1xuICAgIHJldHVybiAxXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDBcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBhcmVEZXNjXG4iLCJ2YXIgc3RhcnRPZkRheSA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2RheS9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFID0gNjAwMDBcbnZhciBNSUxMSVNFQ09ORFNfSU5fREFZID0gODY0MDAwMDBcblxuLyoqXG4gKiBAY2F0ZWdvcnkgRGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIGRheXMgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG51bWJlciBvZiBjYWxlbmRhciBkYXlzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBsYXRlciBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIGVhcmxpZXIgZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG51bWJlciBvZiBjYWxlbmRhciBkYXlzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGNhbGVuZGFyIGRheXMgYXJlIGJldHdlZW5cbiAqIC8vIDIgSnVseSAyMDExIDIzOjAwOjAwIGFuZCAyIEp1bHkgMjAxMiAwMDowMDowMD9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5DYWxlbmRhckRheXMoXG4gKiAgIG5ldyBEYXRlKDIwMTIsIDYsIDIsIDAsIDApLFxuICogICBuZXcgRGF0ZSgyMDExLCA2LCAyLCAyMywgMClcbiAqIClcbiAqIC8vPT4gMzY2XG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJbkNhbGVuZGFyRGF5cyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIHN0YXJ0T2ZEYXlMZWZ0ID0gc3RhcnRPZkRheShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgc3RhcnRPZkRheVJpZ2h0ID0gc3RhcnRPZkRheShkaXJ0eURhdGVSaWdodClcblxuICB2YXIgdGltZXN0YW1wTGVmdCA9IHN0YXJ0T2ZEYXlMZWZ0LmdldFRpbWUoKSAtXG4gICAgc3RhcnRPZkRheUxlZnQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIE1JTExJU0VDT05EU19JTl9NSU5VVEVcbiAgdmFyIHRpbWVzdGFtcFJpZ2h0ID0gc3RhcnRPZkRheVJpZ2h0LmdldFRpbWUoKSAtXG4gICAgc3RhcnRPZkRheVJpZ2h0LmdldFRpbWV6b25lT2Zmc2V0KCkgKiBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFXG5cbiAgLy8gUm91bmQgdGhlIG51bWJlciBvZiBkYXlzIHRvIHRoZSBuZWFyZXN0IGludGVnZXJcbiAgLy8gYmVjYXVzZSB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpbiBhIGRheSBpcyBub3QgY29uc3RhbnRcbiAgLy8gKGUuZy4gaXQncyBkaWZmZXJlbnQgaW4gdGhlIGRheSBvZiB0aGUgZGF5bGlnaHQgc2F2aW5nIHRpbWUgY2xvY2sgc2hpZnQpXG4gIHJldHVybiBNYXRoLnJvdW5kKCh0aW1lc3RhbXBMZWZ0IC0gdGltZXN0YW1wUmlnaHQpIC8gTUlMTElTRUNPTkRTX0lOX0RBWSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5DYWxlbmRhckRheXNcbiIsInZhciBzdGFydE9mSVNPV2VlayA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2lzb193ZWVrL2luZGV4LmpzJylcblxudmFyIE1JTExJU0VDT05EU19JTl9NSU5VVEUgPSA2MDAwMFxudmFyIE1JTExJU0VDT05EU19JTl9XRUVLID0gNjA0ODAwMDAwXG5cbi8qKlxuICogQGNhdGVnb3J5IElTTyBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIElTTyB3ZWVrcyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIElTTyB3ZWVrcyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGxhdGVyIGRhdGVcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgZWFybGllciBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIElTTyB3ZWVrc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIb3cgbWFueSBjYWxlbmRhciBJU08gd2Vla3MgYXJlIGJldHdlZW4gNiBKdWx5IDIwMTQgYW5kIDIxIEp1bHkgMjAxND9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5DYWxlbmRhcklTT1dlZWtzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyMSksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDYsIDYpXG4gKiApXG4gKiAvLz0+IDNcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluQ2FsZW5kYXJJU09XZWVrcyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIHN0YXJ0T2ZJU09XZWVrTGVmdCA9IHN0YXJ0T2ZJU09XZWVrKGRpcnR5RGF0ZUxlZnQpXG4gIHZhciBzdGFydE9mSVNPV2Vla1JpZ2h0ID0gc3RhcnRPZklTT1dlZWsoZGlydHlEYXRlUmlnaHQpXG5cbiAgdmFyIHRpbWVzdGFtcExlZnQgPSBzdGFydE9mSVNPV2Vla0xlZnQuZ2V0VGltZSgpIC1cbiAgICBzdGFydE9mSVNPV2Vla0xlZnQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIE1JTExJU0VDT05EU19JTl9NSU5VVEVcbiAgdmFyIHRpbWVzdGFtcFJpZ2h0ID0gc3RhcnRPZklTT1dlZWtSaWdodC5nZXRUaW1lKCkgLVxuICAgIHN0YXJ0T2ZJU09XZWVrUmlnaHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIE1JTExJU0VDT05EU19JTl9NSU5VVEVcblxuICAvLyBSb3VuZCB0aGUgbnVtYmVyIG9mIGRheXMgdG8gdGhlIG5lYXJlc3QgaW50ZWdlclxuICAvLyBiZWNhdXNlIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGluIGEgd2VlayBpcyBub3QgY29uc3RhbnRcbiAgLy8gKGUuZy4gaXQncyBkaWZmZXJlbnQgaW4gdGhlIHdlZWsgb2YgdGhlIGRheWxpZ2h0IHNhdmluZyB0aW1lIGNsb2NrIHNoaWZ0KVxuICByZXR1cm4gTWF0aC5yb3VuZCgodGltZXN0YW1wTGVmdCAtIHRpbWVzdGFtcFJpZ2h0KSAvIE1JTExJU0VDT05EU19JTl9XRUVLKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPV2Vla3NcbiIsInZhciBnZXRJU09ZZWFyID0gcmVxdWlyZSgnLi4vZ2V0X2lzb195ZWFyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWstTnVtYmVyaW5nIFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGNhbGVuZGFyIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFycyBhcmUgMSBKYW51YXJ5IDIwMTAgYW5kIDEgSmFudWFyeSAyMDEyP1xuICogdmFyIHJlc3VsdCA9IGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPWWVhcnMoXG4gKiAgIG5ldyBEYXRlKDIwMTIsIDAsIDEpLFxuICogICBuZXcgRGF0ZSgyMDEwLCAwLCAxKVxuICogKVxuICogLy89PiAyXG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPWWVhcnMgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHJldHVybiBnZXRJU09ZZWFyKGRpcnR5RGF0ZUxlZnQpIC0gZ2V0SVNPWWVhcihkaXJ0eURhdGVSaWdodClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5DYWxlbmRhcklTT1llYXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1vbnRoIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIG1vbnRocyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIG1vbnRocyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgbW9udGhzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGNhbGVuZGFyIG1vbnRocyBhcmUgYmV0d2VlbiAzMSBKYW51YXJ5IDIwMTQgYW5kIDEgU2VwdGVtYmVyIDIwMTQ/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJNb250aHMoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDEpLFxuICogICBuZXcgRGF0ZSgyMDE0LCAwLCAzMSlcbiAqIClcbiAqIC8vPT4gOFxuICovXG5mdW5jdGlvbiBkaWZmZXJlbmNlSW5DYWxlbmRhck1vbnRocyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHZhciB5ZWFyRGlmZiA9IGRhdGVMZWZ0LmdldEZ1bGxZZWFyKCkgLSBkYXRlUmlnaHQuZ2V0RnVsbFllYXIoKVxuICB2YXIgbW9udGhEaWZmID0gZGF0ZUxlZnQuZ2V0TW9udGgoKSAtIGRhdGVSaWdodC5nZXRNb250aCgpXG5cbiAgcmV0dXJuIHllYXJEaWZmICogMTIgKyBtb250aERpZmZcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5DYWxlbmRhck1vbnRoc1xuIiwidmFyIGdldFF1YXJ0ZXIgPSByZXF1aXJlKCcuLi9nZXRfcXVhcnRlci9pbmRleC5qcycpXG52YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFF1YXJ0ZXIgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgcXVhcnRlcnMgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG51bWJlciBvZiBjYWxlbmRhciBxdWFydGVycyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgcXVhcnRlcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgY2FsZW5kYXIgcXVhcnRlcnMgYXJlIGJldHdlZW4gMzEgRGVjZW1iZXIgMjAxMyBhbmQgMiBKdWx5IDIwMTQ/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJRdWFydGVycyhcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMiksXG4gKiAgIG5ldyBEYXRlKDIwMTMsIDExLCAzMSlcbiAqIClcbiAqIC8vPT4gM1xuICovXG5mdW5jdGlvbiBkaWZmZXJlbmNlSW5DYWxlbmRhclF1YXJ0ZXJzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlUmlnaHQpXG5cbiAgdmFyIHllYXJEaWZmID0gZGF0ZUxlZnQuZ2V0RnVsbFllYXIoKSAtIGRhdGVSaWdodC5nZXRGdWxsWWVhcigpXG4gIHZhciBxdWFydGVyRGlmZiA9IGdldFF1YXJ0ZXIoZGF0ZUxlZnQpIC0gZ2V0UXVhcnRlcihkYXRlUmlnaHQpXG5cbiAgcmV0dXJuIHllYXJEaWZmICogNCArIHF1YXJ0ZXJEaWZmXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJRdWFydGVyc1xuIiwidmFyIHN0YXJ0T2ZXZWVrID0gcmVxdWlyZSgnLi4vc3RhcnRfb2Zfd2Vlay9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFID0gNjAwMDBcbnZhciBNSUxMSVNFQ09ORFNfSU5fV0VFSyA9IDYwNDgwMDAwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIHdlZWtzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgd2Vla3MgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGxhdGVyIGRhdGVcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgZWFybGllciBkYXRlXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gdGhlIG9iamVjdCB3aXRoIG9wdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy53ZWVrU3RhcnRzT249MF0gLSB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayAoMCAtIFN1bmRheSlcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgd2Vla3NcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgY2FsZW5kYXIgd2Vla3MgYXJlIGJldHdlZW4gNSBKdWx5IDIwMTQgYW5kIDIwIEp1bHkgMjAxND9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5DYWxlbmRhcldlZWtzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyMCksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDYsIDUpXG4gKiApXG4gKiAvLz0+IDNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdGhlIHdlZWsgc3RhcnRzIG9uIE1vbmRheSxcbiAqIC8vIGhvdyBtYW55IGNhbGVuZGFyIHdlZWtzIGFyZSBiZXR3ZWVuIDUgSnVseSAyMDE0IGFuZCAyMCBKdWx5IDIwMTQ/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJXZWVrcyhcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMjApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCA1KSxcbiAqICAge3dlZWtTdGFydHNPbjogMX1cbiAqIClcbiAqIC8vPT4gMlxuICovXG5mdW5jdGlvbiBkaWZmZXJlbmNlSW5DYWxlbmRhcldlZWtzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCwgZGlydHlPcHRpb25zKSB7XG4gIHZhciBzdGFydE9mV2Vla0xlZnQgPSBzdGFydE9mV2VlayhkaXJ0eURhdGVMZWZ0LCBkaXJ0eU9wdGlvbnMpXG4gIHZhciBzdGFydE9mV2Vla1JpZ2h0ID0gc3RhcnRPZldlZWsoZGlydHlEYXRlUmlnaHQsIGRpcnR5T3B0aW9ucylcblxuICB2YXIgdGltZXN0YW1wTGVmdCA9IHN0YXJ0T2ZXZWVrTGVmdC5nZXRUaW1lKCkgLVxuICAgIHN0YXJ0T2ZXZWVrTGVmdC5nZXRUaW1lem9uZU9mZnNldCgpICogTUlMTElTRUNPTkRTX0lOX01JTlVURVxuICB2YXIgdGltZXN0YW1wUmlnaHQgPSBzdGFydE9mV2Vla1JpZ2h0LmdldFRpbWUoKSAtXG4gICAgc3RhcnRPZldlZWtSaWdodC5nZXRUaW1lem9uZU9mZnNldCgpICogTUlMTElTRUNPTkRTX0lOX01JTlVURVxuXG4gIC8vIFJvdW5kIHRoZSBudW1iZXIgb2YgZGF5cyB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyXG4gIC8vIGJlY2F1c2UgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaW4gYSB3ZWVrIGlzIG5vdCBjb25zdGFudFxuICAvLyAoZS5nLiBpdCdzIGRpZmZlcmVudCBpbiB0aGUgd2VlayBvZiB0aGUgZGF5bGlnaHQgc2F2aW5nIHRpbWUgY2xvY2sgc2hpZnQpXG4gIHJldHVybiBNYXRoLnJvdW5kKCh0aW1lc3RhbXBMZWZ0IC0gdGltZXN0YW1wUmlnaHQpIC8gTUlMTElTRUNPTkRTX0lOX1dFRUspXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJXZWVrc1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBZZWFyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIHllYXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgY2FsZW5kYXIgeWVhcnMgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGxhdGVyIGRhdGVcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgZWFybGllciBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbnVtYmVyIG9mIGNhbGVuZGFyIHllYXJzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGNhbGVuZGFyIHllYXJzIGFyZSBiZXR3ZWVuIDMxIERlY2VtYmVyIDIwMTMgYW5kIDExIEZlYnJ1YXJ5IDIwMTU/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluQ2FsZW5kYXJZZWFycyhcbiAqICAgbmV3IERhdGUoMjAxNSwgMSwgMTEpLFxuICogICBuZXcgRGF0ZSgyMDEzLCAxMSwgMzEpXG4gKiApXG4gKiAvLz0+IDJcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluQ2FsZW5kYXJZZWFycyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHJldHVybiBkYXRlTGVmdC5nZXRGdWxsWWVhcigpIC0gZGF0ZVJpZ2h0LmdldEZ1bGxZZWFyKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5DYWxlbmRhclllYXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgZGlmZmVyZW5jZUluQ2FsZW5kYXJEYXlzID0gcmVxdWlyZSgnLi4vZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9kYXlzL2luZGV4LmpzJylcbnZhciBjb21wYXJlQXNjID0gcmVxdWlyZSgnLi4vY29tcGFyZV9hc2MvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBudW1iZXIgb2YgZnVsbCBkYXlzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgZnVsbCBkYXlzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBsYXRlciBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIGVhcmxpZXIgZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG51bWJlciBvZiBmdWxsIGRheXNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgZnVsbCBkYXlzIGFyZSBiZXR3ZWVuXG4gKiAvLyAyIEp1bHkgMjAxMSAyMzowMDowMCBhbmQgMiBKdWx5IDIwMTIgMDA6MDA6MDA/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluRGF5cyhcbiAqICAgbmV3IERhdGUoMjAxMiwgNiwgMiwgMCwgMCksXG4gKiAgIG5ldyBEYXRlKDIwMTEsIDYsIDIsIDIzLCAwKVxuICogKVxuICogLy89PiAzNjVcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluRGF5cyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHZhciBzaWduID0gY29tcGFyZUFzYyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KVxuICB2YXIgZGlmZmVyZW5jZSA9IE1hdGguYWJzKGRpZmZlcmVuY2VJbkNhbGVuZGFyRGF5cyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KSlcbiAgZGF0ZUxlZnQuc2V0RGF0ZShkYXRlTGVmdC5nZXREYXRlKCkgLSBzaWduICogZGlmZmVyZW5jZSlcblxuICAvLyBNYXRoLmFicyhkaWZmIGluIGZ1bGwgZGF5cyAtIGRpZmYgaW4gY2FsZW5kYXIgZGF5cykgPT09IDEgaWYgbGFzdCBjYWxlbmRhciBkYXkgaXMgbm90IGZ1bGxcbiAgLy8gSWYgc28sIHJlc3VsdCBtdXN0IGJlIGRlY3JlYXNlZCBieSAxIGluIGFic29sdXRlIHZhbHVlXG4gIHZhciBpc0xhc3REYXlOb3RGdWxsID0gY29tcGFyZUFzYyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KSA9PT0gLXNpZ25cbiAgcmV0dXJuIHNpZ24gKiAoZGlmZmVyZW5jZSAtIGlzTGFzdERheU5vdEZ1bGwpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluRGF5c1xuIiwidmFyIGRpZmZlcmVuY2VJbk1pbGxpc2Vjb25kcyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fbWlsbGlzZWNvbmRzL2luZGV4LmpzJylcblxudmFyIE1JTExJU0VDT05EU19JTl9IT1VSID0gMzYwMDAwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBIb3VyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGhvdXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgaG91cnMgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGxhdGVyIGRhdGVcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgZWFybGllciBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbnVtYmVyIG9mIGhvdXJzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGhvdXJzIGFyZSBiZXR3ZWVuIDIgSnVseSAyMDE0IDA2OjUwOjAwIGFuZCAyIEp1bHkgMjAxNCAxOTowMDowMD9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5Ib3VycyhcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMiwgMTksIDApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCA2LCA1MClcbiAqIClcbiAqIC8vPT4gMTJcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluSG91cnMgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHZhciBkaWZmID0gZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSAvIE1JTExJU0VDT05EU19JTl9IT1VSXG4gIHJldHVybiBkaWZmID4gMCA/IE1hdGguZmxvb3IoZGlmZikgOiBNYXRoLmNlaWwoZGlmZilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5Ib3Vyc1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPWWVhcnMgPSByZXF1aXJlKCcuLi9kaWZmZXJlbmNlX2luX2NhbGVuZGFyX2lzb195ZWFycy9pbmRleC5qcycpXG52YXIgY29tcGFyZUFzYyA9IHJlcXVpcmUoJy4uL2NvbXBhcmVfYXNjL2luZGV4LmpzJylcbnZhciBzdWJJU09ZZWFycyA9IHJlcXVpcmUoJy4uL3N1Yl9pc29feWVhcnMvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2Vlay1OdW1iZXJpbmcgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBmdWxsIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFycyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGZ1bGwgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgZnVsbCBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgZnVsbCBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnMgYXJlIGJldHdlZW4gMSBKYW51YXJ5IDIwMTAgYW5kIDEgSmFudWFyeSAyMDEyP1xuICogdmFyIHJlc3VsdCA9IGRpZmZlcmVuY2VJbklTT1llYXJzKFxuICogICBuZXcgRGF0ZSgyMDEyLCAwLCAxKSxcbiAqICAgbmV3IERhdGUoMjAxMCwgMCwgMSlcbiAqIClcbiAqIC8vPT4gMVxuICovXG5mdW5jdGlvbiBkaWZmZXJlbmNlSW5JU09ZZWFycyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHZhciBzaWduID0gY29tcGFyZUFzYyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KVxuICB2YXIgZGlmZmVyZW5jZSA9IE1hdGguYWJzKGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPWWVhcnMoZGF0ZUxlZnQsIGRhdGVSaWdodCkpXG4gIGRhdGVMZWZ0ID0gc3ViSVNPWWVhcnMoZGF0ZUxlZnQsIHNpZ24gKiBkaWZmZXJlbmNlKVxuXG4gIC8vIE1hdGguYWJzKGRpZmYgaW4gZnVsbCBJU08geWVhcnMgLSBkaWZmIGluIGNhbGVuZGFyIElTTyB5ZWFycykgPT09IDFcbiAgLy8gaWYgbGFzdCBjYWxlbmRhciBJU08geWVhciBpcyBub3QgZnVsbFxuICAvLyBJZiBzbywgcmVzdWx0IG11c3QgYmUgZGVjcmVhc2VkIGJ5IDEgaW4gYWJzb2x1dGUgdmFsdWVcbiAgdmFyIGlzTGFzdElTT1llYXJOb3RGdWxsID0gY29tcGFyZUFzYyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KSA9PT0gLXNpZ25cbiAgcmV0dXJuIHNpZ24gKiAoZGlmZmVyZW5jZSAtIGlzTGFzdElTT1llYXJOb3RGdWxsKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZlcmVuY2VJbklTT1llYXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbGxpc2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IG1pbGxpc2Vjb25kcyBhcmUgYmV0d2VlblxuICogLy8gMiBKdWx5IDIwMTQgMTI6MzA6MjAuNjAwIGFuZCAyIEp1bHkgMjAxNCAxMjozMDoyMS43MDA/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCAxMiwgMzAsIDIxLCA3MDApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCAxMiwgMzAsIDIwLCA2MDApXG4gKiApXG4gKiAvLz0+IDExMDBcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlUmlnaHQpXG4gIHJldHVybiBkYXRlTGVmdC5nZXRUaW1lKCkgLSBkYXRlUmlnaHQuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzXG4iLCJ2YXIgZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzID0gcmVxdWlyZSgnLi4vZGlmZmVyZW5jZV9pbl9taWxsaXNlY29uZHMvaW5kZXguanMnKVxuXG52YXIgTUlMTElTRUNPTkRTX0lOX01JTlVURSA9IDYwMDAwXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbnV0ZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBtaW51dGVzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgbWludXRlcyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgbWludXRlc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIb3cgbWFueSBtaW51dGVzIGFyZSBiZXR3ZWVuIDIgSnVseSAyMDE0IDEyOjA3OjU5IGFuZCAyIEp1bHkgMjAxNCAxMjoyMDowMD9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5NaW51dGVzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCAxMiwgMjAsIDApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCAxMiwgNywgNTkpXG4gKiApXG4gKiAvLz0+IDEyXG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJbk1pbnV0ZXMgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHZhciBkaWZmID0gZGlmZmVyZW5jZUluTWlsbGlzZWNvbmRzKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSAvIE1JTExJU0VDT05EU19JTl9NSU5VVEVcbiAgcmV0dXJuIGRpZmYgPiAwID8gTWF0aC5mbG9vcihkaWZmKSA6IE1hdGguY2VpbChkaWZmKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZlcmVuY2VJbk1pbnV0ZXNcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBkaWZmZXJlbmNlSW5DYWxlbmRhck1vbnRocyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fY2FsZW5kYXJfbW9udGhzL2luZGV4LmpzJylcbnZhciBjb21wYXJlQXNjID0gcmVxdWlyZSgnLi4vY29tcGFyZV9hc2MvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBmdWxsIG1vbnRocyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGZ1bGwgbW9udGhzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBsYXRlciBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIGVhcmxpZXIgZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG51bWJlciBvZiBmdWxsIG1vbnRoc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIb3cgbWFueSBmdWxsIG1vbnRocyBhcmUgYmV0d2VlbiAzMSBKYW51YXJ5IDIwMTQgYW5kIDEgU2VwdGVtYmVyIDIwMTQ/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluTW9udGhzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA4LCAxKSxcbiAqICAgbmV3IERhdGUoMjAxNCwgMCwgMzEpXG4gKiApXG4gKiAvLz0+IDdcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluTW9udGhzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlUmlnaHQpXG5cbiAgdmFyIHNpZ24gPSBjb21wYXJlQXNjKGRhdGVMZWZ0LCBkYXRlUmlnaHQpXG4gIHZhciBkaWZmZXJlbmNlID0gTWF0aC5hYnMoZGlmZmVyZW5jZUluQ2FsZW5kYXJNb250aHMoZGF0ZUxlZnQsIGRhdGVSaWdodCkpXG4gIGRhdGVMZWZ0LnNldE1vbnRoKGRhdGVMZWZ0LmdldE1vbnRoKCkgLSBzaWduICogZGlmZmVyZW5jZSlcblxuICAvLyBNYXRoLmFicyhkaWZmIGluIGZ1bGwgbW9udGhzIC0gZGlmZiBpbiBjYWxlbmRhciBtb250aHMpID09PSAxIGlmIGxhc3QgY2FsZW5kYXIgbW9udGggaXMgbm90IGZ1bGxcbiAgLy8gSWYgc28sIHJlc3VsdCBtdXN0IGJlIGRlY3JlYXNlZCBieSAxIGluIGFic29sdXRlIHZhbHVlXG4gIHZhciBpc0xhc3RNb250aE5vdEZ1bGwgPSBjb21wYXJlQXNjKGRhdGVMZWZ0LCBkYXRlUmlnaHQpID09PSAtc2lnblxuICByZXR1cm4gc2lnbiAqIChkaWZmZXJlbmNlIC0gaXNMYXN0TW9udGhOb3RGdWxsKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZlcmVuY2VJbk1vbnRoc1xuIiwidmFyIGRpZmZlcmVuY2VJbk1vbnRocyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fbW9udGhzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgUXVhcnRlciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBmdWxsIHF1YXJ0ZXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgZnVsbCBxdWFydGVycyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgZnVsbCBxdWFydGVyc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIb3cgbWFueSBmdWxsIHF1YXJ0ZXJzIGFyZSBiZXR3ZWVuIDMxIERlY2VtYmVyIDIwMTMgYW5kIDIgSnVseSAyMDE0P1xuICogdmFyIHJlc3VsdCA9IGRpZmZlcmVuY2VJblF1YXJ0ZXJzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyKSxcbiAqICAgbmV3IERhdGUoMjAxMywgMTEsIDMxKVxuICogKVxuICogLy89PiAyXG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJblF1YXJ0ZXJzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGlmZiA9IGRpZmZlcmVuY2VJbk1vbnRocyhkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkgLyAzXG4gIHJldHVybiBkaWZmID4gMCA/IE1hdGguZmxvb3IoZGlmZikgOiBNYXRoLmNlaWwoZGlmZilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaWZmZXJlbmNlSW5RdWFydGVyc1xuIiwidmFyIGRpZmZlcmVuY2VJbk1pbGxpc2Vjb25kcyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fbWlsbGlzZWNvbmRzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgU2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIHNlY29uZHMgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG51bWJlciBvZiBzZWNvbmRzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBsYXRlciBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIGVhcmxpZXIgZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG51bWJlciBvZiBzZWNvbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IHNlY29uZHMgYXJlIGJldHdlZW5cbiAqIC8vIDIgSnVseSAyMDE0IDEyOjMwOjA3Ljk5OSBhbmQgMiBKdWx5IDIwMTQgMTI6MzA6MjAuMDAwP1xuICogdmFyIHJlc3VsdCA9IGRpZmZlcmVuY2VJblNlY29uZHMoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDYsIDIsIDEyLCAzMCwgMjAsIDApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCAxMiwgMzAsIDcsIDk5OSlcbiAqIClcbiAqIC8vPT4gMTJcbiAqL1xuZnVuY3Rpb24gZGlmZmVyZW5jZUluU2Vjb25kcyAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRpZmYgPSBkaWZmZXJlbmNlSW5NaWxsaXNlY29uZHMoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIC8gMTAwMFxuICByZXR1cm4gZGlmZiA+IDAgPyBNYXRoLmZsb29yKGRpZmYpIDogTWF0aC5jZWlsKGRpZmYpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluU2Vjb25kc1xuIiwidmFyIGRpZmZlcmVuY2VJbkRheXMgPSByZXF1aXJlKCcuLi9kaWZmZXJlbmNlX2luX2RheXMvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbnVtYmVyIG9mIGZ1bGwgd2Vla3MgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG51bWJlciBvZiBmdWxsIHdlZWtzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBsYXRlciBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIGVhcmxpZXIgZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG51bWJlciBvZiBmdWxsIHdlZWtzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGZ1bGwgd2Vla3MgYXJlIGJldHdlZW4gNSBKdWx5IDIwMTQgYW5kIDIwIEp1bHkgMjAxND9cbiAqIHZhciByZXN1bHQgPSBkaWZmZXJlbmNlSW5XZWVrcyhcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMjApLFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCA1KVxuICogKVxuICogLy89PiAyXG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJbldlZWtzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGlmZiA9IGRpZmZlcmVuY2VJbkRheXMoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIC8gN1xuICByZXR1cm4gZGlmZiA+IDAgPyBNYXRoLmZsb29yKGRpZmYpIDogTWF0aC5jZWlsKGRpZmYpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZmVyZW5jZUluV2Vla3NcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBkaWZmZXJlbmNlSW5DYWxlbmRhclllYXJzID0gcmVxdWlyZSgnLi4vZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl95ZWFycy9pbmRleC5qcycpXG52YXIgY29tcGFyZUFzYyA9IHJlcXVpcmUoJy4uL2NvbXBhcmVfYXNjL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBmdWxsIHllYXJzIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgZnVsbCB5ZWFycyBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgbGF0ZXIgZGF0ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBlYXJsaWVyIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgZnVsbCB5ZWFyc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIb3cgbWFueSBmdWxsIHllYXJzIGFyZSBiZXR3ZWVuIDMxIERlY2VtYmVyIDIwMTMgYW5kIDExIEZlYnJ1YXJ5IDIwMTU/XG4gKiB2YXIgcmVzdWx0ID0gZGlmZmVyZW5jZUluWWVhcnMoXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDEsIDExKSxcbiAqICAgbmV3IERhdGUoMjAxMywgMTEsIDMxKVxuICogKVxuICogLy89PiAxXG4gKi9cbmZ1bmN0aW9uIGRpZmZlcmVuY2VJblllYXJzIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlUmlnaHQpXG5cbiAgdmFyIHNpZ24gPSBjb21wYXJlQXNjKGRhdGVMZWZ0LCBkYXRlUmlnaHQpXG4gIHZhciBkaWZmZXJlbmNlID0gTWF0aC5hYnMoZGlmZmVyZW5jZUluQ2FsZW5kYXJZZWFycyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KSlcbiAgZGF0ZUxlZnQuc2V0RnVsbFllYXIoZGF0ZUxlZnQuZ2V0RnVsbFllYXIoKSAtIHNpZ24gKiBkaWZmZXJlbmNlKVxuXG4gIC8vIE1hdGguYWJzKGRpZmYgaW4gZnVsbCB5ZWFycyAtIGRpZmYgaW4gY2FsZW5kYXIgeWVhcnMpID09PSAxIGlmIGxhc3QgY2FsZW5kYXIgeWVhciBpcyBub3QgZnVsbFxuICAvLyBJZiBzbywgcmVzdWx0IG11c3QgYmUgZGVjcmVhc2VkIGJ5IDEgaW4gYWJzb2x1dGUgdmFsdWVcbiAgdmFyIGlzTGFzdFllYXJOb3RGdWxsID0gY29tcGFyZUFzYyhkYXRlTGVmdCwgZGF0ZVJpZ2h0KSA9PT0gLXNpZ25cbiAgcmV0dXJuIHNpZ24gKiAoZGlmZmVyZW5jZSAtIGlzTGFzdFllYXJOb3RGdWxsKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZlcmVuY2VJblllYXJzXG4iLCJ2YXIgY29tcGFyZURlc2MgPSByZXF1aXJlKCcuLi9jb21wYXJlX2Rlc2MvaW5kZXguanMnKVxudmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIGRpZmZlcmVuY2VJblNlY29uZHMgPSByZXF1aXJlKCcuLi9kaWZmZXJlbmNlX2luX3NlY29uZHMvaW5kZXguanMnKVxudmFyIGRpZmZlcmVuY2VJbk1vbnRocyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fbW9udGhzL2luZGV4LmpzJylcbnZhciBlbkxvY2FsZSA9IHJlcXVpcmUoJy4uL2xvY2FsZS9lbi9pbmRleC5qcycpXG5cbnZhciBNSU5VVEVTX0lOX0RBWSA9IDE0NDBcbnZhciBNSU5VVEVTX0lOX0FMTU9TVF9UV09fREFZUyA9IDI1MjBcbnZhciBNSU5VVEVTX0lOX01PTlRIID0gNDMyMDBcbnZhciBNSU5VVEVTX0lOX1RXT19NT05USFMgPSA4NjQwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBDb21tb24gSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcyBpbiB3b3Jkcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZXMgaW4gd29yZHMuXG4gKlxuICogfCBEaXN0YW5jZSBiZXR3ZWVuIGRhdGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFJlc3VsdCAgICAgICAgICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogfCAwIC4uLiAzMCBzZWNzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGxlc3MgdGhhbiBhIG1pbnV0ZSAgfFxuICogfCAzMCBzZWNzIC4uLiAxIG1pbiAzMCBzZWNzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEgbWludXRlICAgICAgICAgICAgfFxuICogfCAxIG1pbiAzMCBzZWNzIC4uLiA0NCBtaW5zIDMwIHNlY3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFsyLi40NF0gbWludXRlcyAgICAgfFxuICogfCA0NCBtaW5zIC4uLiAzMCBzZWNzIC4uLiA4OSBtaW5zIDMwIHNlY3MgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFib3V0IDEgaG91ciAgICAgICAgfFxuICogfCA4OSBtaW5zIDMwIHNlY3MgLi4uIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgICAgICAgICAgICAgICAgICAgICAgICB8IGFib3V0IFsyLi4yNF0gaG91cnMgfFxuICogfCAyMyBocnMgNTkgbWlucyAzMCBzZWNzIC4uLiA0MSBocnMgNTkgbWlucyAzMCBzZWNzICAgICAgICAgICAgICAgICB8IDEgZGF5ICAgICAgICAgICAgICAgfFxuICogfCA0MSBocnMgNTkgbWlucyAzMCBzZWNzIC4uLiAyOSBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgICAgICAgICB8IFsyLi4zMF0gZGF5cyAgICAgICAgfFxuICogfCAyOSBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgLi4uIDQ0IGRheXMgMjMgaHJzIDU5IG1pbnMgMzAgc2VjcyB8IGFib3V0IDEgbW9udGggICAgICAgfFxuICogfCA0NCBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgLi4uIDU5IGRheXMgMjMgaHJzIDU5IG1pbnMgMzAgc2VjcyB8IGFib3V0IDIgbW9udGhzICAgICAgfFxuICogfCA1OSBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgLi4uIDEgeXIgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFsyLi4xMl0gbW9udGhzICAgICAgfFxuICogfCAxIHlyIC4uLiAxIHlyIDMgbW9udGhzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFib3V0IDEgeWVhciAgICAgICAgfFxuICogfCAxIHlyIDMgbW9udGhzIC4uLiAxIHlyIDkgbW9udGggcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG92ZXIgMSB5ZWFyICAgICAgICAgfFxuICogfCAxIHlyIDkgbW9udGhzIC4uLiAyIHlycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFsbW9zdCAyIHllYXJzICAgICAgfFxuICogfCBOIHlycyAuLi4gTiB5cnMgMyBtb250aHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFib3V0IE4geWVhcnMgICAgICAgfFxuICogfCBOIHlycyAzIG1vbnRocyAuLi4gTiB5cnMgOSBtb250aHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG92ZXIgTiB5ZWFycyAgICAgICAgfFxuICogfCBOIHlycyA5IG1vbnRocyAuLi4gTisxIHlycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFsbW9zdCBOKzEgeWVhcnMgICAgfFxuICpcbiAqIFdpdGggYG9wdGlvbnMuaW5jbHVkZVNlY29uZHMgPT0gdHJ1ZWA6XG4gKiB8IERpc3RhbmNlIGJldHdlZW4gZGF0ZXMgfCBSZXN1bHQgICAgICAgICAgICAgICB8XG4gKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gKiB8IDAgc2VjcyAuLi4gNSBzZWNzICAgICAgfCBsZXNzIHRoYW4gNSBzZWNvbmRzICB8XG4gKiB8IDUgc2VjcyAuLi4gMTAgc2VjcyAgICAgfCBsZXNzIHRoYW4gMTAgc2Vjb25kcyB8XG4gKiB8IDEwIHNlY3MgLi4uIDIwIHNlY3MgICAgfCBsZXNzIHRoYW4gMjAgc2Vjb25kcyB8XG4gKiB8IDIwIHNlY3MgLi4uIDQwIHNlY3MgICAgfCBoYWxmIGEgbWludXRlICAgICAgICB8XG4gKiB8IDQwIHNlY3MgLi4uIDYwIHNlY3MgICAgfCBsZXNzIHRoYW4gYSBtaW51dGUgICB8XG4gKiB8IDYwIHNlY3MgLi4uIDkwIHNlY3MgICAgfCAxIG1pbnV0ZSAgICAgICAgICAgICB8XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVUb0NvbXBhcmUgLSB0aGUgZGF0ZSB0byBjb21wYXJlIHdpdGhcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG90aGVyIGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB0aGUgb2JqZWN0IHdpdGggb3B0aW9uc1xuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5pbmNsdWRlU2Vjb25kcz1mYWxzZV0gLSBkaXN0YW5jZXMgbGVzcyB0aGFuIGEgbWludXRlIGFyZSBtb3JlIGRldGFpbGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmFkZFN1ZmZpeD1mYWxzZV0gLSByZXN1bHQgaW5kaWNhdGVzIGlmIHRoZSBzZWNvbmQgZGF0ZSBpcyBlYXJsaWVyIG9yIGxhdGVyIHRoYW4gdGhlIGZpcnN0XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubG9jYWxlPWVuTG9jYWxlXSAtIHRoZSBsb2NhbGUgb2JqZWN0XG4gKiBAcmV0dXJucyB7U3RyaW5nfSB0aGUgZGlzdGFuY2UgaW4gd29yZHNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hhdCBpcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiAyIEp1bHkgMjAxNCBhbmQgMSBKYW51YXJ5IDIwMTU/XG4gKiB2YXIgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzKFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyKSxcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSlcbiAqIClcbiAqIC8vPT4gJzYgbW9udGhzJ1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGF0IGlzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIDEgSmFudWFyeSAyMDE1IDAwOjAwOjE1XG4gKiAvLyBhbmQgMSBKYW51YXJ5IDIwMTUgMDA6MDA6MDAsIGluY2x1ZGluZyBzZWNvbmRzP1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3JkcyhcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSwgMCwgMCwgMTUpLFxuICogICBuZXcgRGF0ZSgyMDE1LCAwLCAxLCAwLCAwLCAwKSxcbiAqICAge2luY2x1ZGVTZWNvbmRzOiB0cnVlfVxuICogKVxuICogLy89PiAnbGVzcyB0aGFuIDIwIHNlY29uZHMnXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoYXQgaXMgdGhlIGRpc3RhbmNlIGZyb20gMSBKYW51YXJ5IDIwMTZcbiAqIC8vIHRvIDEgSmFudWFyeSAyMDE1LCB3aXRoIGEgc3VmZml4P1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3JkcyhcbiAqICAgbmV3IERhdGUoMjAxNiwgMCwgMSksXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDEpLFxuICogICB7YWRkU3VmZml4OiB0cnVlfVxuICogKVxuICogLy89PiAnYWJvdXQgMSB5ZWFyIGFnbydcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hhdCBpcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiAxIEF1Z3VzdCAyMDE2IGFuZCAxIEphbnVhcnkgMjAxNSBpbiBFc3BlcmFudG8/XG4gKiB2YXIgZW9Mb2NhbGUgPSByZXF1aXJlKCdkYXRlLWZucy9sb2NhbGUvZW8nKVxuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3JkcyhcbiAqICAgbmV3IERhdGUoMjAxNiwgNywgMSksXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDEpLFxuICogICB7bG9jYWxlOiBlb0xvY2FsZX1cbiAqIClcbiAqIC8vPT4gJ3BsaSBvbCAxIGphcm8nXG4gKi9cbmZ1bmN0aW9uIGRpc3RhbmNlSW5Xb3JkcyAoZGlydHlEYXRlVG9Db21wYXJlLCBkaXJ0eURhdGUsIGRpcnR5T3B0aW9ucykge1xuICB2YXIgb3B0aW9ucyA9IGRpcnR5T3B0aW9ucyB8fCB7fVxuXG4gIHZhciBjb21wYXJpc29uID0gY29tcGFyZURlc2MoZGlydHlEYXRlVG9Db21wYXJlLCBkaXJ0eURhdGUpXG5cbiAgdmFyIGxvY2FsZSA9IG9wdGlvbnMubG9jYWxlXG4gIHZhciBsb2NhbGl6ZSA9IGVuTG9jYWxlLmRpc3RhbmNlSW5Xb3Jkcy5sb2NhbGl6ZVxuICBpZiAobG9jYWxlICYmIGxvY2FsZS5kaXN0YW5jZUluV29yZHMgJiYgbG9jYWxlLmRpc3RhbmNlSW5Xb3Jkcy5sb2NhbGl6ZSkge1xuICAgIGxvY2FsaXplID0gbG9jYWxlLmRpc3RhbmNlSW5Xb3Jkcy5sb2NhbGl6ZVxuICB9XG5cbiAgdmFyIGxvY2FsaXplT3B0aW9ucyA9IHtcbiAgICBhZGRTdWZmaXg6IEJvb2xlYW4ob3B0aW9ucy5hZGRTdWZmaXgpLFxuICAgIGNvbXBhcmlzb246IGNvbXBhcmlzb25cbiAgfVxuXG4gIHZhciBkYXRlTGVmdCwgZGF0ZVJpZ2h0XG4gIGlmIChjb21wYXJpc29uID4gMCkge1xuICAgIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlEYXRlVG9Db21wYXJlKVxuICAgIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgfSBlbHNlIHtcbiAgICBkYXRlTGVmdCA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgICBkYXRlUmlnaHQgPSBwYXJzZShkaXJ0eURhdGVUb0NvbXBhcmUpXG4gIH1cblxuICB2YXIgc2Vjb25kcyA9IGRpZmZlcmVuY2VJblNlY29uZHMoZGF0ZVJpZ2h0LCBkYXRlTGVmdClcbiAgdmFyIG9mZnNldCA9IGRhdGVSaWdodC5nZXRUaW1lem9uZU9mZnNldCgpIC0gZGF0ZUxlZnQuZ2V0VGltZXpvbmVPZmZzZXQoKVxuICB2YXIgbWludXRlcyA9IE1hdGgucm91bmQoc2Vjb25kcyAvIDYwKSAtIG9mZnNldFxuICB2YXIgbW9udGhzXG5cbiAgLy8gMCB1cCB0byAyIG1pbnNcbiAgaWYgKG1pbnV0ZXMgPCAyKSB7XG4gICAgaWYgKG9wdGlvbnMuaW5jbHVkZVNlY29uZHMpIHtcbiAgICAgIGlmIChzZWNvbmRzIDwgNSkge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ2xlc3NUaGFuWFNlY29uZHMnLCA1LCBsb2NhbGl6ZU9wdGlvbnMpXG4gICAgICB9IGVsc2UgaWYgKHNlY29uZHMgPCAxMCkge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ2xlc3NUaGFuWFNlY29uZHMnLCAxMCwgbG9jYWxpemVPcHRpb25zKVxuICAgICAgfSBlbHNlIGlmIChzZWNvbmRzIDwgMjApIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsaXplKCdsZXNzVGhhblhTZWNvbmRzJywgMjAsIGxvY2FsaXplT3B0aW9ucylcbiAgICAgIH0gZWxzZSBpZiAoc2Vjb25kcyA8IDQwKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGl6ZSgnaGFsZkFNaW51dGUnLCBudWxsLCBsb2NhbGl6ZU9wdGlvbnMpXG4gICAgICB9IGVsc2UgaWYgKHNlY29uZHMgPCA2MCkge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ2xlc3NUaGFuWE1pbnV0ZXMnLCAxLCBsb2NhbGl6ZU9wdGlvbnMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ3hNaW51dGVzJywgMSwgbG9jYWxpemVPcHRpb25zKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobWludXRlcyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ2xlc3NUaGFuWE1pbnV0ZXMnLCAxLCBsb2NhbGl6ZU9wdGlvbnMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbG9jYWxpemUoJ3hNaW51dGVzJywgbWludXRlcywgbG9jYWxpemVPcHRpb25zKVxuICAgICAgfVxuICAgIH1cblxuICAvLyAyIG1pbnMgdXAgdG8gMC43NSBocnNcbiAgfSBlbHNlIGlmIChtaW51dGVzIDwgNDUpIHtcbiAgICByZXR1cm4gbG9jYWxpemUoJ3hNaW51dGVzJywgbWludXRlcywgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDAuNzUgaHJzIHVwIHRvIDEuNSBocnNcbiAgfSBlbHNlIGlmIChtaW51dGVzIDwgOTApIHtcbiAgICByZXR1cm4gbG9jYWxpemUoJ2Fib3V0WEhvdXJzJywgMSwgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDEuNSBocnMgdXAgdG8gMjQgaHJzXG4gIH0gZWxzZSBpZiAobWludXRlcyA8IE1JTlVURVNfSU5fREFZKSB7XG4gICAgdmFyIGhvdXJzID0gTWF0aC5yb3VuZChtaW51dGVzIC8gNjApXG4gICAgcmV0dXJuIGxvY2FsaXplKCdhYm91dFhIb3VycycsIGhvdXJzLCBsb2NhbGl6ZU9wdGlvbnMpXG5cbiAgLy8gMSBkYXkgdXAgdG8gMS43NSBkYXlzXG4gIH0gZWxzZSBpZiAobWludXRlcyA8IE1JTlVURVNfSU5fQUxNT1NUX1RXT19EQVlTKSB7XG4gICAgcmV0dXJuIGxvY2FsaXplKCd4RGF5cycsIDEsIGxvY2FsaXplT3B0aW9ucylcblxuICAvLyAxLjc1IGRheXMgdXAgdG8gMzAgZGF5c1xuICB9IGVsc2UgaWYgKG1pbnV0ZXMgPCBNSU5VVEVTX0lOX01PTlRIKSB7XG4gICAgdmFyIGRheXMgPSBNYXRoLnJvdW5kKG1pbnV0ZXMgLyBNSU5VVEVTX0lOX0RBWSlcbiAgICByZXR1cm4gbG9jYWxpemUoJ3hEYXlzJywgZGF5cywgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDEgbW9udGggdXAgdG8gMiBtb250aHNcbiAgfSBlbHNlIGlmIChtaW51dGVzIDwgTUlOVVRFU19JTl9UV09fTU9OVEhTKSB7XG4gICAgbW9udGhzID0gTWF0aC5yb3VuZChtaW51dGVzIC8gTUlOVVRFU19JTl9NT05USClcbiAgICByZXR1cm4gbG9jYWxpemUoJ2Fib3V0WE1vbnRocycsIG1vbnRocywgbG9jYWxpemVPcHRpb25zKVxuICB9XG5cbiAgbW9udGhzID0gZGlmZmVyZW5jZUluTW9udGhzKGRhdGVSaWdodCwgZGF0ZUxlZnQpXG5cbiAgLy8gMiBtb250aHMgdXAgdG8gMTIgbW9udGhzXG4gIGlmIChtb250aHMgPCAxMikge1xuICAgIHZhciBuZWFyZXN0TW9udGggPSBNYXRoLnJvdW5kKG1pbnV0ZXMgLyBNSU5VVEVTX0lOX01PTlRIKVxuICAgIHJldHVybiBsb2NhbGl6ZSgneE1vbnRocycsIG5lYXJlc3RNb250aCwgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDEgeWVhciB1cCB0byBtYXggRGF0ZVxuICB9IGVsc2Uge1xuICAgIHZhciBtb250aHNTaW5jZVN0YXJ0T2ZZZWFyID0gbW9udGhzICUgMTJcbiAgICB2YXIgeWVhcnMgPSBNYXRoLmZsb29yKG1vbnRocyAvIDEyKVxuXG4gICAgLy8gTiB5ZWFycyB1cCB0byAxIHllYXJzIDMgbW9udGhzXG4gICAgaWYgKG1vbnRoc1NpbmNlU3RhcnRPZlllYXIgPCAzKSB7XG4gICAgICByZXR1cm4gbG9jYWxpemUoJ2Fib3V0WFllYXJzJywgeWVhcnMsIGxvY2FsaXplT3B0aW9ucylcblxuICAgIC8vIE4geWVhcnMgMyBtb250aHMgdXAgdG8gTiB5ZWFycyA5IG1vbnRoc1xuICAgIH0gZWxzZSBpZiAobW9udGhzU2luY2VTdGFydE9mWWVhciA8IDkpIHtcbiAgICAgIHJldHVybiBsb2NhbGl6ZSgnb3ZlclhZZWFycycsIHllYXJzLCBsb2NhbGl6ZU9wdGlvbnMpXG5cbiAgICAvLyBOIHllYXJzIDkgbW9udGhzIHVwIHRvIE4geWVhciAxMiBtb250aHNcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGxvY2FsaXplKCdhbG1vc3RYWWVhcnMnLCB5ZWFycyArIDEsIGxvY2FsaXplT3B0aW9ucylcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaXN0YW5jZUluV29yZHNcbiIsInZhciBjb21wYXJlRGVzYyA9IHJlcXVpcmUoJy4uL2NvbXBhcmVfZGVzYy9pbmRleC5qcycpXG52YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgZGlmZmVyZW5jZUluU2Vjb25kcyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fc2Vjb25kcy9pbmRleC5qcycpXG52YXIgZW5Mb2NhbGUgPSByZXF1aXJlKCcuLi9sb2NhbGUvZW4vaW5kZXguanMnKVxuXG52YXIgTUlOVVRFU19JTl9EQVkgPSAxNDQwXG52YXIgTUlOVVRFU19JTl9NT05USCA9IDQzMjAwXG52YXIgTUlOVVRFU19JTl9ZRUFSID0gNTI1NjAwXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGdpdmVuIGRhdGVzIGluIHdvcmRzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBnaXZlbiBkYXRlcyBpbiB3b3JkcywgdXNpbmcgc3RyaWN0IHVuaXRzLlxuICogVGhpcyBpcyBsaWtlIGBkaXN0YW5jZUluV29yZHNgLCBidXQgZG9lcyBub3QgdXNlIGhlbHBlcnMgbGlrZSAnYWxtb3N0JywgJ292ZXInLFxuICogJ2xlc3MgdGhhbicgYW5kIHRoZSBsaWtlLlxuICpcbiAqIHwgRGlzdGFuY2UgYmV0d2VlbiBkYXRlcyB8IFJlc3VsdCAgICAgICAgICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gKiB8IDAgLi4uIDU5IHNlY3MgICAgICAgICAgfCBbMC4uNTldIHNlY29uZHMgICAgIHxcbiAqIHwgMSAuLi4gNTkgbWlucyAgICAgICAgICB8IFsxLi41OV0gbWludXRlcyAgICAgfFxuICogfCAxIC4uLiAyMyBocnMgICAgICAgICAgIHwgWzEuLjIzXSBob3VycyAgICAgICB8XG4gKiB8IDEgLi4uIDI5IGRheXMgICAgICAgICAgfCBbMS4uMjldIGRheXMgICAgICAgIHxcbiAqIHwgMSAuLi4gMTEgbW9udGhzICAgICAgICB8IFsxLi4xMV0gbW9udGhzICAgICAgfFxuICogfCAxIC4uLiBOIHllYXJzICAgICAgICAgIHwgWzEuLk5dICB5ZWFycyAgICAgICB8XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVUb0NvbXBhcmUgLSB0aGUgZGF0ZSB0byBjb21wYXJlIHdpdGhcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG90aGVyIGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB0aGUgb2JqZWN0IHdpdGggb3B0aW9uc1xuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5hZGRTdWZmaXg9ZmFsc2VdIC0gcmVzdWx0IGluZGljYXRlcyBpZiB0aGUgc2Vjb25kIGRhdGUgaXMgZWFybGllciBvciBsYXRlciB0aGFuIHRoZSBmaXJzdFxuICogQHBhcmFtIHsncyd8J20nfCdoJ3wnZCd8J00nfCdZJ30gW29wdGlvbnMudW5pdF0gLSBpZiBzcGVjaWZpZWQsIHdpbGwgZm9yY2UgYSB1bml0XG4gKiBAcGFyYW0geydmbG9vcid8J2NlaWwnfCdyb3VuZCd9IFtvcHRpb25zLnBhcnRpYWxNZXRob2Q9J2Zsb29yJ10gLSB3aGljaCB3YXkgdG8gcm91bmQgcGFydGlhbCB1bml0c1xuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmxvY2FsZT1lbkxvY2FsZV0gLSB0aGUgbG9jYWxlIG9iamVjdFxuICogQHJldHVybnMge1N0cmluZ30gdGhlIGRpc3RhbmNlIGluIHdvcmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoYXQgaXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gMiBKdWx5IDIwMTQgYW5kIDEgSmFudWFyeSAyMDE1P1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3Jkc1N0cmljdChcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMiksXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDIpXG4gKiApXG4gKiAvLz0+ICc2IG1vbnRocydcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hhdCBpcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiAxIEphbnVhcnkgMjAxNSAwMDowMDoxNVxuICogLy8gYW5kIDEgSmFudWFyeSAyMDE1IDAwOjAwOjAwP1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3Jkc1N0cmljdChcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSwgMCwgMCwgMTUpLFxuICogICBuZXcgRGF0ZSgyMDE1LCAwLCAxLCAwLCAwLCAwKSxcbiAqIClcbiAqIC8vPT4gJzE1IHNlY29uZHMnXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoYXQgaXMgdGhlIGRpc3RhbmNlIGZyb20gMSBKYW51YXJ5IDIwMTZcbiAqIC8vIHRvIDEgSmFudWFyeSAyMDE1LCB3aXRoIGEgc3VmZml4P1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3Jkc1N0cmljdChcbiAqICAgbmV3IERhdGUoMjAxNiwgMCwgMSksXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDEpLFxuICogICB7YWRkU3VmZml4OiB0cnVlfVxuICogKVxuICogLy89PiAnMSB5ZWFyIGFnbydcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hhdCBpcyB0aGUgZGlzdGFuY2UgZnJvbSAxIEphbnVhcnkgMjAxNlxuICogLy8gdG8gMSBKYW51YXJ5IDIwMTUsIGluIG1pbnV0ZXM/XG4gKiB2YXIgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzU3RyaWN0KFxuICogICBuZXcgRGF0ZSgyMDE2LCAwLCAxKSxcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSksXG4gKiAgIHt1bml0OiAnbSd9XG4gKiApXG4gKiAvLz0+ICc1MjU2MDAgbWludXRlcydcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hhdCBpcyB0aGUgZGlzdGFuY2UgZnJvbSAxIEphbnVhcnkgMjAxNlxuICogLy8gdG8gMjggSmFudWFyeSAyMDE1LCBpbiBtb250aHMsIHJvdW5kZWQgdXA/XG4gKiB2YXIgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzU3RyaWN0KFxuICogICBuZXcgRGF0ZSgyMDE1LCAwLCAyOCksXG4gKiAgIG5ldyBEYXRlKDIwMTUsIDAsIDEpLFxuICogICB7dW5pdDogJ00nLCBwYXJ0aWFsTWV0aG9kOiAnY2VpbCd9XG4gKiApXG4gKiAvLz0+ICcxIG1vbnRoJ1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGF0IGlzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIDEgQXVndXN0IDIwMTYgYW5kIDEgSmFudWFyeSAyMDE1IGluIEVzcGVyYW50bz9cbiAqIHZhciBlb0xvY2FsZSA9IHJlcXVpcmUoJ2RhdGUtZm5zL2xvY2FsZS9lbycpXG4gKiB2YXIgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzU3RyaWN0KFxuICogICBuZXcgRGF0ZSgyMDE2LCA3LCAxKSxcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSksXG4gKiAgIHtsb2NhbGU6IGVvTG9jYWxlfVxuICogKVxuICogLy89PiAnMSBqYXJvJ1xuICovXG5mdW5jdGlvbiBkaXN0YW5jZUluV29yZHNTdHJpY3QgKGRpcnR5RGF0ZVRvQ29tcGFyZSwgZGlydHlEYXRlLCBkaXJ0eU9wdGlvbnMpIHtcbiAgdmFyIG9wdGlvbnMgPSBkaXJ0eU9wdGlvbnMgfHwge31cblxuICB2YXIgY29tcGFyaXNvbiA9IGNvbXBhcmVEZXNjKGRpcnR5RGF0ZVRvQ29tcGFyZSwgZGlydHlEYXRlKVxuXG4gIHZhciBsb2NhbGUgPSBvcHRpb25zLmxvY2FsZVxuICB2YXIgbG9jYWxpemUgPSBlbkxvY2FsZS5kaXN0YW5jZUluV29yZHMubG9jYWxpemVcbiAgaWYgKGxvY2FsZSAmJiBsb2NhbGUuZGlzdGFuY2VJbldvcmRzICYmIGxvY2FsZS5kaXN0YW5jZUluV29yZHMubG9jYWxpemUpIHtcbiAgICBsb2NhbGl6ZSA9IGxvY2FsZS5kaXN0YW5jZUluV29yZHMubG9jYWxpemVcbiAgfVxuXG4gIHZhciBsb2NhbGl6ZU9wdGlvbnMgPSB7XG4gICAgYWRkU3VmZml4OiBCb29sZWFuKG9wdGlvbnMuYWRkU3VmZml4KSxcbiAgICBjb21wYXJpc29uOiBjb21wYXJpc29uXG4gIH1cblxuICB2YXIgZGF0ZUxlZnQsIGRhdGVSaWdodFxuICBpZiAoY29tcGFyaXNvbiA+IDApIHtcbiAgICBkYXRlTGVmdCA9IHBhcnNlKGRpcnR5RGF0ZVRvQ29tcGFyZSlcbiAgICBkYXRlUmlnaHQgPSBwYXJzZShkaXJ0eURhdGUpXG4gIH0gZWxzZSB7XG4gICAgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGUpXG4gICAgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlVG9Db21wYXJlKVxuICB9XG5cbiAgdmFyIHVuaXRcbiAgdmFyIG1hdGhQYXJ0aWFsID0gTWF0aFtvcHRpb25zLnBhcnRpYWxNZXRob2QgPyBTdHJpbmcob3B0aW9ucy5wYXJ0aWFsTWV0aG9kKSA6ICdmbG9vciddXG4gIHZhciBzZWNvbmRzID0gZGlmZmVyZW5jZUluU2Vjb25kcyhkYXRlUmlnaHQsIGRhdGVMZWZ0KVxuICB2YXIgb2Zmc2V0ID0gZGF0ZVJpZ2h0LmdldFRpbWV6b25lT2Zmc2V0KCkgLSBkYXRlTGVmdC5nZXRUaW1lem9uZU9mZnNldCgpXG4gIHZhciBtaW51dGVzID0gbWF0aFBhcnRpYWwoc2Vjb25kcyAvIDYwKSAtIG9mZnNldFxuICB2YXIgaG91cnMsIGRheXMsIG1vbnRocywgeWVhcnNcblxuICBpZiAob3B0aW9ucy51bml0KSB7XG4gICAgdW5pdCA9IFN0cmluZyhvcHRpb25zLnVuaXQpXG4gIH0gZWxzZSB7XG4gICAgaWYgKG1pbnV0ZXMgPCAxKSB7XG4gICAgICB1bml0ID0gJ3MnXG4gICAgfSBlbHNlIGlmIChtaW51dGVzIDwgNjApIHtcbiAgICAgIHVuaXQgPSAnbSdcbiAgICB9IGVsc2UgaWYgKG1pbnV0ZXMgPCBNSU5VVEVTX0lOX0RBWSkge1xuICAgICAgdW5pdCA9ICdoJ1xuICAgIH0gZWxzZSBpZiAobWludXRlcyA8IE1JTlVURVNfSU5fTU9OVEgpIHtcbiAgICAgIHVuaXQgPSAnZCdcbiAgICB9IGVsc2UgaWYgKG1pbnV0ZXMgPCBNSU5VVEVTX0lOX1lFQVIpIHtcbiAgICAgIHVuaXQgPSAnTSdcbiAgICB9IGVsc2Uge1xuICAgICAgdW5pdCA9ICdZJ1xuICAgIH1cbiAgfVxuXG4gIC8vIDAgdXAgdG8gNjAgc2Vjb25kc1xuICBpZiAodW5pdCA9PT0gJ3MnKSB7XG4gICAgcmV0dXJuIGxvY2FsaXplKCd4U2Vjb25kcycsIHNlY29uZHMsIGxvY2FsaXplT3B0aW9ucylcblxuICAvLyAxIHVwIHRvIDYwIG1pbnNcbiAgfSBlbHNlIGlmICh1bml0ID09PSAnbScpIHtcbiAgICByZXR1cm4gbG9jYWxpemUoJ3hNaW51dGVzJywgbWludXRlcywgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDEgdXAgdG8gMjQgaG91cnNcbiAgfSBlbHNlIGlmICh1bml0ID09PSAnaCcpIHtcbiAgICBob3VycyA9IG1hdGhQYXJ0aWFsKG1pbnV0ZXMgLyA2MClcbiAgICByZXR1cm4gbG9jYWxpemUoJ3hIb3VycycsIGhvdXJzLCBsb2NhbGl6ZU9wdGlvbnMpXG5cbiAgLy8gMSB1cCB0byAzMCBkYXlzXG4gIH0gZWxzZSBpZiAodW5pdCA9PT0gJ2QnKSB7XG4gICAgZGF5cyA9IG1hdGhQYXJ0aWFsKG1pbnV0ZXMgLyBNSU5VVEVTX0lOX0RBWSlcbiAgICByZXR1cm4gbG9jYWxpemUoJ3hEYXlzJywgZGF5cywgbG9jYWxpemVPcHRpb25zKVxuXG4gIC8vIDEgdXAgdG8gMTIgbW9udGhzXG4gIH0gZWxzZSBpZiAodW5pdCA9PT0gJ00nKSB7XG4gICAgbW9udGhzID0gbWF0aFBhcnRpYWwobWludXRlcyAvIE1JTlVURVNfSU5fTU9OVEgpXG4gICAgcmV0dXJuIGxvY2FsaXplKCd4TW9udGhzJywgbW9udGhzLCBsb2NhbGl6ZU9wdGlvbnMpXG5cbiAgLy8gMSB5ZWFyIHVwIHRvIG1heCBEYXRlXG4gIH0gZWxzZSBpZiAodW5pdCA9PT0gJ1knKSB7XG4gICAgeWVhcnMgPSBtYXRoUGFydGlhbChtaW51dGVzIC8gTUlOVVRFU19JTl9ZRUFSKVxuICAgIHJldHVybiBsb2NhbGl6ZSgneFllYXJzJywgeWVhcnMsIGxvY2FsaXplT3B0aW9ucylcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0OiAnICsgdW5pdClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaXN0YW5jZUluV29yZHNTdHJpY3RcbiIsInZhciBkaXN0YW5jZUluV29yZHMgPSByZXF1aXJlKCcuLi9kaXN0YW5jZV9pbl93b3Jkcy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGdpdmVuIGRhdGUgYW5kIG5vdyBpbiB3b3Jkcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgZ2l2ZW4gZGF0ZSBhbmQgbm93IGluIHdvcmRzLlxuICpcbiAqIHwgRGlzdGFuY2UgdG8gbm93ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBSZXN1bHQgICAgICAgICAgICAgIHxcbiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcbiAqIHwgMCAuLi4gMzAgc2VjcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBsZXNzIHRoYW4gYSBtaW51dGUgIHxcbiAqIHwgMzAgc2VjcyAuLi4gMSBtaW4gMzAgc2VjcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAxIG1pbnV0ZSAgICAgICAgICAgIHxcbiAqIHwgMSBtaW4gMzAgc2VjcyAuLi4gNDQgbWlucyAzMCBzZWNzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbMi4uNDRdIG1pbnV0ZXMgICAgIHxcbiAqIHwgNDQgbWlucyAuLi4gMzAgc2VjcyAuLi4gODkgbWlucyAzMCBzZWNzICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhYm91dCAxIGhvdXIgICAgICAgIHxcbiAqIHwgODkgbWlucyAzMCBzZWNzIC4uLiAyMyBocnMgNTkgbWlucyAzMCBzZWNzICAgICAgICAgICAgICAgICAgICAgICAgfCBhYm91dCBbMi4uMjRdIGhvdXJzIHxcbiAqIHwgMjMgaHJzIDU5IG1pbnMgMzAgc2VjcyAuLi4gNDEgaHJzIDU5IG1pbnMgMzAgc2VjcyAgICAgICAgICAgICAgICAgfCAxIGRheSAgICAgICAgICAgICAgIHxcbiAqIHwgNDEgaHJzIDU5IG1pbnMgMzAgc2VjcyAuLi4gMjkgZGF5cyAyMyBocnMgNTkgbWlucyAzMCBzZWNzICAgICAgICAgfCBbMi4uMzBdIGRheXMgICAgICAgIHxcbiAqIHwgMjkgZGF5cyAyMyBocnMgNTkgbWlucyAzMCBzZWNzIC4uLiA0NCBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgfCBhYm91dCAxIG1vbnRoICAgICAgIHxcbiAqIHwgNDQgZGF5cyAyMyBocnMgNTkgbWlucyAzMCBzZWNzIC4uLiA1OSBkYXlzIDIzIGhycyA1OSBtaW5zIDMwIHNlY3MgfCBhYm91dCAyIG1vbnRocyAgICAgIHxcbiAqIHwgNTkgZGF5cyAyMyBocnMgNTkgbWlucyAzMCBzZWNzIC4uLiAxIHlyICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBbMi4uMTJdIG1vbnRocyAgICAgIHxcbiAqIHwgMSB5ciAuLi4gMSB5ciAzIG1vbnRocyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhYm91dCAxIHllYXIgICAgICAgIHxcbiAqIHwgMSB5ciAzIG1vbnRocyAuLi4gMSB5ciA5IG1vbnRoIHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBvdmVyIDEgeWVhciAgICAgICAgIHxcbiAqIHwgMSB5ciA5IG1vbnRocyAuLi4gMiB5cnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhbG1vc3QgMiB5ZWFycyAgICAgIHxcbiAqIHwgTiB5cnMgLi4uIE4geXJzIDMgbW9udGhzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhYm91dCBOIHllYXJzICAgICAgIHxcbiAqIHwgTiB5cnMgMyBtb250aHMgLi4uIE4geXJzIDkgbW9udGhzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBvdmVyIE4geWVhcnMgICAgICAgIHxcbiAqIHwgTiB5cnMgOSBtb250aHMgLi4uIE4rMSB5cnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhbG1vc3QgTisxIHllYXJzICAgIHxcbiAqXG4gKiBXaXRoIGBvcHRpb25zLmluY2x1ZGVTZWNvbmRzID09IHRydWVgOlxuICogfCBEaXN0YW5jZSB0byBub3cgICAgIHwgUmVzdWx0ICAgICAgICAgICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogfCAwIHNlY3MgLi4uIDUgc2VjcyAgIHwgbGVzcyB0aGFuIDUgc2Vjb25kcyAgfFxuICogfCA1IHNlY3MgLi4uIDEwIHNlY3MgIHwgbGVzcyB0aGFuIDEwIHNlY29uZHMgfFxuICogfCAxMCBzZWNzIC4uLiAyMCBzZWNzIHwgbGVzcyB0aGFuIDIwIHNlY29uZHMgfFxuICogfCAyMCBzZWNzIC4uLiA0MCBzZWNzIHwgaGFsZiBhIG1pbnV0ZSAgICAgICAgfFxuICogfCA0MCBzZWNzIC4uLiA2MCBzZWNzIHwgbGVzcyB0aGFuIGEgbWludXRlICAgfFxuICogfCA2MCBzZWNzIC4uLiA5MCBzZWNzIHwgMSBtaW51dGUgICAgICAgICAgICAgfFxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGdpdmVuIGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB0aGUgb2JqZWN0IHdpdGggb3B0aW9uc1xuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5pbmNsdWRlU2Vjb25kcz1mYWxzZV0gLSBkaXN0YW5jZXMgbGVzcyB0aGFuIGEgbWludXRlIGFyZSBtb3JlIGRldGFpbGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmFkZFN1ZmZpeD1mYWxzZV0gLSByZXN1bHQgc3BlY2lmaWVzIGlmIHRoZSBzZWNvbmQgZGF0ZSBpcyBlYXJsaWVyIG9yIGxhdGVyIHRoYW4gdGhlIGZpcnN0XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubG9jYWxlPWVuTG9jYWxlXSAtIHRoZSBsb2NhbGUgb2JqZWN0XG4gKiBAcmV0dXJucyB7U3RyaW5nfSB0aGUgZGlzdGFuY2UgaW4gd29yZHNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgMSBKYW51YXJ5IDIwMTUsIHdoYXQgaXMgdGhlIGRpc3RhbmNlIHRvIDIgSnVseSAyMDE0P1xuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3Jkc1RvTm93KFxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyKVxuICogKVxuICogLy89PiAnNiBtb250aHMnXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIG5vdyBpcyAxIEphbnVhcnkgMjAxNSAwMDowMDowMCxcbiAqIC8vIHdoYXQgaXMgdGhlIGRpc3RhbmNlIHRvIDEgSmFudWFyeSAyMDE1IDAwOjAwOjE1LCBpbmNsdWRpbmcgc2Vjb25kcz9cbiAqIHZhciByZXN1bHQgPSBkaXN0YW5jZUluV29yZHNUb05vdyhcbiAqICAgbmV3IERhdGUoMjAxNSwgMCwgMSwgMCwgMCwgMTUpLFxuICogICB7aW5jbHVkZVNlY29uZHM6IHRydWV9XG4gKiApXG4gKiAvLz0+ICdsZXNzIHRoYW4gMjAgc2Vjb25kcydcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgMSBKYW51YXJ5IDIwMTUsXG4gKiAvLyB3aGF0IGlzIHRoZSBkaXN0YW5jZSB0byAxIEphbnVhcnkgMjAxNiwgd2l0aCBhIHN1ZmZpeD9cbiAqIHZhciByZXN1bHQgPSBkaXN0YW5jZUluV29yZHNUb05vdyhcbiAqICAgbmV3IERhdGUoMjAxNiwgMCwgMSksXG4gKiAgIHthZGRTdWZmaXg6IHRydWV9XG4gKiApXG4gKiAvLz0+ICdpbiBhYm91dCAxIHllYXInXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDEgSmFudWFyeSAyMDE1LFxuICogLy8gd2hhdCBpcyB0aGUgZGlzdGFuY2UgdG8gMSBBdWd1c3QgMjAxNiBpbiBFc3BlcmFudG8/XG4gKiB2YXIgZW9Mb2NhbGUgPSByZXF1aXJlKCdkYXRlLWZucy9sb2NhbGUvZW8nKVxuICogdmFyIHJlc3VsdCA9IGRpc3RhbmNlSW5Xb3Jkc1RvTm93KFxuICogICBuZXcgRGF0ZSgyMDE2LCA3LCAxKSxcbiAqICAge2xvY2FsZTogZW9Mb2NhbGV9XG4gKiApXG4gKiAvLz0+ICdwbGkgb2wgMSBqYXJvJ1xuICovXG5mdW5jdGlvbiBkaXN0YW5jZUluV29yZHNUb05vdyAoZGlydHlEYXRlLCBkaXJ0eU9wdGlvbnMpIHtcbiAgcmV0dXJuIGRpc3RhbmNlSW5Xb3JkcyhEYXRlLm5vdygpLCBkaXJ0eURhdGUsIGRpcnR5T3B0aW9ucylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkaXN0YW5jZUluV29yZHNUb05vd1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBhcnJheSBvZiBkYXRlcyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgYXJyYXkgb2YgZGF0ZXMgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IHN0YXJ0RGF0ZSAtIHRoZSBmaXJzdCBkYXRlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZW5kRGF0ZSAtIHRoZSBsYXN0IGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlW119IHRoZSBhcnJheSB3aXRoIHN0YXJ0cyBvZiBkYXlzIGZyb20gdGhlIGRheSBvZiBzdGFydERhdGUgdG8gdGhlIGRheSBvZiBlbmREYXRlXG4gKiBAdGhyb3dzIHtFcnJvcn0gc3RhcnREYXRlIGNhbm5vdCBiZSBhZnRlciBlbmREYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEVhY2ggZGF5IGJldHdlZW4gNiBPY3RvYmVyIDIwMTQgYW5kIDEwIE9jdG9iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBlYWNoRGF5KFxuICogICBuZXcgRGF0ZSgyMDE0LCA5LCA2KSxcbiAqICAgbmV3IERhdGUoMjAxNCwgOSwgMTApXG4gKiApXG4gKiAvLz0+IFtcbiAqIC8vICAgTW9uIE9jdCAwNiAyMDE0IDAwOjAwOjAwLFxuICogLy8gICBUdWUgT2N0IDA3IDIwMTQgMDA6MDA6MDAsXG4gKiAvLyAgIFdlZCBPY3QgMDggMjAxNCAwMDowMDowMCxcbiAqIC8vICAgVGh1IE9jdCAwOSAyMDE0IDAwOjAwOjAwLFxuICogLy8gICBGcmkgT2N0IDEwIDIwMTQgMDA6MDA6MDBcbiAqIC8vIF1cbiAqL1xuZnVuY3Rpb24gZWFjaERheSAoZGlydHlTdGFydERhdGUsIGRpcnR5RW5kRGF0ZSkge1xuICB2YXIgc3RhcnREYXRlID0gcGFyc2UoZGlydHlTdGFydERhdGUpXG4gIHZhciBlbmREYXRlID0gcGFyc2UoZGlydHlFbmREYXRlKVxuXG4gIHZhciBlbmRUaW1lID0gZW5kRGF0ZS5nZXRUaW1lKClcblxuICBpZiAoc3RhcnREYXRlLmdldFRpbWUoKSA+IGVuZFRpbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBmaXJzdCBkYXRlIGNhbm5vdCBiZSBhZnRlciB0aGUgc2Vjb25kIGRhdGUnKVxuICB9XG5cbiAgdmFyIGRhdGVzID0gW11cblxuICB2YXIgY3VycmVudERhdGUgPSBzdGFydERhdGVcbiAgY3VycmVudERhdGUuc2V0SG91cnMoMCwgMCwgMCwgMClcblxuICB3aGlsZSAoY3VycmVudERhdGUuZ2V0VGltZSgpIDw9IGVuZFRpbWUpIHtcbiAgICBkYXRlcy5wdXNoKHBhcnNlKGN1cnJlbnREYXRlKSlcbiAgICBjdXJyZW50RGF0ZS5zZXREYXRlKGN1cnJlbnREYXRlLmdldERhdGUoKSArIDEpXG4gIH1cblxuICByZXR1cm4gZGF0ZXNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlYWNoRGF5XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiBhIGRheSBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGVuZCBvZiBhIGRheSBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKiBUaGUgcmVzdWx0IHdpbGwgYmUgaW4gdGhlIGxvY2FsIHRpbWV6b25lLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIGEgZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBlbmQgb2YgYSBkYXkgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gZW5kT2ZEYXkobmV3IERhdGUoMjAxNCwgOCwgMiwgMTEsIDU1LCAwKSlcbiAqIC8vPT4gVHVlIFNlcCAwMiAyMDE0IDIzOjU5OjU5Ljk5OVxuICovXG5mdW5jdGlvbiBlbmRPZkRheSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICBkYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZkRheVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBIb3VyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgZW5kIG9mIGFuIGhvdXIgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBlbmQgb2YgYW4gaG91ciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKiBUaGUgcmVzdWx0IHdpbGwgYmUgaW4gdGhlIGxvY2FsIHRpbWV6b25lLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIGFuIGhvdXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGVuZCBvZiBhbiBob3VyIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IGVuZE9mSG91cihuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUpKVxuICogLy89PiBUdWUgU2VwIDAyIDIwMTQgMTE6NTk6NTkuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mSG91ciAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICBkYXRlLnNldE1pbnV0ZXMoNTksIDU5LCA5OTkpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZW5kT2ZIb3VyXG4iLCJ2YXIgZW5kT2ZXZWVrID0gcmVxdWlyZSgnLi4vZW5kX29mX3dlZWsvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiBhbiBJU08gd2VlayBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGVuZCBvZiBhbiBJU08gd2VlayBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKiBUaGUgcmVzdWx0IHdpbGwgYmUgaW4gdGhlIGxvY2FsIHRpbWV6b25lLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBvcmlnaW5hbCBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGVuZCBvZiBhbiBJU08gd2Vla1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgZW5kIG9mIGFuIElTTyB3ZWVrIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IGVuZE9mSVNPV2VlayhuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBTdW4gU2VwIDA3IDIwMTQgMjM6NTk6NTkuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mSVNPV2VlayAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBlbmRPZldlZWsoZGlydHlEYXRlLCB7d2Vla1N0YXJ0c09uOiAxfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZklTT1dlZWtcbiIsInZhciBnZXRJU09ZZWFyID0gcmVxdWlyZSgnLi4vZ2V0X2lzb195ZWFyL2luZGV4LmpzJylcbnZhciBzdGFydE9mSVNPV2VlayA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2lzb193ZWVrL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWstTnVtYmVyaW5nIFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBlbmQgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBlbmQgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIsXG4gKiB3aGljaCBhbHdheXMgc3RhcnRzIDMgZGF5cyBiZWZvcmUgdGhlIHllYXIncyBmaXJzdCBUaHVyc2RheS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIGFuIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBlbmQgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgZm9yIDIgSnVseSAyMDA1OlxuICogdmFyIHJlc3VsdCA9IGVuZE9mSVNPWWVhcihuZXcgRGF0ZSgyMDA1LCA2LCAyKSlcbiAqIC8vPT4gU3VuIEphbiAwMSAyMDA2IDIzOjU5OjU5Ljk5OVxuICovXG5mdW5jdGlvbiBlbmRPZklTT1llYXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgeWVhciA9IGdldElTT1llYXIoZGlydHlEYXRlKVxuICB2YXIgZm91cnRoT2ZKYW51YXJ5T2ZOZXh0WWVhciA9IG5ldyBEYXRlKDApXG4gIGZvdXJ0aE9mSmFudWFyeU9mTmV4dFllYXIuc2V0RnVsbFllYXIoeWVhciArIDEsIDAsIDQpXG4gIGZvdXJ0aE9mSmFudWFyeU9mTmV4dFllYXIuc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgdmFyIGRhdGUgPSBzdGFydE9mSVNPV2Vlayhmb3VydGhPZkphbnVhcnlPZk5leHRZZWFyKVxuICBkYXRlLnNldE1pbGxpc2Vjb25kcyhkYXRlLmdldE1pbGxpc2Vjb25kcygpIC0gMSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZklTT1llYXJcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTWludXRlIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgZW5kIG9mIGEgbWludXRlIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZW5kIG9mIGEgbWludXRlIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBlbmQgb2YgYSBtaW51dGVcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGVuZCBvZiBhIG1pbnV0ZSBmb3IgMSBEZWNlbWJlciAyMDE0IDIyOjE1OjQ1LjQwMDpcbiAqIHZhciByZXN1bHQgPSBlbmRPZk1pbnV0ZShuZXcgRGF0ZSgyMDE0LCAxMSwgMSwgMjIsIDE1LCA0NSwgNDAwKSlcbiAqIC8vPT4gTW9uIERlYyAwMSAyMDE0IDIyOjE1OjU5Ljk5OVxuICovXG5mdW5jdGlvbiBlbmRPZk1pbnV0ZSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICBkYXRlLnNldFNlY29uZHMoNTksIDk5OSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZk1pbnV0ZVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiBhIG1vbnRoIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZW5kIG9mIGEgbW9udGggZm9yIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBvcmlnaW5hbCBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGVuZCBvZiBhIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBlbmQgb2YgYSBtb250aCBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBlbmRPZk1vbnRoKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFR1ZSBTZXAgMzAgMjAxNCAyMzo1OTo1OS45OTlcbiAqL1xuZnVuY3Rpb24gZW5kT2ZNb250aCAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgbW9udGggPSBkYXRlLmdldE1vbnRoKClcbiAgZGF0ZS5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCksIG1vbnRoICsgMSwgMClcbiAgZGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZW5kT2ZNb250aFxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBRdWFydGVyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgZW5kIG9mIGEgeWVhciBxdWFydGVyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZW5kIG9mIGEgeWVhciBxdWFydGVyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBlbmQgb2YgYSBxdWFydGVyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBlbmQgb2YgYSBxdWFydGVyIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IGVuZE9mUXVhcnRlcihuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBUdWUgU2VwIDMwIDIwMTQgMjM6NTk6NTkuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mUXVhcnRlciAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgY3VycmVudE1vbnRoID0gZGF0ZS5nZXRNb250aCgpXG4gIHZhciBtb250aCA9IGN1cnJlbnRNb250aCAtIGN1cnJlbnRNb250aCAlIDMgKyAzXG4gIGRhdGUuc2V0TW9udGgobW9udGgsIDApXG4gIGRhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVuZE9mUXVhcnRlclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBTZWNvbmQgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBlbmQgb2YgYSBzZWNvbmQgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBlbmQgb2YgYSBzZWNvbmQgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBvcmlnaW5hbCBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGVuZCBvZiBhIHNlY29uZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgZW5kIG9mIGEgc2Vjb25kIGZvciAxIERlY2VtYmVyIDIwMTQgMjI6MTU6NDUuNDAwOlxuICogdmFyIHJlc3VsdCA9IGVuZE9mU2Vjb25kKG5ldyBEYXRlKDIwMTQsIDExLCAxLCAyMiwgMTUsIDQ1LCA0MDApKVxuICogLy89PiBNb24gRGVjIDAxIDIwMTQgMjI6MTU6NDUuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mU2Vjb25kIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIGRhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZlNlY29uZFxuIiwidmFyIGVuZE9mRGF5ID0gcmVxdWlyZSgnLi4vZW5kX29mX2RheS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiB0b2RheS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZW5kIG9mIHRvZGF5LlxuICpcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIHRvZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IGVuZE9mVG9kYXkoKVxuICogLy89PiBNb24gT2N0IDYgMjAxNCAyMzo1OTo1OS45OTlcbiAqL1xuZnVuY3Rpb24gZW5kT2ZUb2RheSAoKSB7XG4gIHJldHVybiBlbmRPZkRheShuZXcgRGF0ZSgpKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVuZE9mVG9kYXlcbiIsIi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiB0b21vcnJvdy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZW5kIG9mIHRvbW9ycm93LlxuICpcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIHRvbW9ycm93XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IGVuZE9mVG9tb3Jyb3coKVxuICogLy89PiBUdWUgT2N0IDcgMjAxNCAyMzo1OTo1OS45OTlcbiAqL1xuZnVuY3Rpb24gZW5kT2ZUb21vcnJvdyAoKSB7XG4gIHZhciBub3cgPSBuZXcgRGF0ZSgpXG4gIHZhciB5ZWFyID0gbm93LmdldEZ1bGxZZWFyKClcbiAgdmFyIG1vbnRoID0gbm93LmdldE1vbnRoKClcbiAgdmFyIGRheSA9IG5vdy5nZXREYXRlKClcblxuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKDApXG4gIGRhdGUuc2V0RnVsbFllYXIoeWVhciwgbW9udGgsIGRheSArIDEpXG4gIGRhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVuZE9mVG9tb3Jyb3dcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiBhIHdlZWsgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBlbmQgb2YgYSB3ZWVrIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIHRoZSBvYmplY3Qgd2l0aCBvcHRpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMud2Vla1N0YXJ0c09uPTBdIC0gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsgKDAgLSBTdW5kYXkpXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGVuZCBvZiBhIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGVuZCBvZiBhIHdlZWsgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gZW5kT2ZXZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFNhdCBTZXAgMDYgMjAxNCAyMzo1OTo1OS45OTlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdGhlIHdlZWsgc3RhcnRzIG9uIE1vbmRheSwgdGhlIGVuZCBvZiB0aGUgd2VlayBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBlbmRPZldlZWsobmV3IERhdGUoMjAxNCwgOCwgMiwgMTEsIDU1LCAwKSwge3dlZWtTdGFydHNPbjogMX0pXG4gKiAvLz0+IFN1biBTZXAgMDcgMjAxNCAyMzo1OTo1OS45OTlcbiAqL1xuZnVuY3Rpb24gZW5kT2ZXZWVrIChkaXJ0eURhdGUsIGRpcnR5T3B0aW9ucykge1xuICB2YXIgd2Vla1N0YXJ0c09uID0gZGlydHlPcHRpb25zID8gKE51bWJlcihkaXJ0eU9wdGlvbnMud2Vla1N0YXJ0c09uKSB8fCAwKSA6IDBcblxuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRheSA9IGRhdGUuZ2V0RGF5KClcbiAgdmFyIGRpZmYgPSAoZGF5IDwgd2Vla1N0YXJ0c09uID8gLTcgOiAwKSArIDYgLSAoZGF5IC0gd2Vla1N0YXJ0c09uKVxuXG4gIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIGRpZmYpXG4gIGRhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVuZE9mV2Vla1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBZZWFyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgZW5kIG9mIGEgeWVhciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGVuZCBvZiBhIHllYXIgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBvcmlnaW5hbCBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIGVuZCBvZiBhIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGVuZCBvZiBhIHllYXIgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gZW5kT2ZZZWFyKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMDApKVxuICogLy89PiBXZWQgRGVjIDMxIDIwMTQgMjM6NTk6NTkuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mWWVhciAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKVxuICBkYXRlLnNldEZ1bGxZZWFyKHllYXIgKyAxLCAwLCAwKVxuICBkYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbmRPZlllYXJcbiIsIi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVuZCBvZiB5ZXN0ZXJkYXkuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGVuZCBvZiB5ZXN0ZXJkYXkuXG4gKlxuICogQHJldHVybnMge0RhdGV9IHRoZSBlbmQgb2YgeWVzdGVyZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IGVuZE9mWWVzdGVyZGF5KClcbiAqIC8vPT4gU3VuIE9jdCA1IDIwMTQgMjM6NTk6NTkuOTk5XG4gKi9cbmZ1bmN0aW9uIGVuZE9mWWVzdGVyZGF5ICgpIHtcbiAgdmFyIG5vdyA9IG5ldyBEYXRlKClcbiAgdmFyIHllYXIgPSBub3cuZ2V0RnVsbFllYXIoKVxuICB2YXIgbW9udGggPSBub3cuZ2V0TW9udGgoKVxuICB2YXIgZGF5ID0gbm93LmdldERhdGUoKVxuXG4gIHZhciBkYXRlID0gbmV3IERhdGUoMClcbiAgZGF0ZS5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCwgZGF5IC0gMSlcbiAgZGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZW5kT2ZZZXN0ZXJkYXlcbiIsInZhciBnZXREYXlPZlllYXIgPSByZXF1aXJlKCcuLi9nZXRfZGF5X29mX3llYXIvaW5kZXguanMnKVxudmFyIGdldElTT1dlZWsgPSByZXF1aXJlKCcuLi9nZXRfaXNvX3dlZWsvaW5kZXguanMnKVxudmFyIGdldElTT1llYXIgPSByZXF1aXJlKCcuLi9nZXRfaXNvX3llYXIvaW5kZXguanMnKVxudmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIGlzVmFsaWQgPSByZXF1aXJlKCcuLi9pc192YWxpZC9pbmRleC5qcycpXG52YXIgZW5Mb2NhbGUgPSByZXF1aXJlKCcuLi9sb2NhbGUvZW4vaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBDb21tb24gSGVscGVyc1xuICogQHN1bW1hcnkgRm9ybWF0IHRoZSBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBmb3JtYXR0ZWQgZGF0ZSBzdHJpbmcgaW4gdGhlIGdpdmVuIGZvcm1hdC5cbiAqXG4gKiBBY2NlcHRlZCB0b2tlbnM6XG4gKiB8IFVuaXQgICAgICAgICAgICAgICAgICAgIHwgVG9rZW4gfCBSZXN1bHQgZXhhbXBsZXMgICAgICAgICAgICAgICAgICB8XG4gKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gKiB8IE1vbnRoICAgICAgICAgICAgICAgICAgIHwgTSAgICAgfCAxLCAyLCAuLi4sIDEyICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTW8gICAgfCAxc3QsIDJuZCwgLi4uLCAxMnRoICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTU0gICAgfCAwMSwgMDIsIC4uLiwgMTIgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTU1NICAgfCBKYW4sIEZlYiwgLi4uLCBEZWMgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTU1NTSAgfCBKYW51YXJ5LCBGZWJydWFyeSwgLi4uLCBEZWNlbWJlciB8XG4gKiB8IFF1YXJ0ZXIgICAgICAgICAgICAgICAgIHwgUSAgICAgfCAxLCAyLCAzLCA0ICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgUW8gICAgfCAxc3QsIDJuZCwgM3JkLCA0dGggICAgICAgICAgICAgICB8XG4gKiB8IERheSBvZiBtb250aCAgICAgICAgICAgIHwgRCAgICAgfCAxLCAyLCAuLi4sIDMxICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgRG8gICAgfCAxc3QsIDJuZCwgLi4uLCAzMXN0ICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgREQgICAgfCAwMSwgMDIsIC4uLiwgMzEgICAgICAgICAgICAgICAgICB8XG4gKiB8IERheSBvZiB5ZWFyICAgICAgICAgICAgIHwgREREICAgfCAxLCAyLCAuLi4sIDM2NiAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgREREbyAgfCAxc3QsIDJuZCwgLi4uLCAzNjZ0aCAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgRERERCAgfCAwMDEsIDAwMiwgLi4uLCAzNjYgICAgICAgICAgICAgICB8XG4gKiB8IERheSBvZiB3ZWVrICAgICAgICAgICAgIHwgZCAgICAgfCAwLCAxLCAuLi4sIDYgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgZG8gICAgfCAwdGgsIDFzdCwgLi4uLCA2dGggICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgZGQgICAgfCBTdSwgTW8sIC4uLiwgU2EgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgZGRkICAgfCBTdW4sIE1vbiwgLi4uLCBTYXQgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgZGRkZCAgfCBTdW5kYXksIE1vbmRheSwgLi4uLCBTYXR1cmRheSAgICB8XG4gKiB8IERheSBvZiBJU08gd2VlayAgICAgICAgIHwgRSAgICAgfCAxLCAyLCAuLi4sIDcgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IElTTyB3ZWVrICAgICAgICAgICAgICAgIHwgVyAgICAgfCAxLCAyLCAuLi4sIDUzICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgV28gICAgfCAxc3QsIDJuZCwgLi4uLCA1M3JkICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgV1cgICAgfCAwMSwgMDIsIC4uLiwgNTMgICAgICAgICAgICAgICAgICB8XG4gKiB8IFllYXIgICAgICAgICAgICAgICAgICAgIHwgWVkgICAgfCAwMCwgMDEsIC4uLiwgOTkgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgWVlZWSAgfCAxOTAwLCAxOTAxLCAuLi4sIDIwOTkgICAgICAgICAgICB8XG4gKiB8IElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIHwgR0cgICAgfCAwMCwgMDEsIC4uLiwgOTkgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgR0dHRyAgfCAxOTAwLCAxOTAxLCAuLi4sIDIwOTkgICAgICAgICAgICB8XG4gKiB8IEFNL1BNICAgICAgICAgICAgICAgICAgIHwgQSAgICAgfCBBTSwgUE0gICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgYSAgICAgfCBhbSwgcG0gICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgYWEgICAgfCBhLm0uLCBwLm0uICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IEhvdXIgICAgICAgICAgICAgICAgICAgIHwgSCAgICAgfCAwLCAxLCAuLi4gMjMgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgSEggICAgfCAwMCwgMDEsIC4uLiAyMyAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgaCAgICAgfCAxLCAyLCAuLi4sIDEyICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgaGggICAgfCAwMSwgMDIsIC4uLiwgMTIgICAgICAgICAgICAgICAgICB8XG4gKiB8IE1pbnV0ZSAgICAgICAgICAgICAgICAgIHwgbSAgICAgfCAwLCAxLCAuLi4sIDU5ICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgbW0gICAgfCAwMCwgMDEsIC4uLiwgNTkgICAgICAgICAgICAgICAgICB8XG4gKiB8IFNlY29uZCAgICAgICAgICAgICAgICAgIHwgcyAgICAgfCAwLCAxLCAuLi4sIDU5ICAgICAgICAgICAgICAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgc3MgICAgfCAwMCwgMDEsIC4uLiwgNTkgICAgICAgICAgICAgICAgICB8XG4gKiB8IDEvMTAgb2Ygc2Vjb25kICAgICAgICAgIHwgUyAgICAgfCAwLCAxLCAuLi4sIDkgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IDEvMTAwIG9mIHNlY29uZCAgICAgICAgIHwgU1MgICAgfCAwMCwgMDEsIC4uLiwgOTkgICAgICAgICAgICAgICAgICB8XG4gKiB8IE1pbGxpc2Vjb25kICAgICAgICAgICAgIHwgU1NTICAgfCAwMDAsIDAwMSwgLi4uLCA5OTkgICAgICAgICAgICAgICB8XG4gKiB8IFRpbWV6b25lICAgICAgICAgICAgICAgIHwgWiAgICAgfCAtMDE6MDAsICswMDowMCwgLi4uICsxMjowMCAgICAgICB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgWlogICAgfCAtMDEwMCwgKzAwMDAsIC4uLiwgKzEyMDAgICAgICAgICB8XG4gKiB8IFNlY29uZHMgdGltZXN0YW1wICAgICAgIHwgWCAgICAgfCA1MTI5Njk1MjAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IE1pbGxpc2Vjb25kcyB0aW1lc3RhbXAgIHwgeCAgICAgfCA1MTI5Njk1MjA5MDAgICAgICAgICAgICAgICAgICAgICB8XG4gKlxuICogVGhlIGNoYXJhY3RlcnMgd3JhcHBlZCBpbiBzcXVhcmUgYnJhY2tldHMgYXJlIGVzY2FwZWQuXG4gKlxuICogVGhlIHJlc3VsdCBtYXkgdmFyeSBieSBsb2NhbGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IFtmb3JtYXQ9J1lZWVktTU0tRERUSEg6bW06c3MuU1NTWiddIC0gdGhlIHN0cmluZyBvZiB0b2tlbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB0aGUgb2JqZWN0IHdpdGggb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmxvY2FsZT1lbkxvY2FsZV0gLSB0aGUgbG9jYWxlIG9iamVjdFxuICogQHJldHVybnMge1N0cmluZ30gdGhlIGZvcm1hdHRlZCBkYXRlIHN0cmluZ1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBSZXByZXNlbnQgMTEgRmVicnVhcnkgMjAxNCBpbiBtaWRkbGUtZW5kaWFuIGZvcm1hdDpcbiAqIHZhciByZXN1bHQgPSBmb3JtYXQoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDEsIDExKSxcbiAqICAgJ01NL0REL1lZWVknXG4gKiApXG4gKiAvLz0+ICcwMi8xMS8yMDE0J1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBSZXByZXNlbnQgMiBKdWx5IDIwMTQgaW4gRXNwZXJhbnRvOlxuICogdmFyIGVvTG9jYWxlID0gcmVxdWlyZSgnZGF0ZS1mbnMvbG9jYWxlL2VvJylcbiAqIHZhciByZXN1bHQgPSBmb3JtYXQoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDYsIDIpLFxuICogICAnRG8gW2RlXSBNTU1NIFlZWVknLFxuICogICB7bG9jYWxlOiBlb0xvY2FsZX1cbiAqIClcbiAqIC8vPT4gJzItYSBkZSBqdWxpbyAyMDE0J1xuICovXG5mdW5jdGlvbiBmb3JtYXQgKGRpcnR5RGF0ZSwgZGlydHlGb3JtYXRTdHIsIGRpcnR5T3B0aW9ucykge1xuICB2YXIgZm9ybWF0U3RyID0gZGlydHlGb3JtYXRTdHIgPyBTdHJpbmcoZGlydHlGb3JtYXRTdHIpIDogJ1lZWVktTU0tRERUSEg6bW06c3MuU1NTWidcbiAgdmFyIG9wdGlvbnMgPSBkaXJ0eU9wdGlvbnMgfHwge31cblxuICB2YXIgbG9jYWxlID0gb3B0aW9ucy5sb2NhbGVcbiAgdmFyIGxvY2FsZUZvcm1hdHRlcnMgPSBlbkxvY2FsZS5mb3JtYXQuZm9ybWF0dGVyc1xuICB2YXIgZm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cCA9IGVuTG9jYWxlLmZvcm1hdC5mb3JtYXR0aW5nVG9rZW5zUmVnRXhwXG4gIGlmIChsb2NhbGUgJiYgbG9jYWxlLmZvcm1hdCAmJiBsb2NhbGUuZm9ybWF0LmZvcm1hdHRlcnMpIHtcbiAgICBsb2NhbGVGb3JtYXR0ZXJzID0gbG9jYWxlLmZvcm1hdC5mb3JtYXR0ZXJzXG5cbiAgICBpZiAobG9jYWxlLmZvcm1hdC5mb3JtYXR0aW5nVG9rZW5zUmVnRXhwKSB7XG4gICAgICBmb3JtYXR0aW5nVG9rZW5zUmVnRXhwID0gbG9jYWxlLmZvcm1hdC5mb3JtYXR0aW5nVG9rZW5zUmVnRXhwXG4gICAgfVxuICB9XG5cbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG5cbiAgaWYgKCFpc1ZhbGlkKGRhdGUpKSB7XG4gICAgcmV0dXJuICdJbnZhbGlkIERhdGUnXG4gIH1cblxuICB2YXIgZm9ybWF0Rm4gPSBidWlsZEZvcm1hdEZuKGZvcm1hdFN0ciwgbG9jYWxlRm9ybWF0dGVycywgZm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cClcblxuICByZXR1cm4gZm9ybWF0Rm4oZGF0ZSlcbn1cblxudmFyIGZvcm1hdHRlcnMgPSB7XG4gIC8vIE1vbnRoOiAxLCAyLCAuLi4sIDEyXG4gICdNJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpICsgMVxuICB9LFxuXG4gIC8vIE1vbnRoOiAwMSwgMDIsIC4uLiwgMTJcbiAgJ01NJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGRhdGUuZ2V0TW9udGgoKSArIDEsIDIpXG4gIH0sXG5cbiAgLy8gUXVhcnRlcjogMSwgMiwgMywgNFxuICAnUSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCgoZGF0ZS5nZXRNb250aCgpICsgMSkgLyAzKVxuICB9LFxuXG4gIC8vIERheSBvZiBtb250aDogMSwgMiwgLi4uLCAzMVxuICAnRCc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpXG4gIH0sXG5cbiAgLy8gRGF5IG9mIG1vbnRoOiAwMSwgMDIsIC4uLiwgMzFcbiAgJ0REJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGRhdGUuZ2V0RGF0ZSgpLCAyKVxuICB9LFxuXG4gIC8vIERheSBvZiB5ZWFyOiAxLCAyLCAuLi4sIDM2NlxuICAnREREJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gZ2V0RGF5T2ZZZWFyKGRhdGUpXG4gIH0sXG5cbiAgLy8gRGF5IG9mIHllYXI6IDAwMSwgMDAyLCAuLi4sIDM2NlxuICAnRERERCc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGFkZExlYWRpbmdaZXJvcyhnZXREYXlPZlllYXIoZGF0ZSksIDMpXG4gIH0sXG5cbiAgLy8gRGF5IG9mIHdlZWs6IDAsIDEsIC4uLiwgNlxuICAnZCc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF5KClcbiAgfSxcblxuICAvLyBEYXkgb2YgSVNPIHdlZWs6IDEsIDIsIC4uLiwgN1xuICAnRSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF5KCkgfHwgN1xuICB9LFxuXG4gIC8vIElTTyB3ZWVrOiAxLCAyLCAuLi4sIDUzXG4gICdXJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gZ2V0SVNPV2VlayhkYXRlKVxuICB9LFxuXG4gIC8vIElTTyB3ZWVrOiAwMSwgMDIsIC4uLiwgNTNcbiAgJ1dXJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGdldElTT1dlZWsoZGF0ZSksIDIpXG4gIH0sXG5cbiAgLy8gWWVhcjogMDAsIDAxLCAuLi4sIDk5XG4gICdZWSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGFkZExlYWRpbmdaZXJvcyhkYXRlLmdldEZ1bGxZZWFyKCksIDQpLnN1YnN0cigyKVxuICB9LFxuXG4gIC8vIFllYXI6IDE5MDAsIDE5MDEsIC4uLiwgMjA5OVxuICAnWVlZWSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGFkZExlYWRpbmdaZXJvcyhkYXRlLmdldEZ1bGxZZWFyKCksIDQpXG4gIH0sXG5cbiAgLy8gSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IDAwLCAwMSwgLi4uLCA5OVxuICAnR0cnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBTdHJpbmcoZ2V0SVNPWWVhcihkYXRlKSkuc3Vic3RyKDIpXG4gIH0sXG5cbiAgLy8gSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IDE5MDAsIDE5MDEsIC4uLiwgMjA5OVxuICAnR0dHRyc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGdldElTT1llYXIoZGF0ZSlcbiAgfSxcblxuICAvLyBIb3VyOiAwLCAxLCAuLi4gMjNcbiAgJ0gnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBkYXRlLmdldEhvdXJzKClcbiAgfSxcblxuICAvLyBIb3VyOiAwMCwgMDEsIC4uLiwgMjNcbiAgJ0hIJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGRhdGUuZ2V0SG91cnMoKSwgMilcbiAgfSxcblxuICAvLyBIb3VyOiAxLCAyLCAuLi4sIDEyXG4gICdoJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICB2YXIgaG91cnMgPSBkYXRlLmdldEhvdXJzKClcbiAgICBpZiAoaG91cnMgPT09IDApIHtcbiAgICAgIHJldHVybiAxMlxuICAgIH0gZWxzZSBpZiAoaG91cnMgPiAxMikge1xuICAgICAgcmV0dXJuIGhvdXJzICUgMTJcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGhvdXJzXG4gICAgfVxuICB9LFxuXG4gIC8vIEhvdXI6IDAxLCAwMiwgLi4uLCAxMlxuICAnaGgnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBhZGRMZWFkaW5nWmVyb3MoZm9ybWF0dGVyc1snaCddKGRhdGUpLCAyKVxuICB9LFxuXG4gIC8vIE1pbnV0ZTogMCwgMSwgLi4uLCA1OVxuICAnbSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpXG4gIH0sXG5cbiAgLy8gTWludXRlOiAwMCwgMDEsIC4uLiwgNTlcbiAgJ21tJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGRhdGUuZ2V0TWludXRlcygpLCAyKVxuICB9LFxuXG4gIC8vIFNlY29uZDogMCwgMSwgLi4uLCA1OVxuICAncyc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgcmV0dXJuIGRhdGUuZ2V0U2Vjb25kcygpXG4gIH0sXG5cbiAgLy8gU2Vjb25kOiAwMCwgMDEsIC4uLiwgNTlcbiAgJ3NzJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKGRhdGUuZ2V0U2Vjb25kcygpLCAyKVxuICB9LFxuXG4gIC8vIDEvMTAgb2Ygc2Vjb25kOiAwLCAxLCAuLi4sIDlcbiAgJ1MnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKGRhdGUuZ2V0TWlsbGlzZWNvbmRzKCkgLyAxMDApXG4gIH0sXG5cbiAgLy8gMS8xMDAgb2Ygc2Vjb25kOiAwMCwgMDEsIC4uLiwgOTlcbiAgJ1NTJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gYWRkTGVhZGluZ1plcm9zKE1hdGguZmxvb3IoZGF0ZS5nZXRNaWxsaXNlY29uZHMoKSAvIDEwKSwgMilcbiAgfSxcblxuICAvLyBNaWxsaXNlY29uZDogMDAwLCAwMDEsIC4uLiwgOTk5XG4gICdTU1MnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBhZGRMZWFkaW5nWmVyb3MoZGF0ZS5nZXRNaWxsaXNlY29uZHMoKSwgMylcbiAgfSxcblxuICAvLyBUaW1lem9uZTogLTAxOjAwLCArMDA6MDAsIC4uLiArMTI6MDBcbiAgJ1onOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBmb3JtYXRUaW1lem9uZShkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCksICc6JylcbiAgfSxcblxuICAvLyBUaW1lem9uZTogLTAxMDAsICswMDAwLCAuLi4gKzEyMDBcbiAgJ1paJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICByZXR1cm4gZm9ybWF0VGltZXpvbmUoZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpKVxuICB9LFxuXG4gIC8vIFNlY29uZHMgdGltZXN0YW1wOiA1MTI5Njk1MjBcbiAgJ1gnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKGRhdGUuZ2V0VGltZSgpIC8gMTAwMClcbiAgfSxcblxuICAvLyBNaWxsaXNlY29uZHMgdGltZXN0YW1wOiA1MTI5Njk1MjA5MDBcbiAgJ3gnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIHJldHVybiBkYXRlLmdldFRpbWUoKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRm9ybWF0Rm4gKGZvcm1hdFN0ciwgbG9jYWxlRm9ybWF0dGVycywgZm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cCkge1xuICB2YXIgYXJyYXkgPSBmb3JtYXRTdHIubWF0Y2goZm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cClcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aFxuXG4gIHZhciBpXG4gIHZhciBmb3JtYXR0ZXJcbiAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgZm9ybWF0dGVyID0gbG9jYWxlRm9ybWF0dGVyc1thcnJheVtpXV0gfHwgZm9ybWF0dGVyc1thcnJheVtpXV1cbiAgICBpZiAoZm9ybWF0dGVyKSB7XG4gICAgICBhcnJheVtpXSA9IGZvcm1hdHRlclxuICAgIH0gZWxzZSB7XG4gICAgICBhcnJheVtpXSA9IHJlbW92ZUZvcm1hdHRpbmdUb2tlbnMoYXJyYXlbaV0pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgdmFyIG91dHB1dCA9ICcnXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFycmF5W2ldIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgb3V0cHV0ICs9IGFycmF5W2ldKGRhdGUsIGZvcm1hdHRlcnMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgKz0gYXJyYXlbaV1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dFxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUZvcm1hdHRpbmdUb2tlbnMgKGlucHV0KSB7XG4gIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKC9eXFxbfF0kL2csICcnKVxuICB9XG4gIHJldHVybiBpbnB1dC5yZXBsYWNlKC9cXFxcL2csICcnKVxufVxuXG5mdW5jdGlvbiBmb3JtYXRUaW1lem9uZSAob2Zmc2V0LCBkZWxpbWV0ZXIpIHtcbiAgZGVsaW1ldGVyID0gZGVsaW1ldGVyIHx8ICcnXG4gIHZhciBzaWduID0gb2Zmc2V0ID4gMCA/ICctJyA6ICcrJ1xuICB2YXIgYWJzT2Zmc2V0ID0gTWF0aC5hYnMob2Zmc2V0KVxuICB2YXIgaG91cnMgPSBNYXRoLmZsb29yKGFic09mZnNldCAvIDYwKVxuICB2YXIgbWludXRlcyA9IGFic09mZnNldCAlIDYwXG4gIHJldHVybiBzaWduICsgYWRkTGVhZGluZ1plcm9zKGhvdXJzLCAyKSArIGRlbGltZXRlciArIGFkZExlYWRpbmdaZXJvcyhtaW51dGVzLCAyKVxufVxuXG5mdW5jdGlvbiBhZGRMZWFkaW5nWmVyb3MgKG51bWJlciwgdGFyZ2V0TGVuZ3RoKSB7XG4gIHZhciBvdXRwdXQgPSBNYXRoLmFicyhudW1iZXIpLnRvU3RyaW5nKClcbiAgd2hpbGUgKG91dHB1dC5sZW5ndGggPCB0YXJnZXRMZW5ndGgpIHtcbiAgICBvdXRwdXQgPSAnMCcgKyBvdXRwdXRcbiAgfVxuICByZXR1cm4gb3V0cHV0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZm9ybWF0XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIGRheSBvZiB0aGUgbW9udGggb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIGRheSBvZiB0aGUgbW9udGggb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIGRheSBvZiBtb250aFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGljaCBkYXkgb2YgdGhlIG1vbnRoIGlzIDI5IEZlYnJ1YXJ5IDIwMTI/XG4gKiB2YXIgcmVzdWx0ID0gZ2V0RGF0ZShuZXcgRGF0ZSgyMDEyLCAxLCAyOSkpXG4gKiAvLz0+IDI5XG4gKi9cbmZ1bmN0aW9uIGdldERhdGUgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRheU9mTW9udGggPSBkYXRlLmdldERhdGUoKVxuICByZXR1cm4gZGF5T2ZNb250aFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGVcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2Vla2RheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIGRheSBvZiB0aGUgd2VlayBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgZGF5IG9mIHRoZSB3ZWVrIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGdpdmVuIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBkYXkgb2Ygd2Vla1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGljaCBkYXkgb2YgdGhlIHdlZWsgaXMgMjkgRmVicnVhcnkgMjAxMj9cbiAqIHZhciByZXN1bHQgPSBnZXREYXkobmV3IERhdGUoMjAxMiwgMSwgMjkpKVxuICogLy89PiAzXG4gKi9cbmZ1bmN0aW9uIGdldERheSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKVxuICByZXR1cm4gZGF5XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RGF5XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgc3RhcnRPZlllYXIgPSByZXF1aXJlKCcuLi9zdGFydF9vZl95ZWFyL2luZGV4LmpzJylcbnZhciBkaWZmZXJlbmNlSW5DYWxlbmRhckRheXMgPSByZXF1aXJlKCcuLi9kaWZmZXJlbmNlX2luX2NhbGVuZGFyX2RheXMvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBkYXkgb2YgdGhlIHllYXIgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIGRheSBvZiB0aGUgeWVhciBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBnaXZlbiBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgZGF5IG9mIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hpY2ggZGF5IG9mIHRoZSB5ZWFyIGlzIDIgSnVseSAyMDE0P1xuICogdmFyIHJlc3VsdCA9IGdldERheU9mWWVhcihuZXcgRGF0ZSgyMDE0LCA2LCAyKSlcbiAqIC8vPT4gMTgzXG4gKi9cbmZ1bmN0aW9uIGdldERheU9mWWVhciAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGlmZiA9IGRpZmZlcmVuY2VJbkNhbGVuZGFyRGF5cyhkYXRlLCBzdGFydE9mWWVhcihkYXRlKSlcbiAgdmFyIGRheU9mWWVhciA9IGRpZmYgKyAxXG4gIHJldHVybiBkYXlPZlllYXJcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXREYXlPZlllYXJcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTW9udGggSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIG1vbnRoIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIG1vbnRoIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGdpdmVuIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEhvdyBtYW55IGRheXMgYXJlIGluIEZlYnJ1YXJ5IDIwMDA/XG4gKiB2YXIgcmVzdWx0ID0gZ2V0RGF5c0luTW9udGgobmV3IERhdGUoMjAwMCwgMSkpXG4gKiAvLz0+IDI5XG4gKi9cbmZ1bmN0aW9uIGdldERheXNJbk1vbnRoIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpXG4gIHZhciBtb250aEluZGV4ID0gZGF0ZS5nZXRNb250aCgpXG4gIHZhciBsYXN0RGF5T2ZNb250aCA9IG5ldyBEYXRlKDApXG4gIGxhc3REYXlPZk1vbnRoLnNldEZ1bGxZZWFyKHllYXIsIG1vbnRoSW5kZXggKyAxLCAwKVxuICBsYXN0RGF5T2ZNb250aC5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gbGFzdERheU9mTW9udGguZ2V0RGF0ZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RGF5c0luTW9udGhcbiIsInZhciBpc0xlYXBZZWFyID0gcmVxdWlyZSgnLi4vaXNfbGVhcF95ZWFyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBkYXlzIGluIGEgeWVhciBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGRheXMgaW4gYSB5ZWFyIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGdpdmVuIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgZGF5cyBhcmUgaW4gMjAxMj9cbiAqIHZhciByZXN1bHQgPSBnZXREYXlzSW5ZZWFyKG5ldyBEYXRlKDIwMTIsIDAsIDEpKVxuICogLy89PiAzNjZcbiAqL1xuZnVuY3Rpb24gZ2V0RGF5c0luWWVhciAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc0xlYXBZZWFyKGRpcnR5RGF0ZSkgPyAzNjYgOiAzNjVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXREYXlzSW5ZZWFyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IEhvdXIgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBob3VycyBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgaG91cnMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIGhvdXJzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEdldCB0aGUgaG91cnMgb2YgMjkgRmVicnVhcnkgMjAxMiAxMTo0NTowMDpcbiAqIHZhciByZXN1bHQgPSBnZXRIb3VycyhuZXcgRGF0ZSgyMDEyLCAxLCAyOSwgMTEsIDQ1KSlcbiAqIC8vPT4gMTFcbiAqL1xuZnVuY3Rpb24gZ2V0SG91cnMgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGhvdXJzID0gZGF0ZS5nZXRIb3VycygpXG4gIHJldHVybiBob3Vyc1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEhvdXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgR2V0IHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIG9mIHRoZSBnaXZlbiBkYXRlLFxuICogd2hpY2ggaXMgNyBmb3IgU3VuZGF5LCAxIGZvciBNb25kYXkgZXRjLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBnaXZlbiBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgZGF5IG9mIElTTyB3ZWVrXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoaWNoIGRheSBvZiB0aGUgSVNPIHdlZWsgaXMgMjYgRmVicnVhcnkgMjAxMj9cbiAqIHZhciByZXN1bHQgPSBnZXRJU09EYXkobmV3IERhdGUoMjAxMiwgMSwgMjYpKVxuICogLy89PiA3XG4gKi9cbmZ1bmN0aW9uIGdldElTT0RheSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKVxuXG4gIGlmIChkYXkgPT09IDApIHtcbiAgICBkYXkgPSA3XG4gIH1cblxuICByZXR1cm4gZGF5XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0SVNPRGF5XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgc3RhcnRPZklTT1dlZWsgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9pc29fd2Vlay9pbmRleC5qcycpXG52YXIgc3RhcnRPZklTT1llYXIgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9pc29feWVhci9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fV0VFSyA9IDYwNDgwMDAwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIElTTyB3ZWVrIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBJU08gd2VlayBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIElTTyB3ZWVrXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoaWNoIHdlZWsgb2YgdGhlIElTTy13ZWVrIG51bWJlcmluZyB5ZWFyIGlzIDIgSmFudWFyeSAyMDA1P1xuICogdmFyIHJlc3VsdCA9IGdldElTT1dlZWsobmV3IERhdGUoMjAwNSwgMCwgMikpXG4gKiAvLz0+IDUzXG4gKi9cbmZ1bmN0aW9uIGdldElTT1dlZWsgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRpZmYgPSBzdGFydE9mSVNPV2VlayhkYXRlKS5nZXRUaW1lKCkgLSBzdGFydE9mSVNPWWVhcihkYXRlKS5nZXRUaW1lKClcblxuICAvLyBSb3VuZCB0aGUgbnVtYmVyIG9mIGRheXMgdG8gdGhlIG5lYXJlc3QgaW50ZWdlclxuICAvLyBiZWNhdXNlIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGluIGEgd2VlayBpcyBub3QgY29uc3RhbnRcbiAgLy8gKGUuZy4gaXQncyBkaWZmZXJlbnQgaW4gdGhlIHdlZWsgb2YgdGhlIGRheWxpZ2h0IHNhdmluZyB0aW1lIGNsb2NrIHNoaWZ0KVxuICByZXR1cm4gTWF0aC5yb3VuZChkaWZmIC8gTUlMTElTRUNPTkRTX0lOX1dFRUspICsgMVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldElTT1dlZWtcbiIsInZhciBzdGFydE9mSVNPWWVhciA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2lzb195ZWFyL2luZGV4LmpzJylcbnZhciBhZGRXZWVrcyA9IHJlcXVpcmUoJy4uL2FkZF93ZWVrcy9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fV0VFSyA9IDYwNDgwMDAwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2Vlay1OdW1iZXJpbmcgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiB3ZWVrcyBpbiBhbiBJU08gd2Vlay1udW1iZXJpbmcgeWVhciBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIHdlZWtzIGluIGFuIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBnaXZlbiBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbnVtYmVyIG9mIElTTyB3ZWVrcyBpbiBhIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSG93IG1hbnkgd2Vla3MgYXJlIGluIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIDIwMTU/XG4gKiB2YXIgcmVzdWx0ID0gZ2V0SVNPV2Vla3NJblllYXIobmV3IERhdGUoMjAxNSwgMSwgMTEpKVxuICogLy89PiA1M1xuICovXG5mdW5jdGlvbiBnZXRJU09XZWVrc0luWWVhciAoZGlydHlEYXRlKSB7XG4gIHZhciB0aGlzWWVhciA9IHN0YXJ0T2ZJU09ZZWFyKGRpcnR5RGF0ZSlcbiAgdmFyIG5leHRZZWFyID0gc3RhcnRPZklTT1llYXIoYWRkV2Vla3ModGhpc1llYXIsIDYwKSlcbiAgdmFyIGRpZmYgPSBuZXh0WWVhci52YWx1ZU9mKCkgLSB0aGlzWWVhci52YWx1ZU9mKClcbiAgLy8gUm91bmQgdGhlIG51bWJlciBvZiB3ZWVrcyB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyXG4gIC8vIGJlY2F1c2UgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaW4gYSB3ZWVrIGlzIG5vdCBjb25zdGFudFxuICAvLyAoZS5nLiBpdCdzIGRpZmZlcmVudCBpbiB0aGUgd2VlayBvZiB0aGUgZGF5bGlnaHQgc2F2aW5nIHRpbWUgY2xvY2sgc2hpZnQpXG4gIHJldHVybiBNYXRoLnJvdW5kKGRpZmYgLyBNSUxMSVNFQ09ORFNfSU5fV0VFSylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRJU09XZWVrc0luWWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIHN0YXJ0T2ZJU09XZWVrID0gcmVxdWlyZSgnLi4vc3RhcnRfb2ZfaXNvX3dlZWsvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2Vlay1OdW1iZXJpbmcgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBJU08gd2Vlay1udW1iZXJpbmcgeWVhciBvZiB0aGUgZ2l2ZW4gZGF0ZSxcbiAqIHdoaWNoIGFsd2F5cyBzdGFydHMgMyBkYXlzIGJlZm9yZSB0aGUgeWVhcidzIGZpcnN0IFRodXJzZGF5LlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBnaXZlbiBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hpY2ggSVNPLXdlZWsgbnVtYmVyaW5nIHllYXIgaXMgMiBKYW51YXJ5IDIwMDU/XG4gKiB2YXIgcmVzdWx0ID0gZ2V0SVNPWWVhcihuZXcgRGF0ZSgyMDA1LCAwLCAyKSlcbiAqIC8vPT4gMjAwNFxuICovXG5mdW5jdGlvbiBnZXRJU09ZZWFyIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpXG5cbiAgdmFyIGZvdXJ0aE9mSmFudWFyeU9mTmV4dFllYXIgPSBuZXcgRGF0ZSgwKVxuICBmb3VydGhPZkphbnVhcnlPZk5leHRZZWFyLnNldEZ1bGxZZWFyKHllYXIgKyAxLCAwLCA0KVxuICBmb3VydGhPZkphbnVhcnlPZk5leHRZZWFyLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHZhciBzdGFydE9mTmV4dFllYXIgPSBzdGFydE9mSVNPV2Vlayhmb3VydGhPZkphbnVhcnlPZk5leHRZZWFyKVxuXG4gIHZhciBmb3VydGhPZkphbnVhcnlPZlRoaXNZZWFyID0gbmV3IERhdGUoMClcbiAgZm91cnRoT2ZKYW51YXJ5T2ZUaGlzWWVhci5zZXRGdWxsWWVhcih5ZWFyLCAwLCA0KVxuICBmb3VydGhPZkphbnVhcnlPZlRoaXNZZWFyLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHZhciBzdGFydE9mVGhpc1llYXIgPSBzdGFydE9mSVNPV2Vlayhmb3VydGhPZkphbnVhcnlPZlRoaXNZZWFyKVxuXG4gIGlmIChkYXRlLmdldFRpbWUoKSA+PSBzdGFydE9mTmV4dFllYXIuZ2V0VGltZSgpKSB7XG4gICAgcmV0dXJuIHllYXIgKyAxXG4gIH0gZWxzZSBpZiAoZGF0ZS5nZXRUaW1lKCkgPj0gc3RhcnRPZlRoaXNZZWFyLmdldFRpbWUoKSkge1xuICAgIHJldHVybiB5ZWFyXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHllYXIgLSAxXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRJU09ZZWFyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbGxpc2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEdldCB0aGUgbWlsbGlzZWNvbmRzIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBtaWxsaXNlY29uZHMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG1pbGxpc2Vjb25kc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBHZXQgdGhlIG1pbGxpc2Vjb25kcyBvZiAyOSBGZWJydWFyeSAyMDEyIDExOjQ1OjA1LjEyMzpcbiAqIHZhciByZXN1bHQgPSBnZXRNaWxsaXNlY29uZHMobmV3IERhdGUoMjAxMiwgMSwgMjksIDExLCA0NSwgNSwgMTIzKSlcbiAqIC8vPT4gMTIzXG4gKi9cbmZ1bmN0aW9uIGdldE1pbGxpc2Vjb25kcyAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgbWlsbGlzZWNvbmRzID0gZGF0ZS5nZXRNaWxsaXNlY29uZHMoKVxuICByZXR1cm4gbWlsbGlzZWNvbmRzXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWlsbGlzZWNvbmRzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbnV0ZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG1pbnV0ZXMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG1pbnV0ZXMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIG1pbnV0ZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gR2V0IHRoZSBtaW51dGVzIG9mIDI5IEZlYnJ1YXJ5IDIwMTIgMTE6NDU6MDU6XG4gKiB2YXIgcmVzdWx0ID0gZ2V0TWludXRlcyhuZXcgRGF0ZSgyMDEyLCAxLCAyOSwgMTEsIDQ1LCA1KSlcbiAqIC8vPT4gNDVcbiAqL1xuZnVuY3Rpb24gZ2V0TWludXRlcyAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgbWludXRlcyA9IGRhdGUuZ2V0TWludXRlcygpXG4gIHJldHVybiBtaW51dGVzXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWludXRlc1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG1vbnRoIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogR2V0IHRoZSBtb250aCBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBnaXZlbiBkYXRlXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbW9udGhcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hpY2ggbW9udGggaXMgMjkgRmVicnVhcnkgMjAxMj9cbiAqIHZhciByZXN1bHQgPSBnZXRNb250aChuZXcgRGF0ZSgyMDEyLCAxLCAyOSkpXG4gKiAvLz0+IDFcbiAqL1xuZnVuY3Rpb24gZ2V0TW9udGggKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIG1vbnRoID0gZGF0ZS5nZXRNb250aCgpXG4gIHJldHVybiBtb250aFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbnZhciBNSUxMSVNFQ09ORFNfSU5fREFZID0gMjQgKiA2MCAqIDYwICogMTAwMFxuXG4vKipcbiAqIEBjYXRlZ29yeSBSYW5nZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG51bWJlciBvZiBkYXlzIHRoYXQgb3ZlcmxhcCBpbiB0d28gZGF0ZSByYW5nZXNcbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgbnVtYmVyIG9mIGRheXMgdGhhdCBvdmVybGFwIGluIHR3byBkYXRlIHJhbmdlc1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBpbml0aWFsUmFuZ2VTdGFydERhdGUgLSB0aGUgc3RhcnQgb2YgdGhlIGluaXRpYWwgcmFuZ2VcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBpbml0aWFsUmFuZ2VFbmREYXRlIC0gdGhlIGVuZCBvZiB0aGUgaW5pdGlhbCByYW5nZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGNvbXBhcmVkUmFuZ2VTdGFydERhdGUgLSB0aGUgc3RhcnQgb2YgdGhlIHJhbmdlIHRvIGNvbXBhcmUgaXQgd2l0aFxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGNvbXBhcmVkUmFuZ2VFbmREYXRlIC0gdGhlIGVuZCBvZiB0aGUgcmFuZ2UgdG8gY29tcGFyZSBpdCB3aXRoXG4gKiBAcmV0dXJucyB7TnVtYmVyfSB0aGUgbnVtYmVyIG9mIGRheXMgdGhhdCBvdmVybGFwIGluIHR3byBkYXRlIHJhbmdlc1xuICogQHRocm93cyB7RXJyb3J9IHN0YXJ0RGF0ZSBvZiBhIGRhdGUgcmFuZ2UgY2Fubm90IGJlIGFmdGVyIGl0cyBlbmREYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZvciBvdmVybGFwcGluZyBkYXRlIHJhbmdlcyBhZGRzIDEgZm9yIGVhY2ggc3RhcnRlZCBvdmVybGFwcGluZyBkYXk6XG4gKiBnZXRPdmVybGFwcGluZ0RheXNJblJhbmdlcyhcbiAqICAgbmV3IERhdGUoMjAxNCwgMCwgMTApLCBuZXcgRGF0ZSgyMDE0LCAwLCAyMCksIG5ldyBEYXRlKDIwMTQsIDAsIDE3KSwgbmV3IERhdGUoMjAxNCwgMCwgMjEpXG4gKiApXG4gKiAvLz0+IDNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRm9yIG5vbi1vdmVybGFwcGluZyBkYXRlIHJhbmdlcyByZXR1cm5zIDA6XG4gKiBnZXRPdmVybGFwcGluZ0RheXNJblJhbmdlcyhcbiAqICAgbmV3IERhdGUoMjAxNCwgMCwgMTApLCBuZXcgRGF0ZSgyMDE0LCAwLCAyMCksIG5ldyBEYXRlKDIwMTQsIDAsIDIxKSwgbmV3IERhdGUoMjAxNCwgMCwgMjIpXG4gKiApXG4gKiAvLz0+IDBcbiAqL1xuZnVuY3Rpb24gZ2V0T3ZlcmxhcHBpbmdEYXlzSW5SYW5nZXMgKGRpcnR5SW5pdGlhbFJhbmdlU3RhcnREYXRlLCBkaXJ0eUluaXRpYWxSYW5nZUVuZERhdGUsIGRpcnR5Q29tcGFyZWRSYW5nZVN0YXJ0RGF0ZSwgZGlydHlDb21wYXJlZFJhbmdlRW5kRGF0ZSkge1xuICB2YXIgaW5pdGlhbFN0YXJ0VGltZSA9IHBhcnNlKGRpcnR5SW5pdGlhbFJhbmdlU3RhcnREYXRlKS5nZXRUaW1lKClcbiAgdmFyIGluaXRpYWxFbmRUaW1lID0gcGFyc2UoZGlydHlJbml0aWFsUmFuZ2VFbmREYXRlKS5nZXRUaW1lKClcbiAgdmFyIGNvbXBhcmVkU3RhcnRUaW1lID0gcGFyc2UoZGlydHlDb21wYXJlZFJhbmdlU3RhcnREYXRlKS5nZXRUaW1lKClcbiAgdmFyIGNvbXBhcmVkRW5kVGltZSA9IHBhcnNlKGRpcnR5Q29tcGFyZWRSYW5nZUVuZERhdGUpLmdldFRpbWUoKVxuXG4gIGlmIChpbml0aWFsU3RhcnRUaW1lID4gaW5pdGlhbEVuZFRpbWUgfHwgY29tcGFyZWRTdGFydFRpbWUgPiBjb21wYXJlZEVuZFRpbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzdGFydCBvZiB0aGUgcmFuZ2UgY2Fubm90IGJlIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHJhbmdlJylcbiAgfVxuXG4gIHZhciBpc092ZXJsYXBwaW5nID0gaW5pdGlhbFN0YXJ0VGltZSA8IGNvbXBhcmVkRW5kVGltZSAmJiBjb21wYXJlZFN0YXJ0VGltZSA8IGluaXRpYWxFbmRUaW1lXG5cbiAgaWYgKCFpc092ZXJsYXBwaW5nKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIHZhciBvdmVybGFwU3RhcnREYXRlID0gY29tcGFyZWRTdGFydFRpbWUgPCBpbml0aWFsU3RhcnRUaW1lXG4gICAgPyBpbml0aWFsU3RhcnRUaW1lXG4gICAgOiBjb21wYXJlZFN0YXJ0VGltZVxuXG4gIHZhciBvdmVybGFwRW5kRGF0ZSA9IGNvbXBhcmVkRW5kVGltZSA+IGluaXRpYWxFbmRUaW1lXG4gICAgPyBpbml0aWFsRW5kVGltZVxuICAgIDogY29tcGFyZWRFbmRUaW1lXG5cbiAgdmFyIGRpZmZlcmVuY2VJbk1zID0gb3ZlcmxhcEVuZERhdGUgLSBvdmVybGFwU3RhcnREYXRlXG5cbiAgcmV0dXJuIE1hdGguY2VpbChkaWZmZXJlbmNlSW5NcyAvIE1JTExJU0VDT05EU19JTl9EQVkpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0T3ZlcmxhcHBpbmdEYXlzSW5SYW5nZXNcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgUXVhcnRlciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIHllYXIgcXVhcnRlciBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEdldCB0aGUgeWVhciBxdWFydGVyIG9mIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGdpdmVuIGRhdGVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHRoZSBxdWFydGVyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoaWNoIHF1YXJ0ZXIgaXMgMiBKdWx5IDIwMTQ/XG4gKiB2YXIgcmVzdWx0ID0gZ2V0UXVhcnRlcihuZXcgRGF0ZSgyMDE0LCA2LCAyKSlcbiAqIC8vPT4gM1xuICovXG5mdW5jdGlvbiBnZXRRdWFydGVyIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBxdWFydGVyID0gTWF0aC5mbG9vcihkYXRlLmdldE1vbnRoKCkgLyAzKSArIDFcbiAgcmV0dXJuIHF1YXJ0ZXJcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRRdWFydGVyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFNlY29uZCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIHNlY29uZHMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIHNlY29uZHMgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIHNlY29uZHNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gR2V0IHRoZSBzZWNvbmRzIG9mIDI5IEZlYnJ1YXJ5IDIwMTIgMTE6NDU6MDUuMTIzOlxuICogdmFyIHJlc3VsdCA9IGdldFNlY29uZHMobmV3IERhdGUoMjAxMiwgMSwgMjksIDExLCA0NSwgNSwgMTIzKSlcbiAqIC8vPT4gNVxuICovXG5mdW5jdGlvbiBnZXRTZWNvbmRzIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBzZWNvbmRzID0gZGF0ZS5nZXRTZWNvbmRzKClcbiAgcmV0dXJuIHNlY29uZHNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRTZWNvbmRzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFRpbWVzdGFtcCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIG1pbGxpc2Vjb25kcyB0aW1lc3RhbXAgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIG1pbGxpc2Vjb25kcyB0aW1lc3RhbXAgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIHRpbWVzdGFtcFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBHZXQgdGhlIHRpbWVzdGFtcCBvZiAyOSBGZWJydWFyeSAyMDEyIDExOjQ1OjA1LjEyMzpcbiAqIHZhciByZXN1bHQgPSBnZXRUaW1lKG5ldyBEYXRlKDIwMTIsIDEsIDI5LCAxMSwgNDUsIDUsIDEyMykpXG4gKiAvLz0+IDEzMzA1MTU5MDUxMjNcbiAqL1xuZnVuY3Rpb24gZ2V0VGltZSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgdGltZXN0YW1wID0gZGF0ZS5nZXRUaW1lKClcbiAgcmV0dXJuIHRpbWVzdGFtcFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFRpbWVcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBHZXQgdGhlIHllYXIgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBHZXQgdGhlIHllYXIgb2YgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZ2l2ZW4gZGF0ZVxuICogQHJldHVybnMge051bWJlcn0gdGhlIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gV2hpY2ggeWVhciBpcyAyIEp1bHkgMjAxND9cbiAqIHZhciByZXN1bHQgPSBnZXRZZWFyKG5ldyBEYXRlKDIwMTQsIDYsIDIpKVxuICogLy89PiAyMDE0XG4gKi9cbmZ1bmN0aW9uIGdldFllYXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKClcbiAgcmV0dXJuIHllYXJcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRZZWFyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZmlyc3QgZGF0ZSBhZnRlciB0aGUgc2Vjb25kIG9uZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBmaXJzdCBkYXRlIGFmdGVyIHRoZSBzZWNvbmQgb25lP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdGhhdCBzaG91bGQgYmUgYWZ0ZXIgdGhlIG90aGVyIG9uZSB0byByZXR1cm4gdHJ1ZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVUb0NvbXBhcmUgLSB0aGUgZGF0ZSB0byBjb21wYXJlIHdpdGhcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZmlyc3QgZGF0ZSBpcyBhZnRlciB0aGUgc2Vjb25kIGRhdGVcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMTAgSnVseSAxOTg5IGFmdGVyIDExIEZlYnJ1YXJ5IDE5ODc/XG4gKiB2YXIgcmVzdWx0ID0gaXNBZnRlcihuZXcgRGF0ZSgxOTg5LCA2LCAxMCksIG5ldyBEYXRlKDE5ODcsIDEsIDExKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc0FmdGVyIChkaXJ0eURhdGUsIGRpcnR5RGF0ZVRvQ29tcGFyZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRhdGVUb0NvbXBhcmUgPSBwYXJzZShkaXJ0eURhdGVUb0NvbXBhcmUpXG4gIHJldHVybiBkYXRlLmdldFRpbWUoKSA+IGRhdGVUb0NvbXBhcmUuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBZnRlclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBDb21tb24gSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGZpcnN0IGRhdGUgYmVmb3JlIHRoZSBzZWNvbmQgb25lP1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogSXMgdGhlIGZpcnN0IGRhdGUgYmVmb3JlIHRoZSBzZWNvbmQgb25lP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdGhhdCBzaG91bGQgYmUgYmVmb3JlIHRoZSBvdGhlciBvbmUgdG8gcmV0dXJuIHRydWVcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlVG9Db21wYXJlIC0gdGhlIGRhdGUgdG8gY29tcGFyZSB3aXRoXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGZpcnN0IGRhdGUgaXMgYmVmb3JlIHRoZSBzZWNvbmQgZGF0ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJcyAxMCBKdWx5IDE5ODkgYmVmb3JlIDExIEZlYnJ1YXJ5IDE5ODc/XG4gKiB2YXIgcmVzdWx0ID0gaXNCZWZvcmUobmV3IERhdGUoMTk4OSwgNiwgMTApLCBuZXcgRGF0ZSgxOTg3LCAxLCAxMSkpXG4gKiAvLz0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQmVmb3JlIChkaXJ0eURhdGUsIGRpcnR5RGF0ZVRvQ29tcGFyZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRhdGVUb0NvbXBhcmUgPSBwYXJzZShkaXJ0eURhdGVUb0NvbXBhcmUpXG4gIHJldHVybiBkYXRlLmdldFRpbWUoKSA8IGRhdGVUb0NvbXBhcmUuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNCZWZvcmVcbiIsIi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gYXJndW1lbnQgYW4gaW5zdGFuY2Ugb2YgRGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBhcmd1bWVudCBhbiBpbnN0YW5jZSBvZiBEYXRlP1xuICpcbiAqIEBwYXJhbSB7Kn0gYXJndW1lbnQgLSB0aGUgYXJndW1lbnQgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgYW4gaW5zdGFuY2Ugb2YgRGF0ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJcyAnbWF5b25uYWlzZScgYSBEYXRlP1xuICogdmFyIHJlc3VsdCA9IGlzRGF0ZSgnbWF5b25uYWlzZScpXG4gKiAvLz0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRGF0ZSAoYXJndW1lbnQpIHtcbiAgcmV0dXJuIGFyZ3VtZW50IGluc3RhbmNlb2YgRGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRGF0ZVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBDb21tb24gSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBlcXVhbD9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgZXF1YWw/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGZpcnN0IGRhdGUgdG8gY29tcGFyZVxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBzZWNvbmQgZGF0ZSB0byBjb21wYXJlXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGVzIGFyZSBlcXVhbFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBcmUgMiBKdWx5IDIwMTQgMDY6MzA6NDUuMDAwIGFuZCAyIEp1bHkgMjAxNCAwNjozMDo0NS41MDAgZXF1YWw/XG4gKiB2YXIgcmVzdWx0ID0gaXNFcXVhbChcbiAqICAgbmV3IERhdGUoMjAxNCwgNiwgMiwgNiwgMzAsIDQ1LCAwKVxuICogICBuZXcgRGF0ZSgyMDE0LCA2LCAyLCA2LCAzMCwgNDUsIDUwMClcbiAqIClcbiAqIC8vPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNFcXVhbCAoZGlydHlMZWZ0RGF0ZSwgZGlydHlSaWdodERhdGUpIHtcbiAgdmFyIGRhdGVMZWZ0ID0gcGFyc2UoZGlydHlMZWZ0RGF0ZSlcbiAgdmFyIGRhdGVSaWdodCA9IHBhcnNlKGRpcnR5UmlnaHREYXRlKVxuICByZXR1cm4gZGF0ZUxlZnQuZ2V0VGltZSgpID09PSBkYXRlUmlnaHQuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNFcXVhbFxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSB0aGUgZmlyc3QgZGF5IG9mIGEgbW9udGg/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSB0aGUgZmlyc3QgZGF5IG9mIGEgbW9udGg/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIHRoZSBmaXJzdCBkYXkgb2YgYSBtb250aFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJcyAxIFNlcHRlbWJlciAyMDE0IHRoZSBmaXJzdCBkYXkgb2YgYSBtb250aD9cbiAqIHZhciByZXN1bHQgPSBpc0ZpcnN0RGF5T2ZNb250aChuZXcgRGF0ZSgyMDE0LCA4LCAxKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc0ZpcnN0RGF5T2ZNb250aCAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldERhdGUoKSA9PT0gMVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRmlyc3REYXlPZk1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgRnJpZGF5P1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogSXMgdGhlIGdpdmVuIGRhdGUgRnJpZGF5P1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBGcmlkYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMjYgU2VwdGVtYmVyIDIwMTQgRnJpZGF5P1xuICogdmFyIHJlc3VsdCA9IGlzRnJpZGF5KG5ldyBEYXRlKDIwMTQsIDgsIDI2KSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc0ZyaWRheSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldERheSgpID09PSA1XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGcmlkYXlcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgQ29tbW9uIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBmdXR1cmU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgZnV0dXJlP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGUgZnV0dXJlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0LCBpcyAzMSBEZWNlbWJlciAyMDE0IGluIHRoZSBmdXR1cmU/XG4gKiB2YXIgcmVzdWx0ID0gaXNGdXR1cmUobmV3IERhdGUoMjAxNCwgMTEsIDMxKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc0Z1dHVyZSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldFRpbWUoKSA+IG5ldyBEYXRlKCkuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdXR1cmVcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBlbmRPZkRheSA9IHJlcXVpcmUoJy4uL2VuZF9vZl9kYXkvaW5kZXguanMnKVxudmFyIGVuZE9mTW9udGggPSByZXF1aXJlKCcuLi9lbmRfb2ZfbW9udGgvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSB0aGUgbGFzdCBkYXkgb2YgYSBtb250aD9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIHRoZSBsYXN0IGRheSBvZiBhIG1vbnRoP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyB0aGUgbGFzdCBkYXkgb2YgYSBtb250aFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJcyAyOCBGZWJydWFyeSAyMDE0IHRoZSBsYXN0IGRheSBvZiBhIG1vbnRoP1xuICogdmFyIHJlc3VsdCA9IGlzTGFzdERheU9mTW9udGgobmV3IERhdGUoMjAxNCwgMSwgMjgpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzTGFzdERheU9mTW9udGggKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgcmV0dXJuIGVuZE9mRGF5KGRhdGUpLmdldFRpbWUoKSA9PT0gZW5kT2ZNb250aChkYXRlKS5nZXRUaW1lKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xhc3REYXlPZk1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIGxlYXAgeWVhcj9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBsZWFwIHllYXI/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIGluIHRoZSBsZWFwIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMSBTZXB0ZW1iZXIgMjAxMiBpbiB0aGUgbGVhcCB5ZWFyP1xuICogdmFyIHJlc3VsdCA9IGlzTGVhcFllYXIobmV3IERhdGUoMjAxMiwgOCwgMSkpXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNMZWFwWWVhciAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKVxuICByZXR1cm4geWVhciAlIDQwMCA9PT0gMCB8fCB5ZWFyICUgNCA9PT0gMCAmJiB5ZWFyICUgMTAwICE9PSAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZWFwWWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrZGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIE1vbmRheT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIE1vbmRheT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgTW9uZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElzIDIyIFNlcHRlbWJlciAyMDE0IE1vbmRheT9cbiAqIHZhciByZXN1bHQgPSBpc01vbmRheShuZXcgRGF0ZSgyMDE0LCA4LCAyMikpXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNNb25kYXkgKGRpcnR5RGF0ZSkge1xuICByZXR1cm4gcGFyc2UoZGlydHlEYXRlKS5nZXREYXkoKSA9PT0gMVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTW9uZGF5XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgcGFzdD9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBwYXN0P1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGUgcGFzdFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0b2RheSBpcyA2IE9jdG9iZXIgMjAxNCwgaXMgMiBKdWx5IDIwMTQgaW4gdGhlIHBhc3Q/XG4gKiB2YXIgcmVzdWx0ID0gaXNQYXN0KG5ldyBEYXRlKDIwMTQsIDYsIDIpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzUGFzdCAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldFRpbWUoKSA8IG5ldyBEYXRlKCkuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQYXN0XG4iLCJ2YXIgc3RhcnRPZkRheSA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2RheS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIGRheT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgaW4gdGhlIHNhbWUgZGF5P1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBmaXJzdCBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIHNlY29uZCBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGVzIGFyZSBpbiB0aGUgc2FtZSBkYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDQgU2VwdGVtYmVyIDA2OjAwOjAwIGFuZCA0IFNlcHRlbWJlciAxODowMDowMCBpbiB0aGUgc2FtZSBkYXk/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lRGF5KFxuICogICBuZXcgRGF0ZSgyMDE0LCA4LCA0LCA2LCAwKSxcbiAqICAgbmV3IERhdGUoMjAxNCwgOCwgNCwgMTgsIDApXG4gKiApXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNTYW1lRGF5IChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnRTdGFydE9mRGF5ID0gc3RhcnRPZkRheShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0U3RhcnRPZkRheSA9IHN0YXJ0T2ZEYXkoZGlydHlEYXRlUmlnaHQpXG5cbiAgcmV0dXJuIGRhdGVMZWZ0U3RhcnRPZkRheS5nZXRUaW1lKCkgPT09IGRhdGVSaWdodFN0YXJ0T2ZEYXkuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTYW1lRGF5XG4iLCJ2YXIgc3RhcnRPZkhvdXIgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9ob3VyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSG91ciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIGhvdXI/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIGhvdXI/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGZpcnN0IGRhdGUgdG8gY2hlY2tcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgc2Vjb25kIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZXMgYXJlIGluIHRoZSBzYW1lIGhvdXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDQgU2VwdGVtYmVyIDIwMTQgMDY6MDA6MDAgYW5kIDQgU2VwdGVtYmVyIDA2OjMwOjAwIGluIHRoZSBzYW1lIGhvdXI/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lSG91cihcbiAqICAgbmV3IERhdGUoMjAxNCwgOCwgNCwgNiwgMCksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDQsIDYsIDMwKVxuICogKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2FtZUhvdXIgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHZhciBkYXRlTGVmdFN0YXJ0T2ZIb3VyID0gc3RhcnRPZkhvdXIoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodFN0YXJ0T2ZIb3VyID0gc3RhcnRPZkhvdXIoZGlydHlEYXRlUmlnaHQpXG5cbiAgcmV0dXJuIGRhdGVMZWZ0U3RhcnRPZkhvdXIuZ2V0VGltZSgpID09PSBkYXRlUmlnaHRTdGFydE9mSG91ci5nZXRUaW1lKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1NhbWVIb3VyXG4iLCJ2YXIgaXNTYW1lV2VlayA9IHJlcXVpcmUoJy4uL2lzX3NhbWVfd2Vlay9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IElTTyBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgaW4gdGhlIHNhbWUgSVNPIHdlZWs/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIElTTyB3ZWVrP1xuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgZmlyc3QgZGF0ZSB0byBjaGVja1xuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBzZWNvbmQgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlcyBhcmUgaW4gdGhlIHNhbWUgSVNPIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDEgU2VwdGVtYmVyIDIwMTQgYW5kIDcgU2VwdGVtYmVyIDIwMTQgaW4gdGhlIHNhbWUgSVNPIHdlZWs/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lSVNPV2VlayhcbiAqICAgbmV3IERhdGUoMjAxNCwgOCwgMSksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDcpXG4gKiApXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNTYW1lSVNPV2VlayAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgcmV0dXJuIGlzU2FtZVdlZWsoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQsIHt3ZWVrU3RhcnRzT246IDF9KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU2FtZUlTT1dlZWtcbiIsInZhciBzdGFydE9mSVNPWWVhciA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX2lzb195ZWFyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWstTnVtYmVyaW5nIFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSBJU08gd2Vlay1udW1iZXJpbmcgeWVhcj9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgaW4gdGhlIHNhbWUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXI/XG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBmaXJzdCBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIHNlY29uZCBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGVzIGFyZSBpbiB0aGUgc2FtZSBJU08gd2Vlay1udW1iZXJpbmcgeWVhclxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBcmUgMjkgRGVjZW1iZXIgMjAwMyBhbmQgMiBKYW51YXJ5IDIwMDUgaW4gdGhlIHNhbWUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXI/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lSVNPWWVhcihcbiAqICAgbmV3IERhdGUoMjAwMywgMTEsIDI5KSxcbiAqICAgbmV3IERhdGUoMjAwNSwgMCwgMilcbiAqIClcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1NhbWVJU09ZZWFyIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnRTdGFydE9mWWVhciA9IHN0YXJ0T2ZJU09ZZWFyKGRpcnR5RGF0ZUxlZnQpXG4gIHZhciBkYXRlUmlnaHRTdGFydE9mWWVhciA9IHN0YXJ0T2ZJU09ZZWFyKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHJldHVybiBkYXRlTGVmdFN0YXJ0T2ZZZWFyLmdldFRpbWUoKSA9PT0gZGF0ZVJpZ2h0U3RhcnRPZlllYXIuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTYW1lSVNPWWVhclxuIiwidmFyIHN0YXJ0T2ZNaW51dGUgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9taW51dGUvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNaW51dGUgSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSBtaW51dGU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIG1pbnV0ZT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgZmlyc3QgZGF0ZSB0byBjaGVja1xuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBzZWNvbmQgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlcyBhcmUgaW4gdGhlIHNhbWUgbWludXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFyZSA0IFNlcHRlbWJlciAyMDE0IDA2OjMwOjAwIGFuZCA0IFNlcHRlbWJlciAyMDE0IDA2OjMwOjE1XG4gKiAvLyBpbiB0aGUgc2FtZSBtaW51dGU/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lTWludXRlKFxuICogICBuZXcgRGF0ZSgyMDE0LCA4LCA0LCA2LCAzMCksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDQsIDYsIDMwLCAxNSlcbiAqIClcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1NhbWVNaW51dGUgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHZhciBkYXRlTGVmdFN0YXJ0T2ZNaW51dGUgPSBzdGFydE9mTWludXRlKGRpcnR5RGF0ZUxlZnQpXG4gIHZhciBkYXRlUmlnaHRTdGFydE9mTWludXRlID0gc3RhcnRPZk1pbnV0ZShkaXJ0eURhdGVSaWdodClcblxuICByZXR1cm4gZGF0ZUxlZnRTdGFydE9mTWludXRlLmdldFRpbWUoKSA9PT0gZGF0ZVJpZ2h0U3RhcnRPZk1pbnV0ZS5nZXRUaW1lKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1NhbWVNaW51dGVcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTW9udGggSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSBtb250aD9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgaW4gdGhlIHNhbWUgbW9udGg/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGZpcnN0IGRhdGUgdG8gY2hlY2tcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgc2Vjb25kIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZXMgYXJlIGluIHRoZSBzYW1lIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFyZSAyIFNlcHRlbWJlciAyMDE0IGFuZCAyNSBTZXB0ZW1iZXIgMjAxNCBpbiB0aGUgc2FtZSBtb250aD9cbiAqIHZhciByZXN1bHQgPSBpc1NhbWVNb250aChcbiAqICAgbmV3IERhdGUoMjAxNCwgOCwgMiksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDI1KVxuICogKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2FtZU1vbnRoIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnQgPSBwYXJzZShkaXJ0eURhdGVMZWZ0KVxuICB2YXIgZGF0ZVJpZ2h0ID0gcGFyc2UoZGlydHlEYXRlUmlnaHQpXG4gIHJldHVybiBkYXRlTGVmdC5nZXRGdWxsWWVhcigpID09PSBkYXRlUmlnaHQuZ2V0RnVsbFllYXIoKSAmJlxuICAgIGRhdGVMZWZ0LmdldE1vbnRoKCkgPT09IGRhdGVSaWdodC5nZXRNb250aCgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTYW1lTW9udGhcbiIsInZhciBzdGFydE9mUXVhcnRlciA9IHJlcXVpcmUoJy4uL3N0YXJ0X29mX3F1YXJ0ZXIvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBRdWFydGVyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IEFyZSB0aGUgZ2l2ZW4gZGF0ZXMgaW4gdGhlIHNhbWUgeWVhciBxdWFydGVyP1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSB5ZWFyIHF1YXJ0ZXI/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGZpcnN0IGRhdGUgdG8gY2hlY2tcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgc2Vjb25kIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZXMgYXJlIGluIHRoZSBzYW1lIHF1YXJ0ZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDEgSmFudWFyeSAyMDE0IGFuZCA4IE1hcmNoIDIwMTQgaW4gdGhlIHNhbWUgcXVhcnRlcj9cbiAqIHZhciByZXN1bHQgPSBpc1NhbWVRdWFydGVyKFxuICogICBuZXcgRGF0ZSgyMDE0LCAwLCAxKSxcbiAqICAgbmV3IERhdGUoMjAxNCwgMiwgOClcbiAqIClcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1NhbWVRdWFydGVyIChkaXJ0eURhdGVMZWZ0LCBkaXJ0eURhdGVSaWdodCkge1xuICB2YXIgZGF0ZUxlZnRTdGFydE9mUXVhcnRlciA9IHN0YXJ0T2ZRdWFydGVyKGRpcnR5RGF0ZUxlZnQpXG4gIHZhciBkYXRlUmlnaHRTdGFydE9mUXVhcnRlciA9IHN0YXJ0T2ZRdWFydGVyKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHJldHVybiBkYXRlTGVmdFN0YXJ0T2ZRdWFydGVyLmdldFRpbWUoKSA9PT0gZGF0ZVJpZ2h0U3RhcnRPZlF1YXJ0ZXIuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTYW1lUXVhcnRlclxuIiwidmFyIHN0YXJ0T2ZTZWNvbmQgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9zZWNvbmQvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBTZWNvbmQgSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSBzZWNvbmQ/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIHNlY29uZD9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZUxlZnQgLSB0aGUgZmlyc3QgZGF0ZSB0byBjaGVja1xuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVSaWdodCAtIHRoZSBzZWNvbmQgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlcyBhcmUgaW4gdGhlIHNhbWUgc2Vjb25kXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEFyZSA0IFNlcHRlbWJlciAyMDE0IDA2OjMwOjE1LjAwMCBhbmQgNCBTZXB0ZW1iZXIgMjAxNCAwNjozMC4xNS41MDBcbiAqIC8vIGluIHRoZSBzYW1lIHNlY29uZD9cbiAqIHZhciByZXN1bHQgPSBpc1NhbWVTZWNvbmQoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDQsIDYsIDMwLCAxNSksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDQsIDYsIDMwLCAxNSwgNTAwKVxuICogKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2FtZVNlY29uZCAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQpIHtcbiAgdmFyIGRhdGVMZWZ0U3RhcnRPZlNlY29uZCA9IHN0YXJ0T2ZTZWNvbmQoZGlydHlEYXRlTGVmdClcbiAgdmFyIGRhdGVSaWdodFN0YXJ0T2ZTZWNvbmQgPSBzdGFydE9mU2Vjb25kKGRpcnR5RGF0ZVJpZ2h0KVxuXG4gIHJldHVybiBkYXRlTGVmdFN0YXJ0T2ZTZWNvbmQuZ2V0VGltZSgpID09PSBkYXRlUmlnaHRTdGFydE9mU2Vjb25kLmdldFRpbWUoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU2FtZVNlY29uZFxuIiwidmFyIHN0YXJ0T2ZXZWVrID0gcmVxdWlyZSgnLi4vc3RhcnRfb2Zfd2Vlay9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWsgSGVscGVyc1xuICogQHN1bW1hcnkgQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSB3ZWVrP1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQXJlIHRoZSBnaXZlbiBkYXRlcyBpbiB0aGUgc2FtZSB3ZWVrP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlTGVmdCAtIHRoZSBmaXJzdCBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZVJpZ2h0IC0gdGhlIHNlY29uZCBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gdGhlIG9iamVjdCB3aXRoIG9wdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy53ZWVrU3RhcnRzT249MF0gLSB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayAoMCAtIFN1bmRheSlcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZXMgYXJlIGluIHRoZSBzYW1lIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDMxIEF1Z3VzdCAyMDE0IGFuZCA0IFNlcHRlbWJlciAyMDE0IGluIHRoZSBzYW1lIHdlZWs/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lV2VlayhcbiAqICAgbmV3IERhdGUoMjAxNCwgNywgMzEpLFxuICogICBuZXcgRGF0ZSgyMDE0LCA4LCA0KVxuICogKVxuICogLy89PiB0cnVlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHdlZWsgc3RhcnRzIHdpdGggTW9uZGF5LFxuICogLy8gYXJlIDMxIEF1Z3VzdCAyMDE0IGFuZCA0IFNlcHRlbWJlciAyMDE0IGluIHRoZSBzYW1lIHdlZWs/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lV2VlayhcbiAqICAgbmV3IERhdGUoMjAxNCwgNywgMzEpLFxuICogICBuZXcgRGF0ZSgyMDE0LCA4LCA0KSxcbiAqICAge3dlZWtTdGFydHNPbjogMX1cbiAqIClcbiAqIC8vPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTYW1lV2VlayAoZGlydHlEYXRlTGVmdCwgZGlydHlEYXRlUmlnaHQsIGRpcnR5T3B0aW9ucykge1xuICB2YXIgZGF0ZUxlZnRTdGFydE9mV2VlayA9IHN0YXJ0T2ZXZWVrKGRpcnR5RGF0ZUxlZnQsIGRpcnR5T3B0aW9ucylcbiAgdmFyIGRhdGVSaWdodFN0YXJ0T2ZXZWVrID0gc3RhcnRPZldlZWsoZGlydHlEYXRlUmlnaHQsIGRpcnR5T3B0aW9ucylcblxuICByZXR1cm4gZGF0ZUxlZnRTdGFydE9mV2Vlay5nZXRUaW1lKCkgPT09IGRhdGVSaWdodFN0YXJ0T2ZXZWVrLmdldFRpbWUoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU2FtZVdlZWtcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIHllYXI/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBcmUgdGhlIGdpdmVuIGRhdGVzIGluIHRoZSBzYW1lIHllYXI/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGVMZWZ0IC0gdGhlIGZpcnN0IGRhdGUgdG8gY2hlY2tcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlUmlnaHQgLSB0aGUgc2Vjb25kIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZXMgYXJlIGluIHRoZSBzYW1lIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXJlIDIgU2VwdGVtYmVyIDIwMTQgYW5kIDI1IFNlcHRlbWJlciAyMDE0IGluIHRoZSBzYW1lIHllYXI/XG4gKiB2YXIgcmVzdWx0ID0gaXNTYW1lWWVhcihcbiAqICAgbmV3IERhdGUoMjAxNCwgOCwgMiksXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDgsIDI1KVxuICogKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2FtZVllYXIgKGRpcnR5RGF0ZUxlZnQsIGRpcnR5RGF0ZVJpZ2h0KSB7XG4gIHZhciBkYXRlTGVmdCA9IHBhcnNlKGRpcnR5RGF0ZUxlZnQpXG4gIHZhciBkYXRlUmlnaHQgPSBwYXJzZShkaXJ0eURhdGVSaWdodClcbiAgcmV0dXJuIGRhdGVMZWZ0LmdldEZ1bGxZZWFyKCkgPT09IGRhdGVSaWdodC5nZXRGdWxsWWVhcigpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTYW1lWWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrZGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIFNhdHVyZGF5P1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogSXMgdGhlIGdpdmVuIGRhdGUgU2F0dXJkYXk/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIFNhdHVyZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElzIDI3IFNlcHRlbWJlciAyMDE0IFNhdHVyZGF5P1xuICogdmFyIHJlc3VsdCA9IGlzU2F0dXJkYXkobmV3IERhdGUoMjAxNCwgOCwgMjcpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU2F0dXJkYXkgKGRpcnR5RGF0ZSkge1xuICByZXR1cm4gcGFyc2UoZGlydHlEYXRlKS5nZXREYXkoKSA9PT0gNlxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU2F0dXJkYXlcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2Vla2RheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSBTdW5kYXk/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBTdW5kYXk/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIFN1bmRheVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJcyAyMSBTZXB0ZW1iZXIgMjAxNCBTdW5kYXk/XG4gKiB2YXIgcmVzdWx0ID0gaXNTdW5kYXkobmV3IERhdGUoMjAxNCwgOCwgMjEpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzU3VuZGF5IChkaXJ0eURhdGUpIHtcbiAgcmV0dXJuIHBhcnNlKGRpcnR5RGF0ZSkuZ2V0RGF5KCkgPT09IDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N1bmRheVxuIiwidmFyIGlzU2FtZUhvdXIgPSByZXF1aXJlKCcuLi9pc19zYW1lX2hvdXIvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBIb3VyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIGhvdXIgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIGhvdXIgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgaW4gdGhpcyBob3VyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIG5vdyBpcyAyNSBTZXB0ZW1iZXIgMjAxNCAxODozMDoxNS41MDAsXG4gKiAvLyBpcyAyNSBTZXB0ZW1iZXIgMjAxNCAxODowMDowMCBpbiB0aGlzIGhvdXI/XG4gKiB2YXIgcmVzdWx0ID0gaXNUaGlzSG91cihuZXcgRGF0ZSgyMDE0LCA4LCAyNSwgMTgpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzVGhpc0hvdXIgKGRpcnR5RGF0ZSkge1xuICByZXR1cm4gaXNTYW1lSG91cihuZXcgRGF0ZSgpLCBkaXJ0eURhdGUpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUaGlzSG91clxuIiwidmFyIGlzU2FtZUlTT1dlZWsgPSByZXF1aXJlKCcuLi9pc19zYW1lX2lzb193ZWVrL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWsgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIHNhbWUgSVNPIHdlZWsgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIElTTyB3ZWVrIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGlzIElTTyB3ZWVrXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDI1IFNlcHRlbWJlciAyMDE0LCBpcyAyMiBTZXB0ZW1iZXIgMjAxNCBpbiB0aGlzIElTTyB3ZWVrP1xuICogdmFyIHJlc3VsdCA9IGlzVGhpc0lTT1dlZWsobmV3IERhdGUoMjAxNCwgOCwgMjIpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzVGhpc0lTT1dlZWsgKGRpcnR5RGF0ZSkge1xuICByZXR1cm4gaXNTYW1lSVNPV2VlayhuZXcgRGF0ZSgpLCBkaXJ0eURhdGUpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUaGlzSVNPV2Vla1xuIiwidmFyIGlzU2FtZUlTT1llYXIgPSByZXF1aXJlKCcuLi9pc19zYW1lX2lzb195ZWFyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWstTnVtYmVyaW5nIFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIHNhbWUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGlzIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDI1IFNlcHRlbWJlciAyMDE0LFxuICogLy8gaXMgMzAgRGVjZW1iZXIgMjAxMyBpbiB0aGlzIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyP1xuICogdmFyIHJlc3VsdCA9IGlzVGhpc0lTT1llYXIobmV3IERhdGUoMjAxMywgMTEsIDMwKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1RoaXNJU09ZZWFyIChkaXJ0eURhdGUpIHtcbiAgcmV0dXJuIGlzU2FtZUlTT1llYXIobmV3IERhdGUoKSwgZGlydHlEYXRlKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGhpc0lTT1llYXJcbiIsInZhciBpc1NhbWVNaW51dGUgPSByZXF1aXJlKCcuLi9pc19zYW1lX21pbnV0ZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbnV0ZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSBtaW51dGUgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIG1pbnV0ZSBhcyB0aGUgY3VycmVudCBkYXRlP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGlzIG1pbnV0ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiBub3cgaXMgMjUgU2VwdGVtYmVyIDIwMTQgMTg6MzA6MTUuNTAwLFxuICogLy8gaXMgMjUgU2VwdGVtYmVyIDIwMTQgMTg6MzA6MDAgaW4gdGhpcyBtaW51dGU/XG4gKiB2YXIgcmVzdWx0ID0gaXNUaGlzTWludXRlKG5ldyBEYXRlKDIwMTQsIDgsIDI1LCAxOCwgMzApKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzVGhpc01pbnV0ZSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc1NhbWVNaW51dGUobmV3IERhdGUoKSwgZGlydHlEYXRlKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGhpc01pbnV0ZVxuIiwidmFyIGlzU2FtZU1vbnRoID0gcmVxdWlyZSgnLi4vaXNfc2FtZV9tb250aC9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1vbnRoIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIG1vbnRoIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSBtb250aCBhcyB0aGUgY3VycmVudCBkYXRlP1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGlzIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDI1IFNlcHRlbWJlciAyMDE0LCBpcyAxNSBTZXB0ZW1iZXIgMjAxNCBpbiB0aGlzIG1vbnRoP1xuICogdmFyIHJlc3VsdCA9IGlzVGhpc01vbnRoKG5ldyBEYXRlKDIwMTQsIDgsIDE1KSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1RoaXNNb250aCAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc1NhbWVNb250aChuZXcgRGF0ZSgpLCBkaXJ0eURhdGUpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUaGlzTW9udGhcbiIsInZhciBpc1NhbWVRdWFydGVyID0gcmVxdWlyZSgnLi4vaXNfc2FtZV9xdWFydGVyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgUXVhcnRlciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSBxdWFydGVyIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSBxdWFydGVyIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIGluIHRoaXMgcXVhcnRlclxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0b2RheSBpcyAyNSBTZXB0ZW1iZXIgMjAxNCwgaXMgMiBKdWx5IDIwMTQgaW4gdGhpcyBxdWFydGVyP1xuICogdmFyIHJlc3VsdCA9IGlzVGhpc1F1YXJ0ZXIobmV3IERhdGUoMjAxNCwgNiwgMikpXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNUaGlzUXVhcnRlciAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc1NhbWVRdWFydGVyKG5ldyBEYXRlKCksIGRpcnR5RGF0ZSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1RoaXNRdWFydGVyXG4iLCJ2YXIgaXNTYW1lU2Vjb25kID0gcmVxdWlyZSgnLi4vaXNfc2FtZV9zZWNvbmQvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBTZWNvbmQgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIHNhbWUgc2Vjb25kIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSBzZWNvbmQgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgaW4gdGhpcyBzZWNvbmRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgbm93IGlzIDI1IFNlcHRlbWJlciAyMDE0IDE4OjMwOjE1LjUwMCxcbiAqIC8vIGlzIDI1IFNlcHRlbWJlciAyMDE0IDE4OjMwOjE1LjAwMCBpbiB0aGlzIHNlY29uZD9cbiAqIHZhciByZXN1bHQgPSBpc1RoaXNTZWNvbmQobmV3IERhdGUoMjAxNCwgOCwgMjUsIDE4LCAzMCwgMTUpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzVGhpc1NlY29uZCAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc1NhbWVTZWNvbmQobmV3IERhdGUoKSwgZGlydHlEYXRlKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGhpc1NlY29uZFxuIiwidmFyIGlzU2FtZVdlZWsgPSByZXF1aXJlKCcuLi9pc19zYW1lX3dlZWsvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIHdlZWsgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBzYW1lIHdlZWsgYXMgdGhlIGN1cnJlbnQgZGF0ZT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gdGhlIG9iamVjdCB3aXRoIG9wdGlvbnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy53ZWVrU3RhcnRzT249MF0gLSB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayAoMCAtIFN1bmRheSlcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBpbiB0aGlzIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgMjUgU2VwdGVtYmVyIDIwMTQsIGlzIDIxIFNlcHRlbWJlciAyMDE0IGluIHRoaXMgd2Vlaz9cbiAqIHZhciByZXN1bHQgPSBpc1RoaXNXZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIxKSlcbiAqIC8vPT4gdHJ1ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0b2RheSBpcyAyNSBTZXB0ZW1iZXIgMjAxNCBhbmQgd2VlayBzdGFydHMgd2l0aCBNb25kYXlcbiAqIC8vIGlzIDIxIFNlcHRlbWJlciAyMDE0IGluIHRoaXMgd2Vlaz9cbiAqIHZhciByZXN1bHQgPSBpc1RoaXNXZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIxKSwge3dlZWtTdGFydHNPbjogMX0pXG4gKiAvLz0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVGhpc1dlZWsgKGRpcnR5RGF0ZSwgZGlydHlPcHRpb25zKSB7XG4gIHJldHVybiBpc1NhbWVXZWVrKG5ldyBEYXRlKCksIGRpcnR5RGF0ZSwgZGlydHlPcHRpb25zKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGhpc1dlZWtcbiIsInZhciBpc1NhbWVZZWFyID0gcmVxdWlyZSgnLi4vaXNfc2FtZV95ZWFyL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSB5ZWFyIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgc2FtZSB5ZWFyIGFzIHRoZSBjdXJyZW50IGRhdGU/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIGluIHRoaXMgeWVhclxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0b2RheSBpcyAyNSBTZXB0ZW1iZXIgMjAxNCwgaXMgMiBKdWx5IDIwMTQgaW4gdGhpcyB5ZWFyP1xuICogdmFyIHJlc3VsdCA9IGlzVGhpc1llYXIobmV3IERhdGUoMjAxNCwgNiwgMikpXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNUaGlzWWVhciAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBpc1NhbWVZZWFyKG5ldyBEYXRlKCksIGRpcnR5RGF0ZSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1RoaXNZZWFyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgVGh1cnNkYXk/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBUaHVyc2RheT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgVGh1cnNkYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMjUgU2VwdGVtYmVyIDIwMTQgVGh1cnNkYXk/XG4gKiB2YXIgcmVzdWx0ID0gaXNUaHVyc2RheShuZXcgRGF0ZSgyMDE0LCA4LCAyNSkpXG4gKiAvLz0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaXNUaHVyc2RheSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldERheSgpID09PSA0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUaHVyc2RheVxuIiwidmFyIHN0YXJ0T2ZEYXkgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9kYXkvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgdG9kYXk/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSB0b2RheT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgdG9kYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgNiBPY3RvYmVyIDIwMTQsIGlzIDYgT2N0b2JlciAxNDowMDowMCB0b2RheT9cbiAqIHZhciByZXN1bHQgPSBpc1RvZGF5KG5ldyBEYXRlKDIwMTQsIDksIDYsIDE0LCAwKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1RvZGF5IChkaXJ0eURhdGUpIHtcbiAgcmV0dXJuIHN0YXJ0T2ZEYXkoZGlydHlEYXRlKS5nZXRUaW1lKCkgPT09IHN0YXJ0T2ZEYXkobmV3IERhdGUoKSkuZ2V0VGltZSgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUb2RheVxuIiwidmFyIHN0YXJ0T2ZEYXkgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9kYXkvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgdG9tb3Jyb3c/XG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJcyB0aGUgZ2l2ZW4gZGF0ZSB0b21vcnJvdz9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgdG9tb3Jyb3dcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgNiBPY3RvYmVyIDIwMTQsIGlzIDcgT2N0b2JlciAxNDowMDowMCB0b21vcnJvdz9cbiAqIHZhciByZXN1bHQgPSBpc1RvbW9ycm93KG5ldyBEYXRlKDIwMTQsIDksIDcsIDE0LCAwKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1RvbW9ycm93IChkaXJ0eURhdGUpIHtcbiAgdmFyIHRvbW9ycm93ID0gbmV3IERhdGUoKVxuICB0b21vcnJvdy5zZXREYXRlKHRvbW9ycm93LmdldERhdGUoKSArIDEpXG4gIHJldHVybiBzdGFydE9mRGF5KGRpcnR5RGF0ZSkuZ2V0VGltZSgpID09PSBzdGFydE9mRGF5KHRvbW9ycm93KS5nZXRUaW1lKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1RvbW9ycm93XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgVHVlc2RheT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIFR1ZXNkYXk/XG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBjaGVja1xuICogQHJldHVybnMge0Jvb2xlYW59IHRoZSBkYXRlIGlzIFR1ZXNkYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMjMgU2VwdGVtYmVyIDIwMTQgVHVlc2RheT9cbiAqIHZhciByZXN1bHQgPSBpc1R1ZXNkYXkobmV3IERhdGUoMjAxNCwgOCwgMjMpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzVHVlc2RheSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldERheSgpID09PSAyXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUdWVzZGF5XG4iLCJ2YXIgaXNEYXRlID0gcmVxdWlyZSgnLi4vaXNfZGF0ZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSB2YWxpZD9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybnMgZmFsc2UgaWYgYXJndW1lbnQgaXMgSW52YWxpZCBEYXRlIGFuZCB0cnVlIG90aGVyd2lzZS5cbiAqIEludmFsaWQgRGF0ZSBpcyBhIERhdGUsIHdob3NlIHRpbWUgdmFsdWUgaXMgTmFOLlxuICpcbiAqIFRpbWUgdmFsdWUgb2YgRGF0ZTogaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS45LjEuMVxuICpcbiAqIEBwYXJhbSB7RGF0ZX0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgdmFsaWRcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gYXJndW1lbnQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBEYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZvciB0aGUgdmFsaWQgZGF0ZTpcbiAqIHZhciByZXN1bHQgPSBpc1ZhbGlkKG5ldyBEYXRlKDIwMTQsIDEsIDMxKSlcbiAqIC8vPT4gdHJ1ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBGb3IgdGhlIGludmFsaWQgZGF0ZTpcbiAqIHZhciByZXN1bHQgPSBpc1ZhbGlkKG5ldyBEYXRlKCcnKSlcbiAqIC8vPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNWYWxpZCAoZGlydHlEYXRlKSB7XG4gIGlmIChpc0RhdGUoZGlydHlEYXRlKSkge1xuICAgIHJldHVybiAhaXNOYU4oZGlydHlEYXRlKVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IodG9TdHJpbmcuY2FsbChkaXJ0eURhdGUpICsgJyBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgRGF0ZScpXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1ZhbGlkXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgSXMgdGhlIGdpdmVuIGRhdGUgV2VkbmVzZGF5P1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogSXMgdGhlIGdpdmVuIGRhdGUgV2VkbmVzZGF5P1xuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyBXZWRuZXNkYXlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSXMgMjQgU2VwdGVtYmVyIDIwMTQgV2VkbmVzZGF5P1xuICogdmFyIHJlc3VsdCA9IGlzV2VkbmVzZGF5KG5ldyBEYXRlKDIwMTQsIDgsIDI0KSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1dlZG5lc2RheSAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBwYXJzZShkaXJ0eURhdGUpLmdldERheSgpID09PSAzXG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNXZWRuZXNkYXlcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2Vla2RheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBEb2VzIHRoZSBnaXZlbiBkYXRlIGZhbGwgb24gYSB3ZWVrZW5kP1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogRG9lcyB0aGUgZ2l2ZW4gZGF0ZSBmYWxsIG9uIGEgd2Vla2VuZD9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgZmFsbHMgb24gYSB3ZWVrZW5kXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIERvZXMgNSBPY3RvYmVyIDIwMTQgZmFsbCBvbiBhIHdlZWtlbmQ/XG4gKiB2YXIgcmVzdWx0ID0gaXNXZWVrZW5kKG5ldyBEYXRlKDIwMTQsIDksIDUpKVxuICogLy89PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzV2Vla2VuZCAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKVxuICByZXR1cm4gZGF5ID09PSAwIHx8IGRheSA9PT0gNlxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzV2Vla2VuZFxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBSYW5nZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBJcyB0aGUgZ2l2ZW4gZGF0ZSB3aXRoaW4gdGhlIHJhbmdlP1xuICpcbiAqIEBkZXNjcmlwdGlvblxuICogSXMgdGhlIGdpdmVuIGRhdGUgd2l0aGluIHRoZSByYW5nZT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gc3RhcnREYXRlIC0gdGhlIHN0YXJ0IG9mIHJhbmdlXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZW5kRGF0ZSAtIHRoZSBlbmQgb2YgcmFuZ2VcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0aGUgZGF0ZSBpcyB3aXRoaW4gdGhlIHJhbmdlXG4gKiBAdGhyb3dzIHtFcnJvcn0gc3RhcnREYXRlIGNhbm5vdCBiZSBhZnRlciBlbmREYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZvciB0aGUgZGF0ZSB3aXRoaW4gdGhlIHJhbmdlOlxuICogaXNXaXRoaW5SYW5nZShcbiAqICAgbmV3IERhdGUoMjAxNCwgMCwgMyksIG5ldyBEYXRlKDIwMTQsIDAsIDEpLCBuZXcgRGF0ZSgyMDE0LCAwLCA3KVxuICogKVxuICogLy89PiB0cnVlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZvciB0aGUgZGF0ZSBvdXRzaWRlIG9mIHRoZSByYW5nZTpcbiAqIGlzV2l0aGluUmFuZ2UoXG4gKiAgIG5ldyBEYXRlKDIwMTQsIDAsIDEwKSwgbmV3IERhdGUoMjAxNCwgMCwgMSksIG5ldyBEYXRlKDIwMTQsIDAsIDcpXG4gKiApXG4gKiAvLz0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzV2l0aGluUmFuZ2UgKGRpcnR5RGF0ZSwgZGlydHlTdGFydERhdGUsIGRpcnR5RW5kRGF0ZSkge1xuICB2YXIgdGltZSA9IHBhcnNlKGRpcnR5RGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBzdGFydFRpbWUgPSBwYXJzZShkaXJ0eVN0YXJ0RGF0ZSkuZ2V0VGltZSgpXG4gIHZhciBlbmRUaW1lID0gcGFyc2UoZGlydHlFbmREYXRlKS5nZXRUaW1lKClcblxuICBpZiAoc3RhcnRUaW1lID4gZW5kVGltZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIHN0YXJ0IG9mIHRoZSByYW5nZSBjYW5ub3QgYmUgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgcmFuZ2UnKVxuICB9XG5cbiAgcmV0dXJuIHRpbWUgPj0gc3RhcnRUaW1lICYmIHRpbWUgPD0gZW5kVGltZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzV2l0aGluUmFuZ2VcbiIsInZhciBzdGFydE9mRGF5ID0gcmVxdWlyZSgnLi4vc3RhcnRfb2ZfZGF5L2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgRGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IElzIHRoZSBnaXZlbiBkYXRlIHllc3RlcmRheT9cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIElzIHRoZSBnaXZlbiBkYXRlIHllc3RlcmRheT9cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gdGhlIGRhdGUgaXMgeWVzdGVyZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0LCBpcyA1IE9jdG9iZXIgMTQ6MDA6MDAgeWVzdGVyZGF5P1xuICogdmFyIHJlc3VsdCA9IGlzWWVzdGVyZGF5KG5ldyBEYXRlKDIwMTQsIDksIDUsIDE0LCAwKSlcbiAqIC8vPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1llc3RlcmRheSAoZGlydHlEYXRlKSB7XG4gIHZhciB5ZXN0ZXJkYXkgPSBuZXcgRGF0ZSgpXG4gIHllc3RlcmRheS5zZXREYXRlKHllc3RlcmRheS5nZXREYXRlKCkgLSAxKVxuICByZXR1cm4gc3RhcnRPZkRheShkaXJ0eURhdGUpLmdldFRpbWUoKSA9PT0gc3RhcnRPZkRheSh5ZXN0ZXJkYXkpLmdldFRpbWUoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzWWVzdGVyZGF5XG4iLCJ2YXIgbGFzdERheU9mV2VlayA9IHJlcXVpcmUoJy4uL2xhc3RfZGF5X29mX3dlZWsvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGFuIElTTyB3ZWVrIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgbGFzdCBkYXkgb2YgYW4gSVNPIHdlZWsgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBsYXN0IGRheSBvZiBhbiBJU08gd2Vla1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgbGFzdCBkYXkgb2YgYW4gSVNPIHdlZWsgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gbGFzdERheU9mSVNPV2VlayhuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBTdW4gU2VwIDA3IDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gbGFzdERheU9mSVNPV2VlayAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBsYXN0RGF5T2ZXZWVrKGRpcnR5RGF0ZSwge3dlZWtTdGFydHNPbjogMX0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdERheU9mSVNPV2Vla1xuIiwidmFyIGdldElTT1llYXIgPSByZXF1aXJlKCcuLi9nZXRfaXNvX3llYXIvaW5kZXguanMnKVxudmFyIHN0YXJ0T2ZJU09XZWVrID0gcmVxdWlyZSgnLi4vc3RhcnRfb2ZfaXNvX3dlZWsvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBJU08gV2Vlay1OdW1iZXJpbmcgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGFuIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgbGFzdCBkYXkgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIsXG4gKiB3aGljaCBhbHdheXMgc3RhcnRzIDMgZGF5cyBiZWZvcmUgdGhlIHllYXIncyBmaXJzdCBUaHVyc2RheS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZW5kIG9mIGFuIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBsYXN0IGRheSBvZiBhbiBJU08gd2Vlay1udW1iZXJpbmcgeWVhciBmb3IgMiBKdWx5IDIwMDU6XG4gKiB2YXIgcmVzdWx0ID0gbGFzdERheU9mSVNPWWVhcihuZXcgRGF0ZSgyMDA1LCA2LCAyKSlcbiAqIC8vPT4gU3VuIEphbiAwMSAyMDA2IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGxhc3REYXlPZklTT1llYXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgeWVhciA9IGdldElTT1llYXIoZGlydHlEYXRlKVxuICB2YXIgZm91cnRoT2ZKYW51YXJ5ID0gbmV3IERhdGUoMClcbiAgZm91cnRoT2ZKYW51YXJ5LnNldEZ1bGxZZWFyKHllYXIgKyAxLCAwLCA0KVxuICBmb3VydGhPZkphbnVhcnkuc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgdmFyIGRhdGUgPSBzdGFydE9mSVNPV2Vlayhmb3VydGhPZkphbnVhcnkpXG4gIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSAtIDEpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdERheU9mSVNPWWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgbW9udGggZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBsYXN0IGRheSBvZiBhIG1vbnRoIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBsYXN0IGRheSBvZiBhIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBsYXN0IGRheSBvZiBhIG1vbnRoIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IGxhc3REYXlPZk1vbnRoKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFR1ZSBTZXAgMzAgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBsYXN0RGF5T2ZNb250aCAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgbW9udGggPSBkYXRlLmdldE1vbnRoKClcbiAgZGF0ZS5zZXRGdWxsWWVhcihkYXRlLmdldEZ1bGxZZWFyKCksIG1vbnRoICsgMSwgMClcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3REYXlPZk1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFF1YXJ0ZXIgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBsYXN0IGRheSBvZiBhIHllYXIgcXVhcnRlciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgeWVhciBxdWFydGVyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBsYXN0IGRheSBvZiBhIHF1YXJ0ZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGxhc3QgZGF5IG9mIGEgcXVhcnRlciBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBsYXN0RGF5T2ZRdWFydGVyKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFR1ZSBTZXAgMzAgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBsYXN0RGF5T2ZRdWFydGVyIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBjdXJyZW50TW9udGggPSBkYXRlLmdldE1vbnRoKClcbiAgdmFyIG1vbnRoID0gY3VycmVudE1vbnRoIC0gY3VycmVudE1vbnRoICUgMyArIDNcbiAgZGF0ZS5zZXRNb250aChtb250aCwgMClcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3REYXlPZlF1YXJ0ZXJcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgV2VlayBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgd2VlayBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgd2VlayBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKiBUaGUgcmVzdWx0IHdpbGwgYmUgaW4gdGhlIGxvY2FsIHRpbWV6b25lLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB0aGUgb2JqZWN0IHdpdGggb3B0aW9uc1xuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLndlZWtTdGFydHNPbj0wXSAtIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrICgwIC0gU3VuZGF5KVxuICogQHJldHVybnMge0RhdGV9IHRoZSBsYXN0IGRheSBvZiBhIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIGxhc3QgZGF5IG9mIGEgd2VlayBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBsYXN0RGF5T2ZXZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFNhdCBTZXAgMDYgMjAxNCAwMDowMDowMFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0aGUgd2VlayBzdGFydHMgb24gTW9uZGF5LCB0aGUgbGFzdCBkYXkgb2YgdGhlIHdlZWsgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gbGFzdERheU9mV2VlayhuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApLCB7d2Vla1N0YXJ0c09uOiAxfSlcbiAqIC8vPT4gU3VuIFNlcCAwNyAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGxhc3REYXlPZldlZWsgKGRpcnR5RGF0ZSwgZGlydHlPcHRpb25zKSB7XG4gIHZhciB3ZWVrU3RhcnRzT24gPSBkaXJ0eU9wdGlvbnMgPyAoTnVtYmVyKGRpcnR5T3B0aW9ucy53ZWVrU3RhcnRzT24pIHx8IDApIDogMFxuXG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKVxuICB2YXIgZGlmZiA9IChkYXkgPCB3ZWVrU3RhcnRzT24gPyAtNyA6IDApICsgNiAtIChkYXkgLSB3ZWVrU3RhcnRzT24pXG5cbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBkaWZmKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3REYXlPZldlZWtcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgeWVhciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIGxhc3QgZGF5IG9mIGEgeWVhciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKiBUaGUgcmVzdWx0IHdpbGwgYmUgaW4gdGhlIGxvY2FsIHRpbWV6b25lLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbGFzdCBkYXkgb2YgYSB5ZWFyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBsYXN0IGRheSBvZiBhIHllYXIgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gbGFzdERheU9mWWVhcihuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDAwKSlcbiAqIC8vPT4gV2VkIERlYyAzMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIGxhc3REYXlPZlllYXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKClcbiAgZGF0ZS5zZXRGdWxsWWVhcih5ZWFyICsgMSwgMCwgMClcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3REYXlPZlllYXJcbiIsInZhciBjb21tb25Gb3JtYXR0ZXJLZXlzID0gW1xuICAnTScsICdNTScsICdRJywgJ0QnLCAnREQnLCAnREREJywgJ0REREQnLCAnZCcsXG4gICdFJywgJ1cnLCAnV1cnLCAnWVknLCAnWVlZWScsICdHRycsICdHR0dHJyxcbiAgJ0gnLCAnSEgnLCAnaCcsICdoaCcsICdtJywgJ21tJyxcbiAgJ3MnLCAnc3MnLCAnUycsICdTUycsICdTU1MnLFxuICAnWicsICdaWicsICdYJywgJ3gnXG5dXG5cbmZ1bmN0aW9uIGJ1aWxkRm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cCAoZm9ybWF0dGVycykge1xuICB2YXIgZm9ybWF0dGVyS2V5cyA9IFtdXG4gIGZvciAodmFyIGtleSBpbiBmb3JtYXR0ZXJzKSB7XG4gICAgaWYgKGZvcm1hdHRlcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgZm9ybWF0dGVyS2V5cy5wdXNoKGtleSlcbiAgICB9XG4gIH1cblxuICB2YXIgZm9ybWF0dGluZ1Rva2VucyA9IGNvbW1vbkZvcm1hdHRlcktleXNcbiAgICAuY29uY2F0KGZvcm1hdHRlcktleXMpXG4gICAgLnNvcnQoKVxuICAgIC5yZXZlcnNlKClcbiAgdmFyIGZvcm1hdHRpbmdUb2tlbnNSZWdFeHAgPSBuZXcgUmVnRXhwKFxuICAgICcoXFxcXFtbXlxcXFxbXSpcXFxcXSl8KFxcXFxcXFxcKT8nICsgJygnICsgZm9ybWF0dGluZ1Rva2Vucy5qb2luKCd8JykgKyAnfC4pJywgJ2cnXG4gIClcblxuICByZXR1cm4gZm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ1aWxkRm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cFxuIiwiZnVuY3Rpb24gYnVpbGREaXN0YW5jZUluV29yZHNMb2NhbGUgKCkge1xuICB2YXIgZGlzdGFuY2VJbldvcmRzTG9jYWxlID0ge1xuICAgIGxlc3NUaGFuWFNlY29uZHM6IHtcbiAgICAgIG9uZTogJ2xlc3MgdGhhbiBhIHNlY29uZCcsXG4gICAgICBvdGhlcjogJ2xlc3MgdGhhbiB7e2NvdW50fX0gc2Vjb25kcydcbiAgICB9LFxuXG4gICAgeFNlY29uZHM6IHtcbiAgICAgIG9uZTogJzEgc2Vjb25kJyxcbiAgICAgIG90aGVyOiAne3tjb3VudH19IHNlY29uZHMnXG4gICAgfSxcblxuICAgIGhhbGZBTWludXRlOiAnaGFsZiBhIG1pbnV0ZScsXG5cbiAgICBsZXNzVGhhblhNaW51dGVzOiB7XG4gICAgICBvbmU6ICdsZXNzIHRoYW4gYSBtaW51dGUnLFxuICAgICAgb3RoZXI6ICdsZXNzIHRoYW4ge3tjb3VudH19IG1pbnV0ZXMnXG4gICAgfSxcblxuICAgIHhNaW51dGVzOiB7XG4gICAgICBvbmU6ICcxIG1pbnV0ZScsXG4gICAgICBvdGhlcjogJ3t7Y291bnR9fSBtaW51dGVzJ1xuICAgIH0sXG5cbiAgICBhYm91dFhIb3Vyczoge1xuICAgICAgb25lOiAnYWJvdXQgMSBob3VyJyxcbiAgICAgIG90aGVyOiAnYWJvdXQge3tjb3VudH19IGhvdXJzJ1xuICAgIH0sXG5cbiAgICB4SG91cnM6IHtcbiAgICAgIG9uZTogJzEgaG91cicsXG4gICAgICBvdGhlcjogJ3t7Y291bnR9fSBob3VycydcbiAgICB9LFxuXG4gICAgeERheXM6IHtcbiAgICAgIG9uZTogJzEgZGF5JyxcbiAgICAgIG90aGVyOiAne3tjb3VudH19IGRheXMnXG4gICAgfSxcblxuICAgIGFib3V0WE1vbnRoczoge1xuICAgICAgb25lOiAnYWJvdXQgMSBtb250aCcsXG4gICAgICBvdGhlcjogJ2Fib3V0IHt7Y291bnR9fSBtb250aHMnXG4gICAgfSxcblxuICAgIHhNb250aHM6IHtcbiAgICAgIG9uZTogJzEgbW9udGgnLFxuICAgICAgb3RoZXI6ICd7e2NvdW50fX0gbW9udGhzJ1xuICAgIH0sXG5cbiAgICBhYm91dFhZZWFyczoge1xuICAgICAgb25lOiAnYWJvdXQgMSB5ZWFyJyxcbiAgICAgIG90aGVyOiAnYWJvdXQge3tjb3VudH19IHllYXJzJ1xuICAgIH0sXG5cbiAgICB4WWVhcnM6IHtcbiAgICAgIG9uZTogJzEgeWVhcicsXG4gICAgICBvdGhlcjogJ3t7Y291bnR9fSB5ZWFycydcbiAgICB9LFxuXG4gICAgb3ZlclhZZWFyczoge1xuICAgICAgb25lOiAnb3ZlciAxIHllYXInLFxuICAgICAgb3RoZXI6ICdvdmVyIHt7Y291bnR9fSB5ZWFycydcbiAgICB9LFxuXG4gICAgYWxtb3N0WFllYXJzOiB7XG4gICAgICBvbmU6ICdhbG1vc3QgMSB5ZWFyJyxcbiAgICAgIG90aGVyOiAnYWxtb3N0IHt7Y291bnR9fSB5ZWFycydcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBsb2NhbGl6ZSAodG9rZW4sIGNvdW50LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cblxuICAgIHZhciByZXN1bHRcbiAgICBpZiAodHlwZW9mIGRpc3RhbmNlSW5Xb3Jkc0xvY2FsZVt0b2tlbl0gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXN1bHQgPSBkaXN0YW5jZUluV29yZHNMb2NhbGVbdG9rZW5dXG4gICAgfSBlbHNlIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzTG9jYWxlW3Rva2VuXS5vbmVcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ID0gZGlzdGFuY2VJbldvcmRzTG9jYWxlW3Rva2VuXS5vdGhlci5yZXBsYWNlKCd7e2NvdW50fX0nLCBjb3VudClcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5hZGRTdWZmaXgpIHtcbiAgICAgIGlmIChvcHRpb25zLmNvbXBhcmlzb24gPiAwKSB7XG4gICAgICAgIHJldHVybiAnaW4gJyArIHJlc3VsdFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCArICcgYWdvJ1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbG9jYWxpemU6IGxvY2FsaXplXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWlsZERpc3RhbmNlSW5Xb3Jkc0xvY2FsZVxuIiwidmFyIGJ1aWxkRm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cCA9IHJlcXVpcmUoJy4uLy4uL19saWIvYnVpbGRfZm9ybWF0dGluZ190b2tlbnNfcmVnX2V4cC9pbmRleC5qcycpXG5cbmZ1bmN0aW9uIGJ1aWxkRm9ybWF0TG9jYWxlICgpIHtcbiAgLy8gTm90ZTogaW4gRW5nbGlzaCwgdGhlIG5hbWVzIG9mIGRheXMgb2YgdGhlIHdlZWsgYW5kIG1vbnRocyBhcmUgY2FwaXRhbGl6ZWQuXG4gIC8vIElmIHlvdSBhcmUgbWFraW5nIGEgbmV3IGxvY2FsZSBiYXNlZCBvbiB0aGlzIG9uZSwgY2hlY2sgaWYgdGhlIHNhbWUgaXMgdHJ1ZSBmb3IgdGhlIGxhbmd1YWdlIHlvdSdyZSB3b3JraW5nIG9uLlxuICAvLyBHZW5lcmFsbHksIGZvcm1hdHRlZCBkYXRlcyBzaG91bGQgbG9vayBsaWtlIHRoZXkgYXJlIGluIHRoZSBtaWRkbGUgb2YgYSBzZW50ZW5jZSxcbiAgLy8gZS5nLiBpbiBTcGFuaXNoIGxhbmd1YWdlIHRoZSB3ZWVrZGF5cyBhbmQgbW9udGhzIHNob3VsZCBiZSBpbiB0aGUgbG93ZXJjYXNlLlxuICB2YXIgbW9udGhzM2NoYXIgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ11cbiAgdmFyIG1vbnRoc0Z1bGwgPSBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXVxuICB2YXIgd2Vla2RheXMyY2hhciA9IFsnU3UnLCAnTW8nLCAnVHUnLCAnV2UnLCAnVGgnLCAnRnInLCAnU2EnXVxuICB2YXIgd2Vla2RheXMzY2hhciA9IFsnU3VuJywgJ01vbicsICdUdWUnLCAnV2VkJywgJ1RodScsICdGcmknLCAnU2F0J11cbiAgdmFyIHdlZWtkYXlzRnVsbCA9IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXVxuICB2YXIgbWVyaWRpZW1VcHBlcmNhc2UgPSBbJ0FNJywgJ1BNJ11cbiAgdmFyIG1lcmlkaWVtTG93ZXJjYXNlID0gWydhbScsICdwbSddXG4gIHZhciBtZXJpZGllbUZ1bGwgPSBbJ2EubS4nLCAncC5tLiddXG5cbiAgdmFyIGZvcm1hdHRlcnMgPSB7XG4gICAgLy8gTW9udGg6IEphbiwgRmViLCAuLi4sIERlY1xuICAgICdNTU0nOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgICAgcmV0dXJuIG1vbnRoczNjaGFyW2RhdGUuZ2V0TW9udGgoKV1cbiAgICB9LFxuXG4gICAgLy8gTW9udGg6IEphbnVhcnksIEZlYnJ1YXJ5LCAuLi4sIERlY2VtYmVyXG4gICAgJ01NTU0nOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgICAgcmV0dXJuIG1vbnRoc0Z1bGxbZGF0ZS5nZXRNb250aCgpXVxuICAgIH0sXG5cbiAgICAvLyBEYXkgb2Ygd2VlazogU3UsIE1vLCAuLi4sIFNhXG4gICAgJ2RkJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgIHJldHVybiB3ZWVrZGF5czJjaGFyW2RhdGUuZ2V0RGF5KCldXG4gICAgfSxcblxuICAgIC8vIERheSBvZiB3ZWVrOiBTdW4sIE1vbiwgLi4uLCBTYXRcbiAgICAnZGRkJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgIHJldHVybiB3ZWVrZGF5czNjaGFyW2RhdGUuZ2V0RGF5KCldXG4gICAgfSxcblxuICAgIC8vIERheSBvZiB3ZWVrOiBTdW5kYXksIE1vbmRheSwgLi4uLCBTYXR1cmRheVxuICAgICdkZGRkJzogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgIHJldHVybiB3ZWVrZGF5c0Z1bGxbZGF0ZS5nZXREYXkoKV1cbiAgICB9LFxuXG4gICAgLy8gQU0sIFBNXG4gICAgJ0EnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgICAgcmV0dXJuIChkYXRlLmdldEhvdXJzKCkgLyAxMikgPj0gMSA/IG1lcmlkaWVtVXBwZXJjYXNlWzFdIDogbWVyaWRpZW1VcHBlcmNhc2VbMF1cbiAgICB9LFxuXG4gICAgLy8gYW0sIHBtXG4gICAgJ2EnOiBmdW5jdGlvbiAoZGF0ZSkge1xuICAgICAgcmV0dXJuIChkYXRlLmdldEhvdXJzKCkgLyAxMikgPj0gMSA/IG1lcmlkaWVtTG93ZXJjYXNlWzFdIDogbWVyaWRpZW1Mb3dlcmNhc2VbMF1cbiAgICB9LFxuXG4gICAgLy8gYS5tLiwgcC5tLlxuICAgICdhYSc6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgICByZXR1cm4gKGRhdGUuZ2V0SG91cnMoKSAvIDEyKSA+PSAxID8gbWVyaWRpZW1GdWxsWzFdIDogbWVyaWRpZW1GdWxsWzBdXG4gICAgfVxuICB9XG5cbiAgLy8gR2VuZXJhdGUgb3JkaW5hbCB2ZXJzaW9uIG9mIGZvcm1hdHRlcnM6IE0gLT4gTW8sIEQgLT4gRG8sIGV0Yy5cbiAgdmFyIG9yZGluYWxGb3JtYXR0ZXJzID0gWydNJywgJ0QnLCAnREREJywgJ2QnLCAnUScsICdXJ11cbiAgb3JkaW5hbEZvcm1hdHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZm9ybWF0dGVyVG9rZW4pIHtcbiAgICBmb3JtYXR0ZXJzW2Zvcm1hdHRlclRva2VuICsgJ28nXSA9IGZ1bmN0aW9uIChkYXRlLCBmb3JtYXR0ZXJzKSB7XG4gICAgICByZXR1cm4gb3JkaW5hbChmb3JtYXR0ZXJzW2Zvcm1hdHRlclRva2VuXShkYXRlKSlcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBmb3JtYXR0ZXJzOiBmb3JtYXR0ZXJzLFxuICAgIGZvcm1hdHRpbmdUb2tlbnNSZWdFeHA6IGJ1aWxkRm9ybWF0dGluZ1Rva2Vuc1JlZ0V4cChmb3JtYXR0ZXJzKVxuICB9XG59XG5cbmZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICB2YXIgcmVtMTAwID0gbnVtYmVyICUgMTAwXG4gIGlmIChyZW0xMDAgPiAyMCB8fCByZW0xMDAgPCAxMCkge1xuICAgIHN3aXRjaCAocmVtMTAwICUgMTApIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIG51bWJlciArICdzdCdcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIG51bWJlciArICduZCdcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIG51bWJlciArICdyZCdcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bWJlciArICd0aCdcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWlsZEZvcm1hdExvY2FsZVxuIiwidmFyIGJ1aWxkRGlzdGFuY2VJbldvcmRzTG9jYWxlID0gcmVxdWlyZSgnLi9idWlsZF9kaXN0YW5jZV9pbl93b3Jkc19sb2NhbGUvaW5kZXguanMnKVxudmFyIGJ1aWxkRm9ybWF0TG9jYWxlID0gcmVxdWlyZSgnLi9idWlsZF9mb3JtYXRfbG9jYWxlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTG9jYWxlc1xuICogQHN1bW1hcnkgRW5nbGlzaCBsb2NhbGUuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkaXN0YW5jZUluV29yZHM6IGJ1aWxkRGlzdGFuY2VJbldvcmRzTG9jYWxlKCksXG4gIGZvcm1hdDogYnVpbGRGb3JtYXRMb2NhbGUoKVxufVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBDb21tb24gSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBsYXRlc3Qgb2YgdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBsYXRlc3Qgb2YgdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7Li4uKERhdGV8U3RyaW5nfE51bWJlcil9IGRhdGVzIC0gdGhlIGRhdGVzIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbGF0ZXN0IG9mIHRoZSBkYXRlc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBXaGljaCBvZiB0aGVzZSBkYXRlcyBpcyB0aGUgbGF0ZXN0P1xuICogdmFyIHJlc3VsdCA9IG1heChcbiAqICAgbmV3IERhdGUoMTk4OSwgNiwgMTApLFxuICogICBuZXcgRGF0ZSgxOTg3LCAxLCAxMSksXG4gKiAgIG5ldyBEYXRlKDE5OTUsIDYsIDIpLFxuICogICBuZXcgRGF0ZSgxOTkwLCAwLCAxKVxuICogKVxuICogLy89PiBTdW4gSnVsIDAyIDE5OTUgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gbWF4ICgpIHtcbiAgdmFyIGRpcnR5RGF0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gIHZhciBkYXRlcyA9IGRpcnR5RGF0ZXMubWFwKGZ1bmN0aW9uIChkaXJ0eURhdGUpIHtcbiAgICByZXR1cm4gcGFyc2UoZGlydHlEYXRlKVxuICB9KVxuICB2YXIgbGF0ZXN0VGltZXN0YW1wID0gTWF0aC5tYXguYXBwbHkobnVsbCwgZGF0ZXMpXG4gIHJldHVybiBuZXcgRGF0ZShsYXRlc3RUaW1lc3RhbXApXG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWF4XG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIGVhcmxpZXN0IG9mIHRoZSBnaXZlbiBkYXRlcy5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgZWFybGllc3Qgb2YgdGhlIGdpdmVuIGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7Li4uKERhdGV8U3RyaW5nfE51bWJlcil9IGRhdGVzIC0gdGhlIGRhdGVzIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgZWFybGllc3Qgb2YgdGhlIGRhdGVzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdoaWNoIG9mIHRoZXNlIGRhdGVzIGlzIHRoZSBlYXJsaWVzdD9cbiAqIHZhciByZXN1bHQgPSBtaW4oXG4gKiAgIG5ldyBEYXRlKDE5ODksIDYsIDEwKSxcbiAqICAgbmV3IERhdGUoMTk4NywgMSwgMTEpLFxuICogICBuZXcgRGF0ZSgxOTk1LCA2LCAyKSxcbiAqICAgbmV3IERhdGUoMTk5MCwgMCwgMSlcbiAqIClcbiAqIC8vPT4gV2VkIEZlYiAxMSAxOTg3IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIG1pbiAoKSB7XG4gIHZhciBkaXJ0eURhdGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVxuICB2YXIgZGF0ZXMgPSBkaXJ0eURhdGVzLm1hcChmdW5jdGlvbiAoZGlydHlEYXRlKSB7XG4gICAgcmV0dXJuIHBhcnNlKGRpcnR5RGF0ZSlcbiAgfSlcbiAgdmFyIGVhcmxpZXN0VGltZXN0YW1wID0gTWF0aC5taW4uYXBwbHkobnVsbCwgZGF0ZXMpXG4gIHJldHVybiBuZXcgRGF0ZShlYXJsaWVzdFRpbWVzdGFtcClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtaW5cbiIsInZhciBpc0RhdGUgPSByZXF1aXJlKCcuLi9pc19kYXRlL2luZGV4LmpzJylcblxudmFyIE1JTExJU0VDT05EU19JTl9IT1VSID0gMzYwMDAwMFxudmFyIE1JTExJU0VDT05EU19JTl9NSU5VVEUgPSA2MDAwMFxudmFyIERFRkFVTFRfQURESVRJT05BTF9ESUdJVFMgPSAyXG5cbnZhciBwYXJzZVRva2VuRGF0ZVRpbWVEZWxpbWV0ZXIgPSAvW1QgXS9cbnZhciBwYXJzZVRva2VuUGxhaW5UaW1lID0gLzovXG5cbi8vIHllYXIgdG9rZW5zXG52YXIgcGFyc2VUb2tlbllZID0gL14oXFxkezJ9KSQvXG52YXIgcGFyc2VUb2tlbnNZWVkgPSBbXG4gIC9eKFsrLV1cXGR7Mn0pJC8sIC8vIDAgYWRkaXRpb25hbCBkaWdpdHNcbiAgL14oWystXVxcZHszfSkkLywgLy8gMSBhZGRpdGlvbmFsIGRpZ2l0XG4gIC9eKFsrLV1cXGR7NH0pJC8gLy8gMiBhZGRpdGlvbmFsIGRpZ2l0c1xuXVxuXG52YXIgcGFyc2VUb2tlbllZWVkgPSAvXihcXGR7NH0pL1xudmFyIHBhcnNlVG9rZW5zWVlZWVkgPSBbXG4gIC9eKFsrLV1cXGR7NH0pLywgLy8gMCBhZGRpdGlvbmFsIGRpZ2l0c1xuICAvXihbKy1dXFxkezV9KS8sIC8vIDEgYWRkaXRpb25hbCBkaWdpdFxuICAvXihbKy1dXFxkezZ9KS8gLy8gMiBhZGRpdGlvbmFsIGRpZ2l0c1xuXVxuXG4vLyBkYXRlIHRva2Vuc1xudmFyIHBhcnNlVG9rZW5NTSA9IC9eLShcXGR7Mn0pJC9cbnZhciBwYXJzZVRva2VuREREID0gL14tPyhcXGR7M30pJC9cbnZhciBwYXJzZVRva2VuTU1ERCA9IC9eLT8oXFxkezJ9KS0/KFxcZHsyfSkkL1xudmFyIHBhcnNlVG9rZW5Xd3cgPSAvXi0/VyhcXGR7Mn0pJC9cbnZhciBwYXJzZVRva2VuV3d3RCA9IC9eLT9XKFxcZHsyfSktPyhcXGR7MX0pJC9cblxuLy8gdGltZSB0b2tlbnNcbnZhciBwYXJzZVRva2VuSEggPSAvXihcXGR7Mn0oWy4sXVxcZCopPykkL1xudmFyIHBhcnNlVG9rZW5ISE1NID0gL14oXFxkezJ9KTo/KFxcZHsyfShbLixdXFxkKik/KSQvXG52YXIgcGFyc2VUb2tlbkhITU1TUyA9IC9eKFxcZHsyfSk6PyhcXGR7Mn0pOj8oXFxkezJ9KFsuLF1cXGQqKT8pJC9cblxuLy8gdGltZXpvbmUgdG9rZW5zXG52YXIgcGFyc2VUb2tlblRpbWV6b25lID0gLyhbWistXS4qKSQvXG52YXIgcGFyc2VUb2tlblRpbWV6b25lWiA9IC9eKFopJC9cbnZhciBwYXJzZVRva2VuVGltZXpvbmVISCA9IC9eKFsrLV0pKFxcZHsyfSkkL1xudmFyIHBhcnNlVG9rZW5UaW1lem9uZUhITU0gPSAvXihbKy1dKShcXGR7Mn0pOj8oXFxkezJ9KSQvXG5cbi8qKlxuICogQGNhdGVnb3J5IENvbW1vbiBIZWxwZXJzXG4gKiBAc3VtbWFyeSBDb252ZXJ0IHRoZSBnaXZlbiBhcmd1bWVudCB0byBhbiBpbnN0YW5jZSBvZiBEYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogQ29udmVydCB0aGUgZ2l2ZW4gYXJndW1lbnQgdG8gYW4gaW5zdGFuY2Ugb2YgRGF0ZS5cbiAqXG4gKiBJZiB0aGUgYXJndW1lbnQgaXMgYW4gaW5zdGFuY2Ugb2YgRGF0ZSwgdGhlIGZ1bmN0aW9uIHJldHVybnMgaXRzIGNsb25lLlxuICpcbiAqIElmIHRoZSBhcmd1bWVudCBpcyBhIG51bWJlciwgaXQgaXMgdHJlYXRlZCBhcyBhIHRpbWVzdGFtcC5cbiAqXG4gKiBJZiBhbiBhcmd1bWVudCBpcyBhIHN0cmluZywgdGhlIGZ1bmN0aW9uIHRyaWVzIHRvIHBhcnNlIGl0LlxuICogRnVuY3Rpb24gYWNjZXB0cyBjb21wbGV0ZSBJU08gODYwMSBmb3JtYXRzIGFzIHdlbGwgYXMgcGFydGlhbCBpbXBsZW1lbnRhdGlvbnMuXG4gKiBJU08gODYwMTogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMVxuICpcbiAqIElmIGFsbCBhYm92ZSBmYWlscywgdGhlIGZ1bmN0aW9uIHBhc3NlcyB0aGUgZ2l2ZW4gYXJndW1lbnQgdG8gRGF0ZSBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gYXJndW1lbnQgLSB0aGUgdmFsdWUgdG8gY29udmVydFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIHRoZSBvYmplY3Qgd2l0aCBvcHRpb25zXG4gKiBAcGFyYW0gezAgfCAxIHwgMn0gW29wdGlvbnMuYWRkaXRpb25hbERpZ2l0cz0yXSAtIHRoZSBhZGRpdGlvbmFsIG51bWJlciBvZiBkaWdpdHMgaW4gdGhlIGV4dGVuZGVkIHllYXIgZm9ybWF0XG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIHBhcnNlZCBkYXRlIGluIHRoZSBsb2NhbCB0aW1lIHpvbmVcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ29udmVydCBzdHJpbmcgJzIwMTQtMDItMTFUMTE6MzA6MzAnIHRvIGRhdGU6XG4gKiB2YXIgcmVzdWx0ID0gcGFyc2UoJzIwMTQtMDItMTFUMTE6MzA6MzAnKVxuICogLy89PiBUdWUgRmViIDExIDIwMTQgMTE6MzA6MzBcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gUGFyc2Ugc3RyaW5nICcrMDIwMTQxMDEnLFxuICogLy8gaWYgdGhlIGFkZGl0aW9uYWwgbnVtYmVyIG9mIGRpZ2l0cyBpbiB0aGUgZXh0ZW5kZWQgeWVhciBmb3JtYXQgaXMgMTpcbiAqIHZhciByZXN1bHQgPSBwYXJzZSgnKzAyMDE0MTAxJywge2FkZGl0aW9uYWxEaWdpdHM6IDF9KVxuICogLy89PiBGcmkgQXByIDExIDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gcGFyc2UgKGFyZ3VtZW50LCBkaXJ0eU9wdGlvbnMpIHtcbiAgaWYgKGlzRGF0ZShhcmd1bWVudCkpIHtcbiAgICAvLyBQcmV2ZW50IHRoZSBkYXRlIHRvIGxvc2UgdGhlIG1pbGxpc2Vjb25kcyB3aGVuIHBhc3NlZCB0byBuZXcgRGF0ZSgpIGluIElFMTBcbiAgICByZXR1cm4gbmV3IERhdGUoYXJndW1lbnQuZ2V0VGltZSgpKVxuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmd1bWVudCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoYXJndW1lbnQpXG4gIH1cblxuICB2YXIgb3B0aW9ucyA9IGRpcnR5T3B0aW9ucyB8fCB7fVxuICB2YXIgYWRkaXRpb25hbERpZ2l0cyA9IG9wdGlvbnMuYWRkaXRpb25hbERpZ2l0c1xuICBpZiAoYWRkaXRpb25hbERpZ2l0cyA9PSBudWxsKSB7XG4gICAgYWRkaXRpb25hbERpZ2l0cyA9IERFRkFVTFRfQURESVRJT05BTF9ESUdJVFNcbiAgfSBlbHNlIHtcbiAgICBhZGRpdGlvbmFsRGlnaXRzID0gTnVtYmVyKGFkZGl0aW9uYWxEaWdpdHMpXG4gIH1cblxuICB2YXIgZGF0ZVN0cmluZ3MgPSBzcGxpdERhdGVTdHJpbmcoYXJndW1lbnQpXG5cbiAgdmFyIHBhcnNlWWVhclJlc3VsdCA9IHBhcnNlWWVhcihkYXRlU3RyaW5ncy5kYXRlLCBhZGRpdGlvbmFsRGlnaXRzKVxuICB2YXIgeWVhciA9IHBhcnNlWWVhclJlc3VsdC55ZWFyXG4gIHZhciByZXN0RGF0ZVN0cmluZyA9IHBhcnNlWWVhclJlc3VsdC5yZXN0RGF0ZVN0cmluZ1xuXG4gIHZhciBkYXRlID0gcGFyc2VEYXRlKHJlc3REYXRlU3RyaW5nLCB5ZWFyKVxuXG4gIGlmIChkYXRlKSB7XG4gICAgdmFyIHRpbWVzdGFtcCA9IGRhdGUuZ2V0VGltZSgpXG4gICAgdmFyIHRpbWUgPSAwXG4gICAgdmFyIG9mZnNldFxuXG4gICAgaWYgKGRhdGVTdHJpbmdzLnRpbWUpIHtcbiAgICAgIHRpbWUgPSBwYXJzZVRpbWUoZGF0ZVN0cmluZ3MudGltZSlcbiAgICB9XG5cbiAgICBpZiAoZGF0ZVN0cmluZ3MudGltZXpvbmUpIHtcbiAgICAgIG9mZnNldCA9IHBhcnNlVGltZXpvbmUoZGF0ZVN0cmluZ3MudGltZXpvbmUpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGdldCBvZmZzZXQgYWNjdXJhdGUgdG8gaG91ciBpbiB0aW1lem9uZXMgdGhhdCBjaGFuZ2Ugb2Zmc2V0XG4gICAgICBvZmZzZXQgPSBuZXcgRGF0ZSh0aW1lc3RhbXAgKyB0aW1lKS5nZXRUaW1lem9uZU9mZnNldCgpXG4gICAgICBvZmZzZXQgPSBuZXcgRGF0ZSh0aW1lc3RhbXAgKyB0aW1lICsgb2Zmc2V0ICogTUlMTElTRUNPTkRTX0lOX01JTlVURSkuZ2V0VGltZXpvbmVPZmZzZXQoKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGF0ZSh0aW1lc3RhbXAgKyB0aW1lICsgb2Zmc2V0ICogTUlMTElTRUNPTkRTX0lOX01JTlVURSlcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IERhdGUoYXJndW1lbnQpXG4gIH1cbn1cblxuZnVuY3Rpb24gc3BsaXREYXRlU3RyaW5nIChkYXRlU3RyaW5nKSB7XG4gIHZhciBkYXRlU3RyaW5ncyA9IHt9XG4gIHZhciBhcnJheSA9IGRhdGVTdHJpbmcuc3BsaXQocGFyc2VUb2tlbkRhdGVUaW1lRGVsaW1ldGVyKVxuICB2YXIgdGltZVN0cmluZ1xuXG4gIGlmIChwYXJzZVRva2VuUGxhaW5UaW1lLnRlc3QoYXJyYXlbMF0pKSB7XG4gICAgZGF0ZVN0cmluZ3MuZGF0ZSA9IG51bGxcbiAgICB0aW1lU3RyaW5nID0gYXJyYXlbMF1cbiAgfSBlbHNlIHtcbiAgICBkYXRlU3RyaW5ncy5kYXRlID0gYXJyYXlbMF1cbiAgICB0aW1lU3RyaW5nID0gYXJyYXlbMV1cbiAgfVxuXG4gIGlmICh0aW1lU3RyaW5nKSB7XG4gICAgdmFyIHRva2VuID0gcGFyc2VUb2tlblRpbWV6b25lLmV4ZWModGltZVN0cmluZylcbiAgICBpZiAodG9rZW4pIHtcbiAgICAgIGRhdGVTdHJpbmdzLnRpbWUgPSB0aW1lU3RyaW5nLnJlcGxhY2UodG9rZW5bMV0sICcnKVxuICAgICAgZGF0ZVN0cmluZ3MudGltZXpvbmUgPSB0b2tlblsxXVxuICAgIH0gZWxzZSB7XG4gICAgICBkYXRlU3RyaW5ncy50aW1lID0gdGltZVN0cmluZ1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkYXRlU3RyaW5nc1xufVxuXG5mdW5jdGlvbiBwYXJzZVllYXIgKGRhdGVTdHJpbmcsIGFkZGl0aW9uYWxEaWdpdHMpIHtcbiAgdmFyIHBhcnNlVG9rZW5ZWVkgPSBwYXJzZVRva2Vuc1lZWVthZGRpdGlvbmFsRGlnaXRzXVxuICB2YXIgcGFyc2VUb2tlbllZWVlZID0gcGFyc2VUb2tlbnNZWVlZWVthZGRpdGlvbmFsRGlnaXRzXVxuXG4gIHZhciB0b2tlblxuXG4gIC8vIFlZWVkgb3IgwrFZWVlZWVxuICB0b2tlbiA9IHBhcnNlVG9rZW5ZWVlZLmV4ZWMoZGF0ZVN0cmluZykgfHwgcGFyc2VUb2tlbllZWVlZLmV4ZWMoZGF0ZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgdmFyIHllYXJTdHJpbmcgPSB0b2tlblsxXVxuICAgIHJldHVybiB7XG4gICAgICB5ZWFyOiBwYXJzZUludCh5ZWFyU3RyaW5nLCAxMCksXG4gICAgICByZXN0RGF0ZVN0cmluZzogZGF0ZVN0cmluZy5zbGljZSh5ZWFyU3RyaW5nLmxlbmd0aClcbiAgICB9XG4gIH1cblxuICAvLyBZWSBvciDCsVlZWVxuICB0b2tlbiA9IHBhcnNlVG9rZW5ZWS5leGVjKGRhdGVTdHJpbmcpIHx8IHBhcnNlVG9rZW5ZWVkuZXhlYyhkYXRlU3RyaW5nKVxuICBpZiAodG9rZW4pIHtcbiAgICB2YXIgY2VudHVyeVN0cmluZyA9IHRva2VuWzFdXG4gICAgcmV0dXJuIHtcbiAgICAgIHllYXI6IHBhcnNlSW50KGNlbnR1cnlTdHJpbmcsIDEwKSAqIDEwMCxcbiAgICAgIHJlc3REYXRlU3RyaW5nOiBkYXRlU3RyaW5nLnNsaWNlKGNlbnR1cnlTdHJpbmcubGVuZ3RoKVxuICAgIH1cbiAgfVxuXG4gIC8vIEludmFsaWQgSVNPLWZvcm1hdHRlZCB5ZWFyXG4gIHJldHVybiB7XG4gICAgeWVhcjogbnVsbFxuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlRGF0ZSAoZGF0ZVN0cmluZywgeWVhcikge1xuICAvLyBJbnZhbGlkIElTTy1mb3JtYXR0ZWQgeWVhclxuICBpZiAoeWVhciA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB2YXIgdG9rZW5cbiAgdmFyIGRhdGVcbiAgdmFyIG1vbnRoXG4gIHZhciB3ZWVrXG5cbiAgLy8gWVlZWVxuICBpZiAoZGF0ZVN0cmluZy5sZW5ndGggPT09IDApIHtcbiAgICBkYXRlID0gbmV3IERhdGUoMClcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHllYXIpXG4gICAgcmV0dXJuIGRhdGVcbiAgfVxuXG4gIC8vIFlZWVktTU1cbiAgdG9rZW4gPSBwYXJzZVRva2VuTU0uZXhlYyhkYXRlU3RyaW5nKVxuICBpZiAodG9rZW4pIHtcbiAgICBkYXRlID0gbmV3IERhdGUoMClcbiAgICBtb250aCA9IHBhcnNlSW50KHRva2VuWzFdLCAxMCkgLSAxXG4gICAgZGF0ZS5zZXRVVENGdWxsWWVhcih5ZWFyLCBtb250aClcbiAgICByZXR1cm4gZGF0ZVxuICB9XG5cbiAgLy8gWVlZWS1EREQgb3IgWVlZWURERFxuICB0b2tlbiA9IHBhcnNlVG9rZW5EREQuZXhlYyhkYXRlU3RyaW5nKVxuICBpZiAodG9rZW4pIHtcbiAgICBkYXRlID0gbmV3IERhdGUoMClcbiAgICB2YXIgZGF5T2ZZZWFyID0gcGFyc2VJbnQodG9rZW5bMV0sIDEwKVxuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoeWVhciwgMCwgZGF5T2ZZZWFyKVxuICAgIHJldHVybiBkYXRlXG4gIH1cblxuICAvLyBZWVlZLU1NLUREIG9yIFlZWVlNTUREXG4gIHRva2VuID0gcGFyc2VUb2tlbk1NREQuZXhlYyhkYXRlU3RyaW5nKVxuICBpZiAodG9rZW4pIHtcbiAgICBkYXRlID0gbmV3IERhdGUoMClcbiAgICBtb250aCA9IHBhcnNlSW50KHRva2VuWzFdLCAxMCkgLSAxXG4gICAgdmFyIGRheSA9IHBhcnNlSW50KHRva2VuWzJdLCAxMClcbiAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHllYXIsIG1vbnRoLCBkYXkpXG4gICAgcmV0dXJuIGRhdGVcbiAgfVxuXG4gIC8vIFlZWVktV3d3IG9yIFlZWVlXd3dcbiAgdG9rZW4gPSBwYXJzZVRva2VuV3d3LmV4ZWMoZGF0ZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgd2VlayA9IHBhcnNlSW50KHRva2VuWzFdLCAxMCkgLSAxXG4gICAgcmV0dXJuIGRheU9mSVNPWWVhcih5ZWFyLCB3ZWVrKVxuICB9XG5cbiAgLy8gWVlZWS1Xd3ctRCBvciBZWVlZV3d3RFxuICB0b2tlbiA9IHBhcnNlVG9rZW5Xd3dELmV4ZWMoZGF0ZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgd2VlayA9IHBhcnNlSW50KHRva2VuWzFdLCAxMCkgLSAxXG4gICAgdmFyIGRheU9mV2VlayA9IHBhcnNlSW50KHRva2VuWzJdLCAxMCkgLSAxXG4gICAgcmV0dXJuIGRheU9mSVNPWWVhcih5ZWFyLCB3ZWVrLCBkYXlPZldlZWspXG4gIH1cblxuICAvLyBJbnZhbGlkIElTTy1mb3JtYXR0ZWQgZGF0ZVxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBwYXJzZVRpbWUgKHRpbWVTdHJpbmcpIHtcbiAgdmFyIHRva2VuXG4gIHZhciBob3Vyc1xuICB2YXIgbWludXRlc1xuXG4gIC8vIGhoXG4gIHRva2VuID0gcGFyc2VUb2tlbkhILmV4ZWModGltZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgaG91cnMgPSBwYXJzZUZsb2F0KHRva2VuWzFdLnJlcGxhY2UoJywnLCAnLicpKVxuICAgIHJldHVybiAoaG91cnMgJSAyNCkgKiBNSUxMSVNFQ09ORFNfSU5fSE9VUlxuICB9XG5cbiAgLy8gaGg6bW0gb3IgaGhtbVxuICB0b2tlbiA9IHBhcnNlVG9rZW5ISE1NLmV4ZWModGltZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgaG91cnMgPSBwYXJzZUludCh0b2tlblsxXSwgMTApXG4gICAgbWludXRlcyA9IHBhcnNlRmxvYXQodG9rZW5bMl0ucmVwbGFjZSgnLCcsICcuJykpXG4gICAgcmV0dXJuIChob3VycyAlIDI0KSAqIE1JTExJU0VDT05EU19JTl9IT1VSICtcbiAgICAgIG1pbnV0ZXMgKiBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFXG4gIH1cblxuICAvLyBoaDptbTpzcyBvciBoaG1tc3NcbiAgdG9rZW4gPSBwYXJzZVRva2VuSEhNTVNTLmV4ZWModGltZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgaG91cnMgPSBwYXJzZUludCh0b2tlblsxXSwgMTApXG4gICAgbWludXRlcyA9IHBhcnNlSW50KHRva2VuWzJdLCAxMClcbiAgICB2YXIgc2Vjb25kcyA9IHBhcnNlRmxvYXQodG9rZW5bM10ucmVwbGFjZSgnLCcsICcuJykpXG4gICAgcmV0dXJuIChob3VycyAlIDI0KSAqIE1JTExJU0VDT05EU19JTl9IT1VSICtcbiAgICAgIG1pbnV0ZXMgKiBNSUxMSVNFQ09ORFNfSU5fTUlOVVRFICtcbiAgICAgIHNlY29uZHMgKiAxMDAwXG4gIH1cblxuICAvLyBJbnZhbGlkIElTTy1mb3JtYXR0ZWQgdGltZVxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBwYXJzZVRpbWV6b25lICh0aW1lem9uZVN0cmluZykge1xuICB2YXIgdG9rZW5cbiAgdmFyIGFic29sdXRlT2Zmc2V0XG5cbiAgLy8gWlxuICB0b2tlbiA9IHBhcnNlVG9rZW5UaW1lem9uZVouZXhlYyh0aW1lem9uZVN0cmluZylcbiAgaWYgKHRva2VuKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIC8vIMKxaGhcbiAgdG9rZW4gPSBwYXJzZVRva2VuVGltZXpvbmVISC5leGVjKHRpbWV6b25lU3RyaW5nKVxuICBpZiAodG9rZW4pIHtcbiAgICBhYnNvbHV0ZU9mZnNldCA9IHBhcnNlSW50KHRva2VuWzJdLCAxMCkgKiA2MFxuICAgIHJldHVybiAodG9rZW5bMV0gPT09ICcrJykgPyAtYWJzb2x1dGVPZmZzZXQgOiBhYnNvbHV0ZU9mZnNldFxuICB9XG5cbiAgLy8gwrFoaDptbSBvciDCsWhobW1cbiAgdG9rZW4gPSBwYXJzZVRva2VuVGltZXpvbmVISE1NLmV4ZWModGltZXpvbmVTdHJpbmcpXG4gIGlmICh0b2tlbikge1xuICAgIGFic29sdXRlT2Zmc2V0ID0gcGFyc2VJbnQodG9rZW5bMl0sIDEwKSAqIDYwICsgcGFyc2VJbnQodG9rZW5bM10sIDEwKVxuICAgIHJldHVybiAodG9rZW5bMV0gPT09ICcrJykgPyAtYWJzb2x1dGVPZmZzZXQgOiBhYnNvbHV0ZU9mZnNldFxuICB9XG5cbiAgcmV0dXJuIDBcbn1cblxuZnVuY3Rpb24gZGF5T2ZJU09ZZWFyIChpc29ZZWFyLCB3ZWVrLCBkYXkpIHtcbiAgd2VlayA9IHdlZWsgfHwgMFxuICBkYXkgPSBkYXkgfHwgMFxuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKDApXG4gIGRhdGUuc2V0VVRDRnVsbFllYXIoaXNvWWVhciwgMCwgNClcbiAgdmFyIGZvdXJ0aE9mSmFudWFyeURheSA9IGRhdGUuZ2V0VVRDRGF5KCkgfHwgN1xuICB2YXIgZGlmZiA9IHdlZWsgKiA3ICsgZGF5ICsgMSAtIGZvdXJ0aE9mSmFudWFyeURheVxuICBkYXRlLnNldFVUQ0RhdGUoZGF0ZS5nZXRVVENEYXRlKCkgKyBkaWZmKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBTZXQgdGhlIGRheSBvZiB0aGUgbW9udGggdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTZXQgdGhlIGRheSBvZiB0aGUgbW9udGggdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gZGF5T2ZNb250aCAtIHRoZSBkYXkgb2YgdGhlIG1vbnRoIG9mIHRoZSBuZXcgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBkYXkgb2YgdGhlIG1vbnRoIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgdGhlIDMwdGggZGF5IG9mIHRoZSBtb250aCB0byAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHNldERhdGUobmV3IERhdGUoMjAxNCwgOCwgMSksIDMwKVxuICogLy89PiBUdWUgU2VwIDMwIDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc2V0RGF0ZSAoZGlydHlEYXRlLCBkaXJ0eURheU9mTW9udGgpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBkYXlPZk1vbnRoID0gTnVtYmVyKGRpcnR5RGF5T2ZNb250aClcbiAgZGF0ZS5zZXREYXRlKGRheU9mTW9udGgpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0RGF0ZVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIGFkZERheXMgPSByZXF1aXJlKCcuLi9hZGRfZGF5cy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBkYXkgb2YgdGhlIHdlZWsgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTZXQgdGhlIGRheSBvZiB0aGUgd2VlayB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBkYXkgLSB0aGUgZGF5IG9mIHRoZSB3ZWVrIG9mIHRoZSBuZXcgZGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIHRoZSBvYmplY3Qgd2l0aCBvcHRpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMud2Vla1N0YXJ0c09uPTBdIC0gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsgKDAgLSBTdW5kYXkpXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIGRheSBvZiB0aGUgd2VlayBzZXR0ZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2V0IFN1bmRheSB0byAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHNldERheShuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgMClcbiAqIC8vPT4gU3VuIEF1ZyAzMSAyMDE0IDAwOjAwOjAwXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHdlZWsgc3RhcnRzIHdpdGggTW9uZGF5LCBzZXQgU3VuZGF5IHRvIDEgU2VwdGVtYmVyIDIwMTQ6XG4gKiB2YXIgcmVzdWx0ID0gc2V0RGF5KG5ldyBEYXRlKDIwMTQsIDgsIDEpLCAwLCB7d2Vla1N0YXJ0c09uOiAxfSlcbiAqIC8vPT4gU3VuIFNlcCAwNyAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHNldERheSAoZGlydHlEYXRlLCBkaXJ0eURheSwgZGlydHlPcHRpb25zKSB7XG4gIHZhciB3ZWVrU3RhcnRzT24gPSBkaXJ0eU9wdGlvbnMgPyAoTnVtYmVyKGRpcnR5T3B0aW9ucy53ZWVrU3RhcnRzT24pIHx8IDApIDogMFxuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRheSA9IE51bWJlcihkaXJ0eURheSlcbiAgdmFyIGN1cnJlbnREYXkgPSBkYXRlLmdldERheSgpXG5cbiAgdmFyIHJlbWFpbmRlciA9IGRheSAlIDdcbiAgdmFyIGRheUluZGV4ID0gKHJlbWFpbmRlciArIDcpICUgN1xuXG4gIHZhciBkaWZmID0gKGRheUluZGV4IDwgd2Vla1N0YXJ0c09uID8gNyA6IDApICsgZGF5IC0gY3VycmVudERheVxuICByZXR1cm4gYWRkRGF5cyhkYXRlLCBkaWZmKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERheVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBkYXkgb2YgdGhlIHllYXIgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTZXQgdGhlIGRheSBvZiB0aGUgeWVhciB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBkYXlPZlllYXIgLSB0aGUgZGF5IG9mIHRoZSB5ZWFyIG9mIHRoZSBuZXcgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBkYXkgb2YgdGhlIHllYXIgc2V0dGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFNldCB0aGUgMm5kIGRheSBvZiB0aGUgeWVhciB0byAyIEp1bHkgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBzZXREYXlPZlllYXIobmV3IERhdGUoMjAxNCwgNiwgMiksIDIpXG4gKiAvLz0+IFRodSBKYW4gMDIgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzZXREYXlPZlllYXIgKGRpcnR5RGF0ZSwgZGlydHlEYXlPZlllYXIpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBkYXlPZlllYXIgPSBOdW1iZXIoZGlydHlEYXlPZlllYXIpXG4gIGRhdGUuc2V0TW9udGgoMClcbiAgZGF0ZS5zZXREYXRlKGRheU9mWWVhcilcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXlPZlllYXJcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSG91ciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBTZXQgdGhlIGhvdXJzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSBob3VycyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBob3VycyAtIHRoZSBob3VycyBvZiB0aGUgbmV3IGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgaG91cnMgc2V0dGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFNldCA0IGhvdXJzIHRvIDEgU2VwdGVtYmVyIDIwMTQgMTE6MzA6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc2V0SG91cnMobmV3IERhdGUoMjAxNCwgOCwgMSwgMTEsIDMwKSwgNClcbiAqIC8vPT4gTW9uIFNlcCAwMSAyMDE0IDA0OjMwOjAwXG4gKi9cbmZ1bmN0aW9uIHNldEhvdXJzIChkaXJ0eURhdGUsIGRpcnR5SG91cnMpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBob3VycyA9IE51bWJlcihkaXJ0eUhvdXJzKVxuICBkYXRlLnNldEhvdXJzKGhvdXJzKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldEhvdXJzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgYWRkRGF5cyA9IHJlcXVpcmUoJy4uL2FkZF9kYXlzL2luZGV4LmpzJylcbnZhciBnZXRJU09EYXkgPSByZXF1aXJlKCcuLi9nZXRfaXNvX2RheS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFdlZWtkYXkgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIHRvIHRoZSBnaXZlbiBkYXRlLlxuICogSVNPIHdlZWsgc3RhcnRzIHdpdGggTW9uZGF5LlxuICogNyBpcyB0aGUgaW5kZXggb2YgU3VuZGF5LCAxIGlzIHRoZSBpbmRleCBvZiBNb25kYXkgZXRjLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGRheSAtIHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIG9mIHRoZSBuZXcgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBkYXkgb2YgdGhlIElTTyB3ZWVrIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgU3VuZGF5IHRvIDEgU2VwdGVtYmVyIDIwMTQ6XG4gKiB2YXIgcmVzdWx0ID0gc2V0SVNPRGF5KG5ldyBEYXRlKDIwMTQsIDgsIDEpLCA3KVxuICogLy89PiBTdW4gU2VwIDA3IDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc2V0SVNPRGF5IChkaXJ0eURhdGUsIGRpcnR5RGF5KSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgZGF5ID0gTnVtYmVyKGRpcnR5RGF5KVxuICB2YXIgY3VycmVudERheSA9IGdldElTT0RheShkYXRlKVxuICB2YXIgZGlmZiA9IGRheSAtIGN1cnJlbnREYXlcbiAgcmV0dXJuIGFkZERheXMoZGF0ZSwgZGlmZilcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRJU09EYXlcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBnZXRJU09XZWVrID0gcmVxdWlyZSgnLi4vZ2V0X2lzb193ZWVrL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWsgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBJU08gd2VlayB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFNldCB0aGUgSVNPIHdlZWsgdG8gdGhlIGdpdmVuIGRhdGUsIHNhdmluZyB0aGUgd2Vla2RheSBudW1iZXIuXG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGlzb1dlZWsgLSB0aGUgSVNPIHdlZWsgb2YgdGhlIG5ldyBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIElTTyB3ZWVrIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgdGhlIDUzcmQgSVNPIHdlZWsgdG8gNyBBdWd1c3QgMjAwNDpcbiAqIHZhciByZXN1bHQgPSBzZXRJU09XZWVrKG5ldyBEYXRlKDIwMDQsIDcsIDcpLCA1MylcbiAqIC8vPT4gU2F0IEphbiAwMSAyMDA1IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHNldElTT1dlZWsgKGRpcnR5RGF0ZSwgZGlydHlJU09XZWVrKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgaXNvV2VlayA9IE51bWJlcihkaXJ0eUlTT1dlZWspXG4gIHZhciBkaWZmID0gZ2V0SVNPV2VlayhkYXRlKSAtIGlzb1dlZWtcbiAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpIC0gZGlmZiAqIDcpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0SVNPV2Vla1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxudmFyIHN0YXJ0T2ZJU09ZZWFyID0gcmVxdWlyZSgnLi4vc3RhcnRfb2ZfaXNvX3llYXIvaW5kZXguanMnKVxudmFyIGRpZmZlcmVuY2VJbkNhbGVuZGFyRGF5cyA9IHJlcXVpcmUoJy4uL2RpZmZlcmVuY2VfaW5fY2FsZW5kYXJfZGF5cy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IElTTyBXZWVrLU51bWJlcmluZyBZZWFyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFNldCB0aGUgSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTZXQgdGhlIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIHRvIHRoZSBnaXZlbiBkYXRlLFxuICogc2F2aW5nIHRoZSB3ZWVrIG51bWJlciBhbmQgdGhlIHdlZWtkYXkgbnVtYmVyLlxuICpcbiAqIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBpc29ZZWFyIC0gdGhlIElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIG9mIHRoZSBuZXcgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBJU08gd2Vlay1udW1iZXJpbmcgeWVhciBzZXR0ZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2V0IElTTyB3ZWVrLW51bWJlcmluZyB5ZWFyIDIwMDcgdG8gMjkgRGVjZW1iZXIgMjAwODpcbiAqIHZhciByZXN1bHQgPSBzZXRJU09ZZWFyKG5ldyBEYXRlKDIwMDgsIDExLCAyOSksIDIwMDcpXG4gKiAvLz0+IE1vbiBKYW4gMDEgMjAwNyAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzZXRJU09ZZWFyIChkaXJ0eURhdGUsIGRpcnR5SVNPWWVhcikge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGlzb1llYXIgPSBOdW1iZXIoZGlydHlJU09ZZWFyKVxuICB2YXIgZGlmZiA9IGRpZmZlcmVuY2VJbkNhbGVuZGFyRGF5cyhkYXRlLCBzdGFydE9mSVNPWWVhcihkYXRlKSlcbiAgdmFyIGZvdXJ0aE9mSmFudWFyeSA9IG5ldyBEYXRlKDApXG4gIGZvdXJ0aE9mSmFudWFyeS5zZXRGdWxsWWVhcihpc29ZZWFyLCAwLCA0KVxuICBmb3VydGhPZkphbnVhcnkuc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgZGF0ZSA9IHN0YXJ0T2ZJU09ZZWFyKGZvdXJ0aE9mSmFudWFyeSlcbiAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgZGlmZilcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRJU09ZZWFyXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbGxpc2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFNldCB0aGUgbWlsbGlzZWNvbmRzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSBtaWxsaXNlY29uZHMgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIC0gdGhlIG1pbGxpc2Vjb25kcyBvZiB0aGUgbmV3IGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgbWlsbGlzZWNvbmRzIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgMzAwIG1pbGxpc2Vjb25kcyB0byAxIFNlcHRlbWJlciAyMDE0IDExOjMwOjQwLjUwMDpcbiAqIHZhciByZXN1bHQgPSBzZXRNaWxsaXNlY29uZHMobmV3IERhdGUoMjAxNCwgOCwgMSwgMTEsIDMwLCA0MCwgNTAwKSwgMzAwKVxuICogLy89PiBNb24gU2VwIDAxIDIwMTQgMTE6MzA6NDAuMzAwXG4gKi9cbmZ1bmN0aW9uIHNldE1pbGxpc2Vjb25kcyAoZGlydHlEYXRlLCBkaXJ0eU1pbGxpc2Vjb25kcykge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIG1pbGxpc2Vjb25kcyA9IE51bWJlcihkaXJ0eU1pbGxpc2Vjb25kcylcbiAgZGF0ZS5zZXRNaWxsaXNlY29uZHMobWlsbGlzZWNvbmRzKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldE1pbGxpc2Vjb25kc1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNaW51dGUgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBtaW51dGVzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSBtaW51dGVzIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbnV0ZXMgLSB0aGUgbWludXRlcyBvZiB0aGUgbmV3IGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgbWludXRlcyBzZXR0ZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2V0IDQ1IG1pbnV0ZXMgdG8gMSBTZXB0ZW1iZXIgMjAxNCAxMTozMDo0MDpcbiAqIHZhciByZXN1bHQgPSBzZXRNaW51dGVzKG5ldyBEYXRlKDIwMTQsIDgsIDEsIDExLCAzMCwgNDApLCA0NSlcbiAqIC8vPT4gTW9uIFNlcCAwMSAyMDE0IDExOjQ1OjQwXG4gKi9cbmZ1bmN0aW9uIHNldE1pbnV0ZXMgKGRpcnR5RGF0ZSwgZGlydHlNaW51dGVzKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICB2YXIgbWludXRlcyA9IE51bWJlcihkaXJ0eU1pbnV0ZXMpXG4gIGRhdGUuc2V0TWludXRlcyhtaW51dGVzKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldE1pbnV0ZXNcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcbnZhciBnZXREYXlzSW5Nb250aCA9IHJlcXVpcmUoJy4uL2dldF9kYXlzX2luX21vbnRoL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTW9udGggSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSBtb250aCB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFNldCB0aGUgbW9udGggdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gbW9udGggLSB0aGUgbW9udGggb2YgdGhlIG5ldyBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIG1vbnRoIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgRmVicnVhcnkgdG8gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBzZXRNb250aChuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgMSlcbiAqIC8vPT4gU2F0IEZlYiAwMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHNldE1vbnRoIChkaXJ0eURhdGUsIGRpcnR5TW9udGgpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBtb250aCA9IE51bWJlcihkaXJ0eU1vbnRoKVxuICB2YXIgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKVxuICB2YXIgZGF5ID0gZGF0ZS5nZXREYXRlKClcblxuICB2YXIgZGF0ZVdpdGhEZXNpcmVkTW9udGggPSBuZXcgRGF0ZSgwKVxuICBkYXRlV2l0aERlc2lyZWRNb250aC5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCwgMTUpXG4gIGRhdGVXaXRoRGVzaXJlZE1vbnRoLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHZhciBkYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoKGRhdGVXaXRoRGVzaXJlZE1vbnRoKVxuICAvLyBTZXQgdGhlIGxhc3QgZGF5IG9mIHRoZSBuZXcgbW9udGhcbiAgLy8gaWYgdGhlIG9yaWdpbmFsIGRhdGUgd2FzIHRoZSBsYXN0IGRheSBvZiB0aGUgbG9uZ2VyIG1vbnRoXG4gIGRhdGUuc2V0TW9udGgobW9udGgsIE1hdGgubWluKGRheSwgZGF5c0luTW9udGgpKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldE1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG52YXIgc2V0TW9udGggPSByZXF1aXJlKCcuLi9zZXRfbW9udGgvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBRdWFydGVyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFNldCB0aGUgeWVhciBxdWFydGVyIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSB5ZWFyIHF1YXJ0ZXIgdG8gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gcXVhcnRlciAtIHRoZSBxdWFydGVyIG9mIHRoZSBuZXcgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBxdWFydGVyIHNldHRlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgdGhlIDJuZCBxdWFydGVyIHRvIDIgSnVseSAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHNldFF1YXJ0ZXIobmV3IERhdGUoMjAxNCwgNiwgMiksIDIpXG4gKiAvLz0+IFdlZCBBcHIgMDIgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzZXRRdWFydGVyIChkaXJ0eURhdGUsIGRpcnR5UXVhcnRlcikge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIHF1YXJ0ZXIgPSBOdW1iZXIoZGlydHlRdWFydGVyKVxuICB2YXIgb2xkUXVhcnRlciA9IE1hdGguZmxvb3IoZGF0ZS5nZXRNb250aCgpIC8gMykgKyAxXG4gIHZhciBkaWZmID0gcXVhcnRlciAtIG9sZFF1YXJ0ZXJcbiAgcmV0dXJuIHNldE1vbnRoKGRhdGUsIGRhdGUuZ2V0TW9udGgoKSArIGRpZmYgKiAzKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFF1YXJ0ZXJcbiIsInZhciBwYXJzZSA9IHJlcXVpcmUoJy4uL3BhcnNlL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgU2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFNldCB0aGUgc2Vjb25kcyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFNldCB0aGUgc2Vjb25kcyB0byB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzZWNvbmRzIC0gdGhlIHNlY29uZHMgb2YgdGhlIG5ldyBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIHNlY29uZHMgc2V0dGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFNldCA0NSBzZWNvbmRzIHRvIDEgU2VwdGVtYmVyIDIwMTQgMTE6MzA6NDA6XG4gKiB2YXIgcmVzdWx0ID0gc2V0U2Vjb25kcyhuZXcgRGF0ZSgyMDE0LCA4LCAxLCAxMSwgMzAsIDQwKSwgNDUpXG4gKiAvLz0+IE1vbiBTZXAgMDEgMjAxNCAxMTozMDo0NVxuICovXG5mdW5jdGlvbiBzZXRTZWNvbmRzIChkaXJ0eURhdGUsIGRpcnR5U2Vjb25kcykge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIHNlY29uZHMgPSBOdW1iZXIoZGlydHlTZWNvbmRzKVxuICBkYXRlLnNldFNlY29uZHMoc2Vjb25kcylcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRTZWNvbmRzXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgU2V0IHRoZSB5ZWFyIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU2V0IHRoZSB5ZWFyIHRvIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IHllYXIgLSB0aGUgeWVhciBvZiB0aGUgbmV3IGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgeWVhciBzZXR0ZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2V0IHllYXIgMjAxMyB0byAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHNldFllYXIobmV3IERhdGUoMjAxNCwgOCwgMSksIDIwMTMpXG4gKiAvLz0+IFN1biBTZXAgMDEgMjAxMyAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzZXRZZWFyIChkaXJ0eURhdGUsIGRpcnR5WWVhcikge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIHllYXIgPSBOdW1iZXIoZGlydHlZZWFyKVxuICBkYXRlLnNldEZ1bGxZZWFyKHllYXIpXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0WWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiBhIGRheSBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGEgZGF5IGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIGRheVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgc3RhcnQgb2YgYSBkYXkgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZkRheShuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBUdWUgU2VwIDAyIDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3RhcnRPZkRheSAoZGlydHlEYXRlKSB7XG4gIHZhciBkYXRlID0gcGFyc2UoZGlydHlEYXRlKVxuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhcnRPZkRheVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBIb3VyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgc3RhcnQgb2YgYW4gaG91ciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGFuIGhvdXIgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBvcmlnaW5hbCBkYXRlXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIHN0YXJ0IG9mIGFuIGhvdXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIHN0YXJ0IG9mIGFuIGhvdXIgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZkhvdXIobmV3IERhdGUoMjAxNCwgOCwgMiwgMTEsIDU1KSlcbiAqIC8vPT4gVHVlIFNlcCAwMiAyMDE0IDExOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHN0YXJ0T2ZIb3VyIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIGRhdGUuc2V0TWludXRlcygwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YXJ0T2ZIb3VyXG4iLCJ2YXIgc3RhcnRPZldlZWsgPSByZXF1aXJlKCcuLi9zdGFydF9vZl93ZWVrL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWsgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiBhbiBJU08gd2VlayBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGFuIElTTyB3ZWVrIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogSVNPIHdlZWstbnVtYmVyaW5nIHllYXI6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZVxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIG9yaWdpbmFsIGRhdGVcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgc3RhcnQgb2YgYW4gSVNPIHdlZWtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIHN0YXJ0IG9mIGFuIElTTyB3ZWVrIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IHN0YXJ0T2ZJU09XZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IE1vbiBTZXAgMDEgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzdGFydE9mSVNPV2VlayAoZGlydHlEYXRlKSB7XG4gIHJldHVybiBzdGFydE9mV2VlayhkaXJ0eURhdGUsIHt3ZWVrU3RhcnRzT246IDF9KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YXJ0T2ZJU09XZWVrXG4iLCJ2YXIgZ2V0SVNPWWVhciA9IHJlcXVpcmUoJy4uL2dldF9pc29feWVhci9pbmRleC5qcycpXG52YXIgc3RhcnRPZklTT1dlZWsgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9pc29fd2Vlay9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IElTTyBXZWVrLU51bWJlcmluZyBZZWFyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgc3RhcnQgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBzdGFydCBvZiBhbiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcixcbiAqIHdoaWNoIGFsd2F5cyBzdGFydHMgMyBkYXlzIGJlZm9yZSB0aGUgeWVhcidzIGZpcnN0IFRodXJzZGF5LlxuICogVGhlIHJlc3VsdCB3aWxsIGJlIGluIHRoZSBsb2NhbCB0aW1lem9uZS5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhbiBJU08geWVhclxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgc3RhcnQgb2YgYW4gSVNPIHdlZWstbnVtYmVyaW5nIHllYXIgZm9yIDIgSnVseSAyMDA1OlxuICogdmFyIHJlc3VsdCA9IHN0YXJ0T2ZJU09ZZWFyKG5ldyBEYXRlKDIwMDUsIDYsIDIpKVxuICogLy89PiBNb24gSmFuIDAzIDIwMDUgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3RhcnRPZklTT1llYXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgeWVhciA9IGdldElTT1llYXIoZGlydHlEYXRlKVxuICB2YXIgZm91cnRoT2ZKYW51YXJ5ID0gbmV3IERhdGUoMClcbiAgZm91cnRoT2ZKYW51YXJ5LnNldEZ1bGxZZWFyKHllYXIsIDAsIDQpXG4gIGZvdXJ0aE9mSmFudWFyeS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICB2YXIgZGF0ZSA9IHN0YXJ0T2ZJU09XZWVrKGZvdXJ0aE9mSmFudWFyeSlcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFydE9mSVNPWWVhclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNaW51dGUgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiBhIG1pbnV0ZSBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGEgbWludXRlIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIG1pbnV0ZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgc3RhcnQgb2YgYSBtaW51dGUgZm9yIDEgRGVjZW1iZXIgMjAxNCAyMjoxNTo0NS40MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZk1pbnV0ZShuZXcgRGF0ZSgyMDE0LCAxMSwgMSwgMjIsIDE1LCA0NSwgNDAwKSlcbiAqIC8vPT4gTW9uIERlYyAwMSAyMDE0IDIyOjE1OjAwXG4gKi9cbmZ1bmN0aW9uIHN0YXJ0T2ZNaW51dGUgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgZGF0ZS5zZXRTZWNvbmRzKDAsIDApXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhcnRPZk1pbnV0ZVxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBNb250aCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIHN0YXJ0IG9mIGEgbW9udGggZm9yIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogUmV0dXJuIHRoZSBzdGFydCBvZiBhIG1vbnRoIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIG1vbnRoXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRoZSBzdGFydCBvZiBhIG1vbnRoIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IHN0YXJ0T2ZNb250aChuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBNb24gU2VwIDAxIDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3RhcnRPZk1vbnRoIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIGRhdGUuc2V0RGF0ZSgxKVxuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhcnRPZk1vbnRoXG4iLCJ2YXIgcGFyc2UgPSByZXF1aXJlKCcuLi9wYXJzZS9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFF1YXJ0ZXIgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiBhIHllYXIgcXVhcnRlciBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGEgeWVhciBxdWFydGVyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIHF1YXJ0ZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIHN0YXJ0IG9mIGEgcXVhcnRlciBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBzdGFydE9mUXVhcnRlcihuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDApKVxuICogLy89PiBUdWUgSnVsIDAxIDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3RhcnRPZlF1YXJ0ZXIgKGRpcnR5RGF0ZSkge1xuICB2YXIgZGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGN1cnJlbnRNb250aCA9IGRhdGUuZ2V0TW9udGgoKVxuICB2YXIgbW9udGggPSBjdXJyZW50TW9udGggLSBjdXJyZW50TW9udGggJSAzXG4gIGRhdGUuc2V0TW9udGgobW9udGgsIDEpXG4gIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFydE9mUXVhcnRlclxuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBTZWNvbmQgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiBhIHNlY29uZCBmb3IgdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIGEgc2Vjb25kIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIHNlY29uZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgc3RhcnQgb2YgYSBzZWNvbmQgZm9yIDEgRGVjZW1iZXIgMjAxNCAyMjoxNTo0NS40MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZlNlY29uZChuZXcgRGF0ZSgyMDE0LCAxMSwgMSwgMjIsIDE1LCA0NSwgNDAwKSlcbiAqIC8vPT4gTW9uIERlYyAwMSAyMDE0IDIyOjE1OjQ1LjAwMFxuICovXG5mdW5jdGlvbiBzdGFydE9mU2Vjb25kIChkaXJ0eURhdGUpIHtcbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIGRhdGUuc2V0TWlsbGlzZWNvbmRzKDApXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhcnRPZlNlY29uZFxuIiwidmFyIHN0YXJ0T2ZEYXkgPSByZXF1aXJlKCcuLi9zdGFydF9vZl9kYXkvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgUmV0dXJuIHRoZSBzdGFydCBvZiB0b2RheS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgc3RhcnQgb2YgdG9kYXkuXG4gKlxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiB0b2RheVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0b2RheSBpcyA2IE9jdG9iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBzdGFydE9mVG9kYXkoKVxuICogLy89PiBNb24gT2N0IDYgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzdGFydE9mVG9kYXkgKCkge1xuICByZXR1cm4gc3RhcnRPZkRheShuZXcgRGF0ZSgpKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YXJ0T2ZUb2RheVxuIiwiLyoqXG4gKiBAY2F0ZWdvcnkgRGF5IEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgc3RhcnQgb2YgdG9tb3Jyb3cuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXR1cm4gdGhlIHN0YXJ0IG9mIHRvbW9ycm93LlxuICpcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgc3RhcnQgb2YgdG9tb3Jyb3dcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSWYgdG9kYXkgaXMgNiBPY3RvYmVyIDIwMTQ6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZlRvbW9ycm93KClcbiAqIC8vPT4gVHVlIE9jdCA3IDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3RhcnRPZlRvbW9ycm93ICgpIHtcbiAgdmFyIG5vdyA9IG5ldyBEYXRlKClcbiAgdmFyIHllYXIgPSBub3cuZ2V0RnVsbFllYXIoKVxuICB2YXIgbW9udGggPSBub3cuZ2V0TW9udGgoKVxuICB2YXIgZGF5ID0gbm93LmdldERhdGUoKVxuXG4gIHZhciBkYXRlID0gbmV3IERhdGUoMClcbiAgZGF0ZS5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCwgZGF5ICsgMSlcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YXJ0T2ZUb21vcnJvd1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgc3RhcnQgb2YgYSB3ZWVrIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgc3RhcnQgb2YgYSB3ZWVrIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIHRoZSBvYmplY3Qgd2l0aCBvcHRpb25zXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMud2Vla1N0YXJ0c09uPTBdIC0gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsgKDAgLSBTdW5kYXkpXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIHN0YXJ0IG9mIGEgd2Vla1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGUgc3RhcnQgb2YgYSB3ZWVrIGZvciAyIFNlcHRlbWJlciAyMDE0IDExOjU1OjAwOlxuICogdmFyIHJlc3VsdCA9IHN0YXJ0T2ZXZWVrKG5ldyBEYXRlKDIwMTQsIDgsIDIsIDExLCA1NSwgMCkpXG4gKiAvLz0+IFN1biBBdWcgMzEgMjAxNCAwMDowMDowMFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJZiB0aGUgd2VlayBzdGFydHMgb24gTW9uZGF5LCB0aGUgc3RhcnQgb2YgdGhlIHdlZWsgZm9yIDIgU2VwdGVtYmVyIDIwMTQgMTE6NTU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3RhcnRPZldlZWsobmV3IERhdGUoMjAxNCwgOCwgMiwgMTEsIDU1LCAwKSwge3dlZWtTdGFydHNPbjogMX0pXG4gKiAvLz0+IE1vbiBTZXAgMDEgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzdGFydE9mV2VlayAoZGlydHlEYXRlLCBkaXJ0eU9wdGlvbnMpIHtcbiAgdmFyIHdlZWtTdGFydHNPbiA9IGRpcnR5T3B0aW9ucyA/IChOdW1iZXIoZGlydHlPcHRpb25zLndlZWtTdGFydHNPbikgfHwgMCkgOiAwXG5cbiAgdmFyIGRhdGUgPSBwYXJzZShkaXJ0eURhdGUpXG4gIHZhciBkYXkgPSBkYXRlLmdldERheSgpXG4gIHZhciBkaWZmID0gKGRheSA8IHdlZWtTdGFydHNPbiA/IDcgOiAwKSArIGRheSAtIHdlZWtTdGFydHNPblxuXG4gIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSAtIGRpZmYpXG4gIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgcmV0dXJuIGRhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFydE9mV2Vla1xuIiwidmFyIHBhcnNlID0gcmVxdWlyZSgnLi4vcGFyc2UvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBZZWFyIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFJldHVybiB0aGUgc3RhcnQgb2YgYSB5ZWFyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgc3RhcnQgb2YgYSB5ZWFyIGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAqIFRoZSByZXN1bHQgd2lsbCBiZSBpbiB0aGUgbG9jYWwgdGltZXpvbmUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgb3JpZ2luYWwgZGF0ZVxuICogQHJldHVybnMge0RhdGV9IHRoZSBzdGFydCBvZiBhIHllYXJcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhlIHN0YXJ0IG9mIGEgeWVhciBmb3IgMiBTZXB0ZW1iZXIgMjAxNCAxMTo1NTowMDpcbiAqIHZhciByZXN1bHQgPSBzdGFydE9mWWVhcihuZXcgRGF0ZSgyMDE0LCA4LCAyLCAxMSwgNTUsIDAwKSlcbiAqIC8vPT4gV2VkIEphbiAwMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHN0YXJ0T2ZZZWFyIChkaXJ0eURhdGUpIHtcbiAgdmFyIGNsZWFuRGF0ZSA9IHBhcnNlKGRpcnR5RGF0ZSlcbiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgwKVxuICBkYXRlLnNldEZ1bGxZZWFyKGNsZWFuRGF0ZS5nZXRGdWxsWWVhcigpLCAwLCAxKVxuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHJldHVybiBkYXRlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RhcnRPZlllYXJcbiIsIi8qKlxuICogQGNhdGVnb3J5IERheSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBSZXR1cm4gdGhlIHN0YXJ0IG9mIHllc3RlcmRheS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFJldHVybiB0aGUgc3RhcnQgb2YgeWVzdGVyZGF5LlxuICpcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgc3RhcnQgb2YgeWVzdGVyZGF5XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIElmIHRvZGF5IGlzIDYgT2N0b2JlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHN0YXJ0T2ZZZXN0ZXJkYXkoKVxuICogLy89PiBTdW4gT2N0IDUgMjAxNCAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzdGFydE9mWWVzdGVyZGF5ICgpIHtcbiAgdmFyIG5vdyA9IG5ldyBEYXRlKClcbiAgdmFyIHllYXIgPSBub3cuZ2V0RnVsbFllYXIoKVxuICB2YXIgbW9udGggPSBub3cuZ2V0TW9udGgoKVxuICB2YXIgZGF5ID0gbm93LmdldERhdGUoKVxuXG4gIHZhciBkYXRlID0gbmV3IERhdGUoMClcbiAgZGF0ZS5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCwgZGF5IC0gMSlcbiAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKVxuICByZXR1cm4gZGF0ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YXJ0T2ZZZXN0ZXJkYXlcbiIsInZhciBhZGREYXlzID0gcmVxdWlyZSgnLi4vYWRkX2RheXMvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBEYXkgSGVscGVyc1xuICogQHN1bW1hcnkgU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZGF5cyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZGF5cyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgb2YgZGF5cyB0byBiZSBzdWJ0cmFjdGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIGRheXMgc3VidHJhY3RlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTdWJ0cmFjdCAxMCBkYXlzIGZyb20gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBzdWJEYXlzKG5ldyBEYXRlKDIwMTQsIDgsIDEpLCAxMClcbiAqIC8vPT4gRnJpIEF1ZyAyMiAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHN1YkRheXMgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIGFtb3VudCA9IE51bWJlcihkaXJ0eUFtb3VudClcbiAgcmV0dXJuIGFkZERheXMoZGlydHlEYXRlLCAtYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1YkRheXNcbiIsInZhciBhZGRIb3VycyA9IHJlcXVpcmUoJy4uL2FkZF9ob3Vycy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IEhvdXIgSGVscGVyc1xuICogQHN1bW1hcnkgU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgaG91cnMgZnJvbSB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFN1YnRyYWN0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGhvdXJzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBob3VycyB0byBiZSBzdWJ0cmFjdGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIGhvdXJzIHN1YnRyYWN0ZWRcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU3VidHJhY3QgMiBob3VycyBmcm9tIDExIEp1bHkgMjAxNCAwMTowMDowMDpcbiAqIHZhciByZXN1bHQgPSBzdWJIb3VycyhuZXcgRGF0ZSgyMDE0LCA2LCAxMSwgMSwgMCksIDIpXG4gKiAvLz0+IFRodSBKdWwgMTAgMjAxNCAyMzowMDowMFxuICovXG5mdW5jdGlvbiBzdWJIb3VycyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgYW1vdW50ID0gTnVtYmVyKGRpcnR5QW1vdW50KVxuICByZXR1cm4gYWRkSG91cnMoZGlydHlEYXRlLCAtYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1YkhvdXJzXG4iLCJ2YXIgYWRkSVNPWWVhcnMgPSByZXF1aXJlKCcuLi9hZGRfaXNvX3llYXJzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgSVNPIFdlZWstTnVtYmVyaW5nIFllYXIgSGVscGVyc1xuICogQHN1bW1hcnkgU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgSVNPIHdlZWstbnVtYmVyaW5nIHllYXJzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnMgZnJvbSB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcjogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnMgdG8gYmUgc3VidHJhY3RlZFxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBJU08gd2Vlay1udW1iZXJpbmcgeWVhcnMgc3VidHJhY3RlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTdWJ0cmFjdCA1IElTTyB3ZWVrLW51bWJlcmluZyB5ZWFycyBmcm9tIDEgU2VwdGVtYmVyIDIwMTQ6XG4gKiB2YXIgcmVzdWx0ID0gc3ViSVNPWWVhcnMobmV3IERhdGUoMjAxNCwgOCwgMSksIDUpXG4gKiAvLz0+IE1vbiBBdWcgMzEgMjAwOSAwMDowMDowMFxuICovXG5mdW5jdGlvbiBzdWJJU09ZZWFycyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgYW1vdW50ID0gTnVtYmVyKGRpcnR5QW1vdW50KVxuICByZXR1cm4gYWRkSVNPWWVhcnMoZGlydHlEYXRlLCAtYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1YklTT1llYXJzXG4iLCJ2YXIgYWRkTWlsbGlzZWNvbmRzID0gcmVxdWlyZSgnLi4vYWRkX21pbGxpc2Vjb25kcy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbGxpc2Vjb25kIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFN1YnRyYWN0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBtaWxsaXNlY29uZHMgdG8gYmUgc3VidHJhY3RlZFxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBtaWxsaXNlY29uZHMgc3VidHJhY3RlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTdWJ0cmFjdCA3NTAgbWlsbGlzZWNvbmRzIGZyb20gMTAgSnVseSAyMDE0IDEyOjQ1OjMwLjAwMDpcbiAqIHZhciByZXN1bHQgPSBzdWJNaWxsaXNlY29uZHMobmV3IERhdGUoMjAxNCwgNiwgMTAsIDEyLCA0NSwgMzAsIDApLCA3NTApXG4gKiAvLz0+IFRodSBKdWwgMTAgMjAxNCAxMjo0NToyOS4yNTBcbiAqL1xuZnVuY3Rpb24gc3ViTWlsbGlzZWNvbmRzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRNaWxsaXNlY29uZHMoZGlydHlEYXRlLCAtYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1Yk1pbGxpc2Vjb25kc1xuIiwidmFyIGFkZE1pbnV0ZXMgPSByZXF1aXJlKCcuLi9hZGRfbWludXRlcy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IE1pbnV0ZSBIZWxwZXJzXG4gKiBAc3VtbWFyeSBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaW51dGVzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaW51dGVzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBtaW51dGVzIHRvIGJlIHN1YnRyYWN0ZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgbWludHVlcyBzdWJ0cmFjdGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN1YnRyYWN0IDMwIG1pbnV0ZXMgZnJvbSAxMCBKdWx5IDIwMTQgMTI6MDA6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3ViTWludXRlcyhuZXcgRGF0ZSgyMDE0LCA2LCAxMCwgMTIsIDApLCAzMClcbiAqIC8vPT4gVGh1IEp1bCAxMCAyMDE0IDExOjMwOjAwXG4gKi9cbmZ1bmN0aW9uIHN1Yk1pbnV0ZXMgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIGFtb3VudCA9IE51bWJlcihkaXJ0eUFtb3VudClcbiAgcmV0dXJuIGFkZE1pbnV0ZXMoZGlydHlEYXRlLCAtYW1vdW50KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1Yk1pbnV0ZXNcbiIsInZhciBhZGRNb250aHMgPSByZXF1aXJlKCcuLi9hZGRfbW9udGhzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgTW9udGggSGVscGVyc1xuICogQHN1bW1hcnkgU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgbW9udGhzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtb250aHMgZnJvbSB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBhbW91bnQgLSB0aGUgYW1vdW50IG9mIG1vbnRocyB0byBiZSBzdWJ0cmFjdGVkXG4gKiBAcmV0dXJucyB7RGF0ZX0gdGhlIG5ldyBkYXRlIHdpdGggdGhlIG1vbnRocyBzdWJ0cmFjdGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN1YnRyYWN0IDUgbW9udGhzIGZyb20gMSBGZWJydWFyeSAyMDE1OlxuICogdmFyIHJlc3VsdCA9IHN1Yk1vbnRocyhuZXcgRGF0ZSgyMDE1LCAxLCAxKSwgNSlcbiAqIC8vPT4gTW9uIFNlcCAwMSAyMDE0IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHN1Yk1vbnRocyAoZGlydHlEYXRlLCBkaXJ0eUFtb3VudCkge1xuICB2YXIgYW1vdW50ID0gTnVtYmVyKGRpcnR5QW1vdW50KVxuICByZXR1cm4gYWRkTW9udGhzKGRpcnR5RGF0ZSwgLWFtb3VudClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdWJNb250aHNcbiIsInZhciBhZGRRdWFydGVycyA9IHJlcXVpcmUoJy4uL2FkZF9xdWFydGVycy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFF1YXJ0ZXIgSGVscGVyc1xuICogQHN1bW1hcnkgU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgeWVhciBxdWFydGVycyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgeWVhciBxdWFydGVycyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgb2YgcXVhcnRlcnMgdG8gYmUgc3VidHJhY3RlZFxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSBxdWFydGVycyBzdWJ0cmFjdGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN1YnRyYWN0IDMgcXVhcnRlcnMgZnJvbSAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHN1YlF1YXJ0ZXJzKG5ldyBEYXRlKDIwMTQsIDgsIDEpLCAzKVxuICogLy89PiBTdW4gRGVjIDAxIDIwMTMgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3ViUXVhcnRlcnMgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIGFtb3VudCA9IE51bWJlcihkaXJ0eUFtb3VudClcbiAgcmV0dXJuIGFkZFF1YXJ0ZXJzKGRpcnR5RGF0ZSwgLWFtb3VudClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdWJRdWFydGVyc1xuIiwidmFyIGFkZFNlY29uZHMgPSByZXF1aXJlKCcuLi9hZGRfc2Vjb25kcy9pbmRleC5qcycpXG5cbi8qKlxuICogQGNhdGVnb3J5IFNlY29uZCBIZWxwZXJzXG4gKiBAc3VtbWFyeSBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzZWNvbmRzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzZWNvbmRzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIHtEYXRlfFN0cmluZ3xOdW1iZXJ9IGRhdGUgLSB0aGUgZGF0ZSB0byBiZSBjaGFuZ2VkXG4gKiBAcGFyYW0ge051bWJlcn0gYW1vdW50IC0gdGhlIGFtb3VudCBvZiBzZWNvbmRzIHRvIGJlIHN1YnRyYWN0ZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgc2Vjb25kcyBzdWJ0cmFjdGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN1YnRyYWN0IDMwIHNlY29uZHMgZnJvbSAxMCBKdWx5IDIwMTQgMTI6NDU6MDA6XG4gKiB2YXIgcmVzdWx0ID0gc3ViU2Vjb25kcyhuZXcgRGF0ZSgyMDE0LCA2LCAxMCwgMTIsIDQ1LCAwKSwgMzApXG4gKiAvLz0+IFRodSBKdWwgMTAgMjAxNCAxMjo0NDozMFxuICovXG5mdW5jdGlvbiBzdWJTZWNvbmRzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRTZWNvbmRzKGRpcnR5RGF0ZSwgLWFtb3VudClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdWJTZWNvbmRzXG4iLCJ2YXIgYWRkV2Vla3MgPSByZXF1aXJlKCcuLi9hZGRfd2Vla3MvaW5kZXguanMnKVxuXG4vKipcbiAqIEBjYXRlZ29yeSBXZWVrIEhlbHBlcnNcbiAqIEBzdW1tYXJ5IFN1YnRyYWN0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHdlZWtzIGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB3ZWVrcyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd8TnVtYmVyfSBkYXRlIC0gdGhlIGRhdGUgdG8gYmUgY2hhbmdlZFxuICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgb2Ygd2Vla3MgdG8gYmUgc3VidHJhY3RlZFxuICogQHJldHVybnMge0RhdGV9IHRoZSBuZXcgZGF0ZSB3aXRoIHRoZSB3ZWVrcyBzdWJ0cmFjdGVkXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN1YnRyYWN0IDQgd2Vla3MgZnJvbSAxIFNlcHRlbWJlciAyMDE0OlxuICogdmFyIHJlc3VsdCA9IHN1YldlZWtzKG5ldyBEYXRlKDIwMTQsIDgsIDEpLCA0KVxuICogLy89PiBNb24gQXVnIDA0IDIwMTQgMDA6MDA6MDBcbiAqL1xuZnVuY3Rpb24gc3ViV2Vla3MgKGRpcnR5RGF0ZSwgZGlydHlBbW91bnQpIHtcbiAgdmFyIGFtb3VudCA9IE51bWJlcihkaXJ0eUFtb3VudClcbiAgcmV0dXJuIGFkZFdlZWtzKGRpcnR5RGF0ZSwgLWFtb3VudClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdWJXZWVrc1xuIiwidmFyIGFkZFllYXJzID0gcmVxdWlyZSgnLi4vYWRkX3llYXJzL2luZGV4LmpzJylcblxuLyoqXG4gKiBAY2F0ZWdvcnkgWWVhciBIZWxwZXJzXG4gKiBAc3VtbWFyeSBTdWJ0cmFjdCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB5ZWFycyBmcm9tIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogU3VidHJhY3QgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgeWVhcnMgZnJvbSB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge0RhdGV8U3RyaW5nfE51bWJlcn0gZGF0ZSAtIHRoZSBkYXRlIHRvIGJlIGNoYW5nZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBhbW91bnQgLSB0aGUgYW1vdW50IG9mIHllYXJzIHRvIGJlIHN1YnRyYWN0ZWRcbiAqIEByZXR1cm5zIHtEYXRlfSB0aGUgbmV3IGRhdGUgd2l0aCB0aGUgeWVhcnMgc3VidHJhY3RlZFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTdWJ0cmFjdCA1IHllYXJzIGZyb20gMSBTZXB0ZW1iZXIgMjAxNDpcbiAqIHZhciByZXN1bHQgPSBzdWJZZWFycyhuZXcgRGF0ZSgyMDE0LCA4LCAxKSwgNSlcbiAqIC8vPT4gVHVlIFNlcCAwMSAyMDA5IDAwOjAwOjAwXG4gKi9cbmZ1bmN0aW9uIHN1YlllYXJzIChkaXJ0eURhdGUsIGRpcnR5QW1vdW50KSB7XG4gIHZhciBhbW91bnQgPSBOdW1iZXIoZGlydHlBbW91bnQpXG4gIHJldHVybiBhZGRZZWFycyhkaXJ0eURhdGUsIC1hbW91bnQpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3ViWWVhcnNcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBhZGREYXlzOiByZXF1aXJlKCcuL2FkZF9kYXlzL2luZGV4LmpzJyksXG4gIGFkZEhvdXJzOiByZXF1aXJlKCcuL2FkZF9ob3Vycy9pbmRleC5qcycpLFxuICBhZGRJU09ZZWFyczogcmVxdWlyZSgnLi9hZGRfaXNvX3llYXJzL2luZGV4LmpzJyksXG4gIGFkZE1pbGxpc2Vjb25kczogcmVxdWlyZSgnLi9hZGRfbWlsbGlzZWNvbmRzL2luZGV4LmpzJyksXG4gIGFkZE1pbnV0ZXM6IHJlcXVpcmUoJy4vYWRkX21pbnV0ZXMvaW5kZXguanMnKSxcbiAgYWRkTW9udGhzOiByZXF1aXJlKCcuL2FkZF9tb250aHMvaW5kZXguanMnKSxcbiAgYWRkUXVhcnRlcnM6IHJlcXVpcmUoJy4vYWRkX3F1YXJ0ZXJzL2luZGV4LmpzJyksXG4gIGFkZFNlY29uZHM6IHJlcXVpcmUoJy4vYWRkX3NlY29uZHMvaW5kZXguanMnKSxcbiAgYWRkV2Vla3M6IHJlcXVpcmUoJy4vYWRkX3dlZWtzL2luZGV4LmpzJyksXG4gIGFkZFllYXJzOiByZXF1aXJlKCcuL2FkZF95ZWFycy9pbmRleC5qcycpLFxuICBhcmVSYW5nZXNPdmVybGFwcGluZzogcmVxdWlyZSgnLi9hcmVfcmFuZ2VzX292ZXJsYXBwaW5nL2luZGV4LmpzJyksXG4gIGNsb3Nlc3RJbmRleFRvOiByZXF1aXJlKCcuL2Nsb3Nlc3RfaW5kZXhfdG8vaW5kZXguanMnKSxcbiAgY2xvc2VzdFRvOiByZXF1aXJlKCcuL2Nsb3Nlc3RfdG8vaW5kZXguanMnKSxcbiAgY29tcGFyZUFzYzogcmVxdWlyZSgnLi9jb21wYXJlX2FzYy9pbmRleC5qcycpLFxuICBjb21wYXJlRGVzYzogcmVxdWlyZSgnLi9jb21wYXJlX2Rlc2MvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluQ2FsZW5kYXJEYXlzOiByZXF1aXJlKCcuL2RpZmZlcmVuY2VfaW5fY2FsZW5kYXJfZGF5cy9pbmRleC5qcycpLFxuICBkaWZmZXJlbmNlSW5DYWxlbmRhcklTT1dlZWtzOiByZXF1aXJlKCcuL2RpZmZlcmVuY2VfaW5fY2FsZW5kYXJfaXNvX3dlZWtzL2luZGV4LmpzJyksXG4gIGRpZmZlcmVuY2VJbkNhbGVuZGFySVNPWWVhcnM6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9pc29feWVhcnMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluQ2FsZW5kYXJNb250aHM6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl9tb250aHMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluQ2FsZW5kYXJRdWFydGVyczogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX2NhbGVuZGFyX3F1YXJ0ZXJzL2luZGV4LmpzJyksXG4gIGRpZmZlcmVuY2VJbkNhbGVuZGFyV2Vla3M6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl9jYWxlbmRhcl93ZWVrcy9pbmRleC5qcycpLFxuICBkaWZmZXJlbmNlSW5DYWxlbmRhclllYXJzOiByZXF1aXJlKCcuL2RpZmZlcmVuY2VfaW5fY2FsZW5kYXJfeWVhcnMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluRGF5czogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX2RheXMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluSG91cnM6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl9ob3Vycy9pbmRleC5qcycpLFxuICBkaWZmZXJlbmNlSW5JU09ZZWFyczogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX2lzb195ZWFycy9pbmRleC5qcycpLFxuICBkaWZmZXJlbmNlSW5NaWxsaXNlY29uZHM6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl9taWxsaXNlY29uZHMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluTWludXRlczogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX21pbnV0ZXMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluTW9udGhzOiByZXF1aXJlKCcuL2RpZmZlcmVuY2VfaW5fbW9udGhzL2luZGV4LmpzJyksXG4gIGRpZmZlcmVuY2VJblF1YXJ0ZXJzOiByZXF1aXJlKCcuL2RpZmZlcmVuY2VfaW5fcXVhcnRlcnMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluU2Vjb25kczogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX3NlY29uZHMvaW5kZXguanMnKSxcbiAgZGlmZmVyZW5jZUluV2Vla3M6IHJlcXVpcmUoJy4vZGlmZmVyZW5jZV9pbl93ZWVrcy9pbmRleC5qcycpLFxuICBkaWZmZXJlbmNlSW5ZZWFyczogcmVxdWlyZSgnLi9kaWZmZXJlbmNlX2luX3llYXJzL2luZGV4LmpzJyksXG4gIGRpc3RhbmNlSW5Xb3JkczogcmVxdWlyZSgnLi9kaXN0YW5jZV9pbl93b3Jkcy9pbmRleC5qcycpLFxuICBkaXN0YW5jZUluV29yZHNTdHJpY3Q6IHJlcXVpcmUoJy4vZGlzdGFuY2VfaW5fd29yZHNfc3RyaWN0L2luZGV4LmpzJyksXG4gIGRpc3RhbmNlSW5Xb3Jkc1RvTm93OiByZXF1aXJlKCcuL2Rpc3RhbmNlX2luX3dvcmRzX3RvX25vdy9pbmRleC5qcycpLFxuICBlYWNoRGF5OiByZXF1aXJlKCcuL2VhY2hfZGF5L2luZGV4LmpzJyksXG4gIGVuZE9mRGF5OiByZXF1aXJlKCcuL2VuZF9vZl9kYXkvaW5kZXguanMnKSxcbiAgZW5kT2ZIb3VyOiByZXF1aXJlKCcuL2VuZF9vZl9ob3VyL2luZGV4LmpzJyksXG4gIGVuZE9mSVNPV2VlazogcmVxdWlyZSgnLi9lbmRfb2ZfaXNvX3dlZWsvaW5kZXguanMnKSxcbiAgZW5kT2ZJU09ZZWFyOiByZXF1aXJlKCcuL2VuZF9vZl9pc29feWVhci9pbmRleC5qcycpLFxuICBlbmRPZk1pbnV0ZTogcmVxdWlyZSgnLi9lbmRfb2ZfbWludXRlL2luZGV4LmpzJyksXG4gIGVuZE9mTW9udGg6IHJlcXVpcmUoJy4vZW5kX29mX21vbnRoL2luZGV4LmpzJyksXG4gIGVuZE9mUXVhcnRlcjogcmVxdWlyZSgnLi9lbmRfb2ZfcXVhcnRlci9pbmRleC5qcycpLFxuICBlbmRPZlNlY29uZDogcmVxdWlyZSgnLi9lbmRfb2Zfc2Vjb25kL2luZGV4LmpzJyksXG4gIGVuZE9mVG9kYXk6IHJlcXVpcmUoJy4vZW5kX29mX3RvZGF5L2luZGV4LmpzJyksXG4gIGVuZE9mVG9tb3Jyb3c6IHJlcXVpcmUoJy4vZW5kX29mX3RvbW9ycm93L2luZGV4LmpzJyksXG4gIGVuZE9mV2VlazogcmVxdWlyZSgnLi9lbmRfb2Zfd2Vlay9pbmRleC5qcycpLFxuICBlbmRPZlllYXI6IHJlcXVpcmUoJy4vZW5kX29mX3llYXIvaW5kZXguanMnKSxcbiAgZW5kT2ZZZXN0ZXJkYXk6IHJlcXVpcmUoJy4vZW5kX29mX3llc3RlcmRheS9pbmRleC5qcycpLFxuICBmb3JtYXQ6IHJlcXVpcmUoJy4vZm9ybWF0L2luZGV4LmpzJyksXG4gIGdldERhdGU6IHJlcXVpcmUoJy4vZ2V0X2RhdGUvaW5kZXguanMnKSxcbiAgZ2V0RGF5OiByZXF1aXJlKCcuL2dldF9kYXkvaW5kZXguanMnKSxcbiAgZ2V0RGF5T2ZZZWFyOiByZXF1aXJlKCcuL2dldF9kYXlfb2ZfeWVhci9pbmRleC5qcycpLFxuICBnZXREYXlzSW5Nb250aDogcmVxdWlyZSgnLi9nZXRfZGF5c19pbl9tb250aC9pbmRleC5qcycpLFxuICBnZXREYXlzSW5ZZWFyOiByZXF1aXJlKCcuL2dldF9kYXlzX2luX3llYXIvaW5kZXguanMnKSxcbiAgZ2V0SG91cnM6IHJlcXVpcmUoJy4vZ2V0X2hvdXJzL2luZGV4LmpzJyksXG4gIGdldElTT0RheTogcmVxdWlyZSgnLi9nZXRfaXNvX2RheS9pbmRleC5qcycpLFxuICBnZXRJU09XZWVrOiByZXF1aXJlKCcuL2dldF9pc29fd2Vlay9pbmRleC5qcycpLFxuICBnZXRJU09XZWVrc0luWWVhcjogcmVxdWlyZSgnLi9nZXRfaXNvX3dlZWtzX2luX3llYXIvaW5kZXguanMnKSxcbiAgZ2V0SVNPWWVhcjogcmVxdWlyZSgnLi9nZXRfaXNvX3llYXIvaW5kZXguanMnKSxcbiAgZ2V0TWlsbGlzZWNvbmRzOiByZXF1aXJlKCcuL2dldF9taWxsaXNlY29uZHMvaW5kZXguanMnKSxcbiAgZ2V0TWludXRlczogcmVxdWlyZSgnLi9nZXRfbWludXRlcy9pbmRleC5qcycpLFxuICBnZXRNb250aDogcmVxdWlyZSgnLi9nZXRfbW9udGgvaW5kZXguanMnKSxcbiAgZ2V0T3ZlcmxhcHBpbmdEYXlzSW5SYW5nZXM6IHJlcXVpcmUoJy4vZ2V0X292ZXJsYXBwaW5nX2RheXNfaW5fcmFuZ2VzL2luZGV4LmpzJyksXG4gIGdldFF1YXJ0ZXI6IHJlcXVpcmUoJy4vZ2V0X3F1YXJ0ZXIvaW5kZXguanMnKSxcbiAgZ2V0U2Vjb25kczogcmVxdWlyZSgnLi9nZXRfc2Vjb25kcy9pbmRleC5qcycpLFxuICBnZXRUaW1lOiByZXF1aXJlKCcuL2dldF90aW1lL2luZGV4LmpzJyksXG4gIGdldFllYXI6IHJlcXVpcmUoJy4vZ2V0X3llYXIvaW5kZXguanMnKSxcbiAgaXNBZnRlcjogcmVxdWlyZSgnLi9pc19hZnRlci9pbmRleC5qcycpLFxuICBpc0JlZm9yZTogcmVxdWlyZSgnLi9pc19iZWZvcmUvaW5kZXguanMnKSxcbiAgaXNEYXRlOiByZXF1aXJlKCcuL2lzX2RhdGUvaW5kZXguanMnKSxcbiAgaXNFcXVhbDogcmVxdWlyZSgnLi9pc19lcXVhbC9pbmRleC5qcycpLFxuICBpc0ZpcnN0RGF5T2ZNb250aDogcmVxdWlyZSgnLi9pc19maXJzdF9kYXlfb2ZfbW9udGgvaW5kZXguanMnKSxcbiAgaXNGcmlkYXk6IHJlcXVpcmUoJy4vaXNfZnJpZGF5L2luZGV4LmpzJyksXG4gIGlzRnV0dXJlOiByZXF1aXJlKCcuL2lzX2Z1dHVyZS9pbmRleC5qcycpLFxuICBpc0xhc3REYXlPZk1vbnRoOiByZXF1aXJlKCcuL2lzX2xhc3RfZGF5X29mX21vbnRoL2luZGV4LmpzJyksXG4gIGlzTGVhcFllYXI6IHJlcXVpcmUoJy4vaXNfbGVhcF95ZWFyL2luZGV4LmpzJyksXG4gIGlzTW9uZGF5OiByZXF1aXJlKCcuL2lzX21vbmRheS9pbmRleC5qcycpLFxuICBpc1Bhc3Q6IHJlcXVpcmUoJy4vaXNfcGFzdC9pbmRleC5qcycpLFxuICBpc1NhbWVEYXk6IHJlcXVpcmUoJy4vaXNfc2FtZV9kYXkvaW5kZXguanMnKSxcbiAgaXNTYW1lSG91cjogcmVxdWlyZSgnLi9pc19zYW1lX2hvdXIvaW5kZXguanMnKSxcbiAgaXNTYW1lSVNPV2VlazogcmVxdWlyZSgnLi9pc19zYW1lX2lzb193ZWVrL2luZGV4LmpzJyksXG4gIGlzU2FtZUlTT1llYXI6IHJlcXVpcmUoJy4vaXNfc2FtZV9pc29feWVhci9pbmRleC5qcycpLFxuICBpc1NhbWVNaW51dGU6IHJlcXVpcmUoJy4vaXNfc2FtZV9taW51dGUvaW5kZXguanMnKSxcbiAgaXNTYW1lTW9udGg6IHJlcXVpcmUoJy4vaXNfc2FtZV9tb250aC9pbmRleC5qcycpLFxuICBpc1NhbWVRdWFydGVyOiByZXF1aXJlKCcuL2lzX3NhbWVfcXVhcnRlci9pbmRleC5qcycpLFxuICBpc1NhbWVTZWNvbmQ6IHJlcXVpcmUoJy4vaXNfc2FtZV9zZWNvbmQvaW5kZXguanMnKSxcbiAgaXNTYW1lV2VlazogcmVxdWlyZSgnLi9pc19zYW1lX3dlZWsvaW5kZXguanMnKSxcbiAgaXNTYW1lWWVhcjogcmVxdWlyZSgnLi9pc19zYW1lX3llYXIvaW5kZXguanMnKSxcbiAgaXNTYXR1cmRheTogcmVxdWlyZSgnLi9pc19zYXR1cmRheS9pbmRleC5qcycpLFxuICBpc1N1bmRheTogcmVxdWlyZSgnLi9pc19zdW5kYXkvaW5kZXguanMnKSxcbiAgaXNUaGlzSG91cjogcmVxdWlyZSgnLi9pc190aGlzX2hvdXIvaW5kZXguanMnKSxcbiAgaXNUaGlzSVNPV2VlazogcmVxdWlyZSgnLi9pc190aGlzX2lzb193ZWVrL2luZGV4LmpzJyksXG4gIGlzVGhpc0lTT1llYXI6IHJlcXVpcmUoJy4vaXNfdGhpc19pc29feWVhci9pbmRleC5qcycpLFxuICBpc1RoaXNNaW51dGU6IHJlcXVpcmUoJy4vaXNfdGhpc19taW51dGUvaW5kZXguanMnKSxcbiAgaXNUaGlzTW9udGg6IHJlcXVpcmUoJy4vaXNfdGhpc19tb250aC9pbmRleC5qcycpLFxuICBpc1RoaXNRdWFydGVyOiByZXF1aXJlKCcuL2lzX3RoaXNfcXVhcnRlci9pbmRleC5qcycpLFxuICBpc1RoaXNTZWNvbmQ6IHJlcXVpcmUoJy4vaXNfdGhpc19zZWNvbmQvaW5kZXguanMnKSxcbiAgaXNUaGlzV2VlazogcmVxdWlyZSgnLi9pc190aGlzX3dlZWsvaW5kZXguanMnKSxcbiAgaXNUaGlzWWVhcjogcmVxdWlyZSgnLi9pc190aGlzX3llYXIvaW5kZXguanMnKSxcbiAgaXNUaHVyc2RheTogcmVxdWlyZSgnLi9pc190aHVyc2RheS9pbmRleC5qcycpLFxuICBpc1RvZGF5OiByZXF1aXJlKCcuL2lzX3RvZGF5L2luZGV4LmpzJyksXG4gIGlzVG9tb3Jyb3c6IHJlcXVpcmUoJy4vaXNfdG9tb3Jyb3cvaW5kZXguanMnKSxcbiAgaXNUdWVzZGF5OiByZXF1aXJlKCcuL2lzX3R1ZXNkYXkvaW5kZXguanMnKSxcbiAgaXNWYWxpZDogcmVxdWlyZSgnLi9pc192YWxpZC9pbmRleC5qcycpLFxuICBpc1dlZG5lc2RheTogcmVxdWlyZSgnLi9pc193ZWRuZXNkYXkvaW5kZXguanMnKSxcbiAgaXNXZWVrZW5kOiByZXF1aXJlKCcuL2lzX3dlZWtlbmQvaW5kZXguanMnKSxcbiAgaXNXaXRoaW5SYW5nZTogcmVxdWlyZSgnLi9pc193aXRoaW5fcmFuZ2UvaW5kZXguanMnKSxcbiAgaXNZZXN0ZXJkYXk6IHJlcXVpcmUoJy4vaXNfeWVzdGVyZGF5L2luZGV4LmpzJyksXG4gIGxhc3REYXlPZklTT1dlZWs6IHJlcXVpcmUoJy4vbGFzdF9kYXlfb2ZfaXNvX3dlZWsvaW5kZXguanMnKSxcbiAgbGFzdERheU9mSVNPWWVhcjogcmVxdWlyZSgnLi9sYXN0X2RheV9vZl9pc29feWVhci9pbmRleC5qcycpLFxuICBsYXN0RGF5T2ZNb250aDogcmVxdWlyZSgnLi9sYXN0X2RheV9vZl9tb250aC9pbmRleC5qcycpLFxuICBsYXN0RGF5T2ZRdWFydGVyOiByZXF1aXJlKCcuL2xhc3RfZGF5X29mX3F1YXJ0ZXIvaW5kZXguanMnKSxcbiAgbGFzdERheU9mV2VlazogcmVxdWlyZSgnLi9sYXN0X2RheV9vZl93ZWVrL2luZGV4LmpzJyksXG4gIGxhc3REYXlPZlllYXI6IHJlcXVpcmUoJy4vbGFzdF9kYXlfb2ZfeWVhci9pbmRleC5qcycpLFxuICBtYXg6IHJlcXVpcmUoJy4vbWF4L2luZGV4LmpzJyksXG4gIG1pbjogcmVxdWlyZSgnLi9taW4vaW5kZXguanMnKSxcbiAgcGFyc2U6IHJlcXVpcmUoJy4vcGFyc2UvaW5kZXguanMnKSxcbiAgc2V0RGF0ZTogcmVxdWlyZSgnLi9zZXRfZGF0ZS9pbmRleC5qcycpLFxuICBzZXREYXk6IHJlcXVpcmUoJy4vc2V0X2RheS9pbmRleC5qcycpLFxuICBzZXREYXlPZlllYXI6IHJlcXVpcmUoJy4vc2V0X2RheV9vZl95ZWFyL2luZGV4LmpzJyksXG4gIHNldEhvdXJzOiByZXF1aXJlKCcuL3NldF9ob3Vycy9pbmRleC5qcycpLFxuICBzZXRJU09EYXk6IHJlcXVpcmUoJy4vc2V0X2lzb19kYXkvaW5kZXguanMnKSxcbiAgc2V0SVNPV2VlazogcmVxdWlyZSgnLi9zZXRfaXNvX3dlZWsvaW5kZXguanMnKSxcbiAgc2V0SVNPWWVhcjogcmVxdWlyZSgnLi9zZXRfaXNvX3llYXIvaW5kZXguanMnKSxcbiAgc2V0TWlsbGlzZWNvbmRzOiByZXF1aXJlKCcuL3NldF9taWxsaXNlY29uZHMvaW5kZXguanMnKSxcbiAgc2V0TWludXRlczogcmVxdWlyZSgnLi9zZXRfbWludXRlcy9pbmRleC5qcycpLFxuICBzZXRNb250aDogcmVxdWlyZSgnLi9zZXRfbW9udGgvaW5kZXguanMnKSxcbiAgc2V0UXVhcnRlcjogcmVxdWlyZSgnLi9zZXRfcXVhcnRlci9pbmRleC5qcycpLFxuICBzZXRTZWNvbmRzOiByZXF1aXJlKCcuL3NldF9zZWNvbmRzL2luZGV4LmpzJyksXG4gIHNldFllYXI6IHJlcXVpcmUoJy4vc2V0X3llYXIvaW5kZXguanMnKSxcbiAgc3RhcnRPZkRheTogcmVxdWlyZSgnLi9zdGFydF9vZl9kYXkvaW5kZXguanMnKSxcbiAgc3RhcnRPZkhvdXI6IHJlcXVpcmUoJy4vc3RhcnRfb2ZfaG91ci9pbmRleC5qcycpLFxuICBzdGFydE9mSVNPV2VlazogcmVxdWlyZSgnLi9zdGFydF9vZl9pc29fd2Vlay9pbmRleC5qcycpLFxuICBzdGFydE9mSVNPWWVhcjogcmVxdWlyZSgnLi9zdGFydF9vZl9pc29feWVhci9pbmRleC5qcycpLFxuICBzdGFydE9mTWludXRlOiByZXF1aXJlKCcuL3N0YXJ0X29mX21pbnV0ZS9pbmRleC5qcycpLFxuICBzdGFydE9mTW9udGg6IHJlcXVpcmUoJy4vc3RhcnRfb2ZfbW9udGgvaW5kZXguanMnKSxcbiAgc3RhcnRPZlF1YXJ0ZXI6IHJlcXVpcmUoJy4vc3RhcnRfb2ZfcXVhcnRlci9pbmRleC5qcycpLFxuICBzdGFydE9mU2Vjb25kOiByZXF1aXJlKCcuL3N0YXJ0X29mX3NlY29uZC9pbmRleC5qcycpLFxuICBzdGFydE9mVG9kYXk6IHJlcXVpcmUoJy4vc3RhcnRfb2ZfdG9kYXkvaW5kZXguanMnKSxcbiAgc3RhcnRPZlRvbW9ycm93OiByZXF1aXJlKCcuL3N0YXJ0X29mX3RvbW9ycm93L2luZGV4LmpzJyksXG4gIHN0YXJ0T2ZXZWVrOiByZXF1aXJlKCcuL3N0YXJ0X29mX3dlZWsvaW5kZXguanMnKSxcbiAgc3RhcnRPZlllYXI6IHJlcXVpcmUoJy4vc3RhcnRfb2ZfeWVhci9pbmRleC5qcycpLFxuICBzdGFydE9mWWVzdGVyZGF5OiByZXF1aXJlKCcuL3N0YXJ0X29mX3llc3RlcmRheS9pbmRleC5qcycpLFxuICBzdWJEYXlzOiByZXF1aXJlKCcuL3N1Yl9kYXlzL2luZGV4LmpzJyksXG4gIHN1YkhvdXJzOiByZXF1aXJlKCcuL3N1Yl9ob3Vycy9pbmRleC5qcycpLFxuICBzdWJJU09ZZWFyczogcmVxdWlyZSgnLi9zdWJfaXNvX3llYXJzL2luZGV4LmpzJyksXG4gIHN1Yk1pbGxpc2Vjb25kczogcmVxdWlyZSgnLi9zdWJfbWlsbGlzZWNvbmRzL2luZGV4LmpzJyksXG4gIHN1Yk1pbnV0ZXM6IHJlcXVpcmUoJy4vc3ViX21pbnV0ZXMvaW5kZXguanMnKSxcbiAgc3ViTW9udGhzOiByZXF1aXJlKCcuL3N1Yl9tb250aHMvaW5kZXguanMnKSxcbiAgc3ViUXVhcnRlcnM6IHJlcXVpcmUoJy4vc3ViX3F1YXJ0ZXJzL2luZGV4LmpzJyksXG4gIHN1YlNlY29uZHM6IHJlcXVpcmUoJy4vc3ViX3NlY29uZHMvaW5kZXguanMnKSxcbiAgc3ViV2Vla3M6IHJlcXVpcmUoJy4vc3ViX3dlZWtzL2luZGV4LmpzJyksXG4gIHN1YlllYXJzOiByZXF1aXJlKCcuL3N1Yl95ZWFycy9pbmRleC5qcycpXG59XG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var root = require('./_root');
/** Built-in value references. */
var Symbol = root.Symbol;
module.exports = Symbol;
},{"./_root":16}],2:[function(require,module,exports){
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
module.exports = arrayMap;
},{}],3:[function(require,module,exports){
var baseProperty = require('./_baseProperty');
/**
* Gets the size of an ASCII `string`.
*
* @private
* @param {string} string The string inspect.
* @returns {number} Returns the string size.
*/
var asciiSize = baseProperty('length');
module.exports = asciiSize;
},{"./_baseProperty":6}],4:[function(require,module,exports){
/**
* Converts an ASCII `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function asciiToArray(string) {
return string.split('');
}
module.exports = asciiToArray;
},{}],5:[function(require,module,exports){
var Symbol = require('./_Symbol'),
getRawTag = require('./_getRawTag'),
objectToString = require('./_objectToString');
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
module.exports = baseGetTag;
},{"./_Symbol":1,"./_getRawTag":13,"./_objectToString":15}],6:[function(require,module,exports){
/**
* The base implementation of `_.property` without support for deep paths.
*
* @private
* @param {string} key The key of the property to get.
* @returns {Function} Returns the new accessor function.
*/
function baseProperty(key) {
return function(object) {
return object == null ? undefined : object[key];
};
}
module.exports = baseProperty;
},{}],7:[function(require,module,exports){
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeFloor = Math.floor;
/**
* The base implementation of `_.repeat` which doesn't coerce arguments.
*
* @private
* @param {string} string The string to repeat.
* @param {number} n The number of times to repeat the string.
* @returns {string} Returns the repeated string.
*/
function baseRepeat(string, n) {
var result = '';
if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
return result;
}
// Leverage the exponentiation by squaring algorithm for a faster repeat.
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
do {
if (n % 2) {
result += string;
}
n = nativeFloor(n / 2);
if (n) {
string += string;
}
} while (n);
return result;
}
module.exports = baseRepeat;
},{}],8:[function(require,module,exports){
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
module.exports = baseSlice;
},{}],9:[function(require,module,exports){
var Symbol = require('./_Symbol'),
arrayMap = require('./_arrayMap'),
isArray = require('./isArray'),
isSymbol = require('./isSymbol');
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isArray(value)) {
// Recursively convert values (susceptible to call stack limits).
return arrayMap(value, baseToString) + '';
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
module.exports = baseToString;
},{"./_Symbol":1,"./_arrayMap":2,"./isArray":21,"./isSymbol":24}],10:[function(require,module,exports){
var baseSlice = require('./_baseSlice');
/**
* Casts `array` to a slice if it's needed.
*
* @private
* @param {Array} array The array to inspect.
* @param {number} start The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the cast slice.
*/
function castSlice(array, start, end) {
var length = array.length;
end = end === undefined ? length : end;
return (!start && end >= length) ? array : baseSlice(array, start, end);
}
module.exports = castSlice;
},{"./_baseSlice":8}],11:[function(require,module,exports){
var baseRepeat = require('./_baseRepeat'),
baseToString = require('./_baseToString'),
castSlice = require('./_castSlice'),
hasUnicode = require('./_hasUnicode'),
stringSize = require('./_stringSize'),
stringToArray = require('./_stringToArray');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil;
/**
* Creates the padding for `string` based on `length`. The `chars` string
* is truncated if the number of characters exceeds `length`.
*
* @private
* @param {number} length The padding length.
* @param {string} [chars=' '] The string used as padding.
* @returns {string} Returns the padding for `string`.
*/
function createPadding(length, chars) {
chars = chars === undefined ? ' ' : baseToString(chars);
var charsLength = chars.length;
if (charsLength < 2) {
return charsLength ? baseRepeat(chars, length) : chars;
}
var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
return hasUnicode(chars)
? castSlice(stringToArray(result), 0, length).join('')
: result.slice(0, length);
}
module.exports = createPadding;
},{"./_baseRepeat":7,"./_baseToString":9,"./_castSlice":10,"./_hasUnicode":14,"./_stringSize":17,"./_stringToArray":18}],12:[function(require,module,exports){
(function (global){
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
module.exports = freeGlobal;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],13:[function(require,module,exports){
var Symbol = require('./_Symbol');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag),
tag = value[symToStringTag];
try {
value[symToStringTag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag] = tag;
} else {
delete value[symToStringTag];
}
}
return result;
}
module.exports = getRawTag;
},{"./_Symbol":1}],14:[function(require,module,exports){
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
rsComboMarksRange = '\\u0300-\\u036f',
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
rsComboSymbolsRange = '\\u20d0-\\u20ff',
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsZWJ = '\\u200d';
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
/**
* Checks if `string` contains Unicode symbols.
*
* @private
* @param {string} string The string to inspect.
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
*/
function hasUnicode(string) {
return reHasUnicode.test(string);
}
module.exports = hasUnicode;
},{}],15:[function(require,module,exports){
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
module.exports = objectToString;
},{}],16:[function(require,module,exports){
var freeGlobal = require('./_freeGlobal');
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
module.exports = root;
},{"./_freeGlobal":12}],17:[function(require,module,exports){
var asciiSize = require('./_asciiSize'),
hasUnicode = require('./_hasUnicode'),
unicodeSize = require('./_unicodeSize');
/**
* Gets the number of symbols in `string`.
*
* @private
* @param {string} string The string to inspect.
* @returns {number} Returns the string size.
*/
function stringSize(string) {
return hasUnicode(string)
? unicodeSize(string)
: asciiSize(string);
}
module.exports = stringSize;
},{"./_asciiSize":3,"./_hasUnicode":14,"./_unicodeSize":19}],18:[function(require,module,exports){
var asciiToArray = require('./_asciiToArray'),
hasUnicode = require('./_hasUnicode'),
unicodeToArray = require('./_unicodeToArray');
/**
* Converts `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function stringToArray(string) {
return hasUnicode(string)
? unicodeToArray(string)
: asciiToArray(string);
}
module.exports = stringToArray;
},{"./_asciiToArray":4,"./_hasUnicode":14,"./_unicodeToArray":20}],19:[function(require,module,exports){
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
rsComboMarksRange = '\\u0300-\\u036f',
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
rsComboSymbolsRange = '\\u20d0-\\u20ff',
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsAstral = '[' + rsAstralRange + ']',
rsCombo = '[' + rsComboRange + ']',
rsFitz = '\\ud83c[\\udffb-\\udfff]',
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
rsZWJ = '\\u200d';
/** Used to compose unicode regexes. */
var reOptMod = rsModifier + '?',
rsOptVar = '[' + rsVarRange + ']?',
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
rsSeq = rsOptVar + reOptMod + rsOptJoin,
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/**
* Gets the size of a Unicode `string`.
*
* @private
* @param {string} string The string inspect.
* @returns {number} Returns the string size.
*/
function unicodeSize(string) {
var result = reUnicode.lastIndex = 0;
while (reUnicode.test(string)) {
++result;
}
return result;
}
module.exports = unicodeSize;
},{}],20:[function(require,module,exports){
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
rsComboMarksRange = '\\u0300-\\u036f',
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
rsComboSymbolsRange = '\\u20d0-\\u20ff',
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsAstral = '[' + rsAstralRange + ']',
rsCombo = '[' + rsComboRange + ']',
rsFitz = '\\ud83c[\\udffb-\\udfff]',
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
rsZWJ = '\\u200d';
/** Used to compose unicode regexes. */
var reOptMod = rsModifier + '?',
rsOptVar = '[' + rsVarRange + ']?',
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
rsSeq = rsOptVar + reOptMod + rsOptJoin,
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/**
* Converts a Unicode `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function unicodeToArray(string) {
return string.match(reUnicode) || [];
}
module.exports = unicodeToArray;
},{}],21:[function(require,module,exports){
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
module.exports = isArray;
},{}],22:[function(require,module,exports){
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
module.exports = isObject;
},{}],23:[function(require,module,exports){
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
module.exports = isObjectLike;
},{}],24:[function(require,module,exports){
var baseGetTag = require('./_baseGetTag'),
isObjectLike = require('./isObjectLike');
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
module.exports = isSymbol;
},{"./_baseGetTag":5,"./isObjectLike":23}],25:[function(require,module,exports){
var toNumber = require('./toNumber');
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0,
MAX_INTEGER = 1.7976931348623157e+308;
/**
* Converts `value` to a finite number.
*
* @static
* @memberOf _
* @since 4.12.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted number.
* @example
*
* _.toFinite(3.2);
* // => 3.2
*
* _.toFinite(Number.MIN_VALUE);
* // => 5e-324
*
* _.toFinite(Infinity);
* // => 1.7976931348623157e+308
*
* _.toFinite('3.2');
* // => 3.2
*/
function toFinite(value) {
if (!value) {
return value === 0 ? value : 0;
}
value = toNumber(value);
if (value === INFINITY || value === -INFINITY) {
var sign = (value < 0 ? -1 : 1);
return sign * MAX_INTEGER;
}
return value === value ? value : 0;
}
module.exports = toFinite;
},{"./toNumber":27}],26:[function(require,module,exports){
var toFinite = require('./toFinite');
/**
* Converts `value` to an integer.
*
* **Note:** This method is loosely based on
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
* @example
*
* _.toInteger(3.2);
* // => 3
*
* _.toInteger(Number.MIN_VALUE);
* // => 0
*
* _.toInteger(Infinity);
* // => 1.7976931348623157e+308
*
* _.toInteger('3.2');
* // => 3
*/
function toInteger(value) {
var result = toFinite(value),
remainder = result % 1;
return result === result ? (remainder ? result - remainder : result) : 0;
}
module.exports = toInteger;
},{"./toFinite":25}],27:[function(require,module,exports){
var isObject = require('./isObject'),
isSymbol = require('./isSymbol');
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
module.exports = toNumber;
},{"./isObject":22,"./isSymbol":24}],28:[function(require,module,exports){
var baseToString = require('./_baseToString');
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
module.exports = toString;
},{"./_baseToString":9}],"lodash/padStart":[function(require,module,exports){
var createPadding = require('./_createPadding'),
stringSize = require('./_stringSize'),
toInteger = require('./toInteger'),
toString = require('./toString');
/**
* Pads `string` on the left side if it's shorter than `length`. Padding
* characters are truncated if they exceed `length`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category String
* @param {string} [string=''] The string to pad.
* @param {number} [length=0] The padding length.
* @param {string} [chars=' '] The string used as padding.
* @returns {string} Returns the padded string.
* @example
*
* _.padStart('abc', 6);
* // => ' abc'
*
* _.padStart('abc', 6, '_-');
* // => '_-_abc'
*
* _.padStart('abc', 3);
* // => 'abc'
*/
function padStart(string, length, chars) {
string = toString(string);
length = toInteger(length);
var strLength = length ? stringSize(string) : 0;
return (length && strLength < length)
? (createPadding(length - strLength, chars) + string)
: string;
}
module.exports = padStart;
},{"./_createPadding":11,"./_stringSize":17,"./toInteger":26,"./toString":28}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIl9TeW1ib2wuanMiLCJfYXJyYXlNYXAuanMiLCJfYXNjaWlTaXplLmpzIiwiX2FzY2lpVG9BcnJheS5qcyIsIl9iYXNlR2V0VGFnLmpzIiwiX2Jhc2VQcm9wZXJ0eS5qcyIsIl9iYXNlUmVwZWF0LmpzIiwiX2Jhc2VTbGljZS5qcyIsIl9iYXNlVG9TdHJpbmcuanMiLCJfY2FzdFNsaWNlLmpzIiwiX2NyZWF0ZVBhZGRpbmcuanMiLCJfZnJlZUdsb2JhbC5qcyIsIl9nZXRSYXdUYWcuanMiLCJfaGFzVW5pY29kZS5qcyIsIl9vYmplY3RUb1N0cmluZy5qcyIsIl9yb290LmpzIiwiX3N0cmluZ1NpemUuanMiLCJfc3RyaW5nVG9BcnJheS5qcyIsIl91bmljb2RlU2l6ZS5qcyIsIl91bmljb2RlVG9BcnJheS5qcyIsImlzQXJyYXkuanMiLCJpc09iamVjdC5qcyIsImlzT2JqZWN0TGlrZS5qcyIsImlzU3ltYm9sLmpzIiwidG9GaW5pdGUuanMiLCJ0b0ludGVnZXIuanMiLCJ0b051bWJlci5qcyIsInRvU3RyaW5nLmpzIiwibG9kYXNoL3BhZFN0YXJ0Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgU3ltYm9sID0gcm9vdC5TeW1ib2w7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ltYm9sO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAqIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheU1hcDtcbiIsInZhciBiYXNlUHJvcGVydHkgPSByZXF1aXJlKCcuL19iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBzaXplIG9mIGFuIEFTQ0lJIGBzdHJpbmdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLlxuICovXG52YXIgYXNjaWlTaXplID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBhc2NpaVNpemU7XG4iLCIvKipcbiAqIENvbnZlcnRzIGFuIEFTQ0lJIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhc2NpaVRvQXJyYXkoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcuc3BsaXQoJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFzY2lpVG9BcnJheTtcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBnZXRSYXdUYWcgPSByZXF1aXJlKCcuL19nZXRSYXdUYWcnKSxcbiAgICBvYmplY3RUb1N0cmluZyA9IHJlcXVpcmUoJy4vX29iamVjdFRvU3RyaW5nJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBudWxsVGFnID0gJ1tvYmplY3QgTnVsbF0nLFxuICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0VGFnYCB3aXRob3V0IGZhbGxiYWNrcyBmb3IgYnVnZ3kgZW52aXJvbm1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRUYWcodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7XG4gIH1cbiAgcmV0dXJuIChzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpKVxuICAgID8gZ2V0UmF3VGFnKHZhbHVlKVxuICAgIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VHZXRUYWc7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcbiIsIi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlRmxvb3IgPSBNYXRoLmZsb29yO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlcGVhdGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byByZXBlYXQgdGhlIHN0cmluZy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gYmFzZVJlcGVhdChzdHJpbmcsIG4pIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICBpZiAoIXN0cmluZyB8fCBuIDwgMSB8fCBuID4gTUFYX1NBRkVfSU5URUdFUikge1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLy8gTGV2ZXJhZ2UgdGhlIGV4cG9uZW50aWF0aW9uIGJ5IHNxdWFyaW5nIGFsZ29yaXRobSBmb3IgYSBmYXN0ZXIgcmVwZWF0LlxuICAvLyBTZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRXhwb25lbnRpYXRpb25fYnlfc3F1YXJpbmcgZm9yIG1vcmUgZGV0YWlscy5cbiAgZG8ge1xuICAgIGlmIChuICUgMikge1xuICAgICAgcmVzdWx0ICs9IHN0cmluZztcbiAgICB9XG4gICAgbiA9IG5hdGl2ZUZsb29yKG4gLyAyKTtcbiAgICBpZiAobikge1xuICAgICAgc3RyaW5nICs9IHN0cmluZztcbiAgICB9XG4gIH0gd2hpbGUgKG4pO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVJlcGVhdDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgfVxuICBlbmQgPSBlbmQgPiBsZW5ndGggPyBsZW5ndGggOiBlbmQ7XG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlbmd0aDtcbiAgfVxuICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gIHN0YXJ0ID4+Pj0gMDtcblxuICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXggKyBzdGFydF07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2xpY2U7XG4iLCJ2YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fU3ltYm9sJyksXG4gICAgYXJyYXlNYXAgPSByZXF1aXJlKCcuL19hcnJheU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc1N5bWJvbCA9IHJlcXVpcmUoJy4vaXNTeW1ib2wnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgSU5GSU5JVFkgPSAxIC8gMDtcblxuLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovXG52YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wgPyBTeW1ib2wucHJvdG90eXBlIDogdW5kZWZpbmVkLFxuICAgIHN5bWJvbFRvU3RyaW5nID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by50b1N0cmluZyA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1N0cmluZ2Agd2hpY2ggZG9lc24ndCBjb252ZXJ0IG51bGxpc2hcbiAqIHZhbHVlcyB0byBlbXB0eSBzdHJpbmdzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBiYXNlVG9TdHJpbmcodmFsdWUpIHtcbiAgLy8gRXhpdCBlYXJseSBmb3Igc3RyaW5ncyB0byBhdm9pZCBhIHBlcmZvcm1hbmNlIGhpdCBpbiBzb21lIGVudmlyb25tZW50cy5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAvLyBSZWN1cnNpdmVseSBjb252ZXJ0IHZhbHVlcyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgYmFzZVRvU3RyaW5nKSArICcnO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gc3ltYm9sVG9TdHJpbmcgPyBzeW1ib2xUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnO1xuICB9XG4gIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gIHJldHVybiAocmVzdWx0ID09ICcwJyAmJiAoMSAvIHZhbHVlKSA9PSAtSU5GSU5JVFkpID8gJy0wJyA6IHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVG9TdHJpbmc7XG4iLCJ2YXIgYmFzZVNsaWNlID0gcmVxdWlyZSgnLi9fYmFzZVNsaWNlJyk7XG5cbi8qKlxuICogQ2FzdHMgYGFycmF5YCB0byBhIHNsaWNlIGlmIGl0J3MgbmVlZGVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3Qgc2xpY2UuXG4gKi9cbmZ1bmN0aW9uIGNhc3RTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IGVuZDtcbiAgcmV0dXJuICghc3RhcnQgJiYgZW5kID49IGxlbmd0aCkgPyBhcnJheSA6IGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FzdFNsaWNlO1xuIiwidmFyIGJhc2VSZXBlYXQgPSByZXF1aXJlKCcuL19iYXNlUmVwZWF0JyksXG4gICAgYmFzZVRvU3RyaW5nID0gcmVxdWlyZSgnLi9fYmFzZVRvU3RyaW5nJyksXG4gICAgY2FzdFNsaWNlID0gcmVxdWlyZSgnLi9fY2FzdFNsaWNlJyksXG4gICAgaGFzVW5pY29kZSA9IHJlcXVpcmUoJy4vX2hhc1VuaWNvZGUnKSxcbiAgICBzdHJpbmdTaXplID0gcmVxdWlyZSgnLi9fc3RyaW5nU2l6ZScpLFxuICAgIHN0cmluZ1RvQXJyYXkgPSByZXF1aXJlKCcuL19zdHJpbmdUb0FycmF5Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVDZWlsID0gTWF0aC5jZWlsO1xuXG4vKipcbiAqIENyZWF0ZXMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgIGJhc2VkIG9uIGBsZW5ndGhgLiBUaGUgYGNoYXJzYCBzdHJpbmdcbiAqIGlzIHRydW5jYXRlZCBpZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZXhjZWVkcyBgbGVuZ3RoYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgcGFkZGluZyBsZW5ndGguXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkaW5nIGZvciBgc3RyaW5nYC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFkZGluZyhsZW5ndGgsIGNoYXJzKSB7XG4gIGNoYXJzID0gY2hhcnMgPT09IHVuZGVmaW5lZCA/ICcgJyA6IGJhc2VUb1N0cmluZyhjaGFycyk7XG5cbiAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICBpZiAoY2hhcnNMZW5ndGggPCAyKSB7XG4gICAgcmV0dXJuIGNoYXJzTGVuZ3RoID8gYmFzZVJlcGVhdChjaGFycywgbGVuZ3RoKSA6IGNoYXJzO1xuICB9XG4gIHZhciByZXN1bHQgPSBiYXNlUmVwZWF0KGNoYXJzLCBuYXRpdmVDZWlsKGxlbmd0aCAvIHN0cmluZ1NpemUoY2hhcnMpKSk7XG4gIHJldHVybiBoYXNVbmljb2RlKGNoYXJzKVxuICAgID8gY2FzdFNsaWNlKHN0cmluZ1RvQXJyYXkocmVzdWx0KSwgMCwgbGVuZ3RoKS5qb2luKCcnKVxuICAgIDogcmVzdWx0LnNsaWNlKDAsIGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUGFkZGluZztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlXG4gKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHN5bVRvU3RyaW5nVGFnID0gU3ltYm9sID8gU3ltYm9sLnRvU3RyaW5nVGFnIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUdldFRhZ2Agd2hpY2ggaWdub3JlcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmF3IGB0b1N0cmluZ1RhZ2AuXG4gKi9cbmZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkge1xuICB2YXIgaXNPd24gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyksXG4gICAgICB0YWcgPSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG5cbiAgdHJ5IHtcbiAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB1bmRlZmluZWQ7XG4gICAgdmFyIHVubWFza2VkID0gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge31cblxuICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIGlmICh1bm1hc2tlZCkge1xuICAgIGlmIChpc093bikge1xuICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdGFnO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFJhd1RhZztcbiIsIi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbnZhciByc0FzdHJhbFJhbmdlID0gJ1xcXFx1ZDgwMC1cXFxcdWRmZmYnLFxuICAgIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcXFx1MDMwMC1cXFxcdTAzNmYnLFxuICAgIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXFxcdWZlMjAtXFxcXHVmZTJmJyxcbiAgICByc0NvbWJvU3ltYm9sc1JhbmdlID0gJ1xcXFx1MjBkMC1cXFxcdTIwZmYnLFxuICAgIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSxcbiAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZic7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi9cbnZhciByc1pXSiA9ICdcXFxcdTIwMGQnO1xuXG4vKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB3aXRoIFt6ZXJvLXdpZHRoIGpvaW5lcnMgb3IgY29kZSBwb2ludHMgZnJvbSB0aGUgYXN0cmFsIHBsYW5lc10oaHR0cDovL2Vldi5lZS9ibG9nLzIwMTUvMDkvMTIvZGFyay1jb3JuZXJzLW9mLXVuaWNvZGUvKS4gKi9cbnZhciByZUhhc1VuaWNvZGUgPSBSZWdFeHAoJ1snICsgcnNaV0ogKyByc0FzdHJhbFJhbmdlICArIHJzQ29tYm9SYW5nZSArIHJzVmFyUmFuZ2UgKyAnXScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgc3RyaW5nYCBjb250YWlucyBVbmljb2RlIHN5bWJvbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGEgc3ltYm9sIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGhhc1VuaWNvZGUoc3RyaW5nKSB7XG4gIHJldHVybiByZUhhc1VuaWNvZGUudGVzdChzdHJpbmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc1VuaWNvZGU7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3RUb1N0cmluZztcbiIsInZhciBmcmVlR2xvYmFsID0gcmVxdWlyZSgnLi9fZnJlZUdsb2JhbCcpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gcm9vdDtcbiIsInZhciBhc2NpaVNpemUgPSByZXF1aXJlKCcuL19hc2NpaVNpemUnKSxcbiAgICBoYXNVbmljb2RlID0gcmVxdWlyZSgnLi9faGFzVW5pY29kZScpLFxuICAgIHVuaWNvZGVTaXplID0gcmVxdWlyZSgnLi9fdW5pY29kZVNpemUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBudW1iZXIgb2Ygc3ltYm9scyBpbiBgc3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAqL1xuZnVuY3Rpb24gc3RyaW5nU2l6ZShzdHJpbmcpIHtcbiAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgID8gdW5pY29kZVNpemUoc3RyaW5nKVxuICAgIDogYXNjaWlTaXplKHN0cmluZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RyaW5nU2l6ZTtcbiIsInZhciBhc2NpaVRvQXJyYXkgPSByZXF1aXJlKCcuL19hc2NpaVRvQXJyYXknKSxcbiAgICBoYXNVbmljb2RlID0gcmVxdWlyZSgnLi9faGFzVW5pY29kZScpLFxuICAgIHVuaWNvZGVUb0FycmF5ID0gcmVxdWlyZSgnLi9fdW5pY29kZVRvQXJyYXknKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gc3RyaW5nVG9BcnJheShzdHJpbmcpIHtcbiAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgID8gdW5pY29kZVRvQXJyYXkoc3RyaW5nKVxuICAgIDogYXNjaWlUb0FycmF5KHN0cmluZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RyaW5nVG9BcnJheTtcbiIsIi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbnZhciByc0FzdHJhbFJhbmdlID0gJ1xcXFx1ZDgwMC1cXFxcdWRmZmYnLFxuICAgIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcXFx1MDMwMC1cXFxcdTAzNmYnLFxuICAgIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXFxcdWZlMjAtXFxcXHVmZTJmJyxcbiAgICByc0NvbWJvU3ltYm9sc1JhbmdlID0gJ1xcXFx1MjBkMC1cXFxcdTIwZmYnLFxuICAgIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSxcbiAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZic7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi9cbnZhciByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJyxcbiAgICByc0ZpdHogPSAnXFxcXHVkODNjW1xcXFx1ZGZmYi1cXFxcdWRmZmZdJyxcbiAgICByc01vZGlmaWVyID0gJyg/OicgKyByc0NvbWJvICsgJ3wnICsgcnNGaXR6ICsgJyknLFxuICAgIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgcnNSZWdpb25hbCA9ICcoPzpcXFxcdWQ4M2NbXFxcXHVkZGU2LVxcXFx1ZGRmZl0pezJ9JyxcbiAgICByc1N1cnJQYWlyID0gJ1tcXFxcdWQ4MDAtXFxcXHVkYmZmXVtcXFxcdWRjMDAtXFxcXHVkZmZmXScsXG4gICAgcnNaV0ogPSAnXFxcXHUyMDBkJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovXG52YXIgcmVPcHRNb2QgPSByc01vZGlmaWVyICsgJz8nLFxuICAgIHJzT3B0VmFyID0gJ1snICsgcnNWYXJSYW5nZSArICddPycsXG4gICAgcnNPcHRKb2luID0gJyg/OicgKyByc1pXSiArICcoPzonICsgW3JzTm9uQXN0cmFsLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc09wdFZhciArIHJlT3B0TW9kICsgJykqJyxcbiAgICByc1NlcSA9IHJzT3B0VmFyICsgcmVPcHRNb2QgKyByc09wdEpvaW4sXG4gICAgcnNTeW1ib2wgPSAnKD86JyArIFtyc05vbkFzdHJhbCArIHJzQ29tYm8gKyAnPycsIHJzQ29tYm8sIHJzUmVnaW9uYWwsIHJzU3VyclBhaXIsIHJzQXN0cmFsXS5qb2luKCd8JykgKyAnKSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIFtzdHJpbmcgc3ltYm9sc10oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtdW5pY29kZSkuICovXG52YXIgcmVVbmljb2RlID0gUmVnRXhwKHJzRml0eiArICcoPz0nICsgcnNGaXR6ICsgJyl8JyArIHJzU3ltYm9sICsgcnNTZXEsICdnJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgc2l6ZSBvZiBhIFVuaWNvZGUgYHN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gKi9cbmZ1bmN0aW9uIHVuaWNvZGVTaXplKHN0cmluZykge1xuICB2YXIgcmVzdWx0ID0gcmVVbmljb2RlLmxhc3RJbmRleCA9IDA7XG4gIHdoaWxlIChyZVVuaWNvZGUudGVzdChzdHJpbmcpKSB7XG4gICAgKytyZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB1bmljb2RlU2l6ZTtcbiIsIi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbnZhciByc0FzdHJhbFJhbmdlID0gJ1xcXFx1ZDgwMC1cXFxcdWRmZmYnLFxuICAgIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcXFx1MDMwMC1cXFxcdTAzNmYnLFxuICAgIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXFxcdWZlMjAtXFxcXHVmZTJmJyxcbiAgICByc0NvbWJvU3ltYm9sc1JhbmdlID0gJ1xcXFx1MjBkMC1cXFxcdTIwZmYnLFxuICAgIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSxcbiAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZic7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi9cbnZhciByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJyxcbiAgICByc0ZpdHogPSAnXFxcXHVkODNjW1xcXFx1ZGZmYi1cXFxcdWRmZmZdJyxcbiAgICByc01vZGlmaWVyID0gJyg/OicgKyByc0NvbWJvICsgJ3wnICsgcnNGaXR6ICsgJyknLFxuICAgIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgcnNSZWdpb25hbCA9ICcoPzpcXFxcdWQ4M2NbXFxcXHVkZGU2LVxcXFx1ZGRmZl0pezJ9JyxcbiAgICByc1N1cnJQYWlyID0gJ1tcXFxcdWQ4MDAtXFxcXHVkYmZmXVtcXFxcdWRjMDAtXFxcXHVkZmZmXScsXG4gICAgcnNaV0ogPSAnXFxcXHUyMDBkJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovXG52YXIgcmVPcHRNb2QgPSByc01vZGlmaWVyICsgJz8nLFxuICAgIHJzT3B0VmFyID0gJ1snICsgcnNWYXJSYW5nZSArICddPycsXG4gICAgcnNPcHRKb2luID0gJyg/OicgKyByc1pXSiArICcoPzonICsgW3JzTm9uQXN0cmFsLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc09wdFZhciArIHJlT3B0TW9kICsgJykqJyxcbiAgICByc1NlcSA9IHJzT3B0VmFyICsgcmVPcHRNb2QgKyByc09wdEpvaW4sXG4gICAgcnNTeW1ib2wgPSAnKD86JyArIFtyc05vbkFzdHJhbCArIHJzQ29tYm8gKyAnPycsIHJzQ29tYm8sIHJzUmVnaW9uYWwsIHJzU3VyclBhaXIsIHJzQXN0cmFsXS5qb2luKCd8JykgKyAnKSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIFtzdHJpbmcgc3ltYm9sc10oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtdW5pY29kZSkuICovXG52YXIgcmVVbmljb2RlID0gUmVnRXhwKHJzRml0eiArICcoPz0nICsgcnNGaXR6ICsgJyl8JyArIHJzU3ltYm9sICsgcnNTZXEsICdnJyk7XG5cbi8qKlxuICogQ29udmVydHMgYSBVbmljb2RlIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiB1bmljb2RlVG9BcnJheShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5tYXRjaChyZVVuaWNvZGUpIHx8IFtdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHVuaWNvZGVUb0FycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3ltYm9sLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3ltYm9sKCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzeW1ib2xUYWcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3ltYm9sO1xuIiwidmFyIHRvTnVtYmVyID0gcmVxdWlyZSgnLi90b051bWJlcicpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEyLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0Zpbml0ZSgzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvRmluaXRlKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b0Zpbml0ZSh2YWx1ZSkge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICB9XG4gIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICB2YXIgc2lnbiA9ICh2YWx1ZSA8IDAgPyAtMSA6IDEpO1xuICAgIHJldHVybiBzaWduICogTUFYX0lOVEVHRVI7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0Zpbml0ZTtcbiIsInZhciB0b0Zpbml0ZSA9IHJlcXVpcmUoJy4vdG9GaW5pdGUnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGludGVnZXIuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9JbnRlZ2VyYF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvaW50ZWdlcikuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0ludGVnZXIoMy4yKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLnRvSW50ZWdlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDBcbiAqXG4gKiBfLnRvSW50ZWdlcihJbmZpbml0eSk7XG4gKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICpcbiAqIF8udG9JbnRlZ2VyKCczLjInKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gdG9JbnRlZ2VyKHZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICByZW1haW5kZXIgPSByZXN1bHQgJSAxO1xuXG4gIHJldHVybiByZXN1bHQgPT09IHJlc3VsdCA/IChyZW1haW5kZXIgPyByZXN1bHQgLSByZW1haW5kZXIgOiByZXN1bHQpIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0ludGVnZXI7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNTeW1ib2wgPSByZXF1aXJlKCcuL2lzU3ltYm9sJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL19iYXNlVG9TdHJpbmcnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYFxuICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvU3RyaW5nKG51bGwpO1xuICogLy8gPT4gJydcbiAqXG4gKiBfLnRvU3RyaW5nKC0wKTtcbiAqIC8vID0+ICctMCdcbiAqXG4gKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAnMSwyLDMnXG4gKi9cbmZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU3RyaW5nO1xuIiwidmFyIGNyZWF0ZVBhZGRpbmcgPSByZXF1aXJlKCcuL19jcmVhdGVQYWRkaW5nJyksXG4gICAgc3RyaW5nU2l6ZSA9IHJlcXVpcmUoJy4vX3N0cmluZ1NpemUnKSxcbiAgICB0b0ludGVnZXIgPSByZXF1aXJlKCcuL3RvSW50ZWdlcicpLFxuICAgIHRvU3RyaW5nID0gcmVxdWlyZSgnLi90b1N0cmluZycpO1xuXG4vKipcbiAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIGxlZnQgc2lkZSBpZiBpdCdzIHNob3J0ZXIgdGhhbiBgbGVuZ3RoYC4gUGFkZGluZ1xuICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBTdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8ucGFkU3RhcnQoJ2FiYycsIDYpO1xuICogLy8gPT4gJyAgIGFiYydcbiAqXG4gKiBfLnBhZFN0YXJ0KCdhYmMnLCA2LCAnXy0nKTtcbiAqIC8vID0+ICdfLV9hYmMnXG4gKlxuICogXy5wYWRTdGFydCgnYWJjJywgMyk7XG4gKiAvLyA9PiAnYWJjJ1xuICovXG5mdW5jdGlvbiBwYWRTdGFydChzdHJpbmcsIGxlbmd0aCwgY2hhcnMpIHtcbiAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgdmFyIHN0ckxlbmd0aCA9IGxlbmd0aCA/IHN0cmluZ1NpemUoc3RyaW5nKSA6IDA7XG4gIHJldHVybiAobGVuZ3RoICYmIHN0ckxlbmd0aCA8IGxlbmd0aClcbiAgICA/IChjcmVhdGVQYWRkaW5nKGxlbmd0aCAtIHN0ckxlbmd0aCwgY2hhcnMpICsgc3RyaW5nKVxuICAgIDogc3RyaW5nO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhZFN0YXJ0O1xuIl19
// Welcome! require() some modules from npm (like you were using browserify)
// and then hit Run Code to run your code on the right side.
// Modules get downloaded from browserify-cdn and bundled in your browser.
const padStart = require('lodash/padStart');
const dateFns = require('date-fns')
const displayValue = "44/1/1";
convertDateDisplayToDateArray = (dateDisplay) => {
return dateDisplay.split('/').reverse().map(item => padStart(item, 2, 0));
}
convertDateDisplayToISO = (dateDisplay) => {
return convertDateDisplayToDateArray(dateDisplay).join('-');
}
convertDateDisplayToDateObject = (dateDisplay) => {
return new Date(...convertDateDisplayToDateArray(dateDisplay));
}
console.log(convertDateDisplayToDateArray(displayValue));
console.log(convertDateDisplayToDateObject(displayValue));
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"date-fns": "1.28.5",
"lodash": "4.17.4"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment