@ng-dl/numeric-input
Version:
override browser's default behavior & localization on numeric inputs
155 lines • 19.7 kB
JavaScript
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==