@framesquared/core 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/util/index.ts","../src/util/String.ts","../src/util/Array.ts","../src/util/Object.ts","../src/util/Function.ts","../src/class/Base.ts","../src/class/ClassManager.ts","../src/class/Configurator.ts","../src/class/decorators.ts","../src/mixin/Identifiable.ts","../src/mixin/Factoryable.ts","../src/mixin/Inheritable.ts","../src/mixin/Hookable.ts","../src/Plugin.ts","../src/mixin/Pluggable.ts","../src/event/Event.ts","../src/event/Observable.ts","../src/event/Destroyable.ts","../src/event/EventDomain.ts","../src/event/EventBus.ts","../src/event/DomEvent.ts","../src/event/GestureRecognizer.ts","../src/event/KeyMap.ts","../src/aria/AriaManager.ts","../src/aria/FocusManager.ts","../src/locale/Locale.ts","../src/locale/LocaleManager.ts","../src/locale/bundles/en-US.ts","../src/locale/bundles/es-ES.ts","../src/locale/bundles/ar-SA.ts","../src/util/Sanitizer.ts","../src/index.ts"],"sourcesContent":["/**\n * @framesquared/core – utility functions\n *\n * Pure, side-effect-free helpers (except timer wrappers and generateId).\n * Every function is individually exported so tree-shaking works out of the box.\n */\n\n// ---------------------------------------------------------------------------\n// identity / emptyFn\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the value unchanged. Useful as a default transform or callback.\n */\nexport function identity<T>(value: T): T {\n return value;\n}\n\n/**\n * A reusable no-op function.\n */\nexport function emptyFn(): void {\n /* intentionally blank */\n}\n\n// ---------------------------------------------------------------------------\n// apply / applyIf\n// ---------------------------------------------------------------------------\n\n/**\n * Copies **own** enumerable properties from `source` to `target`,\n * but only when the property does **not** already exist on `target`\n * (checked via the `in` operator so even `undefined` values are preserved).\n *\n * Returns the mutated `target`.\n */\nexport function applyIf<T extends object>(target: T, source: Partial<T>): T {\n const keys = Object.keys(source) as (keyof T)[];\n for (const key of keys) {\n if (!(key in target)) {\n (target as Record<keyof T, unknown>)[key] = source[key];\n }\n }\n return target;\n}\n\n/**\n * Copies **own** enumerable properties from every `source` to `target`,\n * overwriting any existing values. Sources are applied left-to-right so\n * later sources win.\n *\n * Returns the mutated `target`.\n */\nexport function apply<T extends object>(target: T, ...sources: Partial<T>[]): T {\n for (const source of sources) {\n const keys = Object.keys(source) as (keyof T)[];\n for (const key of keys) {\n (target as Record<keyof T, unknown>)[key] = source[key];\n }\n }\n return target;\n}\n\n// ---------------------------------------------------------------------------\n// clone\n// ---------------------------------------------------------------------------\n\n/**\n * Deep-clones `value` using the platform's `structuredClone`.\n */\nexport function clone<T>(value: T): T {\n return structuredClone(value);\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/**\n * `true` for plain objects only — `{}`, `Object.create(null)`, and objects\n * whose prototype is `Object.prototype`. Returns `false` for arrays,\n * functions, `null`, class instances (`Date`, `RegExp`, …), and primitives.\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * `true` for primitive `string` values only (not `String` wrapper objects).\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * `true` for finite numbers and `±Infinity`. Explicitly **excludes** `NaN`.\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !Number.isNaN(value);\n}\n\n/**\n * `true` for primitive `boolean` values only (not `Boolean` wrapper objects).\n */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\n/**\n * `true` for any callable — arrows, named functions, async functions,\n * generators, and class constructors.\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function';\n}\n\n/**\n * Thin wrapper around `Array.isArray` with an `unknown[]` return type.\n */\nexport function isArray(value: unknown): value is unknown[] {\n return Array.isArray(value);\n}\n\n/**\n * `true` when `value` is neither `undefined` nor `null`.\n */\nexport function isDefined<T>(value: T | undefined | null): value is T {\n return value !== undefined && value !== null;\n}\n\n/**\n * `true` for values that are conceptually \"empty\":\n * `undefined`, `null`, `''`, `[]`, `{}` (plain, no own keys), and `NaN`.\n */\nexport function isEmpty(value: unknown): boolean {\n if (value === undefined || value === null) return true;\n if (typeof value === 'number') return Number.isNaN(value);\n if (typeof value === 'string') return value.length === 0;\n if (Array.isArray(value)) return value.length === 0;\n if (isObject(value)) return Object.keys(value).length === 0;\n return false;\n}\n\n/**\n * `true` when `value` implements the iterable protocol (`Symbol.iterator`).\n * Returns `false` for `null`, `undefined`, and non-iterable objects.\n */\nexport function isIterable(value: unknown): value is Iterable<unknown> {\n if (value === null || value === undefined) return false;\n return typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function';\n}\n\n/**\n * `true` for all seven primitive types:\n * `string`, `number`, `boolean`, `undefined`, `null`, `symbol`, and `bigint`.\n */\nexport function isPrimitive(value: unknown): boolean {\n if (value === null) return true;\n const t = typeof value;\n return t !== 'object' && t !== 'function';\n}\n\n// ---------------------------------------------------------------------------\n// namespace\n// ---------------------------------------------------------------------------\n\n/**\n * Walks (and lazily creates) a dot-separated namespace on `root`.\n *\n * ```ts\n * const root = {};\n * namespace(root, 'a.b.c'); // root is now { a: { b: { c: {} } } }\n * ```\n *\n * Existing intermediate objects are preserved; only missing segments are\n * created as empty plain objects. Returns the **leaf** object.\n */\nexport function namespace(root: object, path: string): object {\n const segments = path.split('.');\n let current: Record<string, unknown> = root as Record<string, unknown>;\n\n for (const segment of segments) {\n if (current[segment] === undefined || current[segment] === null) {\n current[segment] = {};\n }\n current = current[segment] as Record<string, unknown>;\n }\n\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Timer helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Wrapper around `setTimeout` that returns the numeric timer id.\n */\nexport function defer(fn: () => void, millis = 0): number {\n return +setTimeout(fn, millis);\n}\n\n/**\n * Wrapper around `setInterval` that returns the numeric timer id.\n */\nexport function interval(fn: () => void, millis: number): number {\n return +setInterval(fn, millis);\n}\n\n/**\n * High-resolution timestamp via `performance.now()`.\n */\nexport function now(): number {\n return performance.now();\n}\n\n// ---------------------------------------------------------------------------\n// generateId\n// ---------------------------------------------------------------------------\n\nlet idCounter = 0;\n\n/**\n * Generates a globally-unique ID string. The counter is monotonically\n * increasing across all prefixes.\n *\n * ```ts\n * generateId(); // \"framesquared-1\"\n * generateId(); // \"framesquared-2\"\n * generateId('widget'); // \"widget-3\"\n * ```\n */\nexport function generateId(prefix = 'framesquared'): string {\n return `${prefix}-${++idCounter}`;\n}\n","/**\n * @framesquared/core – String utilities\n */\n\n// ---------------------------------------------------------------------------\n// capitalize / uncapitalize\n// ---------------------------------------------------------------------------\n\n/**\n * Capitalizes the first character of `str`.\n */\nexport function capitalize(str: string): string {\n if (str.length === 0) return str;\n return str[0].toUpperCase() + str.slice(1);\n}\n\n/**\n * Lowercases the first character of `str`.\n */\nexport function uncapitalize(str: string): string {\n if (str.length === 0) return str;\n return str[0].toLowerCase() + str.slice(1);\n}\n\n// ---------------------------------------------------------------------------\n// ellipsis\n// ---------------------------------------------------------------------------\n\n/**\n * Truncates `value` to `length` characters (including a trailing `\"…\"` when\n * truncation occurs). When `word` is `true` the cut happens before the last\n * whitespace boundary so words are not split mid-way.\n */\nexport function ellipsis(value: string, length: number, word?: boolean): string {\n if (value.length <= length) return value;\n if (length <= 3) return '...';\n\n const truncLen = length - 3;\n\n if (word) {\n const lastSpace = value.lastIndexOf(' ', truncLen);\n if (lastSpace > 0) {\n return value.slice(0, lastSpace) + '...';\n }\n }\n\n return value.slice(0, truncLen) + '...';\n}\n\n// ---------------------------------------------------------------------------\n// HTML escaping\n// ---------------------------------------------------------------------------\n\nconst HTML_ESCAPE_MAP: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;',\n};\n\nconst HTML_UNESCAPE_MAP: Record<string, string> = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n};\n\nconst HTML_ESCAPE_RE = /[&<>\"']/g;\nconst HTML_UNESCAPE_RE = /&amp;|&lt;|&gt;|&quot;|&#39;/g;\n\n/**\n * Escapes `&`, `<`, `>`, `\"`, and `'` to their HTML entity equivalents.\n */\nexport function escapeHtml(str: string): string {\n return str.replace(HTML_ESCAPE_RE, (ch) => HTML_ESCAPE_MAP[ch]);\n}\n\n/**\n * Reverses {@link escapeHtml}, converting HTML entities back to characters.\n */\nexport function unescapeHtml(str: string): string {\n return str.replace(HTML_UNESCAPE_RE, (entity) => HTML_UNESCAPE_MAP[entity]);\n}\n\n/** Alias for {@link escapeHtml}. */\nexport const htmlEncode: typeof escapeHtml = escapeHtml;\n\n/** Alias for {@link unescapeHtml}. */\nexport const htmlDecode: typeof unescapeHtml = unescapeHtml;\n\n// ---------------------------------------------------------------------------\n// escapeRegex\n// ---------------------------------------------------------------------------\n\nconst REGEX_SPECIAL_RE = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Escapes all RegExp-special characters so the result can be used inside\n * `new RegExp(...)` to match the literal string.\n */\nexport function escapeRegex(str: string): string {\n return str.replace(REGEX_SPECIAL_RE, '\\\\$&');\n}\n\n// ---------------------------------------------------------------------------\n// format\n// ---------------------------------------------------------------------------\n\n/**\n * Replaces `{0}`, `{1}`, … placeholders in `template` with the\n * corresponding positional values (converted via `String()`).\n */\nexport function format(template: string, ...values: unknown[]): string {\n return template.replace(/\\{(\\d+)}/g, (match, index: string) => {\n const i = Number(index);\n return i < values.length ? String(values[i]) : match;\n });\n}\n\n// ---------------------------------------------------------------------------\n// repeat / trim / leftPad\n// ---------------------------------------------------------------------------\n\n/**\n * Repeats `str` exactly `count` times.\n */\nexport function repeat(str: string, count: number): string {\n return str.repeat(count);\n}\n\n/**\n * Trims leading and trailing whitespace.\n */\nexport function trim(str: string): string {\n return str.trim();\n}\n\n/**\n * Left-pads `str` to `size` characters using `char` (default `' '`).\n * Only the first character of `char` is used.\n */\nexport function leftPad(str: string, size: number, char = ' '): string {\n const padChar = char[0];\n const needed = size - str.length;\n if (needed <= 0) return str;\n return padChar.repeat(needed) + str;\n}\n\n// ---------------------------------------------------------------------------\n// toggle\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `value2` when `str === value1`, otherwise returns `value1`.\n */\nexport function toggle(str: string, value1: string, value2: string): string {\n return str === value1 ? value2 : value1;\n}\n\n// ---------------------------------------------------------------------------\n// splitWords / case conversions\n// ---------------------------------------------------------------------------\n\n/**\n * Splits a string into its constituent words, recognising camelCase,\n * PascalCase, snake_case, and kebab-case boundaries.\n *\n * Consecutive uppercase letters are treated as a single acronym, e.g.\n * `\"parseHTMLString\"` → `[\"parse\", \"HTML\", \"String\"]`.\n */\nexport function splitWords(str: string): string[] {\n if (str.length === 0) return [];\n\n // 1. Insert a boundary marker before each transition:\n // - lower/digit → Upper (camelCase boundary)\n // - Upper → Upper+Lower (acronym end: \"HTML\" + \"String\")\n const withBoundaries = str\n .replace(/([a-z0-9])([A-Z])/g, '$1\\0$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2');\n\n // 2. Split on the boundary marker, underscores, and hyphens, then remove empties.\n return withBoundaries.split(/[\\0_-]+/).filter(Boolean);\n}\n\n/**\n * Converts a string to `camelCase`.\n */\nexport function camelCase(str: string): string {\n const words = splitWords(str);\n if (words.length === 0) return '';\n return words\n .map((w, i) => {\n const lower = w.toLowerCase();\n return i === 0 ? lower : capitalize(lower);\n })\n .join('');\n}\n\n/**\n * Converts a string to `kebab-case`.\n */\nexport function kebabCase(str: string): string {\n const words = splitWords(str);\n return words.map((w) => w.toLowerCase()).join('-');\n}\n\n/**\n * Converts a string to `PascalCase`.\n */\nexport function pascalCase(str: string): string {\n const words = splitWords(str);\n return words.map((w) => capitalize(w.toLowerCase())).join('');\n}\n","/**\n * @framesquared/core – Array utilities\n */\n\n// ---------------------------------------------------------------------------\n// from\n// ---------------------------------------------------------------------------\n\n/**\n * Normalizes a value to an array.\n *\n * - If already an array, returns it as-is (same reference).\n * - If an iterable (but not a string), spreads it into a new array.\n * - Otherwise wraps it in a single-element array.\n *\n * Strings are intentionally *not* spread into characters — `from(\"hi\")`\n * returns `[\"hi\"]`, not `[\"h\",\"i\"]`.\n */\nexport function from<T>(value: T | T[] | Iterable<T>): T[] {\n if (Array.isArray(value)) return value as T[];\n // Exclude strings: they are iterable but we want to wrap, not spread.\n if (\n typeof value !== 'string' &&\n value != null &&\n typeof (value as Iterable<T>)[Symbol.iterator] === 'function'\n ) {\n return [...(value as Iterable<T>)];\n }\n return [value as T];\n}\n\n// ---------------------------------------------------------------------------\n// contains / include / remove\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` if `array` contains `item`, using `Array.prototype.includes`\n * (which handles `NaN`).\n */\nexport function contains<T>(array: T[], item: T): boolean {\n return array.includes(item);\n}\n\n/**\n * Adds `item` to `array` if it is not already present. Mutates and returns\n * the same array reference.\n */\nexport function include<T>(array: T[], item: T): T[] {\n if (!array.includes(item)) {\n array.push(item);\n }\n return array;\n}\n\n/**\n * Removes the **first** occurrence of `item` from `array`. Mutates and\n * returns the same array reference.\n */\nexport function remove<T>(array: T[], item: T): T[] {\n const idx = array.indexOf(item);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n}\n\n// ---------------------------------------------------------------------------\n// clean / unique\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a **new** array with all `null` and `undefined` entries removed.\n */\nexport function clean<T>(array: (T | null | undefined)[]): T[] {\n return array.filter((v): v is T => v !== null && v !== undefined);\n}\n\n/**\n * Returns a **new** array with duplicate values removed, preserving the order\n * of first occurrence. Uses a `Set` (strict/reference equality).\n */\nexport function unique<T>(array: T[]): T[] {\n return [...new Set(array)];\n}\n\n// ---------------------------------------------------------------------------\n// flatten\n// ---------------------------------------------------------------------------\n\n/**\n * Flattens one level deep: `[1, [2, 3], 4]` → `[1, 2, 3, 4]`.\n * Does **not** recurse into deeper nesting.\n */\nexport function flatten<T>(array: (T | T[])[]): T[] {\n const result: T[] = [];\n for (const item of array) {\n if (Array.isArray(item)) {\n result.push(...(item as T[]));\n } else {\n result.push(item as T);\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// pluck\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the value of `key` from every element.\n */\nexport function pluck<T, K extends keyof T>(array: T[], key: K): T[K][] {\n return array.map((item) => item[key]);\n}\n\n// ---------------------------------------------------------------------------\n// Numeric aggregates\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the sum of all elements. Returns `0` for an empty array.\n */\nexport function sum(array: number[]): number {\n let total = 0;\n for (const n of array) total += n;\n return total;\n}\n\n/**\n * Returns the arithmetic mean. Returns `NaN` for an empty array.\n */\nexport function mean(array: number[]): number {\n if (array.length === 0) return NaN;\n return sum(array) / array.length;\n}\n\n// ---------------------------------------------------------------------------\n// min / max\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the minimum element. When no `compareFn` is given, uses `<`.\n * Throws if the array is empty.\n */\nexport function min<T>(array: T[], compareFn?: (a: T, b: T) => number): T {\n if (array.length === 0) throw new Error('min() requires a non-empty array');\n const cmp = compareFn ?? defaultCompare;\n let result = array[0];\n for (let i = 1; i < array.length; i++) {\n if (cmp(array[i], result) < 0) result = array[i];\n }\n return result;\n}\n\n/**\n * Returns the maximum element. When no `compareFn` is given, uses `<`.\n * Throws if the array is empty.\n */\nexport function max<T>(array: T[], compareFn?: (a: T, b: T) => number): T {\n if (array.length === 0) throw new Error('max() requires a non-empty array');\n const cmp = compareFn ?? defaultCompare;\n let result = array[0];\n for (let i = 1; i < array.length; i++) {\n if (cmp(array[i], result) > 0) result = array[i];\n }\n return result;\n}\n\nfunction defaultCompare<T>(a: T, b: T): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n\n// ---------------------------------------------------------------------------\n// groupBy / partition\n// ---------------------------------------------------------------------------\n\n/**\n * Groups elements by the string/number key returned by `fn`.\n */\nexport function groupBy<T, K extends string | number>(\n array: T[],\n fn: (item: T) => K,\n): Record<K, T[]> {\n const result = {} as Record<K, T[]>;\n for (const item of array) {\n const key = fn(item);\n if (result[key] === undefined) {\n result[key] = [];\n }\n result[key].push(item);\n }\n return result;\n}\n\n/**\n * Splits an array into two: elements that satisfy the predicate and those\n * that don't.\n */\nexport function partition<T>(\n array: T[],\n predicate: (item: T) => boolean,\n): [T[], T[]] {\n const yes: T[] = [];\n const no: T[] = [];\n for (const item of array) {\n (predicate(item) ? yes : no).push(item);\n }\n return [yes, no];\n}\n\n// ---------------------------------------------------------------------------\n// chunk\n// ---------------------------------------------------------------------------\n\n/**\n * Splits `array` into chunks of at most `size` elements.\n * Throws if `size` is ≤ 0.\n */\nexport function chunk<T>(array: T[], size: number): T[][] {\n if (size <= 0) throw new Error('chunk() requires a positive size');\n const result: T[][] = [];\n for (let i = 0; i < array.length; i += size) {\n result.push(array.slice(i, i + size));\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Set operations\n// ---------------------------------------------------------------------------\n\n/**\n * Returns elements in `array1` that are **not** in `array2`.\n */\nexport function difference<T>(array1: T[], array2: T[]): T[] {\n const set = new Set(array2);\n return array1.filter((item) => !set.has(item));\n}\n\n/**\n * Returns elements that appear in **both** `array1` and `array2`, preserving\n * order from `array1`. Each value appears at most once in the result.\n */\nexport function intersection<T>(array1: T[], array2: T[]): T[] {\n const set = new Set(array2);\n return unique(array1.filter((item) => set.has(item)));\n}\n\n// ---------------------------------------------------------------------------\n// sortBy\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a **new** sorted array. `key` may be a property name or an\n * accessor function. Default direction is `'ASC'`.\n */\nexport function sortBy<T>(\n array: T[],\n key: keyof T | ((item: T) => unknown),\n direction: 'ASC' | 'DESC' = 'ASC',\n): T[] {\n const accessor: (item: T) => unknown =\n typeof key === 'function' ? key : (item: T) => item[key as keyof T];\n const dir = direction === 'DESC' ? -1 : 1;\n return [...array].sort((a, b) => {\n const va = accessor(a) as string | number;\n const vb = accessor(b) as string | number;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n return 0;\n });\n}\n\n// ---------------------------------------------------------------------------\n// findBy\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the first element for which `fn` returns `true`, or `undefined`.\n */\nexport function findBy<T>(array: T[], fn: (item: T) => boolean): T | undefined {\n return array.find(fn);\n}\n\n// ---------------------------------------------------------------------------\n// range\n// ---------------------------------------------------------------------------\n\n/**\n * Generates a half-open range `[start, end)` with the given `step`\n * (default `1`). A negative step produces a descending range.\n * Throws if `step` is `0`.\n */\nexport function range(start: number, end: number, step = 1): number[] {\n if (step === 0) throw new Error('range() step must not be zero');\n\n const result: number[] = [];\n if (step > 0) {\n for (let i = start; i < end; i += step) result.push(i);\n } else {\n for (let i = start; i > end; i += step) result.push(i);\n }\n return result;\n}\n","/**\n * @framesquared/core – Object utilities\n */\n\n// ---------------------------------------------------------------------------\n// keys / values / entries / fromEntries\n// ---------------------------------------------------------------------------\n\n/**\n * Typed wrapper around `Object.keys`.\n */\nexport function keys<T extends object>(obj: T): (keyof T)[] {\n return Object.keys(obj) as (keyof T)[];\n}\n\n/**\n * Typed wrapper around `Object.values`.\n */\nexport function values<T extends object>(obj: T): T[keyof T][] {\n return Object.values(obj) as T[keyof T][];\n}\n\n/**\n * Typed wrapper around `Object.entries`.\n */\nexport function entries<T extends object>(obj: T): [keyof T, T[keyof T]][] {\n return Object.entries(obj) as [keyof T, T[keyof T]][];\n}\n\n/**\n * Typed wrapper around `Object.fromEntries`.\n */\nexport function fromEntries<K extends string, V>(\n items: [K, V][],\n): Record<K, V> {\n return Object.fromEntries(items) as Record<K, V>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers (not exported)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` for plain objects (those whose prototype is\n * `Object.prototype` or `null`). Arrays, Dates, RegExps etc. → `false`.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// merge (deep)\n// ---------------------------------------------------------------------------\n\n/**\n * Deep-merges own enumerable properties from every `source` into `target`.\n *\n * - Plain objects are recursively merged.\n * - Arrays and non-plain objects are **overwritten** (not merged element-wise).\n * - Mutates and returns `target`.\n */\nexport function merge<T extends object>(\n target: T,\n ...sources: Partial<T>[]\n): T {\n for (const source of sources) {\n for (const key of Object.keys(source) as (keyof T)[]) {\n const srcVal = source[key];\n const tgtVal = (target as Record<keyof T, unknown>)[key];\n\n if (isPlainObject(srcVal) && isPlainObject(tgtVal)) {\n merge(tgtVal as Record<string, unknown>, srcVal as Record<string, unknown>);\n } else {\n (target as Record<keyof T, unknown>)[key] = srcVal;\n }\n }\n }\n return target;\n}\n\n// ---------------------------------------------------------------------------\n// pick / omit\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a new object containing only the specified `pickedKeys`.\n */\nexport function pick<T extends object, K extends keyof T>(\n obj: T,\n pickedKeys: K[],\n): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of pickedKeys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/**\n * Returns a new object with the specified `omittedKeys` removed.\n */\nexport function omit<T extends object, K extends keyof T>(\n obj: T,\n omittedKeys: K[],\n): Omit<T, K> {\n const excluded = new Set<PropertyKey>(omittedKeys);\n const result = {} as Record<PropertyKey, unknown>;\n for (const key of Object.keys(obj)) {\n if (!excluded.has(key)) {\n result[key] = (obj as Record<string, unknown>)[key];\n }\n }\n return result as Omit<T, K>;\n}\n\n// ---------------------------------------------------------------------------\n// mapValues / mapKeys\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a new object with every value transformed by `fn`.\n */\nexport function mapValues<T extends object, U>(\n obj: T,\n fn: (value: T[keyof T], key: keyof T) => U,\n): Record<keyof T, U> {\n const result = {} as Record<keyof T, U>;\n for (const key of Object.keys(obj) as (keyof T)[]) {\n result[key] = fn(obj[key] as T[keyof T], key);\n }\n return result;\n}\n\n/**\n * Returns a new object with every key transformed by `fn`.\n */\nexport function mapKeys<T extends object>(\n obj: T,\n fn: (key: keyof T) => string,\n): Record<string, T[keyof T]> {\n const result = {} as Record<string, T[keyof T]>;\n for (const key of Object.keys(obj) as (keyof T)[]) {\n result[fn(key)] = obj[key] as T[keyof T];\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// freeze (deep)\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively freezes `obj` and all nested objects / arrays.\n * Returns the same reference.\n */\nexport function freeze<T extends object>(obj: T): Readonly<T> {\n Object.freeze(obj);\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {\n freeze(value as object);\n }\n }\n return obj;\n}\n\n// ---------------------------------------------------------------------------\n// equals (deep structural equality)\n// ---------------------------------------------------------------------------\n\n/**\n * Deep structural equality comparison. Handles primitives, plain objects,\n * arrays, `Date`, `RegExp`, and `NaN`.\n */\nexport function equals(a: unknown, b: unknown): boolean {\n // Same reference (also covers identical primitives)\n if (a === b) return true;\n\n // NaN check\n if (typeof a === 'number' && typeof b === 'number') {\n return Number.isNaN(a) && Number.isNaN(b);\n }\n\n // null / undefined / type mismatch\n if (a === null || b === null || a === undefined || b === undefined) {\n return false;\n }\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object') return false; // primitives already compared above\n\n // Date\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n // RegExp\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.source === b.source && a.flags === b.flags;\n }\n\n // Array vs non-array\n const aIsArr = Array.isArray(a);\n const bIsArr = Array.isArray(b);\n if (aIsArr !== bIsArr) return false;\n\n if (aIsArr && bIsArr) {\n const arrA = a as unknown[];\n const arrB = b as unknown[];\n if (arrA.length !== arrB.length) return false;\n for (let i = 0; i < arrA.length; i++) {\n if (!equals(arrA[i], arrB[i])) return false;\n }\n return true;\n }\n\n // Plain objects\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(objB, key)) return false;\n if (!equals(objA[key], objB[key])) return false;\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// getNestedValue / setNestedValue\n// ---------------------------------------------------------------------------\n\n/**\n * Traverses `obj` along the dot-separated `path` and returns the value found.\n * Returns `defaultValue` when the path does not exist (i.e. an intermediate\n * segment is missing). If the final property exists but its value is\n * `undefined`, `undefined` is returned (not `defaultValue`).\n */\nexport function getNestedValue(\n obj: object,\n path: string,\n defaultValue?: unknown,\n): unknown {\n const segments = path.split('.');\n let current: unknown = obj;\n\n for (let i = 0; i < segments.length; i++) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return defaultValue;\n }\n const rec = current as Record<string, unknown>;\n const seg = segments[i];\n\n // Last segment: check existence\n if (i === segments.length - 1) {\n return seg in rec ? rec[seg] : defaultValue;\n }\n\n current = rec[seg];\n }\n\n /* istanbul ignore next – unreachable with non-empty path */\n return current;\n}\n\n/**\n * Sets a value at a dot-separated `path`, creating intermediate objects as\n * needed.\n */\nexport function setNestedValue(\n obj: object,\n path: string,\n value: unknown,\n): void {\n const segments = path.split('.');\n let current: Record<string, unknown> = obj as Record<string, unknown>;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (\n current[seg] === undefined ||\n current[seg] === null ||\n typeof current[seg] !== 'object'\n ) {\n current[seg] = {};\n }\n current = current[seg] as Record<string, unknown>;\n }\n\n current[segments[segments.length - 1]] = value;\n}\n\n// ---------------------------------------------------------------------------\n// flattenObject / unflattenObject\n// ---------------------------------------------------------------------------\n\n/**\n * Flattens a nested object into a single-level object with dot-separated keys.\n *\n * Arrays and non-plain objects are treated as leaf values (not recursed into).\n */\nexport function flattenObject(\n obj: object,\n prefix?: string,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (isPlainObject(value)) {\n Object.assign(result, flattenObject(value as Record<string, unknown>, fullKey));\n } else {\n result[fullKey] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Reverse of {@link flattenObject}: expands dot-separated keys into a nested\n * object.\n */\nexport function unflattenObject(\n obj: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [path, value] of Object.entries(obj)) {\n setNestedValue(result, path, value);\n }\n\n return result;\n}\n","/**\n * @framesquared/core – Function utilities\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// bind\n// ---------------------------------------------------------------------------\n\n/**\n * Binds `fn` to `scope` with optional pre-filled arguments.\n */\nexport function bind<T extends Function>(\n fn: T,\n scope: unknown,\n ...args: unknown[]\n): T {\n return ((...callArgs: unknown[]) =>\n fn.apply(scope, [...args, ...callArgs])) as unknown as T;\n}\n\n// ---------------------------------------------------------------------------\n// createBuffered (debounce)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that delays invoking `fn` until `buffer` milliseconds\n * have elapsed since the **last** call. Each new call resets the timer\n * (classic debounce).\n */\nexport function createBuffered(\n fn: Function,\n buffer: number,\n scope?: unknown,\n): (...args: unknown[]) => void {\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n return function (this: unknown, ...args: unknown[]) {\n if (timerId !== undefined) clearTimeout(timerId);\n const ctx = scope ?? this;\n timerId = setTimeout(() => {\n fn.apply(ctx, args);\n timerId = undefined;\n }, buffer);\n };\n}\n\n// ---------------------------------------------------------------------------\n// createDelayed\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that always delays invoking `fn` by `delay` ms.\n * Each call schedules its **own** independent timer (unlike debounce).\n */\nexport function createDelayed(\n fn: Function,\n delay: number,\n scope?: unknown,\n): (...args: unknown[]) => void {\n return function (this: unknown, ...args: unknown[]) {\n const ctx = scope ?? this;\n setTimeout(() => fn.apply(ctx, args), delay);\n };\n}\n\n// ---------------------------------------------------------------------------\n// createThrottled\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that invokes `fn` at most once per `intervalMs`\n * milliseconds. The first call executes immediately.\n */\nexport function createThrottled(\n fn: Function,\n intervalMs: number,\n scope?: unknown,\n): (...args: unknown[]) => void {\n let lastCall = 0;\n\n return function (this: unknown, ...args: unknown[]) {\n const ctx = scope ?? this;\n const elapsed = Date.now() - lastCall;\n if (elapsed >= intervalMs) {\n lastCall = Date.now();\n fn.apply(ctx, args);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// createBarrier\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that only invokes `fn` once the returned function has\n * been called exactly `count` times. Subsequent calls are no-ops.\n */\nexport function createBarrier(\n count: number,\n fn: Function,\n scope?: unknown,\n): (...args: unknown[]) => void {\n let remaining = count;\n let fired = false;\n\n return function (this: unknown, ...args: unknown[]) {\n if (fired) return;\n remaining--;\n if (remaining <= 0) {\n fired = true;\n const ctx = scope ?? this;\n fn.apply(ctx, args);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// interceptBefore / interceptAfter\n// ---------------------------------------------------------------------------\n\n/**\n * Replaces `obj[methodName]` with a wrapper that calls `fn` **before** the\n * original method. `fn` receives the same arguments as the original.\n */\nexport function interceptBefore(\n obj: object,\n methodName: string,\n fn: Function,\n): void {\n const rec = obj as Record<string, Function>;\n const original = rec[methodName];\n\n rec[methodName] = function (this: unknown, ...args: unknown[]) {\n fn.apply(this, args);\n return original.apply(this, args);\n };\n}\n\n/**\n * Replaces `obj[methodName]` with a wrapper that calls `fn` **after** the\n * original method. `fn` receives the original method's return value as its\n * single argument. The wrapper still returns the original return value.\n */\nexport function interceptAfter(\n obj: object,\n methodName: string,\n fn: Function,\n): void {\n const rec = obj as Record<string, Function>;\n const original = rec[methodName];\n\n rec[methodName] = function (this: unknown, ...args: unknown[]) {\n const result = original.apply(this, args);\n fn.call(this, result);\n return result;\n };\n}\n\n// ---------------------------------------------------------------------------\n// createSequence\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that calls every function in `fns` in order, passing\n * all received arguments to each.\n */\nexport function createSequence(\n ...fns: Function[]\n): (...args: unknown[]) => void {\n return (...args: unknown[]) => {\n for (const fn of fns) {\n fn(...args);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// memoize\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a memoized version of `fn`. By default the first argument\n * (stringified) is used as the cache key. Supply a `hasher` for\n * multi-argument or non-primitive keys.\n */\nexport function memoize<T extends (...args: any[]) => any>(\n fn: T,\n hasher?: (...args: Parameters<T>) => string,\n): T {\n const cache = new Map<string, ReturnType<T>>();\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n const key = hasher ? hasher(...args) : String(args[0]);\n if (cache.has(key)) return cache.get(key) as ReturnType<T>;\n const result = fn(...args) as ReturnType<T>;\n cache.set(key, result);\n return result;\n }) as T;\n}\n\n// ---------------------------------------------------------------------------\n// once\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that invokes `fn` at most once. Subsequent calls\n * return the result of the first invocation.\n */\nexport function once<T extends (...args: any[]) => any>(fn: T): T {\n let called = false;\n let result: ReturnType<T>;\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n if (!called) {\n called = true;\n result = fn(...args) as ReturnType<T>;\n }\n return result;\n }) as T;\n}\n\n// ---------------------------------------------------------------------------\n// negate\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a function that negates the boolean return value of `fn`.\n */\nexport function negate<T extends (...args: any[]) => boolean>(fn: T): T {\n return ((...args: Parameters<T>): boolean => !fn(...args)) as unknown as T;\n}\n\n// ---------------------------------------------------------------------------\n// compose / pipe\n// ---------------------------------------------------------------------------\n\n/**\n * Right-to-left function composition.\n * `compose(f, g, h)(x)` is equivalent to `f(g(h(x)))`.\n */\nexport function compose(\n ...fns: Function[]\n): (...args: unknown[]) => unknown {\n return (...args: unknown[]) => {\n let result: unknown = fns[fns.length - 1](...args);\n for (let i = fns.length - 2; i >= 0; i--) {\n result = fns[i](result);\n }\n return result;\n };\n}\n\n/**\n * Left-to-right function composition (aka pipeline).\n * `pipe(f, g, h)(x)` is equivalent to `h(g(f(x)))`.\n */\nexport function pipe(\n ...fns: Function[]\n): (...args: unknown[]) => unknown {\n return (...args: unknown[]) => {\n let result: unknown = fns[0](...args);\n for (let i = 1; i < fns.length; i++) {\n result = fns[i](result);\n }\n return result;\n };\n}\n","/**\n * @framesquared/core – Base class\n *\n * Foundation for the framesquared class system. Provides:\n * - Config auto-generation (getX / setX / applyX / updateX lifecycle)\n * - callParent() for wrapped methods (set up by define())\n * - destroy() + Symbol.dispose\n * - Mixin tracking via hasMixin()\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport { capitalize } from '../util/String.js';\n\n// ---------------------------------------------------------------------------\n// Internal symbols & types\n// ---------------------------------------------------------------------------\n\n/** Tracks whether config accessors have been generated on this class. */\nconst CONFIGS_PROCESSED = Symbol('configsProcessed');\n\n/** Per-instance call-stack entries for callParent(). */\nexport interface CallStackEntry {\n methodName: string;\n owner: typeof Base;\n}\n\n// ---------------------------------------------------------------------------\n// Config processing utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Collects the merged `$configDefs` from the full prototype chain and\n * generates `getFoo` / `setFoo` accessor pairs on the prototype for every\n * config key that doesn't already have them.\n *\n * This is called once per class, lazily on first instantiation **or**\n * eagerly by `define()`.\n */\nexport function processClassConfigs(Ctor: typeof Base): void {\n // Must use hasOwn — otherwise the child inherits the parent's flag via\n // the static prototype chain (ChildCtor.__proto__ === ParentCtor).\n if (Object.hasOwn(Ctor, CONFIGS_PROCESSED)) return;\n\n // Merge config definitions from the ancestor chain (parent first, child overrides).\n const chain: (typeof Base)[] = [];\n let cur: typeof Base | null = Ctor;\n while (cur && cur !== Function.prototype) {\n chain.unshift(cur);\n cur = Object.getPrototypeOf(cur) as typeof Base | null;\n }\n\n const merged: Record<string, unknown> = {};\n for (const cls of chain) {\n if (cls.hasOwnProperty('$configDefs')) {\n Object.assign(merged, cls.$configDefs);\n }\n }\n\n // Store the final merged defs on *this* class so instances can read them.\n Ctor.$configDefs = merged;\n\n // Generate accessor pairs.\n for (const configName of Object.keys(merged)) {\n generateAccessors(Ctor.prototype, configName);\n }\n\n (Ctor as any)[CONFIGS_PROCESSED] = true;\n}\n\n/**\n * Generates `getFoo` and `setFoo` methods on `proto` for the given config\n * name, unless they already exist (allowing user-defined overrides).\n */\nfunction generateAccessors(proto: object, configName: string): void {\n const cap = capitalize(configName);\n const getterName = `get${cap}`;\n const setterName = `set${cap}`;\n const privateProp = `_${configName}`;\n const applyName = `apply${cap}`;\n const updateName = `update${cap}`;\n\n if (!(getterName in proto)) {\n (proto as any)[getterName] = function (this: any) {\n // Lazy init: if never explicitly set, apply the default.\n if (!this.$configInitialized.has(configName)) {\n const defaults = (this.constructor as typeof Base).$configDefs;\n if (defaults && configName in defaults) {\n this[setterName](defaults[configName]);\n }\n }\n return this[privateProp];\n };\n }\n\n if (!(setterName in proto)) {\n (proto as any)[setterName] = function (this: any, value: unknown) {\n const oldValue = this[privateProp];\n\n // Apply transform\n if (typeof this[applyName] === 'function') {\n value = this[applyName](value, oldValue);\n }\n\n this[privateProp] = value;\n this.$configInitialized.add(configName);\n\n // Update hook (only if the value actually changed)\n if (typeof this[updateName] === 'function' && value !== oldValue) {\n this[updateName](value, oldValue);\n }\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Method wrapping for callParent\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps a method so it pushes / pops from the instance's `$callStack`,\n * enabling `callParent()` to locate the correct super-method.\n */\nexport function wrapMethod(\n fn: Function,\n methodName: string,\n ownerClass: typeof Base,\n): Function {\n const wrapped = function (this: Base, ...args: unknown[]) {\n this.$callStack.push({ methodName, owner: ownerClass });\n try {\n return fn.apply(this, args);\n } finally {\n this.$callStack.pop();\n }\n };\n // Mark so we don't double-wrap.\n (wrapped as any).$wrapped = true;\n (wrapped as any).$original = fn;\n (wrapped as any).$owner = ownerClass;\n return wrapped;\n}\n\n// ---------------------------------------------------------------------------\n// Base class\n// ---------------------------------------------------------------------------\n\nexport class Base {\n // -- Class-level metadata ------------------------------------------------\n\n /** Fully-qualified class name. */\n static $className = 'Base';\n\n /** Merged config defaults for this class (populated by processClassConfigs). */\n static $configDefs: Record<string, unknown>;\n\n /** Set of mixin constructors applied to this class (populated by define). */\n static $mixins: Set<typeof Base>;\n\n // -- Instance state ------------------------------------------------------\n\n /** Per-instance call-stack used by `callParent()`. */\n $callStack: CallStackEntry[] = [];\n\n /** Tracks which config properties have been explicitly initialized. */\n $configInitialized: Set<string> = new Set();\n\n /**\n * Raw config object passed to the constructor. Decorator-based configs\n * are consumed from here by `addInitializer` callbacks (which run after\n * auto-accessor field initialization).\n */\n $pendingConfig: Record<string, unknown> | undefined;\n\n /** Whether `destroy()` has been called. */\n isDestroyed = false;\n\n /**\n * Array of cleanup callbacks. Mixins (and user code) can push\n * functions here; they all run during `destroy()`.\n */\n $destroyHooks: (() => void)[] = [];\n\n // -- Getters -------------------------------------------------------------\n\n /** The fully-qualified class name of this instance's constructor. */\n get $className(): string {\n return (this.constructor as typeof Base).$className;\n }\n\n /** Reference to the constructor (like ExtJS's `this.self`). */\n get self(): typeof Base {\n return this.constructor as typeof Base;\n }\n\n // -- Constructor ---------------------------------------------------------\n\n constructor(config?: Record<string, unknown>) {\n // Store for decorator-based configs (consumed by addInitializer).\n this.$pendingConfig = config ? { ...config } : undefined;\n\n if (config) {\n this.initConfig(config);\n }\n }\n\n // -- Factory -------------------------------------------------------------\n\n /**\n * Static factory — creates an instance of the class.\n */\n static create(this: new (...a: any[]) => Base, ...args: any[]): Base {\n return new this(...args);\n }\n\n // -- Config initialisation -----------------------------------------------\n\n /**\n * Applies the given config properties to this instance. Ensures that\n * config accessors have been generated for the class first.\n */\n initConfig(config?: Record<string, unknown>): void {\n const Ctor = this.constructor as typeof Base;\n\n // Ensure define()-style accessors exist (once per class).\n processClassConfigs(Ctor);\n\n if (!config) return;\n\n // Only apply configs that have define()-style $configDefs entries.\n // Decorator-based configs (@config accessor) are handled by the\n // decorator's addInitializer callback which runs after auto-accessor\n // field initialization.\n const defs = Ctor.$configDefs;\n\n for (const key of Object.keys(config)) {\n if (defs && key in defs) {\n const setter = `set${capitalize(key)}`;\n if (typeof (this as any)[setter] === 'function') {\n (this as any)[setter](config[key]);\n }\n }\n // Keys not in $configDefs stay in $pendingConfig for decorator processing\n }\n }\n\n // -- callParent ----------------------------------------------------------\n\n /**\n * Calls the parent (super) class's implementation of the method that is\n * currently executing. Only works for methods wrapped via `define()`.\n */\n callParent(args?: unknown[]): unknown {\n const stack = this.$callStack;\n if (stack.length === 0) {\n return undefined;\n }\n\n const current = stack[stack.length - 1];\n const parentProto = Object.getPrototypeOf(current.owner.prototype);\n\n if (parentProto && typeof parentProto[current.methodName] === 'function') {\n return parentProto[current.methodName].apply(this, args ?? []);\n }\n\n return undefined;\n }\n\n // -- Mixin query ---------------------------------------------------------\n\n /**\n * Returns `true` if the given mixin has been applied to this class (or\n * to any of its ancestors / other mixins).\n */\n hasMixin(mixin: typeof Base): boolean {\n const Ctor = this.constructor as typeof Base;\n return Ctor.$mixins?.has(mixin) ?? false;\n }\n\n // -- Destroy lifecycle ---------------------------------------------------\n\n /**\n * Tears down this instance. Calls `onDestroy()` if defined.\n * Idempotent — second and subsequent calls are no-ops.\n */\n destroy(): void {\n if (this.isDestroyed) return;\n this.isDestroyed = true;\n\n // Run all registered destroy hooks (from mixins, plugins, etc.)\n for (const hook of this.$destroyHooks) {\n hook.call(this);\n }\n\n if (typeof (this as any).onDestroy === 'function') {\n (this as any).onDestroy();\n }\n }\n\n /**\n * `Symbol.dispose` support — calling `[Symbol.dispose]()` is equivalent\n * to `destroy()`, enabling the TC39 `using` keyword.\n */\n [Symbol.dispose](): void {\n this.destroy();\n }\n}\n","/**\n * @framesquared/core – ClassManager + define()\n *\n * Central registry for framesquared classes and the `define()` factory that\n * creates, configures, and registers new classes in a single call.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport { Base, processClassConfigs, wrapMethod } from './Base.js';\n\n// ---------------------------------------------------------------------------\n// ClassDefinition type\n// ---------------------------------------------------------------------------\n\nexport interface ClassDefinition {\n /** Parent class (defaults to Base). */\n extend?: typeof Base;\n /** Mixins to apply. */\n mixins?: (typeof Base)[];\n /** One or more alias strings for ClassManager lookup. */\n alias?: string | string[];\n /** Config property defaults (auto-generates getX / setX). */\n config?: Record<string, unknown>;\n /** Static members to copy onto the constructor. */\n statics?: Record<string, unknown>;\n /** Any other properties are treated as prototype methods / members. */\n [key: string]: unknown;\n}\n\n// Reserved keys that are NOT copied to the prototype as methods.\nconst RESERVED_DEF_KEYS = new Set([\n 'extend',\n 'mixins',\n 'alias',\n 'config',\n 'statics',\n]);\n\n// ---------------------------------------------------------------------------\n// ClassManager singleton\n// ---------------------------------------------------------------------------\n\nclass ClassManagerImpl {\n /** className → constructor */\n private classes = new Map<string, typeof Base>();\n\n /** alias → constructor */\n private aliases = new Map<string, typeof Base>();\n\n // -- Registration -------------------------------------------------------\n\n register(name: string, cls: typeof Base): void {\n this.classes.set(name, cls);\n }\n\n // -- Lookup -------------------------------------------------------------\n\n get(name: string): typeof Base | undefined {\n return this.classes.get(name);\n }\n\n getByAlias(alias: string): typeof Base | undefined {\n return this.aliases.get(alias);\n }\n\n isRegistered(name: string): boolean {\n return this.classes.has(name);\n }\n\n /**\n * Returns all registered class names that start with `prefix`.\n */\n getNamesByPrefix(prefix: string): string[] {\n const result: string[] = [];\n for (const name of this.classes.keys()) {\n if (name.startsWith(prefix)) result.push(name);\n }\n return result;\n }\n\n // -- Instantiation ------------------------------------------------------\n\n /**\n * Creates an instance by alias, passing remaining args to the constructor.\n */\n instantiateByAlias(alias: string, ...args: any[]): Base {\n const Cls = this.aliases.get(alias);\n if (!Cls) {\n throw new Error(`ClassManager: no class registered for alias \"${alias}\"`);\n }\n return new (Cls as any)(...args) as Base;\n }\n\n // -- Alias management (used by define) ----------------------------------\n\n registerAlias(alias: string, cls: typeof Base): void {\n this.aliases.set(alias, cls);\n }\n}\n\n/** Singleton instance. */\nexport const ClassManager = new ClassManagerImpl();\n\n// ---------------------------------------------------------------------------\n// Mixin application\n// ---------------------------------------------------------------------------\n\nfunction applyMixins(\n targetClass: typeof Base,\n mixins: (typeof Base)[],\n): void {\n if (!targetClass.$mixins) {\n targetClass.$mixins = new Set();\n }\n\n for (const mixin of mixins) {\n // Guard against diamond: skip if already applied.\n if (targetClass.$mixins.has(mixin)) continue;\n\n targetClass.$mixins.add(mixin);\n\n // Also pull in the mixin's own mixins (transitive).\n if (mixin.$mixins) {\n for (const transitive of mixin.$mixins) {\n targetClass.$mixins.add(transitive);\n }\n }\n\n // Copy prototype members (methods, getters, etc.) — don't overwrite.\n for (const name of Object.getOwnPropertyNames(mixin.prototype)) {\n if (name === 'constructor') continue;\n // Don't overwrite existing members on the target.\n if (name in targetClass.prototype) continue;\n\n const desc = Object.getOwnPropertyDescriptor(mixin.prototype, name);\n if (desc) {\n Object.defineProperty(targetClass.prototype, name, desc);\n }\n }\n\n // Merge mixin config defs (mixin defaults lose to target defaults).\n if (mixin.$configDefs) {\n targetClass.$configDefs = {\n ...mixin.$configDefs,\n ...(targetClass.$configDefs || {}),\n };\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// define()\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new class, applies mixins, sets up config accessors, wraps\n * methods for `callParent()`, registers with {@link ClassManager}, and\n * returns the ready-to-use constructor.\n *\n * ```ts\n * const Button = define('ui.Button', {\n * extend: Component,\n * mixins: [Focusable],\n * alias: 'widget.button',\n * config: { text: '', disabled: false },\n * onClick() { ... },\n * });\n * ```\n */\nexport function define(\n className: string,\n definition: ClassDefinition,\n): typeof Base {\n const SuperClass = definition.extend || Base;\n\n // 1. Create the subclass dynamically.\n const NewClass = class extends SuperClass {\n constructor(...args: any[]) {\n super(...args);\n }\n } as unknown as typeof Base & { new (...args: any[]): any };\n\n // Set class identity.\n NewClass.$className = className;\n\n // 2. Own config definitions.\n if (definition.config) {\n // Start from parent's defs (if any), overlay own.\n NewClass.$configDefs = {\n ...(SuperClass.$configDefs || {}),\n ...definition.config,\n };\n } else {\n // Still inherit parent defs.\n if (SuperClass.$configDefs) {\n NewClass.$configDefs = { ...SuperClass.$configDefs };\n }\n }\n\n // 3. Copy prototype members from the definition (methods, apply/update hooks, etc.).\n for (const key of Object.keys(definition)) {\n if (RESERVED_DEF_KEYS.has(key)) continue;\n\n const value = definition[key];\n if (typeof value === 'function') {\n // Wrap for callParent support.\n (NewClass.prototype as any)[key] = wrapMethod(value as Function, key, NewClass);\n } else {\n (NewClass.prototype as any)[key] = value;\n }\n }\n\n // 4. Mixins.\n if (definition.mixins && definition.mixins.length > 0) {\n applyMixins(NewClass, definition.mixins);\n }\n\n // Initialise mixin set if not already present.\n if (!NewClass.$mixins) {\n NewClass.$mixins = new Set();\n }\n\n // 5. Process configs (generate get/set accessors).\n processClassConfigs(NewClass);\n\n // 6. Static members.\n if (definition.statics) {\n for (const [k, v] of Object.entries(definition.statics)) {\n (NewClass as any)[k] = v;\n }\n }\n\n // 7. Register with ClassManager.\n ClassManager.register(className, NewClass);\n\n // 8. Aliases.\n if (definition.alias) {\n const aliases = Array.isArray(definition.alias)\n ? definition.alias\n : [definition.alias];\n for (const a of aliases) {\n ClassManager.registerAlias(a, NewClass);\n }\n }\n\n return NewClass;\n}\n","/**\n * @framesquared/core – Configurator\n *\n * Central metadata registry for the `@config` decorator family.\n * Uses TC39 `context.metadata` (Symbol.metadata) so metadata is\n * available immediately after class definition — no instance needed.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ConfigMeta {\n /** Property name. */\n name: string;\n /** True when the config MUST be provided at construction time. */\n required: boolean;\n /** Factory function for lazy configs (computed on first access). */\n lazyFactory?: (this: any) => unknown;\n /** True when the getter result should be cached until next set. */\n cached: boolean;\n /** True when object values should be deep-merged with defaults. */\n merge: boolean;\n /** True when a change event should fire (Phase 2 integration). */\n observable: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Metadata symbol\n// ---------------------------------------------------------------------------\n\n/**\n * Key inside `context.metadata` that holds the per-class config Map.\n */\nexport const CONFIG_META_KEY = Symbol('framesquared:configMeta');\n\n/**\n * Runtime Symbol.metadata (or its esbuild polyfill).\n */\nexport const METADATA_SYMBOL: unique symbol =\n (Symbol as any).metadata ?? Symbol.for('Symbol.metadata');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Gets or creates the per-class config map inside `context.metadata`.\n */\nexport function getOrCreateMetaMap(\n metadata: DecoratorMetadataObject,\n): Map<string, ConfigMeta> {\n let map = (metadata as any)[CONFIG_META_KEY] as Map<string, ConfigMeta> | undefined;\n if (!map) {\n map = new Map();\n (metadata as any)[CONFIG_META_KEY] = map;\n }\n return map;\n}\n\n/**\n * Reads the metadata object from a class constructor.\n */\nfunction getClassMetadata(Ctor: Function): object | undefined {\n return (Ctor as any)[METADATA_SYMBOL] as object | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// ConfiguratorImpl\n// ---------------------------------------------------------------------------\n\nclass ConfiguratorImpl {\n /**\n * Returns the ConfigMeta for a single config on the given class,\n * walking the prototype chain.\n */\n getConfigMeta(Ctor: Function, configName: string): ConfigMeta | undefined {\n let cur: Function | null = Ctor;\n while (cur) {\n const md = getClassMetadata(cur);\n if (md) {\n const map = (md as any)[CONFIG_META_KEY] as Map<string, ConfigMeta> | undefined;\n if (map?.has(configName)) return map.get(configName)!;\n }\n cur = Object.getPrototypeOf(cur) as Function | null;\n }\n return undefined;\n }\n\n /**\n * Collects all ConfigMeta entries for `Ctor`, including inherited.\n */\n getAllConfigMeta(Ctor: Function): ConfigMeta[] {\n const chain: Function[] = [];\n let cur: Function | null = Ctor;\n while (cur) {\n chain.unshift(cur);\n cur = Object.getPrototypeOf(cur) as Function | null;\n }\n const merged = new Map<string, ConfigMeta>();\n for (const cls of chain) {\n const md = getClassMetadata(cls);\n if (md) {\n const map = (md as any)[CONFIG_META_KEY] as Map<string, ConfigMeta> | undefined;\n if (map) {\n for (const [name, meta] of map) merged.set(name, meta);\n }\n }\n }\n return [...merged.values()];\n }\n}\n\n/** Singleton. */\nexport const Configurator = new ConfiguratorImpl();\n","/**\n * @framesquared/core – TC39 Stage 3 decorators\n *\n * Usage:\n * ```ts\n * @alias('widget.panel')\n * @mixin(Draggable)\n * class Panel extends Base {\n * @config accessor title: string = 'Untitled';\n * @config.required accessor id: string = '';\n * @config.lazy(fn) accessor data: object = {};\n * @config.cached accessor fullName: string = '';\n * @config.merge accessor style: object = {};\n * @observable @config accessor theme: string = 'light';\n * }\n * ```\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { capitalize } from '../util/String.js';\nimport type { Base } from './Base.js';\nimport { ClassManager } from './ClassManager.js';\nimport { getOrCreateMetaMap } from './Configurator.js';\nimport type { ConfigMeta } from './Configurator.js';\nimport { merge as deepMerge } from '../util/Object.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object' || Array.isArray(v)) return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n}\n\n/** Per-instance cache for @config.cached. */\nconst cachedValues = new WeakMap<object, Map<string, { valid: boolean; value: unknown }>>();\n\nfunction getCacheEntry(inst: object) {\n let m = cachedValues.get(inst);\n if (!m) { m = new Map(); cachedValues.set(inst, m); }\n return m;\n}\n\n/**\n * Generates `getX()` / `setX()` convenience methods on the prototype,\n * guarded so it only happens once per class per config.\n */\nfunction ensureAccessors(Ctor: Function, configName: string): void {\n const proto = Ctor.prototype;\n const cap = capitalize(configName);\n const getter = `get${cap}`;\n const setter = `set${cap}`;\n\n if (!(getter in proto)) {\n proto[getter] = function (this: any): unknown {\n return this[configName];\n };\n }\n if (!(setter in proto)) {\n proto[setter] = function (this: any, value: unknown): void {\n this[configName] = value;\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core decorator builder\n// ---------------------------------------------------------------------------\n\nfunction createConfigDecorator(metaOverrides: Partial<ConfigMeta> = {}) {\n return function <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ): ClassAccessorDecoratorResult<This, Value> {\n const name = String(context.name);\n const cap = capitalize(name);\n const applyName = `apply${cap}`;\n const updateName = `update${cap}`;\n\n // ── Register metadata at CLASS DEFINITION time via context.metadata ──\n const metaMap = getOrCreateMetaMap(\n context.metadata as DecoratorMetadataObject,\n );\n let meta = metaMap.get(name);\n if (!meta) {\n meta = {\n name,\n required: false,\n cached: false,\n merge: false,\n observable: false,\n };\n metaMap.set(name, meta);\n }\n Object.assign(meta, metaOverrides);\n\n // ── addInitializer: runs per-instance after super() + field init ──\n context.addInitializer(function (this: This) {\n const inst = this as any;\n const Ctor = inst.constructor as Function;\n\n // Generate getX / setX (once per class)\n ensureAccessors(Ctor, name);\n\n // Apply pending config that Base stored during super()\n if (inst.$pendingConfig && name in inst.$pendingConfig) {\n inst[name] = inst.$pendingConfig[name];\n delete inst.$pendingConfig[name];\n inst.$configInitialized?.add(name);\n }\n\n // Validate required\n if (meta!.required && !inst.$configInitialized?.has(name)) {\n throw new Error(\n `Config \"${name}\" is required for ${(Ctor as any).$className || Ctor.name}`,\n );\n }\n });\n\n // ── init: field initialiser, stores the default ──\n const initFn = function (this: This, initialValue: Value): Value {\n // If already set (shouldn't happen before init, but guard)\n if ((this as any).$configInitialized?.has(name)) {\n return target.get.call(this);\n }\n return initialValue;\n };\n\n // ── get: lazy / cached ──\n const getFn = function (this: This): Value {\n const inst = this as any;\n\n // Lazy factory: compute on first access if not explicitly set\n if (\n meta!.lazyFactory &&\n !inst.$configInitialized?.has(name)\n ) {\n const computed = meta!.lazyFactory.call(inst) as Value;\n target.set.call(this, computed);\n inst.$configInitialized?.add(name);\n return computed;\n }\n\n // Cached: return cached value if still valid\n if (meta!.cached) {\n const cacheMap = getCacheEntry(inst);\n const entry = cacheMap.get(name);\n if (entry?.valid) {\n return entry.value as Value;\n }\n const value = target.get.call(this);\n cacheMap.set(name, { valid: true, value });\n return value;\n }\n\n return target.get.call(this);\n };\n\n // ── set: apply → store → invalidate cache → update ──\n const setFn = function (this: This, value: Value): void {\n const inst = this as any;\n const oldValue = target.get.call(this);\n\n // Merge: deep-merge with current value for plain objects\n if (meta!.merge && isPlainObject(value) && isPlainObject(oldValue)) {\n value = deepMerge(\n {} as Record<string, unknown>,\n oldValue,\n value as Record<string, unknown>,\n ) as unknown as Value;\n }\n\n // Apply hook\n if (typeof inst[applyName] === 'function') {\n value = inst[applyName](value, oldValue);\n }\n\n target.set.call(this, value);\n\n // Invalidate cache\n if (meta!.cached) {\n const cacheMap = getCacheEntry(inst);\n cacheMap.set(name, { valid: false, value: undefined });\n }\n\n inst.$configInitialized?.add(name);\n\n // Update hook (only if value actually changed)\n if (typeof inst[updateName] === 'function' && value !== oldValue) {\n inst[updateName](value, oldValue);\n }\n };\n\n return { init: initFn, get: getFn, set: setFn };\n };\n}\n\n// ---------------------------------------------------------------------------\n// @config (with sub-decorators)\n// ---------------------------------------------------------------------------\n\ninterface ConfigDecorator {\n <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ): ClassAccessorDecoratorResult<This, Value>;\n\n required: <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ) => ClassAccessorDecoratorResult<This, Value>;\n\n lazy: (factory: (this: any) => unknown) => <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ) => ClassAccessorDecoratorResult<This, Value>;\n\n cached: <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ) => ClassAccessorDecoratorResult<This, Value>;\n\n merge: <This extends Base, Value>(\n target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n ) => ClassAccessorDecoratorResult<This, Value>;\n}\n\nexport const config: ConfigDecorator = Object.assign(\n createConfigDecorator(),\n {\n required: createConfigDecorator({ required: true }),\n lazy(factory: (this: any) => unknown) {\n return createConfigDecorator({ lazyFactory: factory });\n },\n cached: createConfigDecorator({ cached: true }),\n merge: createConfigDecorator({ merge: true }),\n },\n);\n\n// ---------------------------------------------------------------------------\n// @observable\n// ---------------------------------------------------------------------------\n\n/**\n * Marks a `@config` accessor as observable. Stores metadata only;\n * event firing is Phase 2.\n */\nexport function observable<This extends Base, Value>(\n _target: ClassAccessorDecoratorTarget<This, Value>,\n context: ClassAccessorDecoratorContext<This, Value>,\n): void {\n const name = String(context.name);\n const metaMap = getOrCreateMetaMap(\n context.metadata as DecoratorMetadataObject,\n );\n let meta = metaMap.get(name);\n if (!meta) {\n meta = {\n name,\n required: false,\n cached: false,\n merge: false,\n observable: true,\n };\n metaMap.set(name, meta);\n } else {\n meta.observable = true;\n }\n // Return void — don't wrap get/set. @config handles the accessor logic.\n}\n\n// ---------------------------------------------------------------------------\n// @alias — class decorator\n// ---------------------------------------------------------------------------\n\nexport function alias(aliasName: string) {\n return function <T extends abstract new (...args: any[]) => any>(\n target: T,\n _context: ClassDecoratorContext<T>,\n ): T {\n ClassManager.registerAlias(aliasName, target as unknown as typeof Base);\n return target;\n };\n}\n\n// ---------------------------------------------------------------------------\n// @mixin — class decorator\n// ---------------------------------------------------------------------------\n\nexport function mixin(mixinClass: typeof Base) {\n return function <T extends abstract new (...args: any[]) => any>(\n target: T,\n _context: ClassDecoratorContext<T>,\n ): T {\n const targetCls = target as unknown as typeof Base;\n\n if (!targetCls.$mixins) targetCls.$mixins = new Set();\n if (targetCls.$mixins.has(mixinClass)) return target;\n\n targetCls.$mixins.add(mixinClass);\n if (mixinClass.$mixins) {\n for (const m of mixinClass.$mixins) targetCls.$mixins.add(m);\n }\n\n for (const name of Object.getOwnPropertyNames(mixinClass.prototype)) {\n if (name === 'constructor') continue;\n if (name in targetCls.prototype) continue;\n const desc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name);\n if (desc) Object.defineProperty(targetCls.prototype, name, desc);\n }\n\n return target;\n };\n}\n\n// ---------------------------------------------------------------------------\n// @override — class decorator\n// ---------------------------------------------------------------------------\n\nexport function override(targetClass: typeof Base) {\n return function <T extends abstract new (...args: any[]) => any>(\n patchClass: T,\n _context: ClassDecoratorContext<T>,\n ): T {\n const patchProto = (patchClass as unknown as typeof Base).prototype;\n\n for (const name of Object.getOwnPropertyNames(patchProto)) {\n if (name === 'constructor') continue;\n const desc = Object.getOwnPropertyDescriptor(patchProto, name);\n if (desc) Object.defineProperty(targetClass.prototype, name, desc);\n }\n\n return patchClass;\n };\n}\n","/**\n * @framesquared/core – Identifiable mixin\n *\n * Adds an `id` config to any class. If no id is provided, one is\n * auto-generated via `generateId()`. Instances are registered in a\n * global {@link IdentityMap} for lookup by id and automatically\n * removed on destroy.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base } from '../class/Base.js';\nimport { define } from '../class/ClassManager.js';\nimport { generateId } from '../util/index.js';\n\n// ---------------------------------------------------------------------------\n// Global identity registry\n// ---------------------------------------------------------------------------\n\nclass IdentityMapImpl {\n private map = new Map<string, Base>();\n\n register(id: string, instance: Base): void {\n this.map.set(id, instance);\n }\n\n unregister(id: string): void {\n this.map.delete(id);\n }\n\n get(id: string): Base | undefined {\n return this.map.get(id);\n }\n\n has(id: string): boolean {\n return this.map.has(id);\n }\n}\n\n/** Singleton global identity map. */\nexport const IdentityMap = new IdentityMapImpl();\n\n// ---------------------------------------------------------------------------\n// Mixin class\n// ---------------------------------------------------------------------------\n\nexport const Identifiable: typeof Base = define('Ext.mixin.Identifiable', {\n config: {\n id: '',\n },\n\n /**\n * applyId: auto-generates an id if none provided, and registers\n * in the global identity map.\n */\n applyId(this: any, id: string, oldId: string | undefined): string {\n // Unregister old id if present\n if (oldId) {\n IdentityMap.unregister(oldId);\n }\n\n // Auto-generate if empty\n if (!id) {\n id = generateId('framesquared');\n }\n\n // Register\n IdentityMap.register(id, this as Base);\n\n // Install destroy hook (only once)\n if (!this.$identifiableHooked) {\n this.$identifiableHooked = true;\n this.$destroyHooks.push(() => {\n const currentId = this.getId?.();\n if (currentId) {\n IdentityMap.unregister(currentId);\n }\n });\n }\n\n return id;\n },\n});\n","/**\n * @framesquared/core – Factoryable\n *\n * Static factory that creates `Base` instances from flexible input:\n *\n * - Config object with `xtype` or `type` → alias lookup via ClassManager\n * - Plain string → treated as an alias\n * - Existing Base instance → returned as-is\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base } from '../class/Base.js';\nimport { ClassManager } from '../class/ClassManager.js';\n\nexport const Factoryable = {\n /**\n * Creates a `Base` instance from a config descriptor.\n *\n * @param config An object with `xtype`/`type`, a string alias, or\n * an existing `Base` instance.\n */\n create(config: string | Base | Record<string, any>): Base {\n // Already an instance — return as-is.\n if (config instanceof Base) {\n return config;\n }\n\n // String shorthand — treat as alias.\n if (typeof config === 'string') {\n return ClassManager.instantiateByAlias(config);\n }\n\n // Object with xtype / type\n const alias = config.xtype ?? config.type;\n if (!alias || typeof alias !== 'string') {\n throw new Error(\n 'Factoryable.create(): config must have an \"xtype\" or \"type\" property, ' +\n 'be a string alias, or be a Base instance',\n );\n }\n\n // Remove xtype/type from the config passed to the constructor\n const { xtype: _x, type: _t, ...rest } = config;\n return ClassManager.instantiateByAlias(alias, rest);\n },\n};\n","/**\n * @framesquared/core – Inheritable mixin\n *\n * Provides hierarchical parent → child config inheritance. Each instance\n * can have an \"inherited parent\" whose inherited state is merged with the\n * instance's own inherited state. Lookup walks up the chain.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base } from '../class/Base.js';\nimport { define } from '../class/ClassManager.js';\n\n// Per-instance storage for inherited state and parent reference.\nconst ownState = new WeakMap<Base, Record<string, unknown>>();\nconst parentRef = new WeakMap<Base, Base>();\n\nexport const Inheritable: typeof Base = define('Ext.mixin.Inheritable', {\n /**\n * Sets the parent in the inherited-state chain.\n */\n setInheritedParent(this: Base, parent: Base): void {\n parentRef.set(this, parent);\n },\n\n /**\n * Returns the parent in the inherited-state chain, or undefined.\n */\n getInheritedParent(this: Base): Base | undefined {\n return parentRef.get(this);\n },\n\n /**\n * Stores this instance's own inherited state. This is typically\n * called during component setup.\n */\n initInheritedState(this: Base, state: Record<string, unknown>): void {\n ownState.set(this, state);\n },\n\n /**\n * Returns the fully merged inherited state, walking up the parent chain.\n * Own state overrides parent state on key collisions.\n */\n getInherited(this: Base): Record<string, unknown> {\n const parent = parentRef.get(this);\n const parentState = parent && typeof (parent as any).getInherited === 'function'\n ? (parent as any).getInherited()\n : {};\n const own = ownState.get(this) ?? {};\n return { ...parentState, ...own };\n },\n\n /**\n * Resolves a single key by walking up the inherited chain.\n * Returns the first defined value found, or undefined.\n */\n getInheritedConfig(this: Base, key: string): unknown {\n const own = ownState.get(this);\n if (own && key in own) {\n return own[key];\n }\n const parent = parentRef.get(this);\n if (parent && typeof (parent as any).getInheritedConfig === 'function') {\n return (parent as any).getInheritedConfig(key);\n }\n return undefined;\n },\n});\n","/**\n * @framesquared/core – Hookable mixin\n *\n * Provides per-instance before/after hook points for any method.\n * Hooks fire in registration order. Adding a hook wraps the method\n * on the instance (not the prototype), so other instances are unaffected.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport { Base } from '../class/Base.js';\nimport { define } from '../class/ClassManager.js';\n\ninterface HookEntry {\n before: Function[];\n after: Function[];\n original: Function;\n installed: boolean;\n}\n\n/** Per-instance hook storage. Keyed by method name. */\nconst hookStore = new WeakMap<Base, Map<string, HookEntry>>();\n\nfunction getHookMap(inst: Base): Map<string, HookEntry> {\n let map = hookStore.get(inst);\n if (!map) {\n map = new Map();\n hookStore.set(inst, map);\n }\n return map;\n}\n\nfunction ensureEntry(inst: Base, methodName: string): HookEntry {\n const map = getHookMap(inst);\n let entry = map.get(methodName);\n if (!entry) {\n // Grab original from the instance (or its prototype)\n const original = (inst as any)[methodName];\n if (typeof original !== 'function') {\n throw new Error(`Hookable: \"${methodName}\" is not a method on this instance`);\n }\n entry = { before: [], after: [], original, installed: false };\n map.set(methodName, entry);\n }\n return entry;\n}\n\n/**\n * Install the wrapping function on the instance that calls\n * before hooks → original → after hooks.\n */\nfunction installWrapper(inst: Base, methodName: string, entry: HookEntry): void {\n if (entry.installed) return;\n entry.installed = true;\n\n (inst as any)[methodName] = function (this: any, ...args: unknown[]) {\n // Before hooks\n for (const fn of entry.before) {\n fn.apply(this, args);\n }\n\n // Original\n const result = entry.original.apply(this, args);\n\n // After hooks (receive the return value)\n for (const fn of entry.after) {\n fn.call(this, result);\n }\n\n return result;\n };\n}\n\nexport const Hookable: typeof Base = define('Ext.mixin.Hookable', {\n /**\n * Adds a function that runs BEFORE the named method.\n * The hook receives the same arguments as the method.\n */\n addBeforeHook(this: Base, methodName: string, fn: Function): void {\n const entry = ensureEntry(this, methodName);\n entry.before.push(fn);\n installWrapper(this, methodName, entry);\n },\n\n /**\n * Adds a function that runs AFTER the named method.\n * The hook receives the method's return value as its single argument.\n */\n addAfterHook(this: Base, methodName: string, fn: Function): void {\n const entry = ensureEntry(this, methodName);\n entry.after.push(fn);\n installWrapper(this, methodName, entry);\n },\n\n /**\n * Removes a previously registered hook (before or after).\n */\n removeHook(this: Base, methodName: string, fn: Function): void {\n const map = hookStore.get(this);\n if (!map) return;\n const entry = map.get(methodName);\n if (!entry) return;\n\n entry.before = entry.before.filter((f) => f !== fn);\n entry.after = entry.after.filter((f) => f !== fn);\n },\n});\n","/**\n * @framesquared/core – Plugin base class\n *\n * Base class for plugins used with the Pluggable mixin.\n * Each plugin has an `id`, an `init(owner)` lifecycle hook, and\n * is destroyed when its owner is destroyed.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base } from './class/Base.js';\nimport { generateId } from './util/index.js';\nimport { capitalize } from './util/String.js';\n\n/**\n * Declare the config-generated methods so TypeScript knows about them.\n */\nexport interface Plugin {\n getId(): string;\n setId(id: string): void;\n getOwner(): Base | null;\n setOwner(owner: Base | null): void;\n}\n\nexport class Plugin extends Base {\n static override $className = 'Plugin';\n\n // $configDefs for the define()-style config system\n static override $configDefs: Record<string, unknown> = {\n id: '',\n owner: null,\n };\n\n /**\n * Initialises this plugin. Called by the Pluggable mixin after the\n * plugin is added to an owner.\n */\n init(owner: Base): void {\n (this as any).setOwner(owner);\n }\n\n /**\n * Override of initConfig that ensures an auto-generated id.\n */\n override initConfig(config?: Record<string, unknown>): void {\n super.initConfig(config);\n\n // Auto-generate id if not provided\n if (!(this as any).$configInitialized.has('id') || !(this as any)._id) {\n const setter = `set${capitalize('id')}`;\n if (typeof (this as any)[setter] === 'function') {\n (this as any)[setter](generateId('plugin'));\n }\n }\n }\n}\n","/**\n * @framesquared/core – Pluggable mixin\n *\n * Adds plugin management to any class. Plugins are instantiated from\n * config objects (using Factoryable semantics) or accepted as instances.\n * All plugins are destroyed when the owner is destroyed.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base } from '../class/Base.js';\nimport { define } from '../class/ClassManager.js';\nimport { Factoryable } from './Factoryable.js';\nimport { Plugin } from '../Plugin.js';\n\n/** Per-instance plugin list. */\nconst pluginStore = new WeakMap<Base, Plugin[]>();\n\nfunction getPlugins(inst: Base): Plugin[] {\n let list = pluginStore.get(inst);\n if (!list) {\n list = [];\n pluginStore.set(inst, list);\n }\n return list;\n}\n\nexport const Pluggable: typeof Base = define('Ext.mixin.Pluggable', {\n config: {\n plugins: null,\n },\n\n /**\n * applyPlugins: processes the raw plugins config array.\n * Each entry can be a Plugin instance, a config object with type/xtype,\n * or will be passed through Factoryable.\n */\n applyPlugins(this: Base, plugins: any[] | null): any[] | null {\n if (!plugins || !Array.isArray(plugins)) return null;\n\n const list = getPlugins(this);\n for (const pluginCfg of plugins) {\n let plugin: Plugin;\n\n if (pluginCfg instanceof Plugin) {\n plugin = pluginCfg;\n } else if (typeof pluginCfg === 'object') {\n // Use Factoryable to create from config.\n // If no type/xtype, create a base Plugin.\n if (pluginCfg.xtype || pluginCfg.type) {\n plugin = Factoryable.create(pluginCfg) as Plugin;\n } else {\n plugin = new Plugin(pluginCfg);\n }\n } else {\n continue;\n }\n\n plugin.init(this);\n list.push(plugin);\n }\n\n // Install destroy hook (only once per instance)\n if (!(this as any).$pluggableHooked) {\n (this as any).$pluggableHooked = true;\n this.$destroyHooks.push(() => {\n const l = pluginStore.get(this);\n if (l) {\n for (const p of l) {\n if (!p.isDestroyed) p.destroy();\n }\n l.length = 0;\n }\n });\n }\n\n return plugins;\n },\n\n /**\n * Returns the plugin with the given id, or undefined.\n */\n getPlugin(this: Base, id: string): Plugin | undefined {\n const list = pluginStore.get(this);\n if (!list) return undefined;\n return list.find((p) => !p.isDestroyed && p.getId() === id);\n },\n\n /**\n * Adds a plugin to this instance. Calls plugin.init(this).\n */\n addPlugin(this: Base, plugin: Plugin): void {\n const list = getPlugins(this);\n plugin.init(this);\n list.push(plugin);\n\n // Install destroy hook if not already done\n if (!(this as any).$pluggableHooked) {\n (this as any).$pluggableHooked = true;\n this.$destroyHooks.push(() => {\n const l = pluginStore.get(this);\n if (l) {\n for (const p of l) {\n if (!p.isDestroyed) p.destroy();\n }\n l.length = 0;\n }\n });\n }\n },\n\n /**\n * Removes a plugin from this instance. Destroys the plugin.\n */\n removePlugin(this: Base, plugin: Plugin): void {\n const list = pluginStore.get(this);\n if (!list) return;\n const idx = list.indexOf(plugin);\n if (idx !== -1) {\n list.splice(idx, 1);\n }\n plugin.destroy();\n },\n});\n","/**\n * @framesquared/core – ExtEvent\n *\n * Represents a fired event. Provides `preventDefault()`,\n * `stopPropagation()`, and `stopEvent()` controls.\n */\n\nexport class ExtEvent {\n readonly eventName: string;\n readonly source: unknown;\n readonly timestamp: number;\n\n defaultPrevented = false;\n propagationStopped = false;\n\n constructor(eventName: string, source: unknown) {\n this.eventName = eventName;\n this.source = source;\n this.timestamp = performance.now();\n }\n\n preventDefault(): void {\n this.defaultPrevented = true;\n }\n\n stopPropagation(): void {\n this.propagationStopped = true;\n }\n\n /** Convenience: prevents default AND stops propagation. */\n stopEvent(): void {\n this.defaultPrevented = true;\n this.propagationStopped = true;\n }\n}\n","/**\n * @framesquared/core – Observable mixin\n *\n * The event system backbone. Mix into any Base subclass to gain full\n * event management: `on`, `un`, `fireEvent`, suspend/resume, relay,\n * managed listeners, and more.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport { Base } from '../class/Base.js';\nimport { define } from '../class/ClassManager.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ListenerOptions {\n /** Fire only once, then auto-remove. */\n single?: boolean;\n /** Delay in ms before the handler is called. */\n delay?: number;\n /** Buffer (debounce) in ms — resets on each fire. */\n buffer?: number;\n /** Higher priority fires first. Default is 0. */\n priority?: number;\n /** Extra arguments prepended to handler call. */\n args?: unknown[];\n /** Insert at front within the same priority band. */\n prepend?: boolean;\n /** Return a Destroyable handle from `on()`. */\n destroyable?: boolean;\n}\n\nexport interface Destroyable {\n destroy(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface ListenerEntry {\n fn: Function;\n scope: object | undefined;\n priority: number;\n single: boolean;\n delay: number;\n buffer: number;\n args: unknown[] | undefined;\n /** For buffered listeners — active debounce timer. */\n bufferTimerId?: ReturnType<typeof setTimeout>;\n}\n\ninterface QueuedEvent {\n eventName: string;\n args: unknown[];\n}\n\ninterface ManagedListenerEntry {\n target: any;\n eventName: string;\n fn: Function;\n scope: object | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Per-instance state (WeakMap based — no property pollution)\n// ---------------------------------------------------------------------------\n\ninterface ObservableState {\n /** eventName → sorted listener array */\n listeners: Map<string, ListenerEntry[]>;\n /** Suspend depth counter */\n suspendCount: number;\n /** Whether to queue events during suspension */\n queueSuspended: boolean;\n /** Queued events during suspension */\n eventQueue: QueuedEvent[];\n /** Managed listener records for auto-cleanup */\n managedListeners: ManagedListenerEntry[];\n}\n\nconst stateMap = new WeakMap<Base, ObservableState>();\n\nfunction getState(inst: Base): ObservableState {\n let state = stateMap.get(inst);\n if (!state) {\n state = {\n listeners: new Map(),\n suspendCount: 0,\n queueSuspended: false,\n eventQueue: [],\n managedListeners: [],\n };\n stateMap.set(inst, state);\n }\n return state;\n}\n\nfunction getListeners(state: ObservableState, eventName: string): ListenerEntry[] {\n let list = state.listeners.get(eventName);\n if (!list) {\n list = [];\n state.listeners.set(eventName, list);\n }\n return list;\n}\n\n/**\n * Insert a listener entry into the sorted array.\n * Entries are sorted by priority descending.\n * If prepend=true, insert before existing entries with the same priority.\n */\nfunction insertListener(\n list: ListenerEntry[],\n entry: ListenerEntry,\n prepend: boolean,\n): void {\n const p = entry.priority;\n let idx: number;\n\n if (prepend) {\n // Find first entry with priority < p (insert before)\n idx = list.findIndex((e) => e.priority < p);\n } else {\n // Find first entry with priority strictly less than p\n // but after all existing entries with same priority\n idx = list.findIndex((e) => e.priority < p);\n }\n\n if (idx === -1) {\n if (prepend) {\n // Insert before entries with same priority\n idx = list.findIndex((e) => e.priority <= p);\n if (idx === -1) list.push(entry);\n else list.splice(idx, 0, entry);\n } else {\n list.push(entry);\n }\n } else {\n if (prepend) {\n // Walk backwards to find the start of this priority band\n while (idx > 0 && list[idx - 1].priority === p) idx--;\n list.splice(idx, 0, entry);\n } else {\n list.splice(idx, 0, entry);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// The actual fire logic\n// ---------------------------------------------------------------------------\n\nfunction doFireEvent(inst: Base, eventName: string, args: unknown[]): boolean {\n const state = getState(inst);\n\n // Check suspension\n if (state.suspendCount > 0) {\n if (state.queueSuspended) {\n state.eventQueue.push({ eventName, args });\n }\n return true;\n }\n\n const list = state.listeners.get(eventName);\n if (!list || list.length === 0) return true;\n\n // Snapshot for safe iteration (listeners may remove themselves)\n const snapshot = [...list];\n let cancelled = false;\n\n for (const entry of snapshot) {\n // Check if entry was removed during iteration\n if (!list.includes(entry)) continue;\n\n const callArgs = entry.args ? [...entry.args, ...args] : args;\n const scope = entry.scope;\n\n // --- delay ---\n if (entry.delay > 0) {\n setTimeout(() => entry.fn.apply(scope, callArgs), entry.delay);\n if (entry.single) removeEntry(list, entry);\n continue;\n }\n\n // --- buffer ---\n if (entry.buffer > 0) {\n if (entry.bufferTimerId !== undefined) {\n clearTimeout(entry.bufferTimerId);\n }\n entry.bufferTimerId = setTimeout(() => {\n entry.bufferTimerId = undefined;\n entry.fn.apply(scope, callArgs);\n }, entry.buffer);\n if (entry.single) removeEntry(list, entry);\n continue;\n }\n\n // --- immediate ---\n const result = entry.fn.apply(scope, callArgs);\n\n if (entry.single) {\n removeEntry(list, entry);\n }\n\n if (result === false) {\n cancelled = true;\n }\n }\n\n return !cancelled;\n}\n\nfunction removeEntry(list: ListenerEntry[], entry: ListenerEntry): void {\n const idx = list.indexOf(entry);\n if (idx !== -1) list.splice(idx, 1);\n}\n\nfunction findEntry(\n list: ListenerEntry[],\n fn: Function,\n scope: object | undefined,\n): ListenerEntry | undefined {\n return list.find(\n (e) => e.fn === fn && e.scope === scope,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Observable mixin definition\n// ---------------------------------------------------------------------------\n\nexport const Observable: typeof Base = define('Ext.mixin.Observable', {\n // ----- on (with overloads) -----\n on(\n this: Base,\n eventNameOrMap: string | Record<string, Function>,\n handlerOrScope?: Function | object,\n scope?: object,\n options?: ListenerOptions,\n ): Destroyable | void {\n // Map overload: on({ click: fn, hover: fn }, scope)\n if (typeof eventNameOrMap === 'object' && eventNameOrMap !== null) {\n const map = eventNameOrMap as Record<string, Function>;\n const mapScope = handlerOrScope as object | undefined;\n for (const [evName, handler] of Object.entries(map)) {\n (this as any).on(evName, handler, mapScope);\n }\n return;\n }\n\n const eventName = eventNameOrMap as string;\n const handler = handlerOrScope as Function;\n const opts = options ?? {};\n const state = getState(this);\n const list = getListeners(state, eventName);\n\n const entry: ListenerEntry = {\n fn: handler,\n scope: scope,\n priority: opts.priority ?? 0,\n single: opts.single ?? false,\n delay: opts.delay ?? 0,\n buffer: opts.buffer ?? 0,\n args: opts.args,\n };\n\n insertListener(list, entry, opts.prepend ?? false);\n\n if (opts.destroyable) {\n return {\n destroy: () => {\n removeEntry(list, entry);\n },\n };\n }\n },\n\n // ----- un -----\n un(this: Base, eventName: string, handler: Function, scope?: object): void {\n const state = getState(this);\n const list = state.listeners.get(eventName);\n if (!list) return;\n const entry = findEntry(list, handler, scope);\n if (entry) removeEntry(list, entry);\n },\n\n // ----- aliases -----\n addListener(\n this: any,\n ...args: unknown[]\n ): Destroyable | void {\n return this.on(...args);\n },\n\n removeListener(this: any, ...args: unknown[]): void {\n return this.un(...args);\n },\n\n // ----- fireEvent -----\n fireEvent(this: Base, eventName: string, ...args: unknown[]): boolean {\n return doFireEvent(this, eventName, args);\n },\n\n // ----- fireEventArgs -----\n fireEventArgs(this: Base, eventName: string, args: unknown[]): boolean {\n return doFireEvent(this, eventName, args);\n },\n\n // ----- fireEventedAction -----\n fireEventedAction(\n this: Base,\n eventName: string,\n args: unknown[],\n beforeFn: Function,\n afterFn: Function,\n scope?: object,\n ): void {\n // 1. Fire \"before\" + eventName\n const beforeResult = doFireEvent(this, `before${eventName}`, args);\n if (!beforeResult) return; // cancelled\n\n // 2. Call beforeFn\n beforeFn.apply(scope, args);\n\n // 3. Fire eventName\n doFireEvent(this, eventName, args);\n\n // 4. Call afterFn\n afterFn.apply(scope, args);\n },\n\n // ----- suspendEvents -----\n suspendEvents(this: Base, queueSuspended?: boolean): void {\n const state = getState(this);\n state.suspendCount++;\n if (queueSuspended) {\n state.queueSuspended = true;\n }\n },\n\n // ----- resumeEvents -----\n resumeEvents(this: Base, discardQueue?: boolean): void {\n const state = getState(this);\n if (state.suspendCount > 0) {\n state.suspendCount--;\n }\n\n if (state.suspendCount === 0) {\n if (!discardQueue && state.queueSuspended) {\n // Replay queued events\n const queue = state.eventQueue.splice(0);\n state.queueSuspended = false;\n for (const qe of queue) {\n doFireEvent(this, qe.eventName, qe.args);\n }\n } else {\n state.eventQueue.length = 0;\n state.queueSuspended = false;\n }\n }\n },\n\n // ----- isSuspended -----\n isSuspended(this: Base): boolean {\n return getState(this).suspendCount > 0;\n },\n\n // ----- hasListener -----\n hasListener(this: Base, eventName: string): boolean {\n const state = stateMap.get(this);\n if (!state) return false;\n const list = state.listeners.get(eventName);\n return !!list && list.length > 0;\n },\n\n // ----- clearListeners -----\n clearListeners(this: Base): void {\n const state = stateMap.get(this);\n if (state) {\n state.listeners.clear();\n state.eventQueue.length = 0;\n }\n },\n\n // ----- relayEvents -----\n relayEvents(\n this: Base,\n origin: Base,\n events: string[],\n prefix?: string,\n ): Destroyable {\n const handlers: { eventName: string; fn: Function }[] = [];\n const self = this;\n\n for (const eventName of events) {\n const targetName = (prefix ?? '') + eventName;\n const fn = (...args: unknown[]) => {\n doFireEvent(self, targetName, args);\n };\n (origin as any).on(eventName, fn);\n handlers.push({ eventName, fn });\n }\n\n return {\n destroy() {\n for (const { eventName, fn } of handlers) {\n (origin as any).un(eventName, fn);\n }\n handlers.length = 0;\n },\n };\n },\n\n // ----- mon (managed listener) -----\n mon(\n this: Base,\n target: Base,\n eventName: string,\n handler: Function,\n scope?: object,\n ): void {\n const state = getState(this);\n (target as any).on(eventName, handler, scope);\n state.managedListeners.push({ target, eventName, fn: handler, scope });\n },\n\n // ----- mun (remove managed listener) -----\n mun(\n this: Base,\n target: Base,\n eventName: string,\n handler: Function,\n ): void {\n const state = getState(this);\n (target as any).un(eventName, handler);\n state.managedListeners = state.managedListeners.filter(\n (ml) => !(ml.target === target && ml.eventName === eventName && ml.fn === handler),\n );\n },\n});\n\n// ---------------------------------------------------------------------------\n// Destroy hook — install via $destroyHooks for composability with other mixins\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Destroy hook — lazily installed on first on() / mon() call per instance\n// ---------------------------------------------------------------------------\n\nconst hookedInstances = new WeakSet<Base>();\n\n// We patch Observable's `on` and `mon` to lazily install the $destroyHooks\n// callback the first time any listener is registered on an instance.\n\nconst obsProto = Observable.prototype as any;\n\nfunction installDestroyHook(inst: Base): void {\n if (hookedInstances.has(inst)) return;\n hookedInstances.add(inst);\n inst.$destroyHooks.push(() => {\n const state = stateMap.get(inst);\n if (state) {\n state.listeners.clear();\n state.eventQueue.length = 0;\n for (const ml of state.managedListeners) {\n (ml.target as any).un(ml.eventName, ml.fn, ml.scope);\n }\n state.managedListeners.length = 0;\n }\n });\n}\n\nconst origOn = obsProto.on;\nobsProto.on = function (\n this: Base,\n ...args: any[]\n): Destroyable | void {\n installDestroyHook(this);\n return origOn.apply(this, args);\n};\n\nconst origMon = obsProto.mon;\nobsProto.mon = function (\n this: Base,\n ...args: any[]\n): void {\n installDestroyHook(this);\n return origMon.apply(this, args);\n};\n","/**\n * @framesquared/core – Destroyable\n *\n * Interface for objects that support deterministic cleanup, plus a\n * utility to combine multiple destroyables into one.\n */\n\nexport interface Destroyable {\n destroy(): void;\n}\n\nexport const DestroyableUtil = {\n /**\n * Returns a single {@link Destroyable} whose `destroy()` method calls\n * `destroy()` on every item. The combined handle is idempotent — second\n * and subsequent calls are no-ops.\n */\n combine(...items: Destroyable[]): Destroyable {\n let destroyed = false;\n return {\n destroy() {\n if (destroyed) return;\n destroyed = true;\n for (const item of items) {\n item.destroy();\n }\n },\n };\n },\n};\n","/**\n * @framesquared/core – EventDomain\n *\n * A domain groups events by category (e.g. 'component', 'store').\n * Controllers can use `domain.listen({ '#myButton': { click: handler } })`\n * to route events by selector.\n *\n * Selectors:\n * - `#itemId` — matches target.getItemId() === 'itemId'\n * - `ClassName` — matches target.$className === 'ClassName'\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport type { Base } from '../class/Base.js';\nimport type { Destroyable } from './Destroyable.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Selector → { eventName → handler } */\nexport type ListenerConfig = Record<string, Record<string, Function>>;\n\ninterface RegisteredListener {\n selector: string;\n eventName: string;\n handler: Function;\n}\n\n// ---------------------------------------------------------------------------\n// Static domain registry\n// ---------------------------------------------------------------------------\n\nconst domainRegistry = new Map<string, EventDomain>();\n\n// ---------------------------------------------------------------------------\n// EventDomain\n// ---------------------------------------------------------------------------\n\nexport class EventDomain {\n readonly name: string;\n private readonly matchFn: (target: Base) => boolean;\n private registeredListeners: RegisteredListener[] = [];\n\n constructor(name: string, matchFn: (target: Base) => boolean) {\n this.name = name;\n this.matchFn = matchFn;\n }\n\n // -- Static registry ----------------------------------------------------\n\n static register(name: string, domain: EventDomain): void {\n domainRegistry.set(name, domain);\n }\n\n static get(name: string): EventDomain | undefined {\n return domainRegistry.get(name);\n }\n\n // -- Instance API -------------------------------------------------------\n\n /**\n * Returns `true` if `target` belongs to this domain.\n */\n match(target: Base): boolean {\n return this.matchFn(target);\n }\n\n /**\n * Registers a controller-style listener config.\n *\n * ```ts\n * domain.listen({\n * '#myButton': { click: handler },\n * 'MyApp.view.Panel': { collapse: handler },\n * });\n * ```\n *\n * Returns a {@link Destroyable} that removes all registered listeners.\n */\n listen(config: ListenerConfig): Destroyable {\n const entries: RegisteredListener[] = [];\n\n for (const [selector, events] of Object.entries(config)) {\n for (const [eventName, handler] of Object.entries(events)) {\n const entry: RegisteredListener = { selector, eventName, handler };\n entries.push(entry);\n this.registeredListeners.push(entry);\n }\n }\n\n return {\n destroy: () => {\n for (const entry of entries) {\n const idx = this.registeredListeners.indexOf(entry);\n if (idx !== -1) this.registeredListeners.splice(idx, 1);\n }\n entries.length = 0;\n },\n };\n }\n\n /**\n * Dispatches an event from `source` through this domain.\n * All registered listeners whose selector matches are called.\n */\n dispatch(source: Base, eventName: string, args: unknown[]): void {\n if (!this.match(source)) return;\n\n for (const entry of this.registeredListeners) {\n if (entry.eventName !== eventName) continue;\n if (!this.matchesSelector(source, entry.selector)) continue;\n entry.handler.apply(undefined, args);\n }\n }\n\n // -- Selector matching --------------------------------------------------\n\n private matchesSelector(target: Base, selector: string): boolean {\n // #itemId selector\n if (selector.startsWith('#')) {\n const id = selector.slice(1);\n const targetId =\n typeof (target as any).getItemId === 'function'\n ? (target as any).getItemId()\n : typeof (target as any).getId === 'function'\n ? (target as any).getId()\n : undefined;\n return targetId === id;\n }\n\n // ClassName selector\n return (target as any).$className === selector;\n }\n}\n","/**\n * @framesquared/core – EventBus\n *\n * Global singleton event bus with publish / subscribe semantics.\n * Supports dot-separated namespaced channels and wildcards:\n *\n * - `\"user.login\"` — exact match\n * - `\"user.*\"` — matches one segment after \"user.\"\n * - `\"user.**\"` — matches one or more segments after \"user.\"\n * - `\"**\"` — matches any channel\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\nimport type { Destroyable } from './Destroyable.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface Subscription {\n pattern: string;\n handler: Function;\n scope: object | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Wildcard matching\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` if `channel` matches the subscription `pattern`.\n *\n * - Exact match: `\"a.b.c\"` matches `\"a.b.c\"`\n * - Single wild: `\"a.*\"` matches `\"a.x\"` but not `\"a\"` or `\"a.x.y\"`\n * - Deep wild: `\"a.**\"` matches `\"a.x\"`, `\"a.x.y\"`, `\"a.x.y.z\"`\n * - Global deep: `\"**\"` matches everything\n */\nfunction matchPattern(pattern: string, channel: string): boolean {\n // Global deep wildcard\n if (pattern === '**') return true;\n\n // Deep wildcard suffix\n if (pattern.endsWith('.**')) {\n const prefix = pattern.slice(0, -3); // \"user\" from \"user.**\"\n return channel.startsWith(prefix + '.');\n }\n\n // Single wildcard suffix\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2); // \"user\" from \"user.*\"\n if (!channel.startsWith(prefix + '.')) return false;\n // Must have exactly one more segment\n const rest = channel.slice(prefix.length + 1);\n return rest.length > 0 && !rest.includes('.');\n }\n\n // Exact match\n return pattern === channel;\n}\n\n// ---------------------------------------------------------------------------\n// EventBus singleton\n// ---------------------------------------------------------------------------\n\nclass EventBusImpl {\n private subscriptions: Subscription[] = [];\n\n /**\n * Publishes a message to a channel. All matching subscribers are called.\n */\n publish(channel: string, ...args: unknown[]): void {\n // Snapshot for safe iteration\n const snapshot = [...this.subscriptions];\n for (const sub of snapshot) {\n if (matchPattern(sub.pattern, channel)) {\n sub.handler.apply(sub.scope, args);\n }\n }\n }\n\n /**\n * Subscribes to a channel (exact or wildcard pattern).\n * Returns a {@link Destroyable} handle.\n */\n subscribe(\n channel: string,\n handler: Function,\n scope?: object,\n ): Destroyable {\n const sub: Subscription = { pattern: channel, handler, scope };\n this.subscriptions.push(sub);\n\n return {\n destroy: () => {\n const idx = this.subscriptions.indexOf(sub);\n if (idx !== -1) this.subscriptions.splice(idx, 1);\n },\n };\n }\n\n /**\n * Removes a specific subscription by handler reference.\n */\n unsubscribe(channel: string, handler: Function): void {\n const idx = this.subscriptions.findIndex(\n (s) => s.pattern === channel && s.handler === handler,\n );\n if (idx !== -1) this.subscriptions.splice(idx, 1);\n }\n}\n\n/** Singleton global event bus. */\nexport const EventBus = new EventBusImpl();\n","/**\n * @framesquared/core – EventManager (DomEvent)\n *\n * Thin layer over native DOM events providing:\n * - Tracked listener registration with bulk cleanup\n * - Event delegation via closest()\n * - DOM-ready callback\n * - Utility helpers for coordinates, keys, stopEvent\n */\n\nimport type { Destroyable } from './Destroyable.js';\n\n// ---------------------------------------------------------------------------\n// Internal tracking\n// ---------------------------------------------------------------------------\n\ninterface TrackedListener {\n element: Element | Document;\n eventName: string;\n handler: EventListener;\n options?: AddEventListenerOptions;\n}\n\nconst tracked: TrackedListener[] = [];\n\n// ---------------------------------------------------------------------------\n// EventManager singleton\n// ---------------------------------------------------------------------------\n\nexport const EventManager = {\n // ----- on -----\n\n /**\n * Registers a DOM event listener. The listener is tracked for\n * bulk removal via {@link removeAll}.\n *\n * Returns a {@link Destroyable} handle.\n */\n on(\n element: Element | Document,\n eventName: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): Destroyable {\n element.addEventListener(eventName, handler, options);\n const entry: TrackedListener = { element, eventName, handler, options };\n tracked.push(entry);\n\n return {\n destroy() {\n element.removeEventListener(eventName, handler, options);\n const idx = tracked.indexOf(entry);\n if (idx !== -1) tracked.splice(idx, 1);\n },\n };\n },\n\n // ----- un -----\n\n /**\n * Removes a DOM event listener.\n */\n un(\n element: Element | Document,\n eventName: string,\n handler: EventListener,\n ): void {\n element.removeEventListener(eventName, handler);\n const idx = tracked.findIndex(\n (t) => t.element === element && t.eventName === eventName && t.handler === handler,\n );\n if (idx !== -1) tracked.splice(idx, 1);\n },\n\n // ----- delegate -----\n\n /**\n * Event delegation: listens on `element` and fires `handler` only when\n * the event target (or an ancestor up to `element`) matches `selector`.\n *\n * Uses `Element.closest()` — no IE polyfill needed.\n */\n delegate(\n element: Element,\n eventName: string,\n selector: string,\n handler: (e: Event, matchedTarget: Element) => void,\n ): Destroyable {\n const delegateHandler: EventListener = (e: Event) => {\n const target = e.target as Element | null;\n if (!target) return;\n const matched = target.closest(selector);\n if (matched && element.contains(matched)) {\n handler(e, matched);\n }\n };\n\n return EventManager.on(element, eventName, delegateHandler);\n },\n\n // ----- onReady -----\n\n /**\n * Calls `fn` when the DOM is ready. If it's already ready (interactive\n * or complete), fires immediately.\n */\n onReady(fn: () => void): void {\n if (\n typeof document !== 'undefined' &&\n (document.readyState === 'interactive' || document.readyState === 'complete')\n ) {\n fn();\n } else if (typeof document !== 'undefined') {\n document.addEventListener('DOMContentLoaded', fn, { once: true });\n }\n },\n\n // ----- utility helpers -----\n\n /** Prevents default and stops propagation. */\n stopEvent(e: Event): void {\n e.preventDefault();\n e.stopPropagation();\n },\n\n /** Returns `e.pageX` (or `e.clientX` as fallback). */\n getPageX(e: MouseEvent): number {\n return e.pageX ?? e.clientX;\n },\n\n /** Returns `e.pageY` (or `e.clientY` as fallback). */\n getPageY(e: MouseEvent): number {\n return e.pageY ?? e.clientY;\n },\n\n /** Returns `e.relatedTarget`. */\n getRelatedTarget(e: MouseEvent): Element | null {\n return e.relatedTarget as Element | null;\n },\n\n /** Returns `e.key` (modern key value). */\n getKeyCode(e: KeyboardEvent): string {\n return e.key;\n },\n\n // ----- bulk cleanup -----\n\n /**\n * Removes all listeners registered via {@link on} and {@link delegate}.\n */\n removeAll(): void {\n for (const entry of tracked) {\n entry.element.removeEventListener(entry.eventName, entry.handler, entry.options);\n }\n tracked.length = 0;\n },\n};\n","/**\n * @framesquared/core – GestureRecognizer\n *\n * Detects touch/pointer gestures and dispatches synthetic CustomEvents\n * on the target element. Uses PointerEvent exclusively (no IE).\n *\n * Recognized gestures: tap, doubletap, longpress, swipe, pinch, rotate.\n */\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst TAP_MAX_DURATION = 400; // ms — max time for a tap\nconst TAP_MAX_DISTANCE = 15; // px — max movement for a tap\nconst DOUBLETAP_INTERVAL = 300; // ms — max gap between two taps\nconst LONGPRESS_DURATION = 500; // ms — hold time for longpress\nconst SWIPE_MIN_DISTANCE = 50; // px — minimum swipe distance\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction distance(x1: number, y1: number, x2: number, y2: number): number {\n return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n}\n\nfunction angle(x1: number, y1: number, x2: number, y2: number): number {\n return Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI);\n}\n\nfunction dispatchGesture(\n el: Element,\n name: string,\n detail?: Record<string, unknown>,\n): void {\n el.dispatchEvent(new CustomEvent(name, {\n bubbles: true,\n cancelable: true,\n detail: detail ?? {},\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Pointer tracking\n// ---------------------------------------------------------------------------\n\ninterface PointerState {\n id: number;\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n startTime: number;\n}\n\n// ---------------------------------------------------------------------------\n// GestureRecognizer\n// ---------------------------------------------------------------------------\n\nexport class GestureRecognizer {\n private el: Element;\n private pointers = new Map<number, PointerState>();\n private longpressTimer: ReturnType<typeof setTimeout> | undefined;\n private lastTapTime = 0;\n private destroyed = false;\n\n // Multi-touch initial state\n private initialPinchDistance = 0;\n private initialPinchAngle = 0;\n\n // Bound handlers for removal\n private handleDown: (e: Event) => void;\n private handleMove: (e: Event) => void;\n private handleUp: (e: Event) => void;\n private handleCancel: (e: Event) => void;\n\n constructor(element: Element) {\n this.el = element;\n\n this.handleDown = (e) => this.onPointerDown(e as PointerEvent);\n this.handleMove = (e) => this.onPointerMove(e as PointerEvent);\n this.handleUp = (e) => this.onPointerUp(e as PointerEvent);\n this.handleCancel = (e) => this.onPointerCancel(e as PointerEvent);\n\n element.addEventListener('pointerdown', this.handleDown);\n element.addEventListener('pointermove', this.handleMove);\n element.addEventListener('pointerup', this.handleUp);\n element.addEventListener('pointercancel', this.handleCancel);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.el.removeEventListener('pointerdown', this.handleDown);\n this.el.removeEventListener('pointermove', this.handleMove);\n this.el.removeEventListener('pointerup', this.handleUp);\n this.el.removeEventListener('pointercancel', this.handleCancel);\n this.clearLongpress();\n this.pointers.clear();\n }\n\n // ----- pointer down -----\n\n private onPointerDown(e: PointerEvent): void {\n if (this.destroyed) return;\n\n const state: PointerState = {\n id: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n currentX: e.clientX,\n currentY: e.clientY,\n startTime: Date.now(),\n };\n this.pointers.set(e.pointerId, state);\n\n if (this.pointers.size === 1) {\n // Single pointer — start longpress timer\n this.startLongpress(state);\n } else if (this.pointers.size === 2) {\n // Two pointers — record initial pinch/rotate state\n this.clearLongpress();\n this.recordTwoPointerBaseline();\n }\n }\n\n // ----- pointer move -----\n\n private onPointerMove(e: PointerEvent): void {\n if (this.destroyed) return;\n\n const state = this.pointers.get(e.pointerId);\n if (!state) return;\n\n state.currentX = e.clientX;\n state.currentY = e.clientY;\n\n // If moved too far, cancel longpress\n const dist = distance(state.startX, state.startY, state.currentX, state.currentY);\n if (dist > TAP_MAX_DISTANCE) {\n this.clearLongpress();\n }\n\n // Two-pointer gestures\n if (this.pointers.size === 2) {\n this.handleTwoPointerMove();\n }\n }\n\n // ----- pointer up -----\n\n private onPointerUp(e: PointerEvent): void {\n if (this.destroyed) return;\n\n const state = this.pointers.get(e.pointerId);\n if (!state) return;\n\n state.currentX = e.clientX;\n state.currentY = e.clientY;\n\n this.clearLongpress();\n\n const dt = Date.now() - state.startTime;\n const dist = distance(state.startX, state.startY, state.currentX, state.currentY);\n\n this.pointers.delete(e.pointerId);\n\n // Only process single-pointer gestures\n if (this.pointers.size > 0) return;\n\n // Swipe detection\n if (dist >= SWIPE_MIN_DISTANCE && dt < 1000) {\n this.fireSwipe(state);\n return;\n }\n\n // Tap detection\n if (dt < TAP_MAX_DURATION && dist < TAP_MAX_DISTANCE) {\n const now = Date.now();\n if (now - this.lastTapTime < DOUBLETAP_INTERVAL) {\n // Double tap\n dispatchGesture(this.el, 'doubletap');\n this.lastTapTime = 0; // reset so triple tap doesn't re-fire\n } else {\n // Single tap\n dispatchGesture(this.el, 'tap');\n this.lastTapTime = now;\n }\n }\n }\n\n // ----- pointer cancel -----\n\n private onPointerCancel(e: PointerEvent): void {\n if (this.destroyed) return;\n this.pointers.delete(e.pointerId);\n this.clearLongpress();\n }\n\n // ----- longpress -----\n\n private startLongpress(state: PointerState): void {\n this.clearLongpress();\n this.longpressTimer = setTimeout(() => {\n this.longpressTimer = undefined;\n // Check the pointer is still down and hasn't moved\n const current = this.pointers.get(state.id);\n if (!current) return;\n const dist = distance(current.startX, current.startY, current.currentX, current.currentY);\n if (dist < TAP_MAX_DISTANCE) {\n dispatchGesture(this.el, 'longpress');\n }\n }, LONGPRESS_DURATION);\n }\n\n private clearLongpress(): void {\n if (this.longpressTimer !== undefined) {\n clearTimeout(this.longpressTimer);\n this.longpressTimer = undefined;\n }\n }\n\n // ----- swipe -----\n\n private fireSwipe(state: PointerState): void {\n const dx = state.currentX - state.startX;\n const dy = state.currentY - state.startY;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n\n let direction: string;\n if (absDx > absDy) {\n direction = dx > 0 ? 'right' : 'left';\n } else {\n direction = dy > 0 ? 'down' : 'up';\n }\n\n dispatchGesture(this.el, 'swipe', {\n direction,\n distance: Math.max(absDx, absDy),\n deltaX: dx,\n deltaY: dy,\n });\n }\n\n // ----- two-pointer: pinch + rotate -----\n\n private recordTwoPointerBaseline(): void {\n const pts = [...this.pointers.values()];\n if (pts.length < 2) return;\n this.initialPinchDistance = distance(\n pts[0].currentX, pts[0].currentY,\n pts[1].currentX, pts[1].currentY,\n );\n this.initialPinchAngle = angle(\n pts[0].currentX, pts[0].currentY,\n pts[1].currentX, pts[1].currentY,\n );\n }\n\n private handleTwoPointerMove(): void {\n const pts = [...this.pointers.values()];\n if (pts.length < 2) return;\n\n const currentDist = distance(\n pts[0].currentX, pts[0].currentY,\n pts[1].currentX, pts[1].currentY,\n );\n const currentAngle = angle(\n pts[0].currentX, pts[0].currentY,\n pts[1].currentX, pts[1].currentY,\n );\n\n // Pinch\n if (this.initialPinchDistance > 0) {\n const scale = currentDist / this.initialPinchDistance;\n dispatchGesture(this.el, 'pinch', {\n scale,\n distance: currentDist,\n });\n }\n\n // Rotate\n const angleDelta = currentAngle - this.initialPinchAngle;\n dispatchGesture(this.el, 'rotate', {\n angle: angleDelta,\n rotation: angleDelta,\n });\n }\n}\n","/**\n * @framesquared/core – KeyMap\n *\n * Maps key combinations to handlers. Supports modifier keys\n * (Ctrl, Alt, Shift, Meta) with exact matching.\n *\n * ```ts\n * const km = new KeyMap({\n * target: myElement,\n * bindings: [\n * { key: 'Ctrl+S', handler: onSave, preventDefault: true },\n * { key: 'Escape', handler: onClose },\n * ],\n * });\n * ```\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface KeyBinding {\n /** Key combo string, e.g. `\"Ctrl+Shift+S\"`, `\"Enter\"`, `\"Alt+F4\"`. */\n key: string;\n /** Handler called when the combo matches. */\n handler: Function;\n /** Optional `this` scope for the handler. */\n scope?: object;\n /** If true, `e.preventDefault()` is called when the combo matches. */\n preventDefault?: boolean;\n}\n\nexport interface KeyMapConfig {\n target: Element;\n bindings: KeyBinding[];\n}\n\n// ---------------------------------------------------------------------------\n// Internal: parsed binding\n// ---------------------------------------------------------------------------\n\ninterface ParsedBinding {\n raw: KeyBinding;\n keyLower: string;\n ctrl: boolean;\n alt: boolean;\n shift: boolean;\n meta: boolean;\n}\n\nfunction parseBinding(binding: KeyBinding): ParsedBinding {\n const parts = binding.key.split('+').map((p) => p.trim());\n let ctrl = false;\n let alt = false;\n let shift = false;\n let meta = false;\n\n // The last part is the key; preceding parts are modifiers.\n const keyPart = parts.pop()!;\n\n for (const mod of parts) {\n switch (mod.toLowerCase()) {\n case 'ctrl':\n case 'control':\n ctrl = true;\n break;\n case 'alt':\n alt = true;\n break;\n case 'shift':\n shift = true;\n break;\n case 'meta':\n case 'cmd':\n case 'command':\n meta = true;\n break;\n }\n }\n\n return {\n raw: binding,\n keyLower: keyPart.toLowerCase(),\n ctrl,\n alt,\n shift,\n meta,\n };\n}\n\nfunction matchesEvent(parsed: ParsedBinding, e: KeyboardEvent): boolean {\n if (e.key.toLowerCase() !== parsed.keyLower) return false;\n if (e.ctrlKey !== parsed.ctrl) return false;\n if (e.altKey !== parsed.alt) return false;\n if (e.shiftKey !== parsed.shift) return false;\n if (e.metaKey !== parsed.meta) return false;\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// KeyMap\n// ---------------------------------------------------------------------------\n\nexport class KeyMap {\n private target: Element;\n private parsedBindings: ParsedBinding[] = [];\n private enabled = true;\n private handleKeyDown: (e: Event) => void;\n\n constructor(config: KeyMapConfig) {\n this.target = config.target;\n\n for (const b of config.bindings) {\n this.parsedBindings.push(parseBinding(b));\n }\n\n this.handleKeyDown = (e: Event) => this.onKeyDown(e as KeyboardEvent);\n this.target.addEventListener('keydown', this.handleKeyDown);\n }\n\n // ----- event handler -----\n\n private onKeyDown(e: KeyboardEvent): void {\n if (!this.enabled) return;\n\n for (const parsed of this.parsedBindings) {\n if (matchesEvent(parsed, e)) {\n if (parsed.raw.preventDefault) {\n e.preventDefault();\n }\n parsed.raw.handler.call(parsed.raw.scope, e);\n }\n }\n }\n\n // ----- public API -----\n\n enable(): void {\n this.enabled = true;\n }\n\n disable(): void {\n this.enabled = false;\n }\n\n addBinding(binding: KeyBinding): void {\n this.parsedBindings.push(parseBinding(binding));\n }\n\n removeBinding(binding: KeyBinding): void {\n const idx = this.parsedBindings.findIndex((p) => p.raw === binding);\n if (idx !== -1) this.parsedBindings.splice(idx, 1);\n }\n\n destroy(): void {\n this.target.removeEventListener('keydown', this.handleKeyDown);\n this.parsedBindings.length = 0;\n this.enabled = false;\n }\n}\n","/**\n * @framesquared/core – AriaManager\n *\n * Manages ARIA attributes across the framework. Provides helpers\n * for setting roles, labels, descriptions, live regions, and\n * screen reader announcements.\n */\n\nlet descCounter = 0;\nlet liveRegion: HTMLElement | null = null;\nlet assertiveRegion: HTMLElement | null = null;\n\nfunction ensureLiveRegion(priority: 'polite' | 'assertive'): HTMLElement {\n if (priority === 'assertive') {\n if (!assertiveRegion) {\n assertiveRegion = document.createElement('div');\n assertiveRegion.setAttribute('aria-live', 'assertive');\n assertiveRegion.setAttribute('aria-atomic', 'true');\n assertiveRegion.setAttribute('role', 'status');\n assertiveRegion.style.cssText =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;';\n document.body.appendChild(assertiveRegion);\n }\n return assertiveRegion;\n }\n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.setAttribute('aria-live', 'polite');\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.setAttribute('role', 'status');\n liveRegion.style.cssText =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;';\n document.body.appendChild(liveRegion);\n }\n return liveRegion;\n}\n\nexport const AriaManager = {\n setRole(element: Element, role: string): void {\n element.setAttribute('role', role);\n },\n\n setLabel(element: Element, label: string): void {\n element.setAttribute('aria-label', label);\n },\n\n setLabelledBy(element: Element, id: string): void {\n element.setAttribute('aria-labelledby', id);\n },\n\n setDescription(element: Element, description: string): void {\n const id = `ext-aria-desc-${descCounter++}`;\n const descEl = document.createElement('span');\n descEl.id = id;\n descEl.textContent = description;\n descEl.style.cssText =\n 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);';\n element.parentNode?.appendChild(descEl) ?? document.body.appendChild(descEl);\n element.setAttribute('aria-describedby', id);\n },\n\n setLive(element: Element, mode: 'polite' | 'assertive' | 'off'): void {\n element.setAttribute('aria-live', mode);\n },\n\n announce(message: string, priority: 'polite' | 'assertive' = 'polite'): void {\n const region = ensureLiveRegion(priority);\n region.textContent = message;\n },\n\n /** Generate a unique ID for ARIA linking. */\n generateId(prefix = 'ext-aria'): string {\n return `${prefix}-${descCounter++}`;\n },\n};\n","/**\n * @framesquared/core – FocusManager\n *\n * Manages focus trapping for modal dialogs, focus save/restore,\n * and roving tabindex patterns.\n */\n\nlet trapped = false;\nlet trapContainer: HTMLElement | null = null;\nlet savedFocus: Element | null = null;\nlet keyHandler: ((e: KeyboardEvent) => void) | null = null;\n\nconst FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nfunction getFocusableElements(container: HTMLElement): HTMLElement[] {\n return Array.from(container.querySelectorAll(FOCUSABLE));\n}\n\nfunction onKeyDown(e: KeyboardEvent): void {\n if (e.key !== 'Tab' || !trapContainer) return;\n const focusable = getFocusableElements(trapContainer);\n if (focusable.length === 0) return;\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n}\n\nexport const FocusManager = {\n /**\n * Trap focus within a container. Tab/Shift+Tab cycle among\n * focusable elements inside the container.\n */\n trapFocus(container: HTMLElement): void {\n trapped = true;\n trapContainer = container;\n keyHandler = onKeyDown;\n document.addEventListener('keydown', keyHandler);\n // Focus first focusable element\n const focusable = getFocusableElements(container);\n if (focusable.length > 0) focusable[0].focus();\n },\n\n /** Release the focus trap. */\n releaseFocus(): void {\n trapped = false;\n trapContainer = null;\n if (keyHandler) {\n document.removeEventListener('keydown', keyHandler);\n keyHandler = null;\n }\n },\n\n isTrapped(): boolean {\n return trapped;\n },\n\n /** Save the currently focused element for later restoration. */\n saveFocus(): void {\n savedFocus = document.activeElement;\n },\n\n /** Restore focus to the previously saved element. */\n restoreFocus(): void {\n if (savedFocus && typeof (savedFocus as HTMLElement).focus === 'function') {\n (savedFocus as HTMLElement).focus();\n }\n savedFocus = null;\n },\n\n /** Reset all state (for tests). */\n reset(): void {\n if (keyHandler) {\n document.removeEventListener('keydown', keyHandler);\n keyHandler = null;\n }\n trapped = false;\n trapContainer = null;\n savedFocus = null;\n },\n};\n","/**\n * @framesquared/core – Locale\n *\n * Manages translations, number/date formatting (via Intl APIs),\n * plural rules, RTL direction, and locale-aware collation.\n */\n\nexport interface NumberFormatOptions {\n currency?: string;\n}\n\nexport interface LocaleConfig {\n language: string;\n rtl?: boolean;\n messages: Record<string, string>;\n dateFormat?: string;\n timeFormat?: string;\n numberFormat?: NumberFormatOptions;\n firstDayOfWeek?: number;\n pluralRules?: (count: number) => string;\n}\n\nexport class Locale {\n private _language: string;\n private _rtl: boolean;\n private _messages: Record<string, string>;\n private _numberFormat: NumberFormatOptions;\n private _firstDayOfWeek: number;\n private _pluralRules: ((count: number) => string) | null;\n private _collator: Intl.Collator;\n private _numberFormatter: Intl.NumberFormat;\n private _dateFormatter: Intl.DateTimeFormat;\n private _timeFormatter: Intl.DateTimeFormat;\n private _currencyFormatter: Intl.NumberFormat | null = null;\n\n constructor(config: LocaleConfig) {\n this._language = config.language;\n this._rtl = config.rtl ?? false;\n this._messages = { ...config.messages };\n this._numberFormat = config.numberFormat ?? {};\n this._firstDayOfWeek = config.firstDayOfWeek ?? 0;\n this._pluralRules = config.pluralRules ?? null;\n\n // Intl formatters\n this._collator = new Intl.Collator(this._language);\n this._numberFormatter = new Intl.NumberFormat(this._language);\n this._dateFormatter = new Intl.DateTimeFormat(this._language, {\n year: 'numeric', month: 'numeric', day: 'numeric',\n });\n this._timeFormatter = new Intl.DateTimeFormat(this._language, {\n hour: 'numeric', minute: 'numeric',\n });\n\n if (this._numberFormat.currency) {\n this._currencyFormatter = new Intl.NumberFormat(this._language, {\n style: 'currency', currency: this._numberFormat.currency,\n });\n }\n }\n\n // -----------------------------------------------------------------------\n // Accessors\n // -----------------------------------------------------------------------\n\n getLanguage(): string { return this._language; }\n isRtl(): boolean { return this._rtl; }\n getDirection(): 'ltr' | 'rtl' { return this._rtl ? 'rtl' : 'ltr'; }\n getFirstDayOfWeek(): number { return this._firstDayOfWeek; }\n\n // -----------------------------------------------------------------------\n // Translation\n // -----------------------------------------------------------------------\n\n t(key: string, params?: Record<string, unknown>): string {\n let msg = this._messages[key];\n if (msg === undefined) return key;\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n msg = msg.replaceAll(`{${k}}`, String(v ?? ''));\n }\n }\n return msg;\n }\n\n /**\n * Translate with plural support. Appends the plural category\n * to the key (e.g., 'items.one', 'items.other').\n */\n tp(key: string, count: number, params?: Record<string, unknown>): string {\n const category = this.getPlural(count);\n return this.t(`${key}.${category}`, params);\n }\n\n // -----------------------------------------------------------------------\n // Plural rules\n // -----------------------------------------------------------------------\n\n getPlural(count: number): string {\n if (this._pluralRules) return this._pluralRules(count);\n // Use Intl.PluralRules\n try {\n return new Intl.PluralRules(this._language).select(count);\n } catch {\n return count === 1 ? 'one' : 'other';\n }\n }\n\n // -----------------------------------------------------------------------\n // Number formatting\n // -----------------------------------------------------------------------\n\n formatNumber(value: number): string {\n return this._numberFormatter.format(value);\n }\n\n formatCurrency(value: number): string {\n if (this._currencyFormatter) return this._currencyFormatter.format(value);\n return this._numberFormatter.format(value);\n }\n\n // -----------------------------------------------------------------------\n // Date / time formatting\n // -----------------------------------------------------------------------\n\n formatDate(date: Date): string {\n return this._dateFormatter.format(date);\n }\n\n formatTime(date: Date): string {\n return this._timeFormatter.format(date);\n }\n\n // -----------------------------------------------------------------------\n // Collation / sorting\n // -----------------------------------------------------------------------\n\n compare(a: string, b: string): number {\n return this._collator.compare(a, b);\n }\n}\n","/**\n * @framesquared/core – LocaleManager\n *\n * Singleton that manages registered locales. setLocale() applies\n * dir and lang attributes to document.documentElement and fires\n * 'localechange'.\n */\n\nimport type { Locale } from './Locale.js';\n\nconst locales = new Map<string, Locale>();\nlet activeLocale: Locale | null = null;\nconst listeners: Record<string, Function[]> = {};\n\nfunction fire(event: string, ...args: unknown[]): void {\n (listeners[event] ?? []).forEach(fn => fn(...args));\n}\n\nexport const LocaleManager = {\n register(locale: Locale): void {\n locales.set(locale.getLanguage(), locale);\n },\n\n setLocale(language: string): void {\n const locale = locales.get(language);\n if (!locale) return;\n activeLocale = locale;\n\n // Apply to document\n const root = document.documentElement;\n root.setAttribute('lang', language);\n root.setAttribute('dir', locale.getDirection());\n\n fire('localechange', locale, language);\n },\n\n getLocale(): Locale | null {\n return activeLocale;\n },\n\n t(key: string, params?: Record<string, unknown>): string {\n if (!activeLocale) return key;\n return activeLocale.t(key, params);\n },\n\n getDirection(): 'ltr' | 'rtl' {\n return activeLocale?.getDirection() ?? 'ltr';\n },\n\n on(event: string, fn: Function): void {\n (listeners[event] ??= []).push(fn);\n },\n\n off(event: string, fn: Function): void {\n const list = listeners[event];\n if (!list) return;\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n },\n\n reset(): void {\n activeLocale = null;\n locales.clear();\n for (const key of Object.keys(listeners)) listeners[key] = [];\n document.documentElement.removeAttribute('dir');\n document.documentElement.removeAttribute('lang');\n },\n};\n","/**\n * @framesquared/core – en-US locale bundle\n */\n\nimport { Locale } from '../Locale.js';\n\nexport const enUS = new Locale({\n language: 'en-US',\n rtl: false,\n firstDayOfWeek: 0,\n numberFormat: { currency: 'USD' },\n messages: {\n // Buttons\n 'btn.ok': 'OK',\n 'btn.cancel': 'Cancel',\n 'btn.yes': 'Yes',\n 'btn.no': 'No',\n 'btn.save': 'Save',\n 'btn.close': 'Close',\n 'btn.apply': 'Apply',\n 'btn.reset': 'Reset',\n\n // Grid\n 'grid.noData': 'No data to display',\n 'grid.loading': 'Loading...',\n 'grid.page': 'Page {page} of {total}',\n 'grid.pageSize': 'Items per page',\n\n // Form validation\n 'validation.required': 'This field is required',\n 'validation.minLength': 'Minimum length is {min} characters',\n 'validation.maxLength': 'Maximum length is {max} characters',\n 'validation.email': 'This is not a valid email address',\n 'validation.range': 'Value must be between {min} and {max}',\n 'validation.format': 'Invalid format',\n\n // Date picker — months\n 'datepicker.months.0': 'January',\n 'datepicker.months.1': 'February',\n 'datepicker.months.2': 'March',\n 'datepicker.months.3': 'April',\n 'datepicker.months.4': 'May',\n 'datepicker.months.5': 'June',\n 'datepicker.months.6': 'July',\n 'datepicker.months.7': 'August',\n 'datepicker.months.8': 'September',\n 'datepicker.months.9': 'October',\n 'datepicker.months.10': 'November',\n 'datepicker.months.11': 'December',\n\n // Date picker — days\n 'datepicker.days.0': 'Sunday',\n 'datepicker.days.1': 'Monday',\n 'datepicker.days.2': 'Tuesday',\n 'datepicker.days.3': 'Wednesday',\n 'datepicker.days.4': 'Thursday',\n 'datepicker.days.5': 'Friday',\n 'datepicker.days.6': 'Saturday',\n\n // Date picker — short days\n 'datepicker.daysShort.0': 'Sun',\n 'datepicker.daysShort.1': 'Mon',\n 'datepicker.daysShort.2': 'Tue',\n 'datepicker.daysShort.3': 'Wed',\n 'datepicker.daysShort.4': 'Thu',\n 'datepicker.daysShort.5': 'Fri',\n 'datepicker.daysShort.6': 'Sat',\n\n // MessageBox\n 'messagebox.alert.title': 'Alert',\n 'messagebox.confirm.title': 'Confirm',\n 'messagebox.prompt.title': 'Prompt',\n\n // Misc\n 'loading': 'Loading...',\n 'error': 'Error',\n },\n});\n","/**\n * @framesquared/core – es-ES locale bundle\n */\n\nimport { Locale } from '../Locale.js';\n\nexport const esES = new Locale({\n language: 'es-ES',\n rtl: false,\n firstDayOfWeek: 1,\n numberFormat: { currency: 'EUR' },\n messages: {\n 'btn.ok': 'Aceptar',\n 'btn.cancel': 'Cancelar',\n 'btn.yes': 'Sí',\n 'btn.no': 'No',\n 'btn.save': 'Guardar',\n 'btn.close': 'Cerrar',\n 'btn.apply': 'Aplicar',\n 'btn.reset': 'Restablecer',\n\n 'grid.noData': 'No hay datos para mostrar',\n 'grid.loading': 'Cargando...',\n 'grid.page': 'Página {page} de {total}',\n 'grid.pageSize': 'Elementos por página',\n\n 'validation.required': 'Este campo es obligatorio',\n 'validation.minLength': 'La longitud mínima es de {min} caracteres',\n 'validation.maxLength': 'La longitud máxima es de {max} caracteres',\n 'validation.email': 'No es una dirección de correo válida',\n 'validation.range': 'El valor debe estar entre {min} y {max}',\n 'validation.format': 'Formato inválido',\n\n 'datepicker.months.0': 'Enero',\n 'datepicker.months.1': 'Febrero',\n 'datepicker.months.2': 'Marzo',\n 'datepicker.months.3': 'Abril',\n 'datepicker.months.4': 'Mayo',\n 'datepicker.months.5': 'Junio',\n 'datepicker.months.6': 'Julio',\n 'datepicker.months.7': 'Agosto',\n 'datepicker.months.8': 'Septiembre',\n 'datepicker.months.9': 'Octubre',\n 'datepicker.months.10': 'Noviembre',\n 'datepicker.months.11': 'Diciembre',\n\n 'datepicker.days.0': 'Domingo',\n 'datepicker.days.1': 'Lunes',\n 'datepicker.days.2': 'Martes',\n 'datepicker.days.3': 'Miércoles',\n 'datepicker.days.4': 'Jueves',\n 'datepicker.days.5': 'Viernes',\n 'datepicker.days.6': 'Sábado',\n\n 'datepicker.daysShort.0': 'Dom',\n 'datepicker.daysShort.1': 'Lun',\n 'datepicker.daysShort.2': 'Mar',\n 'datepicker.daysShort.3': 'Mié',\n 'datepicker.daysShort.4': 'Jue',\n 'datepicker.daysShort.5': 'Vie',\n 'datepicker.daysShort.6': 'Sáb',\n\n 'messagebox.alert.title': 'Alerta',\n 'messagebox.confirm.title': 'Confirmar',\n 'messagebox.prompt.title': 'Aviso',\n\n 'loading': 'Cargando...',\n 'error': 'Error',\n },\n});\n","/**\n * @framesquared/core – ar-SA locale bundle\n */\n\nimport { Locale } from '../Locale.js';\n\nexport const arSA = new Locale({\n language: 'ar-SA',\n rtl: true,\n firstDayOfWeek: 6,\n numberFormat: { currency: 'SAR' },\n messages: {\n 'btn.ok': 'موافق',\n 'btn.cancel': 'إلغاء',\n 'btn.yes': 'نعم',\n 'btn.no': 'لا',\n 'btn.save': 'حفظ',\n 'btn.close': 'إغلاق',\n 'btn.apply': 'تطبيق',\n 'btn.reset': 'إعادة تعيين',\n\n 'grid.noData': 'لا توجد بيانات للعرض',\n 'grid.loading': 'جاري التحميل...',\n 'grid.page': 'صفحة {page} من {total}',\n 'grid.pageSize': 'عناصر في الصفحة',\n\n 'validation.required': 'هذا الحقل مطلوب',\n 'validation.minLength': 'الحد الأدنى للطول هو {min} حرفًا',\n 'validation.maxLength': 'الحد الأقصى للطول هو {max} حرفًا',\n 'validation.email': 'هذا ليس عنوان بريد إلكتروني صالحًا',\n 'validation.range': 'يجب أن تكون القيمة بين {min} و {max}',\n 'validation.format': 'تنسيق غير صالح',\n\n 'datepicker.months.0': 'يناير',\n 'datepicker.months.1': 'فبراير',\n 'datepicker.months.2': 'مارس',\n 'datepicker.months.3': 'أبريل',\n 'datepicker.months.4': 'مايو',\n 'datepicker.months.5': 'يونيو',\n 'datepicker.months.6': 'يوليو',\n 'datepicker.months.7': 'أغسطس',\n 'datepicker.months.8': 'سبتمبر',\n 'datepicker.months.9': 'أكتوبر',\n 'datepicker.months.10': 'نوفمبر',\n 'datepicker.months.11': 'ديسمبر',\n\n 'datepicker.days.0': 'الأحد',\n 'datepicker.days.1': 'الإثنين',\n 'datepicker.days.2': 'الثلاثاء',\n 'datepicker.days.3': 'الأربعاء',\n 'datepicker.days.4': 'الخميس',\n 'datepicker.days.5': 'الجمعة',\n 'datepicker.days.6': 'السبت',\n\n 'datepicker.daysShort.0': 'أحد',\n 'datepicker.daysShort.1': 'إثن',\n 'datepicker.daysShort.2': 'ثلا',\n 'datepicker.daysShort.3': 'أرب',\n 'datepicker.daysShort.4': 'خمي',\n 'datepicker.daysShort.5': 'جمع',\n 'datepicker.daysShort.6': 'سبت',\n\n 'messagebox.alert.title': 'تنبيه',\n 'messagebox.confirm.title': 'تأكيد',\n 'messagebox.prompt.title': 'إدخال',\n\n 'loading': 'جاري التحميل...',\n 'error': 'خطأ',\n },\n});\n","/**\n * @framesquared/core – Sanitizer\n *\n * HTML sanitization utility for safe innerHTML usage.\n * Uses a whitelist approach — only known-safe tags and attributes pass through.\n * No dependencies on DOMPurify; uses the browser's own DOMParser.\n *\n * @example\n * ```typescript\n * import { Sanitizer } from '@framesquared/core';\n *\n * const clean = Sanitizer.sanitize('<p onclick=\"alert(1)\">Hello <b>world</b></p>');\n * // Returns: '<p>Hello <b>world</b></p>'\n * ```\n *\n * @since 0.1.0\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst SAFE_TAGS = new Set([\n 'a', 'abbr', 'b', 'blockquote', 'br', 'caption', 'cite', 'code',\n 'col', 'colgroup', 'dd', 'del', 'details', 'div', 'dl', 'dt', 'em',\n 'figcaption', 'figure', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr',\n 'i', 'img', 'ins', 'kbd', 'label', 'li', 'mark', 'ol', 'p', 'pre',\n 'q', 's', 'samp', 'small', 'span', 'strong', 'sub', 'summary', 'sup',\n 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'time', 'tr', 'u',\n 'ul', 'var', 'wbr',\n]);\n\nconst SAFE_ATTRS = new Set([\n 'align', 'alt', 'class', 'colspan', 'dir', 'height', 'href', 'id',\n 'lang', 'name', 'role', 'rowspan', 'scope', 'src', 'style', 'tabindex',\n 'target', 'title', 'type', 'valign', 'width',\n // ARIA\n 'aria-controls', 'aria-describedby', 'aria-disabled', 'aria-expanded',\n 'aria-haspopup', 'aria-hidden', 'aria-label', 'aria-labelledby',\n 'aria-live', 'aria-modal', 'aria-pressed', 'aria-selected', 'aria-sort',\n]);\n\nconst SAFE_URL_PATTERN = /^(?:https?|mailto|tel|#):/i;\nconst DATA_URL_PATTERN = /^data:image\\/(?:png|gif|jpeg|webp|svg\\+xml);base64,/i;\n\nfunction isUrlSafe(attr: string, value: string): boolean {\n if (attr !== 'href' && attr !== 'src') return true;\n const trimmed = value.trim();\n if (trimmed.startsWith('#') || trimmed.startsWith('/')) return true;\n return SAFE_URL_PATTERN.test(trimmed) || DATA_URL_PATTERN.test(trimmed);\n}\n\nconst DANGEROUS_TAGS = new Set([\n 'script', 'style', 'iframe', 'object', 'embed', 'applet', 'base',\n 'link', 'meta', 'noscript', 'template',\n]);\n\nfunction sanitizeNode(node: Node, doc: Document): Node | null {\n if (node.nodeType === 3) {\n // Text node — always safe\n return doc.createTextNode(node.textContent ?? '');\n }\n\n if (node.nodeType !== 1) return null; // Skip comments, processing instructions, etc.\n\n const el = node as Element;\n const tagName = el.tagName.toLowerCase();\n\n // Dangerous tags — strip entirely including content\n if (DANGEROUS_TAGS.has(tagName)) return null;\n\n if (!SAFE_TAGS.has(tagName)) {\n // Unsafe tag — keep children but remove the tag itself\n const frag = doc.createDocumentFragment();\n for (const child of Array.from(el.childNodes)) {\n const cleaned = sanitizeNode(child, doc);\n if (cleaned) frag.appendChild(cleaned);\n }\n return frag;\n }\n\n // Safe tag — recreate with only safe attributes\n const cleanEl = doc.createElement(tagName);\n\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (!SAFE_ATTRS.has(name)) continue;\n if (name.startsWith('on')) continue; // Block all event handlers\n if (!isUrlSafe(name, attr.value)) continue;\n cleanEl.setAttribute(name, attr.value);\n }\n\n // Recurse into children\n for (const child of Array.from(el.childNodes)) {\n const cleaned = sanitizeNode(child, doc);\n if (cleaned) cleanEl.appendChild(cleaned);\n }\n\n return cleanEl;\n}\n\nexport const Sanitizer = {\n /**\n * Sanitize an HTML string by removing dangerous tags and attributes.\n * Uses a whitelist approach — only known-safe elements pass through.\n *\n * @param html - Raw HTML string\n * @returns Sanitized HTML string safe for innerHTML\n */\n sanitize(html: string): string {\n if (!html) return '';\n // Fast path: no HTML tags at all\n if (!/</.test(html)) return html;\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<body>${html}</body>`, 'text/html');\n const body = doc.body;\n\n const frag = doc.createDocumentFragment();\n for (const child of Array.from(body.childNodes)) {\n const cleaned = sanitizeNode(child, doc);\n if (cleaned) frag.appendChild(cleaned);\n }\n\n const wrapper = doc.createElement('div');\n wrapper.appendChild(frag);\n return wrapper.innerHTML;\n },\n\n /**\n * Escape HTML special characters for safe text insertion.\n *\n * @param text - Raw text\n * @returns Escaped string safe for HTML context\n */\n escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n },\n\n /**\n * Check if an HTML string contains potentially dangerous content.\n *\n * @param html - HTML string to check\n * @returns true if the HTML appears safe\n */\n isSafe(html: string): boolean {\n // Check for script tags, event handlers, javascript: URLs\n const dangerous = /<script|javascript:|on\\w+\\s*=/i;\n return !dangerous.test(html);\n },\n};\n","/**\n * @framesquared/core\n * Class system, events, and utilities\n */\n\nexport const VERSION = '0.0.1';\n\n// General utilities\nexport {\n identity,\n emptyFn,\n applyIf,\n apply,\n clone,\n isObject,\n isString,\n isNumber,\n isBoolean,\n isFunction,\n isArray,\n isDefined,\n isEmpty,\n isIterable,\n isPrimitive,\n namespace,\n defer,\n interval,\n now,\n generateId,\n} from './util/index.js';\n\n// String utilities\nexport {\n capitalize,\n uncapitalize,\n ellipsis,\n escapeHtml,\n unescapeHtml,\n escapeRegex,\n format,\n repeat,\n trim,\n leftPad,\n toggle,\n splitWords,\n camelCase,\n kebabCase,\n pascalCase,\n htmlEncode,\n htmlDecode,\n} from './util/String.js';\n\n// Array utilities\nexport {\n from,\n contains,\n include,\n remove,\n clean,\n unique,\n flatten,\n pluck,\n sum,\n mean,\n min,\n max,\n groupBy,\n partition,\n chunk,\n difference,\n intersection,\n sortBy,\n findBy,\n range,\n} from './util/Array.js';\n\n// Object utilities\nexport {\n keys,\n values,\n entries,\n fromEntries,\n merge,\n pick,\n omit,\n mapValues,\n mapKeys,\n freeze,\n equals,\n getNestedValue,\n setNestedValue,\n flattenObject,\n unflattenObject,\n} from './util/Object.js';\n\n// Function utilities\nexport {\n bind,\n createBuffered,\n createDelayed,\n createThrottled,\n createBarrier,\n interceptBefore,\n interceptAfter,\n createSequence,\n memoize,\n once,\n negate,\n compose,\n pipe,\n} from './util/Function.js';\n\n// Class system\nexport { Base, ClassManager, define } from './class/index.js';\nexport type { ClassDefinition } from './class/index.js';\n\n// Decorators & Configurator\nexport { config, observable, alias, mixin, override, Configurator } from './class/index.js';\nexport type { ConfigMeta } from './class/index.js';\n\n// Mixins\nexport {\n Identifiable,\n IdentityMap,\n Factoryable,\n Inheritable,\n Hookable,\n Pluggable,\n} from './mixin/index.js';\n\n// Plugin\nexport { Plugin } from './Plugin.js';\n\n// Event system\nexport { ExtEvent, Observable, DestroyableUtil, EventDomain, EventBus, EventManager, GestureRecognizer, KeyMap } from './event/index.js';\nexport type { ListenerOptions, Destroyable, ListenerConfig, TypedObservable, EventMap, KeyBinding, KeyMapConfig } from './event/index.js';\n\n// ARIA / Accessibility\nexport { AriaManager } from './aria/AriaManager.js';\nexport { FocusManager } from './aria/FocusManager.js';\n\n// Locale / i18n\nexport { Locale } from './locale/Locale.js';\nexport type { LocaleConfig, NumberFormatOptions } from './locale/Locale.js';\nexport { LocaleManager } from './locale/LocaleManager.js';\nexport { enUS } from './locale/bundles/en-US.js';\nexport { esES } from './locale/bundles/es-ES.js';\nexport { arSA } from './locale/bundles/ar-SA.js';\n\n// Security / Sanitization\nexport { Sanitizer } from './util/Sanitizer.js';\n"],"mappings":"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","names":["keys","values","config","mixin","alias","mixin","isPlainObject","config","alias","config","handler","config","entries","now","config","config"]}
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@framesquared/core",
3
+ "version": "0.1.0",
4
+ "description": "Class system, events, and utilities",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "test": "vitest run",
20
+ "clean": "rm -rf dist",
21
+ "typecheck": "tsc --noEmit --project tsconfig.build.json"
22
+ }
23
+ }