from-string.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. // tslint:disable-next-line
  6. import { defaultLocaleMonthsShort, defaultLocaleWeekdaysShort } from '../locale/locale.class';
  7. import { isString } from '../utils/type-checks';
  8. import { configFromStringAndFormat } from './from-string-and-format';
  9. import { createUTCDate } from './date-from-array';
  10. import { createInvalid, markInvalid } from './valid';
  11. import { getParsingFlags } from './parsing-flags';
  12. // iso 8601 regex
  13. // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
  14. // tslint:disable-next-line
  15. /** @type {?} */
  16. const extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
  17. // tslint:disable-next-line
  18. /** @type {?} */
  19. const basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
  20. /** @type {?} */
  21. const tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
  22. /** @type {?} */
  23. const isoDates = [
  24. ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/, true],
  25. ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/, true],
  26. ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/, true],
  27. ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
  28. ['YYYY-DDD', /\d{4}-\d{3}/, true],
  29. ['YYYY-MM', /\d{4}-\d\d/, false],
  30. ['YYYYYYMMDD', /[+-]\d{10}/, true],
  31. ['YYYYMMDD', /\d{8}/, true],
  32. // YYYYMM is NOT allowed by the standard
  33. ['GGGG[W]WWE', /\d{4}W\d{3}/, true],
  34. ['GGGG[W]WW', /\d{4}W\d{2}/, false],
  35. ['YYYYDDD', /\d{7}/, true]
  36. ];
  37. // iso time formats and regexes
  38. /** @type {?} */
  39. const isoTimes = [
  40. ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
  41. ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
  42. ['HH:mm:ss', /\d\d:\d\d:\d\d/],
  43. ['HH:mm', /\d\d:\d\d/],
  44. ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
  45. ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
  46. ['HHmmss', /\d\d\d\d\d\d/],
  47. ['HHmm', /\d\d\d\d/],
  48. ['HH', /\d\d/]
  49. ];
  50. /** @type {?} */
  51. const aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
  52. /** @type {?} */
  53. const obsOffsets = {
  54. UT: 0,
  55. GMT: 0,
  56. EDT: -4 * 60,
  57. EST: -5 * 60,
  58. CDT: -5 * 60,
  59. CST: -6 * 60,
  60. MDT: -6 * 60,
  61. MST: -7 * 60,
  62. PDT: -7 * 60,
  63. PST: -8 * 60
  64. };
  65. // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
  66. // tslint:disable-next-line
  67. /** @type {?} */
  68. const rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
  69. // date from iso format
  70. /**
  71. * @param {?} config
  72. * @return {?}
  73. */
  74. export function configFromISO(config) {
  75. if (!isString(config._i)) {
  76. return config;
  77. }
  78. /** @type {?} */
  79. const input = config._i;
  80. /** @type {?} */
  81. const match = extendedIsoRegex.exec(input) || basicIsoRegex.exec(input);
  82. /** @type {?} */
  83. let allowTime;
  84. /** @type {?} */
  85. let dateFormat;
  86. /** @type {?} */
  87. let timeFormat;
  88. /** @type {?} */
  89. let tzFormat;
  90. if (!match) {
  91. config._isValid = false;
  92. return config;
  93. }
  94. // getParsingFlags(config).iso = true;
  95. /** @type {?} */
  96. let i;
  97. /** @type {?} */
  98. let l;
  99. for (i = 0, l = isoDates.length; i < l; i++) {
  100. if (isoDates[i][1].exec(match[1])) {
  101. dateFormat = isoDates[i][0];
  102. allowTime = isoDates[i][2] !== false;
  103. break;
  104. }
  105. }
  106. if (dateFormat == null) {
  107. config._isValid = false;
  108. return config;
  109. }
  110. if (match[3]) {
  111. for (i = 0, l = isoTimes.length; i < l; i++) {
  112. if (isoTimes[i][1].exec(match[3])) {
  113. // match[2] should be 'T' or space
  114. timeFormat = (match[2] || ' ') + isoTimes[i][0];
  115. break;
  116. }
  117. }
  118. if (timeFormat == null) {
  119. config._isValid = false;
  120. return config;
  121. }
  122. }
  123. if (!allowTime && timeFormat != null) {
  124. config._isValid = false;
  125. return config;
  126. }
  127. if (match[4]) {
  128. if (tzRegex.exec(match[4])) {
  129. tzFormat = 'Z';
  130. }
  131. else {
  132. config._isValid = false;
  133. return config;
  134. }
  135. }
  136. config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
  137. return configFromStringAndFormat(config);
  138. }
  139. // tslint:disable-next-line
  140. /**
  141. * @param {?} yearStr
  142. * @param {?} monthStr
  143. * @param {?} dayStr
  144. * @param {?} hourStr
  145. * @param {?} minuteStr
  146. * @param {?} secondStr
  147. * @return {?}
  148. */
  149. function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
  150. /** @type {?} */
  151. const result = [
  152. untruncateYear(yearStr),
  153. defaultLocaleMonthsShort.indexOf(monthStr),
  154. parseInt(dayStr, 10),
  155. parseInt(hourStr, 10),
  156. parseInt(minuteStr, 10)
  157. ];
  158. if (secondStr) {
  159. result.push(parseInt(secondStr, 10));
  160. }
  161. return result;
  162. }
  163. /**
  164. * @param {?} yearStr
  165. * @return {?}
  166. */
  167. function untruncateYear(yearStr) {
  168. /** @type {?} */
  169. const year = parseInt(yearStr, 10);
  170. return year <= 49 ? year + 2000 : year;
  171. }
  172. /**
  173. * @param {?} str
  174. * @return {?}
  175. */
  176. function preprocessRFC2822(str) {
  177. // Remove comments and folding whitespace and replace multiple-spaces with a single space
  178. return str
  179. .replace(/\([^)]*\)|[\n\t]/g, ' ')
  180. .replace(/(\s\s+)/g, ' ').trim();
  181. }
  182. /**
  183. * @param {?} weekdayStr
  184. * @param {?} parsedInput
  185. * @param {?} config
  186. * @return {?}
  187. */
  188. function checkWeekday(weekdayStr, parsedInput, config) {
  189. if (weekdayStr) {
  190. // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
  191. /** @type {?} */
  192. const weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr);
  193. /** @type {?} */
  194. const weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
  195. if (weekdayProvided !== weekdayActual) {
  196. getParsingFlags(config).weekdayMismatch = true;
  197. config._isValid = false;
  198. return false;
  199. }
  200. }
  201. return true;
  202. }
  203. /**
  204. * @param {?} obsOffset
  205. * @param {?} militaryOffset
  206. * @param {?} numOffset
  207. * @return {?}
  208. */
  209. function calculateOffset(obsOffset, militaryOffset, numOffset) {
  210. if (obsOffset) {
  211. return obsOffsets[obsOffset];
  212. }
  213. else if (militaryOffset) {
  214. // the only allowed military tz is Z
  215. return 0;
  216. }
  217. else {
  218. /** @type {?} */
  219. const hm = parseInt(numOffset, 10);
  220. /** @type {?} */
  221. const m = hm % 100;
  222. /** @type {?} */
  223. const h = (hm - m) / 100;
  224. return h * 60 + m;
  225. }
  226. }
  227. // date and time from ref 2822 format
  228. /**
  229. * @param {?} config
  230. * @return {?}
  231. */
  232. export function configFromRFC2822(config) {
  233. if (!isString(config._i)) {
  234. return config;
  235. }
  236. /** @type {?} */
  237. const match = rfc2822.exec(preprocessRFC2822(config._i));
  238. if (!match) {
  239. return markInvalid(config);
  240. }
  241. /** @type {?} */
  242. const parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
  243. if (!checkWeekday(match[1], parsedArray, config)) {
  244. return config;
  245. }
  246. config._a = parsedArray;
  247. config._tzm = calculateOffset(match[8], match[9], match[10]);
  248. config._d = createUTCDate.apply(null, config._a);
  249. config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
  250. getParsingFlags(config).rfc2822 = true;
  251. return config;
  252. }
  253. // date from iso format or fallback
  254. /**
  255. * @param {?} config
  256. * @return {?}
  257. */
  258. export function configFromString(config) {
  259. if (!isString(config._i)) {
  260. return config;
  261. }
  262. /** @type {?} */
  263. const matched = aspNetJsonRegex.exec(config._i);
  264. if (matched !== null) {
  265. config._d = new Date(+matched[1]);
  266. return config;
  267. }
  268. // todo: update logic processing
  269. // isISO -> configFromISO
  270. // isRFC -> configFromRFC
  271. configFromISO(config);
  272. if (config._isValid === false) {
  273. delete config._isValid;
  274. }
  275. else {
  276. return config;
  277. }
  278. configFromRFC2822(config);
  279. if (config._isValid === false) {
  280. delete config._isValid;
  281. }
  282. else {
  283. return config;
  284. }
  285. // Final attempt, use Input Fallback
  286. // hooks.createFromInputFallback(config);
  287. return createInvalid(config);
  288. }
  289. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbS1zdHJpbmcuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwL2Nocm9ub3MvIiwic291cmNlcyI6WyJjcmVhdGUvZnJvbS1zdHJpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFDQSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc5RixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDaEQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7TUFLNUMsZ0JBQWdCLEdBQUcsa0pBQWtKOzs7TUFFckssYUFBYSxHQUFHLDZJQUE2STs7TUFFN0osT0FBTyxHQUFHLHVCQUF1Qjs7TUFFakMsUUFBUSxHQUFnQztJQUM1QyxDQUFDLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxJQUFJLENBQUM7SUFDN0MsQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxDQUFDO0lBQ3ZDLENBQUMsY0FBYyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQztJQUN4QyxDQUFDLFlBQVksRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDO0lBQ3BDLENBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUM7SUFDakMsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQztJQUNoQyxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDO0lBQ2xDLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUM7SUFDM0Isd0NBQXdDO0lBQ3hDLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxJ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QUM3QixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUM7S0FDeEI7U0FBTTtRQUNMLE9BQU8sTUFBTSxDQUFDO0tBQ2Y7SUFFRCxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQixJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssS0FBSyxFQUFFO1FBQzdCLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQztLQUN4QjtTQUFNO1FBQ0wsT0FBTyxNQUFNLENBQUM7S0FDZjtJQUVELG9DQUFvQztJQUNwQyx5Q0FBeUM7SUFDekMsT0FBTyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxuaW1wb3J0IHsgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LCBkZWZhdWx0TG9jYWxlV2Vla2RheXNTaG9ydCB9IGZyb20gJy4uL2xvY2FsZS9sb2NhbGUuY2xhc3MnO1xuaW1wb3J0IHsgRGF0ZUFycmF5IH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgRGF0ZVBhcnNpbmdDb25maWcgfSBmcm9tICcuL3BhcnNpbmcudHlwZXMnO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICcuLi91dGlscy90eXBlLWNoZWNrcyc7XG5pbXBvcnQgeyBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0IH0gZnJvbSAnLi9mcm9tLXN0cmluZy1hbmQtZm9ybWF0JztcbmltcG9ydCB7IGNyZWF0ZVVUQ0RhdGUgfSBmcm9tICcuL2RhdGUtZnJvbS1hcnJheSc7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkLCBtYXJrSW52YWxpZCB9IGZyb20gJy4vdmFsaWQnO1xuaW1wb3J0IHsgZ2V0UGFyc2luZ0ZsYWdzIH0gZnJvbSAnLi9wYXJzaW5nLWZsYWdzJztcblxuLy8gaXNvIDg2MDEgcmVnZXhcbi8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG5jb25zdCBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG5jb25zdCBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuY29uc3QgdHpSZWdleCA9IC9afFsrLV1cXGRcXGQoPzo6P1xcZFxcZCk/LztcblxuY29uc3QgaXNvRGF0ZXM6IFtzdHJpbmcsIFJlZ0V4cCwgYm9vbGVhbl1bXSA9IFtcbiAgWydZWVlZWVktTU0tREQnLCAvWystXVxcZHs2fS1cXGRcXGQtXFxkXFxkLywgdHJ1ZV0sXG4gIFsnWVlZWS1NTS1ERCcsIC9cXGR7NH0tXFxkXFxkLVxcZFxcZC8sIHRydWVdLFxuICBbJ0dHR0ctW1ddV1ctRScsIC9cXGR7NH0tV1xcZFxcZC1cXGQvLCB0cnVlXSxcbiAgWydHR0dHLVtXXVdXJywgL1xcZHs0fS1XXFxkXFxkLywgZmFsc2VdLFxuICBbJ1lZWVktREREJywgL1xcZHs0fS1cXGR7M30vLCB0cnVlXSxcbiAgWydZWVlZLU1NJywgL1xcZHs0fS1cXGRcXGQvLCBmYWxzZV0sXG4gIFsnWVlZWVlZTU1ERCcsIC9bKy1dXFxkezEwfS8sIHRydWVdLFxuICBbJ1lZWVlNTUREJywgL1xcZHs4fS8sIHRydWVdLFxuICAvLyBZWVlZTU0gaXMgTk9UIGFsbG93ZWQgYnkgdGhlIHN0YW5kYXJkXG4gIFsnR0dHR1tXXVdXRScsIC9cXGR7NH1XXFxkezN9LywgdHJ1ZV0sXG4gIFsnR0dHR1tXXVdXJywgL1xcZHs0fVdcXGR7Mn0vLCBmYWxzZV0sXG4gIFsnWVlZWURERCcsIC9cXGR7N30vLCB0cnVlXVxuXTtcblxuLy8gaXNvIHRpbWUgZm9ybWF0cyBhbmQgcmVnZXhlc1xuY29uc3QgaXNvVGltZXM6IFtzdHJpbmcsIFJlZ0V4cF1bXSA9IFtcbiAgWydISDptbTpzcy5TU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkXFwuXFxkKy9dLFxuICBbJ0hIOm1tOnNzLFNTU1MnLCAvXFxkXFxkOlxcZFxcZDpcXGRcXGQsXFxkKy9dLFxuICBbJ0hIOm1tOnNzJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkL10sXG4gIFsnSEg6bW0nLCAvXFxkXFxkOlxcZFxcZC9dLFxuICBbJ0hIbW1zcy5TU1NTJywgL1xcZFxcZFxcZFxcZFxcZFxcZFxcLlxcZCsvXSxcbiAgWydISG1tc3MsU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGQsXFxkKy9dLFxuICBbJ0hIbW1zcycsIC9cXGRcXGRcXGRcXGRcXGRcXGQvXSxcbiAgWydISG1tJywgL1xcZFxcZFxcZFxcZC9dLFxuICBbJ0hIJywgL1xcZFxcZC9dXG5dO1xuXG5jb25zdCBhc3BOZXRKc29uUmVnZXggPSAvXlxcLz9EYXRlXFwoKFxcLT9cXGQrKS9pO1xuXG5jb25zdCBvYnNPZmZzZXRzOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge1xuICBVVDogMCxcbiAgR01UOiAwLFxuICBFRFQ6IC00ICogNjAsXG4gIEVTVDogLTUgKiA2MCxcbiAgQ0RUOiAtNSAqIDYwLFxuICBDU1Q6IC02ICogNjAsXG4gIE1EVDogLTYgKiA2MCxcbiAgTVNUOiAtNyAqIDYwLFxuICBQRFQ6IC03ICogNjAsXG4gIFBTVDogLTggKiA2MFxufTtcblxuLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG5jb25zdCByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuLy8gZGF0ZSBmcm9tIGlzbyBmb3JtYXRcbmV4cG9ydCBmdW5jdGlvbiBjb25maWdGcm9tSVNPKGNvbmZpZzogRGF0ZVBhcnNpbmdDb25maWcpOiBEYXRlUGFyc2luZ0NvbmZpZyB7XG4gIGlmICghaXNTdHJpbmcoY29uZmlnLl9pKSkge1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cblxuICBjb25zdCBpbnB1dCA9IGNvbmZpZy5faTtcbiAgY29uc3QgbWF0Y2ggPSBleHRlbmRlZElzb1JlZ2V4LmV4ZWMoaW5wdXQpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhpbnB1dCk7XG5cblxuICBsZXQgYWxsb3dUaW1lO1xuICBsZXQgZGF0ZUZvcm1hdDtcbiAgbGV0IHRpbWVGb3JtYXQ7XG4gIGxldCB0ekZvcm1hdDtcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG5cbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgLy8gZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaXNvID0gdHJ1ZTtcbiAgbGV0IGk7XG4gIGxldCBsO1xuICBmb3IgKGkgPSAwLCBsID0gaXNvRGF0ZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKGlzb0RhdGVzW2ldWzFdLmV4ZWMobWF0Y2hbMV0pKSB7XG4gICAgICBkYXRlRm9ybWF0ID0gaXNvRGF0ZXNbaV1bMF07XG4gICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoZGF0ZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG5cbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgaWYgKG1hdGNoWzNdKSB7XG4gICAgZm9yIChpID0gMCwgbCA9IGlzb1RpbWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKGlzb1RpbWVzW2ldWzFdLmV4ZWMobWF0Y2hbM10pKSB7XG4gICAgICAgIC8vIG1hdGNoWzJdIHNob3VsZCBiZSAnVCcgb3Igc3BhY2VcbiAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aW1lRm9ybWF0ID09IG51bGwpIHtcbiAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuXG4gICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cblxuICB9XG4gIGlmICghYWxsb3dUaW1lICYmIHRpbWVGb3JtYXQgIT0gbnVsbCkge1xuICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIGlmIChtYXRjaFs0XSkge1xuICAgIGlmICh0elJlZ2V4LmV4ZWMobWF0Y2hbNF0pKSB7XG4gICAgICB0ekZvcm1hdCA9ICdaJztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG5cbiAgICAgIHJldHVybiBjb25maWc7XG4gICAgfVxuICB9XG5cbiAgY29uZmlnLl9mID0gZGF0ZUZvcm1hdCArICh0aW1lRm9ybWF0IHx8ICcnKSArICh0ekZvcm1hdCB8fCAnJyk7XG5cbiAgcmV0dXJuIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbn1cblxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG5mdW5jdGlvbiBleHRyYWN0RnJvbVJGQzI4MjJTdHJpbmdzKHllYXJTdHI6IHN0cmluZywgbW9udGhTdHI6IHN0cmluZywgZGF5U3RyOiBzdHJpbmcsIGhvdXJTdHI6IHN0cmluZywgbWludXRlU3RyOiBzdHJpbmcsIHNlY29uZFN0cjogc3RyaW5nKTogRGF0ZUFycmF5IHtcbiAgY29uc3QgcmVzdWx0ID0gW1xuICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydC5pbmRleE9mKG1vbnRoU3RyKSxcbiAgICBwYXJzZUludChkYXlTdHIsIDEwKSxcbiAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgcGFyc2VJbnQobWludXRlU3RyLCAxMClcbiAgXTtcblxuICBpZiAoc2Vjb25kU3RyKSB7XG4gICAgcmVzdWx0LnB1c2gocGFyc2VJbnQoc2Vjb25kU3RyLCAxMCkpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cjogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcblxuICByZXR1cm4geWVhciA8PSA0OSA/IHllYXIgKyAyMDAwIDogeWVhcjtcbn1cblxuZnVuY3Rpb24gcHJlcHJvY2Vzc1JGQzI4MjIoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZW1vdmUgY29tbWVudHMgYW5kIGZvbGRpbmcgd2hpdGVzcGFjZSBhbmQgcmVwbGFjZSBtdWx0aXBsZS1zcGFjZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuICByZXR1cm4gc3RyXG4gICAgLnJlcGxhY2UoL1xcKFteKV0qXFwpfFtcXG5cXHRdL2csICcgJylcbiAgICAucmVwbGFjZSgvKFxcc1xccyspL2csICcgJykudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0cjogc3RyaW5nLCBwYXJzZWRJbnB1dDogRGF0ZUFycmF5LCBjb25maWc6IERhdGVQYXJzaW5nQ29uZmlnKTogYm9vbGVhbiB7XG4gIGlmICh3ZWVrZGF5U3RyKSB7XG4gICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgIGNvbnN0IHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0cik7XG4gICAgY29uc3Qgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgIGlmICh3ZWVrZGF5UHJvdmlkZWQgIT09IHdlZWtkYXlBY3R1YWwpIHtcbiAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0OiBzdHJpbmcsIG1pbGl0YXJ5T2Zmc2V0OiBzdHJpbmcsIG51bU9mZnNldDogc3RyaW5nKSB7XG4gIGlmIChvYnNPZmZzZXQpIHtcbiAgICByZXR1cm4gb2JzT2Zmc2V0c1tvYnNPZmZzZXRdO1xuICB9IGVsc2UgaWYgKG1pbGl0YXJ5T2Zmc2V0KSB7XG4gICAgLy8gdGhlIG9ubHkgYWxsb3dlZCBtaWxpdGFyeSB0eiBpcyBaXG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICBjb25zdCBtID0gaG0gJSAxMDA7XG4gICAgY29uc3QgaCA9IChobSAtIG0pIC8gMTAwO1xuXG4gICAgcmV0dXJuIGggKiA2MCArIG07XG4gIH1cbn1cblxuLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuZXhwb3J0IGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZzogRGF0ZVBhcnNpbmdDb25maWcpOiBEYXRlUGFyc2luZ0NvbmZpZyB7XG4gIGlmICghaXNTdHJpbmcoY29uZmlnLl9pKSkge1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cblxuICBjb25zdCBtYXRjaCA9IHJmYzI4MjIuZXhlYyhwcmVwcm9jZXNzUkZDMjgyMihjb25maWcuX2kpKTtcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIG1hcmtJbnZhbGlkKGNvbmZpZyk7XG4gIH1cblxuICBjb25zdCBwYXJzZWRBcnJheSA9IGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MobWF0Y2hbNF0sIG1hdGNoWzNdLCBtYXRjaFsyXSwgbWF0Y2hbNV0sIG1hdGNoWzZdLCBtYXRjaFs3XSk7XG4gIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cblxuICBjb25maWcuX2EgPSBwYXJzZWRBcnJheTtcbiAgY29uZmlnLl90em0gPSBjYWxjdWxhdGVPZmZzZXQobWF0Y2hbOF0sIG1hdGNoWzldLCBtYXRjaFsxMF0pO1xuXG4gIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgY29uZmlnLl9kLnNldFVUQ01pbnV0ZXMoY29uZmlnLl9kLmdldFVUQ01pbnV0ZXMoKSAtIGNvbmZpZy5fdHptKTtcblxuICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5yZmMyODIyID0gdHJ1ZTtcblxuICByZXR1cm4gY29uZmlnO1xufVxuXG4vLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuZXhwb3J0IGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnOiBEYXRlUGFyc2luZ0NvbmZpZyk6IERhdGVQYXJzaW5nQ29uZmlnIHtcbiAgaWYgKCFpc1N0cmluZyhjb25maWcuX2kpKSB7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIGNvbnN0IG1hdGNoZWQgPSBhc3BOZXRKc29uUmVnZXguZXhlYyhjb25maWcuX2kpO1xuXG4gIGlmIChtYXRjaGVkICE9PSBudWxsKSB7XG4gICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuXG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIC8vIHRvZG86IHVwZGF0ZSBsb2dpYyBwcm9jZXNzaW5nXG4gIC8vIGlzSVNPIC0+IGNvbmZpZ0Zyb21JU09cbiAgLy8gaXNSRkMgLT4gY29uZmlnRnJvbVJGQ1xuXG4gIGNvbmZpZ0Zyb21JU08oY29uZmlnKTtcbiAgaWYgKGNvbmZpZy5faXNWYWxpZCA9PT0gZmFsc2UpIHtcbiAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cblxuICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgIGRlbGV0ZSBjb25maWcuX2lzVmFsaWQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIC8vIEZpbmFsIGF0dGVtcHQsIHVzZSBJbnB1dCBGYWxsYmFja1xuICAvLyBob29rcy5jcmVhdGVGcm9tSW5wdXRGYWxsYmFjayhjb25maWcpO1xuICByZXR1cm4gY3JlYXRlSW52YWxpZChjb25maWcpO1xufVxuXG4vLyBob29rcy5jcmVhdGVGcm9tSW5wdXRGYWxsYmFjayA9IGRlcHJlY2F0ZShcbi8vICAgICAndmFsdWUgcHJvdmlkZWQgaXMgbm90IGluIGEgcmVjb2duaXplZCBSRkMyODIyIG9yIElTTyBmb3JtYXQuIG1vbWVudCBjb25zdHJ1Y3Rpb24gZmFsbHMgYmFjayB0byBqcyBEYXRlKCksICcgK1xuLy8gICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuLy8gICAgICdkaXNjb3VyYWdlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGFuIHVwY29taW5nIG1ham9yIHJlbGVhc2UuIFBsZWFzZSByZWZlciB0byAnICtcbi8vICAgICAnaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9qcy1kYXRlLyBmb3IgbW9yZSBpbmZvLicsXG4vLyAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuLy8gICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShjb25maWcuX2kgKyAoY29uZmlnLl91c2VVVEMgPyAnIFVUQycgOiAnJykpO1xuLy8gICAgIH1cbi8vICk7XG4iXX0=