UNPKG

@ng-dl/numeric-input

Version:

override browser's default behavior & localization on numeric inputs

155 lines 19.7 kB
const UNSIGNED_INTEGER_REGEX = '^[0-9]*$'; const SIGNED_DOUBLE_REGEX = '^-?[0-9]+(.[0-9]+)?$'; const NUMBERS_REGEX = /\d/g; const CHROME_MIN_VALIDATION_MESSAGE = 'Value must be greater than or equal to'; const CHROME_MAX_VALIDATION_MESSAGE = 'Value must be less than or equal to'; const DEFAULT_NUMERIC_VALUE = 0; const DEFAULT_ACTION_KEYS = ['a', 'c', 'v', 'x']; const DEFAULT_ALLOWED_KEYS = [ 'Backspace', 'ArrowLeft', 'ArrowRight', 'Escape', 'Tab', 'Enter' ]; /** * Override input attributes for validation and mobile support. * @param input - input element */ export function overrideInputType(input) { input.setAttribute('type', 'text'); input.setAttribute('inputmode', 'decimal'); input.removeAttribute('pattern'); } /** * Get formatted value, if the value is a valid numeric value it will be formatted if not a default value will be returned. * @param value - value to format. * @param decimalSeparator - decimal separator to replace (if needed). * @param thousandsSeparator - thousands separator to remove (if needed). */ export function getFormattedValue(value, decimalSeparator, thousandsSeparator) { const formatted = Number(parseValue(value, decimalSeparator, thousandsSeparator).replace(decimalSeparator, '.')); return isNaN(formatted) ? DEFAULT_NUMERIC_VALUE : formatted; } /** * Check if the pressed key is allowed in the numeric input field. * @param e - keyboard event. * @param decimalSeparators - array of supported separators. */ export function isAllowedKey(e, decimalSeparators) { const key = getKeyName(e); const allowedKeys = getAllowedKeys(e, decimalSeparators); return (allowedKeys.includes(key) || (DEFAULT_ACTION_KEYS.includes(key) && isActionKey(e)) || isNumberKey(e)); } /** * Align all browsers to validate as same as Chrome browser does. * Validation will be after the field loose focus and with Chrome default messages. * @param el - input element. * @param value - input value. * @param min - minimum valid value. * @param max - maximum valid value. */ export function validate(el, value, min, max) { if (value < min) { el.setCustomValidity(`${CHROME_MIN_VALIDATION_MESSAGE} ${min}.`); return false; } if (value > max) { el.setCustomValidity(`${CHROME_MAX_VALIDATION_MESSAGE} ${max}.`); return false; } el.setCustomValidity(''); return true; } /** * support for old browsers. */ function mapKeyCodeToKeyName(keyCode) { if (keyCode && String.fromCharCode) { switch (keyCode) { case 8: return 'Backspace'; case 9: return 'Tab'; case 27: return 'Escape'; case 37: return 'ArrowLeft'; case 39: return 'ArrowRight'; case 188: return ','; case 190: return '.'; case 109: case 173: case 189: return '-'; default: return String.fromCharCode(keyCode); } } return ''; } /** * Add zero to decimal values, replaces the decimal separator and remove the thousand separator. * If the value is a numeric value the parsed value will be returned, if not - the default numeric value. * @param value - value to parse. * @param decimalSeparator - decimal separator to replace (if needed). * @param thousandsSeparator - thousands separator to remove (if needed). */ function parseValue(value, decimalSeparator, thousandSeparator) { value = replaceDecimalSeparator(value, decimalSeparator); value = appendZeroToDecimal(value, decimalSeparator); value = removeThousandsSeparator(value, thousandSeparator); const isValid = new RegExp(SIGNED_DOUBLE_REGEX).test(value); return isValid ? value : DEFAULT_NUMERIC_VALUE.toString(); } function replaceDecimalSeparator(value, decimalSeparator) { const separator = value.replace('-', '').replace(NUMBERS_REGEX, ''); return value.replace(separator || decimalSeparator, decimalSeparator); } function appendZeroToDecimal(value, decimalSeparator) { const firstCharacter = value.charAt(0); if (firstCharacter === decimalSeparator) { return 0 + value; } const lastCharacter = value.charAt(value.length - 1); if (lastCharacter === decimalSeparator) { return value + 0; } return value; } function removeThousandsSeparator(value, thousandsSeparator) { return value.replace(thousandsSeparator, ''); } function isActionKey(e) { return e.ctrlKey || e.metaKey; } function getKeyName(e) { return e.key || mapKeyCodeToKeyName(e.keyCode); } function isNumberKey(e) { const key = getKeyName(e); return new RegExp(UNSIGNED_INTEGER_REGEX).test(key); } function getAllowedKeys(e, decimalSeparators) { const allowedKeys = [...DEFAULT_ALLOWED_KEYS]; const originalValue = e.target.value; const cursorPosition = e.target.selectionStart || 0; const signExists = originalValue.includes('-'); const separatorExists = decimalSeparators.some((separator) => originalValue.includes(separator)); const separatorIsCloseToSign = signExists && cursorPosition <= 1; if (!separatorIsCloseToSign && !separatorExists) { allowedKeys.push(...decimalSeparators); } const firstCharacterIsSeparator = decimalSeparators.some((separator) => originalValue.charAt(0) === separator); if (!signExists && !firstCharacterIsSeparator && cursorPosition === 0) { allowedKeys.push('-'); } return allowedKeys; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtZXJpYy1pbnB1dC51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL251bWVyaWMtaW5wdXQvc3JjL2xpYi9udW1lcmljLWlucHV0LnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sc0JBQXNCLEdBQUcsVUFBVSxDQUFDO0FBQzFDLE1BQU0sbUJBQW1CLEdBQUcsc0JBQXNCLENBQUM7QUFDbkQsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDO0FBQzVCLE1BQU0sNkJBQTZCLEdBQUcsd0NBQXdDLENBQUM7QUFDL0UsTUFBTSw2QkFBNkIsR0FBRyxxQ0FBcUMsQ0FBQztBQUM1RSxNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUNoQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDakQsTUFBTSxvQkFBb0IsR0FBRztJQUMzQixXQUFXO0lBQ1gsV0FBVztJQUNYLFlBQVk7SUFDWixRQUFRO0lBQ1IsS0FBSztJQUNMLE9BQU87Q0FDUixDQUFDO0FBR0Y7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEtBQXVCO0lBQ3ZELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLEtBQUssQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzNDLEtBQUssQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixLQUFhLEVBQ2IsZ0JBQXdCLEVBQ3hCLGtCQUEwQjtJQUUxQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQ3RCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxPQUFPLENBQUMsZ0JBQWdC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MC05XSokJztcbmNvbnN0IFNJR05FRF9ET1VCTEVfUkVHRVggPSAnXi0/WzAtOV0rKC5bMC05XSspPyQnO1xuY29uc3QgTlVNQkVSU19SRUdFWCA9IC9cXGQvZztcbmNvbnN0IENIUk9NRV9NSU5fVkFMSURBVElPTl9NRVNTQUdFID0gJ1ZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvJztcbmNvbnN0IENIUk9NRV9NQVhfVkFMSURBVElPTl9NRVNTQUdFID0gJ1ZhbHVlIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvJztcbmNvbnN0IERFRkFVTFRfTlVNRVJJQ19WQUxVRSA9IDA7XG5jb25zdCBERUZBVUxUX0FDVElPTl9LRVlTID0gWydhJywgJ2MnLCAndicsICd4J107XG5jb25zdCBERUZBVUxUX0FMTE9XRURfS0VZUyA9IFtcbiAgJ0JhY2tzcGFjZScsXG4gICdBcnJvd0xlZnQnLFxuICAnQXJyb3dSaWdodCcsXG4gICdFc2NhcGUnLFxuICAnVGFiJyxcbiAgJ0VudGVyJ1xuXTtcblxuXG4vKipcbiAqIE92ZXJyaWRlIGlucHV0IGF0dHJpYnV0ZXMgZm9yIHZhbGlkYXRpb24gYW5kIG1vYmlsZSBzdXBwb3J0LlxuICogQHBhcmFtIGlucHV0IC0gaW5wdXQgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gb3ZlcnJpZGVJbnB1dFR5cGUoaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQpOiB2b2lkIHtcbiAgaW5wdXQuc2V0QXR0cmlidXRlKCd0eXBlJywgJ3RleHQnKTtcbiAgaW5wdXQuc2V0QXR0cmlidXRlKCdpbnB1dG1vZGUnLCAnZGVjaW1hbCcpO1xuICBpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ3BhdHRlcm4nKTtcbn1cblxuLyoqXG4gKiBHZXQgZm9ybWF0dGVkIHZhbHVlLCBpZiB0aGUgdmFsdWUgaXMgYSB2YWxpZCBudW1lcmljIHZhbHVlIGl0IHdpbGwgYmUgZm9ybWF0dGVkIGlmIG5vdCBhIGRlZmF1bHQgdmFsdWUgd2lsbCBiZSByZXR1cm5lZC5cbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIGZvcm1hdC5cbiAqIEBwYXJhbSBkZWNpbWFsU2VwYXJhdG9yIC0gZGVjaW1hbCBzZXBhcmF0b3IgdG8gcmVwbGFjZSAoaWYgbmVlZGVkKS5cbiAqIEBwYXJhbSB0aG91c2FuZHNTZXBhcmF0b3IgLSB0aG91c2FuZHMgc2VwYXJhdG9yIHRvIHJlbW92ZSAoaWYgbmVlZGVkKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZFZhbHVlKFxuICB2YWx1ZTogc3RyaW5nLFxuICBkZWNpbWFsU2VwYXJhdG9yOiBzdHJpbmcsXG4gIHRob3VzYW5kc1NlcGFyYXRvcjogc3RyaW5nXG4pOiBudW1iZXIge1xuICBjb25zdCBmb3JtYXR0ZWQgPSBOdW1iZXIoXG4gICAgcGFyc2VWYWx1ZSh2YWx1ZSwgZGVjaW1hbFNlcGFyYXRvciwgdGhvdXNhbmRzU2VwYXJhdG9yKS5yZXBsYWNlKGRlY2ltYWxTZXBhcmF0b3IsICcuJylcbiAgKTtcbiAgcmV0dXJuIGlzTmFOKGZvcm1hdHRlZCkgPyBERUZBVUxUX05VTUVSSUNfVkFMVUUgOiBmb3JtYXR0ZWQ7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHByZXNzZWQga2V5IGlzIGFsbG93ZWQgaW4gdGhlIG51bWVyaWMgaW5wdXQgZmllbGQuXG4gKiBAcGFyYW0gZSAtIGtleWJvYXJkIGV2ZW50LlxuICogQHBhcmFtIGRlY2ltYWxTZXBhcmF0b3JzIC0gYXJyYXkgb2Ygc3VwcG9ydGVkIHNlcGFyYXRvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FsbG93ZWRLZXkoXG4gIGU6IEtleWJvYXJkRXZlbnQsXG4gIGRlY2ltYWxTZXBhcmF0b3JzOiBzdHJpbmdbXVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleTogc3RyaW5nID0gZ2V0S2V5TmFtZShlKTtcbiAgY29uc3QgYWxsb3dlZEtleXMgPSBnZXRBbGxvd2VkS2V5cyhlLCBkZWNpbWFsU2VwYXJhdG9ycyk7XG4gIHJldHVybiAoXG4gICAgYWxsb3dlZEtleXMuaW5jbHVkZXMoa2V5KSB8fFxuICAgIChERUZBVUxUX0FDVElPTl9LRVlTLmluY2x1ZGVzKGtleSkgJiYgaXNBY3Rpb25LZXkoZSkpIHx8XG4gICAgaXNOdW1iZXJLZXkoZSlcbiAgKTtcbn1cblxuLyoqXG4gKiBBbGlnbiBhbGwgYnJvd3NlcnMgdG8gdmFsaWRhdGUgYXMgc2FtZSBhcyBDaHJvbWUgYnJvd3NlciBkb2VzLlxuICogVmFsaWRhdGlvbiB3aWxsIGJlIGFmdGVyIHRoZSBmaWVsZCBsb29zZSBmb2N1cyBhbmQgd2l0aCBDaHJvbWUgZGVmYXVsdCBtZXNzYWdlcy5cbiAqIEBwYXJhbSBlbCAtIGlucHV0IGVsZW1lbnQuXG4gKiBAcGFyYW0gdmFsdWUgLSBpbnB1dCB2YWx1ZS5cbiAqIEBwYXJhbSBtaW4gLSBtaW5pbXVtIHZhbGlkIHZhbHVlLlxuICogQHBhcmFtIG1heCAtIG1heGltdW0gdmFsaWQgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZShcbiAgZWw6IEhUTUxJbnB1dEVsZW1lbnQsXG4gIHZhbHVlOiBudW1iZXIsXG4gIG1pbj86IG51bWJlcixcbiAgbWF4PzogbnVtYmVyXG4pOiBib29sZWFuIHtcbiAgaWYgKHZhbHVlIDwgbWluKSB7XG4gICAgZWwuc2V0Q3VzdG9tVmFsaWRpdHkoYCR7Q0hST01FX01JTl9WQUxJREFUSU9OX01FU1NBR0V9ICR7bWlufS5gKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodmFsdWUgPiBtYXgpIHtcbiAgICBlbC5zZXRDdXN0b21WYWxpZGl0eShgJHtDSFJPTUVfTUFYX1ZBTElEQVRJT05fTUVTU0FHRX0gJHttYXh9LmApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGVsLnNldEN1c3RvbVZhbGlkaXR5KCcnKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogc3VwcG9ydCBmb3Igb2xkIGJyb3dzZXJzLlxuICovXG5mdW5jdGlvbiBtYXBLZXlDb2RlVG9LZXlOYW1lKGtleUNvZGU6IG51bWJlcik6IHN0cmluZyB7XG4gIGlmIChrZXlDb2RlICYmIFN0cmluZy5mcm9tQ2hhckNvZGUpIHtcbiAgICBzd2l0Y2ggKGtleUNvZGUpIHtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgcmV0dXJuICdCYWNrc3BhY2UnO1xuICAgICAgY2FzZSA5OlxuICAgICAgICByZXR1cm4gJ1RhYic7XG4gICAgICBjYXNlIDI3OlxuICAgICAgICByZXR1cm4gJ0VzY2FwZSc7XG4gICAgICBjYXNlIDM3OlxuICAgICAgICByZXR1cm4gJ0Fycm93TGVmdCc7XG4gICAgICBjYXNlIDM5OlxuICAgICAgICByZXR1cm4gJ0Fycm93UmlnaHQnO1xuICAgICAgY2FzZSAxODg6XG4gICAgICAgIHJldHVybiAnLCc7XG4gICAgICBjYXNlIDE5MDpcbiAgICAgICAgcmV0dXJuICcuJztcbiAgICAgIGNhc2UgMTA5OlxuICAgICAgY2FzZSAxNzM6XG4gICAgICBjYXNlIDE4OTpcbiAgICAgICAgcmV0dXJuICctJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogQWRkIHplcm8gdG8gZGVjaW1hbCB2YWx1ZXMsIHJlcGxhY2VzIHRoZSBkZWNpbWFsIHNlcGFyYXRvciBhbmQgcmVtb3ZlIHRoZSB0aG91c2FuZCBzZXBhcmF0b3IuXG4gKiBJZiB0aGUgdmFsdWUgaXMgYSBudW1lcmljIHZhbHVlIHRoZSBwYXJzZWQgdmFsdWUgd2lsbCBiZSByZXR1cm5lZCwgaWYgbm90IC0gdGhlIGRlZmF1bHQgbnVtZXJpYyB2YWx1ZS5cbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIHBhcnNlLlxuICogQHBhcmFtIGRlY2ltYWxTZXBhcmF0b3IgLSBkZWNpbWFsIHNlcGFyYXRvciB0byByZXBsYWNlIChpZiBuZWVkZWQpLlxuICogQHBhcmFtIHRob3VzYW5kc1NlcGFyYXRvciAtIHRob3VzYW5kcyBzZXBhcmF0b3IgdG8gcmVtb3ZlIChpZiBuZWVkZWQpLlxuICovXG5mdW5jdGlvbiBwYXJzZVZhbHVlKHZhbHVlOiBzdHJpbmcsIGRlY2ltYWxTZXBhcmF0b3I6IHN0cmluZywgdGhvdXNhbmRTZXBhcmF0b3I6IHN0cmluZyk6IHN0cmluZyB7XG4gIHZhbHVlID0gcmVwbGFjZURlY2ltYWxTZXBhcmF0b3IodmFsdWUsIGRlY2ltYWxTZXBhcmF0b3IpO1xuICB2YWx1ZSA9IGFwcGVuZFplcm9Ub0RlY2ltYWwodmFsdWUsIGRlY2ltYWxTZXBhcmF0b3IpO1xuICB2YWx1ZSA9IHJlbW92ZVRob3VzYW5kc1NlcGFyYXRvcih2YWx1ZSwgdGhvdXNhbmRTZXBhcmF0b3IpO1xuICBjb25zdCBpc1ZhbGlkOiBib29sZWFuID0gbmV3IFJlZ0V4cChTSUdORURfRE9VQkxFX1JFR0VYKS50ZXN0KHZhbHVlKTtcbiAgcmV0dXJuIGlzVmFsaWQgPyB2YWx1ZSA6IERFRkFVTFRfTlVNRVJJQ19WQUxVRS50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlRGVjaW1hbFNlcGFyYXRvcih2YWx1ZTogc3RyaW5nLCBkZWNpbWFsU2VwYXJhdG9yOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBzZXBhcmF0b3IgPSB2YWx1ZS5yZXBsYWNlKCctJywgJycpLnJlcGxhY2UoTlVNQkVSU19SRUdFWCwgJycpO1xuICByZXR1cm4gdmFsdWUucmVwbGFjZShzZXBhcmF0b3IgfHwgZGVjaW1hbFNlcGFyYXRvciwgZGVjaW1hbFNlcGFyYXRvcik7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZFplcm9Ub0RlY2ltYWwodmFsdWU6IHN0cmluZywgZGVjaW1hbFNlcGFyYXRvcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlyc3RDaGFyYWN0ZXIgPSB2YWx1ZS5jaGFyQXQoMCk7XG4gIGlmIChmaXJzdENoYXJhY3RlciA9PT0gZGVjaW1hbFNlcGFyYXRvcikge1xuICAgIHJldHVybiAwICsgdmFsdWU7XG4gIH1cblxuICBjb25zdCBsYXN0Q2hhcmFjdGVyID0gdmFsdWUuY2hhckF0KHZhbHVlLmxlbmd0aCAtIDEpO1xuICBpZiAobGFzdENoYXJhY3RlciA9PT0gZGVjaW1hbFNlcGFyYXRvcikge1xuICAgIHJldHVybiB2YWx1ZSArIDA7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVRob3VzYW5kc1NlcGFyYXRvcih2YWx1ZTogc3RyaW5nLCB0aG91c2FuZHNTZXBhcmF0b3I6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKHRob3VzYW5kc1NlcGFyYXRvciwgJycpO1xufVxuXG5mdW5jdGlvbiBpc0FjdGlvbktleShlOiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiBlLmN0cmxLZXkgfHwgZS5tZXRhS2V5O1xufVxuXG5mdW5jdGlvbiBnZXRLZXlOYW1lKGU6IEtleWJvYXJkRXZlbnQpOiBzdHJpbmcge1xuICByZXR1cm4gZS5rZXkgfHwgbWFwS2V5Q29kZVRvS2V5TmFtZShlLmtleUNvZGUpO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcktleShlOiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleSA9IGdldEtleU5hbWUoZSk7XG4gIHJldHVybiBuZXcgUmVnRXhwKFVOU0lHTkVEX0lOVEVHRVJfUkVHRVgpLnRlc3Qoa2V5KTtcbn1cblxuZnVuY3Rpb24gZ2V0QWxsb3dlZEtleXMoXG4gIGU6IEtleWJvYXJkRXZlbnQsXG4gIGRlY2ltYWxTZXBhcmF0b3JzOiBzdHJpbmdbXVxuKTogc3RyaW5nW10ge1xuICBjb25zdCBhbGxvd2VkS2V5cyA9IFsuLi5ERUZBVUxUX0FMTE9XRURfS0VZU107XG4gIGNvbnN0IG9yaWdpbmFsVmFsdWU6IHN0cmluZyA9IChlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgY29uc3QgY3Vyc29yUG9zaXRpb246IG51bWJlciA9XG4gICAgKGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnNlbGVjdGlvblN0YXJ0IHx8IDA7XG4gIGNvbnN0IHNpZ25FeGlzdHMgPSBvcmlnaW5hbFZhbHVlLmluY2x1ZGVzKCctJyk7XG4gIGNvbnN0IHNlcGFyYXRvckV4aXN0cyA9IGRlY2ltYWxTZXBhcmF0b3JzLnNvbWUoKHNlcGFyYXRvcikgPT5cbiAgICBvcmlnaW5hbFZhbHVlLmluY2x1ZGVzKHNlcGFyYXRvcilcbiAgKTtcblxuICBjb25zdCBzZXBhcmF0b3JJc0Nsb3NlVG9TaWduID0gc2lnbkV4aXN0cyAmJiBjdXJzb3JQb3NpdGlvbiA8PSAxO1xuICBpZiAoIXNlcGFyYXRvcklzQ2xvc2VUb1NpZ24gJiYgIXNlcGFyYXRvckV4aXN0cykge1xuICAgIGFsbG93ZWRLZXlzLnB1c2goLi4uZGVjaW1hbFNlcGFyYXRvcnMpO1xuICB9XG5cbiAgY29uc3QgZmlyc3RDaGFyYWN0ZXJJc1NlcGFyYXRvciA9IGRlY2ltYWxTZXBhcmF0b3JzLnNvbWUoXG4gICAgKHNlcGFyYXRvcikgPT4gb3JpZ2luYWxWYWx1ZS5jaGFyQXQoMCkgPT09IHNlcGFyYXRvclxuICApO1xuXG4gIGlmICghc2lnbkV4aXN0cyAmJiAhZmlyc3RDaGFyYWN0ZXJJc1NlcGFyYXRvciAmJiBjdXJzb3JQb3NpdGlvbiA9PT0gMCkge1xuICAgIGFsbG93ZWRLZXlzLnB1c2goJy0nKTtcbiAgfVxuXG4gIHJldHVybiBhbGxvd2VkS2V5cztcbn1cbiJdfQ==