tsgrid-ui 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +229 -0
- package/dist/base.d.ts +148 -0
- package/dist/base.es6.js +11 -0
- package/dist/base.es6.js.map +1 -0
- package/dist/chunks/chunk-26XP2XU3.js +1795 -0
- package/dist/chunks/chunk-26XP2XU3.js.map +1 -0
- package/dist/chunks/chunk-3NYH6545.js +2423 -0
- package/dist/chunks/chunk-3NYH6545.js.map +1 -0
- package/dist/chunks/chunk-BIB3X2TW.js +1638 -0
- package/dist/chunks/chunk-BIB3X2TW.js.map +1 -0
- package/dist/chunks/chunk-DXZJHS4M.js +1283 -0
- package/dist/chunks/chunk-DXZJHS4M.js.map +1 -0
- package/dist/chunks/chunk-EVZMMVXO.js +1212 -0
- package/dist/chunks/chunk-EVZMMVXO.js.map +1 -0
- package/dist/chunks/chunk-GJD5NFWQ.js +2305 -0
- package/dist/chunks/chunk-GJD5NFWQ.js.map +1 -0
- package/dist/chunks/chunk-IYF3Q7GX.js +127 -0
- package/dist/chunks/chunk-IYF3Q7GX.js.map +1 -0
- package/dist/chunks/chunk-OFASTA2A.js +2980 -0
- package/dist/chunks/chunk-OFASTA2A.js.map +1 -0
- package/dist/chunks/chunk-OMLGN735.js +677 -0
- package/dist/chunks/chunk-OMLGN735.js.map +1 -0
- package/dist/chunks/chunk-WKSLGUB3.js +1127 -0
- package/dist/chunks/chunk-WKSLGUB3.js.map +1 -0
- package/dist/chunks/chunk-YBY52G2U.js +849 -0
- package/dist/chunks/chunk-YBY52G2U.js.map +1 -0
- package/dist/field.d.ts +329 -0
- package/dist/field.es6.js +11 -0
- package/dist/field.es6.js.map +1 -0
- package/dist/form.d.ts +162 -0
- package/dist/form.es6.js +14 -0
- package/dist/form.es6.js.map +1 -0
- package/dist/layout.d.ts +108 -0
- package/dist/layout.es6.js +13 -0
- package/dist/layout.es6.js.map +1 -0
- package/dist/locale.d.ts +30 -0
- package/dist/locale.es6.js +7 -0
- package/dist/locale.es6.js.map +1 -0
- package/dist/metafile-esm.json +1 -0
- package/dist/popup.d.ts +92 -0
- package/dist/popup.es6.js +18 -0
- package/dist/popup.es6.js.map +1 -0
- package/dist/query-CKGg5Ugv.d.ts +81 -0
- package/dist/sidebar.d.ts +138 -0
- package/dist/sidebar.es6.js +11 -0
- package/dist/sidebar.es6.js.map +1 -0
- package/dist/tabs.d.ts +63 -0
- package/dist/tabs.es6.js +11 -0
- package/dist/tabs.es6.js.map +1 -0
- package/dist/toolbar.d.ts +97 -0
- package/dist/toolbar.es6.js +11 -0
- package/dist/toolbar.es6.js.map +1 -0
- package/dist/tooltip.d.ts +322 -0
- package/dist/tooltip.es6.js +18 -0
- package/dist/tooltip.es6.js.map +1 -0
- package/dist/tsgrid-ui.css +2 -2
- package/dist/tsgrid-ui.d.ts +16 -2004
- package/dist/tsgrid-ui.es6.js +7750 -23831
- package/dist/tsgrid-ui.es6.js.map +1 -1
- package/dist/tsgrid-ui.es6.min.js +28 -28
- package/dist/tsgrid-ui.js +103 -25
- package/dist/tsgrid-ui.min.css +2 -2
- package/dist/tsgrid-ui.min.js +24 -24
- package/dist/tsutils-message-CogFtVtO.d.ts +82 -0
- package/dist/utils.d.ts +418 -0
- package/dist/utils.es6.js +14 -0
- package/dist/utils.es6.js.map +1 -0
- package/package.json +26 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/tsutils-color.ts","../../src/tsutils-string.ts","../../src/tsutils-marker.ts","../../src/tsutils-notify.ts","../../src/tsutils-message.ts","../../src/tsutils-dom.ts","../../src/tsutils-datetime.ts","../../src/tsutils-locale.ts","../../src/tsutils.ts"],"sourcesContent":["/**\n * Part of TsUi 2.0 library — color cluster sub-module\n * - Extracted from src/tsutils.ts by v2.1 SDD refactor (Phase 2)\n * - No dependencies on TsBase, TsUtils, or any other sub-module (L1 DAG leaf)\n * - All exports are plain functions — no default export\n *\n * 4-space indent (project convention for sub-modules).\n */\n\n/** RGB(A) color as returned by parseColor() */\nexport interface TsColorRgb {\n r: number\n g: number\n b: number\n a: number\n}\n\n/**\n * Parse a color string (hex, RGB, RGBA) into a TsColorRgb object.\n * Returns null for unrecognised input (word colors, empty strings, etc.).\n */\nexport function parseColor(str: string | null | undefined): TsColorRgb | null {\n if (typeof str !== 'string') return null; else str = str.trim().toUpperCase()\n if (str[0] === '#') str = str.substr(1)\n let color: TsColorRgb = { r: 0, g: 0, b: 0, a: 1 }\n if (str.length === 3) {\n const s0 = str[0] ?? '0', s1 = str[1] ?? '0', s2 = str[2] ?? '0'\n color = {\n r: parseInt(s0 + s0, 16),\n g: parseInt(s1 + s1, 16),\n b: parseInt(s2 + s2, 16),\n a: 1\n }\n } else if (str.length === 6) {\n color = {\n r: parseInt(str.substr(0, 2), 16),\n g: parseInt(str.substr(2, 2), 16),\n b: parseInt(str.substr(4, 2), 16),\n a: 1\n }\n } else if (str.length === 8) {\n color = {\n r: parseInt(str.substr(0, 2), 16),\n g: parseInt(str.substr(2, 2), 16),\n b: parseInt(str.substr(4, 2), 16),\n a: Math.round(parseInt(str.substr(6, 2), 16) / 255 * 100) / 100 // alpha channel 0-1\n }\n } else if (str.length > 4 && str.substr(0, 4) === 'RGB(') {\n const tmp = str.replace('RGB', '').replace(/\\(/g, '').replace(/\\)/g, '').split(',')\n color = {\n r: parseInt(tmp[0] ?? '0', 10),\n g: parseInt(tmp[1] ?? '0', 10),\n b: parseInt(tmp[2] ?? '0', 10),\n a: 1\n }\n } else if (str.length > 5 && str.substr(0, 5) === 'RGBA(') {\n const tmp = str.replace('RGBA', '').replace(/\\(/g, '').replace(/\\)/g, '').split(',')\n color = {\n r: parseInt(tmp[0] ?? '0', 10),\n g: parseInt(tmp[1] ?? '0', 10),\n b: parseInt(tmp[2] ?? '0', 10),\n a: parseFloat(tmp[3] ?? '1')\n }\n } else {\n // word color\n return null\n }\n return color\n}\n\n/**\n * Compute WCAG contrast ratio between two color strings as a raw number.\n * Uses local parseColor — NOT TsUtils.parseColor (N3 fix: no back-edge in DAG).\n */\nexport function colorContrastValue(color1: string, color2: string): number {\n const lum1 = calcLumens(color1)\n const lum2 = calcLumens(color2)\n return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05)\n\n function calcLumens(color: string): number {\n const { r, g, b } = parseColor(color) ?? { r: 0, g: 0, b: 0, a: 1 }\n const gamma = 2.2\n const normR = r / 255\n const normG = g / 255\n const normB = b / 255\n const sR = (normR <= 0.03928) ? normR / 12.92 : Math.pow((normR + 0.055) / 1.055, gamma)\n const sG = (normG <= 0.03928) ? normG / 12.92 : Math.pow((normG + 0.055) / 1.055, gamma)\n const sB = (normB <= 0.03928) ? normB / 12.92 : Math.pow((normB + 0.055) / 1.055, gamma)\n return 0.2126 * sR + 0.7152 * sG + 0.0722 * sB\n }\n}\n\n/**\n * Compute WCAG contrast ratio between two color strings.\n * Returns a string formatted to 2 decimal places (e.g. \"21.00\").\n * For programmatic use prefer `colorContrastValue` (returns a number).\n */\nexport function colorContrast(color1: string, color2: string): string {\n return colorContrastValue(color1, color2).toFixed(2)\n}\n\n/**\n * Convert HSV to RGB.\n * Scales: h=0..360, s=0..100, v=0..100.\n * Dual-form: accepts either (h, s, v, a?) or a single object {h, s, v, a?}.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function hsv2rgb(h: any, s?: any, v?: any, a?: any): { r: number; g: number; b: number; a: number } { // any: overloaded — first arg can be {h,s,v,a} object or a number\n let r: number | undefined, g: number | undefined, b: number | undefined\n // typeof detection (not arguments.length): delegator pattern always forwards 4 args, so length-based dispatch breaks object-form callers\n if (typeof h === 'object' && h !== null) {\n s = h.s; v = h.v; a = h.a; h = h.h\n }\n h = h / 360\n s = s / 100\n v = v / 100\n const i = Math.floor(h * 6)\n const f = h * 6 - i\n const p = v * (1 - s)\n const q = v * (1 - f * s)\n const t = v * (1 - (1 - f) * s)\n switch (i % 6) {\n case 0: r = v, g = t, b = p; break\n case 1: r = q, g = v, b = p; break\n case 2: r = p, g = v, b = t; break\n case 3: r = p, g = q, b = v; break\n case 4: r = t, g = p, b = v; break\n case 5: r = v, g = p, b = q; break\n }\n return {\n r: Math.round((r ?? 0) * 255),\n g: Math.round((g ?? 0) * 255),\n b: Math.round((b ?? 0) * 255),\n a: (a != null ? a : 1)\n }\n}\n\n/**\n * Convert RGB to HSV.\n * Scales: r/g/b=0..255; returns h=0..360, s=0..100, v=0..100.\n * Dual-form: accepts either (r, g, b, a?) or a single object {r, g, b, a?}.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function rgb2hsv(r: any, g?: any, b?: any, a?: any): { h: number; s: number; v: number; a: number } { // any: overloaded — first arg can be {r,g,b,a} object or a number\n // typeof detection (not arguments.length): delegator pattern always forwards 4 args, so length-based dispatch breaks object-form callers\n if (typeof r === 'object' && r !== null) {\n g = r.g; b = r.b; a = r.a; r = r.r\n }\n const max = Math.max(r, g, b), min = Math.min(r, g, b),\n d = max - min\n let h: number | undefined\n const s = (max === 0 ? 0 : d / max),\n v = max / 255\n switch (max) {\n case min: h = 0; break\n case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break\n case g: h = (b - r) + d * 2; h /= 6 * d; break\n case b: h = (r - g) + d * 4; h /= 6 * d; break\n }\n return {\n h: Math.round((h ?? 0) * 360),\n s: Math.round(s * 100),\n v: Math.round(v * 100),\n a: (a != null ? a : 1)\n }\n}\n","/**\n * Part of TsUi 2.1 library\n *\n * String-helpers sub-module — extracted from TsUtils (Phase 5 of v2.1 SDD).\n * Pure functions only. No default export.\n *\n * N2 fix applied: all this.extend(...) → extend(...) (imported ref)\n * all recursive this.X(...) → X(...) (local function ref)\n */\n\nimport { extend } from './tsutils-data.js'\n\nexport function stripSpaces(html: unknown): unknown {\n if (html == null) return html\n switch (typeof html) {\n case 'number':\n break\n case 'string':\n html = String(html).replace(/(?:\\r\\n|\\r|\\n)/g, ' ').replace(/\\s\\s+/g, ' ').trim()\n break\n case 'object':\n // does not modify original object, but creates a copy\n if (Array.isArray(html)) {\n const arr = extend([], html) as unknown[]\n arr.forEach((key, ind) => { arr[ind] = stripSpaces(key) })\n return arr\n } else {\n const obj = extend({}, html) as Record<string, unknown>\n Object.keys(obj).forEach(key => { obj[key] = stripSpaces(obj[key]) })\n return obj\n }\n }\n return html\n}\n\nexport function stripTags(html: unknown): unknown {\n if (html == null) return html\n switch (typeof html) {\n case 'number':\n break\n case 'string':\n html = String(html).replace(/<(?:[^>=]|='[^']*'|=\"[^\"]*\"|=[^'\"][^\\s>]*)*>/ig, '')\n break\n case 'object':\n // does not modify original object, but creates a copy\n if (Array.isArray(html)) {\n const arr = extend([], html) as unknown[]\n arr.forEach((key, ind) => { arr[ind] = stripTags(key) })\n return arr\n } else {\n const obj = extend({}, html) as Record<string, unknown>\n Object.keys(obj).forEach(key => { obj[key] = stripTags(obj[key]) })\n return obj\n }\n }\n return html\n}\n\nexport function encodeTags(html: unknown): unknown {\n if (html == null) return html\n switch (typeof html) {\n case 'number':\n break\n case 'string':\n html = String(html).replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/\"/g, '"')\n break\n case 'object':\n // does not modify original object, but creates a copy\n if (Array.isArray(html)) {\n const arr = extend([], html) as unknown[]\n arr.forEach((key, ind) => { arr[ind] = encodeTags(key) })\n return arr\n } else {\n const obj = extend({}, html) as Record<string, unknown>\n Object.keys(obj).forEach(key => { obj[key] = encodeTags(obj[key]) })\n return obj\n }\n }\n return html\n}\n\nexport function decodeTags(html: unknown): unknown {\n if (html == null) return html\n switch (typeof html) {\n case 'number':\n break\n case 'string':\n html = String(html).replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '\"').replace(/&/g, '&')\n break\n case 'object':\n // does not modify original object, but creates a copy\n if (Array.isArray(html)) {\n const arr = extend([], html) as unknown[]\n arr.forEach((key, ind) => { arr[ind] = decodeTags(key) })\n return arr\n } else {\n const obj = extend({}, html) as Record<string, unknown>\n Object.keys(obj).forEach(key => { obj[key] = decodeTags(obj[key]) })\n return obj\n }\n }\n return html\n}\n\nexport function escapeId(id: unknown): string {\n // This logic is borrowed from jQuery\n if (id === '' || id == null) return ''\n const re = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\w-]/g\n return (id + '').replace(re, (ch, asCodePoint) => {\n if (asCodePoint) {\n if (ch === '\\0') return '�'\n return ch.slice( 0, -1 ) + '\\\\' + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + ' '\n }\n return '\\\\' + ch\n })\n}\n\nexport function unescapeId(id: string | null | undefined): string {\n // This logic is borrowed from jQuery\n if (id === '' || id == null) return ''\n const re = /\\\\[\\da-fA-F]{1,6}[\\x20\\t\\r\\n\\f]?|\\\\([^\\r\\n\\f])/g\n return id.replace(re, (escape, nonHex) => {\n const high = (parseInt('0x' + escape.slice(1), 16)) - 0x10000\n return nonHex ? nonHex : high < 0\n ? String.fromCharCode(high + 0x10000 )\n : String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00)\n })\n}\n\nexport function base64encode(str: string): string {\n // Fast Native support in Chrome since 2010\n const utf8Bytes = new TextEncoder().encode(str)\n let binaryString = ''\n for (const byte of utf8Bytes) {\n binaryString += String.fromCharCode(byte)\n }\n return btoa(binaryString)\n}\n\nexport function base64decode(encodedStr: string): string {\n // Fast Native support in Chrome since 2010\n const binaryString = atob(encodedStr)\n const utf8Bytes = new Uint8Array(binaryString.length)\n for (let i = 0; i < binaryString.length; i++) {\n utf8Bytes[i] = binaryString.charCodeAt(i)\n }\n return new TextDecoder().decode(utf8Bytes)\n}\n\nexport async function sha256(str: string): Promise<string> {\n const utf8 = new TextEncoder().encode(str)\n return crypto.subtle.digest('SHA-256', utf8).then((hashBuffer) => {\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n return hashArray.map((bytes) => bytes.toString(16).padStart(2, '0')).join('')\n })\n}\n\nexport function execTemplate(\n // any: str and replace_obj are dynamic template params; types vary by caller\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n str: any,\n // any: targeted-any per typing_policy; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n replace_obj: any\n// any: return type any — caller narrows by code path; TsUtils helper accepts heterogeneous runtime input\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n if (typeof str !== 'string' || !replace_obj || typeof replace_obj !== 'object') {\n return str\n }\n // any: $2 is the matched key from template literal, replace_obj[$2] is dynamic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return str.replace(/\\${([^}]+)?}/g, function(_$1: any, $2: any) { return replace_obj[$2]||$2 })\n}\n","/**\n * TsUtils marker sub-module — extracted pure functions for highlight/marker\n * Part of tsutils v2.1 SDD decomposition (Phase 6)\n * No default export. 4-space indent.\n */\n\nimport { query as _query, Query } from './query.js'\n// Cast query to always return Query — same pattern as tsutils.ts line 48\n// any: selector parameter is heterogeneous at call sites (string, Element, etc.)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst query = _query as (selector: any, context?: any) => Query\n\n/** Options for TsUtils.marker() */\ninterface _W2MarkerOptions {\n onlyFirst?: boolean\n wholeWord?: boolean\n isRegex?: boolean\n tag?: string\n class?: string\n raplace?: (matched: string) => string\n}\n\n// any: el is string or HTMLElement; runtime-checked via typeof\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _clearMarkers(el: any, options: _W2MarkerOptions) {\n // options.class is always set (??= 'tsg-marker') before this helper is called — non-null assertion is safe\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const markerRE = new RegExp(`<${options.tag}[^>]*class=[\"']${options.class!.replace(/-/g, '\\\\-')}[\"'][^>]*>([\\\\s\\\\S]*?)<\\\\/${options.tag}>`, 'ig')\n if (typeof el == 'string') {\n while (el.indexOf(`<${options.tag} class=\"${options.class}\"`) !== -1) {\n el = el.replace(markerRE, '$1') // unmark\n }\n } else {\n while (el.innerHTML.indexOf(`<${options.tag} class=\"${options.class}\"`) !== -1) {\n el.innerHTML = el.innerHTML.replace(markerRE, '$1') // unmark\n }\n }\n}\n\n// any: _replace is an internal helper operating on raw HTML strings; terms are dynamic\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _replace(html: any, term: any, replaceWith: any, options: _W2MarkerOptions) {\n const ww = options.wholeWord\n if (typeof term !== 'string') term = String(term)\n // escape regex special chars\n term = term\n .replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n .replace(/&/g, '&')\n .replace(/</g, '>')\n .replace(/>/g, '<')\n // only outside tags\n // and only outside of quotes\n // let regex = new RegExp((ww ? '\\\\b' : '') + term + (ww ? '\\\\b' : '') + '(?=([a-z-0-9]+=\"[^\"]*\")*?[^\"]+$)' + '(?!([^<]+)?>)', 'i' + (!options.onlyFirst ? 'g' : ''))\n // -- the one above would not match inside html tags\n const regex = new RegExp((ww ? '\\\\b' : '') + term + (ww ? '\\\\b' : '') + '(?![^<]*>)', 'i' + (!options.onlyFirst ? 'g' : ''))\n return html = html.replace(regex, replaceWith)\n}\n\n// any: parameter typed any — runtime dispatch by call site; TsUtils helper accepts heterogeneous runtime input\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function marker(el: any, items: any, options: any = { onlyFirst: false, wholeWord: false, isRegex: false}) {\n options.tag ??= 'span'\n options.class ??= 'tsg-marker'\n // any: matched is the regex capture group — dynamic string from DOM text\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options.raplace = (matched: any) => `<${options.tag} class=\"${options.class}\">${matched}</${options.tag}>`\n\n const isRegexSearch = options.isRegex || false\n if (!Array.isArray(items)) {\n if (items != null && items !== '') {\n items = [items]\n } else {\n items = []\n }\n }\n if (typeof el == 'string') {\n _clearMarkers(el, options)\n // any: items is a mixed array of string/regex passed dynamically via marker() api\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n items.forEach((item: any) => {\n if (isRegexSearch) {\n // For regex searches with string elements\n try {\n const flags = 'i' + (!options.onlyFirst ? 'g' : '')\n const regex = new RegExp(item, flags)\n el = el.replace(regex, options.raplace)\n } catch (e) {\n console.error('Invalid regular expression:', e)\n // Fallback to standard replace\n el = _replace(el, item, options.raplace, options)\n }\n } else {\n // Standard string replace\n el = _replace(el, item, options.raplace, options)\n }\n })\n } else {\n // any: query.each() gives Node at runtime; el is HTMLElement — cast at use sites\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n query(el).each((el: any) => {\n _clearMarkers(el, options)\n if (isRegexSearch) {\n // For regex searches, use DOM traversal approach\n // any: pattern is string|regex from dynamic items array\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n items.forEach((pattern: any) => {\n try {\n let flags = 'i' // Always case-insensitive\n if (!options.onlyFirst) {\n flags += 'g' // Add 'g' for global unless onlyFirst is true\n }\n if (options.wholeWord) {\n // If wholeWord is true, wrap the pattern with word boundary markers\n pattern = '\\b' + pattern + '\\b'\n }\n\n const regex = new RegExp(pattern, flags)\n\n // Get all text nodes\n // any: DOM walker for arbitrary node tree — nodeType/tagName/childNodes are dynamic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const textNodes: any[] = []\n // any: callback parameter — caller signature varies; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function getTextNodes(node: any) {\n if (node.nodeType === 3) { // Text node\n textNodes.push(node)\n } else if (node.nodeType === 1) { // Element node\n // Skip script and style tags\n if (node.tagName !== 'SCRIPT' && node.tagName !== 'STYLE') {\n for (let i = 0; i < node.childNodes.length; i++) {\n getTextNodes(node.childNodes[i])\n }\n }\n }\n }\n\n getTextNodes(el)\n\n // Process each text node\n textNodes.forEach(textNode => {\n const text = textNode.nodeValue\n const matches = []\n let match\n\n // Find all matches\n if (options.onlyFirst) {\n match = regex.exec(text)\n if (match) matches.push({\n index: match.index,\n text: match[0]\n })\n } else {\n while ((match = regex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n text: match[0]\n })\n }\n }\n\n // Apply highlighting\n if (matches.length > 0) {\n const parent = textNode.parentNode\n const fragment = document.createDocumentFragment()\n let lastIndex = 0\n\n matches.forEach(match => {\n // Add text before match\n if (match.index > lastIndex) {\n fragment.appendChild(document.createTextNode(\n text.substring(lastIndex, match.index)\n ))\n }\n\n // Add highlighted match\n const span = document.createElement(options.tag)\n span.className = options.class\n span.appendChild(document.createTextNode(match.text))\n fragment.appendChild(span)\n\n lastIndex = match.index + match.text.length\n })\n\n // Add remaining text\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(\n text.substring(lastIndex)\n ))\n }\n\n // Replace the text node with our fragment\n parent.replaceChild(fragment, textNode)\n }\n })\n } catch (e) {\n console.error('Invalid regular expression:', e)\n // Fallback to standard innerHTML replace\n // any: el from query.each() is Node; cast to HTMLElement for innerHTML\n ;(el as HTMLElement).innerHTML = _replace((el as HTMLElement).innerHTML, pattern, options.raplace, options)\n }\n })\n } else {\n // Standard innerHTML replace for non-regex\n // any: item from dynamic items array\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n items.forEach((item: any) => {\n ;(el as HTMLElement).innerHTML = _replace((el as HTMLElement).innerHTML, item, options.raplace, options)\n })\n }\n })\n }\n return el\n}\n","/**\n * TsUtils notify — Phase 1 of v2.3 SDD (message-cluster-extraction).\n *\n * Extracted from TsUtils.notify() in src/tsutils.ts.\n * INV-4 satisfied: this module does NOT import from tsbase.ts or tsutils.ts.\n * INV-9 satisfied: no `this.X` references — all class state is passed via NotifyDeps.\n *\n * Imports:\n * - query from ./query.js (DOM helper, leaf module)\n */\nimport { query as _query, Query } from './query.js'\n\n// query() overload returns void|Query when called with a callback; notify only uses selector calls.\n// Cast to always return Query so chained calls don't need type guards — matches tsutils.ts pattern.\n// any: same recast as in tsutils.ts:50\nconst query = _query as (selector: unknown, context?: unknown) => Query\n\n// ── dependency interface ───────────────────────────────────────────────────\n\n/**\n * Dependency injection shape for the extracted notify() function.\n * The class delegator on TsUtils.prototype constructs this per-call:\n *\n * _notify(text, options, { execTemplate: this.execTemplate.bind(this), tmpSlot: this.tmp })\n *\n * Using `this.tmp` by reference (Option A from design §C.4) preserves the\n * single-object identity visible in devtools and avoids ownership transfer.\n */\nexport interface NotifyDeps {\n /** String template interpolator — sourced from tsutils-string.ts via TsUtils.execTemplate */\n execTemplate: (str: unknown, replaceObj: unknown) => unknown\n /** Reference to TsUtils.tmp — notify reads/writes notify_resolve, notify_where, notify_timer */\n tmpSlot: Record<string, unknown>\n}\n\n// ── exported function ──────────────────────────────────────────────────────\n\n/**\n * Shows a small notification message at the bottom of the page, or a container\n * specified in options.where.\n *\n * TsUtils.notify('Document saved')\n * TsUtils.notify('Message sent ${undo}', { actions: { undo: function () {...} } })\n *\n * @param text Message string or options object (object-form shorthand)\n * @param options Optional options: { where, timeout, error, success, class, actions }\n * @param deps Injected dependencies (execTemplate + tmpSlot)\n * @returns Promise<void> that resolves when the notification is dismissed\n */\nexport function notify(\n text: string | Record<string, unknown>,\n options: Record<string, unknown> | undefined,\n deps: NotifyDeps,\n): Promise<void> {\n return new Promise<void>(resolve => {\n // any: text can be an options object; normalize in-place\n let opts: Record<string, unknown> = options ?? {}\n let textStr: string = ''\n if (typeof text == 'object') {\n opts = text\n textStr = String(opts['text'] ?? '')\n } else {\n textStr = String(text ?? '')\n }\n opts['where'] ??= document.body\n opts['timeout'] ??= 15_000 // 15 seconds or will be hidden on route change\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (typeof deps.tmpSlot['notify_resolve'] == 'function') {\n ;(deps.tmpSlot['notify_resolve'] as () => void)()\n query(deps.tmpSlot['notify_where']).find('#tsg-notify').remove()\n }\n deps.tmpSlot['notify_resolve'] = resolve\n deps.tmpSlot['notify_where'] = opts['where']\n clearTimeout(deps.tmpSlot['notify_timer'] as number)\n const where = opts['where']\n if (textStr) {\n if (typeof opts['actions'] == 'object') {\n const actions: Record<string, string> = {}\n Object.keys(opts['actions'] as Record<string, unknown>).forEach(action => {\n actions[action] = `<a class=\"tsg-notify-link\" value=\"${action}\">${action}</a>`\n })\n textStr = deps.execTemplate(textStr, actions) as string\n }\n const html = `\n <div id=\"tsg-notify\" style=\"${where == document.body ? 'position: fixed' : ''}\">\n <div class=\"${opts['class'] ?? ''} ${opts['error'] ? 'tsg-notify-error' : ''} ${opts['success'] ? 'tsg-notify-success' : ''}\">\n ${textStr}\n <span class=\"tsg-notify-close tsg-icon-cross\"></span>\n </div>\n </div>`\n query(where).append(html)\n query(where).find('#tsg-notify').find('.tsg-notify-close')\n .on('click', (_event: Event) => {\n query(where).find('#tsg-notify').remove()\n resolve()\n })\n if (opts['actions']) {\n query(where).find('#tsg-notify .tsg-notify-link')\n .on('click', (event: Event) => {\n const value = query(event.target).attr('value') ?? ''\n ;((opts['actions'] as Record<string, unknown>)[value] as () => void)()\n query(where).find('#tsg-notify').remove()\n resolve()\n })\n }\n if ((opts['timeout'] as number) > 0) {\n deps.tmpSlot['notify_timer'] = setTimeout(() => {\n query(where).find('#tsg-notify').remove()\n resolve()\n }, opts['timeout'] as number)\n }\n }\n })\n}\n","/**\n * TsUtils message cluster (message/alert/confirm/prompt/normButtons + types)\n * — Phase 2-4 of v2.3 SDD (message-cluster-extraction).\n *\n * IMPORTANT: This module imports TsBase from tsbase.ts — the only carve-out\n * to INV-4. Rationale: message() does `new TsBase()` to mix events into msgBase.\n * This exception is documented here and whitelisted in the INV-4 grep policy.\n *\n * Exports (Phase 2):\n * normButtons — standalone pure helper; no DOM, no timers\n *\n * Exports (Phase 3a):\n * TsMessageProm, TsMessageWhere, TsMessageOptions (types)\n * MessageDeps (deps interface for _message — scaffold for Phase 3b)\n * _message (stub — body lands in Phase 3b)\n *\n * Exports (Phase 3b+):\n * _message (full body), _alert, _confirm, _prompt (Phase 4)\n *\n * Imports: TsBase from tsbase.ts (INV-4 carve-out, see above)\n * TsUISettings type from tsutils.ts (type-only, no runtime dep)\n * query from query.js (DOM helper)\n */\n\nimport { TsBase } from './tsbase.js'\nimport type { TsUISettings } from './tsutils.js'\nimport { query as _query, Query } from './query.js'\n\n// TsUtils always calls query() with a selector (never a callback) so the return is always Query.\nconst query = _query as (selector: unknown, context?: unknown) => Query\n\n// ---------------------------------------------------------------------------\n// Public types — TsMessageProm / TsMessageWhere / TsMessageOptions\n// These are re-exported from tsutils.ts to keep the public barrel unaffected.\n// ---------------------------------------------------------------------------\n\n/** Promise-chain handle returned by message() / confirm() / prompt() */\nexport interface TsMessageProm {\n self: TsBase\n action(callBack: (event: unknown) => void): TsMessageProm\n close(callBack: (event: unknown) => void): TsMessageProm\n open(callBack: (event: unknown) => void): TsMessageProm\n then(callBack: (event: unknown) => void): TsMessageProm\n change?: (callBack: (event: unknown) => void) => TsMessageProm\n [key: string]: unknown // dynamic action keys (yes/no/ok/cancel) added at runtime\n}\n\n/** Where-descriptor for message() */\nexport interface TsMessageWhere {\n box: string | Element | null\n after?: string | Element | null\n owner?: { name?: string; lock?: (...args: unknown[]) => void; unlock?: (...args: unknown[]) => void; focus?: () => void }\n param?: unknown\n}\n\n/** Options for message() */\nexport interface TsMessageOptions {\n width?: number\n height?: number\n text?: string | null\n body?: string\n buttons?: string\n html?: string\n focus?: number | string | null\n hideOn?: string[]\n actions?: Record<string, unknown>\n cancelAction?: string\n on?: unknown\n onOpen?: unknown\n onClose?: unknown\n onAction?: unknown\n originalWidth?: number\n originalHeight?: number\n msgIndex?: number\n tmp?: { zIndex: string; overflow: string }\n input?: Element | null\n box?: Element | null\n trigger?: (event: string, data: Record<string, unknown>) => unknown\n close?: () => void\n setFocus?: (focus: number | string | null | undefined) => void\n action?: (action: string, event: unknown) => void\n // any: message mixes in TsBase methods at runtime via extend(); typed loosely here\n [key: string]: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Deps interface for normButtons\n// ---------------------------------------------------------------------------\n\nexport interface NormButtonsDeps {\n /** Object/array merge — sourced from tsutils-data */\n extend: (target: object, ...sources: object[]) => object\n /** i18n translation — sourced from TsUtils.lang.bind(this) */\n lang: (phrase: string, params?: Record<string, string | number> | boolean) => string\n /** Settings object — sourced from TsUtils.settings */\n settings: TsUISettings\n}\n\n// ---------------------------------------------------------------------------\n// Deps interface for _message (Phase 3b — full body)\n// Per design §C.2.\n// ---------------------------------------------------------------------------\n\nexport interface MessageDeps {\n /** Object/array merge — sourced from tsutils-data */\n extend: (target: object, ...sources: object[]) => object\n /** DOM data-event binder — sourced from Utils singleton (forward ref) */\n bindEvents: (selector: unknown, subject: Record<string, unknown>) => void\n /** Lock — sourced from Utils singleton (this.lock) */\n lock: (box: unknown, options?: unknown) => void\n /** Unlock — sourced from Utils singleton (this.unlock) */\n unlock: (box: unknown, speed?: number) => void\n /** Widget owner name for DOM IDs like tsg-message-${ownerName}-${i} */\n ownerName: string | undefined\n /** Utils instance — passed as subject to bindEvents for the message box element binding */\n self: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// normButtons — extracted from TsUtils.prototype.normButtons (tsutils.ts:1560-1599)\n// ---------------------------------------------------------------------------\n\n/**\n * Normalizes yes/no/ok/cancel buttons for confirmation dialogs.\n * Pure function — no DOM access, no timers, no this references.\n *\n * Substitutions from original:\n * TsUtils.lang(...) → deps.lang(...)\n * TsUtils.settings.* → deps.settings.*\n * TsUtils.extend(...) → deps.extend(...)\n */\nexport function normButtons(\n options: Record<string, unknown>,\n btn: Record<string, unknown>,\n deps: NormButtonsDeps\n): Record<string, unknown> {\n options['actions'] = options['actions'] ?? {}\n const btns = Object.keys(btn)\n btns.forEach(name => {\n const action = options['btn_' + name] as Record<string, unknown> | undefined\n if (action) {\n btn[name] = {\n text: deps.lang(String(action['text'] ?? btn[name] ?? '')),\n class: action['class'] ?? '',\n style: action['style'] ?? '',\n attrs: action['attrs'] ?? ''\n }\n delete options['btn_' + name]\n }\n ;['text', 'class', 'style', 'attrs'].forEach(suffix => {\n if (options[name + '_' + suffix]) {\n if (typeof btn[name] == 'string') {\n btn[name] = { text: btn[name] }\n }\n ;(btn[name] as Record<string, unknown>)[suffix] = options[name + '_' + suffix]\n delete options[name + '_' + suffix]\n }\n })\n })\n if (btns.includes('yes') && btns.includes('no')) {\n if (deps.settings.macButtonOrder) {\n deps.extend(options['actions'] as object, { no: btn['no'], yes: btn['yes'] })\n } else {\n deps.extend(options['actions'] as object, { yes: btn['yes'], no: btn['no'] })\n }\n }\n if (btns.includes('ok') && btns.includes('cancel')) {\n if (deps.settings.macButtonOrder) {\n deps.extend(options['actions'] as object, { cancel: btn['cancel'], ok: btn['ok'] })\n } else {\n deps.extend(options['actions'] as object, { ok: btn['ok'], cancel: btn['cancel'] })\n }\n }\n return options\n}\n\n// ---------------------------------------------------------------------------\n// _message — full body (Phase 3b)\n// Extracted verbatim from TsUtils.prototype.message (tsutils.ts:1030-1390)\n// with the following deps-injection substitutions:\n// TsUtils.extend(...) → deps.extend(...)\n// TsUtils.bindEvents(...) → deps.bindEvents(...)\n// this.unlock(...) → deps.unlock(...)\n// this.lock(...) → deps.lock(...)\n// typeof this.lock == 'function' → typeof deps.lock == 'function'\n// (this as ...)['name'] → deps.ownerName\n// TsUtils.bindEvents(box, this)→ deps.bindEvents(box, deps.self)\n// arguments.length == 1 || options == null → options == null (INV-8 / design §F)\n// @internal — called by the TsUtils class delegator only\n// ---------------------------------------------------------------------------\n\n/**\n * Extracted message() implementation — full body (Phase 3b).\n * @internal — called by the TsUtils class delegator only\n */\nexport function _message(\n this: void,\n where: TsMessageWhere,\n options: TsMessageOptions | string | number | undefined,\n deps: MessageDeps\n): TsMessageProm | undefined {\n let closeTimer: ReturnType<typeof setTimeout>,\n openTimer: ReturnType<typeof setTimeout>,\n edata: unknown\n // any: msgBase is the live TsMessageOptions reference shared across all closures\n let msgBase: TsMessageOptions = {}\n const removeLast = () => {\n const msgs = query(where?.box).find('.tsg-message')\n if (msgs.length == 0) return // no messages already\n // any: DOM element has _msg_options stored dynamically at open time\n msgBase = (msgs.get(0) as unknown as Record<string, unknown>)['_msg_options'] as TsMessageOptions || {}\n if (typeof msgBase?.close == 'function') {\n msgBase.close!()\n }\n }\n // any: options is morphed into a TsBase instance mid-function; the full shape is known only at runtime\n const closeComplete = (options: Record<string, unknown>) => {\n // any: DOM element has _msg_prevFocus stored dynamically at open time\n const msgBoxEl = options['box'] as Record<string, unknown> | null\n const focus = msgBoxEl?.['_msg_prevFocus'] as Element | undefined\n if (query(where.box).find('.tsg-message').length <= 1) {\n if (where.owner) {\n where.owner.unlock?.(where.param, 150)\n } else {\n deps.unlock(where.box, 150)\n }\n } else {\n query(where.box).find(`#tsg-message-${where.owner?.name}-${(options['msgIndex'] as number)-1}`).css('z-index', '1500')\n }\n if (focus) {\n const msg = query(focus).closest('.tsg-message')\n if (msg.length > 0) {\n // any: DOM element has _msg_options + setFocus stored dynamically at open time\n const opt = (msg.get(0) as unknown as Record<string, unknown>)['_msg_options'] as Record<string, unknown>\n ;(opt['setFocus'] as (f: Element) => void)(focus)\n } else {\n (focus as HTMLElement).focus()\n }\n } else {\n if (typeof where.owner?.focus == 'function') where.owner.focus()\n }\n query(options['box'] as unknown).remove()\n if (options['msgIndex'] === 0) {\n const tmp = options['tmp'] as { zIndex: string; overflow: string }\n head.css('z-index', tmp.zIndex)\n query(where.box).css('overflow', tmp.overflow)\n }\n // event after\n if (options['trigger']) {\n // any: edata is a TsEvent whose finish() is called after close; runtime-owned by options.trigger\n ;((edata as Record<string, unknown>)?.['finish'] as (() => void) | undefined)?.()\n }\n }\n\n if (typeof options == 'string' || typeof options == 'number') {\n msgBase = {\n width : (String(options).length < 300 ? 350 : 550),\n height: (String(options).length < 300 ? 170: 250),\n text : String(options),\n }\n } else if (options == null) {\n // INV-8: arguments.length == 1 replaced with options == null (covers undefined AND null).\n // Per design §F.2: strict superset of original guard. Parity tests lock this in Phase 3b.\n msgBase = where as unknown as TsMessageOptions\n } else {\n msgBase = options ?? {}\n }\n if ((msgBase.text === '' || msgBase.text == null) && (msgBase.body === '' || msgBase.body == null)) {\n removeLast()\n return\n }\n if (msgBase.text != null) msgBase.body = `<div class=\"tsg-centered tsg-msg-text\">${msgBase.text}</div>`\n if (msgBase.width == null) msgBase.width = 350\n if (msgBase.height == null) msgBase.height = 170\n if (msgBase.hideOn == null) msgBase.hideOn = ['esc']\n msgBase.cancelAction ??= 'Ok'\n // mix in events\n // any: msgBase is coerced into a TsBase instance here so that .on/.off/.trigger work;\n // the resulting shape is a hybrid TsMessageOptions + TsBase that TS cannot express statically\n if (msgBase.on == null) {\n const opts = msgBase\n msgBase = new TsBase() as unknown as TsMessageOptions\n deps.extend(msgBase as object, opts as object)\n }\n // any: at this point msgBase has both TsMessageOptions fields AND TsBase event methods (on/off/trigger)\n const msgOpts = msgBase as unknown as Record<string, unknown>\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('open', (event: Record<string, unknown>) => {\n deps.bindEvents(query(msgOpts['box'] as unknown).find('.tsg-eaction'), msgOpts) // msgOpts is TsBase object\n const detail = event['detail'] as Record<string, unknown>\n query(detail['box'] as unknown).find('button, input, textarea, [name=hidden-first]')\n .off('.message')\n .on('keydown.message', function(evt: Event) {\n const keyEvt = evt as KeyboardEvent\n if (keyEvt.keyCode == 27 && (msgOpts['hideOn'] as string[]).includes('esc')) {\n if (msgOpts['cancelAction']) {\n ;(msgOpts['action'] as (..._a: unknown[]) => unknown)(msgOpts['cancelAction'])\n } else {\n ;(msgOpts['close'] as (..._a: unknown[]) => unknown)()\n }\n }\n })\n // timeout is needed because messages opens over 0.3 seconds\n setTimeout(() => (msgOpts['setFocus'] as (..._a: unknown[]) => unknown)(msgOpts['focus']), 300)\n })\n ;(msgOpts['off'] as (..._a: unknown[]) => unknown)('.prom')\n const prom: TsMessageProm = {\n self: msgBase as unknown as TsBase,\n action(callBack: (event: unknown) => void) {\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('action.prom', callBack)\n return prom\n },\n close(callBack: (event: unknown) => void) {\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('close.prom', callBack)\n return prom\n },\n open(callBack: (event: unknown) => void) {\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('open.prom', callBack)\n return prom\n },\n then(callBack: (event: unknown) => void) {\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('open:after.prom', callBack)\n return prom\n }\n }\n if (msgBase.actions == null && msgBase.buttons == null && msgBase.html == null) {\n msgBase.actions = { Ok(event: Record<string, unknown>) { ((event['detail'] as Record<string, unknown>)?.['self'] as Record<string, () => void> | null | undefined)?.['close']?.() }}\n }\n ;(msgOpts['off'] as (..._a: unknown[]) => unknown)('.buttons')\n if (msgBase.actions != null) {\n msgBase.buttons = ''\n Object.keys(msgBase.actions).forEach((action) => {\n const handler = msgBase.actions![action]\n let btnAction: string = action\n if (typeof handler == 'function') {\n msgBase.buttons += `<button class=\"tsg-btn tsg-eaction\" data-click='[\"action\",\"${action}\",\"event\"]' name=\"${action}\">${action}</button>`\n }\n if (typeof handler == 'object' && handler !== null) {\n const h = handler as Record<string, unknown>\n msgBase.buttons += `<button class=\"tsg-btn tsg-eaction ${h['class'] || ''}\" name=\"${action}\" data-click='[\"action\",\"${action}\",\"event\"]'\n style=\"${h['style'] ?? ''}\" ${h['attrs'] ?? ''}>${h['text'] || action}</button>`\n btnAction = Array.isArray(msgBase.actions) ? String(h['text']) : action\n }\n if (typeof handler == 'string') {\n msgBase.buttons += `<button class=\"tsg-btn tsg-eaction\" name=\"${handler}\" data-click='[\"action\",\"${handler}\",\"event\"]'>${handler}</button>`\n btnAction = handler\n }\n if (typeof btnAction == 'string') {\n btnAction = (btnAction[0] ?? '').toLowerCase() + btnAction.substr(1).replace(/\\s+/g, '')\n }\n prom[btnAction] = function (callBack: (event: unknown) => void) {\n ;(msgOpts['on'] as (..._a: unknown[]) => unknown)('action.buttons', (event: Record<string, unknown>) => {\n const detail = event['detail'] as Record<string, unknown>\n const act = String(detail['action'])\n const target = (act[0] ?? '').toLowerCase() + act.substr(1).replace(/\\s+/g, '')\n if (target == btnAction) callBack(event)\n })\n return prom\n }\n })\n }\n // trim if any\n ;(['html', 'body', 'buttons'] as const).forEach(param => {\n msgBase[param] = String(msgBase[param] ?? '').trim()\n })\n if (msgBase.body !== '' || msgBase.buttons !== '') {\n msgBase.html = `\n <div class=\"tsg-message-body\">${msgBase.body || ''}</div>\n <div class=\"tsg-message-buttons\">${msgBase.buttons || ''}</div>\n `\n }\n let styles = getComputedStyle(query(where.box).get(0) as Element)\n const pWidth = parseFloat(styles.width)\n const pHeight = parseFloat(styles.height)\n let titleHeight = 0\n if (query(where.after).length > 0) {\n styles = getComputedStyle(query(where.after).get(0) as Element)\n titleHeight = parseInt(styles.display != 'none' ? styles.height : '0')\n }\n if ((msgBase.width ?? 0) > pWidth) msgBase.width = pWidth - 10\n if ((msgBase.height ?? 0) > pHeight - titleHeight) msgBase.height = pHeight - 10 - titleHeight\n if (msgBase.width != null) msgBase.originalWidth = msgBase.width\n if (msgBase.height != null) msgBase.originalHeight = msgBase.height\n if (parseInt(String(msgBase.width)) < 0) msgBase.width = pWidth + (msgBase.width ?? 0)\n if (parseInt(String(msgBase.width)) < 10) msgBase.width = 10\n if (parseInt(String(msgBase.height)) < 0) msgBase.height = pHeight + (msgBase.height ?? 0) - titleHeight\n if (parseInt(String(msgBase.height)) < 10) msgBase.height = 10\n // negative value means margin\n if ((msgBase.originalHeight ?? 0) < 0) msgBase.height = pHeight + (msgBase.originalHeight ?? 0) - titleHeight\n if ((msgBase.originalWidth ?? 0) < 0) msgBase.width = pWidth + (msgBase.originalWidth ?? 0) * 2 // x 2 because there is left and right margin\n const head = query(where.box).find(where.after as string) // needed for z-index manipulations\n if (!msgBase.tmp) {\n msgBase.tmp = {\n zIndex: String(head.css('z-index')),\n overflow: styles.overflow\n }\n }\n // remove message\n if (msgBase.html === '' && msgBase.body === '' && msgBase.buttons === '') {\n removeLast()\n } else {\n msgBase.msgIndex = query(where.box).find('.tsg-message').length\n if (msgBase.msgIndex === 0 && typeof deps.lock == 'function') {\n query(where.box).css('overflow', 'hidden')\n if (where.owner) { // where.param is used in the panel\n // any: lock() is a widget method accessed via TsBase index signature; safe runtime call\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(where.owner as any).lock?.(where.param)\n } else {\n deps.lock(where.box)\n }\n }\n // send back previous messages\n query(where.box).find('.tsg-message').css('z-index', '1390')\n head.css('z-index', '1501')\n // add message\n const content = `\n <div id=\"tsg-message-${where.owner?.name}-${msgBase.msgIndex}\" class=\"tsg-message\" data-mousedown=\"stop\"\n style=\"z-index: 1500; left: ${((pWidth - (msgBase.width ?? 0)) / 2)}px; top: ${titleHeight}px;\n width: ${msgBase.width}px; height: ${msgBase.height}px; transform: translateY(-${msgBase.height}px)\"\n ${(msgBase.hideOn ?? []).includes('click')\n ? where.param\n ? `data-click='[\"message\", \"${where.param}\"]`\n : 'data-click=\"message\"'\n : ''}>\n <span name=\"hidden-first\" tabindex=\"0\" style=\"position: absolute; top: 0; outline: none\"></span>\n ${msgBase.html}\n <span name=\"hidden-last\" tabindex=\"0\" style=\"position: absolute; top: 0; outline: none\"></span>\n </div>`\n if (query(where.after).length > 0) {\n query(where.box).find(where.after as string).after(content)\n } else {\n query(where.box).prepend(content)\n }\n // any: DOM elements get _msg_options + _msg_prevFocus dynamic properties at open time\n msgBase.box = query(where.box).find(`#tsg-message-${where.owner?.name}-${msgBase.msgIndex}`)[0] as Element\n deps.bindEvents(msgBase.box, deps.self)\n query(msgBase.box)\n .addClass('animating')\n // remember options and prev focus\n ;(msgBase.box as unknown as Record<string, unknown>)['_msg_options'] = msgBase\n ;(msgBase.box as unknown as Record<string, unknown>)['_msg_prevFocus'] = document.activeElement\n // timeout is needed so that callBacks are setup\n setTimeout(() => {\n // before event\n // any: trigger is mixed in from TsBase; edata is a TsEvent with isCancelled + finish()\n edata = (msgOpts['trigger'] as (..._a: unknown[]) => unknown)('open', { target: deps.ownerName, box: msgBase.box, self: msgBase })\n const edataR = edata as Record<string, unknown>\n if (edataR['isCancelled'] === true) {\n query(where.box).find(`#tsg-message-${where.owner?.name}-${msgBase.msgIndex}`).remove()\n if (msgBase.msgIndex === 0) {\n head.css('z-index', msgBase.tmp!.zIndex)\n query(where.box).css('overflow', msgBase.tmp!.overflow)\n }\n return\n }\n // slide down\n query(msgBase.box).css({\n transition: '0.3s',\n transform: 'translateY(0px)'\n })\n }, 0)\n // timeout is needed so that animation can finish\n openTimer = setTimeout(() => {\n // has to be on top of lock\n query(where.box)\n .find(`#tsg-message-${where.owner?.name}-${msgBase.msgIndex}`)\n .removeClass('animating')\n .css({ 'transition': '0s' })\n // event after\n ;((edata as Record<string, unknown>)?.['finish'] as (() => void) | undefined)?.()\n }, 300)\n }\n // action handler\n msgBase.action = (action: string, event: unknown) => {\n let click = msgBase.actions?.[action]\n if (click instanceof Object && (click as Record<string, unknown>)['onClick']) click = (click as Record<string, unknown>)['onClick'] as unknown\n // event before\n // any: trigger is mixed in from TsBase\n const edata = (msgOpts['trigger'] as (..._a: unknown[]) => unknown)('action', { target: deps.ownerName, action, self: msgBase,\n originalEvent: event, value: msgBase.input ? (msgBase.input as HTMLInputElement).value : null })\n const edataR = edata as Record<string, unknown>\n if (edataR['isCancelled'] === true) return\n // default actions\n if (typeof click === 'function') click(edata)\n // event after\n ;(edataR['finish'] as (() => void) | undefined)?.()\n }\n msgBase.close = () => {\n // any: trigger is mixed in from TsBase\n edata = (msgOpts['trigger'] as (..._a: unknown[]) => unknown)('close', { target: 'self', box: msgBase.box, self: msgBase })\n const edataR = edata as Record<string, unknown>\n if (edataR['isCancelled'] === true) return\n clearTimeout(openTimer)\n if (query(msgBase.box).hasClass('animating')) {\n clearTimeout(closeTimer)\n closeComplete(msgOpts)\n return\n }\n // default behavior\n query(msgBase.box)\n .addClass('tsg-closing animating')\n .css({\n 'transition': '0.15s',\n 'transform': 'translateY(-' + msgBase.height + 'px)'\n })\n if ((msgBase.msgIndex ?? 0) !== 0) {\n // previous message\n query(where.box).find(`#tsg-message-${where.owner?.name}-${(msgBase.msgIndex ?? 1)-1}`).css('z-index', '1499')\n }\n closeTimer = setTimeout(() => { closeComplete(msgOpts) }, 150)\n }\n msgBase.setFocus = (focus: number | string | null | undefined) => {\n // in message or popup\n const cnt = query(where.box).find('.tsg-message').length - 1\n const box = query(where.box).find(`#tsg-message-${where.owner?.name}-${cnt}`)\n const sel = 'input, button, select, textarea, [contentEditable], .tsg-input'\n if (focus != null) {\n // any: parameter typed any — runtime dispatch by call site; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const el: any = typeof focus === 'string'\n ? box.find(sel).filter(focus).get(0)\n : box.find(sel).get(focus as number)\n el?.focus()\n } else {\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (box.find('[name=hidden-first]').get(0) as any)?.focus()\n }\n\n // clear focus if there are other messages\n query(where.box)\n .find('.tsg-message')\n .find(sel + ',[name=hidden-first],[name=hidden-last]')\n .off('.keep-focus')\n\n // keep focus/blur inside popup\n query(box)\n .find(sel + ',[name=hidden-first],[name=hidden-last]')\n .on('blur.keep-focus', function (_event) {\n setTimeout(() => {\n const focus = document.activeElement\n const inside = focus != null && query(box).find(sel).filter(focus as Node).length > 0\n const name = query(focus).attr('name')\n if (!inside && focus && focus !== document.body) {\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (query(box).find(sel).get(0) as any)?.focus()\n }\n if (name == 'hidden-last') {\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (query(box).find(sel).get(0) as any)?.focus()\n }\n if (name == 'hidden-first') {\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (query(box).find(sel).get(-1) as any)?.focus()\n }\n }, 1)\n })\n }\n return prom\n}\n\n// ---------------------------------------------------------------------------\n// Phase 4 — _alert, _confirm, _prompt\n// Extracted verbatim from TsUtils.prototype.alert/confirm/prompt (tsutils.ts)\n// with deps-injection substitutions.\n//\n// Key INV-8 fix: `arguments.length == 1` replaced with `options == null`\n// in both _confirm and _prompt (design §F.2). This is a strict behavioral\n// superset: covers single-arg calls AND explicit undefined/null 2nd arg.\n// ---------------------------------------------------------------------------\n\n/**\n * Deps interface for _confirm() — per design §C.3.\n * @internal\n */\nexport interface ConfirmDeps {\n /** Object/array merge — sourced from tsutils-data */\n extend: (target: object, ...sources: object[]) => object\n /** Normalize yes/no/ok/cancel buttons — already extracted as normButtons() */\n normButtons: (options: Record<string, unknown>, btn: Record<string, unknown>) => Record<string, unknown>\n /** Forward ref to extracted message() delegator — preserves widget mixing via this.message() */\n message: (where: TsMessageWhere, options: TsMessageOptions | string | number | undefined) => TsMessageProm | undefined\n /** Settings object (for macButtonOrder in normButtons) */\n settings: { macButtonOrder?: boolean; [key: string]: unknown }\n /** i18n translation — bound to this at call time (prompt only, confirm may omit) */\n lang?: (phrase: string, params?: Record<string, string | number> | boolean) => string\n}\n\n/**\n * Deps interface for _prompt() — per design §C.3 (extends ConfirmDeps with lang required).\n * @internal\n */\nexport interface PromptDeps extends ConfirmDeps {\n /** i18n translation — required for prompt (Ok / Cancel button labels) */\n lang: (phrase: string, params?: Record<string, string | number> | boolean) => string\n}\n\n/**\n * Extracted alert() implementation — delegator-to-delegator.\n * alert() is behaviorally identical to message(); it delegates directly.\n * @internal — called by the TsUtils class delegator only\n */\nexport function _alert(\n this: void,\n where: TsMessageWhere,\n options: TsMessageOptions | string | number | undefined,\n deps: MessageDeps\n): TsMessageProm | undefined {\n return _message(where, options, deps)\n}\n\n/**\n * Extracted confirm() implementation — full body (Phase 4).\n * Extracted from TsUtils.prototype.confirm (tsutils.ts:1067-1088).\n *\n * INV-8 fix: `arguments.length == 1` → `options == null`\n * (options == null covers both undefined and explicit null, which is a strict superset\n * of the original guard and fixes the delegator-wrapping silently-always-2-args bug)\n *\n * Substitutions:\n * TsUtils.normButtons(...) → deps.normButtons(...)\n * TsUtils.message(...) → deps.message(...)\n * arguments.length == 1 → options == null (INV-8 / design §F.2)\n * @internal — called by the TsUtils class delegator only\n */\nexport function _confirm(\n this: void,\n where: TsMessageWhere,\n options: TsMessageOptions | string | number | undefined,\n deps: ConfirmDeps\n): TsMessageProm | undefined {\n // any: options is normalized in-place; shape is TsMessageOptions at runtime\n let msgOpts: Record<string, unknown> = {}\n if (['string', 'number'].includes(typeof options)) {\n msgOpts = { text: options }\n } else if (options == null) {\n // INV-8: replaces `arguments.length == 1` — covers single-arg call AND explicit undefined/null\n msgOpts = where as unknown as Record<string, unknown>\n } else {\n msgOpts = (options ?? {}) as unknown as Record<string, unknown>\n }\n deps.normButtons(msgOpts, { yes: 'Yes', no: 'No' })\n msgOpts['cancelAction'] ??= 'No'\n const prom = deps.message(where, msgOpts as unknown as TsMessageOptions)\n if (prom) {\n prom.action((event: unknown) => {\n const d = (event as Record<string, unknown>)['detail'] as Record<string, unknown>\n const self = d?.['self'] as Record<string, unknown>\n ;(self?.['close'] as (() => void) | undefined)?.()\n })\n }\n return prom\n}\n\n/**\n * Extracted prompt() implementation — full body (Phase 4).\n * Extracted from TsUtils.prototype.prompt (tsutils.ts:1103-1169).\n *\n * INV-8 fix: `arguments.length == 1` → `options == null`\n *\n * Substitutions:\n * TsUtils.normButtons(...) → deps.normButtons(...)\n * TsUtils.lang(...) → deps.lang(...) (bound at call time: this.lang.bind(this))\n * TsUtils.message(...) → deps.message(...)\n * arguments.length == 1 → options == null (INV-8 / design §F.2)\n *\n * Design §C.3 normButtons closure caveat:\n * The normButtons call uses `deps.lang('Ok')` and `deps.lang('Cancel')` which are\n * evaluated at _prompt() call time. `deps.lang` is bound to `this` in the class\n * delegator (this.lang.bind(this)), preserving the call-time binding semantics.\n * @internal — called by the TsUtils class delegator only\n */\nexport function _prompt(\n this: void,\n where: TsMessageWhere,\n options: TsMessageOptions | string | number | undefined,\n deps: PromptDeps\n): TsMessageProm | undefined {\n // any: options is normalized in-place; shape is TsMessageOptions at runtime\n let msgOpts: Record<string, unknown> = {}\n if (['string', 'number'].includes(typeof options)) {\n msgOpts = { label: options }\n } else if (options == null) {\n // INV-8: replaces `arguments.length == 1` — covers single-arg call AND explicit undefined/null\n msgOpts = where as unknown as Record<string, unknown>\n } else {\n msgOpts = (options ?? {}) as unknown as Record<string, unknown>\n }\n msgOpts['cancelAction'] ??= 'Cancel'\n if (msgOpts['label']) {\n msgOpts['focus'] = 0 // the input should be in focus, which is first in the popup\n msgOpts['body'] = (msgOpts['textarea']\n ? `<div class=\"tsg-prompt textarea\">\n <div>${msgOpts['label']}</div>\n <textarea id=\"TsPrompt\" class=\"tsg-input\" ${msgOpts['attrs'] ?? ''}\n data-keydown=\"keydown|event\" data-keyup=\"change|event\"></textarea>\n </div>`\n : `<div class=\"tsg-prompt tsg-centered\">\n <label>${msgOpts['label']} </label>\n <input id=\"TsPrompt\" class=\"tsg-input\" ${msgOpts['attrs'] ?? ''}\n data-keydown=\"keydown|event\" data-keyup=\"change|event\">\n </div>`\n )\n }\n deps.normButtons(msgOpts, { ok: deps.lang('Ok'), cancel: deps.lang('Cancel') })\n const prom = deps.message(where, msgOpts as unknown as TsMessageOptions)\n if (prom) {\n prom.change = function(callBack: (event: unknown) => void) {\n const selfR = prom.self as unknown as Record<string, unknown>\n ;(selfR?.['on'] as ((ev: string, cb: (event: unknown) => void) => void) | undefined)?.('change.prom', callBack)\n return prom\n }\n prom\n .action((event: unknown) => {\n const d = (event as Record<string, unknown>)['detail'] as Record<string, unknown>\n const self = d?.['self'] as Record<string, unknown>\n ;(self?.['close'] as (() => void) | undefined)?.()\n })\n .then((event: unknown) => {\n const d = (event as Record<string, unknown>)['detail'] as Record<string, unknown>\n ;(d?.['self'] as Record<string, unknown>)['input'] = query(d?.['box']).find('#TsPrompt').get(0)\n query(d?.['box'])\n .find('#TsPrompt')\n // any: callback parameter — caller signature varies; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('keydown', (evt: any) => {\n if (evt.keyCode == 13 && evt.shiftKey === false) {\n evt.preventDefault()\n }\n })\n // any: callback parameter — caller signature varies; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .on('keyup', (evt: any) => {\n const self = d?.['self'] as Record<string, unknown>\n // any: trigger is mixed in from TsBase\n const edata = (self?.['trigger'] as (..._a: unknown[]) => unknown)?.('change', { value: evt.target.value, input: evt.target, originalEvent: evt })\n if (evt.keyCode == 13 && evt.shiftKey === false) {\n ;(self?.['action'] as (..._a: unknown[]) => unknown)?.('Ok', evt)\n }\n ;((edata as Record<string, unknown>)?.['finish'] as (() => void) | undefined)?.()\n })\n })\n }\n return prom\n}\n","/**\n * TsUtils DOM sub-module — Phase 5b of v2.4 SDD.\n * DAG position: leaf module (no tsbase/tsutils imports).\n *\n * Imports: ./tsutils-string.js (_encodeTags), ./tsutils-type-guards.js (_isInt),\n * ./tsutils-data.js (_extend), ./query.js (query, Query), DOM globals only.\n * 4-space indent convention.\n *\n * INV-4: MUST NOT import from tsbase.ts or tsutils.ts.\n * INV-8: No arguments.length usage.\n * INV-9: No this.X in exported function bodies.\n */\n\nimport { encodeTags as _encodeTags } from './tsutils-string.js'\nimport { isInt as _isInt } from './tsutils-type-guards.js'\nimport { extend as _extend } from './tsutils-data.js'\nimport { query as _query, Query } from './query.js'\n\n// TsUtils always calls query() with a selector (never a callback) so the return is always Query.\n// any: query() overload returns void|Query when called with a callback; we only use selector calls here\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst query = _query as (selector: any, context?: unknown) => Query\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Options for TsUtils.lock() — moved from tsutils.ts (Phase 5a of v2.4 SDD) */\nexport interface TsLockOptions {\n msg?: string | number\n spinner?: boolean\n opacity?: number\n bgColor?: string\n onClick?: () => void\n}\n\n// ---------------------------------------------------------------------------\n// Exported functions — Phase 5b (real bodies)\n// ---------------------------------------------------------------------------\n\n/**\n * Animates a transition between two DOM elements.\n * Playwright-only coverage: jsdom cannot observe CSS transitions.\n */\nexport function transition(\n divOld: HTMLElement,\n divNew: HTMLElement,\n type: string,\n callBack?: () => void\n): Promise<void> {\n return new Promise<void>((resolve, _reject) => {\n const styles = getComputedStyle(divOld)\n const width = parseInt(styles.width)\n const height = parseInt(styles.height)\n const time = 0.5\n\n if (!divOld || !divNew) {\n console.log('ERROR: Cannot do transition when one of the divs is null')\n return\n }\n\n // any: parentNode is ParentNode | null; for transition usage it's always an HTMLElement\n ;(divOld.parentNode as HTMLElement).style.cssText += 'perspective: 900px; overflow: hidden;'\n divOld.style.cssText += '; position: absolute; z-index: 1019; backface-visibility: hidden'\n divNew.style.cssText += '; position: absolute; z-index: 1020; backface-visibility: hidden'\n\n switch (type) {\n case 'slide-left':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; transform: translate3d('+ width + 'px, 0, 0)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: translate3d(-'+ width +'px, 0, 0)'\n }, 1)\n break\n\n case 'slide-right':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; transform: translate3d(-'+ width +'px, 0, 0)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: translate3d(0px, 0, 0)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: translate3d('+ width +'px, 0, 0)'\n }, 1)\n break\n\n case 'slide-down':\n // init divs\n divOld.style.cssText += 'overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, '+ height +'px, 0)'\n }, 1)\n break\n\n case 'slide-up':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; transform: translate3d(0, '+ height +'px, 0)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)'\n }, 1)\n break\n\n case 'flip-left':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: rotateY(0deg)'\n divNew.style.cssText += 'overflow: hidden; transform: rotateY(-180deg)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: rotateY(180deg)'\n }, 1)\n break\n\n case 'flip-right':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: rotateY(0deg)'\n divNew.style.cssText += 'overflow: hidden; transform: rotateY(180deg)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: rotateY(-180deg)'\n }, 1)\n break\n\n case 'flip-down':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: rotateX(0deg)'\n divNew.style.cssText += 'overflow: hidden; transform: rotateX(180deg)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: rotateX(-180deg)'\n }, 1)\n break\n\n case 'flip-up':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: rotateX(0deg)'\n divNew.style.cssText += 'overflow: hidden; transform: rotateX(-180deg)'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)'\n divOld.style.cssText += 'transition: '+ time +'s; transform: rotateX(180deg)'\n }, 1)\n break\n\n case 'pop-in':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; transform: scale(1); opacity: 1;'\n divOld.style.cssText += 'transition: '+ time +'s;'\n }, 1)\n break\n\n case 'pop-out':\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;'\n divNew.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; opacity: 1;'\n divOld.style.cssText += 'transition: '+ time +'s; transform: scale(1.7); opacity: 0;'\n }, 1)\n break\n\n default:\n // init divs\n divOld.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)'\n divNew.style.cssText += 'overflow: hidden; translate3d(0, 0, 0); opacity: 0;'\n query(divNew).show()\n // -- need a timing function because otherwise not working\n setTimeout(() => {\n divNew.style.cssText += 'transition: '+ time +'s; opacity: 1;'\n divOld.style.cssText += 'transition: '+ time +'s'\n }, 1)\n break\n }\n\n setTimeout(() => {\n if (type === 'slide-down') {\n query(divOld).css('z-index', '1019')\n query(divNew).css('z-index', '1020')\n }\n if (divNew) {\n // any: .css({...}) returns Query when called with object arg; chain cast needed\n ;(query(divNew).css({ 'opacity': '1' }) as Query).css({ 'transition': '', 'transform' : '' })\n }\n if (divOld) {\n ;(query(divOld).css({ 'opacity': '1' }) as Query).css({ 'transition': '', 'transform' : '' })\n }\n if (typeof callBack === 'function') callBack()\n resolve()\n }, time * 1000)\n })\n}\n\n/**\n * Locks a DOM element with an optional overlay message.\n * R-DOM-1: internal unlock call uses module-level unlock() directly (no this.unlock).\n * R-DOM-1b: internal extend call uses _extend directly (no this.extend).\n */\nexport function lock(\n box: unknown,\n options: TsLockOptions | string = {},\n ...rest: unknown[]\n): void {\n if (box == null) return\n // Normalise: string shorthand → { msg }\n let opts: TsLockOptions = typeof options === 'string' ? { msg: options } : { ...options }\n if (rest[0] != null) {\n opts.spinner = rest[0] as boolean\n }\n opts = _extend({ spinner: false }, opts) as TsLockOptions\n // for backward compatibility: unwrap jQuery-like array wrappers\n // any: box may be a legacy jQuery wrapper with [0] and .get(); normalise to a plain selector\n let boxSel: unknown = box\n if ((box as Record<string, unknown>)?.[0] instanceof Node) {\n boxSel = Array.isArray(box) ? box : (box as { get(): unknown[] }).get()\n }\n if (!opts.msg && opts.msg !== 0) opts.msg = ''\n unlock(boxSel) // R-DOM-1: direct module-level call (was this.unlock)\n // any: Query.get(0) returns Element|null; HTMLElement is needed for scrollWidth/scrollHeight\n const el = query(boxSel).get(0) as HTMLElement\n const pWidth = el.scrollWidth\n const pHeight = el.scrollHeight\n // if it is body and only has absolute elements, its height will be 0, need to lock entire window\n let style = `height: ${pHeight}px; width: ${pWidth}px`\n if (el.tagName == 'BODY') {\n style = 'position: fixed; right: 0; bottom: 0;'\n }\n query(boxSel).prepend(\n `<div class=\"tsg-lock\" style=\"${style}\"></div>` +\n '<div class=\"tsg-lock-msg\"></div>'\n )\n const $lock = query(boxSel).find('.tsg-lock')\n const $mess = query(boxSel).find('.tsg-lock-msg')\n if (!opts.msg) {\n $mess.css({\n 'background-color': 'transparent',\n 'background-image': 'none',\n 'border': '0px',\n 'box-shadow': 'none'\n })\n }\n if (opts.spinner === true) {\n opts.msg = `<div class=\"tsg-spinner\" ${(!opts.msg ? 'style=\"width: 35px; height: 35px\"' : '')}></div>`\n + opts.msg\n }\n if (opts.msg) {\n // any: .html(str) returns Query when setting content; cast needed for chaining\n ;($mess.html(String(opts.msg)) as Query).css('display', 'block')\n } else {\n $mess.remove()\n }\n if (opts.opacity != null) {\n $lock.css('opacity', String(opts.opacity))\n }\n $lock.css({ display: 'block' })\n if (opts.bgColor) {\n $lock.css({ 'background-color': opts.bgColor })\n }\n const styles = getComputedStyle($lock.get(0) as Element)\n const opacity = styles.opacity ?? 0.15\n $lock\n .on('mousedown', function() {\n if (typeof opts.onClick == 'function') {\n opts.onClick()\n } else {\n $lock.css({\n 'transition': '.2s',\n 'opacity': String(Number(opacity) * 1.5)\n })\n }\n })\n .on('mouseup', function() {\n if (typeof opts.onClick !== 'function') {\n $lock.css({\n 'transition': '.2s',\n 'opacity': String(opacity)\n })\n }\n })\n .on('mousewheel', function(event) {\n if (event) {\n event.stopPropagation()\n event.preventDefault()\n }\n })\n}\n\n/**\n * Removes the lock overlay from a DOM element.\n * R-UNLOCK-1: this.isInt → _isInt (direct import from tsutils-type-guards).\n */\nexport function unlock(box: unknown, speed?: number): void {\n if (box == null) return\n // any: box may store a _prevUnlock timer id on the element; dynamic property on Element\n const prevBox = box as Record<string, unknown>\n clearTimeout(prevBox['_prevUnlock'] as number)\n // for backward compatibility\n let boxSel: unknown = box\n if ((box as Record<string, unknown>)?.[0] instanceof Node) {\n boxSel = Array.isArray(box) ? box : (box as { get(): unknown[] }).get()\n }\n if (_isInt(speed) && (speed ?? 0) > 0) {\n query(boxSel).find('.tsg-lock').css({\n transition: ((speed ?? 0)/1000) + 's',\n opacity: 0,\n })\n // any: Element may have a dynamic _prevUnlock property used for timer management\n const _box = query(boxSel).get(0) as unknown as Record<string, unknown>\n clearTimeout(_box['_prevUnlock'] as number)\n _box['_prevUnlock'] = setTimeout(() => {\n query(boxSel).find('.tsg-lock').remove()\n }, speed)\n query(boxSel).find('.tsg-lock-msg').remove()\n } else {\n query(boxSel).find('.tsg-lock').remove()\n query(boxSel).find('.tsg-lock-msg').remove()\n }\n}\n\n/**\n * Returns a numeric CSS size measurement for a DOM element.\n */\nexport function getSize(el: unknown, type: string): number {\n const $el = query(el) // for backward compatibility\n let ret = 0\n if ($el.length > 0) {\n const styles = getComputedStyle($el[0] as Element)\n switch (type) {\n case 'width' :\n ret = parseFloat(styles.width)\n if (styles.width === 'auto') ret = 0\n break\n case 'height' :\n ret = parseFloat(styles.height)\n if (styles.height === 'auto') ret = 0\n break\n default:\n // any: type is a CSS property name; CSSStyleDeclaration is indexable by string\n ret = parseFloat(String(styles[type as keyof CSSStyleDeclaration] ?? '')) || 0\n break\n }\n }\n return ret\n}\n\n/**\n * Measures the pixel dimensions of a string rendered with given styles.\n * R-DOM-2: this.encodeTags → _encodeTags (direct import from tsutils-string.js).\n */\nexport function getStrDimentions(\n str: string,\n styles?: string,\n raw?: boolean\n): { width: number; height: number } {\n let div = query('body > #_tmp_width')\n if (div.length === 0) {\n query('body').append('<div id=\"_tmp_width\" style=\"position: absolute; top: -9000px;\"></div>')\n div = query('body > #_tmp_width')\n }\n if (raw === undefined && str.trim().startsWith('<') && str.trim().endsWith('>')) {\n raw = true\n }\n ;(div.html(raw ? str : _encodeTags(str ?? '') as string) as Query).attr('style', `position: absolute; top: -9000px; ${styles || ''}`)\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const width = (div[0] as any).clientWidth\n // any: cast-to-any for dynamic dispatch; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const height = (div[0] as any).clientHeight\n div.html('')\n return { width, height }\n}\n\n/**\n * Returns the pixel width of a string rendered with given styles.\n * Delegates to module-level getStrDimentions (was this.getStrDimentions).\n */\nexport function getStrWidth(str: string, styles?: string, raw?: boolean): number {\n return getStrDimentions(str, styles, raw).width\n}\n\n/**\n * Returns the pixel height of a string rendered with given styles.\n * Delegates to module-level getStrDimentions (was this.getStrDimentions).\n */\nexport function getStrHeight(str: string, styles?: string, raw?: boolean): number {\n return getStrDimentions(str, styles, raw).height\n}\n\n/**\n * Binds DOM events from a subject map to matching child elements.\n */\nexport function bindEvents(\n selector: unknown,\n subject: Record<string, unknown>\n): void {\n // format is\n // <div ... data-<event>='[\"<method>\",\"param1\",\"param2\",...]'> -- should be valid JSON (no undefined)\n // <div ... data-<event>=\"<method>|param1|param2\">\n // -- can have \"event\", \"this\", \"stop\", \"stopPrevent\", \"alert\" - as predefined objects\n // any: selector can be Element, Node[], Query, or string; normalize via query()\n const selectorR = selector as Record<string, unknown>\n if ((selectorR?.['length'] as number) == 0) return\n // for backward compatibility\n let normalizedSelector = selector\n if (selectorR?.[0] instanceof Node) {\n normalizedSelector = Array.isArray(selector) ? selector : (selector as { get(): unknown[] }).get()\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(query(normalizedSelector as any) as ReturnType<typeof query>).each((el) => { // any: normalizedSelector is pre-validated above\n const actions = query(el).data() as Record<string, unknown>\n Object.keys(actions).forEach(name => {\n const events = ['click', 'dblclick', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mousedown', 'mousemove', 'mouseup',\n 'contextmenu', 'focus', 'focusin', 'focusout', 'blur', 'input', 'change', 'keydown', 'keyup', 'keypress']\n if (events.indexOf(String(name).toLowerCase()) == -1) {\n return\n }\n let params: unknown[] = Array.isArray(actions[name]) ? actions[name] as unknown[] : [actions[name]]\n if (typeof actions[name] == 'string') {\n params = (actions[name] as string).split('|').map(key => {\n // any: key is progressively coerced from string to typed value\n let val: unknown = key\n if (key === 'true') val = true\n if (key === 'false') val = false\n if (key === 'undefined') val = undefined\n if (key === 'null') val = null\n if (typeof val === 'string' && parseFloat(val) == (val as unknown as number)) val = parseFloat(val)\n const quotes = ['\\'', '\"', '`']\n if (typeof val == 'string' && quotes.includes(val[0] ?? '') && quotes.includes(val[val.length-1] ?? '')) {\n val = val.substring(1, val.length-1)\n }\n return val\n })\n }\n const method = String(params[0]) // params[0] is the method name\n params = params.slice(1) // should be new array\n query(el)\n .off(name + '.TsUtils-bind')\n .on(name + '.TsUtils-bind', function(this: HTMLElement, event: Event) {\n switch (method) {\n case 'alert':\n alert(params[0]) // for testing purposes\n break\n case 'stop':\n event.stopPropagation()\n break\n case 'prevent':\n event.preventDefault()\n break\n case 'stopPrevent':\n event.stopPropagation()\n event.preventDefault()\n return false\n break\n default:\n if (subject[method] == null) {\n throw new Error(`Cannot dispatch event as the method \"${method}\" does not exist.`)\n }\n // any: subject[method] is a function mixed in at runtime; cast required\n ;(subject[method] as (...args: unknown[]) => void)(...params.map((key, _ind) => {\n switch (String(key).toLowerCase()) {\n case 'event':\n return event\n case 'this':\n return this\n default:\n return key\n }\n }))\n }\n })\n })\n })\n}\n","/**\n * TsUtils date-time sub-module — Phase 5b of v2.5 SDD.\n * DAG position: leaf module (no tsbase/tsutils imports).\n *\n * Imports:\n * ./tsutils-type-guards.js — isInt as _isInt (needed by isDate, isTime, formatDate, formatTime)\n * ./tsutils.js — type-only import type { TsUISettings } (TS erases at emit)\n * Precedent: tsutils-type-guards.ts:9, tsutils-message.ts:26\n *\n * INV-4: MUST NOT import from tsbase.ts or tsutils.ts at runtime.\n * INV-8: No arguments.length usage.\n * INV-9: No this.X in exported function bodies.\n *\n * 4-space indent convention.\n *\n * OQ-2 (TsTimeResult): local non-exported interface `TsTimeResult` defined inline\n * here (structurally identical to tsutils.ts copy). Avoids back-import of a\n * non-exported type; the class delegator in tsutils.ts casts via `as boolean | TsTimeResult`.\n *\n * R-DT-3 (settings reference): `settings` is passed as a reference to `this.settings`\n * from delegators — never cloned. TsLocale mutations to fullmonths/shortmonths/dateFormat\n * etc. flow through without restart.\n *\n * R-DT-2 / R-DT-8 (intra-cluster calls): _isDateTime calls _isDate + _isTime directly\n * as module-level function refs. _formatDateTime calls _formatDate + _formatTime directly.\n * _formatTime calls _isTime directly. Zero this.X inside any extracted body.\n */\n\nimport type { TsUISettings } from './tsutils.js'\nimport { isInt as _isInt } from './tsutils-type-guards.js'\n\n// ---------------------------------------------------------------------------\n// Local types (non-exported — structurally identical to tsutils.ts TsTimeResult)\n// ---------------------------------------------------------------------------\n\n/** Return value from _isTime() / TsUtils.isTime() when retTime === true — single canonical declaration (v2.6 dedup) */\nexport interface TsTimeResult {\n hours: number\n minutes: number\n seconds: number\n}\n\n// ---------------------------------------------------------------------------\n// Locale-injection interface — v2.6 DateDeps pattern (mirrors MessageDeps/NotifyDeps)\n// ---------------------------------------------------------------------------\n\n/**\n * Locale dependencies injected into _date() by the TsUtils.date() delegator.\n * Follows the v2.3 MessageDeps / NotifyDeps single-field deps-injection pattern.\n * A-1: exported so callers can type their own deps objects.\n * A-2: only `lang` field — no other locale surface in v2.6.\n */\nexport interface DateDeps {\n lang: (phrase: string) => string\n}\n\n// ---------------------------------------------------------------------------\n// Exported functions — Phase 5b (real bodies)\n// ---------------------------------------------------------------------------\n\n/**\n * Check if val is a valid date. Optionally return the Date object.\n * @param val - value to check\n * @param format - date format string (e.g. 'mm/dd/yyyy'); defaults to settings.dateFormat\n * @param retDate - if true, return the Date object instead of boolean\n * @param settings - TsUISettings reference (TsLocale fields: fullmonths, dateFormat)\n */\nexport function _isDate(\n val: unknown,\n format: string | null | undefined,\n retDate: boolean | undefined,\n settings: TsUISettings\n): boolean | Date {\n if (!val) return false\n\n let dt: Date | string = 'Invalid Date'\n let month: number | string | undefined, day: number | string | undefined, year: number | string | undefined\n\n if (format == null) format = settings.dateFormat\n\n if (val instanceof Date) { // date object\n year = val.getFullYear()\n month = val.getMonth() + 1\n day = val.getDate()\n } else if (typeof val === 'number' || (typeof val === 'string' && parseInt(val) == (val as unknown as number) && parseInt(val) > 0)) {\n const d = new Date(parseInt(String(val)))\n year = d.getFullYear()\n month = d.getMonth() + 1\n day = d.getDate()\n } else {\n let strVal = String(val)\n // convert month formats\n if (new RegExp('mon', 'ig').test(format)) {\n format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\\/\\//g, '/').toLowerCase()\n strVal = strVal.replace(/[, ]/ig, '/').replace(/\\/\\//g, '/').toLowerCase()\n for (let m = 0, len = settings.fullmonths.length; m < len; m++) {\n const t = settings.fullmonths[m] ?? ''\n strVal = strVal.replace(new RegExp(t, 'ig'), String(m + 1)).replace(new RegExp(t.substr(0, 3), 'ig'), String(m + 1))\n }\n }\n // format date\n const tmp = strVal.replace(/-/g, '/').replace(/\\./g, '/').toLowerCase().split('/')\n const tmp2 = format.replace(/-/g, '/').replace(/\\./g, '/').toLowerCase()\n if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2] }\n if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2] }\n if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2] }\n if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2] }\n if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0] }\n if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0] }\n if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0] }\n if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0] }\n if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2] }\n if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2] ?? '0') + 1900 }\n if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2] ?? '0') + 1900 }\n if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2] ?? '0') + 1900 }\n if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0] ?? '0') + 1900 }\n if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0] ?? '0') + 1900 }\n if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0] ?? '0') + 1900 }\n if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0] ?? '0') + 1900 }\n }\n if (!_isInt(year)) return false\n if (!_isInt(month)) return false\n if (!_isInt(day)) return false\n // year/month/day are string|number after isInt guards above; the checks ensure they are defined\n const numYear = +(year ?? 0)\n const numMonth = +(month ?? 0)\n const numDay = +(day ?? 0)\n dt = new Date(numYear, numMonth - 1, numDay)\n dt.setFullYear(numYear)\n // do checks\n if (numMonth == null) return false\n if (String(dt) === 'Invalid Date') return false\n if ((dt.getMonth() + 1 !== numMonth) || (dt.getDate() !== numDay) || (dt.getFullYear() !== numYear)) return false\n if (retDate === true) return dt; else return true\n}\n\n/**\n * Check if val is a valid time string. Optionally return { hours, minutes, seconds }.\n * @param val - value to check (e.g. '14:30', '2:30 pm')\n * @param retTime - if true, return the TsTimeResult object\n */\nexport function _isTime(\n val: unknown,\n retTime?: boolean\n): boolean | TsTimeResult {\n // Both formats 10:20pm and 22:20\n if (val == null) return false\n let max: number\n // -- process american format\n let strVal = String(val).toUpperCase()\n const am = strVal.indexOf('AM') >= 0\n const pm = strVal.indexOf('PM') >= 0\n const ampm = (pm || am)\n if (ampm) max = 12; else max = 24\n strVal = strVal.replace('AM', '').replace('PM', '').trim()\n // ---\n const tmp = strVal.split(':')\n const tmp0 = tmp[0] ?? '', tmp1 = tmp[1] ?? '', tmp2 = tmp[2] ?? ''\n let h = parseInt(tmp0 || '0')\n const m = parseInt(tmp1 || '0'), s = parseInt(tmp2 || '0')\n // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT:\n if ((!ampm || tmp.length !== 1) && tmp.length !== 2 && tmp.length !== 3) { return false }\n if (tmp0 === '' || h < 0 || h > max || !_isInt(tmp0) || tmp0.length > 2) { return false }\n if (tmp.length > 1 && (tmp1 === '' || m < 0 || m > 59 || !_isInt(tmp1) || tmp1.length !== 2)) { return false }\n if (tmp.length > 2 && (tmp2 === '' || s < 0 || s > 59 || !_isInt(tmp2) || tmp2.length !== 2)) { return false }\n // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00).\n // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are.\n if (!ampm && max === h && (m !== 0 || s !== 0)) { return false }\n if (ampm && tmp.length === 1 && h === 0) { return false }\n\n if (retTime === true) {\n if (pm && h !== 12) h += 12 // 12:00pm - is noon\n if (am && h === 12) h += 12 // 12:00am - is midnight\n return {\n hours: h,\n minutes: m,\n seconds: s\n }\n }\n return true\n}\n\n/**\n * Check if val is a valid date-time string. Optionally return the Date object.\n * @param val - value to check\n * @param format - datetime format string (pipe-separated date|time); defaults to settings.datetimeFormat\n * @param retDate - if true, return the Date object\n * @param settings - TsUISettings reference (datetimeFormat, dateFormat, timeFormat)\n *\n * R-DT-11: settings is threaded through the full function body even though it is only\n * consumed in the `tmp >= 0` branch (split-datetime path). Required for _isDate call.\n */\nexport function _isDateTime(\n val: unknown,\n format: string | null | undefined,\n retDate: boolean | undefined,\n settings: TsUISettings\n): boolean | Date {\n if (val instanceof Date) { // date object\n if (retDate !== true) return true\n return val\n }\n const intVal = parseInt(String(val))\n if (intVal === (val as number)) {\n if (intVal < 0) return false\n else if (retDate !== true) return true\n else return new Date(intVal)\n }\n const strVal = String(val)\n const tmp = strVal.indexOf(' ')\n if (tmp < 0) {\n if (strVal.indexOf('T') < 0 || String(new Date(strVal)) == 'Invalid Date') return false\n else if (retDate !== true) return true\n else return new Date(strVal)\n } else {\n if (format == null) format = settings.datetimeFormat\n const formats = format.split('|')\n const values = [strVal.substr(0, tmp), strVal.substr(tmp).trim()]\n if (formats[0] != null) formats[0] = formats[0].trim()\n if (formats[1]) formats[1] = formats[1].trim()\n // check — R-DT-2: intra-cluster calls use module-level function refs (no this.X)\n const tmp1 = _isDate(values[0], formats[0], true, settings)\n const tmp2 = _isTime(values[1], true)\n if (tmp1 !== false && tmp2 !== false) {\n if (retDate !== true) return true\n const dt1 = tmp1 as Date\n const t2 = tmp2 as TsTimeResult\n dt1.setHours(t2.hours)\n dt1.setMinutes(t2.minutes)\n dt1.setSeconds(t2.seconds)\n return dt1\n } else {\n return false\n }\n }\n}\n\n/**\n * Return a human-readable age string for a date (e.g. '5 mins', '2 years').\n * Stateless — no settings dependency (OQ-6: all output strings are hardcoded English).\n * @param dateStr - date value (Date, number timestamp, or date string)\n */\nexport function _age(dateStr: unknown): string {\n let d1: Date\n if (dateStr === '' || dateStr == null) return ''\n if (dateStr instanceof Date) { // date object\n d1 = dateStr\n } else if (typeof dateStr === 'number' || (typeof dateStr === 'string' && parseInt(dateStr) == (dateStr as unknown as number) && parseInt(dateStr) > 0)) {\n d1 = new Date(parseInt(String(dateStr)))\n } else {\n d1 = new Date(String(dateStr))\n }\n if (String(d1) === 'Invalid Date') return ''\n\n const d2 = new Date()\n const sec = (d2.getTime() - d1.getTime()) / 1000\n let amount: number = 0\n let type = ''\n if (sec < 0) {\n amount = 0\n type = 'sec'\n } else if (sec < 60) {\n amount = Math.floor(sec)\n type = 'sec'\n if (sec < 0) { amount = 0; type = 'sec' }\n } else if (sec < 60*60) {\n amount = Math.floor(sec/60)\n type = 'min'\n } else if (sec < 24*60*60) {\n amount = Math.floor(sec/60/60)\n type = 'hour'\n } else if (sec < 30*24*60*60) {\n amount = Math.floor(sec/24/60/60)\n type = 'day'\n } else if (sec < 365*24*60*60) {\n amount = Math.floor(sec/30/24/60/60*10)/10\n type = 'month'\n } else if (sec < 365*4*24*60*60) {\n amount = Math.floor(sec/365/24/60/60*10)/10\n type = 'year'\n } else if (sec >= 365*4*24*60*60) {\n // factor in leap year shift (only older then 4 years)\n amount = Math.floor(sec/365.25/24/60/60*10)/10\n type = 'year'\n }\n return amount + ' ' + type + (amount > 1 ? 's' : '')\n}\n\n/**\n * Return a human-readable duration string for a millisecond value (e.g. '45 secs', '2.3 hours').\n * Stateless — no settings dependency.\n * @param value - duration in milliseconds\n */\nexport function _interval(value: number): string {\n let ret = ''\n if (value < 100) {\n ret = '< 0.01 sec'\n } else if (value < 1000) {\n ret = (Math.floor(value / 10) / 100) + ' sec'\n } else if (value < 10000) {\n ret = (Math.floor(value / 100) / 10) + ' sec'\n } else if (value < 60000) {\n ret = Math.floor(value / 1000) + ' secs'\n } else if (value < 3600000) {\n ret = Math.floor(value / 60000) + ' mins'\n } else if (value < 86400000) {\n ret = Math.floor(value / 3600000 * 10) / 10 + ' hours'\n } else if (value < 2628000000) {\n ret = Math.floor(value / 86400000 * 10) / 10 + ' days'\n } else if (value < 3.1536e+10) {\n ret = Math.floor(value / 2628000000 * 10) / 10 + ' months'\n } else {\n ret = Math.floor(value / 3.1536e+9) / 10 + ' years'\n }\n return ret\n}\n\n/**\n * Format a date value as a string using the given format and settings.\n * @param dateStr - date value (Date, number timestamp, or date string)\n * @param format - date format string; defaults to settings.dateFormat\n * @param settings - TsUISettings reference (dateFormat, fullmonths, shortmonths)\n */\nexport function _formatDate(\n dateStr: unknown,\n format: string | null | undefined,\n settings: TsUISettings\n): string { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String\n if (!format) format = settings.dateFormat\n if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !(dateStr as Date).getMonth)) return ''\n\n let dt = new Date(dateStr as string | number)\n if (_isInt(dateStr)) dt = new Date(Number(dateStr)) // for unix timestamps\n if (String(dt) === 'Invalid Date') return ''\n\n const year = dt.getFullYear()\n const month = dt.getMonth()\n const date = dt.getDate()\n return format.toLowerCase()\n .replace('month', settings.fullmonths[month] ?? '')\n .replace('mon', settings.shortmonths[month] ?? '')\n .replace(/yyyy/g, ('000' + year).slice(-4))\n .replace(/yyy/g, ('000' + year).slice(-4))\n .replace(/yy/g, ('0' + year).slice(-2))\n .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceded by a letter\n .replace(/mm/g, ('0' + (month + 1)).slice(-2))\n .replace(/dd/g, ('0' + date).slice(-2))\n .replace(/th/g, (date == 1 ? 'st' : 'th'))\n .replace(/th/g, (date == 2 ? 'nd' : 'th'))\n .replace(/th/g, (date == 3 ? 'rd' : 'th'))\n .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceded by a letter\n .replace(/(^|[^a-z$])d/g, '$1' + date) // only y's that are not preceded by a letter\n}\n\n/**\n * Format a time value as a string using the given format and settings.\n * @param dateStr - time value (time string or full date string)\n * @param format - time format string (e.g. 'hh:mi pm'); defaults to settings.timeFormat\n * @param settings - TsUISettings reference (timeFormat)\n *\n * R-DT-8: intra-cluster calls to _isTime use module-level function refs (no this.X).\n */\nexport function _formatTime(\n dateStr: unknown,\n format: string | null | undefined,\n settings: TsUISettings\n): string { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String\n if (!format) format = settings.timeFormat\n if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !(dateStr as Date).getMonth)) return ''\n\n let dt = new Date(dateStr as string | number)\n if (_isInt(dateStr)) dt = new Date(Number(dateStr)) // for unix timestamps\n // R-DT-8: both isTime calls become intra-module refs\n if (_isTime(dateStr)) {\n const tmp = _isTime(dateStr, true) as TsTimeResult\n dt = new Date()\n dt.setHours(tmp.hours)\n dt.setMinutes(tmp.minutes)\n }\n if (String(dt) === 'Invalid Date') return ''\n if (format == 'h12') format = 'hh:mi pm'\n\n let type = 'am'\n let hour: string | number = dt.getHours()\n const h24 = dt.getHours()\n let min: string | number = dt.getMinutes()\n let sec: string | number = dt.getSeconds()\n if (min < 10) min = '0' + min\n if (sec < 10) sec = '0' + sec\n if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) {\n if (hour >= 12) type = 'pm'\n if (hour > 12) hour = hour - 12\n if (hour === 0) hour = 12\n }\n const hourStr = String(hour)\n const minStr = String(min)\n const secStr = String(sec)\n const h24Str = String(h24)\n return format.toLowerCase()\n .replace('am', type)\n .replace('pm', type)\n .replace('hhh', (Number(hour) < 10 ? '0' + hourStr : hourStr))\n .replace('hh24', (h24 < 10 ? '0' + h24Str : h24Str))\n .replace('h24', h24Str)\n .replace('hh', hourStr)\n .replace('mm', minStr)\n .replace('mi', minStr)\n .replace('ss', secStr)\n .replace(/(^|[^a-z$])h/g, '$1' + hourStr) // only y's that are not preceded by a letter\n .replace(/(^|[^a-z$])m/g, '$1' + minStr) // only y's that are not preceded by a letter\n .replace(/(^|[^a-z$])s/g, '$1' + secStr) // only y's that are not preceded by a letter\n}\n\n/**\n * Format a date-time value as a combined date+time string.\n * @param dateStr - datetime value\n * @param format - pipe-separated date|time format; defaults to settings.dateFormat + settings.timeFormat\n * @param settings - TsUISettings reference (dateFormat, timeFormat)\n *\n * R-DT-2: intra-cluster calls _formatDate + _formatTime use module-level function refs.\n */\nexport function _formatDateTime(\n dateStr: unknown,\n format: string | null | undefined,\n settings: TsUISettings\n): string {\n let fmt: string[]\n if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !(dateStr as Date).getMonth)) return ''\n if (typeof format !== 'string') {\n fmt = [settings.dateFormat, settings.timeFormat]\n } else {\n fmt = format.split('|')\n if (fmt[0] != null) fmt[0] = fmt[0].trim()\n fmt[1] = (fmt.length > 1 ? (fmt[1] ?? '').trim() : settings.timeFormat)\n }\n // older formats support\n if (fmt[1] === 'h12') fmt[1] = 'h:m pm'\n if (fmt[1] === 'h24') fmt[1] = 'h24:m'\n // R-DT-2: both intra-cluster calls become module-level function refs\n return _formatDate(dateStr, fmt[0], settings) + ' ' + _formatTime(dateStr, fmt[1], settings)\n}\n\n/**\n * Return an HTML `<span>` string representing a date value relative to today.\n * Today's date returns a time-of-day string; yesterday returns the locale phrase;\n * older dates return the formatted month-day-year string.\n *\n * @param dateStr - date value (string, number timestamp, null, or undefined)\n * @param settings - TsUISettings reference (shortmonths, passed by reference — R-DT-3)\n * @param deps - DateDeps locale callbacks (lang for 'Yesterday' lookup — INV-DATE-LOCALE)\n *\n * Phase 5a stub — body filled at Phase 5b.\n * B-1: exact parameter order: dateStr, settings, deps.\n */\nexport function _date(\n dateStr: unknown,\n settings: TsUISettings,\n deps: DateDeps\n): string {\n if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !(dateStr as Date).getMonth)) return ''\n let d1 = new Date(dateStr as string | number)\n if (_isInt(dateStr)) d1 = new Date(Number(dateStr)) // for unix timestamps (was this.isInt → _isInt)\n if (String(d1) === 'Invalid Date') return ''\n\n const months = settings.shortmonths // was this.settings.shortmonths\n const d2 = new Date() // today\n const d3 = new Date()\n d3.setTime(d3.getTime() - 86400000) // yesterday\n\n const dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear()\n const dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear()\n const dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear()\n\n const time = (d1.getHours() - (d1.getHours() > 12 ? 12 : 0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am')\n const time2 = (d1.getHours() - (d1.getHours() > 12 ? 12 : 0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am')\n let dsp = dd1\n if (dd1 === dd2) dsp = time\n if (dd1 === dd3) dsp = deps.lang('Yesterday') // was this.lang('Yesterday') → deps.lang (INV-DATE-LOCALE)\n\n return '<span title=\"' + dd1 + ' ' + time2 + '\">' + dsp + '</span>'\n}\n","/**\n * TsUtils locale sub-module — Phase 5b of v2.7 SDD.\n * DAG position: leaf module (no tsbase/tsutils runtime imports).\n *\n * Imports:\n * ./tslocale.js — runtime import for TsLocale data const (zero-dep data leaf)\n * ./tsutils.js — type-only import type { TsUISettings } (TS erases at emit)\n * Precedent: tsutils-datetime.ts:29\n *\n * INV-4 / INV-L7-LEAF: MUST NOT import from tsbase.ts or tsutils.ts at runtime.\n * INV-8: No arguments.length usage.\n * INV-9: No this.X in exported function bodies.\n *\n * 4-space indent convention.\n */\n\nimport type { TsUISettings } from './tsutils.js'\nimport { TsLocale } from './tslocale.js'\n\n// ---------------------------------------------------------------------------\n// DI interface — LocaleDeps (v2.7 locale injection pattern)\n// ---------------------------------------------------------------------------\n\n/**\n * Locale loader dependencies injected into _locale() by the TsUtils.locale() delegator.\n * Follows the v2.3 MessageDeps / v2.6 DateDeps deps-injection pattern.\n * Both fields are REQUIRED — no optional fallbacks (design OQ-1/D1).\n *\n * Internal only — NOT re-exported through src/index.ts barrel (INV-L7-DEPS-INTERNAL).\n */\nexport interface LocaleDeps {\n extend: (target: object, ...sources: object[]) => object\n fetch: (url: string, init?: { method?: string }) => Promise<Response>\n}\n\n// ---------------------------------------------------------------------------\n// Internal result type\n// ---------------------------------------------------------------------------\n\n/**\n * Internal resolved-value shape returned by _locale() to the delegator.\n * The delegator unwraps this to the public Promise<{ file; data } | void> shape.\n *\n * @internal\n */\nexport type LocaleResult =\n | { kind: 'load'; file: string; data: unknown; settings?: TsUISettings }\n | { kind: 'merge'; settings: TsUISettings }\n | { kind: 'void'; settings?: TsUISettings }\n\n// ---------------------------------------------------------------------------\n// _locale() — Phase 5b (full body)\n// Extracted from TsUtils.locale() body (tsutils.ts:625-686 in v2.6.0).\n// ---------------------------------------------------------------------------\n\n/**\n * Locale loader — pure async function extracted from TsUtils.locale() body.\n * Called by the TsUtils.locale() delegator; NOT part of the public API.\n *\n * INV-9: zero this.X references in this body.\n * INV-L7-LEAF: no runtime imports from tsutils.ts or tsbase.ts.\n *\n * @param locale - string locale code, full URL, array of codes, or plain object to merge\n * @param keepPhrases - if true, existing phrases are preserved before merge (default: clear)\n * @param noMerge - if true, settings are NOT mutated; resolves with { file, data } payload\n * @param settings - TsUISettings reference (passed by ref from the delegator)\n * @param deps - injected dependencies (extend + fetch)\n */\nexport async function _locale(\n locale: string | string[] | Record<string, unknown>,\n keepPhrases: boolean | undefined,\n noMerge: boolean | undefined,\n settings: TsUISettings,\n deps: LocaleDeps,\n): Promise<LocaleResult> {\n // --- Array branch (OQ-2/D2 — DIRECT recursion via _locale, not through delegator) ---\n if (Array.isArray(locale)) {\n // Pre-reset phrases before fanout — v2.7.1 PATCH (INV-L7-PHRASES-CLEAR, array clause).\n // The spread { ...settings, phrases: {} } resets phrases to a fresh empty object BEFORE\n // deep-extend deep-clones the result. Pre-v2.7.1 the `{ phrases: {} }` source position\n // was a deep-extend no-op (extend iterates Object.keys({}) → 0 keys), so pre-existing\n // settings.phrases keys leaked into the initial accumulator.\n let mergedSettings: TsUISettings = deps.extend({}, { ...settings, phrases: {} }) as TsUISettings\n // .map() upfront — produces a FRESH array of expanded paths; original `locale` is never\n // mutated. v2.7.1 PATCH for R-LOC-2 (INV-L7-IMMUTABLE-INPUT). Downstream merge loop at\n // line 99 consumes localeArr (expanded) for files[file] lookup keys — semantics identical.\n const localeArr = (locale as string[]).map(f =>\n f.length === 5 ? 'locale/'+ f.toLowerCase() +'.json' : f\n )\n const proms: Array<Promise<LocaleResult>> = []\n const files: Record<string, unknown> = {}\n localeArr.forEach(file => {\n // Direct _locale call — NOT through delegator. Design OQ-2/D2 chosen option (ii).\n // keepPhrases=true, noMerge=false for inner recursive calls (mirrors original line 638)\n proms.push(_locale(file, true, false, mergedSettings, deps))\n })\n const res = await Promise.allSettled(proms)\n res.forEach(r => {\n if (r.status === 'fulfilled' && r.value.kind === 'load') {\n files[r.value.file] = r.value.data\n }\n })\n // Merge in declared order (order of files is important — mirrors original lines 646-648)\n localeArr.forEach(file => {\n mergedSettings = deps.extend({}, mergedSettings, (files[file] ?? {}) as object) as TsUISettings\n })\n return { kind: 'void', settings: mergedSettings }\n }\n\n if (!locale) locale = 'en-us'\n\n // --- Object branch (Thread C — INV-L7-OBJFIX fix) ---\n // Original line 658: `return` without resolve → Promise hung forever.\n // Fix: async function return auto-wraps; return { kind: 'merge', settings } resolves correctly.\n if (typeof locale === 'object') {\n const mergedSettings = deps.extend({}, settings, TsLocale, locale) as TsUISettings\n return { kind: 'merge', settings: mergedSettings }\n }\n\n // --- String branch (5-char auto-expansion or full path) ---\n let localeStr = locale as string\n if (localeStr.length === 5) {\n localeStr = 'locale/'+ localeStr.toLowerCase() +'.json'\n }\n\n // Load from the file (mirrors original lines 667-684)\n try {\n const res = await deps.fetch(localeStr, { method: 'GET' })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = await (res as any).json() as object\n if (noMerge !== true) {\n if (keepPhrases) {\n // keep phrases, useful for recursive calls (mirrors original line 673)\n const newSettings = deps.extend({}, settings, data) as TsUISettings\n return { kind: 'load', file: localeStr, data, settings: newSettings }\n } else {\n // clear phrases from language before merging — v2.7.1 PATCH (INV-L7-PHRASES-CLEAR)\n // The spread { ...settings, phrases: {} } resets phrases to a fresh empty object\n // BEFORE deep-extend sees it; subsequent TsLocale + data sources then populate phrases\n // from a clean baseline. Pre-v2.7.1 the `{ phrases: {} }` source position was a\n // deep-extend no-op (extend iterates Object.keys({}) → 0 keys), so pre-existing\n // settings.phrases keys survived. See engram #925 (discovery).\n const phrasesCleared = { ...settings, phrases: {} }\n const newSettings = deps.extend({}, phrasesCleared, TsLocale, data) as TsUISettings\n return { kind: 'load', file: localeStr, data, settings: newSettings }\n }\n }\n return { kind: 'load', file: localeStr, data }\n } catch (err) {\n console.log('ERROR: Cannot load locale '+ localeStr)\n throw err // rejects the async Promise (T-LOC-8); mirrors original .catch(reject)\n }\n}\n","/**\n * Part of TsUi 2.0 library\n * - Dependencies: mQuery, TsUtils, TsBase, TsLocale\n *\n * T2.5: @ts-nocheck removed; file typed aggressively per typing_policy.\n * See commit body for targeted-any inventory.\n *\n * == TODO ==\n * - add TsUtils.lang wrap for all captions in all buttons.\n * - check transition (also with layout)\n * - deprecate TsUtils.tooltip\n *\n * == 2.0 changes\n * - CSP - fixed inline events (TsUtils.tooltip still has it)\n * - transition returns a promise\n * - removed jQuery\n * - refactores TsUtils.message()\n * - added TsUtils.confirm()\n * - added isPlainObject\n * - added stripSpaces\n * - implemented marker - can now take an element or just html\n * - cssPrefix - deprecated\n * - TsUtils.debounce\n * - TsUtils.prepareParams\n * - TsUtils.getStrHeight\n * - TsUtils.getStrDimentions\n * - TsUtils.alrert() - same as TsUtils.message()\n * - TsUtils.prompt() - similar to TsPrompt\n * - TsUtils.normMenu(..., options) got options parameter that can have itemMap\n * - TsUtils.getNested()\n * - TsUtils.wait() - async timer\n */\n\n// TsBase import removed in Phase 3b — new TsBase() is now called in tsutils-message.ts only.\n// Per design §J.9: tsutils.ts no longer needs TsBase after message() body extraction.\nimport { TsLocale } from './tslocale.js'\nimport { query as _query, Query } from './query.js'\nimport { isInt as _isInt, isHex as _isHex, isAlphaNumeric as _isAlphaNumeric, isEmail as _isEmail, isIpAddress as _isIpAddress, isPlainObject as _isPlainObject, isBin as _isBin, isFloat as _isFloat, isMoney as _isMoney } from './tsutils-type-guards.js'\nimport { parseColor as _parseColor, colorContrast as _colorContrast, colorContrastValue as _colorContrastValue, hsv2rgb as _hsv2rgb, rgb2hsv as _rgb2hsv } from './tsutils-color.js'\nimport type { TsColorRgb } from './tsutils-color.js'\nimport { clone as _clone, extend as _extend, naturalCompare as _naturalCompare, getNested as _getNested, normMenu as _normMenu, encodeParams as _encodeParams, prepareParams as _prepareParams, parseRoute as _parseRoute, debounce as _debounce, wait as _wait } from './tsutils-data.js'\nimport type { TsCloneOptions, TsNormMenuOptions } from './tsutils-data.js'\nexport type { TsNormMenuOptions } from './tsutils-data.js'\nimport { stripSpaces as _stripSpaces, stripTags as _stripTags, encodeTags as _encodeTags, decodeTags as _decodeTags, escapeId as _escapeId, unescapeId as _unescapeId, base64encode as _base64encode, base64decode as _base64decode, sha256 as _sha256, execTemplate as _execTemplate } from './tsutils-string.js'\nimport { marker as _marker } from './tsutils-marker.js'\nimport { TsUi, checkName as _checkName } from './tsutils-registry.js'\nimport { notify as _notify } from './tsutils-notify.js'\nimport { normButtons as _normButtons, _message as _messageFn, _alert as _alertFn, _confirm as _confirmFn, _prompt as _promptFn } from './tsutils-message.js'\nimport type { TsMessageProm, TsMessageWhere, TsMessageOptions, MessageDeps, ConfirmDeps, PromptDeps } from './tsutils-message.js'\nexport type { TsMessageProm, TsMessageWhere, TsMessageOptions } from './tsutils-message.js'\nimport { transition as _transition, lock as _lock, unlock as _unlock, getSize as _getSize, getStrDimentions as _getStrDimentions, getStrWidth as _getStrWidth, getStrHeight as _getStrHeight, bindEvents as _bindEvents } from './tsutils-dom.js'\nimport type { TsLockOptions } from './tsutils-dom.js'\nexport type { TsLockOptions } from './tsutils-dom.js'\nimport { _isDate, _isTime, _isDateTime, _age, _interval, _formatDate, _formatTime, _formatDateTime, _date } from './tsutils-datetime.js'\nimport type { TsTimeResult } from './tsutils-datetime.js'\nimport { _locale } from './tsutils-locale.js'\nimport type { LocaleDeps } from './tsutils-locale.js'\n\n// TsUtils always calls query() with a selector (never a callback) so the return is always Query.\n// any: query() overload returns void|Query when called with a callback; we only use selector calls here\nconst query = _query as (selector: unknown, context?: unknown) => Query\n\n// ---------------------------------------------------------------------------\n// Public interfaces — exported via TsUtils instance\n// ---------------------------------------------------------------------------\n\n/** Settings object merged from TsLocale + user locale overrides */\nexport interface TsUISettings {\n dataType: string\n dateFormat: string\n timeFormat: string\n datetimeFormat: string\n dateStartYear: number\n dateEndYear: number\n currencyPrefix: string\n currencySuffix: string\n currencyPrecision: number\n groupSymbol: string\n decimalSymbol: string\n shortmonths: string[]\n fullmonths: string[]\n shortdays: string[]\n fulldays: string[]\n weekStarts: string\n macButtonOrder: boolean\n warnNoPhrase: boolean\n phrases: Record<string, string> | null\n missing?: Record<string, string>\n locale?: string\n [key: string]: unknown // locale files can add arbitrary keys; unknown forces cast at use-sites\n}\n\n/** Extra data passed to grid cell formatters */\ninterface TsFormatterExtra {\n value: unknown\n params?: unknown\n record?: unknown\n [key: string]: unknown\n}\n\n/** Signature of a grid-cell formatter function */\ntype TsFormatter = (record: TsFormatterExtra, extra?: TsFormatterExtra) => string\n\n\n/** RGB(A) color as returned by TsUtils.parseColor() — defined in tsutils-color, re-exported here for barrel compatibility */\nexport type { TsColorRgb } from './tsutils-color.js'\n\n/** Return value from TsUtils.isTime() — defined in tsutils-datetime, re-exported here for barrel compatibility */\nexport type { TsTimeResult } from './tsutils-datetime.js'\n\n/** Options for TsUtils.clone() — defined in tsutils-data, re-exported here for barrel compatibility */\nexport type { TsCloneOptions } from './tsutils-data.js'\n\n/** Route parameter descriptor */\ninterface TsRouteKey {\n name: string\n optional: boolean\n}\n\n/** Parsed route as returned by TsUtils.parseRoute() */\ninterface _W2ParsedRoute {\n path: RegExp\n keys: TsRouteKey[]\n}\n\n/** A normalized menu item */\nexport interface TsMenuItem {\n id: string | number | null\n text: string\n caption?: string\n class?: string\n style?: string\n attrs?: string\n [key: string]: unknown\n}\n\n// TsMessageProm, TsMessageWhere, TsMessageOptions — moved to tsutils-message.ts (Phase 3a of v2.3 SDD).\n// Re-exported above via: export type { TsMessageProm, TsMessageWhere, TsMessageOptions } from './tsutils-message.js'\n\nclass Utils {\n version: string\n tmp: Record<string, unknown>\n settings: TsUISettings\n i18nCompare: (a: string, b: string) => number\n hasLocalStorage: boolean\n isMac: boolean\n isMobile: boolean\n isIOS: boolean\n isAndroid: boolean\n isSafari: boolean\n isFirefox: boolean\n formatters: Record<string, TsFormatter>\n\n constructor () {\n this.version = '2.0.x'\n this.tmp = {}\n this.settings = this.extend({}, {\n 'dataType' : 'JSON', // can be HTTP, JSON, RESTFULL (case sensitive)\n 'dateStartYear' : 1950, // start year for date-picker\n 'dateEndYear' : 2030, // end year for date picker\n 'macButtonOrder' : false, // if true, Yes on the right side\n 'warnNoPhrase' : false, // call console.warn if lang() encounters a missing phrase\n }, TsLocale, { phrases: null }), // if there are no phrases, then it is original language\n this.i18nCompare = Intl.Collator().compare\n this.hasLocalStorage = testLocalStorage()\n\n // some internal variables\n this.isMac = /Mac/i.test(navigator.platform)\n this.isMobile = /(iphone|ipod|mobile|android)/i.test(navigator.userAgent)\n this.isIOS = /(iphone|ipod|ipad)/i.test(navigator.platform)\n this.isAndroid = /(android)/i.test(navigator.userAgent)\n this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n this.isFirefox = /(Firefox)/i.test(navigator.userAgent)\n\n // Formatters: Primarily used in grid\n this.formatters = {\n 'number'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params\n if (parseInt(String(params)) > 20) params = 20\n if (parseInt(String(params)) < 0) params = 0\n if (value == null || value === '') return ''\n return TsUtils.formatNumber(parseFloat(String(value)), params as number, true)\n },\n\n 'float'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n return TsUtils.formatters['number']?.(record, extra) ?? ''\n },\n\n 'int'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n return TsUtils.formatters['number']?.(record, extra) ?? ''\n },\n\n 'money'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n if (value == null || value === '') return ''\n const data = TsUtils.formatNumber(Number(value), TsUtils.settings.currencyPrecision, true)\n return (TsUtils.settings.currencyPrefix || '') + data + (TsUtils.settings.currencySuffix || '')\n },\n\n 'currency'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n return TsUtils.formatters['money']?.(record, extra) ?? ''\n },\n\n 'percent'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value, params } = extra\n if (value == null || value === '') return ''\n return TsUtils.formatNumber(value, (params as number) || 1) + '%'\n },\n\n 'size'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n if (value == null || value === '') return ''\n return String(TsUtils.formatSize(parseInt(String(value))))\n },\n\n 'date'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params as string | undefined\n if (params === '') params = TsUtils.settings.dateFormat\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, params ?? null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, params ?? null, true) as boolean | Date\n const dtStr = dt instanceof Date ? dt : ''\n return '<span title=\"'+ dtStr +'\">' + TsUtils.formatDate(dt instanceof Date ? dt : undefined, params) + '</span>'\n },\n\n 'datetime'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params as string | undefined\n if (params === '') params = TsUtils.settings.datetimeFormat\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, params ?? null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, params ?? null, true) as boolean | Date\n const dtStr = dt instanceof Date ? dt : ''\n return '<span title=\"'+ dtStr +'\">' + TsUtils.formatDateTime(dt instanceof Date ? dt : undefined, params) + '</span>'\n },\n\n 'time'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params as string | undefined\n if (params === '') params = TsUtils.settings.timeFormat\n if (params === 'h12') params = 'hh:mi pm'\n if (params === 'h24') params = 'h24:mi'\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, params ?? null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, params ?? null, true) as boolean | Date\n const dtStr = dt instanceof Date ? dt : ''\n return '<span title=\"'+ dtStr +'\">' + TsUtils.formatTime(value, params) + '</span>'\n },\n\n 'timestamp'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params as string | undefined\n if (params === '') params = TsUtils.settings.datetimeFormat\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, params ?? null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, params ?? null, true) as boolean | Date\n return dt instanceof Date ? dt.toString() : ''\n },\n\n 'gmt'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let params = extra.params as string | undefined\n if (params === '') params = TsUtils.settings.datetimeFormat\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, params ?? null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, params ?? null, true) as boolean | Date\n return dt instanceof Date ? dt.toUTCString() : ''\n },\n\n 'age'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value, params } = extra\n if (value == null || value === 0 || value === '') return ''\n let dt: boolean | Date = TsUtils.isDateTime(value, null, true) as boolean | Date\n if (dt === false) dt = TsUtils.isDate(value, null, true) as boolean | Date\n const dtStr = dt instanceof Date ? dt : ''\n return '<span title=\"'+ dtStr +'\">' + TsUtils.age(value) + (params ? (' ' + params) : '') + '</span>'\n },\n\n 'interval'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value, params } = extra\n if (value == null || value === 0 || value === '') return ''\n return TsUtils.interval(Number(value)) + (params ? (' ' + params) : '')\n },\n\n 'toggle'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n return (value ? TsUtils.lang('Yes') : '')\n },\n\n 'password'(record: TsFormatterExtra, extra?: TsFormatterExtra): string {\n if (extra == undefined) extra = record\n const { value } = extra\n let ret = ''\n if (!value) return ret\n const strVal = String(value)\n for (let i = 0; i < strVal.length; i++) {\n ret += '*'\n }\n return ret\n }\n }\n return\n\n function testLocalStorage() {\n // test if localStorage is available, see issue #1282\n const str = 'w2ui_test'\n try {\n localStorage.setItem(str, str)\n localStorage.removeItem(str)\n return true\n } catch (e) {\n return false\n }\n }\n }\n\n isBin(val: unknown): boolean { return _isBin(val) }\n\n isInt(val: unknown): boolean { return _isInt(val) }\n\n isFloat(val: unknown): boolean { return _isFloat(val, this.settings) }\n\n isMoney(val: unknown): boolean { return _isMoney(val, this.settings) }\n\n isHex(val: unknown): boolean { return _isHex(val) }\n\n isAlphaNumeric(val: unknown): boolean { return _isAlphaNumeric(val) }\n\n isEmail(val: unknown): boolean { return _isEmail(val) }\n\n isIpAddress(val: unknown): boolean { return _isIpAddress(val) }\n\n isDate(val: unknown, format?: string | null, retDate?: boolean): boolean | Date {\n return _isDate(val, format, retDate, this.settings)\n }\n\n isTime(val: unknown, retTime?: boolean): boolean | TsTimeResult {\n return _isTime(val, retTime) as boolean | TsTimeResult\n }\n\n isDateTime(val: unknown, format?: string | null, retDate?: boolean): boolean | Date {\n return _isDateTime(val, format, retDate, this.settings)\n }\n\n age(dateStr: unknown): string { return _age(dateStr) }\n\n interval(value: number): string { return _interval(value) }\n\n date(dateStr: unknown): string {\n return _date(dateStr, this.settings, { lang: this.lang.bind(this) })\n }\n\n formatSize(sizeStr: unknown): string | number {\n if (!this.isFloat(sizeStr) || sizeStr === '') return ''\n const num = parseFloat(String(sizeStr))\n if (num === 0) return 0\n const sizes = ['Bt', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB']\n const i = parseInt(String(Math.floor( Math.log(num) / Math.log(1024) )))\n return (Math.floor(num / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + (sizes[i] || '??')\n }\n\n formatNumber(val: unknown, fraction?: number | string | null, useGrouping?: boolean): string {\n if (val == null || val === '' || typeof val === 'object') return ''\n const options: Intl.NumberFormatOptions = {\n minimumFractionDigits: fraction != null ? parseInt(String(fraction)) : undefined,\n maximumFractionDigits: fraction != null ? parseInt(String(fraction)) : undefined,\n useGrouping: !!useGrouping\n }\n if (fraction == null || Number(fraction) < 0) {\n options.minimumFractionDigits = 0\n options.maximumFractionDigits = 20\n }\n return parseFloat(String(val)).toLocaleString(this.settings.locale, options)\n }\n\n formatDate(dateStr: unknown, format?: string | null): string {\n return _formatDate(dateStr, format, this.settings)\n }\n\n formatTime(dateStr: unknown, format?: string | null): string {\n return _formatTime(dateStr, format, this.settings)\n }\n\n formatDateTime(dateStr: unknown, format?: string | null): string {\n return _formatDateTime(dateStr, format, this.settings)\n }\n\n stripSpaces(html: unknown): unknown { return _stripSpaces(html) }\n\n stripTags(html: unknown): unknown { return _stripTags(html) }\n\n encodeTags(html: unknown): unknown { return _encodeTags(html) }\n\n decodeTags(html: unknown): unknown { return _decodeTags(html) }\n\n escapeId(id: unknown): string { return _escapeId(id) }\n\n unescapeId(id: string | null | undefined): string { return _unescapeId(id) }\n\n base64encode(str: string): string { return _base64encode(str) }\n\n base64decode(encodedStr: string): string { return _base64decode(encodedStr) }\n\n sha256(str: string): Promise<string> { return _sha256(str) }\n\n transition(div_old: HTMLElement, div_new: HTMLElement, type: string, callBack?: () => void): Promise<void> { return _transition(div_old, div_new, type, callBack) }\n\n lock(box: unknown, options: TsLockOptions | string = {}, ...rest: unknown[]): void { return _lock(box, options, ...rest) }\n\n unlock(box: unknown, speed?: number): void { return _unlock(box, speed) }\n\n /**\n * Constructs the MessageDeps object for the _message() delegator.\n * Called once per message() invocation — captures `this` at call time.\n * Per design §C.5 / §C.2.\n * @internal\n */\n private _msgDeps(): MessageDeps {\n return {\n extend: _extend,\n bindEvents: (s, subj) => this.bindEvents(s, subj),\n lock: (box, opts) => this.lock(box, opts as never),\n unlock: (box, speed) => this.unlock(box, speed),\n // any: 'name' is set dynamically on widget instances (TsGrid, TsForm, etc.) at runtime\n ownerName: (this as unknown as Record<string, unknown>)['name'] as string | undefined,\n self: this as unknown as Record<string, unknown>\n }\n }\n\n /**\n * Constructs the ConfirmDeps object for the _confirm() delegator.\n * Per design §C.3.\n * normButtons closure: uses inline lambda that binds this.lang and this.settings\n * at call time — preserving the call-time timing semantics (design §C.3 caveat).\n * @internal\n */\n private _confirmDeps(): ConfirmDeps {\n return {\n extend: _extend,\n normButtons: (opts, btn) => _normButtons(opts, btn, { extend: _extend, lang: this.lang.bind(this), settings: this.settings }),\n message: (w, o) => this.message(w, o),\n settings: this.settings,\n lang: this.lang.bind(this)\n }\n }\n\n /**\n * Constructs the PromptDeps object for the _prompt() delegator.\n * Per design §C.3.\n * lang is bound at call time so deps.lang('Ok') uses current locale.\n * @internal\n */\n private _promptDeps(): PromptDeps {\n return {\n extend: _extend,\n normButtons: (opts, btn) => _normButtons(opts, btn, { extend: _extend, lang: this.lang.bind(this), settings: this.settings }),\n message: (w, o) => this.message(w, o),\n settings: this.settings,\n lang: this.lang.bind(this)\n }\n }\n\n /**\n * Opens a context message, similar in parameters as TsPopup.open()\n *\n * Sample Calls\n * TsUtils.message({ box: '#div', text: 'message' }).ok(() => {})\n * TsUtils.message({ box: '#div', text: 'message', width: 300 }).ok(() => {})\n * TsUtils.message({ box: '#div', text: 'message', actions: ['Save'] }).Save(() => {})\n *\n * Used in TsGrid, TsForm, TsLayout (should be in TsPopup too)\n * should be called with .call(...) method\n *\n * @param where = {\n * box, // where to open\n * after, // title if any, adds title heights\n * param // additional parameters, used in layouts for panel\n * }\n * @param options {\n * width, // (int), width in px, if negative, then it is maxWidth - width\n * height, // (int), height in px, if negative, then it is maxHeight - height\n * text, // centered text\n * body, // body of the message\n * buttons, // buttons of the message\n * html, // if body & buttons are not defined, then html is the entire message\n * focus, // int or id with a selector, default is 0\n * hideOn, // ['esc', 'click'], default is ['esc']\n * actions, // array of actions (only if buttons is not defined)\n * onOpen, // event when opened\n * onClose, // event when closed\n * onAction, // event on action\n * }\n */\n message(where: TsMessageWhere, options?: TsMessageOptions | string | number): TsMessageProm | undefined {\n return _messageFn(where, options, this._msgDeps())\n }\n\n alert(where: TsMessageWhere, options?: TsMessageOptions | string | number): TsMessageProm | undefined {\n return _alertFn(where, options, this._msgDeps())\n }\n\n /**\n * Shows a prompt as a context message. It will use same where: { box: ... } as TsUtils.message() function\n * but it will have options similar to TsPrompt dialog\n *\n * Example:\n * - TsUtils.conrirm({\n * box: '#custom',\n * text: 'Some message'\n * })\n * .yes(event => console.log(event))\n */\n confirm(where: TsMessageWhere, options?: TsMessageOptions | string | number): TsMessageProm | undefined {\n return _confirmFn(where, options, this._confirmDeps())\n }\n\n /**\n * Shows a prompt as a context message. It will use same where: { box: ... } as TsUtils.message() function\n * but it will have options similar to TsPrompt dialog\n *\n * Example:\n * - TsUtils.prompt({\n * box: '#custom',\n * label: 'Enter Name',\n * textarea: false,\n * attrs: 'style=\"border: 1px solid red\"'\n * })\n * .ok(event => console.log(event))\n */\n prompt(where: TsMessageWhere, options?: TsMessageOptions | string | number): TsMessageProm | undefined {\n return _promptFn(where, options, this._promptDeps())\n }\n\n /**\n * Normalizes yes, no buttons for confirmation dialog\n *\n * @param {*} options\n * @returns options\n */\n normButtons(options: Record<string, unknown>, btn: Record<string, unknown>): Record<string, unknown> {\n return _normButtons(options, btn, {\n extend: _extend,\n lang: this.lang.bind(this),\n settings: this.settings\n })\n }\n\n /**\n * Shows small notification message at the bottom of the page, or containter that you specify\n * in options.where (could be element or a selector)\n *\n * TsUtils.notify('Document saved')\n * TsUtils.notify('Mesage sent ${udon}', { actions: { undo: function () {...} }})\n *\n * @param {String/Object} options can be {\n * text: string, // message, can be html\n * where: el/selector, // element or selector where to show, default is document.body\n * timeout: int, // timeout when to hide, if 0 - indefinite\n * error: boolean, // add error clases\n * class: string, // additional class strings\n * actions: object // object with action functions, it should correspot to templated text: '... ${action} ...'\n * }\n * @returns promise\n */\n notify(text: string | Record<string, unknown>, options?: Record<string, unknown>): Promise<void> {\n return _notify(text, options, { execTemplate: this.execTemplate.bind(this), tmpSlot: this.tmp })\n }\n\n getSize(el: unknown, type: string): number { return _getSize(el, type) }\n\n getStrDimentions(str: string, styles?: string, raw?: boolean) { return _getStrDimentions(str, styles, raw) }\n\n getStrWidth(str: string, styles?: string, raw?: boolean) { return this.getStrDimentions(str, styles, raw).width }\n\n getStrHeight(str: string, styles?: string, raw?: boolean) { return this.getStrDimentions(str, styles, raw).height }\n\n // any: targeted-any per typing_policy; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n execTemplate(str: any, replace_obj: any): any { return _execTemplate(str, replace_obj) }\n\n // any: parameter typed any — runtime dispatch by call site; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n marker(el: any, items: any, options?: any): unknown { return _marker(el, items, options) }\n\n\n lang(phrase: string, params?: Record<string, string | number> | boolean): string {\n if (!phrase || this.settings.phrases == null // if no phrases at all\n || typeof phrase !== 'string' || '<=>='.includes(phrase)) {\n return this.execTemplate(phrase, params)\n }\n let translation = this.settings.phrases[phrase]\n if (translation == null) {\n translation = phrase\n if (this.settings.warnNoPhrase) {\n if (!this.settings.missing) {\n this.settings.missing = {}\n }\n this.settings.missing[phrase] = '---' // collect phrases for translation, warn once\n this.settings.phrases[phrase] = '---'\n console.log(`Missing translation for \"%c${phrase}%c\", see %c TsUtils.settings.phrases %c with value \"---\"`,\n 'color: orange', '',\n 'color: #999', '')\n }\n } else if (translation === '---' && !this.settings.warnNoPhrase) {\n translation = phrase\n }\n if (translation === '---') {\n translation = `<span ${this.tooltip(phrase)}>---</span>`\n }\n return this.execTemplate(translation, params)\n }\n\n locale(locale: string | string[] | Record<string, unknown>, keepPhrases?: boolean, noMerge?: boolean): Promise<{ file: string; data: unknown } | void> {\n const deps: LocaleDeps = {\n extend: this.extend.bind(this) as (target: object, ...sources: object[]) => object,\n fetch: globalThis.fetch.bind(globalThis),\n }\n return _locale(locale, keepPhrases, noMerge, this.settings, deps).then(result => {\n if (result.settings) this.settings = result.settings\n return result.kind === 'load' ? { file: result.file, data: result.data } : undefined\n })\n }\n\n scrollBarSize() {\n if (this.tmp['scrollBarSize']) return this.tmp['scrollBarSize']\n const html = `\n <div id=\"_scrollbar_width\" style=\"position: absolute; top: -300px; width: 100px; height: 100px; overflow-y: scroll;\">\n <div style=\"height: 120px\">1</div>\n </div>\n `\n query('body').append(html)\n this.tmp['scrollBarSize'] = 100 - (query('#_scrollbar_width > div')[0] as HTMLElement).clientWidth\n query('#_scrollbar_width').remove()\n return this.tmp['scrollBarSize']\n }\n\n checkName(name: string): boolean {\n return _checkName(name)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n checkUniqueId(id: any, items: any, desc: any, obj: any): boolean { // any: generic runtime utility; callers pass heterogeneous types\n if (!Array.isArray(items)) items = [items]\n let isUnique = true\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n items.forEach((item: any) => { // any: item is an arbitrary menu/record object\n if (item.id === id) {\n console.log(`ERROR: The item id=\"${id}\" is not unique within the ${desc} \"${obj}\".`, items)\n isUnique = false\n }\n })\n return isUnique\n }\n\n /**\n * Takes an object and encodes it into params string to be passed as a url\n * { a: 1, b: 'str'} => \"a=1&b=str\"\n * { a: 1, b: { c: 2 }} => \"a=1&b[c]=2\"\n * { a: 1, b: {c: { k: 'dfdf' } } } => \"a=1&b[c][k]=dfdf\"\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n encodeParams(obj: any, prefix = ''): string { // any: arbitrary nested object from user code\n return _encodeParams(obj, prefix)\n }\n\n parseRoute(route: string): { path: RegExp; keys: { name: string; optional: boolean }[] } {\n return _parseRoute(route)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getCursorPosition(input: any): number | null { // any: accepts HTMLInputElement, HTMLTextAreaElement, contenteditable div, etc.\n if (input == null) return null\n let caretOffset = 0\n const doc = input.ownerDocument || input.document\n const win = doc.defaultView || doc.parentWindow\n let sel\n if (['INPUT', 'TEXTAREA'].includes(input.tagName)) {\n caretOffset = input.selectionStart\n } else {\n if (win.getSelection) {\n sel = win.getSelection()\n if (sel.rangeCount > 0) {\n const range = sel.getRangeAt(0)\n const preCaretRange = range.cloneRange()\n preCaretRange.selectNodeContents(input)\n preCaretRange.setEnd(range.endContainer, range.endOffset)\n caretOffset = preCaretRange.toString().length\n }\n } else if ( (sel = doc.selection) && sel.type !== 'Control') {\n const textRange = sel.createRange()\n const preCaretTextRange = doc.body.createTextRange()\n preCaretTextRange.moveToElementText(input)\n preCaretTextRange.setEndPoint('EndToEnd', textRange)\n caretOffset = preCaretTextRange.text.length\n }\n }\n return caretOffset\n }\n\n setCursorPosition(input: HTMLElement | null, pos: number, posEnd?: number): void {\n if (input == null) return\n const range = document.createRange()\n let el: Node | null = null\n const sel = window.getSelection()\n if (['INPUT', 'TEXTAREA'].includes(input.tagName)) {\n ;(input as HTMLInputElement).setSelectionRange(pos, posEnd ?? pos)\n } else {\n for (let i = 0; i < input.childNodes.length; i++) {\n // any: query().text() / .html() returns string|Query; cast to string\n let tmp = String(query(input.childNodes[i]).text())\n if ((input.childNodes[i] as HTMLElement).tagName) {\n tmp = String(query(input.childNodes[i]).html())\n tmp = tmp.replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/&/g, '&')\n .replace(/"/g, '\"')\n .replace(/ /g, ' ')\n }\n if (pos <= tmp.length) {\n el = input.childNodes[i] ?? null\n if (el != null && el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] ?? null\n if (el != null && el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] ?? null\n break\n } else {\n pos -= tmp.length\n }\n }\n if (el == null) return\n // any: el is a Text node at this point; cast to access .length\n const elLen = (el as Text).length ?? 0\n if (pos > elLen) pos = elLen\n range.setStart(el, pos)\n if (posEnd) {\n range.setEnd(el, posEnd)\n } else {\n range.collapse(true)\n }\n sel?.removeAllRanges()\n sel?.addRange(range)\n }\n }\n\n parseColor(str: string | null | undefined): TsColorRgb | null { return _parseColor(str) }\n\n colorContrast(color1: string, color2: string): string { return _colorContrast(color1, color2) }\n\n colorContrastValue(color1: string, color2: string): number { return _colorContrastValue(color1, color2) }\n\n // h=0..360, s=0..100, v=0..100\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hsv2rgb(h: any, s?: any, v?: any, a?: any): { r: number; g: number; b: number; a: number } { return (_hsv2rgb as any)(h, s, v, a) } // any: overloaded dual-form delegator\n\n // r=0..255, g=0..255, b=0..255\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n rgb2hsv(r: any, g?: any, b?: any, a?: any): { h: number; s: number; v: number; a: number } { return (_rgb2hsv as any)(r, g, b, a) } // any: overloaded dual-form delegator\n\n tooltip(html: string | Record<string, unknown>, options?: Record<string, unknown>): string {\n let showOn = 'mouseenter'\n let hideOn = 'mouseleave'\n let opts: Record<string, unknown> = options ?? {}\n if (typeof html == 'object') {\n opts = html\n }\n if (typeof html == 'string') {\n opts = { ...opts, html }\n }\n if (opts['showOn']) {\n showOn = opts['showOn'] as string\n delete opts['showOn']\n }\n if (opts['hideOn']) {\n hideOn = opts['hideOn'] as string\n delete opts['hideOn']\n }\n if (!opts['name']) opts['name'] = 'no-name'\n // base64 is needed to avoid '\"<> and other special chars conflicts\n const actions = ` on${showOn}=\"TsTooltip.show(this, `\n + `JSON.parse(TsUtils.base64decode('${this.base64encode(JSON.stringify(opts))}')))\" `\n + `on${hideOn}=\"TsTooltip.hide('${opts['name']}')\"`\n return actions\n }\n\n // determins if it is plain Object, not DOM element, nor a function, event, etc.\n isPlainObject(value: unknown): boolean { return _isPlainObject(value) }\n\n /**\n * Deep copy of an object or an array. Function, events and HTML elements will not be cloned,\n * you can choose to include them or not, by default they are included.\n * You can also exclude certain elements from final object if used with options: { exclude }\n */\n // any: return type any — caller narrows by code path; TsUtils helper accepts heterogeneous runtime input\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n clone(obj: unknown, options?: Partial<TsCloneOptions>): any { return _clone(obj, options) }\n\n /**\n * Deep extend an object, if an array, it overwrrites it, cloning objects in the process\n * target, source1, source2, ...\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n extend(target: any, source: any, ...rest: unknown[]): any { return _extend(target, source, ...rest) } // any: generic deep-extend; arbitrary object shapes at runtime\n\n /*\n * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)\n * @license MIT License\n */\n naturalCompare(a: unknown, b: unknown): number {\n return _naturalCompare(a, b)\n }\n\n /**\n * Takes a menu (used in drop downs, context menu, field: list/combo/enum) and normalizes it to the common structure, which\n * is { id: ..., text: ... }. In options you can pass { itemMap: { id: 'id_field', text: 'text_field' }} that will be used\n * to find out id and text fields.\n */\n normMenu(menu: unknown, options: TsNormMenuOptions = {}): TsMenuItem[] | undefined {\n return _normMenu(menu, options) as TsMenuItem[] | undefined\n }\n\n /**\n * Takes Url object and fetchOptions and changes it in place applying selected user dataType. Since\n * dataType is in TsUtils. This method is used in grid, form and tooltip to prepare fetch parameters\n */\n prepareParams(url: URL, fetchOptions: Record<string, unknown>, options: Record<string, unknown> = {}): Record<string, unknown> {\n return _prepareParams(url, fetchOptions, options, TsUtils.settings.dataType)\n }\n\n bindEvents(selector: unknown, subject: Record<string, unknown>): void { return _bindEvents(selector, subject) }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n debounce(func: (...args: any[]) => void, wait = 250): (...args: any[]) => void { // any: debounce wraps arbitrary functions\n return _debounce(func, wait)\n }\n\n async wait(time = 0): Promise<void> {\n return _wait(time)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getNested(obj: any, prop: any): unknown { // any: traverses arbitrary nested objects via dot-path string\n return _getNested(obj, prop)\n }\n}\nvar TsUtils = new Utils() // eslint-disable-line -- needs to be functional/module scope variable\nexport { TsUi, TsUtils, query }\n"],"mappings":"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","names":["query","el","getTextNodes","match","query","query","options","edata","focus","query","query","query","wait"]}
|