UNPKG

@tabler/core

Version:

Premium and Open Source dashboard template with responsive and high quality UI.

1,551 lines (1,531 loc) 282 kB
/*! * Tabler v1.0.0-beta24 (https://tabler.io) * @version 1.0.0-beta24 * @link https://tabler.io * Copyright 2018-2025 The Tabler Authors * Copyright 2018-2025 codecalm.net Paweł Kuna * Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE) */ (function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); })((function () { 'use strict'; var e=new Map;function t(t){var o=e.get(t);o&&o.destroy();}function o(t){var o=e.get(t);o&&o.update();}var r=null;"undefined"==typeof window?((r=function(e){return e}).destroy=function(e){return e},r.update=function(e){return e}):((r=function(t,o){return t&&Array.prototype.forEach.call(t.length?t:[t],function(t){return function(t){if(t&&t.nodeName&&"TEXTAREA"===t.nodeName&&!e.has(t)){var o,r=null,n=window.getComputedStyle(t),i=(o=t.value,function(){a({testForHeightReduction:""===o||!t.value.startsWith(o),restoreTextAlign:null}),o=t.value;}),l=function(o){t.removeEventListener("autosize:destroy",l),t.removeEventListener("autosize:update",s),t.removeEventListener("input",i),window.removeEventListener("resize",s),Object.keys(o).forEach(function(e){return t.style[e]=o[e]}),e.delete(t);}.bind(t,{height:t.style.height,resize:t.style.resize,textAlign:t.style.textAlign,overflowY:t.style.overflowY,overflowX:t.style.overflowX,wordWrap:t.style.wordWrap});t.addEventListener("autosize:destroy",l),t.addEventListener("autosize:update",s),t.addEventListener("input",i),window.addEventListener("resize",s),t.style.overflowX="hidden",t.style.wordWrap="break-word",e.set(t,{destroy:l,update:s}),s();}function a(e){var o,i,l=e.restoreTextAlign,s=void 0===l?null:l,d=e.testForHeightReduction,u=void 0===d||d,c=n.overflowY;if(0!==t.scrollHeight&&("vertical"===n.resize?t.style.resize="none":"both"===n.resize&&(t.style.resize="horizontal"),u&&(o=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push([e.parentNode,e.parentNode.scrollTop]),e=e.parentNode;return function(){return t.forEach(function(e){var t=e[0],o=e[1];t.style.scrollBehavior="auto",t.scrollTop=o,t.style.scrollBehavior=null;})}}(t),t.style.height=""),i="content-box"===n.boxSizing?t.scrollHeight-(parseFloat(n.paddingTop)+parseFloat(n.paddingBottom)):t.scrollHeight+parseFloat(n.borderTopWidth)+parseFloat(n.borderBottomWidth),"none"!==n.maxHeight&&i>parseFloat(n.maxHeight)?("hidden"===n.overflowY&&(t.style.overflow="scroll"),i=parseFloat(n.maxHeight)):"hidden"!==n.overflowY&&(t.style.overflow="hidden"),t.style.height=i+"px",s&&(t.style.textAlign=s),o&&o(),r!==i&&(t.dispatchEvent(new Event("autosize:resized",{bubbles:!0})),r=i),c!==n.overflow&&!s)){var v=n.textAlign;"hidden"===n.overflow&&(t.style.textAlign="start"===v?"end":"start"),a({restoreTextAlign:v,testForHeightReduction:!0});}}function s(){a({testForHeightReduction:!0,restoreTextAlign:null});}}(t)}),t}).destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],t),e},r.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e});var n=r; var elements$1 = document.querySelectorAll('[data-bs-toggle="autosize"]'); if (elements$1.length) { elements$1.forEach(function (element) { n(element); }); } var elements = document.querySelectorAll('[data-countup]'); if (elements.length) { elements.forEach(function (element) { var options = {}; try { options = element.getAttribute('data-countup') ? JSON.parse(element.getAttribute('data-countup')) : {}; } catch (error) {} var value = parseInt(element.innerHTML, 10); var countUp = new window.countUp.CountUp(element, value, options); if (!countUp.error) { countUp.start(); } }); } function isString(str) { return typeof str === 'string' || str instanceof String; } function isObject(obj) { var _obj$constructor; return typeof obj === 'object' && obj != null && (obj == null || (_obj$constructor = obj.constructor) == null ? void 0 : _obj$constructor.name) === 'Object'; } function pick(obj, keys) { if (Array.isArray(keys)) return pick(obj, (_, k) => keys.includes(k)); return Object.entries(obj).reduce((acc, _ref) => { let [k, v] = _ref; if (keys(v, k)) acc[k] = v; return acc; }, {}); } const DIRECTION = { NONE: 'NONE', LEFT: 'LEFT', FORCE_LEFT: 'FORCE_LEFT', RIGHT: 'RIGHT', FORCE_RIGHT: 'FORCE_RIGHT' }; function forceDirection(direction) { switch (direction) { case DIRECTION.LEFT: return DIRECTION.FORCE_LEFT; case DIRECTION.RIGHT: return DIRECTION.FORCE_RIGHT; default: return direction; } } function escapeRegExp(str) { return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1'); } function objectIncludes(b, a) { if (a === b) return true; const arrA = Array.isArray(a), arrB = Array.isArray(b); let i; if (arrA && arrB) { if (a.length != b.length) return false; for (i = 0; i < a.length; i++) if (!objectIncludes(a[i], b[i])) return false; return true; } if (arrA != arrB) return false; if (a && b && typeof a === 'object' && typeof b === 'object') { const dateA = a instanceof Date, dateB = b instanceof Date; if (dateA && dateB) return a.getTime() == b.getTime(); if (dateA != dateB) return false; const regexpA = a instanceof RegExp, regexpB = b instanceof RegExp; if (regexpA && regexpB) return a.toString() == b.toString(); if (regexpA != regexpB) return false; const keys = Object.keys(a); for (i = 0; i < keys.length; i++) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = 0; i < keys.length; i++) if (!objectIncludes(b[keys[i]], a[keys[i]])) return false; return true; } else if (a && b && typeof a === 'function' && typeof b === 'function') { return a.toString() === b.toString(); } return false; } class ActionDetails { constructor(opts) { Object.assign(this, opts); while (this.value.slice(0, this.startChangePos) !== this.oldValue.slice(0, this.startChangePos)) { --this.oldSelection.start; } if (this.insertedCount) { while (this.value.slice(this.cursorPos) !== this.oldValue.slice(this.oldSelection.end)) { if (this.value.length - this.cursorPos < this.oldValue.length - this.oldSelection.end) ++this.oldSelection.end;else ++this.cursorPos; } } } get startChangePos() { return Math.min(this.cursorPos, this.oldSelection.start); } get insertedCount() { return this.cursorPos - this.startChangePos; } get inserted() { return this.value.substr(this.startChangePos, this.insertedCount); } get removedCount() { return Math.max(this.oldSelection.end - this.startChangePos || this.oldValue.length - this.value.length, 0); } get removed() { return this.oldValue.substr(this.startChangePos, this.removedCount); } get head() { return this.value.substring(0, this.startChangePos); } get tail() { return this.value.substring(this.startChangePos + this.insertedCount); } get removeDirection() { if (!this.removedCount || this.insertedCount) return DIRECTION.NONE; return (this.oldSelection.end === this.cursorPos || this.oldSelection.start === this.cursorPos) && this.oldSelection.end === this.oldSelection.start ? DIRECTION.RIGHT : DIRECTION.LEFT; } } function IMask(el, opts) { return new IMask.InputMask(el, opts); } function maskedClass(mask) { if (mask == null) throw new Error('mask property should be defined'); if (mask instanceof RegExp) return IMask.MaskedRegExp; if (isString(mask)) return IMask.MaskedPattern; if (mask === Date) return IMask.MaskedDate; if (mask === Number) return IMask.MaskedNumber; if (Array.isArray(mask) || mask === Array) return IMask.MaskedDynamic; if (IMask.Masked && mask.prototype instanceof IMask.Masked) return mask; if (IMask.Masked && mask instanceof IMask.Masked) return mask.constructor; if (mask instanceof Function) return IMask.MaskedFunction; console.warn('Mask not found for mask', mask); return IMask.Masked; } function normalizeOpts(opts) { if (!opts) throw new Error('Options in not defined'); if (IMask.Masked) { if (opts.prototype instanceof IMask.Masked) return { mask: opts }; const { mask = undefined, ...instanceOpts } = opts instanceof IMask.Masked ? { mask: opts } : isObject(opts) && opts.mask instanceof IMask.Masked ? opts : {}; if (mask) { const _mask = mask.mask; return { ...pick(mask, (_, k) => !k.startsWith('_')), mask: mask.constructor, _mask, ...instanceOpts }; } } if (!isObject(opts)) return { mask: opts }; return { ...opts }; } function createMask(opts) { if (IMask.Masked && opts instanceof IMask.Masked) return opts; const nOpts = normalizeOpts(opts); const MaskedClass = maskedClass(nOpts.mask); if (!MaskedClass) throw new Error("Masked class is not found for provided mask " + nOpts.mask + ", appropriate module needs to be imported manually before creating mask."); if (nOpts.mask === MaskedClass) delete nOpts.mask; if (nOpts._mask) { nOpts.mask = nOpts._mask; delete nOpts._mask; } return new MaskedClass(nOpts); } IMask.createMask = createMask; class MaskElement { get selectionStart() { let start; try { start = this._unsafeSelectionStart; } catch {} return start != null ? start : this.value.length; } get selectionEnd() { let end; try { end = this._unsafeSelectionEnd; } catch {} return end != null ? end : this.value.length; } select(start, end) { if (start == null || end == null || start === this.selectionStart && end === this.selectionEnd) return; try { this._unsafeSelect(start, end); } catch {} } get isActive() { return false; } } IMask.MaskElement = MaskElement; const KEY_Z = 90; const KEY_Y = 89; class HTMLMaskElement extends MaskElement { constructor(input) { super(); this.input = input; this._onKeydown = this._onKeydown.bind(this); this._onInput = this._onInput.bind(this); this._onBeforeinput = this._onBeforeinput.bind(this); this._onCompositionEnd = this._onCompositionEnd.bind(this); } get rootElement() { var _this$input$getRootNo, _this$input$getRootNo2, _this$input; return (_this$input$getRootNo = (_this$input$getRootNo2 = (_this$input = this.input).getRootNode) == null ? void 0 : _this$input$getRootNo2.call(_this$input)) != null ? _this$input$getRootNo : document; } get isActive() { return this.input === this.rootElement.activeElement; } bindEvents(handlers) { this.input.addEventListener('keydown', this._onKeydown); this.input.addEventListener('input', this._onInput); this.input.addEventListener('beforeinput', this._onBeforeinput); this.input.addEventListener('compositionend', this._onCompositionEnd); this.input.addEventListener('drop', handlers.drop); this.input.addEventListener('click', handlers.click); this.input.addEventListener('focus', handlers.focus); this.input.addEventListener('blur', handlers.commit); this._handlers = handlers; } _onKeydown(e) { if (this._handlers.redo && (e.keyCode === KEY_Z && e.shiftKey && (e.metaKey || e.ctrlKey) || e.keyCode === KEY_Y && e.ctrlKey)) { e.preventDefault(); return this._handlers.redo(e); } if (this._handlers.undo && e.keyCode === KEY_Z && (e.metaKey || e.ctrlKey)) { e.preventDefault(); return this._handlers.undo(e); } if (!e.isComposing) this._handlers.selectionChange(e); } _onBeforeinput(e) { if (e.inputType === 'historyUndo' && this._handlers.undo) { e.preventDefault(); return this._handlers.undo(e); } if (e.inputType === 'historyRedo' && this._handlers.redo) { e.preventDefault(); return this._handlers.redo(e); } } _onCompositionEnd(e) { this._handlers.input(e); } _onInput(e) { if (!e.isComposing) this._handlers.input(e); } unbindEvents() { this.input.removeEventListener('keydown', this._onKeydown); this.input.removeEventListener('input', this._onInput); this.input.removeEventListener('beforeinput', this._onBeforeinput); this.input.removeEventListener('compositionend', this._onCompositionEnd); this.input.removeEventListener('drop', this._handlers.drop); this.input.removeEventListener('click', this._handlers.click); this.input.removeEventListener('focus', this._handlers.focus); this.input.removeEventListener('blur', this._handlers.commit); this._handlers = {}; } } IMask.HTMLMaskElement = HTMLMaskElement; class HTMLInputMaskElement extends HTMLMaskElement { constructor(input) { super(input); this.input = input; } get _unsafeSelectionStart() { return this.input.selectionStart != null ? this.input.selectionStart : this.value.length; } get _unsafeSelectionEnd() { return this.input.selectionEnd; } _unsafeSelect(start, end) { this.input.setSelectionRange(start, end); } get value() { return this.input.value; } set value(value) { this.input.value = value; } } IMask.HTMLMaskElement = HTMLMaskElement; class HTMLContenteditableMaskElement extends HTMLMaskElement { get _unsafeSelectionStart() { const root = this.rootElement; const selection = root.getSelection && root.getSelection(); const anchorOffset = selection && selection.anchorOffset; const focusOffset = selection && selection.focusOffset; if (focusOffset == null || anchorOffset == null || anchorOffset < focusOffset) { return anchorOffset; } return focusOffset; } get _unsafeSelectionEnd() { const root = this.rootElement; const selection = root.getSelection && root.getSelection(); const anchorOffset = selection && selection.anchorOffset; const focusOffset = selection && selection.focusOffset; if (focusOffset == null || anchorOffset == null || anchorOffset > focusOffset) { return anchorOffset; } return focusOffset; } _unsafeSelect(start, end) { if (!this.rootElement.createRange) return; const range = this.rootElement.createRange(); range.setStart(this.input.firstChild || this.input, start); range.setEnd(this.input.lastChild || this.input, end); const root = this.rootElement; const selection = root.getSelection && root.getSelection(); if (selection) { selection.removeAllRanges(); selection.addRange(range); } } get value() { return this.input.textContent || ''; } set value(value) { this.input.textContent = value; } } IMask.HTMLContenteditableMaskElement = HTMLContenteditableMaskElement; class InputHistory { constructor() { this.states = []; this.currentIndex = 0; } get currentState() { return this.states[this.currentIndex]; } get isEmpty() { return this.states.length === 0; } push(state) { if (this.currentIndex < this.states.length - 1) this.states.length = this.currentIndex + 1; this.states.push(state); if (this.states.length > InputHistory.MAX_LENGTH) this.states.shift(); this.currentIndex = this.states.length - 1; } go(steps) { this.currentIndex = Math.min(Math.max(this.currentIndex + steps, 0), this.states.length - 1); return this.currentState; } undo() { return this.go(-1); } redo() { return this.go(+1); } clear() { this.states.length = 0; this.currentIndex = 0; } } InputHistory.MAX_LENGTH = 100; class InputMask { constructor(el, opts) { this.el = el instanceof MaskElement ? el : el.isContentEditable && el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA' ? new HTMLContenteditableMaskElement(el) : new HTMLInputMaskElement(el); this.masked = createMask(opts); this._listeners = {}; this._value = ''; this._unmaskedValue = ''; this._rawInputValue = ''; this.history = new InputHistory(); this._saveSelection = this._saveSelection.bind(this); this._onInput = this._onInput.bind(this); this._onChange = this._onChange.bind(this); this._onDrop = this._onDrop.bind(this); this._onFocus = this._onFocus.bind(this); this._onClick = this._onClick.bind(this); this._onUndo = this._onUndo.bind(this); this._onRedo = this._onRedo.bind(this); this.alignCursor = this.alignCursor.bind(this); this.alignCursorFriendly = this.alignCursorFriendly.bind(this); this._bindEvents(); this.updateValue(); this._onChange(); } maskEquals(mask) { var _this$masked; return mask == null || ((_this$masked = this.masked) == null ? void 0 : _this$masked.maskEquals(mask)); } get mask() { return this.masked.mask; } set mask(mask) { if (this.maskEquals(mask)) return; if (!(mask instanceof IMask.Masked) && this.masked.constructor === maskedClass(mask)) { this.masked.updateOptions({ mask }); return; } const masked = mask instanceof IMask.Masked ? mask : createMask({ mask }); masked.unmaskedValue = this.masked.unmaskedValue; this.masked = masked; } get value() { return this._value; } set value(str) { if (this.value === str) return; this.masked.value = str; this.updateControl('auto'); } get unmaskedValue() { return this._unmaskedValue; } set unmaskedValue(str) { if (this.unmaskedValue === str) return; this.masked.unmaskedValue = str; this.updateControl('auto'); } get rawInputValue() { return this._rawInputValue; } set rawInputValue(str) { if (this.rawInputValue === str) return; this.masked.rawInputValue = str; this.updateControl(); this.alignCursor(); } get typedValue() { return this.masked.typedValue; } set typedValue(val) { if (this.masked.typedValueEquals(val)) return; this.masked.typedValue = val; this.updateControl('auto'); } get displayValue() { return this.masked.displayValue; } _bindEvents() { this.el.bindEvents({ selectionChange: this._saveSelection, input: this._onInput, drop: this._onDrop, click: this._onClick, focus: this._onFocus, commit: this._onChange, undo: this._onUndo, redo: this._onRedo }); } _unbindEvents() { if (this.el) this.el.unbindEvents(); } _fireEvent(ev, e) { const listeners = this._listeners[ev]; if (!listeners) return; listeners.forEach(l => l(e)); } get selectionStart() { return this._cursorChanging ? this._changingCursorPos : this.el.selectionStart; } get cursorPos() { return this._cursorChanging ? this._changingCursorPos : this.el.selectionEnd; } set cursorPos(pos) { if (!this.el || !this.el.isActive) return; this.el.select(pos, pos); this._saveSelection(); } _saveSelection( ) { if (this.displayValue !== this.el.value) { console.warn('Element value was changed outside of mask. Syncronize mask using `mask.updateValue()` to work properly.'); } this._selection = { start: this.selectionStart, end: this.cursorPos }; } updateValue() { this.masked.value = this.el.value; this._value = this.masked.value; this._unmaskedValue = this.masked.unmaskedValue; this._rawInputValue = this.masked.rawInputValue; } updateControl(cursorPos) { const newUnmaskedValue = this.masked.unmaskedValue; const newValue = this.masked.value; const newRawInputValue = this.masked.rawInputValue; const newDisplayValue = this.displayValue; const isChanged = this.unmaskedValue !== newUnmaskedValue || this.value !== newValue || this._rawInputValue !== newRawInputValue; this._unmaskedValue = newUnmaskedValue; this._value = newValue; this._rawInputValue = newRawInputValue; if (this.el.value !== newDisplayValue) this.el.value = newDisplayValue; if (cursorPos === 'auto') this.alignCursor();else if (cursorPos != null) this.cursorPos = cursorPos; if (isChanged) this._fireChangeEvents(); if (!this._historyChanging && (isChanged || this.history.isEmpty)) this.history.push({ unmaskedValue: newUnmaskedValue, selection: { start: this.selectionStart, end: this.cursorPos } }); } updateOptions(opts) { const { mask, ...restOpts } = opts; const updateMask = !this.maskEquals(mask); const updateOpts = this.masked.optionsIsChanged(restOpts); if (updateMask) this.mask = mask; if (updateOpts) this.masked.updateOptions(restOpts); if (updateMask || updateOpts) this.updateControl(); } updateCursor(cursorPos) { if (cursorPos == null) return; this.cursorPos = cursorPos; this._delayUpdateCursor(cursorPos); } _delayUpdateCursor(cursorPos) { this._abortUpdateCursor(); this._changingCursorPos = cursorPos; this._cursorChanging = setTimeout(() => { if (!this.el) return; this.cursorPos = this._changingCursorPos; this._abortUpdateCursor(); }, 10); } _fireChangeEvents() { this._fireEvent('accept', this._inputEvent); if (this.masked.isComplete) this._fireEvent('complete', this._inputEvent); } _abortUpdateCursor() { if (this._cursorChanging) { clearTimeout(this._cursorChanging); delete this._cursorChanging; } } alignCursor() { this.cursorPos = this.masked.nearestInputPos(this.masked.nearestInputPos(this.cursorPos, DIRECTION.LEFT)); } alignCursorFriendly() { if (this.selectionStart !== this.cursorPos) return; this.alignCursor(); } on(ev, handler) { if (!this._listeners[ev]) this._listeners[ev] = []; this._listeners[ev].push(handler); return this; } off(ev, handler) { if (!this._listeners[ev]) return this; if (!handler) { delete this._listeners[ev]; return this; } const hIndex = this._listeners[ev].indexOf(handler); if (hIndex >= 0) this._listeners[ev].splice(hIndex, 1); return this; } _onInput(e) { this._inputEvent = e; this._abortUpdateCursor(); const details = new ActionDetails({ value: this.el.value, cursorPos: this.cursorPos, oldValue: this.displayValue, oldSelection: this._selection }); const oldRawValue = this.masked.rawInputValue; const offset = this.masked.splice(details.startChangePos, details.removed.length, details.inserted, details.removeDirection, { input: true, raw: true }).offset; const removeDirection = oldRawValue === this.masked.rawInputValue ? details.removeDirection : DIRECTION.NONE; let cursorPos = this.masked.nearestInputPos(details.startChangePos + offset, removeDirection); if (removeDirection !== DIRECTION.NONE) cursorPos = this.masked.nearestInputPos(cursorPos, DIRECTION.NONE); this.updateControl(cursorPos); delete this._inputEvent; } _onChange() { if (this.displayValue !== this.el.value) this.updateValue(); this.masked.doCommit(); this.updateControl(); this._saveSelection(); } _onDrop(ev) { ev.preventDefault(); ev.stopPropagation(); } _onFocus(ev) { this.alignCursorFriendly(); } _onClick(ev) { this.alignCursorFriendly(); } _onUndo() { this._applyHistoryState(this.history.undo()); } _onRedo() { this._applyHistoryState(this.history.redo()); } _applyHistoryState(state) { if (!state) return; this._historyChanging = true; this.unmaskedValue = state.unmaskedValue; this.el.select(state.selection.start, state.selection.end); this._saveSelection(); this._historyChanging = false; } destroy() { this._unbindEvents(); this._listeners.length = 0; delete this.el; } } IMask.InputMask = InputMask; class ChangeDetails { static normalize(prep) { return Array.isArray(prep) ? prep : [prep, new ChangeDetails()]; } constructor(details) { Object.assign(this, { inserted: '', rawInserted: '', tailShift: 0, skip: false }, details); } aggregate(details) { this.inserted += details.inserted; this.rawInserted += details.rawInserted; this.tailShift += details.tailShift; this.skip = this.skip || details.skip; return this; } get offset() { return this.tailShift + this.inserted.length; } get consumed() { return Boolean(this.rawInserted) || this.skip; } equals(details) { return this.inserted === details.inserted && this.tailShift === details.tailShift && this.rawInserted === details.rawInserted && this.skip === details.skip; } } IMask.ChangeDetails = ChangeDetails; class ContinuousTailDetails { constructor(value, from, stop) { if (value === void 0) { value = ''; } if (from === void 0) { from = 0; } this.value = value; this.from = from; this.stop = stop; } toString() { return this.value; } extend(tail) { this.value += String(tail); } appendTo(masked) { return masked.append(this.toString(), { tail: true }).aggregate(masked._appendPlaceholder()); } get state() { return { value: this.value, from: this.from, stop: this.stop }; } set state(state) { Object.assign(this, state); } unshift(beforePos) { if (!this.value.length || beforePos != null && this.from >= beforePos) return ''; const shiftChar = this.value[0]; this.value = this.value.slice(1); return shiftChar; } shift() { if (!this.value.length) return ''; const shiftChar = this.value[this.value.length - 1]; this.value = this.value.slice(0, -1); return shiftChar; } } class Masked { constructor(opts) { this._value = ''; this._update({ ...Masked.DEFAULTS, ...opts }); this._initialized = true; } updateOptions(opts) { if (!this.optionsIsChanged(opts)) return; this.withValueRefresh(this._update.bind(this, opts)); } _update(opts) { Object.assign(this, opts); } get state() { return { _value: this.value, _rawInputValue: this.rawInputValue }; } set state(state) { this._value = state._value; } reset() { this._value = ''; } get value() { return this._value; } set value(value) { this.resolve(value, { input: true }); } resolve(value, flags) { if (flags === void 0) { flags = { input: true }; } this.reset(); this.append(value, flags, ''); this.doCommit(); } get unmaskedValue() { return this.value; } set unmaskedValue(value) { this.resolve(value, {}); } get typedValue() { return this.parse ? this.parse(this.value, this) : this.unmaskedValue; } set typedValue(value) { if (this.format) { this.value = this.format(value, this); } else { this.unmaskedValue = String(value); } } get rawInputValue() { return this.extractInput(0, this.displayValue.length, { raw: true }); } set rawInputValue(value) { this.resolve(value, { raw: true }); } get displayValue() { return this.value; } get isComplete() { return true; } get isFilled() { return this.isComplete; } nearestInputPos(cursorPos, direction) { return cursorPos; } totalInputPositions(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } return Math.min(this.displayValue.length, toPos - fromPos); } extractInput(fromPos, toPos, flags) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } return this.displayValue.slice(fromPos, toPos); } extractTail(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } return new ContinuousTailDetails(this.extractInput(fromPos, toPos), fromPos); } appendTail(tail) { if (isString(tail)) tail = new ContinuousTailDetails(String(tail)); return tail.appendTo(this); } _appendCharRaw(ch, flags) { if (!ch) return new ChangeDetails(); this._value += ch; return new ChangeDetails({ inserted: ch, rawInserted: ch }); } _appendChar(ch, flags, checkTail) { if (flags === void 0) { flags = {}; } const consistentState = this.state; let details; [ch, details] = this.doPrepareChar(ch, flags); if (ch) { details = details.aggregate(this._appendCharRaw(ch, flags)); if (!details.rawInserted && this.autofix === 'pad') { const noFixState = this.state; this.state = consistentState; let fixDetails = this.pad(flags); const chDetails = this._appendCharRaw(ch, flags); fixDetails = fixDetails.aggregate(chDetails); if (chDetails.rawInserted || fixDetails.equals(details)) { details = fixDetails; } else { this.state = noFixState; } } } if (details.inserted) { let consistentTail; let appended = this.doValidate(flags) !== false; if (appended && checkTail != null) { const beforeTailState = this.state; if (this.overwrite === true) { consistentTail = checkTail.state; for (let i = 0; i < details.rawInserted.length; ++i) { checkTail.unshift(this.displayValue.length - details.tailShift); } } let tailDetails = this.appendTail(checkTail); appended = tailDetails.rawInserted.length === checkTail.toString().length; if (!(appended && tailDetails.inserted) && this.overwrite === 'shift') { this.state = beforeTailState; consistentTail = checkTail.state; for (let i = 0; i < details.rawInserted.length; ++i) { checkTail.shift(); } tailDetails = this.appendTail(checkTail); appended = tailDetails.rawInserted.length === checkTail.toString().length; } if (appended && tailDetails.inserted) this.state = beforeTailState; } if (!appended) { details = new ChangeDetails(); this.state = consistentState; if (checkTail && consistentTail) checkTail.state = consistentTail; } } return details; } _appendPlaceholder() { return new ChangeDetails(); } _appendEager() { return new ChangeDetails(); } append(str, flags, tail) { if (!isString(str)) throw new Error('value should be string'); const checkTail = isString(tail) ? new ContinuousTailDetails(String(tail)) : tail; if (flags != null && flags.tail) flags._beforeTailState = this.state; let details; [str, details] = this.doPrepare(str, flags); for (let ci = 0; ci < str.length; ++ci) { const d = this._appendChar(str[ci], flags, checkTail); if (!d.rawInserted && !this.doSkipInvalid(str[ci], flags, checkTail)) break; details.aggregate(d); } if ((this.eager === true || this.eager === 'append') && flags != null && flags.input && str) { details.aggregate(this._appendEager()); } if (checkTail != null) { details.tailShift += this.appendTail(checkTail).tailShift; } return details; } remove(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.displayValue.length; } this._value = this.displayValue.slice(0, fromPos) + this.displayValue.slice(toPos); return new ChangeDetails(); } withValueRefresh(fn) { if (this._refreshing || !this._initialized) return fn(); this._refreshing = true; const rawInput = this.rawInputValue; const value = this.value; const ret = fn(); this.rawInputValue = rawInput; if (this.value && this.value !== value && value.indexOf(this.value) === 0) { this.append(value.slice(this.displayValue.length), {}, ''); this.doCommit(); } delete this._refreshing; return ret; } runIsolated(fn) { if (this._isolated || !this._initialized) return fn(this); this._isolated = true; const state = this.state; const ret = fn(this); this.state = state; delete this._isolated; return ret; } doSkipInvalid(ch, flags, checkTail) { return Boolean(this.skipInvalid); } doPrepare(str, flags) { if (flags === void 0) { flags = {}; } return ChangeDetails.normalize(this.prepare ? this.prepare(str, this, flags) : str); } doPrepareChar(str, flags) { if (flags === void 0) { flags = {}; } return ChangeDetails.normalize(this.prepareChar ? this.prepareChar(str, this, flags) : str); } doValidate(flags) { return (!this.validate || this.validate(this.value, this, flags)) && (!this.parent || this.parent.doValidate(flags)); } doCommit() { if (this.commit) this.commit(this.value, this); } splice(start, deleteCount, inserted, removeDirection, flags) { if (inserted === void 0) { inserted = ''; } if (removeDirection === void 0) { removeDirection = DIRECTION.NONE; } if (flags === void 0) { flags = { input: true }; } const tailPos = start + deleteCount; const tail = this.extractTail(tailPos); const eagerRemove = this.eager === true || this.eager === 'remove'; let oldRawValue; if (eagerRemove) { removeDirection = forceDirection(removeDirection); oldRawValue = this.extractInput(0, tailPos, { raw: true }); } let startChangePos = start; const details = new ChangeDetails(); if (removeDirection !== DIRECTION.NONE) { startChangePos = this.nearestInputPos(start, deleteCount > 1 && start !== 0 && !eagerRemove ? DIRECTION.NONE : removeDirection); details.tailShift = startChangePos - start; } details.aggregate(this.remove(startChangePos)); if (eagerRemove && removeDirection !== DIRECTION.NONE && oldRawValue === this.rawInputValue) { if (removeDirection === DIRECTION.FORCE_LEFT) { let valLength; while (oldRawValue === this.rawInputValue && (valLength = this.displayValue.length)) { details.aggregate(new ChangeDetails({ tailShift: -1 })).aggregate(this.remove(valLength - 1)); } } else if (removeDirection === DIRECTION.FORCE_RIGHT) { tail.unshift(); } } return details.aggregate(this.append(inserted, flags, tail)); } maskEquals(mask) { return this.mask === mask; } optionsIsChanged(opts) { return !objectIncludes(this, opts); } typedValueEquals(value) { const tval = this.typedValue; return value === tval || Masked.EMPTY_VALUES.includes(value) && Masked.EMPTY_VALUES.includes(tval) || (this.format ? this.format(value, this) === this.format(this.typedValue, this) : false); } pad(flags) { return new ChangeDetails(); } } Masked.DEFAULTS = { skipInvalid: true }; Masked.EMPTY_VALUES = [undefined, null, '']; IMask.Masked = Masked; class ChunksTailDetails { constructor(chunks, from) { if (chunks === void 0) { chunks = []; } if (from === void 0) { from = 0; } this.chunks = chunks; this.from = from; } toString() { return this.chunks.map(String).join(''); } extend(tailChunk) { if (!String(tailChunk)) return; tailChunk = isString(tailChunk) ? new ContinuousTailDetails(String(tailChunk)) : tailChunk; const lastChunk = this.chunks[this.chunks.length - 1]; const extendLast = lastChunk && ( lastChunk.stop === tailChunk.stop || tailChunk.stop == null) && tailChunk.from === lastChunk.from + lastChunk.toString().length; if (tailChunk instanceof ContinuousTailDetails) { if (extendLast) { lastChunk.extend(tailChunk.toString()); } else { this.chunks.push(tailChunk); } } else if (tailChunk instanceof ChunksTailDetails) { if (tailChunk.stop == null) { let firstTailChunk; while (tailChunk.chunks.length && tailChunk.chunks[0].stop == null) { firstTailChunk = tailChunk.chunks.shift(); firstTailChunk.from += tailChunk.from; this.extend(firstTailChunk); } } if (tailChunk.toString()) { tailChunk.stop = tailChunk.blockIndex; this.chunks.push(tailChunk); } } } appendTo(masked) { if (!(masked instanceof IMask.MaskedPattern)) { const tail = new ContinuousTailDetails(this.toString()); return tail.appendTo(masked); } const details = new ChangeDetails(); for (let ci = 0; ci < this.chunks.length; ++ci) { const chunk = this.chunks[ci]; const lastBlockIter = masked._mapPosToBlock(masked.displayValue.length); const stop = chunk.stop; let chunkBlock; if (stop != null && ( !lastBlockIter || lastBlockIter.index <= stop)) { if (chunk instanceof ChunksTailDetails || masked._stops.indexOf(stop) >= 0) { details.aggregate(masked._appendPlaceholder(stop)); } chunkBlock = chunk instanceof ChunksTailDetails && masked._blocks[stop]; } if (chunkBlock) { const tailDetails = chunkBlock.appendTail(chunk); details.aggregate(tailDetails); const remainChars = chunk.toString().slice(tailDetails.rawInserted.length); if (remainChars) details.aggregate(masked.append(remainChars, { tail: true })); } else { details.aggregate(masked.append(chunk.toString(), { tail: true })); } } return details; } get state() { return { chunks: this.chunks.map(c => c.state), from: this.from, stop: this.stop, blockIndex: this.blockIndex }; } set state(state) { const { chunks, ...props } = state; Object.assign(this, props); this.chunks = chunks.map(cstate => { const chunk = "chunks" in cstate ? new ChunksTailDetails() : new ContinuousTailDetails(); chunk.state = cstate; return chunk; }); } unshift(beforePos) { if (!this.chunks.length || beforePos != null && this.from >= beforePos) return ''; const chunkShiftPos = beforePos != null ? beforePos - this.from : beforePos; let ci = 0; while (ci < this.chunks.length) { const chunk = this.chunks[ci]; const shiftChar = chunk.unshift(chunkShiftPos); if (chunk.toString()) { if (!shiftChar) break; ++ci; } else { this.chunks.splice(ci, 1); } if (shiftChar) return shiftChar; } return ''; } shift() { if (!this.chunks.length) return ''; let ci = this.chunks.length - 1; while (0 <= ci) { const chunk = this.chunks[ci]; const shiftChar = chunk.shift(); if (chunk.toString()) { if (!shiftChar) break; --ci; } else { this.chunks.splice(ci, 1); } if (shiftChar) return shiftChar; } return ''; } } class PatternCursor { constructor(masked, pos) { this.masked = masked; this._log = []; const { offset, index } = masked._mapPosToBlock(pos) || (pos < 0 ? { index: 0, offset: 0 } : { index: this.masked._blocks.length, offset: 0 }); this.offset = offset; this.index = index; this.ok = false; } get block() { return this.masked._blocks[this.index]; } get pos() { return this.masked._blockStartPos(this.index) + this.offset; } get state() { return { index: this.index, offset: this.offset, ok: this.ok }; } set state(s) { Object.assign(this, s); } pushState() { this._log.push(this.state); } popState() { const s = this._log.pop(); if (s) this.state = s; return s; } bindBlock() { if (this.block) return; if (this.index < 0) { this.index = 0; this.offset = 0; } if (this.index >= this.masked._blocks.length) { this.index = this.masked._blocks.length - 1; this.offset = this.block.displayValue.length; } } _pushLeft(fn) { this.pushState(); for (this.bindBlock(); 0 <= this.index; --this.index, this.offset = ((_this$block = this.block) == null ? void 0 : _this$block.displayValue.length) || 0) { var _this$block; if (fn()) return this.ok = true; } return this.ok = false; } _pushRight(fn) { this.pushState(); for (this.bindBlock(); this.index < this.masked._blocks.length; ++this.index, this.offset = 0) { if (fn()) return this.ok = true; } return this.ok = false; } pushLeftBeforeFilled() { return this._pushLeft(() => { if (this.block.isFixed || !this.block.value) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.FORCE_LEFT); if (this.offset !== 0) return true; }); } pushLeftBeforeInput() { return this._pushLeft(() => { if (this.block.isFixed) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.LEFT); return true; }); } pushLeftBeforeRequired() { return this._pushLeft(() => { if (this.block.isFixed || this.block.isOptional && !this.block.value) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.LEFT); return true; }); } pushRightBeforeFilled() { return this._pushRight(() => { if (this.block.isFixed || !this.block.value) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.FORCE_RIGHT); if (this.offset !== this.block.value.length) return true; }); } pushRightBeforeInput() { return this._pushRight(() => { if (this.block.isFixed) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.NONE); return true; }); } pushRightBeforeRequired() { return this._pushRight(() => { if (this.block.isFixed || this.block.isOptional && !this.block.value) return; this.offset = this.block.nearestInputPos(this.offset, DIRECTION.NONE); return true; }); } } class PatternFixedDefinition { constructor(opts) { Object.assign(this, opts); this._value = ''; this.isFixed = true; } get value() { return this._value; } get unmaskedValue() { return this.isUnmasking ? this.value : ''; } get rawInputValue() { return this._isRawInput ? this.value : ''; } get displayValue() { return this.value; } reset() { this._isRawInput = false; this._value = ''; } remove(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this._value.length; } this._value = this._value.slice(0, fromPos) + this._value.slice(toPos); if (!this._value) this._isRawInput = false; return new ChangeDetails(); } nearestInputPos(cursorPos, direction) { if (direction === void 0) { direction = DIRECTION.NONE; } const minPos = 0; const maxPos = this._value.length; switch (direction) { case DIRECTION.LEFT: case DIRECTION.FORCE_LEFT: return minPos; case DIRECTION.NONE: case DIRECTION.RIGHT: case DIRECTION.FORCE_RIGHT: default: return maxPos; } } totalInputPositions(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this._value.length; } return this._isRawInput ? toPos - fromPos : 0; } extractInput(fromPos, toPos, flags) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this._value.length; } if (flags === void 0) { flags = {}; } return flags.raw && this._isRawInput && this._value.slice(fromPos, toPos) || ''; } get isComplete() { return true; } get isFilled() { return Boolean(this._value); } _appendChar(ch, flags) { if (flags === void 0) { flags = {}; } if (this.isFilled) return new ChangeDetails(); const appendEager = this.eager === true || this.eager === 'append'; const appended = this.char === ch; const isResolved = appended && (this.isUnmasking || flags.input || flags.raw) && (!flags.raw || !appendEager) && !flags.tail; const details = new ChangeDetails({ inserted: this.char, rawInserted: isResolved ? this.char : '' }); this._value = this.char; this._isRawInput = isResolved && (flags.raw || flags.input); return details; } _appendEager() { return this._appendChar(this.char, { tail: true }); } _appendPlaceholder() { const details = new ChangeDetails(); if (this.isFilled) return details; this._value = details.inserted = this.char; return details; } extractTail() { return new ContinuousTailDetails(''); } appendTail(tail) { if (isString(tail)) tail = new ContinuousTailDetails(String(tail)); return tail.appendTo(this); } append(str, flags, tail) { const details = this._appendChar(str[0], flags); if (tail != null) { details.tailShift += this.appendTail(tail).tailShift; } return details; } doCommit() {} get state() { return { _value: this._value, _rawInputValue: this.rawInputValue }; } set state(state) { this._value = state._value; this._isRawInput = Boolean(state._rawInputValue); } pad(flags) { return this._appendPlaceholder(); } } class PatternInputDefinition { constructor(opts) { const { parent, isOptional, placeholderChar, displayChar, lazy, eager, ...maskOpts } = opts; this.masked = createMask(maskOpts); Object.assign(this, { parent, isOptional, placeholderChar, displayChar, lazy, eager }); } reset() { this.isFilled = false; this.masked.reset(); } remove(fromPos, toPos) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.value.length; } if (fromPos === 0 && toPos >= 1) { this.isFilled = false; return this.masked.remove(fromPos, toPos); } return new ChangeDetails(); } get value() { return this.masked.value || (this.isFilled && !this.isOptional ? this.placeholderChar : ''); } get unmaskedValue() { return this.masked.unmaskedValue; } get rawInputValue() { return this.masked.rawInputValue; } get displayValue() { return this.masked.value && this.displayChar || this.value; } get isComplete() { return Boolean(this.masked.value) || this.isOptional; } _appendChar(ch, flags) { if (flags === void 0) { flags = {}; } if (this.isFilled) return new ChangeDetails(); const state = this.masked.state; let details = this.masked._appendChar(ch, this.currentMaskFlags(flags)); if (details.inserted && this.doValidate(flags) === false) { details = new ChangeDetails(); this.masked.state = state; } if (!details.inserted && !this.isOptional && !this.lazy && !flags.input) { details.inserted = this.placeholderChar; } details.skip = !details.inserted && !this.isOptional; this.isFilled = Boolean(details.inserted); return details; } append(str, flags, tail) { return this.masked.append(str, this.currentMaskFlags(flags), tail); } _appendPlaceholder() { if (this.isFilled || this.isOptional) return new ChangeDetails(); this.isFilled = true; return new ChangeDetails({ inserted: this.placeholderChar }); } _appendEager() { return new ChangeDetails(); } extractTail(fromPos, toPos) { return this.masked.extractTail(fromPos, toPos); } appendTail(tail) { return this.masked.appendTail(tail); } extractInput(fromPos, toPos, flags) { if (fromPos === void 0) { fromPos = 0; } if (toPos === void 0) { toPos = this.value.length; } return this.masked.extractInput(fromPos, toPos, flags); } nearestInputPos(cursorPos, direction) { if (direction === void 0) { direction = DIRECTION.NONE; } const minPos = 0; const maxPos = this.value.length; const boundPos = Math.min(Math.max(cursorPos, minPos), maxPos); switch (direction) { case DIRECTION.LEFT: case DIRECTION.FORCE_LEFT: return this.isComplete ? boundPos : minPos; case DIRECTION.RIGHT: case DIRECTION.FORCE_RIGHT: return this.isComplete ? boundPos : maxPos; case DIRECTION.NONE: