From 27902a7b25eb575cf7bc6ef3f267053d69c4e139 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 03:05:44 +0800 Subject: [PATCH 01/24] feat(ts): add TypeScript typings and type-check tests - Publish .d.ts for core and plugins: es6/jsmind.d.ts, es6/jsmind.draggable-node.d.ts, es6/jsmind.screenshot.d.ts - Add Jest-based type-check (tsc noEmit) at tests/unit/typescript.types.test.js, validating tsconfig.json includes example/typescript-test.ts and es6/*.d.ts - Update package.json to expose types and exports types entries - Add bilingual CHANGELOG.md (2025-08-09) documenting the TS support and testing - Remove temporary TS docs: TYPESCRIPT.md, TYPESCRIPT-INTEGRATION-SUMMARY.md, typescript-integration-progress.md - All tests pass locally (13 suites, 95 tests) --- CHANGELOG.md | 16 ++ es6/jsmind.d.ts | 369 ++++++++++++++++++++++++++++ es6/jsmind.draggable-node.d.ts | 171 +++++++++++++ es6/jsmind.screenshot.d.ts | 133 ++++++++++ example/js/typescript-demo.js | 252 +++++++++++++++++++ example/typescript-example.ts | 119 +++++++++ example/typescript-test.ts | 303 +++++++++++++++++++++++ package-lock.json | 17 +- package.json | 22 +- tests/unit/typescript.types.test.js | 54 ++++ tsconfig.json | 17 ++ 11 files changed, 1468 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 es6/jsmind.d.ts create mode 100644 es6/jsmind.draggable-node.d.ts create mode 100644 es6/jsmind.screenshot.d.ts create mode 100644 example/js/typescript-demo.js create mode 100644 example/typescript-example.ts create mode 100644 example/typescript-test.ts create mode 100644 tests/unit/typescript.types.test.js create mode 100644 tsconfig.json diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..46d9028a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +## Changelog / 变更日志 + +### 2025-08-09 + +- Added / 新增 + - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). + - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). + +- Changed / 调整 + - Updated root `package.json` to expose `types` and proper `exports` fields for typings. + +- Notes / 说明 + - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. + - Running `npm test` will now validate TypeScript definitions. + + diff --git a/es6/jsmind.d.ts b/es6/jsmind.d.ts new file mode 100644 index 00000000..51dc439a --- /dev/null +++ b/es6/jsmind.d.ts @@ -0,0 +1,369 @@ +/** + * TypeScript definitions for jsMind + * @version 0.8.7 + * @author jsMind Community + * @license BSD-3-Clause + */ + +// ============================================================================ +// 基础枚举和常量 +// ============================================================================ + +export interface DirectionType { + left: -1; + center: 0; + right: 1; + of(dir: string | number): number | undefined; +} + +export interface EventTypeEnum { + show: 1; + resize: 2; + edit: 3; + select: 4; +} + +export interface LogLevelEnum { + debug: 1; + info: 2; + warn: 3; + error: 4; + disable: 9; +} + +export interface KeyEnum { + meta: 8192; + ctrl: 4096; + alt: 2048; + shift: 1024; +} + +// ============================================================================ +// 数据格式接口 +// ============================================================================ + +export interface NodeData { + [key: string]: any; +} + +export interface MindMapMeta { + name?: string; + author?: string; + version?: string; +} + +export interface NodeTreeFormat { + meta?: MindMapMeta; + format: 'node_tree'; + data: NodeTreeData; +} + +export interface NodeTreeData { + id: string; + topic: string; + data?: NodeData; + direction?: number; + expanded?: boolean; + children?: NodeTreeData[]; +} + +export interface NodeArrayFormat { + meta?: MindMapMeta; + format: 'node_array'; + data: NodeArrayData[]; +} + +export interface NodeArrayData { + id: string; + topic: string; + parentid?: string; + data?: NodeData; + direction?: number; + expanded?: boolean; + isroot?: boolean; +} + +export type MindMapData = NodeTreeFormat | NodeArrayFormat | string; + +// ============================================================================ +// 配置选项接口 +// ============================================================================ + +export interface ZoomOptions { + min?: number; + max?: number; + step?: number; + mask_key?: number; +} + +export interface ViewOptions { + engine?: 'canvas' | 'svg'; + enable_device_pixel_ratio?: boolean; + hmargin?: number; + vmargin?: number; + line_width?: number; + line_color?: string; + line_style?: 'curved' | 'straight'; + draggable?: boolean; + hide_scrollbars_when_draggable?: boolean; + node_overflow?: 'hidden' | 'wrap'; + zoom?: ZoomOptions; + custom_node_render?: ((jm: jsMind, element: HTMLElement, node: Node) => void) | null; + expander_style?: 'char' | 'number'; +} + +export interface LayoutOptions { + hspace?: number; + vspace?: number; + pspace?: number; + cousin_space?: number; +} + +export interface DefaultEventHandleOptions { + enable_mousedown_handle?: boolean; + enable_click_handle?: boolean; + enable_dblclick_handle?: boolean; + enable_mousewheel_handle?: boolean; +} + +export interface ShortcutMapping { + addchild?: number | number[]; + addbrother?: number | number[]; + editnode?: number | number[]; + delnode?: number | number[]; + toggle?: number | number[]; + left?: number | number[]; + up?: number | number[]; + right?: number | number[]; + down?: number | number[]; + [key: string]: number | number[] | undefined; +} + +export interface ShortcutOptions { + enable?: boolean; + handles?: { [key: string]: () => void }; + mapping?: ShortcutMapping; +} + +export interface PluginOptions { + [pluginName: string]: any; +} + +export interface JsMindOptions { + container: string; + editable?: boolean; + theme?: string | null; + mode?: 'full' | 'side'; + support_html?: boolean; + log_level?: 'debug' | 'info' | 'warn' | 'error' | 'disable'; + view?: ViewOptions; + layout?: LayoutOptions; + default_event_handle?: DefaultEventHandleOptions; + shortcut?: ShortcutOptions; + plugin?: PluginOptions; +} + +// ============================================================================ +// 核心类接口 +// ============================================================================ + +export interface NodeLocation { + x: number; + y: number; +} + +export interface NodeSize { + w: number; + h: number; +} + +export class Node { + id: string; + index: number; + topic: string; + data: NodeData; + isroot: boolean; + parent: Node | null; + direction: number; + expanded: boolean; + children: Node[]; + _data: any; + + constructor( + sId: string, + iIndex: number, + sTopic: string, + oData?: NodeData, + bIsRoot?: boolean, + oParent?: Node | null, + eDirection?: number, + bExpanded?: boolean + ); + + get_location(): NodeLocation; + get_size(): NodeSize; + + static compare(node1: Node, node2: Node): number; + static inherited(parent_node: Node, node: Node): boolean; + static is_node(n: any): n is Node; +} + +export class Mind { + name: string | null; + author: string | null; + version: string | null; + root: Node | null; + selected: Node | null; + nodes: { [id: string]: Node }; + + constructor(); + + get_node(node_id: string): Node | null; + set_root(node_id: string, topic: string, data?: NodeData): Node | null; + add_node( + parent_node: Node, + node_id: string, + topic: string, + data?: NodeData, + direction?: number, + expanded?: boolean, + idx?: number + ): Node | null; + insert_node_before(node_before: Node, node_id: string, topic: string, data?: NodeData): Node | null; + insert_node_after(node_after: Node, node_id: string, topic: string, data?: NodeData): Node | null; + remove_node(node: Node): boolean; + move_node(node: Node, before_id?: string, parent_id?: string, direction?: number): Node | null; +} + +// ============================================================================ +// 工具类接口 +// ============================================================================ + +export interface FileUtil { + read(file_data: File, fn_callback: (result: string, name: string) => void): void; + save(file_data: string, type: string, name: string): void; +} + +export interface JsonUtil { + json2string(json: any): string; + string2json(json_str: string): any; + merge(target: any, source: any): any; +} + +export interface UuidUtil { + newid(): string; +} + +export interface TextUtil { + is_empty(s?: string | null): boolean; +} + +export interface Util { + file: FileUtil; + json: JsonUtil; + uuid: UuidUtil; + text: TextUtil; +} + +export interface Dom { + w: Window; + d: Document; + g(id: string): HTMLElement | null; + c(tag: string): HTMLElement; + t(n: HTMLElement, t: string): void; + h(n: HTMLElement, t: string | HTMLElement): void; + i(el: any): el is HTMLElement; + on(t: HTMLElement, e: string, h: EventListener): void; +} + +// ============================================================================ +// 事件处理接口 +// ============================================================================ + +export interface EventData { + evt?: string; + data?: any[]; + node?: string; +} + +export type EventHandler = (type: number, data: EventData) => void; + +// ============================================================================ +// 主类定义 +// ============================================================================ + +export default class jsMind { + static mind: typeof Mind; + static node: typeof Node; + static direction: DirectionType; + static event_type: EventTypeEnum; + static $: Dom; + static plugin: any; + static register_plugin(plugin_name: string, plugin_init: (jm: jsMind) => void): void; + static util: Util; + static current: jsMind; + + version: string; + options: JsMindOptions; + initialized: boolean; + mind: Mind | null; + event_handles: EventHandler[]; + data: any; + layout: any; + view: any; + shortcut: any; + + constructor(options: JsMindOptions); + + init(): void; + show(mind?: MindMapData, skip_centering?: boolean): void; + get_editable(): boolean; + enable_edit(): void; + disable_edit(): void; + get_view_draggable(): boolean; + enable_view_draggable(): void; + disable_view_draggable(): void; + get_meta(): MindMapMeta; + get_data(data_format?: 'node_tree' | 'node_array' | 'freemind' | 'text'): any; + get_root(): Node | null; + get_node(node: string | Node): Node | null; + add_node(parent_node: Node | string, node_id: string, topic: string, data?: NodeData, direction?: number): Node | null; + insert_node_before(node_before: Node | string, node_id: string, topic: string, data?: NodeData): Node | null; + insert_node_after(node_after: Node | string, node_id: string, topic: string, data?: NodeData): Node | null; + remove_node(node: Node | string): boolean; + update_node(node_id: string, topic: string): void; + move_node(node: Node | string, before_id?: string, parent_id?: string, direction?: number): void; + select_node(node: Node | string): void; + select_clear(): void; + get_selected_node(): Node | null; + is_node_visible(node: Node | string): boolean; + find_node_before(node: Node | string): Node | null; + find_node_after(node: Node | string): Node | null; + set_node_color(node_id: string, bg_color?: string, fg_color?: string): void; + set_node_font_style(node_id: string, size?: number, weight?: string, style?: string): void; + set_node_background_image(node_id: string, image: string, width?: number, height?: number, rotation?: number): void; + set_node_background_rotation(node_id: string, rotation: number): void; + resize(): void; + begin_edit(node?: Node | string): void; + end_edit(): void; + toggle_node(node?: Node | string): void; + expand_node(node: Node | string): void; + collapse_node(node: Node | string): void; + expand_all(): void; + collapse_all(): void; + expand_to_depth(depth: number): void; + scroll_node_to_center(node: Node | string): void; + scroll_node_to_visible(node: Node | string): void; + add_event_listener(event_listener: EventHandler): void; + invoke_event_handle(type: number, data: EventData): void; +} + +// ============================================================================ +// 模块导出 +// ============================================================================ + +export { jsMind }; +export const direction: DirectionType; +export const event_type: EventTypeEnum; +export const $: Dom; +export const util: Util; diff --git a/es6/jsmind.draggable-node.d.ts b/es6/jsmind.draggable-node.d.ts new file mode 100644 index 00000000..281023e4 --- /dev/null +++ b/es6/jsmind.draggable-node.d.ts @@ -0,0 +1,171 @@ +/** + * TypeScript definitions for jsMind draggable-node plugin + * @version 0.4.0 + * @author jsMind Community + * @license BSD-3-Clause + */ + +import jsMind, { Node } from './jsmind'; + +// ============================================================================ +// 插件配置选项接口 +// ============================================================================ + +export interface DraggableNodeOptions { + /** 拖拽线条宽度 */ + line_width?: number; + /** 拖拽线条颜色 */ + line_color?: string; + /** 无效拖拽线条颜色 */ + line_color_invalid?: string; + /** 查找延迟时间(毫秒) */ + lookup_delay?: number; + /** 查找间隔时间(毫秒) */ + lookup_interval?: number; + /** 滚动触发宽度 */ + scrolling_trigger_width?: number; + /** 滚动步长 */ + scrolling_step_length?: number; + /** 阴影节点CSS类名 */ + shadow_node_class_name?: string; +} + +// ============================================================================ +// 插件类定义 +// ============================================================================ + +export class DraggableNode { + version: string; + jm: jsMind; + options: Required; + e_canvas: HTMLCanvasElement | null; + canvas_ctx: CanvasRenderingContext2D | null; + shadow: HTMLElement | null; + shadow_p_x: number; + shadow_p_y: number; + shadow_w: number; + shadow_h: number; + active_node: Node | null; + target_node: Node | null; + target_direct: number | null; + client_w: number; + client_h: number; + offset_x: number; + offset_y: number; + hlookup_delay: number; + hlookup_timer: number; + capture: boolean; + moved: boolean; + canvas_draggable: boolean; + view_panel: HTMLElement; + view_panel_rect: DOMRect | null; + + constructor(jm: jsMind, options?: DraggableNodeOptions); + + /** 初始化插件 */ + init(): void; + + /** 调整大小 */ + resize(): void; + + /** 创建画布 */ + create_canvas(): void; + + /** 创建阴影节点 */ + create_shadow(): void; + + /** 重置阴影节点 */ + reset_shadow(element: HTMLElement): void; + + /** 显示阴影节点 */ + show_shadow(): void; + + /** 隐藏阴影节点 */ + hide_shadow(): void; + + /** 磁性吸附阴影 */ + magnet_shadow(shadow_p: { x: number; y: number }, node_p: { x: number; y: number }, invalid: boolean): void; + + /** 清除线条 */ + clear_lines(): void; + + /** 画布画线 */ + canvas_lineto(x1: number, y1: number, x2: number, y2: number): void; + + /** 绑定事件 */ + event_bind(): void; + + /** 开始拖拽 */ + dragstart(e: MouseEvent | TouchEvent): void; + + /** 拖拽中 */ + drag(e: MouseEvent | TouchEvent): void; + + /** 结束拖拽 */ + dragend(e: MouseEvent | TouchEvent): void; + + /** 查找节点元素 */ + find_node_element(element: HTMLElement): HTMLElement | null; + + /** 获取根节点X坐标 */ + get_root_x(): number; + + /** 查找目标节点 */ + lookup_target_node(): void; + + /** 根据位置查找重叠的节点父级 */ + lookup_overlapping_node_parent(direction: number): Node | null; + + /** 根据位置查找节点父级 */ + lookup_node_parent_by_location(x: number, y: number): Node | null; + + /** 查找最近的节点 */ + lookup_close_node(direction: number): Node; + + /** 检查阴影是否在目标侧 */ + shadow_on_target_side(node: Node, direction: number): boolean; + + /** 阴影到节点左侧的距离 */ + shadow_to_left_of_node(node: Node): number; + + /** 阴影到节点右侧的距离 */ + shadow_to_right_of_node(node: Node): number; + + /** 阴影到节点基线的距离 */ + shadow_to_base_line_of_node(node: Node): number; + + /** 阴影到节点的距离 */ + shadow_to_node(node: Node, dir: number): number; + + /** 计算节点的点位置 */ + calc_point_of_node(node: Node, dir: number): { + sp: { x: number; y: number }; + np: { x: number; y: number }; + }; + + /** 移动节点 */ + move_node(src_node: Node, target_node: Node | null, target_direct: number | null): void; + + /** jsMind事件处理 */ + jm_event_handle(type: number, data: any): void; +} + +// ============================================================================ +// 模块声明扩展 +// ============================================================================ + +declare module './jsmind' { + interface PluginOptions { + draggable_node?: DraggableNodeOptions; + } +} + +// ============================================================================ +// 插件注册 +// ============================================================================ + +/** 拖拽节点插件实例 */ +export const draggable_plugin: any; + +// 自动注册插件到jsMind +export default DraggableNode; diff --git a/es6/jsmind.screenshot.d.ts b/es6/jsmind.screenshot.d.ts new file mode 100644 index 00000000..56aaf44f --- /dev/null +++ b/es6/jsmind.screenshot.d.ts @@ -0,0 +1,133 @@ +/** + * TypeScript definitions for jsMind screenshot plugin + * @version 0.2.0 + * @author jsMind Community + * @license BSD-3-Clause + */ + +import jsMind from './jsmind'; + +// ============================================================================ +// 插件配置选项接口 +// ============================================================================ + +export interface WatermarkOptions { + /** 左侧水印文本 */ + left?: string | Location; + /** 右侧水印文本 */ + right?: string; +} + +export interface ScreenshotOptions { + /** 导出文件名(不包含扩展名) */ + filename?: string | null; + /** 水印配置 */ + watermark?: WatermarkOptions; + /** 背景颜色,'transparent' 表示透明背景 */ + background?: string; +} + +// ============================================================================ +// 插件类定义 +// ============================================================================ + +export class JmScreenshot { + version: string; + jm: jsMind; + options: Required; + dpr: number; + + constructor(jm: jsMind, options?: ScreenshotOptions); + + /** + * 截图并下载 + * 执行完整的截图流程:创建画布 -> 绘制背景 -> 绘制线条 -> 绘制节点 -> 添加水印 -> 下载 -> 清理 + */ + shoot(): void; + + /** + * 创建画布 + * @returns 返回创建的canvas元素 + */ + create_canvas(): HTMLCanvasElement; + + /** + * 清理画布 + * @param c 要清理的canvas元素 + */ + clear(c: HTMLCanvasElement): void; + + /** + * 绘制背景 + * @param ctx 画布上下文 + * @returns Promise,完成后返回画布上下文 + */ + draw_background(ctx: CanvasRenderingContext2D): Promise; + + /** + * 绘制连接线 + * @param ctx 画布上下文 + * @returns Promise,完成后返回画布上下文 + */ + draw_lines(ctx: CanvasRenderingContext2D): Promise; + + /** + * 绘制节点 + * @param ctx 画布上下文 + * @returns Promise,完成后返回画布上下文 + */ + draw_nodes(ctx: CanvasRenderingContext2D): Promise; + + /** + * 绘制水印 + * @param c 画布元素 + * @param ctx 画布上下文 + * @returns 画布上下文 + */ + draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + + /** + * 加载图片 + * @param url 图片URL + * @returns Promise,完成后返回HTMLImageElement + */ + load_image(url: string): Promise; + + /** + * 下载画布内容为PNG文件 + * @param c 画布元素 + */ + download(c: HTMLCanvasElement): void; +} + +// ============================================================================ +// 模块声明扩展 +// ============================================================================ + +declare module './jsmind' { + interface PluginOptions { + screenshot?: ScreenshotOptions; + } + + // 扩展jsMind类,添加screenshot插件方法 + export default interface jsMind { + /** screenshot插件实例 */ + screenshot?: JmScreenshot; + + /** + * 截图方法(由screenshot插件添加) + * 执行截图并下载为PNG文件 + */ + shoot?(): void; + } +} + +// ============================================================================ +// 插件注册 +// ============================================================================ + +/** screenshot插件实例 */ +export const screenshot_plugin: any; + +// 自动注册插件到jsMind +export default JmScreenshot; diff --git a/example/js/typescript-demo.js b/example/js/typescript-demo.js new file mode 100644 index 00000000..03266bec --- /dev/null +++ b/example/js/typescript-demo.js @@ -0,0 +1,252 @@ +/** + * jsMind TypeScript Demo + * 这个文件展示了如何在 TypeScript 中使用 jsMind + * 编译命令: npx tsc example/typescript-demo.ts --outDir example/js --target ES2020 --module ESNext + */ +import jsMind from '../es6/jsmind'; +// 全局变量 +let jm = null; +let isEditMode = false; +// TypeScript 配置选项 - 享受完整的类型检查和智能提示 +const options = { + container: 'jsmind_container', + editable: true, + theme: 'primary', + view: { + engine: 'canvas', + draggable: true, + zoom: { + min: 0.5, + max: 2.0, + step: 0.1 + }, + line_color: '#667eea', + line_width: 2 + }, + layout: { + hspace: 30, + vspace: 20, + pspace: 13 + }, + plugin: { + draggable_node: { + line_width: 5, + line_color: 'rgba(102, 126, 234, 0.6)', + line_color_invalid: 'rgba(220, 53, 69, 0.6)', + lookup_delay: 200 + } + } +}; +// TypeScript 数据格式 - 类型安全的数据定义 +const sampleMindData = { + meta: { + name: 'TypeScript Demo', + author: 'jsMind TypeScript', + version: '1.0' + }, + format: 'node_tree', + data: { + id: 'root', + topic: 'jsMind TypeScript 集成', + children: [ + { + id: 'features', + topic: '🚀 主要特性', + direction: jsMind.direction.right, + expanded: true, + children: [ + { + id: 'type-safety', + topic: '类型安全', + data: { + note: '编译时类型检查', + background: '#e3f2fd' + } + }, + { + id: 'intellisense', + topic: '智能提示', + data: { + note: 'IDE 自动完成', + background: '#f3e5f5' + } + }, + { + id: 'refactoring', + topic: '安全重构', + data: { + note: '重命名和移动', + background: '#e8f5e8' + } + } + ] + }, + { + id: 'benefits', + topic: '💡 开发优势', + direction: jsMind.direction.left, + expanded: true, + children: [ + { + id: 'errors', + topic: '错误预防', + data: { background: '#ff6b6b' } + }, + { + id: 'docs', + topic: '自文档化', + data: { background: '#4ecdc4' } + }, + { + id: 'maintenance', + topic: '易维护性', + data: { background: '#45b7d1' } + } + ] + }, + { + id: 'plugins', + topic: '🔌 插件支持', + direction: jsMind.direction.right, + children: [ + { id: 'draggable', topic: '拖拽节点' }, + { id: 'screenshot', topic: '截图导出' } + ] + } + ] + } +}; +// 初始化函数 - 类型安全的 jsMind 实例创建 +function initJsMind() { + jm = new jsMind(options); + // 事件监听 - TypeScript 提供类型安全的事件处理 + jm.add_event_listener((type, data) => { + let eventName = ''; + switch (type) { + case jsMind.event_type.show: + eventName = '显示'; + break; + case jsMind.event_type.select: + eventName = '选择'; + break; + case jsMind.event_type.edit: + eventName = '编辑'; + break; + case jsMind.event_type.resize: + eventName = '调整大小'; + break; + } + updateStatus(`事件触发: ${eventName} - ${JSON.stringify(data)}`); + }); + updateStatus('jsMind 初始化完成 - TypeScript 类型定义已生效'); +} +// 加载示例数据 +function loadSampleData() { + if (!jm) + initJsMind(); + jm.show(sampleMindData); + updateStatus('示例数据已加载 - 使用了 TypeScript NodeTreeFormat 类型'); +} +// 添加随机节点 - 展示类型安全的 API 调用 +function addRandomNode() { + if (!jm) { + updateStatus('请先加载数据'); + return; + } + const selectedNode = jm.get_selected_node(); + const parentNode = selectedNode || jm.get_root(); + if (parentNode) { + const nodeId = jsMind.util.uuid.newid(); + const topics = ['新想法', '重要提醒', '待办事项', '灵感闪现', '项目计划']; + const topic = topics[Math.floor(Math.random() * topics.length)]; + const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57']; + const color = colors[Math.floor(Math.random() * colors.length)]; + // TypeScript 确保方法调用的类型正确性 + const newNode = jm.add_node(parentNode, nodeId, topic, { + background: color, + created: new Date().toISOString() + }, Math.random() > 0.5 ? jsMind.direction.right : jsMind.direction.left); + if (newNode) { + jm.set_node_color(newNode.id, color, '#ffffff'); + jm.select_node(newNode); + updateStatus(`已添加新节点: ${topic} (ID: ${nodeId})`); + } + } +} +// 切换编辑模式 +function toggleEdit() { + if (!jm) { + updateStatus('请先加载数据'); + return; + } + isEditMode = !isEditMode; + if (isEditMode) { + jm.enable_edit(); + updateStatus('编辑模式已启用 - 双击节点可编辑'); + } + else { + jm.disable_edit(); + updateStatus('编辑模式已禁用'); + } +} +// 展开所有节点 +function expandAll() { + if (!jm) + return; + jm.expand_all(); + updateStatus('所有节点已展开'); +} +// 收起所有节点 +function collapseAll() { + if (!jm) + return; + jm.collapse_all(); + updateStatus('所有节点已收起'); +} +// 清空思维导图 +function clearMindMap() { + if (!jm) + return; + jm.show(); + updateStatus('思维导图已清空'); +} +// 更新状态信息 +function updateStatus(message) { + const statusElement = document.getElementById('status'); + if (statusElement) { + statusElement.textContent = `${new Date().toLocaleTimeString()} - ${message}`; + } +} +// 演示工具函数的使用 +function demonstrateUtilFunctions() { + // UUID 生成 + const nodeId = jsMind.util.uuid.newid(); + console.log('Generated UUID:', nodeId); + // JSON 操作 + const jsonString = jsMind.util.json.json2string(sampleMindData); + const parsedData = jsMind.util.json.string2json(jsonString); + console.log('JSON serialization test passed'); + // 文本工具 + const isEmpty = jsMind.util.text.is_empty(''); + const isNotEmpty = jsMind.util.text.is_empty('hello'); + console.log('Text utility test:', { isEmpty, isNotEmpty }); + // DOM 工具 + const element = jsMind.$.g('jsmind_container'); + if (element) { + console.log('DOM element found:', element.tagName); + } +} +// 导出函数供全局使用 +window.loadSampleData = loadSampleData; +window.addRandomNode = addRandomNode; +window.toggleEdit = toggleEdit; +window.expandAll = expandAll; +window.collapseAll = collapseAll; +window.clearMindMap = clearMindMap; +// 页面加载完成后的初始化 +window.addEventListener('load', () => { + updateStatus('页面加载完成 - TypeScript 类型定义验证成功'); + demonstrateUtilFunctions(); +}); +// 导出主要对象供其他模块使用 +export { jm, options, sampleMindData }; diff --git a/example/typescript-example.ts b/example/typescript-example.ts new file mode 100644 index 00000000..b633ed1c --- /dev/null +++ b/example/typescript-example.ts @@ -0,0 +1,119 @@ +/** + * jsMind TypeScript 使用示例 + * 展示如何在 TypeScript 项目中使用 jsMind + */ + +import jsMind, { JsMindOptions, NodeTreeFormat } from '../es6/jsmind'; + +// 创建配置选项 +const options: JsMindOptions = { + container: 'jsmind_container', + editable: true, + theme: 'primary', + view: { + engine: 'canvas', + draggable: true, + zoom: { + min: 0.5, + max: 2.0, + step: 0.1, + }, + }, + layout: { + hspace: 30, + vspace: 20, + }, +}; + +// 创建思维导图数据 +const mindData: NodeTreeFormat = { + meta: { + name: 'TypeScript Example', + author: 'jsMind User', + version: '1.0', + }, + format: 'node_tree', + data: { + id: 'root', + topic: 'TypeScript Integration', + children: [ + { + id: 'features', + topic: 'Features', + direction: 1, + children: [ + { id: 'types', topic: 'Type Safety' }, + { id: 'intellisense', topic: 'IntelliSense' }, + { id: 'refactoring', topic: 'Safe Refactoring' }, + ], + }, + { + id: 'benefits', + topic: 'Benefits', + direction: -1, + children: [ + { id: 'errors', topic: 'Compile-time Error Detection' }, + { id: 'docs', topic: 'Self-documenting Code' }, + { id: 'maintenance', topic: 'Better Maintainability' }, + ], + }, + ], + }, +}; + +// 创建 jsMind 实例 +const jm = new jsMind(options); + +// 显示思维导图 +jm.show(mindData); + +// 添加事件监听器 +jm.add_event_listener((type, data) => { + switch (type) { + case jsMind.event_type.show: + console.log('Mind map displayed'); + break; + case jsMind.event_type.select: + console.log('Node selected:', data); + break; + case jsMind.event_type.edit: + console.log('Node edited:', data); + break; + } +}); + +// 获取根节点并添加新节点 +const root = jm.get_root(); +if (root) { + const newNode = jm.add_node( + root, + 'new_feature', + 'New Feature', + { + background: '#ff6b6b', + foreground: '#ffffff', + }, + jsMind.direction.right + ); + + if (newNode) { + // 设置节点样式 + jm.set_node_color(newNode.id, '#ff6b6b', '#ffffff'); + jm.set_node_font_style(newNode.id, 14, 'bold'); + + // 选择新节点 + jm.select_node(newNode); + } +} + +// 工具函数使用示例 +const nodeId = jsMind.util.uuid.newid(); +const isEmpty = jsMind.util.text.is_empty(''); +const jsonData = jsMind.util.json.json2string(mindData); + +console.log('Generated node ID:', nodeId); +console.log('Is empty string:', isEmpty); +console.log('JSON data length:', jsonData.length); + +// 导出实例供其他模块使用 +export { jm, options, mindData }; diff --git a/example/typescript-test.ts b/example/typescript-test.ts new file mode 100644 index 00000000..06bcbc90 --- /dev/null +++ b/example/typescript-test.ts @@ -0,0 +1,303 @@ +/** + * TypeScript 类型定义验证测试文件 + * 用于验证 jsMind 的 TypeScript 类型定义是否正确 + */ + +// 导入主库和插件 +import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from '../es6/jsmind'; +// 注意:在实际使用中,插件需要单独导入来注册 +// import './es6/jsmind.draggable-node'; +// import './es6/jsmind.screenshot'; + +// ============================================================================ +// 基础配置测试 +// ============================================================================ + +// 测试基本配置选项 +const basicOptions: JsMindOptions = { + container: 'jsmind_container', + editable: true, + theme: 'orange', + mode: 'full', + support_html: true, + log_level: 'info', +}; + +// 测试完整配置选项 +const fullOptions: JsMindOptions = { + container: 'jsmind_container', + editable: true, + theme: 'greensea', + mode: 'side', + support_html: false, + log_level: 'debug', + view: { + engine: 'canvas', + enable_device_pixel_ratio: true, + hmargin: 120, + vmargin: 60, + line_width: 3, + line_color: '#333', + line_style: 'straight', + draggable: true, + hide_scrollbars_when_draggable: true, + node_overflow: 'wrap', + zoom: { + min: 0.3, + max: 3.0, + step: 0.2, + mask_key: 4096, + }, + custom_node_render: (jm, element, node) => { + element.innerHTML = `${node.topic}`; + }, + expander_style: 'number', + }, + layout: { + hspace: 40, + vspace: 25, + pspace: 15, + cousin_space: 5, + }, + default_event_handle: { + enable_mousedown_handle: true, + enable_click_handle: true, + enable_dblclick_handle: false, + enable_mousewheel_handle: true, + }, + shortcut: { + enable: true, + handles: { + custom_action: () => console.log('Custom action triggered'), + }, + mapping: { + addchild: [45, 4096 + 13], + addbrother: 13, + editnode: 113, + delnode: 46, + toggle: 32, + left: 37, + up: 38, + right: 39, + down: 40, + }, + }, + plugin: { + draggable_node: { + line_width: 6, + line_color: 'rgba(255,0,0,0.5)', + lookup_delay: 300, + }, + screenshot: { + filename: 'my-mindmap', + background: '#ffffff', + watermark: { + left: 'My Company', + right: 'https://example.com', + }, + }, + }, +}; + +// ============================================================================ +// 数据格式测试 +// ============================================================================ + +// 测试节点树格式数据 +const nodeTreeData: NodeTreeFormat = { + meta: { + name: 'Test Mind Map', + author: 'TypeScript Tester', + version: '1.0', + }, + format: 'node_tree', + data: { + id: 'root', + topic: 'Root Topic', + data: { + background: '#ff0000', + foreground: '#ffffff', + }, + children: [ + { + id: 'child1', + topic: 'Child 1', + direction: 1, + expanded: true, + children: [ + { + id: 'grandchild1', + topic: 'Grandchild 1', + data: { note: 'This is a note' }, + }, + ], + }, + { + id: 'child2', + topic: 'Child 2', + direction: -1, + expanded: false, + }, + ], + }, +}; + +// ============================================================================ +// jsMind 实例测试 +// ============================================================================ + +// 创建 jsMind 实例 +const jm = new jsMind(basicOptions); + +// 测试静态属性 +const NodeClass = jsMind.node; +const MindClass = jsMind.mind; +const direction = jsMind.direction; +const eventType = jsMind.event_type; +const domUtil = jsMind.$; +const util = jsMind.util; + +// 测试方向枚举 +const leftDirection: number = direction.left; // -1 +const rightDirection: number = direction.right; // 1 +const centerDirection: number = direction.center; // 0 +const parsedDirection: number | undefined = direction.of('left'); + +// 测试事件类型 +const showEvent: number = eventType.show; +const resizeEvent: number = eventType.resize; + +// ============================================================================ +// API 方法测试 +// ============================================================================ + +// 显示思维导图 +jm.show(nodeTreeData); +jm.show(); // 显示空白思维导图 + +// 获取信息 +const meta = jm.get_meta(); +const data = jm.get_data('node_tree'); +const root = jm.get_root(); + +// 节点操作 +if (root) { + const newNode = jm.add_node(root, 'new_node', 'New Topic', { color: 'blue' }, 1); + if (newNode) { + jm.update_node(newNode.id, 'Updated Topic'); + jm.select_node(newNode); + + const selectedNode = jm.get_selected_node(); + if (selectedNode) { + jm.set_node_color(selectedNode.id, '#ff0000', '#ffffff'); + jm.set_node_font_style(selectedNode.id, 16, 'bold', 'italic'); + } + } +} + +// 编辑操作 +jm.enable_edit(); +const isEditable: boolean = jm.get_editable(); +jm.begin_edit(); +jm.end_edit(); +jm.disable_edit(); + +// 布局操作 +jm.expand_all(); +jm.collapse_all(); +jm.expand_to_depth(2); + +// 视图操作 +jm.enable_view_draggable(); +const isDraggable: boolean = jm.get_view_draggable(); +jm.disable_view_draggable(); +jm.resize(); + +// 事件监听 +jm.add_event_listener((type: number, data: any) => { + console.log(`Event ${type} triggered with data:`, data); +}); + +// ============================================================================ +// Node 类测试 +// ============================================================================ + +// 创建节点实例(通常不直接创建,而是通过 jsMind API) +const testNode = new Node('test_id', 1, 'Test Topic', { custom: 'data' }, false, null, 1, true); + +// 测试节点属性 +const nodeId: string = testNode.id; +const nodeTopic: string = testNode.topic; +const nodeChildren: Node[] = testNode.children; +const isRoot: boolean = testNode.isroot; + +// 测试节点方法 +const location = testNode.get_location(); +const size = testNode.get_size(); + +// 测试静态方法 +const isNodeInstance: boolean = Node.is_node(testNode); +const comparison: number = Node.compare(testNode, testNode); + +// ============================================================================ +// 工具类测试 +// ============================================================================ + +// JSON 工具 +const jsonString: string = util.json.json2string({ test: 'data' }); +const jsonObject: any = util.json.string2json('{"test":"data"}'); +const mergedObject: any = util.json.merge({}, { test: 'data' }); + +// UUID 工具 +const newId: string = util.uuid.newid(); + +// 文本工具 +const isEmpty: boolean = util.text.is_empty(''); +const isNotEmpty: boolean = util.text.is_empty('hello'); + +// 文件工具(需要 File 对象) +// util.file.read(fileObject, (result, name) => { +// console.log(`File ${name} content:`, result); +// }); + +// DOM 工具 +const element = domUtil.g('some_id'); +const newElement = domUtil.c('div'); + +// ============================================================================ +// 类型检查验证 +// ============================================================================ + +// 这些代码应该通过 TypeScript 编译器的类型检查 +function validateTypes() { + // 验证配置选项类型 + const config: JsMindOptions = basicOptions; + + // 验证数据格式类型 + const mindData: MindMapData = nodeTreeData; + + // 验证方法返回类型 + const rootNode: Node | null = jm.get_root(); + const selectedNode: Node | null = jm.get_selected_node(); + + // 验证事件处理器类型 + const eventHandler = (type: number, data: any) => { + if (type === jsMind.event_type.show) { + console.log('Mind map shown'); + } + }; + + return { + config, + mindData, + rootNode, + selectedNode, + eventHandler, + }; +} + +// 导出验证函数供测试使用 +export { validateTypes }; + +console.log('TypeScript 类型定义验证测试完成!'); +console.log('如果此文件能够成功编译,说明类型定义是正确的。'); diff --git a/package-lock.json b/package-lock.json index 2e87ac1b..62c3eede 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "jest-environment-jsdom": "^28.1.0", "prettier": "2.6.2", "rollup": "2.79.2", - "rollup-plugin-cleanup": "^3.2.1" + "rollup-plugin-cleanup": "^3.2.1", + "typescript": "^5.9.2" } }, "node_modules/@ampproject/remapping": { @@ -4455,6 +4456,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz", diff --git a/package.json b/package.json index b3df0bcb..9119d0e3 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,23 @@ "version": "0.8.7", "description": "jsMind is a pure javascript library for mindmap, it base on html5 canvas. jsMind was released under BSD license, you can embed it in any project, if only you observe the license.", "main": "es6/jsmind.js", + "types": "es6/jsmind.d.ts", "exports": { - ".": "./es6/jsmind.js", - "./draggable-node": "./es6/jsmind.draggable-node.js", - "./screenshot": "./es6/jsmind.screenshot.js", + ".": { + "import": "./es6/jsmind.js", + "require": "./es6/jsmind.js", + "types": "./es6/jsmind.d.ts" + }, + "./draggable-node": { + "import": "./es6/jsmind.draggable-node.js", + "require": "./es6/jsmind.draggable-node.js", + "types": "./es6/jsmind.draggable-node.d.ts" + }, + "./screenshot": { + "import": "./es6/jsmind.screenshot.js", + "require": "./es6/jsmind.screenshot.js", + "types": "./es6/jsmind.screenshot.d.ts" + }, "./style/jsmind.css": "./style/jsmind.css" }, "directories": { @@ -45,13 +58,14 @@ } ], "devDependencies": { + "@rollup/plugin-terser": "^0.4.4", "http-server": "^14.1.1", "jest": "^28.1.0", "jest-environment-jsdom": "^28.1.0", "prettier": "2.6.2", "rollup": "2.79.2", "rollup-plugin-cleanup": "^3.2.1", - "@rollup/plugin-terser": "^0.4.4" + "typescript": "^5.9.2" }, "jest": { "verbose": true, diff --git a/tests/unit/typescript.types.test.js b/tests/unit/typescript.types.test.js new file mode 100644 index 00000000..1f8a13be --- /dev/null +++ b/tests/unit/typescript.types.test.js @@ -0,0 +1,54 @@ +/** @jest-environment node */ + +// 使用 TypeScript 编译器 API 执行类型检查,等价于 `tsc --noEmit` +import * as path from 'path'; +import ts from 'typescript'; + +function parseTsConfig(tsconfigPath) { + const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile); + if (configFile.error) { + const message = ts.formatDiagnosticsWithColorAndContext([configFile.error], formatHost()); + throw new Error(`读取 tsconfig 失败:\n${message}`); + } + return ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsconfigPath)); +} + +function formatHost() { + return { + getCanonicalFileName: f => f, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, + }; +} + +describe('TypeScript 类型定义校验', () => { + test('example/typescript-test.ts 应通过类型检查(无诊断错误)', () => { + const projectRoot = process.cwd(); + const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); + + const parsed = parseTsConfig(tsconfigPath); + + // 强制不输出文件(即使 tsconfig 设置了 declaration),仅进行类型检查 + const compilerOptions = { ...parsed.options, noEmit: true }; + + const program = ts.createProgram({ rootNames: parsed.fileNames, options: compilerOptions }); + + const diagnostics = [ + ...program.getConfigFileParsingDiagnostics(), + ...program.getOptionsDiagnostics(), + ...program.getSyntacticDiagnostics(), + ...program.getSemanticDiagnostics(), + ]; + + if (diagnostics.length > 0) { + const message = ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost()); + // 提供清晰的失败输出,便于定位问题 + // eslint-disable-next-line no-console + console.error('\nTypeScript 诊断信息:\n'); + // eslint-disable-next-line no-console + console.error(message); + } + + expect(diagnostics.length).toBe(0); + }); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c5b3083d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "outDir": "./dist", + "rootDir": "./", + "noEmit": true + }, + "include": ["example/typescript-test.ts", "es6/*.d.ts"], + "exclude": ["node_modules", "dist", "tests"] +} From 6902d7572e8cbc94f7e10ab75a3ed93316464ef6 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 12:32:16 +0800 Subject: [PATCH 02/24] refactor(ts): move type definitions to separate types/ directory - Move .d.ts files from es6/ to types/ directory (es6/ is build output) - Update package.json types and exports.types to point to types/ - Update tsconfig.json include and add baseUrl/paths for package name resolution - Update examples to import from package name 'jsmind' instead of relative paths - Remove old .d.ts files from es6/ - All tests pass (13 suites, 95 tests including TypeScript type checking) --- es6/jsmind.screenshot.d.ts | 133 ---------------------- example/typescript-example.ts | 2 +- example/typescript-test.ts | 8 +- package.json | 8 +- tsconfig.json | 10 +- {es6 => types}/jsmind.d.ts | 51 +++++++-- {es6 => types}/jsmind.draggable-node.d.ts | 96 ++-------------- types/jsmind.screenshot.d.ts | 49 ++++++++ 8 files changed, 119 insertions(+), 238 deletions(-) delete mode 100644 es6/jsmind.screenshot.d.ts rename {es6 => types}/jsmind.d.ts (90%) rename {es6 => types}/jsmind.draggable-node.d.ts (54%) create mode 100644 types/jsmind.screenshot.d.ts diff --git a/es6/jsmind.screenshot.d.ts b/es6/jsmind.screenshot.d.ts deleted file mode 100644 index 56aaf44f..00000000 --- a/es6/jsmind.screenshot.d.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * TypeScript definitions for jsMind screenshot plugin - * @version 0.2.0 - * @author jsMind Community - * @license BSD-3-Clause - */ - -import jsMind from './jsmind'; - -// ============================================================================ -// 插件配置选项接口 -// ============================================================================ - -export interface WatermarkOptions { - /** 左侧水印文本 */ - left?: string | Location; - /** 右侧水印文本 */ - right?: string; -} - -export interface ScreenshotOptions { - /** 导出文件名(不包含扩展名) */ - filename?: string | null; - /** 水印配置 */ - watermark?: WatermarkOptions; - /** 背景颜色,'transparent' 表示透明背景 */ - background?: string; -} - -// ============================================================================ -// 插件类定义 -// ============================================================================ - -export class JmScreenshot { - version: string; - jm: jsMind; - options: Required; - dpr: number; - - constructor(jm: jsMind, options?: ScreenshotOptions); - - /** - * 截图并下载 - * 执行完整的截图流程:创建画布 -> 绘制背景 -> 绘制线条 -> 绘制节点 -> 添加水印 -> 下载 -> 清理 - */ - shoot(): void; - - /** - * 创建画布 - * @returns 返回创建的canvas元素 - */ - create_canvas(): HTMLCanvasElement; - - /** - * 清理画布 - * @param c 要清理的canvas元素 - */ - clear(c: HTMLCanvasElement): void; - - /** - * 绘制背景 - * @param ctx 画布上下文 - * @returns Promise,完成后返回画布上下文 - */ - draw_background(ctx: CanvasRenderingContext2D): Promise; - - /** - * 绘制连接线 - * @param ctx 画布上下文 - * @returns Promise,完成后返回画布上下文 - */ - draw_lines(ctx: CanvasRenderingContext2D): Promise; - - /** - * 绘制节点 - * @param ctx 画布上下文 - * @returns Promise,完成后返回画布上下文 - */ - draw_nodes(ctx: CanvasRenderingContext2D): Promise; - - /** - * 绘制水印 - * @param c 画布元素 - * @param ctx 画布上下文 - * @returns 画布上下文 - */ - draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; - - /** - * 加载图片 - * @param url 图片URL - * @returns Promise,完成后返回HTMLImageElement - */ - load_image(url: string): Promise; - - /** - * 下载画布内容为PNG文件 - * @param c 画布元素 - */ - download(c: HTMLCanvasElement): void; -} - -// ============================================================================ -// 模块声明扩展 -// ============================================================================ - -declare module './jsmind' { - interface PluginOptions { - screenshot?: ScreenshotOptions; - } - - // 扩展jsMind类,添加screenshot插件方法 - export default interface jsMind { - /** screenshot插件实例 */ - screenshot?: JmScreenshot; - - /** - * 截图方法(由screenshot插件添加) - * 执行截图并下载为PNG文件 - */ - shoot?(): void; - } -} - -// ============================================================================ -// 插件注册 -// ============================================================================ - -/** screenshot插件实例 */ -export const screenshot_plugin: any; - -// 自动注册插件到jsMind -export default JmScreenshot; diff --git a/example/typescript-example.ts b/example/typescript-example.ts index b633ed1c..f889c789 100644 --- a/example/typescript-example.ts +++ b/example/typescript-example.ts @@ -3,7 +3,7 @@ * 展示如何在 TypeScript 项目中使用 jsMind */ -import jsMind, { JsMindOptions, NodeTreeFormat } from '../es6/jsmind'; +import jsMind, { JsMindOptions, NodeTreeFormat } from 'jsmind'; // 创建配置选项 const options: JsMindOptions = { diff --git a/example/typescript-test.ts b/example/typescript-test.ts index 06bcbc90..f803398d 100644 --- a/example/typescript-test.ts +++ b/example/typescript-test.ts @@ -3,11 +3,11 @@ * 用于验证 jsMind 的 TypeScript 类型定义是否正确 */ -// 导入主库和插件 -import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from '../es6/jsmind'; +// 导入主库(通过包名解析到 types/) +import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from 'jsmind'; // 注意:在实际使用中,插件需要单独导入来注册 -// import './es6/jsmind.draggable-node'; -// import './es6/jsmind.screenshot'; +// import 'jsmind/draggable-node'; +// import 'jsmind/screenshot'; // ============================================================================ // 基础配置测试 diff --git a/package.json b/package.json index 9119d0e3..b0ada48e 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,22 @@ "version": "0.8.7", "description": "jsMind is a pure javascript library for mindmap, it base on html5 canvas. jsMind was released under BSD license, you can embed it in any project, if only you observe the license.", "main": "es6/jsmind.js", - "types": "es6/jsmind.d.ts", + "types": "types/jsmind.d.ts", "exports": { ".": { "import": "./es6/jsmind.js", "require": "./es6/jsmind.js", - "types": "./es6/jsmind.d.ts" + "types": "./types/jsmind.d.ts" }, "./draggable-node": { "import": "./es6/jsmind.draggable-node.js", "require": "./es6/jsmind.draggable-node.js", - "types": "./es6/jsmind.draggable-node.d.ts" + "types": "./types/jsmind.draggable-node.d.ts" }, "./screenshot": { "import": "./es6/jsmind.screenshot.js", "require": "./es6/jsmind.screenshot.js", - "types": "./es6/jsmind.screenshot.d.ts" + "types": "./types/jsmind.screenshot.d.ts" }, "./style/jsmind.css": "./style/jsmind.css" }, diff --git a/tsconfig.json b/tsconfig.json index c5b3083d..a8e68274 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,8 +10,14 @@ "declaration": true, "outDir": "./dist", "rootDir": "./", - "noEmit": true + "noEmit": true, + "baseUrl": ".", + "paths": { + "jsmind": ["types/jsmind.d.ts"], + "jsmind/draggable-node": ["types/jsmind.draggable-node.d.ts"], + "jsmind/screenshot": ["types/jsmind.screenshot.d.ts"] + } }, - "include": ["example/typescript-test.ts", "es6/*.d.ts"], + "include": ["example/typescript-test.ts", "example/typescript-example.ts", "types/*.d.ts"], "exclude": ["node_modules", "dist", "tests"] } diff --git a/es6/jsmind.d.ts b/types/jsmind.d.ts similarity index 90% rename from es6/jsmind.d.ts rename to types/jsmind.d.ts index 51dc439a..b89072b2 100644 --- a/es6/jsmind.d.ts +++ b/types/jsmind.d.ts @@ -229,8 +229,18 @@ export class Mind { expanded?: boolean, idx?: number ): Node | null; - insert_node_before(node_before: Node, node_id: string, topic: string, data?: NodeData): Node | null; - insert_node_after(node_after: Node, node_id: string, topic: string, data?: NodeData): Node | null; + insert_node_before( + node_before: Node, + node_id: string, + topic: string, + data?: NodeData + ): Node | null; + insert_node_after( + node_after: Node, + node_id: string, + topic: string, + data?: NodeData + ): Node | null; remove_node(node: Node): boolean; move_node(node: Node, before_id?: string, parent_id?: string, direction?: number): Node | null; } @@ -327,12 +337,33 @@ export default class jsMind { get_data(data_format?: 'node_tree' | 'node_array' | 'freemind' | 'text'): any; get_root(): Node | null; get_node(node: string | Node): Node | null; - add_node(parent_node: Node | string, node_id: string, topic: string, data?: NodeData, direction?: number): Node | null; - insert_node_before(node_before: Node | string, node_id: string, topic: string, data?: NodeData): Node | null; - insert_node_after(node_after: Node | string, node_id: string, topic: string, data?: NodeData): Node | null; + add_node( + parent_node: Node | string, + node_id: string, + topic: string, + data?: NodeData, + direction?: number + ): Node | null; + insert_node_before( + node_before: Node | string, + node_id: string, + topic: string, + data?: NodeData + ): Node | null; + insert_node_after( + node_after: Node | string, + node_id: string, + topic: string, + data?: NodeData + ): Node | null; remove_node(node: Node | string): boolean; update_node(node_id: string, topic: string): void; - move_node(node: Node | string, before_id?: string, parent_id?: string, direction?: number): void; + move_node( + node: Node | string, + before_id?: string, + parent_id?: string, + direction?: number + ): void; select_node(node: Node | string): void; select_clear(): void; get_selected_node(): Node | null; @@ -341,7 +372,13 @@ export default class jsMind { find_node_after(node: Node | string): Node | null; set_node_color(node_id: string, bg_color?: string, fg_color?: string): void; set_node_font_style(node_id: string, size?: number, weight?: string, style?: string): void; - set_node_background_image(node_id: string, image: string, width?: number, height?: number, rotation?: number): void; + set_node_background_image( + node_id: string, + image: string, + width?: number, + height?: number, + rotation?: number + ): void; set_node_background_rotation(node_id: string, rotation: number): void; resize(): void; begin_edit(node?: Node | string): void; diff --git a/es6/jsmind.draggable-node.d.ts b/types/jsmind.draggable-node.d.ts similarity index 54% rename from es6/jsmind.draggable-node.d.ts rename to types/jsmind.draggable-node.d.ts index 281023e4..0c1fe269 100644 --- a/es6/jsmind.draggable-node.d.ts +++ b/types/jsmind.draggable-node.d.ts @@ -1,39 +1,21 @@ /** * TypeScript definitions for jsMind draggable-node plugin * @version 0.4.0 - * @author jsMind Community - * @license BSD-3-Clause */ import jsMind, { Node } from './jsmind'; -// ============================================================================ -// 插件配置选项接口 -// ============================================================================ - export interface DraggableNodeOptions { - /** 拖拽线条宽度 */ line_width?: number; - /** 拖拽线条颜色 */ line_color?: string; - /** 无效拖拽线条颜色 */ line_color_invalid?: string; - /** 查找延迟时间(毫秒) */ lookup_delay?: number; - /** 查找间隔时间(毫秒) */ lookup_interval?: number; - /** 滚动触发宽度 */ scrolling_trigger_width?: number; - /** 滚动步长 */ scrolling_step_length?: number; - /** 阴影节点CSS类名 */ shadow_node_class_name?: string; } -// ============================================================================ -// 插件类定义 -// ============================================================================ - export class DraggableNode { version: string; jm: jsMind; @@ -61,111 +43,51 @@ export class DraggableNode { view_panel_rect: DOMRect | null; constructor(jm: jsMind, options?: DraggableNodeOptions); - - /** 初始化插件 */ init(): void; - - /** 调整大小 */ resize(): void; - - /** 创建画布 */ create_canvas(): void; - - /** 创建阴影节点 */ create_shadow(): void; - - /** 重置阴影节点 */ reset_shadow(element: HTMLElement): void; - - /** 显示阴影节点 */ show_shadow(): void; - - /** 隐藏阴影节点 */ hide_shadow(): void; - - /** 磁性吸附阴影 */ - magnet_shadow(shadow_p: { x: number; y: number }, node_p: { x: number; y: number }, invalid: boolean): void; - - /** 清除线条 */ + magnet_shadow( + shadow_p: { x: number; y: number }, + node_p: { x: number; y: number }, + invalid: boolean + ): void; clear_lines(): void; - - /** 画布画线 */ canvas_lineto(x1: number, y1: number, x2: number, y2: number): void; - - /** 绑定事件 */ event_bind(): void; - - /** 开始拖拽 */ dragstart(e: MouseEvent | TouchEvent): void; - - /** 拖拽中 */ drag(e: MouseEvent | TouchEvent): void; - - /** 结束拖拽 */ dragend(e: MouseEvent | TouchEvent): void; - - /** 查找节点元素 */ find_node_element(element: HTMLElement): HTMLElement | null; - - /** 获取根节点X坐标 */ get_root_x(): number; - - /** 查找目标节点 */ lookup_target_node(): void; - - /** 根据位置查找重叠的节点父级 */ lookup_overlapping_node_parent(direction: number): Node | null; - - /** 根据位置查找节点父级 */ lookup_node_parent_by_location(x: number, y: number): Node | null; - - /** 查找最近的节点 */ lookup_close_node(direction: number): Node; - - /** 检查阴影是否在目标侧 */ shadow_on_target_side(node: Node, direction: number): boolean; - - /** 阴影到节点左侧的距离 */ shadow_to_left_of_node(node: Node): number; - - /** 阴影到节点右侧的距离 */ shadow_to_right_of_node(node: Node): number; - - /** 阴影到节点基线的距离 */ shadow_to_base_line_of_node(node: Node): number; - - /** 阴影到节点的距离 */ shadow_to_node(node: Node, dir: number): number; - - /** 计算节点的点位置 */ - calc_point_of_node(node: Node, dir: number): { + calc_point_of_node( + node: Node, + dir: number + ): { sp: { x: number; y: number }; np: { x: number; y: number }; }; - - /** 移动节点 */ move_node(src_node: Node, target_node: Node | null, target_direct: number | null): void; - - /** jsMind事件处理 */ jm_event_handle(type: number, data: any): void; } -// ============================================================================ -// 模块声明扩展 -// ============================================================================ - declare module './jsmind' { interface PluginOptions { draggable_node?: DraggableNodeOptions; } } -// ============================================================================ -// 插件注册 -// ============================================================================ - -/** 拖拽节点插件实例 */ export const draggable_plugin: any; - -// 自动注册插件到jsMind export default DraggableNode; diff --git a/types/jsmind.screenshot.d.ts b/types/jsmind.screenshot.d.ts new file mode 100644 index 00000000..f44039e1 --- /dev/null +++ b/types/jsmind.screenshot.d.ts @@ -0,0 +1,49 @@ +/** + * TypeScript definitions for jsMind screenshot plugin + * @version 0.2.0 + */ + +import jsMind from './jsmind'; + +export interface WatermarkOptions { + left?: string | Location; + right?: string; +} + +export interface ScreenshotOptions { + filename?: string | null; + watermark?: WatermarkOptions; + background?: string; +} + +export class JmScreenshot { + version: string; + jm: jsMind; + options: Required; + dpr: number; + + constructor(jm: jsMind, options?: ScreenshotOptions); + shoot(): void; + create_canvas(): HTMLCanvasElement; + clear(c: HTMLCanvasElement): void; + draw_background(ctx: CanvasRenderingContext2D): Promise; + draw_lines(ctx: CanvasRenderingContext2D): Promise; + draw_nodes(ctx: CanvasRenderingContext2D): Promise; + draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + load_image(url: string): Promise; + download(c: HTMLCanvasElement): void; +} + +declare module './jsmind' { + interface PluginOptions { + screenshot?: ScreenshotOptions; + } + + export default interface jsMind { + screenshot?: JmScreenshot; + shoot?(): void; + } +} + +export const screenshot_plugin: any; +export default JmScreenshot; From 7a9362832e3c68f3741f62cd0522e9903d76c9a3 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 12:48:42 +0800 Subject: [PATCH 03/24] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20jsmind.screen?= =?UTF-8?q?shot.d.ts=20=E4=B8=AD=E7=9A=84=E6=A8=A1=E5=9D=97=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将错误的 'export default interface jsMind' 改为正确的 'interface jsMind' - 解决 VSCode 中显示 jsMind 有两处定义的问题 - 使用正确的接口合并语法进行类型扩展 --- types/jsmind.screenshot.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/jsmind.screenshot.d.ts b/types/jsmind.screenshot.d.ts index f44039e1..fe835092 100644 --- a/types/jsmind.screenshot.d.ts +++ b/types/jsmind.screenshot.d.ts @@ -39,7 +39,7 @@ declare module './jsmind' { screenshot?: ScreenshotOptions; } - export default interface jsMind { + interface jsMind { screenshot?: JmScreenshot; shoot?(): void; } From f1a789cb15f83443f78daa838ec35bffc69def1a Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 19:58:02 +0800 Subject: [PATCH 04/24] fix: run prettier lint --- CHANGELOG.md | 16 +++---- example/js/typescript-demo.js | 79 ++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46d9028a..6b3b666a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,15 @@ ### 2025-08-09 -- Added / 新增 - - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). - - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). +- Added / 新增 -- Changed / 调整 - - Updated root `package.json` to expose `types` and proper `exports` fields for typings. + - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). + - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). -- Notes / 说明 - - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. - - Running `npm test` will now validate TypeScript definitions. +- Changed / 调整 + - Updated root `package.json` to expose `types` and proper `exports` fields for typings. +- Notes / 说明 + - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. + - Running `npm test` will now validate TypeScript definitions. diff --git a/example/js/typescript-demo.js b/example/js/typescript-demo.js index 03266bec..1b3306b7 100644 --- a/example/js/typescript-demo.js +++ b/example/js/typescript-demo.js @@ -18,31 +18,31 @@ const options = { zoom: { min: 0.5, max: 2.0, - step: 0.1 + step: 0.1, }, line_color: '#667eea', - line_width: 2 + line_width: 2, }, layout: { hspace: 30, vspace: 20, - pspace: 13 + pspace: 13, }, plugin: { draggable_node: { line_width: 5, line_color: 'rgba(102, 126, 234, 0.6)', line_color_invalid: 'rgba(220, 53, 69, 0.6)', - lookup_delay: 200 - } - } + lookup_delay: 200, + }, + }, }; // TypeScript 数据格式 - 类型安全的数据定义 const sampleMindData = { meta: { name: 'TypeScript Demo', author: 'jsMind TypeScript', - version: '1.0' + version: '1.0', }, format: 'node_tree', data: { @@ -60,26 +60,26 @@ const sampleMindData = { topic: '类型安全', data: { note: '编译时类型检查', - background: '#e3f2fd' - } + background: '#e3f2fd', + }, }, { id: 'intellisense', topic: '智能提示', data: { note: 'IDE 自动完成', - background: '#f3e5f5' - } + background: '#f3e5f5', + }, }, { id: 'refactoring', topic: '安全重构', data: { note: '重命名和移动', - background: '#e8f5e8' - } - } - ] + background: '#e8f5e8', + }, + }, + ], }, { id: 'benefits', @@ -90,19 +90,19 @@ const sampleMindData = { { id: 'errors', topic: '错误预防', - data: { background: '#ff6b6b' } + data: { background: '#ff6b6b' }, }, { id: 'docs', topic: '自文档化', - data: { background: '#4ecdc4' } + data: { background: '#4ecdc4' }, }, { id: 'maintenance', topic: '易维护性', - data: { background: '#45b7d1' } - } - ] + data: { background: '#45b7d1' }, + }, + ], }, { id: 'plugins', @@ -110,11 +110,11 @@ const sampleMindData = { direction: jsMind.direction.right, children: [ { id: 'draggable', topic: '拖拽节点' }, - { id: 'screenshot', topic: '截图导出' } - ] - } - ] - } + { id: 'screenshot', topic: '截图导出' }, + ], + }, + ], + }, }; // 初始化函数 - 类型安全的 jsMind 实例创建 function initJsMind() { @@ -142,8 +142,7 @@ function initJsMind() { } // 加载示例数据 function loadSampleData() { - if (!jm) - initJsMind(); + if (!jm) initJsMind(); jm.show(sampleMindData); updateStatus('示例数据已加载 - 使用了 TypeScript NodeTreeFormat 类型'); } @@ -162,10 +161,16 @@ function addRandomNode() { const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57']; const color = colors[Math.floor(Math.random() * colors.length)]; // TypeScript 确保方法调用的类型正确性 - const newNode = jm.add_node(parentNode, nodeId, topic, { - background: color, - created: new Date().toISOString() - }, Math.random() > 0.5 ? jsMind.direction.right : jsMind.direction.left); + const newNode = jm.add_node( + parentNode, + nodeId, + topic, + { + background: color, + created: new Date().toISOString(), + }, + Math.random() > 0.5 ? jsMind.direction.right : jsMind.direction.left + ); if (newNode) { jm.set_node_color(newNode.id, color, '#ffffff'); jm.select_node(newNode); @@ -183,30 +188,26 @@ function toggleEdit() { if (isEditMode) { jm.enable_edit(); updateStatus('编辑模式已启用 - 双击节点可编辑'); - } - else { + } else { jm.disable_edit(); updateStatus('编辑模式已禁用'); } } // 展开所有节点 function expandAll() { - if (!jm) - return; + if (!jm) return; jm.expand_all(); updateStatus('所有节点已展开'); } // 收起所有节点 function collapseAll() { - if (!jm) - return; + if (!jm) return; jm.collapse_all(); updateStatus('所有节点已收起'); } // 清空思维导图 function clearMindMap() { - if (!jm) - return; + if (!jm) return; jm.show(); updateStatus('思维导图已清空'); } From 3570508b4312893354637fbaac119ffc9096159c Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 21:19:45 +0800 Subject: [PATCH 05/24] refactor(typings): use package-name module augmentation and English comments\n\n- switch declare module target from './jsmind' to 'jsmind' for plugins\n- convert test descriptions and comments to English per review\n- slim tsconfig include to typings + typescript-test only\n- keep example/typescript-test.ts for type-check coverage (no runtime) --- example/typescript-test.ts | 84 ++++++++++++++--------------- tests/unit/typescript.types.test.js | 14 ++--- tsconfig.json | 5 +- types/jsmind.draggable-node.d.ts | 2 +- types/jsmind.screenshot.d.ts | 2 +- 5 files changed, 55 insertions(+), 52 deletions(-) diff --git a/example/typescript-test.ts b/example/typescript-test.ts index f803398d..c4feb615 100644 --- a/example/typescript-test.ts +++ b/example/typescript-test.ts @@ -1,19 +1,19 @@ /** - * TypeScript 类型定义验证测试文件 - * 用于验证 jsMind 的 TypeScript 类型定义是否正确 + * TypeScript typings validation example + * This file exercises jsMind's public API for type-checking purposes only. */ -// 导入主库(通过包名解析到 types/) +// Import core library (resolved via package name to types/) import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from 'jsmind'; -// 注意:在实际使用中,插件需要单独导入来注册 +// Note: in real usage, plugins should be imported to register themselves // import 'jsmind/draggable-node'; // import 'jsmind/screenshot'; // ============================================================================ -// 基础配置测试 +// Basic options // ============================================================================ -// 测试基本配置选项 +// Minimal options const basicOptions: JsMindOptions = { container: 'jsmind_container', editable: true, @@ -23,7 +23,7 @@ const basicOptions: JsMindOptions = { log_level: 'info', }; -// 测试完整配置选项 +// Full options const fullOptions: JsMindOptions = { container: 'jsmind_container', editable: true, @@ -100,10 +100,10 @@ const fullOptions: JsMindOptions = { }; // ============================================================================ -// 数据格式测试 +// Data formats // ============================================================================ -// 测试节点树格式数据 +// NodeTreeFormat specimen const nodeTreeData: NodeTreeFormat = { meta: { name: 'Test Mind Map', @@ -143,13 +143,13 @@ const nodeTreeData: NodeTreeFormat = { }; // ============================================================================ -// jsMind 实例测试 +// jsMind instance // ============================================================================ -// 创建 jsMind 实例 +// Create jsMind instance const jm = new jsMind(basicOptions); -// 测试静态属性 +// Static members const NodeClass = jsMind.node; const MindClass = jsMind.mind; const direction = jsMind.direction; @@ -157,30 +157,30 @@ const eventType = jsMind.event_type; const domUtil = jsMind.$; const util = jsMind.util; -// 测试方向枚举 +// Direction enum const leftDirection: number = direction.left; // -1 const rightDirection: number = direction.right; // 1 const centerDirection: number = direction.center; // 0 const parsedDirection: number | undefined = direction.of('left'); -// 测试事件类型 +// Event types const showEvent: number = eventType.show; const resizeEvent: number = eventType.resize; // ============================================================================ -// API 方法测试 +// API methods // ============================================================================ -// 显示思维导图 +// Show mind map jm.show(nodeTreeData); jm.show(); // 显示空白思维导图 -// 获取信息 +// Query state const meta = jm.get_meta(); const data = jm.get_data('node_tree'); const root = jm.get_root(); -// 节点操作 +// Node operations if (root) { const newNode = jm.add_node(root, 'new_node', 'New Topic', { color: 'blue' }, 1); if (newNode) { @@ -195,92 +195,92 @@ if (root) { } } -// 编辑操作 +// Edit operations jm.enable_edit(); const isEditable: boolean = jm.get_editable(); jm.begin_edit(); jm.end_edit(); jm.disable_edit(); -// 布局操作 +// Layout operations jm.expand_all(); jm.collapse_all(); jm.expand_to_depth(2); -// 视图操作 +// View operations jm.enable_view_draggable(); const isDraggable: boolean = jm.get_view_draggable(); jm.disable_view_draggable(); jm.resize(); -// 事件监听 +// Event listener jm.add_event_listener((type: number, data: any) => { console.log(`Event ${type} triggered with data:`, data); }); // ============================================================================ -// Node 类测试 +// Node class // ============================================================================ -// 创建节点实例(通常不直接创建,而是通过 jsMind API) +// Create node instance (normally created via API) const testNode = new Node('test_id', 1, 'Test Topic', { custom: 'data' }, false, null, 1, true); -// 测试节点属性 +// Node fields const nodeId: string = testNode.id; const nodeTopic: string = testNode.topic; const nodeChildren: Node[] = testNode.children; const isRoot: boolean = testNode.isroot; -// 测试节点方法 +// Node methods const location = testNode.get_location(); const size = testNode.get_size(); -// 测试静态方法 +// Static helpers const isNodeInstance: boolean = Node.is_node(testNode); const comparison: number = Node.compare(testNode, testNode); // ============================================================================ -// 工具类测试 +// Utils // ============================================================================ -// JSON 工具 +// JSON utils const jsonString: string = util.json.json2string({ test: 'data' }); const jsonObject: any = util.json.string2json('{"test":"data"}'); const mergedObject: any = util.json.merge({}, { test: 'data' }); -// UUID 工具 +// UUID utils const newId: string = util.uuid.newid(); -// 文本工具 +// Text utils const isEmpty: boolean = util.text.is_empty(''); const isNotEmpty: boolean = util.text.is_empty('hello'); -// 文件工具(需要 File 对象) +// File utils (would require a File object) // util.file.read(fileObject, (result, name) => { // console.log(`File ${name} content:`, result); // }); -// DOM 工具 +// DOM utils const element = domUtil.g('some_id'); const newElement = domUtil.c('div'); // ============================================================================ -// 类型检查验证 +// Type validation // ============================================================================ -// 这些代码应该通过 TypeScript 编译器的类型检查 +// The code below should pass the TS compiler type-check function validateTypes() { - // 验证配置选项类型 + // Validate option types const config: JsMindOptions = basicOptions; - // 验证数据格式类型 + // Validate data format types const mindData: MindMapData = nodeTreeData; - // 验证方法返回类型 + // Validate return types const rootNode: Node | null = jm.get_root(); const selectedNode: Node | null = jm.get_selected_node(); - // 验证事件处理器类型 + // Validate event handler shape const eventHandler = (type: number, data: any) => { if (type === jsMind.event_type.show) { console.log('Mind map shown'); @@ -296,8 +296,8 @@ function validateTypes() { }; } -// 导出验证函数供测试使用 +// Export for the Jest runner to import if needed export { validateTypes }; -console.log('TypeScript 类型定义验证测试完成!'); -console.log('如果此文件能够成功编译,说明类型定义是正确的。'); +console.log('TypeScript typings validation example done.'); +console.log('If this file compiles, typings are consistent.'); diff --git a/tests/unit/typescript.types.test.js b/tests/unit/typescript.types.test.js index 1f8a13be..0c0185d7 100644 --- a/tests/unit/typescript.types.test.js +++ b/tests/unit/typescript.types.test.js @@ -1,6 +1,6 @@ /** @jest-environment node */ -// 使用 TypeScript 编译器 API 执行类型检查,等价于 `tsc --noEmit` +// Run type-check using TypeScript Compiler API, equivalent to `tsc --noEmit` import * as path from 'path'; import ts from 'typescript'; @@ -8,7 +8,7 @@ function parseTsConfig(tsconfigPath) { const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile); if (configFile.error) { const message = ts.formatDiagnosticsWithColorAndContext([configFile.error], formatHost()); - throw new Error(`读取 tsconfig 失败:\n${message}`); + throw new Error(`Failed to read tsconfig:\n${message}`); } return ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsconfigPath)); } @@ -21,14 +21,14 @@ function formatHost() { }; } -describe('TypeScript 类型定义校验', () => { - test('example/typescript-test.ts 应通过类型检查(无诊断错误)', () => { +describe('TypeScript typings validation', () => { + test('example/typescript-test.ts should pass type-check (no diagnostics)', () => { const projectRoot = process.cwd(); const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); const parsed = parseTsConfig(tsconfigPath); - // 强制不输出文件(即使 tsconfig 设置了 declaration),仅进行类型检查 + // Force no output (even if `declaration` is on); only type-check const compilerOptions = { ...parsed.options, noEmit: true }; const program = ts.createProgram({ rootNames: parsed.fileNames, options: compilerOptions }); @@ -42,9 +42,9 @@ describe('TypeScript 类型定义校验', () => { if (diagnostics.length > 0) { const message = ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost()); - // 提供清晰的失败输出,便于定位问题 + // Provide detailed diagnostics for debugging // eslint-disable-next-line no-console - console.error('\nTypeScript 诊断信息:\n'); + console.error('\nTypeScript diagnostics:\n'); // eslint-disable-next-line no-console console.error(message); } diff --git a/tsconfig.json b/tsconfig.json index a8e68274..55fc12f2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,9 @@ "jsmind/screenshot": ["types/jsmind.screenshot.d.ts"] } }, - "include": ["example/typescript-test.ts", "example/typescript-example.ts", "types/*.d.ts"], + "include": [ + "types/*.d.ts", + "example/typescript-test.ts" + ], "exclude": ["node_modules", "dist", "tests"] } diff --git a/types/jsmind.draggable-node.d.ts b/types/jsmind.draggable-node.d.ts index 0c1fe269..1012ab97 100644 --- a/types/jsmind.draggable-node.d.ts +++ b/types/jsmind.draggable-node.d.ts @@ -83,7 +83,7 @@ export class DraggableNode { jm_event_handle(type: number, data: any): void; } -declare module './jsmind' { +declare module 'jsmind' { interface PluginOptions { draggable_node?: DraggableNodeOptions; } diff --git a/types/jsmind.screenshot.d.ts b/types/jsmind.screenshot.d.ts index fe835092..d1f5cd9b 100644 --- a/types/jsmind.screenshot.d.ts +++ b/types/jsmind.screenshot.d.ts @@ -34,7 +34,7 @@ export class JmScreenshot { download(c: HTMLCanvasElement): void; } -declare module './jsmind' { +declare module 'jsmind' { interface PluginOptions { screenshot?: ScreenshotOptions; } From dd37dbb42b608a42de50c6998d283a3a4f2f9c84 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 21:24:41 +0800 Subject: [PATCH 06/24] chore(types): move TS type-check fixture to tests/fixtures and drop unused examples\n\n- move example/typescript-test.ts -> tests/fixtures/typescript-test.ts\n- remove example/js/typescript-demo.js and example/typescript-example.ts (no HTML)\n- update tsconfig include to point to fixtures --- example/js/typescript-demo.js | 253 ------------------ example/typescript-example.ts | 119 -------- .../fixtures}/typescript-test.ts | 0 tsconfig.json | 7 +- 4 files changed, 5 insertions(+), 374 deletions(-) delete mode 100644 example/js/typescript-demo.js delete mode 100644 example/typescript-example.ts rename {example => tests/fixtures}/typescript-test.ts (100%) diff --git a/example/js/typescript-demo.js b/example/js/typescript-demo.js deleted file mode 100644 index 1b3306b7..00000000 --- a/example/js/typescript-demo.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * jsMind TypeScript Demo - * 这个文件展示了如何在 TypeScript 中使用 jsMind - * 编译命令: npx tsc example/typescript-demo.ts --outDir example/js --target ES2020 --module ESNext - */ -import jsMind from '../es6/jsmind'; -// 全局变量 -let jm = null; -let isEditMode = false; -// TypeScript 配置选项 - 享受完整的类型检查和智能提示 -const options = { - container: 'jsmind_container', - editable: true, - theme: 'primary', - view: { - engine: 'canvas', - draggable: true, - zoom: { - min: 0.5, - max: 2.0, - step: 0.1, - }, - line_color: '#667eea', - line_width: 2, - }, - layout: { - hspace: 30, - vspace: 20, - pspace: 13, - }, - plugin: { - draggable_node: { - line_width: 5, - line_color: 'rgba(102, 126, 234, 0.6)', - line_color_invalid: 'rgba(220, 53, 69, 0.6)', - lookup_delay: 200, - }, - }, -}; -// TypeScript 数据格式 - 类型安全的数据定义 -const sampleMindData = { - meta: { - name: 'TypeScript Demo', - author: 'jsMind TypeScript', - version: '1.0', - }, - format: 'node_tree', - data: { - id: 'root', - topic: 'jsMind TypeScript 集成', - children: [ - { - id: 'features', - topic: '🚀 主要特性', - direction: jsMind.direction.right, - expanded: true, - children: [ - { - id: 'type-safety', - topic: '类型安全', - data: { - note: '编译时类型检查', - background: '#e3f2fd', - }, - }, - { - id: 'intellisense', - topic: '智能提示', - data: { - note: 'IDE 自动完成', - background: '#f3e5f5', - }, - }, - { - id: 'refactoring', - topic: '安全重构', - data: { - note: '重命名和移动', - background: '#e8f5e8', - }, - }, - ], - }, - { - id: 'benefits', - topic: '💡 开发优势', - direction: jsMind.direction.left, - expanded: true, - children: [ - { - id: 'errors', - topic: '错误预防', - data: { background: '#ff6b6b' }, - }, - { - id: 'docs', - topic: '自文档化', - data: { background: '#4ecdc4' }, - }, - { - id: 'maintenance', - topic: '易维护性', - data: { background: '#45b7d1' }, - }, - ], - }, - { - id: 'plugins', - topic: '🔌 插件支持', - direction: jsMind.direction.right, - children: [ - { id: 'draggable', topic: '拖拽节点' }, - { id: 'screenshot', topic: '截图导出' }, - ], - }, - ], - }, -}; -// 初始化函数 - 类型安全的 jsMind 实例创建 -function initJsMind() { - jm = new jsMind(options); - // 事件监听 - TypeScript 提供类型安全的事件处理 - jm.add_event_listener((type, data) => { - let eventName = ''; - switch (type) { - case jsMind.event_type.show: - eventName = '显示'; - break; - case jsMind.event_type.select: - eventName = '选择'; - break; - case jsMind.event_type.edit: - eventName = '编辑'; - break; - case jsMind.event_type.resize: - eventName = '调整大小'; - break; - } - updateStatus(`事件触发: ${eventName} - ${JSON.stringify(data)}`); - }); - updateStatus('jsMind 初始化完成 - TypeScript 类型定义已生效'); -} -// 加载示例数据 -function loadSampleData() { - if (!jm) initJsMind(); - jm.show(sampleMindData); - updateStatus('示例数据已加载 - 使用了 TypeScript NodeTreeFormat 类型'); -} -// 添加随机节点 - 展示类型安全的 API 调用 -function addRandomNode() { - if (!jm) { - updateStatus('请先加载数据'); - return; - } - const selectedNode = jm.get_selected_node(); - const parentNode = selectedNode || jm.get_root(); - if (parentNode) { - const nodeId = jsMind.util.uuid.newid(); - const topics = ['新想法', '重要提醒', '待办事项', '灵感闪现', '项目计划']; - const topic = topics[Math.floor(Math.random() * topics.length)]; - const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57']; - const color = colors[Math.floor(Math.random() * colors.length)]; - // TypeScript 确保方法调用的类型正确性 - const newNode = jm.add_node( - parentNode, - nodeId, - topic, - { - background: color, - created: new Date().toISOString(), - }, - Math.random() > 0.5 ? jsMind.direction.right : jsMind.direction.left - ); - if (newNode) { - jm.set_node_color(newNode.id, color, '#ffffff'); - jm.select_node(newNode); - updateStatus(`已添加新节点: ${topic} (ID: ${nodeId})`); - } - } -} -// 切换编辑模式 -function toggleEdit() { - if (!jm) { - updateStatus('请先加载数据'); - return; - } - isEditMode = !isEditMode; - if (isEditMode) { - jm.enable_edit(); - updateStatus('编辑模式已启用 - 双击节点可编辑'); - } else { - jm.disable_edit(); - updateStatus('编辑模式已禁用'); - } -} -// 展开所有节点 -function expandAll() { - if (!jm) return; - jm.expand_all(); - updateStatus('所有节点已展开'); -} -// 收起所有节点 -function collapseAll() { - if (!jm) return; - jm.collapse_all(); - updateStatus('所有节点已收起'); -} -// 清空思维导图 -function clearMindMap() { - if (!jm) return; - jm.show(); - updateStatus('思维导图已清空'); -} -// 更新状态信息 -function updateStatus(message) { - const statusElement = document.getElementById('status'); - if (statusElement) { - statusElement.textContent = `${new Date().toLocaleTimeString()} - ${message}`; - } -} -// 演示工具函数的使用 -function demonstrateUtilFunctions() { - // UUID 生成 - const nodeId = jsMind.util.uuid.newid(); - console.log('Generated UUID:', nodeId); - // JSON 操作 - const jsonString = jsMind.util.json.json2string(sampleMindData); - const parsedData = jsMind.util.json.string2json(jsonString); - console.log('JSON serialization test passed'); - // 文本工具 - const isEmpty = jsMind.util.text.is_empty(''); - const isNotEmpty = jsMind.util.text.is_empty('hello'); - console.log('Text utility test:', { isEmpty, isNotEmpty }); - // DOM 工具 - const element = jsMind.$.g('jsmind_container'); - if (element) { - console.log('DOM element found:', element.tagName); - } -} -// 导出函数供全局使用 -window.loadSampleData = loadSampleData; -window.addRandomNode = addRandomNode; -window.toggleEdit = toggleEdit; -window.expandAll = expandAll; -window.collapseAll = collapseAll; -window.clearMindMap = clearMindMap; -// 页面加载完成后的初始化 -window.addEventListener('load', () => { - updateStatus('页面加载完成 - TypeScript 类型定义验证成功'); - demonstrateUtilFunctions(); -}); -// 导出主要对象供其他模块使用 -export { jm, options, sampleMindData }; diff --git a/example/typescript-example.ts b/example/typescript-example.ts deleted file mode 100644 index f889c789..00000000 --- a/example/typescript-example.ts +++ /dev/null @@ -1,119 +0,0 @@ -/** - * jsMind TypeScript 使用示例 - * 展示如何在 TypeScript 项目中使用 jsMind - */ - -import jsMind, { JsMindOptions, NodeTreeFormat } from 'jsmind'; - -// 创建配置选项 -const options: JsMindOptions = { - container: 'jsmind_container', - editable: true, - theme: 'primary', - view: { - engine: 'canvas', - draggable: true, - zoom: { - min: 0.5, - max: 2.0, - step: 0.1, - }, - }, - layout: { - hspace: 30, - vspace: 20, - }, -}; - -// 创建思维导图数据 -const mindData: NodeTreeFormat = { - meta: { - name: 'TypeScript Example', - author: 'jsMind User', - version: '1.0', - }, - format: 'node_tree', - data: { - id: 'root', - topic: 'TypeScript Integration', - children: [ - { - id: 'features', - topic: 'Features', - direction: 1, - children: [ - { id: 'types', topic: 'Type Safety' }, - { id: 'intellisense', topic: 'IntelliSense' }, - { id: 'refactoring', topic: 'Safe Refactoring' }, - ], - }, - { - id: 'benefits', - topic: 'Benefits', - direction: -1, - children: [ - { id: 'errors', topic: 'Compile-time Error Detection' }, - { id: 'docs', topic: 'Self-documenting Code' }, - { id: 'maintenance', topic: 'Better Maintainability' }, - ], - }, - ], - }, -}; - -// 创建 jsMind 实例 -const jm = new jsMind(options); - -// 显示思维导图 -jm.show(mindData); - -// 添加事件监听器 -jm.add_event_listener((type, data) => { - switch (type) { - case jsMind.event_type.show: - console.log('Mind map displayed'); - break; - case jsMind.event_type.select: - console.log('Node selected:', data); - break; - case jsMind.event_type.edit: - console.log('Node edited:', data); - break; - } -}); - -// 获取根节点并添加新节点 -const root = jm.get_root(); -if (root) { - const newNode = jm.add_node( - root, - 'new_feature', - 'New Feature', - { - background: '#ff6b6b', - foreground: '#ffffff', - }, - jsMind.direction.right - ); - - if (newNode) { - // 设置节点样式 - jm.set_node_color(newNode.id, '#ff6b6b', '#ffffff'); - jm.set_node_font_style(newNode.id, 14, 'bold'); - - // 选择新节点 - jm.select_node(newNode); - } -} - -// 工具函数使用示例 -const nodeId = jsMind.util.uuid.newid(); -const isEmpty = jsMind.util.text.is_empty(''); -const jsonData = jsMind.util.json.json2string(mindData); - -console.log('Generated node ID:', nodeId); -console.log('Is empty string:', isEmpty); -console.log('JSON data length:', jsonData.length); - -// 导出实例供其他模块使用 -export { jm, options, mindData }; diff --git a/example/typescript-test.ts b/tests/fixtures/typescript-test.ts similarity index 100% rename from example/typescript-test.ts rename to tests/fixtures/typescript-test.ts diff --git a/tsconfig.json b/tsconfig.json index 55fc12f2..5db373a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,10 @@ }, "include": [ "types/*.d.ts", - "example/typescript-test.ts" + "tests/fixtures/typescript-test.ts" ], - "exclude": ["node_modules", "dist", "tests"] + "exclude": [ + "node_modules", + "dist" + ] } From f56b662ffea0b3b77c223ce2505242208ca7f8bc Mon Sep 17 00:00:00 2001 From: umbraci Date: Sat, 9 Aug 2025 21:25:06 +0800 Subject: [PATCH 07/24] test(typings): update test title to fixtures path after file move --- tests/unit/typescript.types.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/typescript.types.test.js b/tests/unit/typescript.types.test.js index 0c0185d7..6d0ceedf 100644 --- a/tests/unit/typescript.types.test.js +++ b/tests/unit/typescript.types.test.js @@ -22,7 +22,7 @@ function formatHost() { } describe('TypeScript typings validation', () => { - test('example/typescript-test.ts should pass type-check (no diagnostics)', () => { + test('tests/fixtures/typescript-test.ts should pass type-check (no diagnostics)', () => { const projectRoot = process.cwd(); const tsconfigPath = path.join(projectRoot, 'tsconfig.json'); From 5768f9df75f20b64646ff91f3678d7371f5beab9 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 10:07:02 +0800 Subject: [PATCH 08/24] build(types): add JSDoc-based .d.ts generation via tsc allowJs\n\n- add tsconfig.decls.json (emitDeclarationOnly, allowJs)\n- add npm scripts: gen:dts, gen:dts:check\n- initial generated declarations under types/generated/ --- package.json | 3 + tsconfig.decls.json | 30 ++++ types/generated/jsmind.common.d.ts | 63 ++++++++ types/generated/jsmind.d.ts | 148 ++++++++++++++++++ types/generated/jsmind.data_provider.d.ts | 36 +++++ types/generated/jsmind.dom.d.ts | 20 +++ types/generated/jsmind.format.d.ts | 131 ++++++++++++++++ types/generated/jsmind.graph.d.ts | 51 ++++++ types/generated/jsmind.layout_provider.d.ts | 49 ++++++ types/generated/jsmind.mind.d.ts | 23 +++ types/generated/jsmind.node.d.ts | 24 +++ types/generated/jsmind.option.d.ts | 1 + types/generated/jsmind.plugin.d.ts | 7 + types/generated/jsmind.shortcut_provider.d.ts | 23 +++ types/generated/jsmind.util.d.ts | 17 ++ types/generated/jsmind.view_provider.d.ts | 118 ++++++++++++++ .../plugins/jsmind.draggable-node.d.ts | 1 + .../generated/plugins/jsmind.screenshot.d.ts | 1 + 18 files changed, 746 insertions(+) create mode 100644 tsconfig.decls.json create mode 100644 types/generated/jsmind.common.d.ts create mode 100644 types/generated/jsmind.d.ts create mode 100644 types/generated/jsmind.data_provider.d.ts create mode 100644 types/generated/jsmind.dom.d.ts create mode 100644 types/generated/jsmind.format.d.ts create mode 100644 types/generated/jsmind.graph.d.ts create mode 100644 types/generated/jsmind.layout_provider.d.ts create mode 100644 types/generated/jsmind.mind.d.ts create mode 100644 types/generated/jsmind.node.d.ts create mode 100644 types/generated/jsmind.option.d.ts create mode 100644 types/generated/jsmind.plugin.d.ts create mode 100644 types/generated/jsmind.shortcut_provider.d.ts create mode 100644 types/generated/jsmind.util.d.ts create mode 100644 types/generated/jsmind.view_provider.d.ts create mode 100644 types/generated/plugins/jsmind.draggable-node.d.ts create mode 100644 types/generated/plugins/jsmind.screenshot.d.ts diff --git a/package.json b/package.json index b0ada48e..210d51ba 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,8 @@ "test": "NODE_OPTIONS=--experimental-vm-modules jest", "test-legacy": "jest tests/legacy", "test-es6": "NODE_OPTIONS=--experimental-vm-modules jest tests/unit", + "gen:dts": "tsc -p tsconfig.decls.json", + "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", "format": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --write .", "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check ." }, @@ -65,6 +67,7 @@ "prettier": "2.6.2", "rollup": "2.79.2", "rollup-plugin-cleanup": "^3.2.1", + "tsd-jsdoc": "^2.5.0", "typescript": "^5.9.2" }, "jest": { diff --git a/tsconfig.decls.json b/tsconfig.decls.json new file mode 100644 index 00000000..cd475caf --- /dev/null +++ b/tsconfig.decls.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": false, + "skipLibCheck": true, + "esModuleInterop": true, + "declaration": true, + "emitDeclarationOnly": true, + "allowJs": true, + "checkJs": false, + "outDir": "types/generated", + "rootDir": "src", + "baseUrl": "." + }, + "include": [ + "src/**/*.js" + ], + "exclude": [ + "node_modules", + "dist", + "tests", + "example", + "es6", + "js-legacy" + ] +} + + diff --git a/types/generated/jsmind.common.d.ts b/types/generated/jsmind.common.d.ts new file mode 100644 index 00000000..ae371445 --- /dev/null +++ b/types/generated/jsmind.common.d.ts @@ -0,0 +1,63 @@ +/** + * @license BSD + * @copyright 2014-2025 hizzgdev@163.com + * + * Project Home: + * https://github.com/hizzgdev/jsmind/ + */ +export const __version__: "0.8.7"; +export const __author__: "hizzgdev@163.com"; +export namespace Direction { + let left: number; + let center: number; + let right: number; + function of(dir: any): any; +} +export namespace EventType { + let show: number; + let resize: number; + let edit: number; + let select: number; +} +export namespace Key { + let meta: number; + let ctrl: number; + let alt: number; + let shift: number; +} +export namespace LogLevel { + let debug: number; + let info: number; + let warn: number; + let error: number; + let disable: number; +} +export namespace logger { + export { setup_logger_level as level }; + export let log: { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; + }; + let debug_1: { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; + }; + export { debug_1 as debug }; + let info_1: { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; + }; + export { info_1 as info }; + let warn_1: { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; + }; + export { warn_1 as warn }; + let error_1: { + (...data: any[]): void; + (message?: any, ...optionalParams: any[]): void; + }; + export { error_1 as error }; +} +declare function setup_logger_level(log_level: any): void; +export {}; diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts new file mode 100644 index 00000000..b140c838 --- /dev/null +++ b/types/generated/jsmind.d.ts @@ -0,0 +1,148 @@ +export default class jsMind { + static mind: typeof Mind; + static node: typeof Node; + static direction: { + left: number; + center: number; + right: number; + of: (dir: any) => any; + }; + static event_type: { + show: number; + resize: number; + edit: number; + select: number; + }; + static $: { + w: any; + d: any; + g: (id: any) => any; + c: (tag: any) => any; + t: (n: any, t: any) => void; + h: (n: any, t: any) => void; + i: (el: any) => boolean; + on: (t: any, e: any, h: any) => void; + }; + static plugin: typeof Plugin; + static register_plugin: typeof _register_plugin; + static util: { + file: { + read: (file_data: any, fn_callback: any) => void; + save: (file_data: any, type: any, name: any) => void; + }; + json: { + json2string: (json: any) => string; + string2json: (json_str: any) => any; + merge: (b: any, a: any) => any; + }; + uuid: { + newid: () => string; + }; + text: { + is_empty: (s: any) => boolean; + }; + }; + static show(options: any, mind: any): jsMind; + constructor(options: any); + options: {}; + version: string; + initialized: boolean; + mind: Mind; + event_handles: any[]; + init(): void; + data: DataProvider; + layout: LayoutProvider; + view: ViewProvider; + shortcut: ShortcutProvider; + get_editable(): any; + enable_edit(): void; + disable_edit(): void; + get_view_draggable(): any; + enable_view_draggable(): void; + disable_view_draggable(): void; + enable_event_handle(event_handle: any): void; + disable_event_handle(event_handle: any): void; + set_theme(theme: any): void; + _event_bind(): void; + mousedown_handle(e: any): void; + click_handle(e: any): void; + dblclick_handle(e: any): void; + mousewheel_handle(e: any): void; + begin_edit(node: any): any; + end_edit(): void; + toggle_node(node: any): any; + expand_node(node: any): any; + collapse_node(node: any): any; + expand_all(): void; + collapse_all(): void; + expand_to_depth(depth: any): void; + _reset(): void; + _show(mind: any, skip_centering: any): void; + show(mind: any, skip_centering: any): void; + get_meta(): { + name: any; + author: any; + version: any; + }; + get_data(data_format: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: { + id: any; + topic: any; + expanded: boolean; + }; + } | { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: any[]; + } | { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: string; + }; + get_root(): Node; + get_node(node: any): any; + add_node(parent_node: any, node_id: any, topic: any, data: any, direction: any): Node; + insert_node_before(node_before: any, node_id: any, topic: any, data: any, direction: any): Node; + insert_node_after(node_after: any, node_id: any, topic: any, data: any, direction: any): Node; + remove_node(node: any): any; + update_node(node_id: any, topic: any): void; + move_node(node_id: any, before_id: any, parent_id: any, direction: any): void; + select_node(node: any): any; + get_selected_node(): any; + select_clear(): void; + is_node_visible(node: any): boolean; + scroll_node_to_center(node: any): void; + find_node_before(node: any): any; + find_node_after(node: any): any; + set_node_color(node_id: any, bg_color: any, fg_color: any): any; + set_node_font_style(node_id: any, size: any, weight: any, style: any): any; + set_node_background_image(node_id: any, image: any, width: any, height: any, rotation: any): any; + set_node_background_rotation(node_id: any, rotation: any): any; + resize(): void; + add_event_listener(callback: any): void; + clear_event_listener(): void; + invoke_event_handle(type: any, data: any): void; + _invoke_event_handle(type: any, data: any): void; +} +import { Mind } from './jsmind.mind.js'; +import { DataProvider } from './jsmind.data_provider.js'; +import { LayoutProvider } from './jsmind.layout_provider.js'; +import { ViewProvider } from './jsmind.view_provider.js'; +import { ShortcutProvider } from './jsmind.shortcut_provider.js'; +import { Node } from './jsmind.node.js'; +import { Plugin } from './jsmind.plugin.js'; +import { register as _register_plugin } from './jsmind.plugin.js'; diff --git a/types/generated/jsmind.data_provider.d.ts b/types/generated/jsmind.data_provider.d.ts new file mode 100644 index 00000000..573f68e2 --- /dev/null +++ b/types/generated/jsmind.data_provider.d.ts @@ -0,0 +1,36 @@ +export class DataProvider { + constructor(jm: any); + jm: any; + init(): void; + reset(): void; + load(mind_data: any): import("./jsmind.mind.js").Mind; + get_data(data_format: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: { + id: any; + topic: any; + expanded: boolean; + }; + } | { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: any[]; + } | { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: string; + }; +} diff --git a/types/generated/jsmind.dom.d.ts b/types/generated/jsmind.dom.d.ts new file mode 100644 index 00000000..00027953 --- /dev/null +++ b/types/generated/jsmind.dom.d.ts @@ -0,0 +1,20 @@ +export const $: Dom; +/** + * @license BSD + * @copyright 2014-2025 hizzgdev@163.com + * + * Project Home: + * https://github.com/hizzgdev/jsmind/ + */ +declare class Dom { + constructor(w: any); + w: any; + d: any; + g: (id: any) => any; + c: (tag: any) => any; + t: (n: any, t: any) => void; + h: (n: any, t: any) => void; + i: (el: any) => boolean; + on: (t: any, e: any, h: any) => void; +} +export {}; diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts new file mode 100644 index 00000000..caa4cf54 --- /dev/null +++ b/types/generated/jsmind.format.d.ts @@ -0,0 +1,131 @@ +export namespace format { + namespace node_tree { + namespace example { + export { DEFAULT_META as meta }; + export let format: string; + export namespace data { + let id: string; + let topic: string; + } + } + function get_mind(source: any): Mind; + function get_data(mind: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: { + id: any; + topic: any; + expanded: boolean; + }; + }; + function _parse(mind: any, node_root: any): void; + function _extract_data(node_json: any): {}; + function _extract_subnode(mind: any, node_parent: any, node_json: any): void; + function _build_node(node: any): { + id: any; + topic: any; + expanded: boolean; + }; + } + namespace node_array { + export namespace example_1 { + export { DEFAULT_META as meta }; + let format_1: string; + export { format_1 as format }; + let data_1: { + id: string; + topic: string; + isroot: boolean; + }[]; + export { data_1 as data }; + } + export { example_1 as example }; + export function get_mind_1(source: any): Mind; + export { get_mind_1 as get_mind }; + export function get_data_1(mind: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: any[]; + }; + export { get_data_1 as get_data }; + export function _parse_1(mind: any, node_array: any): void; + export { _parse_1 as _parse }; + export function _extract_root(mind: any, node_array: any): any; + export function _extract_subnode_1(mind: any, parent_node: any, node_array: any): number; + export { _extract_subnode_1 as _extract_subnode }; + export function _extract_data_1(node_json: any): {}; + export { _extract_data_1 as _extract_data }; + export function _array(mind: any, node_array: any): void; + export function _array_node(node: any, node_array: any): void; + } + namespace freemind { + export namespace example_2 { + export { DEFAULT_META as meta }; + let format_2: string; + export { format_2 as format }; + let data_2: string; + export { data_2 as data }; + } + export { example_2 as example }; + export function get_mind_2(source: any): Mind; + export { get_mind_2 as get_mind }; + export function get_data_2(mind: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: string; + }; + export { get_data_2 as get_data }; + export function _parse_xml(xml: any): any; + export function _find_root(xml_doc: any): any; + export function _load_node(mind: any, parent_node: any, xml_node: any): void; + export function _load_attributes(xml_node: any): {}; + export function _build_map(node: any, xml_lines: any): void; + export function _escape(text: any): any; + } + namespace text { + export namespace example_3 { + export { DEFAULT_META as meta }; + let format_3: string; + export { format_3 as format }; + let data_3: string; + export { data_3 as data }; + } + export { example_3 as example }; + export let _line_regex: RegExp; + export function get_mind_3(source: any): Mind; + export { get_mind_3 as get_mind }; + export function _fill_nodes(mind: any, lines: any): void; + export function get_data_3(mind: any): { + meta: { + name: any; + author: any; + version: any; + }; + format: string; + data: string; + }; + export { get_data_3 as get_data }; + export function _build_lines(lines: any, nodes: any, level: any): void; + } +} +declare namespace DEFAULT_META { + export let name: string; + export { __author__ as author }; + export { __version__ as version }; +} +import { Mind } from './jsmind.mind.js'; +import { __author__ } from './jsmind.common.js'; +import { __version__ } from './jsmind.common.js'; +export {}; diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts new file mode 100644 index 00000000..63ef9a26 --- /dev/null +++ b/types/generated/jsmind.graph.d.ts @@ -0,0 +1,51 @@ +export function init_graph(view: any, engine: any): SvgGraph | CanvasGraph; +declare class SvgGraph { + static c(tag: any): any; + constructor(view: any); + view: any; + opts: any; + e_svg: any; + size: { + w: number; + h: number; + }; + lines: any[]; + line_drawing: { + straight: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + curved: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + }; + init_line_render(): void; + drawing: any; + element(): any; + set_size(w: any, h: any): void; + clear(): void; + draw_line(pout: any, pin: any, offset: any, color: any): void; + copy_to(dest_canvas_ctx: any, callback: any): void; + _bezier_to(path: any, x1: any, y1: any, x2: any, y2: any): void; + _line_to(path: any, x1: any, y1: any, x2: any, y2: any): void; +} +declare class CanvasGraph { + constructor(view: any); + opts: any; + e_canvas: any; + canvas_ctx: any; + size: { + w: number; + h: number; + }; + line_drawing: { + straight: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + curved: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + }; + dpr: any; + init_line_render(): void; + drawing: any; + element(): any; + set_size(w: any, h: any): void; + clear(): void; + draw_line(pout: any, pin: any, offset: any, color: any): void; + copy_to(dest_canvas_ctx: any, callback: any): void; + _bezier_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; + _line_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; +} +export {}; diff --git a/types/generated/jsmind.layout_provider.d.ts b/types/generated/jsmind.layout_provider.d.ts new file mode 100644 index 00000000..5e92c83e --- /dev/null +++ b/types/generated/jsmind.layout_provider.d.ts @@ -0,0 +1,49 @@ +export class LayoutProvider { + constructor(jm: any, options: any); + opts: any; + jm: any; + isside: boolean; + bounds: { + n: number; + s: number; + w: number; + e: number; + }; + cache_valid: boolean; + init(): void; + reset(): void; + calculate_next_child_direction(node: any): number; + layout(): void; + layout_direction(): void; + _layout_direction_root(): void; + _layout_direction_side(node: any, direction: any, side_index: any): void; + layout_offset(): void; + _layout_offset_subnodes(nodes: any): number; + _layout_offset_subnodes_height(nodes: any): number; + _should_reserve_cousin_space(node: any): boolean; + get_node_offset(node: any): any; + get_node_point(node: any): { + x: any; + y: number; + }; + get_node_point_in(node: any): any; + get_node_point_out(node: any): any; + get_expander_point(node: any): { + x: any; + y: number; + }; + get_min_size(): { + w: number; + h: number; + }; + toggle_node(node: any): void; + expand_node(node: any): void; + collapse_node(node: any): void; + expand_all(): void; + collapse_all(): void; + expand_to_depth(target_depth: any, curr_nodes: any, curr_depth: any): void; + part_layout(node: any): void; + set_visible(nodes: any, visible: any): void; + is_expand(node: any): any; + is_visible(node: any): boolean; +} diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts new file mode 100644 index 00000000..03c771f7 --- /dev/null +++ b/types/generated/jsmind.mind.d.ts @@ -0,0 +1,23 @@ +export class Mind { + name: any; + author: any; + version: any; + root: Node; + selected: any; + nodes: {}; + get_node(node_id: any): any; + set_root(node_id: any, topic: any, data: any): Node; + add_node(parent_node: any, node_id: any, topic: any, data: any, direction: any, expanded: any, idx: any): Node; + insert_node_before(node_before: any, node_id: any, topic: any, data: any, direction: any): Node; + get_node_before(node: any): any; + insert_node_after(node_after: any, node_id: any, topic: any, data: any, direction: any): Node; + get_node_after(node: any): any; + move_node(node: any, before_id: any, parent_id: any, direction: any): any; + _flow_node_direction(node: any, direction: any): void; + _move_node_internal(node: any, before_id: any): any; + _move_node(node: any, before_id: any, parent_id: any, direction: any): any; + remove_node(node: any): boolean; + _put_node(node: any): boolean; + _update_index(node: any): void; +} +import { Node } from './jsmind.node.js'; diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts new file mode 100644 index 00000000..fb149351 --- /dev/null +++ b/types/generated/jsmind.node.d.ts @@ -0,0 +1,24 @@ +export class Node { + static compare(node1: any, node2: any): number; + static inherited(parent_node: any, node: any): boolean; + static is_node(n: any): boolean; + constructor(sId: any, iIndex: any, sTopic: any, oData: any, bIsRoot: any, oParent: any, eDirection: any, bExpanded: any); + id: any; + index: number; + topic: any; + data: any; + isroot: any; + parent: any; + direction: any; + expanded: boolean; + children: any[]; + _data: {}; + get_location(): { + x: any; + y: any; + }; + get_size(): { + w: any; + h: any; + }; +} diff --git a/types/generated/jsmind.option.d.ts b/types/generated/jsmind.option.d.ts new file mode 100644 index 00000000..6f993b90 --- /dev/null +++ b/types/generated/jsmind.option.d.ts @@ -0,0 +1 @@ +export function merge_option(options: any): {}; diff --git a/types/generated/jsmind.plugin.d.ts b/types/generated/jsmind.plugin.d.ts new file mode 100644 index 00000000..3ad9668e --- /dev/null +++ b/types/generated/jsmind.plugin.d.ts @@ -0,0 +1,7 @@ +export function register(plugin: any): void; +export function apply(jm: any, options: any): void; +export class Plugin { + constructor(name: any, fn_init: any); + name: any; + fn_init: any; +} diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts new file mode 100644 index 00000000..e481395d --- /dev/null +++ b/types/generated/jsmind.shortcut_provider.d.ts @@ -0,0 +1,23 @@ +export class ShortcutProvider { + constructor(jm: any, options: any); + jm: any; + opts: any; + mapping: any; + handles: any; + _newid: any; + _mapping: {}; + init(): void; + enable_shortcut(): void; + disable_shortcut(): void; + handler(e: any): boolean; + handle_addchild(_jm: any, e: any): void; + handle_addbrother(_jm: any, e: any): void; + handle_editnode(_jm: any, e: any): void; + handle_delnode(_jm: any, e: any): void; + handle_toggle(_jm: any, e: any): void; + handle_up(_jm: any, e: any): void; + handle_down(_jm: any, e: any): void; + handle_left(_jm: any, e: any): void; + handle_right(_jm: any, e: any): void; + _handle_direction(_jm: any, e: any, d: any): void; +} diff --git a/types/generated/jsmind.util.d.ts b/types/generated/jsmind.util.d.ts new file mode 100644 index 00000000..d774469a --- /dev/null +++ b/types/generated/jsmind.util.d.ts @@ -0,0 +1,17 @@ +export namespace util { + namespace file { + function read(file_data: any, fn_callback: any): void; + function save(file_data: any, type: any, name: any): void; + } + namespace json { + function json2string(json: any): string; + function string2json(json_str: any): any; + function merge(b: any, a: any): any; + } + namespace uuid { + function newid(): string; + } + namespace text { + function is_empty(s: any): boolean; + } +} diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts new file mode 100644 index 00000000..963f7469 --- /dev/null +++ b/types/generated/jsmind.view_provider.d.ts @@ -0,0 +1,118 @@ +export class ViewProvider { + constructor(jm: any, options: any); + opts: any; + jm: any; + layout: any; + container: any; + e_panel: any; + e_nodes: any; + size: { + w: number; + h: number; + }; + selected_node: any; + editing_node: any; + graph: { + view: any; + opts: any; + e_svg: any; + size: { + w: number; + h: number; + }; + lines: any[]; + line_drawing: { + straight: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + curved: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + }; + init_line_render(): void; + drawing: any; + element(): any; + set_size(w: any, h: any): void; + clear(): void; + draw_line(pout: any, pin: any, offset: any, color: any): void; + copy_to(dest_canvas_ctx: any, callback: any): void; + _bezier_to(path: any, x1: any, y1: any, x2: any, y2: any): void; + _line_to(path: any, x1: any, y1: any, x2: any, y2: any): void; + } | { + opts: any; + e_canvas: any; + canvas_ctx: any; + size: { + w: number; + h: number; + }; + line_drawing: { + straight: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + curved: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + }; + dpr: any; + init_line_render(): void; + drawing: any; + element(): any; + set_size(w: any, h: any): void; + clear(): void; + draw_line(pout: any, pin: any, offset: any, color: any): void; + copy_to(dest_canvas_ctx: any, callback: any): void; + _bezier_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; + _line_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; + }; + render_node: (ele: any, node: any) => void; + zoom_current: number; + device_pixel_ratio: any; + _initialized: boolean; + init(): void; + e_editor: any; + add_event(obj: any, event_name: any, event_handle: any, capture_by_panel: any): void; + get_binded_nodeid(element: any): any; + is_node(element: any): any; + is_expander(element: any): boolean; + reset(): void; + reset_theme(): void; + reset_custom_style(): void; + load(): void; + expand_size(): void; + init_nodes_size(node: any): void; + init_nodes(): void; + add_node(node: any): void; + run_in_c11y_mode_if_needed(func: any): void; + create_node_element(node: any, parent_node: any): void; + remove_node(node: any): void; + update_node(node: any): void; + select_node(node: any): void; + select_clear(): void; + get_editing_node(): any; + is_editing(): boolean; + edit_node_begin(node: any): void; + edit_node_end(): void; + get_view_offset(): { + x: number; + y: number; + }; + resize(): void; + _show(): void; + zoom_in(e: any): boolean; + zoom_out(e: any): boolean; + set_zoom(zoom: any, e: any): boolean; + show(keep_center: any): void; + relayout(): void; + save_location(node: any): void; + restore_location(node: any): void; + clear_nodes(): void; + show_nodes(): void; + _show_expander(node: any, view_offset: any): void; + _get_expander_text(node: any): any; + _default_node_render(ele: any, node: any): void; + _custom_node_render(ele: any, node: any): void; + reset_node_custom_style(node: any): void; + _reset_node_custom_style(node_element: any, node_data: any): void; + restore_selected_node_custom_style(node: any): void; + clear_selected_node_custom_style(node: any): void; + clear_lines(): void; + show_lines(): void; + setup_canvas_draggable(enabled: any): void; + center_node(node: any): boolean; + zoomIn(e: any): boolean; + zoomOut(e: any): boolean; + setZoom(zoom: any, e: any): boolean; +} diff --git a/types/generated/plugins/jsmind.draggable-node.d.ts b/types/generated/plugins/jsmind.draggable-node.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/types/generated/plugins/jsmind.draggable-node.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/types/generated/plugins/jsmind.screenshot.d.ts b/types/generated/plugins/jsmind.screenshot.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/types/generated/plugins/jsmind.screenshot.d.ts @@ -0,0 +1 @@ +export {}; From 70f10858b01421dd61e35a85a2fb23175d25498b Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 10:11:40 +0800 Subject: [PATCH 09/24] docs(typings): convert comments to English and exclude js-legacy from JSDoc-based generation --- tsconfig.decls.json | 45 +++++++++++++++++---------------------------- types/jsmind.d.ts | 17 +++++++++-------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/tsconfig.decls.json b/tsconfig.decls.json index cd475caf..dda20ff5 100644 --- a/tsconfig.decls.json +++ b/tsconfig.decls.json @@ -1,30 +1,19 @@ { - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "node", - "strict": false, - "skipLibCheck": true, - "esModuleInterop": true, - "declaration": true, - "emitDeclarationOnly": true, - "allowJs": true, - "checkJs": false, - "outDir": "types/generated", - "rootDir": "src", - "baseUrl": "." - }, - "include": [ - "src/**/*.js" - ], - "exclude": [ - "node_modules", - "dist", - "tests", - "example", - "es6", - "js-legacy" - ] + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": false, + "skipLibCheck": true, + "esModuleInterop": true, + "declaration": true, + "emitDeclarationOnly": true, + "allowJs": true, + "checkJs": false, + "outDir": "types/generated", + "rootDir": "src", + "baseUrl": "." + }, + "include": ["src/**/*.js"], + "exclude": ["node_modules", "dist", "tests", "example", "es6", "js-legacy", "js-legacy/**/*.js"] } - - diff --git a/types/jsmind.d.ts b/types/jsmind.d.ts index b89072b2..9c5a0f1a 100644 --- a/types/jsmind.d.ts +++ b/types/jsmind.d.ts @@ -6,7 +6,7 @@ */ // ============================================================================ -// 基础枚举和常量 +// Basic enums and constants // ============================================================================ export interface DirectionType { @@ -39,10 +39,11 @@ export interface KeyEnum { } // ============================================================================ -// 数据格式接口 +// Data format interfaces // ============================================================================ export interface NodeData { + // Arbitrary custom data attached to a node [key: string]: any; } @@ -86,7 +87,7 @@ export interface NodeArrayData { export type MindMapData = NodeTreeFormat | NodeArrayFormat | string; // ============================================================================ -// 配置选项接口 +// Options interfaces // ============================================================================ export interface ZoomOptions { @@ -164,7 +165,7 @@ export interface JsMindOptions { } // ============================================================================ -// 核心类接口 +// Core class interfaces // ============================================================================ export interface NodeLocation { @@ -246,7 +247,7 @@ export class Mind { } // ============================================================================ -// 工具类接口 +// Utility interfaces // ============================================================================ export interface FileUtil { @@ -287,7 +288,7 @@ export interface Dom { } // ============================================================================ -// 事件处理接口 +// Event handling interfaces // ============================================================================ export interface EventData { @@ -299,7 +300,7 @@ export interface EventData { export type EventHandler = (type: number, data: EventData) => void; // ============================================================================ -// 主类定义 +// Main class // ============================================================================ export default class jsMind { @@ -396,7 +397,7 @@ export default class jsMind { } // ============================================================================ -// 模块导出 +// Module exports // ============================================================================ export { jsMind }; From 0854a0d524eae701c2c0668db85ea88a3769277a Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 10:30:21 +0800 Subject: [PATCH 10/24] =?UTF-8?q?chore:=20=E5=AE=89=E8=A3=85=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=94=9F=E6=88=90.d.ts=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 269 ++++ package.json | 4 +- pnpm-lock.yaml | 3122 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3393 insertions(+), 2 deletions(-) create mode 100644 pnpm-lock.yaml diff --git a/package-lock.json b/package-lock.json index 62c3eede..03092af0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "prettier": "2.6.2", "rollup": "2.79.2", "rollup-plugin-cleanup": "^3.2.1", + "tsd-jsdoc": "^2.5.0", "typescript": "^5.9.2" } }, @@ -1076,6 +1077,34 @@ "@types/tough-cookie": "*" } }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/node": { "version": "22.7.5", "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.7.5.tgz", @@ -1374,6 +1403,14 @@ "node": ">= 0.8" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1520,6 +1557,20 @@ } ] }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmmirror.com/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", @@ -1852,6 +1903,17 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz", @@ -3252,6 +3314,62 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "3.6.11", + "resolved": "https://registry.npmmirror.com/jsdoc/-/jsdoc-3.6.11.tgz", + "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@babel/parser": "^7.9.4", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsdom": { "version": "19.0.0", "resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-19.0.0.tgz", @@ -3328,6 +3446,17 @@ "node": ">=6" } }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz", @@ -3352,6 +3481,17 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", @@ -3424,6 +3564,58 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmmirror.com/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmmirror.com/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "license": "Unlicense", + "peer": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0", + "peer": true + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3434,6 +3626,14 @@ "node": ">= 0.4" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3924,6 +4124,17 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz", @@ -4323,6 +4534,13 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmmirror.com/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", + "dev": true, + "peer": true + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz", @@ -4435,6 +4653,33 @@ "node": ">=12" } }, + "node_modules/tsd-jsdoc": { + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tsd-jsdoc/-/tsd-jsdoc-2.5.0.tgz", + "integrity": "sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "typescript": "^3.2.1" + }, + "peerDependencies": { + "jsdoc": "^3.6.3" + } + }, + "node_modules/tsd-jsdoc/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz", @@ -4470,6 +4715,22 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz", @@ -4724,6 +4985,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 210d51ba..582e1a0a 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "test": "NODE_OPTIONS=--experimental-vm-modules jest", "test-legacy": "jest tests/legacy", "test-es6": "NODE_OPTIONS=--experimental-vm-modules jest tests/unit", - "gen:dts": "tsc -p tsconfig.decls.json", - "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", + "gen:dts": "tsc -p tsconfig.decls.json", + "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", "format": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --write .", "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check ." }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..91e7558a --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3122 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@rollup/plugin-terser': + specifier: ^0.4.4 + version: 0.4.4(rollup@2.79.2) + http-server: + specifier: ^14.1.1 + version: 14.1.1 + jest: + specifier: ^28.1.0 + version: 28.1.3 + jest-environment-jsdom: + specifier: ^28.1.0 + version: 28.1.3 + prettier: + specifier: 2.6.2 + version: 2.6.2 + rollup: + specifier: 2.79.2 + version: 2.79.2 + rollup-plugin-cleanup: + specifier: ^3.2.1 + version: 3.2.1(rollup@2.79.2) + tsd-jsdoc: + specifier: ^2.5.0 + version: 2.5.0(jsdoc@3.6.11) + typescript: + specifier: ^5.9.2 + version: 5.9.2 + +packages: + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@babel/code-frame@7.27.1: + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + dev: true + + /@babel/compat-data@7.28.0: + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.28.0: + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.28.2 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.28.0: + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + dev: true + + /@babel/helper-compilation-targets@7.27.2: + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.2 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-globals@7.28.0: + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-module-imports@7.27.1: + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0): + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils@7.27.1: + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-string-parser@7.27.1: + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.27.1: + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.27.1: + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.28.2: + resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + dev: true + + /@babel/parser@7.28.0: + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0): + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0): + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/template@7.27.2: + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + dev: true + + /@babel/traverse@7.28.0: + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.28.2: + resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@28.1.3: + resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + dev: true + + /@jest/core@28.1.3: + resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 28.1.3 + '@jest/reporters': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 28.1.3 + jest-config: 28.1.3(@types/node@24.2.1) + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-resolve-dependencies: 28.1.3 + jest-runner: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + jest-watcher: 28.1.3 + micromatch: 4.0.8 + pretty-format: 28.1.3 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /@jest/environment@28.1.3: + resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + dev: true + + /@jest/expect-utils@28.1.3: + resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-get-type: 28.0.2 + dev: true + + /@jest/expect@28.1.3: + resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + expect: 28.1.3 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@28.1.3: + resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@sinonjs/fake-timers': 9.1.2 + '@types/node': 24.2.1 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /@jest/globals@28.1.3: + resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/types': 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@28.1.3: + resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.29 + '@types/node': 24.2.1 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + jest-worker: 28.1.3 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + terminal-link: 2.1.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas@28.1.3: + resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@sinclair/typebox': 0.24.51 + dev: true + + /@jest/source-map@28.1.2: + resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@28.1.3: + resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/console': 28.1.3 + '@jest/types': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@28.1.3: + resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/test-result': 28.1.3 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + slash: 3.0.0 + dev: true + + /@jest/transform@28.1.3: + resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/core': 7.28.0 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.29 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@28.1.3: + resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/schemas': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.2.1 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.12: + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.10: + resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==} + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@jridgewell/sourcemap-codec@1.5.4: + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + dev: true + + /@jridgewell/trace-mapping@0.3.29: + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.4 + dev: true + + /@rollup/plugin-terser@0.4.4(rollup@2.79.2): + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 2.79.2 + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.43.1 + dev: true + + /@sinclair/typebox@0.24.51: + resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} + dev: true + + /@sinonjs/commons@1.8.6: + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@9.1.2: + resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} + dependencies: + '@sinonjs/commons': 1.8.6 + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + dev: true + + /@types/babel__generator@7.27.0: + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + dev: true + + /@types/babel__traverse@7.28.0: + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + dependencies: + '@types/node': 24.2.1 + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true + + /@types/jsdom@16.2.15: + resolution: {integrity: sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==} + dependencies: + '@types/node': 24.2.1 + '@types/parse5': 6.0.3 + '@types/tough-cookie': 4.0.5 + dev: true + + /@types/linkify-it@5.0.0: + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + dev: true + + /@types/markdown-it@12.2.3: + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: true + + /@types/mdurl@2.0.0: + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + dev: true + + /@types/node@24.2.1: + resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==} + dependencies: + undici-types: 7.10.0 + dev: true + + /@types/parse5@6.0.3: + resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} + dev: true + + /@types/prettier@2.7.3: + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + dev: true + + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: true + + /@types/tough-cookie@4.0.5: + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + dev: true + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: true + + /@types/yargs@17.0.33: + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + dev: true + + /acorn-globals@6.0.0: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + dev: true + + /acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /babel-jest@28.1.3(@babel/core@7.28.0): + resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.28.0 + '@jest/transform': 28.1.3 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 28.1.3(@babel/core@7.28.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@28.1.3: + resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + dev: true + + /babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.0): + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0) + dev: true + + /babel-preset-jest@28.1.3(@babel/core@7.28.0): + resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.28.0 + babel-plugin-jest-hoist: 28.1.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /basic-auth@2.0.1: + resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} + engines: {node: '>= 0.8'} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + + /brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true + + /browser-process-hrtime@1.0.0: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + dev: true + + /browserslist@4.25.2: + resolution: {integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001733 + electron-to-chromium: 1.5.199 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.2) + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + dev: true + + /call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001733: + resolution: {integrity: sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==} + dev: true + + /catharsis@0.9.0: + resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} + engines: {node: '>= 10'} + dependencies: + lodash: 4.17.21 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + + /cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /corser@2.0.1: + resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==} + engines: {node: '>= 0.4.0'} + dev: true + + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + dev: true + + /cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + dev: true + + /cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + dependencies: + cssom: 0.3.8 + dev: true + + /data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + dev: true + + /debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + dev: true + + /dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff-sequences@28.1.1: + resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + dependencies: + webidl-conversions: 7.0.0 + dev: true + + /dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: true + + /electron-to-chromium@1.5.199: + resolution: {integrity: sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ==} + dev: true + + /emittery@0.10.2: + resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} + engines: {node: '>=12'} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + + /es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expect@28.1.3: + resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/expect-utils': 28.1.3 + jest-get-type: 28.0.2 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.1.0 + dev: true + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + dependencies: + whatwg-encoding: 2.0.0 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: true + + /http-server@14.1.1: + resolution: {integrity: sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==} + engines: {node: '>=12'} + hasBin: true + dependencies: + basic-auth: 2.0.1 + chalk: 4.1.2 + corser: 2.0.1 + he: 1.2.0 + html-encoding-sniffer: 3.0.0 + http-proxy: 1.18.1 + mime: 1.6.0 + minimist: 1.2.8 + opener: 1.5.2 + portfinder: 1.0.37 + secure-compare: 3.0.1 + union: 0.5.0 + url-join: 4.0.1 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.28.0 + '@babel/parser': 7.28.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jest-changed-files@28.1.3: + resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + execa: 5.1.1 + p-limit: 3.1.0 + dev: true + + /jest-circus@28.1.3: + resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + p-limit: 3.1.0 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-cli@28.1.3: + resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.2.0 + jest-config: 28.1.3(@types/node@24.2.1) + jest-util: 28.1.3 + jest-validate: 28.1.3 + prompts: 2.4.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest-config@28.1.3(@types/node@24.2.1): + resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.28.0 + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + babel-jest: 28.1.3(@babel/core@7.28.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 28.1.3 + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 28.1.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-diff@28.1.3: + resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 28.1.1 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-docblock@28.1.1: + resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@28.1.3: + resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + chalk: 4.1.2 + jest-get-type: 28.0.2 + jest-util: 28.1.3 + pretty-format: 28.1.3 + dev: true + + /jest-environment-jsdom@28.1.3: + resolution: {integrity: sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/jsdom': 16.2.15 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + jest-util: 28.1.3 + jsdom: 19.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node@28.1.3: + resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /jest-get-type@28.0.2: + resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /jest-haste-map@28.1.3: + resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 24.2.1 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + jest-worker: 28.1.3 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-leak-detector@28.1.3: + resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-matcher-utils@28.1.3: + resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-message-util@28.1.3: + resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 28.1.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@28.1.3: + resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@28.1.3): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 28.1.3 + dev: true + + /jest-regex-util@28.0.2: + resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dev: true + + /jest-resolve-dependencies@28.1.3: + resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + jest-regex-util: 28.0.2 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@28.1.3: + resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-pnp-resolver: 1.2.3(jest-resolve@28.1.3) + jest-util: 28.1.3 + jest-validate: 28.1.3 + resolve: 1.22.10 + resolve.exports: 1.1.1 + slash: 3.0.0 + dev: true + + /jest-runner@28.1.3: + resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/console': 28.1.3 + '@jest/environment': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + emittery: 0.10.2 + graceful-fs: 4.2.11 + jest-docblock: 28.1.1 + jest-environment-node: 28.1.3 + jest-haste-map: 28.1.3 + jest-leak-detector: 28.1.3 + jest-message-util: 28.1.3 + jest-resolve: 28.1.3 + jest-runtime: 28.1.3 + jest-util: 28.1.3 + jest-watcher: 28.1.3 + jest-worker: 28.1.3 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@28.1.3: + resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/globals': 28.1.3 + '@jest/source-map': 28.1.2 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + execa: 5.1.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot@28.1.3: + resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@babel/core': 7.28.0 + '@babel/generator': 7.28.0 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + '@jest/expect-utils': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/babel__traverse': 7.28.0 + '@types/prettier': 2.7.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) + chalk: 4.1.2 + expect: 28.1.3 + graceful-fs: 4.2.11 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + jest-haste-map: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + natural-compare: 1.4.0 + pretty-format: 28.1.3 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@28.1.3: + resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@28.1.3: + resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/types': 28.1.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 28.0.2 + leven: 3.1.0 + pretty-format: 28.1.3 + dev: true + + /jest-watcher@28.1.3: + resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.10.2 + jest-util: 28.1.3 + string-length: 4.0.2 + dev: true + + /jest-worker@28.1.3: + resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@types/node': 24.2.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@28.1.3: + resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/types': 28.1.3 + import-local: 3.2.0 + jest-cli: 28.1.3 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /js-cleanup@1.2.0: + resolution: {integrity: sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==} + engines: {node: ^10.14.2 || >=12.0.0} + dependencies: + magic-string: 0.25.9 + perf-regexes: 1.0.1 + skip-regex: 1.0.2 + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js2xmlparser@4.0.2: + resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} + dependencies: + xmlcreate: 2.0.4 + dev: true + + /jsdoc@3.6.11: + resolution: {integrity: sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + '@babel/parser': 7.28.0 + '@types/markdown-it': 12.2.3 + bluebird: 3.7.2 + catharsis: 0.9.0 + escape-string-regexp: 2.0.0 + js2xmlparser: 4.0.2 + klaw: 3.0.0 + markdown-it: 12.3.2 + markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) + marked: 4.3.0 + mkdirp: 1.0.4 + requizzle: 0.2.4 + strip-json-comments: 3.1.1 + taffydb: 2.6.2 + underscore: 1.13.7 + dev: true + + /jsdom@19.0.0: + resolution: {integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==} + engines: {node: '>=12'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.15.0 + acorn-globals: 6.0.0 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.6.0 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.4 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.21 + parse5: 6.0.1 + saxes: 5.0.1 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 3.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 10.0.0 + ws: 8.18.3 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /klaw@3.0.0: + resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} + dependencies: + graceful-fs: 4.2.11 + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} + dependencies: + uc.micro: 1.0.6 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.7.2 + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): + resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + dependencies: + '@types/markdown-it': 12.2.3 + markdown-it: 12.3.2 + dev: true + + /markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: true + + /marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + dev: true + + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + dev: true + + /mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.12 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} + dev: true + + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /perf-regexes@1.0.1: + resolution: {integrity: sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==} + engines: {node: '>=6.14'} + dev: true + + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /portfinder@1.0.37: + resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==} + engines: {node: '>= 10.12'} + dependencies: + async: 3.2.6 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /prettier@2.6.2: + resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-format@28.1.3: + resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + dependencies: + '@jest/schemas': 28.1.3 + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 18.3.1 + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + dependencies: + punycode: 2.3.1 + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.1.0 + dev: true + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + + /requizzle@0.2.4: + resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} + dependencies: + lodash: 4.17.21 + dev: true + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve.exports@1.1.1: + resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-cleanup@3.2.1(rollup@2.79.2): + resolution: {integrity: sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==} + engines: {node: ^10.14.2 || >=12.0.0} + peerDependencies: + rollup: '>=2.0' + dependencies: + js-cleanup: 1.2.0 + rollup: 2.79.2 + rollup-pluginutils: 2.8.2 + dev: true + + /rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + dependencies: + estree-walker: 0.6.1 + dev: true + + /rollup@2.79.2: + resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /secure-compare@3.0.1: + resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==} + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: true + + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /skip-regex@1.0.2: + resolution: {integrity: sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==} + engines: {node: '>=4.2'} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + dev: true + + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + dev: true + + /taffydb@2.6.2: + resolution: {integrity: sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==} + dev: true + + /terminal-link@2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + dev: true + + /terser@5.43.1: + resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.10 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + + /tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + dependencies: + punycode: 2.3.1 + dev: true + + /tsd-jsdoc@2.5.0(jsdoc@3.6.11): + resolution: {integrity: sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g==} + peerDependencies: + jsdoc: ^3.6.3 + dependencies: + jsdoc: 3.6.11 + typescript: 3.9.10 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /typescript@3.9.10: + resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: true + + /underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + dev: true + + /undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + dev: true + + /union@0.5.0: + resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==} + engines: {node: '>= 0.8.0'} + dependencies: + qs: 6.14.0 + dev: true + + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + + /update-browserslist-db@1.1.3(browserslist@4.25.2): + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.25.2 + escalade: 3.2.0 + picocolors: 1.1.1 + dev: true + + /url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + /v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + + /w3c-hr-time@1.0.2: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. + dependencies: + browser-process-hrtime: 1.0.0 + dev: true + + /w3c-xmlserializer@3.0.0: + resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} + engines: {node: '>=12'} + dependencies: + xml-name-validator: 4.0.0 + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: true + + /whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + dependencies: + iconv-lite: 0.6.3 + dev: true + + /whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + dev: true + + /whatwg-url@10.0.0: + resolution: {integrity: sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==} + engines: {node: '>=12'} + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + + /whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + dev: true + + /xmlcreate@2.0.4: + resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true From 9a9372c714ed7d6adfe98caa001b564047d73385 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 10:48:15 +0800 Subject: [PATCH 11/24] chore: replace remaining Chinese comment in typings fixture and ensure no Chinese in non-generated files --- tests/fixtures/typescript-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/typescript-test.ts b/tests/fixtures/typescript-test.ts index c4feb615..995f8cd4 100644 --- a/tests/fixtures/typescript-test.ts +++ b/tests/fixtures/typescript-test.ts @@ -173,7 +173,7 @@ const resizeEvent: number = eventType.resize; // Show mind map jm.show(nodeTreeData); -jm.show(); // 显示空白思维导图 +jm.show(); // Show an empty mind map // Query state const meta = jm.get_meta(); From fd1777dbc1dc48ef0015aeb5b20aa5688d76f837 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 10:53:14 +0800 Subject: [PATCH 12/24] docs(jsdoc): annotate jsMind.find_node_before param and return types\n\n- add JSDoc to generate (string | Node) input and (Node | null) return in generated .d.ts\n- regen declarations via tsc allowJs --- src/jsmind.js | 6 ++++++ types/generated/jsmind.d.ts | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/jsmind.js b/src/jsmind.js index 9f7d88df..de83daed 100644 --- a/src/jsmind.js +++ b/src/jsmind.js @@ -526,6 +526,12 @@ export default class jsMind { } this.view.center_node(node); } + /** + * Find the previous sibling node of the given node. + * + * @param {string | import('./jsmind.node.js').Node} node - Node id or Node instance + * @returns {import('./jsmind.node.js').Node | null} + */ find_node_before(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts index b140c838..3f573bfd 100644 --- a/types/generated/jsmind.d.ts +++ b/types/generated/jsmind.d.ts @@ -126,7 +126,13 @@ export default class jsMind { select_clear(): void; is_node_visible(node: any): boolean; scroll_node_to_center(node: any): void; - find_node_before(node: any): any; + /** + * Find the previous sibling node of the given node. + * + * @param {string | import('./jsmind.node.js').Node} node - Node id or Node instance + * @returns {import('./jsmind.node.js').Node | null} + */ + find_node_before(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; find_node_after(node: any): any; set_node_color(node_id: any, bg_color: any, fg_color: any): any; set_node_font_style(node_id: any, size: any, weight: any, style: any): any; From 91e974902f5a0fffba877d00c1ef528c2a8d6c3a Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 12:31:30 +0800 Subject: [PATCH 13/24] feat(types): add JSDoc annotations and prepublish type generation - Add comprehensive JSDoc annotations to all JavaScript source files - Add prepublishOnly script to automatically generate .d.ts files before npm publish - Regenerate TypeScript declarations with improved type information - Ensure type definitions are always up-to-date for releases --- .github/workflows/npm-publish.yml | 4 +- package.json | 3 +- src/jsmind.common.js | 24 ++ src/jsmind.data_provider.js | 16 + src/jsmind.dom.js | 34 ++ src/jsmind.format.js | 45 +++ src/jsmind.graph.js | 68 ++++ src/jsmind.js | 139 ++++++++ src/jsmind.layout_provider.js | 114 +++++- src/jsmind.mind.js | 95 +++++ src/jsmind.node.js | 36 ++ src/jsmind.option.js | 36 ++ src/jsmind.plugin.js | 19 +- src/jsmind.shortcut_provider.js | 61 ++++ src/jsmind.util.js | 9 + src/jsmind.view_provider.js | 114 ++++++ src/plugins/jsmind.draggable-node.js | 159 ++++++++- src/plugins/jsmind.screenshot.js | 67 +++- tsconfig.decls.json | 1 + types/generated/jsmind.common.d.ts | 77 ++-- types/generated/jsmind.d.ts | 290 ++++++++++----- types/generated/jsmind.data_provider.d.ts | 52 ++- types/generated/jsmind.dom.d.ts | 46 ++- types/generated/jsmind.format.d.ts | 168 +++------ types/generated/jsmind.graph.d.ts | 178 ++++++++-- types/generated/jsmind.layout_provider.d.ts | 181 ++++++++-- types/generated/jsmind.mind.d.ts | 120 ++++++- types/generated/jsmind.node.d.ts | 64 +++- types/generated/jsmind.option.d.ts | 54 ++- types/generated/jsmind.plugin.d.ts | 24 +- types/generated/jsmind.shortcut_provider.d.ts | 101 +++++- types/generated/jsmind.util.d.ts | 43 ++- types/generated/jsmind.view_provider.d.ts | 332 ++++++++++++++---- .../plugins/jsmind.draggable-node.d.ts | 230 +++++++++++- .../generated/plugins/jsmind.screenshot.d.ts | 84 ++++- 35 files changed, 2613 insertions(+), 475 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 6b9a1ff7..302a3b63 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18.x - - run: npm ci + - run: npm ci && npm run gen:dts:check - run: npm test publish-npm: @@ -28,7 +28,7 @@ jobs: node-version: 18.x registry-url: https://registry.npmjs.org/ - run: npm ci - - run: npm run build + - run: npm run gen:dts && npm run build - run: npm publish env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} diff --git a/package.json b/package.json index 582e1a0a..06f22c29 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "gen:dts": "tsc -p tsconfig.decls.json", "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", "format": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --write .", - "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check ." + "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check .", + "prepublishOnly": "npm run gen:dts" }, "repository": { "type": "git", diff --git a/src/jsmind.common.js b/src/jsmind.common.js index e52468c2..895b7e9d 100644 --- a/src/jsmind.common.js +++ b/src/jsmind.common.js @@ -6,7 +6,15 @@ * https://github.com/hizzgdev/jsmind/ */ +/** + * Library version string. + * @type {string} + */ export const __version__ = '0.8.7'; +/** + * Library author. + * @type {string} + */ export const __author__ = 'hizzgdev@163.com'; if (typeof String.prototype.startsWith != 'function') { @@ -15,6 +23,11 @@ if (typeof String.prototype.startsWith != 'function') { }; } +/** + * Direction constants and parser. + * @typedef {{left:number,center:number,right:number,of:(dir:(string|number))=>number|undefined}} DirectionType + */ +/** @type {DirectionType} */ export const Direction = { left: -1, center: 0, @@ -37,12 +50,19 @@ export const Direction = { } }, }; +/** @enum {number} */ export const EventType = { show: 1, resize: 2, edit: 3, select: 4 }; +/** @enum {number} */ export const Key = { meta: 1 << 13, ctrl: 1 << 12, alt: 1 << 11, shift: 1 << 10 }; +/** @enum {number} */ export const LogLevel = { debug: 1, info: 2, warn: 3, error: 4, disable: 9 }; // an noop function define var _noop = function () {}; +/** + * Logger facade with dynamic level. + * @type {{level:(lvl:number)=>void,log:Function,debug:Function,info:Function,warn:Function,error:Function}} + */ export let logger = typeof console === 'undefined' ? { @@ -62,6 +82,10 @@ export let logger = error: console.error, }; +/** + * Set logger level. + * @param {number} log_level + */ function setup_logger_level(log_level) { if (log_level > LogLevel.debug) { logger.debug = _noop; diff --git a/src/jsmind.data_provider.js b/src/jsmind.data_provider.js index 78019c05..016bf26c 100644 --- a/src/jsmind.data_provider.js +++ b/src/jsmind.data_provider.js @@ -10,16 +10,27 @@ import { logger } from './jsmind.common.js'; import { format } from './jsmind.format.js'; export class DataProvider { + /** + * Data provider: loads and serializes mind data by format. + * @param {import('./jsmind.js').default} jm - jsMind instance + */ constructor(jm) { this.jm = jm; } + /** Initialize data provider. */ init() { logger.debug('data.init'); } + /** Reset data provider state. */ reset() { logger.debug('data.reset'); } + /** + * Load a Mind from mixed source. + * @param {any} mind_data - object with {format,data} or a format-specific payload + * @returns {import('./jsmind.mind.js').Mind|null} + */ load(mind_data) { var df = null; var mind = null; @@ -46,6 +57,11 @@ export class DataProvider { } return mind; } + /** + * Serialize current mind to target format. + * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format + * @returns {any} + */ get_data(data_format) { var data = null; if (data_format == 'node_array') { diff --git a/src/jsmind.dom.js b/src/jsmind.dom.js index 32f56244..39308f50 100644 --- a/src/jsmind.dom.js +++ b/src/jsmind.dom.js @@ -6,16 +6,34 @@ * https://github.com/hizzgdev/jsmind/ */ +/** + * Lightweight DOM helpers bound to a window. + */ class Dom { constructor(w) { this.w = w; this.d = w.document; + /** + * Get element by id. + * @param {string} id + * @returns {HTMLElement|null} + */ this.g = function (id) { return this.d.getElementById(id); }; + /** + * Create element with given tag. + * @param {string} tag + * @returns {HTMLElement} + */ this.c = function (tag) { return this.d.createElement(tag); }; + /** + * Set text content for element. + * @param {HTMLElement} n + * @param {string} t + */ this.t = function (n, t) { if (n.hasChildNodes()) { n.firstChild.nodeValue = t; @@ -24,6 +42,11 @@ class Dom { } }; + /** + * Set inner HTML or append element. + * @param {HTMLElement} n + * @param {string|HTMLElement} t + */ this.h = function (n, t) { if (t instanceof HTMLElement) { n.innerHTML = ''; @@ -33,6 +56,11 @@ class Dom { } }; // detect isElement + /** + * Runtime check for HTMLElement. + * @param {any} el + * @returns {el is HTMLElement} + */ this.i = function (el) { return ( !!el && @@ -44,6 +72,12 @@ class Dom { }; //target,eventType,handler + /** + * Add event listener with legacy fallback. + * @param {HTMLElement} t + * @param {string} e + * @param {(ev:Event)=>void} h + */ this.on = function (t, e, h) { if (!!t.addEventListener) { t.addEventListener(e, h, false); diff --git a/src/jsmind.format.js b/src/jsmind.format.js index b26dc553..5c1b8978 100644 --- a/src/jsmind.format.js +++ b/src/jsmind.format.js @@ -11,8 +11,19 @@ import { Mind } from './jsmind.mind.js'; import { Node } from './jsmind.node.js'; import { util } from './jsmind.util.js'; +/** @typedef {{name:string,author:string,version:string}} MindMapMeta */ +/** @type {MindMapMeta} */ const DEFAULT_META = { name: 'jsMind', author: __author__, version: __version__ }; +/** + * Mind data format handlers. + * @type {{ + * node_tree: { example:{meta:MindMapMeta,format:'node_tree',data:any}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * node_array: { example:{meta:MindMapMeta,format:'node_array',data:any[]}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } + * }} + */ export const format = { node_tree: { example: { @@ -20,6 +31,7 @@ export const format = { format: 'node_tree', data: { id: 'root', topic: 'jsMind node_tree example' }, }, + /** @param {{meta:MindMapMeta,data:any}} source @returns {Mind} */ get_mind: function (source) { var df = format.node_tree; var mind = new Mind(); @@ -29,6 +41,7 @@ export const format = { df._parse(mind, source.data); return mind; }, + /** @param {Mind} mind */ get_data: function (mind) { var df = format.node_tree; var json = {}; @@ -42,6 +55,7 @@ export const format = { return json; }, + /** @param {Mind} mind @param {{id:string,topic:string,children?:any[]}} node_root */ _parse: function (mind, node_root) { var df = format.node_tree; var data = df._extract_data(node_root); @@ -54,6 +68,12 @@ export const format = { } }, + /** + * Extract custom data from node JSON, excluding standard properties. + * @private + * @param {any} node_json - Node JSON object + * @returns {Record} Custom data object + */ _extract_data: function (node_json) { var data = {}; for (var k in node_json) { @@ -71,6 +91,7 @@ export const format = { return data; }, + /** @param {Mind} mind @param {Node} node_parent @param {{id:string,topic:string,children?:any[]}} node_json */ _extract_subnode: function (mind, node_parent, node_json) { var df = format.node_tree; var data = df._extract_data(node_json); @@ -94,6 +115,12 @@ export const format = { } }, + /** + * Build JSON object from a node. + * @private + * @param {Node} node - Node to convert + * @returns {any} JSON representation of node + */ _build_node: function (node) { var df = format.node_tree; if (!(node instanceof Node)) { @@ -131,6 +158,7 @@ export const format = { data: [{ id: 'root', topic: 'jsMind node_array example', isroot: true }], }, + /** @param {{meta:MindMapMeta,data:any[]}} source @returns {Mind} */ get_mind: function (source) { var df = format.node_array; var mind = new Mind(); @@ -141,6 +169,7 @@ export const format = { return mind; }, + /** @param {Mind} mind */ get_data: function (mind) { var df = format.node_array; var json = {}; @@ -155,6 +184,7 @@ export const format = { return json; }, + /** @param {Mind} mind @param {any[]} node_array */ _parse: function (mind, node_array) { var df = format.node_array; var nodes = node_array.slice(0); @@ -168,6 +198,7 @@ export const format = { } }, + /** @param {Mind} mind @param {any[]} node_array */ _extract_root: function (mind, node_array) { var df = format.node_array; var i = node_array.length; @@ -183,6 +214,7 @@ export const format = { return null; }, + /** @param {Mind} mind @param {Node} parent_node @param {any[]} node_array */ _extract_subnode: function (mind, parent_node, node_array) { var df = format.node_array; var i = node_array.length; @@ -237,11 +269,13 @@ export const format = { return data; }, + /** @param {Mind} mind @param {any[]} node_array */ _array: function (mind, node_array) { var df = format.node_array; df._array_node(mind.root, node_array); }, + /** @param {Node} node @param {any[]} node_array */ _array_node: function (node, node_array) { var df = format.node_array; if (!(node instanceof Node)) { @@ -281,6 +315,7 @@ export const format = { format: 'freemind', data: '', }, + /** @param {{meta:MindMapMeta,data:string}} source @returns {Mind} */ get_mind: function (source) { var df = format.freemind; var mind = new Mind(); @@ -311,6 +346,7 @@ export const format = { return json; }, + /** @param {string} xml */ _parse_xml: function (xml) { var xml_doc = null; if (window.DOMParser) { @@ -325,6 +361,7 @@ export const format = { return xml_doc; }, + /** @param {Document} xml_doc */ _find_root: function (xml_doc) { var nodes = xml_doc.childNodes; var node = null; @@ -351,6 +388,7 @@ export const format = { return node; }, + /** @param {Mind} mind @param {Node|null} parent_node @param {Element} xml_node */ _load_node: function (mind, parent_node, xml_node) { var df = format.freemind; var node_id = xml_node.getAttribute('ID'); @@ -411,6 +449,7 @@ export const format = { } }, + /** @param {Element} xml_node */ _load_attributes: function (xml_node) { var children = xml_node.childNodes; var attr = null; @@ -424,6 +463,7 @@ export const format = { return attr_data; }, + /** @param {Node} node @param {string[]} xml_lines */ _build_map: function (node, xml_lines) { var df = format.freemind; var pos = null; @@ -467,6 +507,7 @@ export const format = { xml_lines.push(''); }, + /** @param {string} text */ _escape: function (text) { return text .replace(/&/g, '&') @@ -483,6 +524,7 @@ export const format = { data: 'jsMind text example\n node1\n node1-sub\n node1-sub\n node2', }, _line_regex: /\s*/, + /** @param {{meta:MindMapMeta,data:string}} source @returns {Mind} */ get_mind: function (source) { var df = format.text; var mind = new Mind(); @@ -494,6 +536,7 @@ export const format = { return mind; }, + /** @param {Mind} mind @param {string[]} lines */ _fill_nodes: function (mind, lines) { let node_path = []; let i = 0; @@ -533,6 +576,7 @@ export const format = { node_path.length = 0; }, + /** @param {Mind} mind */ get_data: function (mind) { var df = format.text; var json = {}; @@ -548,6 +592,7 @@ export const format = { return json; }, + /** @param {string[]} lines @param {Node[]} nodes @param {number} level */ _build_lines: function (lines, nodes, level) { let prefix = new Array(level + 1).join(' '); for (let node of nodes) { diff --git a/src/jsmind.graph.js b/src/jsmind.graph.js index 5914f7fb..080da94c 100644 --- a/src/jsmind.graph.js +++ b/src/jsmind.graph.js @@ -9,7 +9,14 @@ import { $ } from './jsmind.dom.js'; import { logger } from './jsmind.common.js'; +/** + * SVG-based graph renderer. + */ class SvgGraph { + /** + * Create SVG graph renderer. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + */ constructor(view) { this.view = view; this.opts = view.opts; @@ -23,9 +30,11 @@ class SvgGraph { }; this.init_line_render(); } + /** @param {string} tag */ static c(tag) { return $.d.createElementNS('http://www.w3.org/2000/svg', tag); } + /** Choose line drawing renderer. */ init_line_render() { if (typeof this.opts.custom_line_render === 'function') { this.drawing = (path, x1, y1, x2, y2) => { @@ -43,9 +52,11 @@ class SvgGraph { this.drawing = this.line_drawing[this.opts.line_style] || this.line_drawing.curved; } } + /** @returns {SVGSVGElement} */ element() { return this.e_svg; } + /** @param {number} w @param {number} h */ set_size(w, h) { this.size.w = w; this.size.h = h; @@ -59,6 +70,7 @@ class SvgGraph { } this.lines.length = 0; } + /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ draw_line(pout, pin, offset, color) { var line = SvgGraph.c('path'); line.setAttribute('stroke', color || this.opts.line_color); @@ -75,6 +87,7 @@ class SvgGraph { ); } + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ copy_to(dest_canvas_ctx, callback) { var img = new Image(); img.onload = function () { @@ -84,6 +97,15 @@ class SvgGraph { img.src = 'data:image/svg+xml;base64,' + btoa(new XMLSerializer().serializeToString(this.e_svg)); } + /** + * Draw bezier curve to SVG path. + * @internal + * @param {SVGPathElement} path - SVG path element + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ _bezier_to(path, x1, y1, x2, y2) { path.setAttribute( 'd', @@ -105,12 +127,28 @@ class SvgGraph { y2 ); } + /** + * Draw straight line to SVG path. + * @internal + * @param {SVGPathElement} path - SVG path element + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ _line_to(path, x1, y1, x2, y2) { path.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' L ' + x2 + ' ' + y2); } } +/** + * Canvas-based graph renderer. + */ class CanvasGraph { + /** + * Create canvas graph renderer. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + */ constructor(view) { this.opts = view.opts; this.e_canvas = $.c('canvas'); @@ -124,6 +162,7 @@ class CanvasGraph { this.dpr = view.device_pixel_ratio; this.init_line_render(); } + /** Choose line drawing renderer. */ init_line_render() { if (typeof this.opts.custom_line_render === 'function') { this.drawing = (ctx, x1, y1, x2, y2) => { @@ -141,9 +180,11 @@ class CanvasGraph { this.drawing = this.line_drawing[this.opts.line_style] || this.line_drawing.curved; } } + /** @returns {HTMLCanvasElement} */ element() { return this.e_canvas; } + /** @param {number} w @param {number} h */ set_size(w, h) { this.size.w = w; this.size.h = h; @@ -160,9 +201,11 @@ class CanvasGraph { } } + /** Clear the canvas. */ clear() { this.canvas_ctx.clearRect(0, 0, this.size.w, this.size.h); } + /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ draw_line(pout, pin, offset, color) { var ctx = this.canvas_ctx; ctx.strokeStyle = color || this.opts.line_color; @@ -170,16 +213,35 @@ class CanvasGraph { ctx.lineCap = 'round'; this.drawing(ctx, pin.x + offset.x, pin.y + offset.y, pout.x + offset.x, pout.y + offset.y); } + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ copy_to(dest_canvas_ctx, callback) { dest_canvas_ctx.drawImage(this.e_canvas, 0, 0, this.size.w, this.size.h); !!callback && callback(); } + /** + * Draw bezier curve on canvas. + * @internal + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ _bezier_to(ctx, x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.bezierCurveTo(x1 + ((x2 - x1) * 2) / 3, y1, x1, y2, x2, y2); ctx.stroke(); } + /** + * Draw straight line on canvas. + * @internal + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ _line_to(ctx, x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); @@ -188,6 +250,12 @@ class CanvasGraph { } } +/** + * Initialize graph renderer based on engine type. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + * @param {'canvas'|'svg'} engine - Rendering engine type + * @returns {SvgGraph|CanvasGraph} Graph renderer instance + */ export function init_graph(view, engine) { return engine.toLowerCase() === 'svg' ? new SvgGraph(view) : new CanvasGraph(view); } diff --git a/src/jsmind.js b/src/jsmind.js index de83daed..4525853f 100644 --- a/src/jsmind.js +++ b/src/jsmind.js @@ -19,6 +19,9 @@ import { format } from './jsmind.format.js'; import { $ } from './jsmind.dom.js'; import { util as _util } from './jsmind.util.js'; +/** + * jsMind runtime: orchestrates data/layout/view/shortcut and exposes public API. + */ export default class jsMind { static mind = Mind; static node = Node; @@ -29,6 +32,10 @@ export default class jsMind { static register_plugin = _register_plugin; static util = _util; + /** + * Create a jsMind instance. + * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options + */ constructor(options) { jsMind.current = this; this.options = merge_option(options); @@ -40,6 +47,7 @@ export default class jsMind { this.init(); } + /** Initialize sub-systems and plugins. */ init() { if (!!this.initialized) { return; @@ -85,34 +93,52 @@ export default class jsMind { apply_plugins(this, this.options.plugin); } + /** @returns {boolean} whether current mind map is editable */ get_editable() { return this.options.editable; } + /** enable editing */ enable_edit() { this.options.editable = true; } + /** disable editing */ disable_edit() { this.options.editable = false; } + /** @returns {boolean} whether view is draggable */ get_view_draggable() { return this.options.view.draggable; } + /** enable view dragging */ enable_view_draggable() { this.options.view.draggable = true; this.view.setup_canvas_draggable(true); } + /** disable view dragging */ disable_view_draggable() { this.options.view.draggable = false; this.view.setup_canvas_draggable(false); } // options are 'mousedown', 'click', 'dblclick', 'mousewheel' + /** + * Enable default event handle. + * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle + */ enable_event_handle(event_handle) { this.options.default_event_handle['enable_' + event_handle + '_handle'] = true; } // options are 'mousedown', 'click', 'dblclick', 'mousewheel' + /** + * Disable default event handle. + * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle + */ disable_event_handle(event_handle) { this.options.default_event_handle['enable_' + event_handle + '_handle'] = false; } + /** + * Set theme name. + * @param {string|null} theme + */ set_theme(theme) { var theme_old = this.options.theme; this.options.theme = !!theme ? theme : null; @@ -121,12 +147,14 @@ export default class jsMind { this.view.reset_custom_style(); } } + /** bind internal DOM events */ _event_bind() { this.view.add_event(this, 'mousedown', this.mousedown_handle); this.view.add_event(this, 'click', this.click_handle); this.view.add_event(this, 'dblclick', this.dblclick_handle); this.view.add_event(this, 'wheel', this.mousewheel_handle, true); } + /** @param {MouseEvent} e */ mousedown_handle(e) { if (!this.options.default_event_handle['enable_mousedown_handle']) { return; @@ -141,6 +169,7 @@ export default class jsMind { this.select_clear(); } } + /** @param {MouseEvent} e */ click_handle(e) { if (!this.options.default_event_handle['enable_click_handle']) { return; @@ -154,6 +183,7 @@ export default class jsMind { } } } + /** @param {MouseEvent} e */ dblclick_handle(e) { if (!this.options.default_event_handle['enable_dblclick_handle']) { return; @@ -170,6 +200,7 @@ export default class jsMind { } } // Use [Ctrl] + Mousewheel, to zoom in/out. + /** @param {WheelEvent} e */ mousewheel_handle(e) { // Test if mousewheel option is enabled and Ctrl key is pressed. var kc = (e.metaKey << 13) + (e.ctrlKey << 12) + (e.altKey << 11) + (e.shiftKey << 10); @@ -189,6 +220,11 @@ export default class jsMind { this.view.zoom_out(evt); } } + /** + * Begin editing a node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {boolean|void} + */ begin_edit(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -206,9 +242,14 @@ export default class jsMind { return; } } + /** End editing */ end_edit() { this.view.edit_node_end(); } + /** + * Toggle a node's expanded state. + * @param {string | import('./jsmind.node.js').Node} node + */ toggle_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -227,6 +268,10 @@ export default class jsMind { this.view.relayout(); this.view.restore_location(node); } + /** + * Expand a node. + * @param {string | import('./jsmind.node.js').Node} node + */ expand_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -245,6 +290,10 @@ export default class jsMind { this.view.relayout(); this.view.restore_location(node); } + /** + * Collapse a node. + * @param {string | import('./jsmind.node.js').Node} node + */ collapse_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -263,23 +312,32 @@ export default class jsMind { this.view.relayout(); this.view.restore_location(node); } + /** Expand all nodes */ expand_all() { this.layout.expand_all(); this.view.relayout(); } + /** Collapse all nodes */ collapse_all() { this.layout.collapse_all(); this.view.relayout(); } + /** @param {number} depth */ expand_to_depth(depth) { this.layout.expand_to_depth(depth); this.view.relayout(); } + /** reset view/layout/data */ _reset() { this.view.reset(); this.layout.reset(); this.data.reset(); } + /** + * Internal show flow. + * @param {any} mind + * @param {boolean=} skip_centering + */ _show(mind, skip_centering) { var m = mind || format.node_array.example; this.mind = this.data.load(m); @@ -301,10 +359,16 @@ export default class jsMind { this.invoke_event_handle(EventType.show, { data: [mind] }); } + /** + * Show a mind (or example) on the canvas. + * @param {any} mind + * @param {boolean=} skip_centering + */ show(mind, skip_centering) { this._reset(); this._show(mind, skip_centering); } + /** @returns {{name:string,author:string,version:string}} */ get_meta() { return { name: this.mind.name, @@ -312,19 +376,38 @@ export default class jsMind { version: this.mind.version, }; } + /** + * Serialize current mind to given format. + * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] + * @returns {any} + */ get_data(data_format) { var df = data_format || 'node_tree'; return this.data.get_data(df); } + /** @returns {import('./jsmind.node.js').Node} */ get_root() { return this.mind.root; } + /** + * @param {string | import('./jsmind.node.js').Node} node + * @returns {import('./jsmind.node.js').Node} + */ get_node(node) { if (Node.is_node(node)) { return node; } return this.mind.get_node(node); } + /** + * Add a node under parent. + * @param {string | import('./jsmind.node.js').Node} parent_node + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ add_node(parent_node, node_id, topic, data, direction) { if (this.get_editable()) { var the_parent_node = this.get_node(parent_node); @@ -351,6 +434,15 @@ export default class jsMind { return null; } } + /** + * Insert a node before target node. + * @param {string | import('./jsmind.node.js').Node} node_before + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ insert_node_before(node_before, node_id, topic, data, direction) { if (this.get_editable()) { var the_node_before = this.get_node(node_before); @@ -375,6 +467,15 @@ export default class jsMind { return null; } } + /** + * Insert a node after target node. + * @param {string | import('./jsmind.node.js').Node} node_after + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ insert_node_after(node_after, node_id, topic, data, direction) { if (this.get_editable()) { var the_node_after = this.get_node(node_after); @@ -399,6 +500,11 @@ export default class jsMind { return null; } } + /** + * Remove a node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {boolean} + */ remove_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -434,6 +540,7 @@ export default class jsMind { return false; } } + /** @param {string} node_id @param {string} topic */ update_node(node_id, topic) { if (this.get_editable()) { if (_util.text.is_empty(topic)) { @@ -462,6 +569,13 @@ export default class jsMind { return; } } + /** + * Move a node and optionally change direction. + * @param {string} node_id + * @param {string=} before_id + * @param {string=} parent_id + * @param {number=} direction + */ move_node(node_id, before_id, parent_id, direction) { if (this.get_editable()) { var node = this.get_node(node_id); @@ -481,6 +595,7 @@ export default class jsMind { return; } } + /** @param {string | import('./jsmind.node.js').Node} node */ select_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -498,6 +613,7 @@ export default class jsMind { this.view.select_node(node); this.invoke_event_handle(EventType.select, { evt: 'select_node', data: [], node: node.id }); } + /** @returns {import('./jsmind.node.js').Node|null} */ get_selected_node() { if (!!this.mind) { return this.mind.selected; @@ -505,15 +621,18 @@ export default class jsMind { return null; } } + /** clear selection */ select_clear() { if (!!this.mind) { this.mind.selected = null; this.view.select_clear(); } } + /** @param {string | import('./jsmind.node.js').Node} node */ is_node_visible(node) { return this.layout.is_visible(node); } + /** @param {string | import('./jsmind.node.js').Node} node */ scroll_node_to_center(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -564,6 +683,11 @@ export default class jsMind { } return n; } + /** + * Find the next sibling node of the given node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {import('./jsmind.node.js').Node | null} + */ find_node_after(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -599,6 +723,7 @@ export default class jsMind { } return n; } + /** @param {string} node_id @param {string=} bg_color @param {string=} fg_color */ set_node_color(node_id, bg_color, fg_color) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -616,6 +741,7 @@ export default class jsMind { return null; } } + /** @param {string} node_id @param {number=} size @param {string=} weight @param {string=} style */ set_node_font_style(node_id, size, weight, style) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -639,6 +765,7 @@ export default class jsMind { return null; } } + /** @param {string} node_id @param {string} image @param {number=} width @param {number=} height @param {number=} rotation */ set_node_background_image(node_id, image, width, height, rotation) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -665,6 +792,7 @@ export default class jsMind { return null; } } + /** @param {string} node_id @param {number} rotation */ set_node_background_rotation(node_id, rotation) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -686,24 +814,29 @@ export default class jsMind { return null; } } + /** trigger view resize */ resize() { this.view.resize(); } // callback(type ,data) + /** @param {(type:number, data:any)=>void} callback */ add_event_listener(callback) { if (typeof callback === 'function') { this.event_handles.push(callback); } } + /** clear event listeners */ clear_event_listener() { this.event_handles = []; } + /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ invoke_event_handle(type, data) { var j = this; $.w.setTimeout(function () { j._invoke_event_handle(type, data); }, 0); } + /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ _invoke_event_handle(type, data) { var l = this.event_handles.length; for (var i = 0; i < l; i++) { @@ -711,6 +844,12 @@ export default class jsMind { } } + /** + * Deprecated: static show constructor helper. + * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options + * @param {any} mind + * @returns {jsMind} + */ static show(options, mind) { logger.warn( '`jsMind.show(options, mind)` is deprecated, please use `jm = new jsMind(options); jm.show(mind);` instead' diff --git a/src/jsmind.layout_provider.js b/src/jsmind.layout_provider.js index dc06fa74..04b63833 100644 --- a/src/jsmind.layout_provider.js +++ b/src/jsmind.layout_provider.js @@ -8,6 +8,11 @@ import { logger, Direction, EventType } from './jsmind.common.js'; export class LayoutProvider { + /** + * Layout engine for positioning nodes and lines. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{mode:'full'|'side', hspace:number, vspace:number, pspace:number, cousin_space:number}} options - Layout configuration options + */ constructor(jm, options) { this.opts = options; this.jm = jm; @@ -16,13 +21,20 @@ export class LayoutProvider { this.cache_valid = false; } + /** Initialize layout provider. */ init() { logger.debug('layout.init'); } + /** Reset layout state and bounds. */ reset() { logger.debug('layout.reset'); this.bounds = { n: 0, s: 0, w: 0, e: 0 }; } + /** + * Decide the next child's direction for a parent node. + * @param {import('./jsmind.node.js').Node} node + * @returns {number} + */ calculate_next_child_direction(node) { if (this.isside) { return Direction.right; @@ -39,14 +51,20 @@ export class LayoutProvider { } return children_len > 1 && r > 0 ? Direction.left : Direction.right; } + /** Perform layout and offsets recalculation. */ layout() { logger.debug('layout.layout'); this.layout_direction(); this.layout_offset(); } + /** Calculate and set direction for all nodes. */ layout_direction() { this._layout_direction_root(); } + /** + * Set direction layout for root node and its children. + * @private + */ _layout_direction_root() { var node = this.jm.mind.root; var layout_data = null; @@ -78,6 +96,13 @@ export class LayoutProvider { } } } + /** + * Set direction layout for a node and its descendants. + * @private + * @param {import('./jsmind.node.js').Node} node - Target node + * @param {number} direction - Direction constant (-1, 0, 1) + * @param {number} side_index - Index among siblings + */ _layout_direction_side(node, direction, side_index) { var layout_data = null; if ('layout' in node._data) { @@ -96,6 +121,7 @@ export class LayoutProvider { this._layout_direction_side(children[i], direction, i); } } + /** Calculate and set position offsets for all nodes. */ layout_offset() { var node = this.jm.mind.root; var layout_data = node._data.layout; @@ -124,7 +150,12 @@ export class LayoutProvider { this.bounds.n = 0; this.bounds.s = Math.max(layout_data.outer_height_left, layout_data.outer_height_right); } - // layout both the x and y axis + /** + * Layout both the x and y axis for subnodes. + * @private + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout + * @returns {number} Total height of all nodes + */ _layout_offset_subnodes(nodes) { var total_height = 0; var nodes_count = nodes.length; @@ -175,7 +206,12 @@ export class LayoutProvider { } return total_height; } - // layout the y axis only, for collapse/expand a node + /** + * Layout the y axis only, for collapse/expand a node. + * @private + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout + * @returns {number} Total height of all nodes + */ _layout_offset_subnodes_height(nodes) { var total_height = 0; var nodes_count = nodes.length; @@ -217,9 +253,20 @@ export class LayoutProvider { } return total_height; } + /** + * Check if node should reserve cousin space. + * @private + * @param {import('./jsmind.node.js').Node} node - Node to check + * @returns {boolean} True if cousin space should be reserved + */ _should_reserve_cousin_space(node) { return node.children.length > 0 && node.parent.children.length > 1; } + /** + * Get absolute offset for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Absolute position offset + */ get_node_offset(node) { var layout_data = node._data.layout; var offset_cache = null; @@ -242,6 +289,11 @@ export class LayoutProvider { } return offset_cache; } + /** + * Get anchor point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Anchor point coordinates + */ get_node_point(node) { var view_data = node._data.view; var offset_p = this.get_node_offset(node); @@ -250,10 +302,20 @@ export class LayoutProvider { p.y = offset_p.y - view_data.height / 2; return p; } + /** + * Get input point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Input point coordinates + */ get_node_point_in(node) { var p = this.get_node_offset(node); return p; } + /** + * Get output point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Output point coordinates + */ get_node_point_out(node) { var layout_data = node._data.layout; var pout_cache = null; @@ -277,6 +339,11 @@ export class LayoutProvider { } return pout_cache; } + /** + * Get expander point for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Expander point coordinates + */ get_expander_point(node) { var p = this.get_node_point_out(node); var ex_p = {}; @@ -288,6 +355,10 @@ export class LayoutProvider { ex_p.y = p.y - Math.ceil(this.opts.pspace / 2); return ex_p; } + /** + * Get minimal canvas size to contain all nodes. + * @returns {{w:number, h:number}} Minimum size required + */ get_min_size() { var nodes = this.jm.mind.nodes; var node = null; @@ -307,6 +378,10 @@ export class LayoutProvider { h: this.bounds.s - this.bounds.n, }; } + /** + * Toggle node expanded/collapsed state. + * @param {import('./jsmind.node.js').Node} node - Target node + */ toggle_node(node) { if (node.isroot) { return; @@ -317,6 +392,10 @@ export class LayoutProvider { this.expand_node(node); } } + /** + * Expand a node and show its children. + * @param {import('./jsmind.node.js').Node} node - Target node + */ expand_node(node) { node.expanded = true; this.part_layout(node); @@ -327,6 +406,10 @@ export class LayoutProvider { node: node.id, }); } + /** + * Collapse a node and hide its children. + * @param {import('./jsmind.node.js').Node} node - Target node + */ collapse_node(node) { node.expanded = false; this.part_layout(node); @@ -337,6 +420,7 @@ export class LayoutProvider { node: node.id, }); } + /** Expand all nodes in the mind map. */ expand_all() { var nodes = this.jm.mind.nodes; var c = 0; @@ -354,6 +438,7 @@ export class LayoutProvider { this.set_visible(root.children, true); } } + /** Collapse all nodes in the mind map. */ collapse_all() { var nodes = this.jm.mind.nodes; var c = 0; @@ -371,6 +456,12 @@ export class LayoutProvider { this.set_visible(root.children, true); } } + /** + * Expand nodes to a specific depth level. + * @param {number} target_depth - Target depth level + * @param {import('./jsmind.node.js').Node[]=} curr_nodes - Current nodes to process + * @param {number=} curr_depth - Current depth level + */ expand_to_depth(target_depth, curr_nodes, curr_depth) { if (target_depth < 1) { return; @@ -394,6 +485,10 @@ export class LayoutProvider { } } } + /** + * Perform partial layout for a node and its subtree. + * @param {import('./jsmind.node.js').Node} node - Target node + */ part_layout(node) { var root = this.jm.mind.root; if (!!root) { @@ -425,6 +520,11 @@ export class LayoutProvider { logger.warn('can not found root node'); } } + /** + * Set visibility for nodes and their children. + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes + * @param {boolean} visible - Visibility state + */ set_visible(nodes, visible) { var i = nodes.length; var node = null; @@ -442,9 +542,19 @@ export class LayoutProvider { } } } + /** + * Check if a node is expanded. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {boolean} True if node is expanded + */ is_expand(node) { return node.expanded; } + /** + * Check if a node is visible. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {boolean} True if node is visible + */ is_visible(node) { var layout_data = node._data.layout; if ('visible' in layout_data && !layout_data.visible) { diff --git a/src/jsmind.mind.js b/src/jsmind.mind.js index 62999d83..5815f923 100644 --- a/src/jsmind.mind.js +++ b/src/jsmind.mind.js @@ -10,6 +10,9 @@ import { Node } from './jsmind.node.js'; import { logger, Direction } from './jsmind.common.js'; export class Mind { + /** + * Mind model: holds nodes and selection. + */ constructor() { this.name = null; this.author = null; @@ -18,6 +21,11 @@ export class Mind { this.selected = null; this.nodes = {}; } + /** + * Get a node by id. + * @param {string} node_id + * @returns {Node | null} + */ get_node(node_id) { if (node_id in this.nodes) { return this.nodes[node_id]; @@ -26,6 +34,13 @@ export class Mind { return null; } } + /** + * Set the root node, only once. + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @returns {Node | null} + */ set_root(node_id, topic, data) { if (this.root == null) { this.root = new Node(node_id, 0, topic, data, true); @@ -36,6 +51,17 @@ export class Mind { return null; } } + /** + * Add a child node under parent. + * @param {Node} parent_node + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @param {boolean=} expanded + * @param {number=} idx + * @returns {Node | null} + */ add_node(parent_node, node_id, topic, data, direction, expanded, idx) { if (!Node.is_node(parent_node)) { logger.error('the parent_node ' + parent_node + ' is not a node.'); @@ -64,6 +90,15 @@ export class Mind { } return node; } + /** + * Insert a node before target node. + * @param {Node} node_before + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {Node | null} + */ insert_node_before(node_before, node_id, topic, data, direction) { if (!Node.is_node(node_before)) { logger.error('the node_before ' + node_before + ' is not a node.'); @@ -72,6 +107,11 @@ export class Mind { var node_index = node_before.index - 0.5; return this.add_node(node_before.parent, node_id, topic, data, direction, true, node_index); } + /** + * Get previous sibling of a node or node id. + * @param {string | Node} node + * @returns {Node | null} + */ get_node_before(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -92,6 +132,15 @@ export class Mind { return null; } } + /** + * Insert a node after target node. + * @param {Node} node_after + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {Node | null} + */ insert_node_after(node_after, node_id, topic, data, direction) { if (!Node.is_node(node_after)) { logger.error('the node_after ' + node_after + ' is not a node.'); @@ -100,6 +149,11 @@ export class Mind { var node_index = node_after.index + 0.5; return this.add_node(node_after.parent, node_id, topic, data, direction, true, node_index); } + /** + * Get next sibling of a node or node id. + * @param {string | Node} node + * @returns {Node | null} + */ get_node_after(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -121,6 +175,14 @@ export class Mind { return null; } } + /** + * Move a node to new parent/position. + * @param {Node} node + * @param {string=} before_id + * @param {string=} parent_id + * @param {number=} direction + * @returns {Node | null} + */ move_node(node, before_id, parent_id, direction) { if (!Node.is_node(node)) { logger.error('the parameter node ' + node + ' is not a node.'); @@ -131,6 +193,11 @@ export class Mind { } return this._move_node(node, before_id, parent_id, direction); } + /** + * Propagate direction to descendants. + * @param {Node} node + * @param {number=} direction + */ _flow_node_direction(node, direction) { if (typeof direction === 'undefined') { direction = node.direction; @@ -142,6 +209,12 @@ export class Mind { this._flow_node_direction(node.children[len], direction); } } + /** + * Re-index node among siblings based on before_id marker. + * @param {Node} node + * @param {string} before_id + * @returns {Node} + */ _move_node_internal(node, before_id) { if (!!node && !!before_id) { if (before_id == '_last_') { @@ -164,6 +237,14 @@ export class Mind { } return node; } + /** + * Internal move implementation. + * @param {Node} node + * @param {string} before_id + * @param {string} parent_id + * @param {number=} direction + * @returns {Node | null} + */ _move_node(node, before_id, parent_id, direction) { if (!!node && !!parent_id) { var parent_node = this.get_node(parent_id); @@ -201,6 +282,11 @@ export class Mind { } return node; } + /** + * Remove a node from the mind. + * @param {Node} node + * @returns {boolean} + */ remove_node(node) { if (!Node.is_node(node)) { logger.error('the parameter node ' + node + ' is not a node.'); @@ -242,6 +328,11 @@ export class Mind { this._update_index(node_parent); return true; } + /** + * Put node into the map if id is not taken. + * @param {Node} node + * @returns {boolean} + */ _put_node(node) { if (node.id in this.nodes) { logger.warn("the node_id '" + node.id + "' has been already exist."); @@ -251,6 +342,10 @@ export class Mind { return true; } } + /** + * Re-index children by Node.compare. + * @param {Node} node + */ _update_index(node) { if (node instanceof Node) { node.children.sort(Node.compare); diff --git a/src/jsmind.node.js b/src/jsmind.node.js index 6d136ee6..537313ba 100644 --- a/src/jsmind.node.js +++ b/src/jsmind.node.js @@ -8,6 +8,17 @@ import { logger } from './jsmind.common.js'; export class Node { + /** + * Create a Node instance. + * @param {string} sId - Node id + * @param {number} iIndex - Node index (order among siblings). Use -1 for tail + * @param {string} sTopic - Node topic text + * @param {Record=} oData - Arbitrary node data + * @param {boolean=} bIsRoot - Whether it is the root node + * @param {Node | null=} oParent - Parent node + * @param {number=} eDirection - Direction for children under root (-1 left, 0 center, 1 right) + * @param {boolean=} bExpanded - Expanded state + */ constructor(sId, iIndex, sTopic, oData, bIsRoot, oParent, eDirection, bExpanded) { if (!sId) { logger.error('invalid node id'); @@ -32,6 +43,10 @@ export class Node { this._data = {}; } + /** + * Get absolute location of this node in view coordinates. + * @returns {{x:number,y:number}} + */ get_location() { var vd = this._data.view; return { @@ -39,6 +54,10 @@ export class Node { y: vd.abs_y, }; } + /** + * Get rendered size of this node. + * @returns {{w:number,h:number}} + */ get_size() { var vd = this._data.view; return { @@ -47,6 +66,12 @@ export class Node { }; } + /** + * Compare two nodes by index for ordering. + * @param {Node} node1 + * @param {Node} node2 + * @returns {number} + */ static compare(node1, node2) { // '-1' is always the latest var r = 0; @@ -65,6 +90,12 @@ export class Node { } return r; } + /** + * Check if node is the same as or a descendant of parent_node. + * @param {Node} parent_node + * @param {Node} node + * @returns {boolean} + */ static inherited(parent_node, node) { if (!!parent_node && !!node) { if (parent_node.id === node.id) { @@ -84,6 +115,11 @@ export class Node { } return false; } + /** + * Runtime check for Node instance. + * @param {any} n + * @returns {n is Node} + */ static is_node(n) { return !!n && n instanceof Node; } diff --git a/src/jsmind.option.js b/src/jsmind.option.js index 1cac2919..466352b9 100644 --- a/src/jsmind.option.js +++ b/src/jsmind.option.js @@ -8,6 +8,37 @@ import { util } from './jsmind.util.js'; +/** + * @typedef {{ + * container: string|HTMLElement, + * editable: boolean, + * theme: (string|null), + * mode: ('full'|'side'), + * support_html: boolean, + * log_level: 'debug'|'info'|'warn'|'error'|'disable', + * view: { + * engine: 'canvas'|'svg', + * enable_device_pixel_ratio: boolean, + * hmargin: number, + * vmargin: number, + * line_width: number, + * line_color: string, + * line_style: 'curved'|'straight', + * custom_line_render?: Function, + * draggable: boolean, + * hide_scrollbars_when_draggable: boolean, + * node_overflow: 'hidden'|'wrap', + * zoom: { min:number, max:number, step:number, mask_key:number }, + * custom_node_render: (null|function(any,HTMLElement, any):void), + * expander_style: 'char'|'number' + * }, + * layout: { hspace:number, vspace:number, pspace:number, cousin_space:number }, + * default_event_handle: { enable_mousedown_handle:boolean, enable_click_handle:boolean, enable_dblclick_handle:boolean, enable_mousewheel_handle:boolean }, + * shortcut: { enable:boolean, handles: Record, mapping: Record }, + * plugin: Record + * }} JsMindRuntimeOptions + */ +/** @type {JsMindRuntimeOptions} */ const default_options = { container: '', // id of the container editable: false, // you can change it in your options @@ -66,6 +97,11 @@ const default_options = { plugin: {}, }; +/** + * Merge user options with defaults. Throws if container missing. + * @param {Partial} options + * @returns {JsMindRuntimeOptions} + */ export function merge_option(options) { var opts = {}; util.json.merge(opts, default_options); diff --git a/src/jsmind.plugin.js b/src/jsmind.plugin.js index 26f5c6cf..06d94288 100644 --- a/src/jsmind.plugin.js +++ b/src/jsmind.plugin.js @@ -8,10 +8,15 @@ import { $ } from './jsmind.dom.js'; +/** @type {{ plugins: Array> }} */ const plugin_data = { plugins: [], }; +/** + * Register a plugin instance. + * @param {Plugin} plugin + */ export function register(plugin) { if (!(plugin instanceof Plugin)) { throw new Error('can not register plugin, it is not an instance of Plugin'); @@ -22,18 +27,30 @@ export function register(plugin) { plugin_data.plugins.push(plugin); } +/** + * Apply registered plugins asynchronously. + * @param {import('./jsmind.js').default} jm + * @param {Record} options + */ export function apply(jm, options) { $.w.setTimeout(function () { _apply(jm, options); }, 0); } +/** + * @param {import('./jsmind.js').default} jm + * @param {Record} options */ function _apply(jm, options) { plugin_data.plugins.forEach(p => p.fn_init(jm, options[p.name])); } export class Plugin { - // function fn_init(jm, options){ } + /** + * @template [TOptions=any] + * @param {string} name + * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init + */ constructor(name, fn_init) { if (!name) { throw new Error('plugin must has a name'); diff --git a/src/jsmind.shortcut_provider.js b/src/jsmind.shortcut_provider.js index c0255288..9e460e65 100644 --- a/src/jsmind.shortcut_provider.js +++ b/src/jsmind.shortcut_provider.js @@ -11,6 +11,11 @@ import { util } from './jsmind.util.js'; import { Direction } from './jsmind.common.js'; export class ShortcutProvider { + /** + * Keyboard shortcut handler. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{enable:boolean, handles:Record, mapping:Record}} options - Shortcut configuration options + */ constructor(jm, options) { this.jm = jm; this.opts = options; @@ -19,6 +24,7 @@ export class ShortcutProvider { this._newid = null; this._mapping = {}; } + /** Initialize keyboard listeners and mapping. */ init() { $.on(this.jm.view.e_panel, 'keydown', this.handler.bind(this)); @@ -50,12 +56,15 @@ export class ShortcutProvider { this._newid = util.uuid.newid; } } + /** Enable shortcuts. */ enable_shortcut() { this.opts.enable = true; } + /** Disable shortcuts. */ disable_shortcut() { this.opts.enable = false; } + /** @param {KeyboardEvent} e */ handler(e) { if (e.which == 9) { e.preventDefault(); @@ -77,6 +86,11 @@ export class ShortcutProvider { this._mapping[kc].call(this, this.jm, e); } } + /** + * Handle add child node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_addchild(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { @@ -88,6 +102,11 @@ export class ShortcutProvider { } } } + /** + * Handle add brother node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_addbrother(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -99,12 +118,22 @@ export class ShortcutProvider { } } } + /** + * Handle edit node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_editnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { _jm.begin_edit(selected_node); } } + /** + * Handle delete node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_delnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -112,6 +141,11 @@ export class ShortcutProvider { _jm.remove_node(selected_node); } } + /** + * Handle toggle node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_toggle(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -121,6 +155,11 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** + * Handle up arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_up(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -139,6 +178,11 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** + * Handle down arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_down(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -157,12 +201,29 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** + * Handle left arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_left(_jm, e) { this._handle_direction(_jm, e, Direction.left); } + /** + * Handle right arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ handle_right(_jm, e) { this._handle_direction(_jm, e, Direction.right); } + /** + * Handle directional navigation. + * @private + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + * @param {number} d - Direction constant + */ _handle_direction(_jm, e, d) { var evt = e || event; var selected_node = _jm.get_selected_node(); diff --git a/src/jsmind.util.js b/src/jsmind.util.js index 9e64d9fb..d84af91c 100644 --- a/src/jsmind.util.js +++ b/src/jsmind.util.js @@ -8,6 +8,15 @@ import { $ } from './jsmind.dom.js'; +/** + * Misc utility collection. + * @type {{ + * file: { read: (file: File, cb:(result:string,name:string)=>void)=>void, save:(data:string,type:string,name:string)=>void}, + * json: { json2string:(v:any)=>string, string2json:(s:string)=>any, merge:(b:any,a:any)=>any }, + * uuid: { newid:()=>string }, + * text: { is_empty:(s?:string)=>boolean } + * }} + */ export const util = { file: { read: function (file_data, fn_callback) { diff --git a/src/jsmind.view_provider.js b/src/jsmind.view_provider.js index 8058d165..8affa918 100644 --- a/src/jsmind.view_provider.js +++ b/src/jsmind.view_provider.js @@ -11,6 +11,26 @@ import { init_graph } from './jsmind.graph.js'; import { util } from './jsmind.util.js'; export class ViewProvider { + /** + * View layer: DOM nodes, editor, graph and zoom. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{ + * engine: 'canvas'|'svg', + * enable_device_pixel_ratio: boolean, + * hmargin: number, + * vmargin: number, + * line_width: number, + * line_color: string, + * line_style: 'curved'|'straight', + * custom_line_render?: Function, + * draggable: boolean, + * hide_scrollbars_when_draggable: boolean, + * node_overflow: 'hidden'|'wrap', + * zoom: {min:number, max:number, step:number, mask_key:number}, + * custom_node_render?: Function, + * expander_style: 'char'|'number' + * }} options - View configuration options + */ constructor(jm, options) { this.opts = options; this.jm = jm; @@ -35,6 +55,7 @@ export class ViewProvider { : 1; this._initialized = false; } + /** Initialize DOM structure, graph and editor. */ init() { logger.debug(this.opts); logger.debug('view.init'); @@ -81,6 +102,13 @@ export class ViewProvider { } } + /** + * Add a delegated event handler. + * @param {any} obj + * @param {string} event_name + * @param {(e:Event)=>void} event_handle + * @param {boolean=} capture_by_panel + */ add_event(obj, event_name, event_handle, capture_by_panel) { let target = !!capture_by_panel ? this.e_panel : this.e_nodes; $.on(target, event_name, function (e) { @@ -88,6 +116,7 @@ export class ViewProvider { event_handle.call(obj, evt); }); } + /** @param {HTMLElement|null} element */ get_binded_nodeid(element) { if (element == null) { return null; @@ -101,6 +130,7 @@ export class ViewProvider { return this.get_binded_nodeid(element.parentElement); } } + /** @param {HTMLElement|null} element */ is_node(element) { if (element == null) { return false; @@ -114,6 +144,7 @@ export class ViewProvider { return this.is_node(element.parentElement); } } + /** @param {HTMLElement} element */ is_expander(element) { return element.tagName.toLowerCase() == 'jmexpander'; } @@ -132,18 +163,21 @@ export class ViewProvider { this.e_nodes.className = ''; } } + /** Reset custom styles for all nodes. */ reset_custom_style() { var nodes = this.jm.mind.nodes; for (var nodeid in nodes) { this.reset_node_custom_style(nodes[nodeid]); } } + /** Load and initialize the view. */ load() { logger.debug('view.load'); this.setup_canvas_draggable(this.opts.draggable); this.init_nodes(); this._initialized = true; } + /** Calculate and set the expanded canvas size. */ expand_size() { var min_size = this.layout.get_min_size(); var min_width = min_size.w + this.opts.hmargin * 2; @@ -159,11 +193,16 @@ export class ViewProvider { this.size.w = client_w; this.size.h = client_h; } + /** + * Initialize size data for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + */ init_nodes_size(node) { var view_data = node._data.view; view_data.width = view_data.element.clientWidth; view_data.height = view_data.element.clientHeight; } + /** Initialize DOM elements for all nodes. */ init_nodes() { var nodes = this.jm.mind.nodes; var doc_frag = $.d.createDocumentFragment(); @@ -178,12 +217,20 @@ export class ViewProvider { } }); } + /** + * Add a new node to the view. + * @param {import('./jsmind.node.js').Node} node - Node to add + */ add_node(node) { this.create_node_element(node, this.e_nodes); this.run_in_c11y_mode_if_needed(() => { this.init_nodes_size(node); }); } + /** + * Run function in compatibility mode if container is not visible. + * @param {Function} func - Function to execute + */ run_in_c11y_mode_if_needed(func) { if (!!this.container.offsetParent) { func(); @@ -200,6 +247,11 @@ export class ViewProvider { this.e_panel.style.position = null; this.e_panel.style.top = null; } + /** + * Create a DOM element for a node and append to parent container. + * @param {import('./jsmind.node.js').Node} node + * @param {HTMLElement} parent_node + */ create_node_element(node, parent_node) { var view_data = null; if ('view' in node._data) { @@ -230,6 +282,10 @@ export class ViewProvider { parent_node.appendChild(d); view_data.element = d; } + /** + * Remove a node from the view. + * @param {import('./jsmind.node.js').Node} node - Node to remove + */ remove_node(node) { if (this.selected_node != null && this.selected_node.id == node.id) { this.selected_node = null; @@ -252,6 +308,10 @@ export class ViewProvider { node._data.view.expander = null; } } + /** + * Update a node's display. + * @param {import('./jsmind.node.js').Node} node - Node to update + */ update_node(node) { var view_data = node._data.view; var element = view_data.element; @@ -269,6 +329,10 @@ export class ViewProvider { element.style = origin_style; } } + /** + * Select a node visually. + * @param {import('./jsmind.node.js').Node|null} node - Node to select + */ select_node(node) { if (!!this.selected_node) { var element = this.selected_node._data.view.element; @@ -281,15 +345,28 @@ export class ViewProvider { this.clear_selected_node_custom_style(node); } } + /** Clear node selection. */ select_clear() { this.select_node(null); } + /** + * Get currently editing node. + * @returns {import('./jsmind.node.js').Node|null} Currently editing node + */ get_editing_node() { return this.editing_node; } + /** + * Check if any node is being edited. + * @returns {boolean} True if editing + */ is_editing() { return !!this.editing_node; } + /** + * Begin editing a node. + * @param {import('./jsmind.node.js').Node} node - Node to edit + */ edit_node_begin(node) { if (!node.topic) { logger.warn("don't edit image nodes"); @@ -315,6 +392,7 @@ export class ViewProvider { this.e_editor.focus(); this.e_editor.select(); } + /** End editing current node. */ edit_node_end() { if (this.editing_node != null) { var node = this.editing_node; @@ -332,12 +410,14 @@ export class ViewProvider { } this.e_panel.focus(); } + /** @returns {{x:number,y:number}} */ get_view_offset() { var bounds = this.layout.bounds; var _x = (this.size.w - bounds.e - bounds.w) / 2; var _y = this.size.h / 2; return { x: _x, y: _y }; } + /** Resize the view to fit container. */ resize() { this.graph.set_size(1, 1); this.e_nodes.style.width = '1px'; @@ -346,6 +426,10 @@ export class ViewProvider { this.expand_size(); this._show(); } + /** + * Internal show implementation. + * @private + */ _show() { this.graph.set_size(this.size.w, this.size.h); this.e_nodes.style.width = this.size.w + 'px'; @@ -355,12 +439,27 @@ export class ViewProvider { //this.layout.cache_valid = true; this.jm.invoke_event_handle(EventType.resize, { data: [] }); } + /** + * Zoom in the view. + * @param {MouseEvent=} e - Mouse event for zoom center + * @returns {boolean} True if zoom succeeded + */ zoom_in(e) { return this.set_zoom(this.zoom_current + this.opts.zoom.step, e); } + /** + * Zoom out the view. + * @param {MouseEvent=} e - Mouse event for zoom center + * @returns {boolean} True if zoom succeeded + */ zoom_out(e) { return this.set_zoom(this.zoom_current - this.opts.zoom.step, e); } + /** + * Set zoom level and keep scroll around zoom center. + * @param {number} zoom + * @param {MouseEvent=} e + */ set_zoom(zoom, e) { if (zoom < this.opts.zoom.min || zoom > this.opts.zoom.max) { return false; @@ -403,6 +502,7 @@ export class ViewProvider { this.expand_size(); this._show(); } + /** @param {import('./jsmind.node.js').Node} node */ save_location(node) { var vd = node._data.view; vd._saved_location = { @@ -410,6 +510,7 @@ export class ViewProvider { y: parseInt(vd.element.style.top) - this.e_panel.scrollTop, }; } + /** @param {import('./jsmind.node.js').Node} node */ restore_location(node) { var vd = node._data.view; this.e_panel.scrollLeft = parseInt(vd.element.style.left) - vd._saved_location.x; @@ -429,6 +530,7 @@ export class ViewProvider { } this.e_nodes.innerHTML = ''; } + /** Render node elements and expanders to screen. */ show_nodes() { var nodes = this.jm.mind.nodes; var node = null; @@ -456,6 +558,7 @@ export class ViewProvider { this._show_expander(node, view_offset); } } + /** @param {import('./jsmind.node.js').Node} node */ _show_expander(node, view_offset) { if (node.isroot) { return; @@ -488,6 +591,7 @@ export class ViewProvider { } } + /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ _default_node_render(ele, node) { if (this.opts.support_html) { $.h(ele, node.topic); @@ -495,15 +599,18 @@ export class ViewProvider { $.t(ele, node.topic); } } + /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ _custom_node_render(ele, node) { let rendered = this.opts.custom_node_render(this.jm, ele, node); if (!rendered) { this._default_node_render(ele, node); } } + /** @param {import('./jsmind.node.js').Node} node */ reset_node_custom_style(node) { this._reset_node_custom_style(node._data.view.element, node.data); } + /** @param {HTMLElement} node_element @param {Record} node_data */ _reset_node_custom_style(node_element, node_data) { if ('background-color' in node_data) { node_element.style.backgroundColor = node_data['background-color']; @@ -561,6 +668,7 @@ export class ViewProvider { } } } + /** @param {import('./jsmind.node.js').Node} node */ restore_selected_node_custom_style(node) { var node_element = node._data.view.element; var node_data = node.data; @@ -571,6 +679,7 @@ export class ViewProvider { node_element.style.color = node_data['foreground-color']; } } + /** @param {import('./jsmind.node.js').Node} node */ clear_selected_node_custom_style(node) { var node_element = node._data.view.element; node_element.style.backgroundColor = ''; @@ -602,6 +711,10 @@ export class ViewProvider { } } // Drag the whole mind map with your mouse, when it's larger that the container + /** + * Enable/disable dragging the whole canvas with mouse. + * @param {boolean} enabled + */ setup_canvas_draggable(enabled) { this.opts.draggable = enabled; if (!this._initialized) { @@ -637,6 +750,7 @@ export class ViewProvider { }); } } + /** @param {import('./jsmind.node.js').Node} node */ center_node(node) { if (!this.layout.is_visible(node)) { logger.warn('can not scroll to the node, because it is invisible'); diff --git a/src/plugins/jsmind.draggable-node.js b/src/plugins/jsmind.draggable-node.js index 7cf61a8b..e12da618 100644 --- a/src/plugins/jsmind.draggable-node.js +++ b/src/plugins/jsmind.draggable-node.js @@ -23,6 +23,18 @@ const clear_selection = $.d.selection.empty(); }; +/** + * Default options for draggable node plugin. + * @typedef {Object} DraggableNodeOptions + * @property {number} [line_width] + * @property {string} [line_color] + * @property {string} [line_color_invalid] + * @property {number} [lookup_delay] + * @property {number} [lookup_interval] + * @property {number} [scrolling_trigger_width] + * @property {number} [scrolling_step_length] + * @property {string} [shadow_node_class_name] + */ const DEFAULT_OPTIONS = { line_width: 5, line_color: 'rgba(0,0,0,0.3)', @@ -34,47 +46,81 @@ const DEFAULT_OPTIONS = { shadow_node_class_name: 'jsmind-draggable-shadow-node', }; -class DraggableNode { +/** + * Draggable node plugin for jsMind. + */ +export class DraggableNode { + /** + * Create draggable node plugin instance. + * @param {import('../jsmind.js').default} jm - jsMind instance + * @param {Partial} options - Plugin options + */ constructor(jm, options) { var opts = {}; jsMind.util.json.merge(opts, DEFAULT_OPTIONS); jsMind.util.json.merge(opts, options); this.version = '0.4.0'; + /** @type {import('../jsmind.js').default} */ this.jm = jm; + /** @type {DraggableNodeOptions} */ this.options = opts; + /** @type {HTMLCanvasElement|null} */ this.e_canvas = null; + /** @type {CanvasRenderingContext2D|null} */ this.canvas_ctx = null; + /** @type {HTMLElement|null} */ this.shadow = null; + /** @type {number} */ this.shadow_p_x = 0; + /** @type {number} */ this.shadow_p_y = 0; + /** @type {number} */ this.shadow_w = 0; + /** @type {number} */ this.shadow_h = 0; + /** @type {import('../jsmind.node.js').Node|null} */ this.active_node = null; + /** @type {import('../jsmind.node.js').Node|null} */ this.target_node = null; + /** @type {number|null} */ this.target_direct = null; + /** @type {number} */ this.client_w = 0; + /** @type {number} */ this.client_h = 0; + /** @type {number} */ this.offset_x = 0; + /** @type {number} */ this.offset_y = 0; + /** @type {number} */ this.hlookup_delay = 0; + /** @type {number} */ this.hlookup_timer = 0; + /** @type {boolean} */ this.capture = false; + /** @type {boolean} */ this.moved = false; + /** @type {boolean} */ this.canvas_draggable = jm.get_view_draggable(); + /** @type {HTMLElement} */ this.view_panel = jm.view.e_panel; + /** @type {DOMRect|null} */ this.view_panel_rect = null; } + /** Initialize the draggable node plugin. */ init() { this.create_canvas(); this.create_shadow(); this.event_bind(); } + /** Resize canvas and shadow elements. */ resize() { this.jm.view.e_nodes.appendChild(this.shadow); this.e_canvas.width = this.jm.view.size.w; this.e_canvas.height = this.jm.view.size.h; } + /** Create canvas for drawing drag lines. */ create_canvas() { var c = $.c('canvas'); this.jm.view.e_panel.appendChild(c); @@ -91,6 +137,10 @@ class DraggableNode { s.className = this.options.shadow_node_class_name; this.shadow = s; } + /** + * Reset shadow element style and cache its size. + * @param {HTMLElement} el - The node element to mirror as shadow + */ reset_shadow(el) { var s = this.shadow.style; this.shadow.innerHTML = el.innerHTML; @@ -104,14 +154,22 @@ class DraggableNode { this.shadow_w = this.shadow.clientWidth; this.shadow_h = this.shadow.clientHeight; } + /** Show the shadow element. */ show_shadow() { if (!this.moved) { this.shadow.style.visibility = 'visible'; } } + /** Hide the shadow element. */ hide_shadow() { this.shadow.style.visibility = 'hidden'; } + /** + * Draw a helper line between the shadow and target node. + * @param {{x:number,y:number}} shadow_p - Shadow anchor point + * @param {{x:number,y:number}} node_p - Target node anchor point + * @param {boolean} invalid - Whether current target is invalid + */ magnet_shadow(shadow_p, node_p, invalid) { this.canvas_ctx.lineWidth = this.options.line_width; this.canvas_ctx.strokeStyle = invalid @@ -121,15 +179,24 @@ class DraggableNode { this.clear_lines(); this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y); } + /** Clear helper lines from canvas. */ clear_lines() { this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h); } + /** + * Draw a straight helper line. + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + */ canvas_lineto(x1, y1, x2, y2) { this.canvas_ctx.beginPath(); this.canvas_ctx.moveTo(x1, y1); this.canvas_ctx.lineTo(x2, y2); this.canvas_ctx.stroke(); } + /** Bind mouse/touch events for dragging. */ event_bind() { var jd = this; var container = this.jm.view.container; @@ -156,6 +223,10 @@ class DraggableNode { jd.dragend.call(jd, e); }); } + /** + * Begin dragging interaction. + * @param {MouseEvent|TouchEvent} e - Pointer down event + */ dragstart(e) { if (!this.jm.get_editable()) { return; @@ -207,6 +278,10 @@ class DraggableNode { } } } + /** + * Drag handler to move shadow and auto-scroll container. + * @param {MouseEvent|TouchEvent} e - Pointer move event + */ drag(e) { if (!this.jm.get_editable()) { return; @@ -258,6 +333,10 @@ class DraggableNode { clear_selection(); } } + /** + * Finish dragging, move the node if applicable. + * @param {MouseEvent|TouchEvent} e - Pointer up event + */ dragend(e) { if (!this.jm.get_editable()) { return; @@ -288,6 +367,11 @@ class DraggableNode { this.moved = false; this.capture = false; } + /** + * Find the closest node element from an event target. + * @param {HTMLElement} el - Current DOM element + * @returns {HTMLElement|null} Matched node element or null + */ find_node_element(el) { if ( el === this.jm.view.e_nodes || @@ -301,6 +385,7 @@ class DraggableNode { } return this.find_node_element(el.parentNode); } + /** Recompute target node under the shadow and draw helper. */ lookup_target_node() { let sx = this.shadow.offsetLeft; let sy = this.shadow.offsetTop; @@ -324,6 +409,10 @@ class DraggableNode { this.target_direct = target_direction; } } + /** + * Get X coordinate of root node center. + * @returns {number} + */ get_root_x() { let root = this.jm.get_root(); let root_location = root.get_location(); @@ -331,6 +420,11 @@ class DraggableNode { return root_location.x + root_size.w / 2; } + /** + * Lookup overlapping node's parent near the shadow position. + * @param {number} direction - Direction constant + * @returns {import('../jsmind.node.js').Node|null} + */ lookup_overlapping_node_parent(direction) { let shadowRect = this.shadow.getBoundingClientRect(); let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2; @@ -355,6 +449,12 @@ class DraggableNode { } } + /** + * Find node's parent by a screen location. + * @param {number} x - Client X + * @param {number} y - Client Y + * @returns {import('../jsmind.node.js').Node|null} + */ lookup_node_parent_by_location(x, y) { return $.d .elementsFromPoint(x, y) @@ -367,6 +467,11 @@ class DraggableNode { .find(n => n); } + /** + * Lookup the closest node along a direction. + * @param {number} direction + * @returns {import('../jsmind.node.js').Node} + */ lookup_close_node(direction) { return Object.values(this.jm.mind.nodes) .filter(n => n.direction == direction || n.isroot) @@ -381,6 +486,12 @@ class DraggableNode { ).node; } + /** + * Check if shadow is on the target side of a node. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {boolean} + */ shadow_on_target_side(node, dir) { return ( (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) || @@ -388,18 +499,39 @@ class DraggableNode { ); } + /** + * Distance from shadow to the right side of a node. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ shadow_to_right_of_node(node) { return this.shadow_p_x - node.get_location().x - node.get_size().w; } + /** + * Distance from shadow to the left side of a node. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ shadow_to_left_of_node(node) { return node.get_location().x - this.shadow_p_x - this.shadow_w; } + /** + * Vertical distance between shadow centerline and node centerline. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ shadow_to_base_line_of_node(node) { return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2; } + /** + * Manhattan distance to a node along a direction. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {number} + */ shadow_to_node(node, dir) { let distance_x = dir === jsMind.direction.right @@ -409,6 +541,12 @@ class DraggableNode { return distance_x + distance_y; } + /** + * Calculate connection points of a node and the shadow. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}} + */ calc_point_of_node(node, dir) { let ns = node.get_size(); let nl = node.get_location(); @@ -425,6 +563,12 @@ class DraggableNode { }; } + /** + * Move a node to a new parent/position. + * @param {import('../jsmind.node.js').Node} src_node + * @param {import('../jsmind.node.js').Node|null} target_node + * @param {number|null} target_direct + */ move_node(src_node, target_node, target_direct) { var shadow_h = this.shadow.offsetTop; if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) { @@ -455,6 +599,11 @@ class DraggableNode { this.target_node = null; this.target_direct = null; } + /** + * Handle jsMind events. + * @param {number|string} type - Event type + * @param {any} [data] - Event data + */ jm_event_handle(type, data) { if (type === jsMind.event_type.resize) { this.resize(); @@ -462,7 +611,11 @@ class DraggableNode { } } -var draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) { +/** + * Draggable node plugin registration. + * @type {import('../jsmind.plugin.js').Plugin>} + */ +export const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) { var jd = new DraggableNode(jm, options); jd.init(); jm.add_event_listener(function (type, data) { @@ -471,3 +624,5 @@ var draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options }); jsMind.register_plugin(draggable_plugin); + +export default DraggableNode; diff --git a/src/plugins/jsmind.screenshot.js b/src/plugins/jsmind.screenshot.js index 338459e3..b718c7da 100644 --- a/src/plugins/jsmind.screenshot.js +++ b/src/plugins/jsmind.screenshot.js @@ -19,6 +19,13 @@ if (!domtoimage) { const $ = jsMind.$; +/** + * Default options for screenshot plugin. + * @typedef {Object} ScreenshotOptions + * @property {string|null} [filename] + * @property {{left?:string|Location,right?:string}} [watermark] + * @property {string} [background] + */ const DEFAULT_OPTIONS = { filename: null, watermark: { @@ -28,18 +35,30 @@ const DEFAULT_OPTIONS = { background: 'transparent', }; -class JmScreenshot { +/** + * Screenshot plugin for jsMind. + */ +export class JmScreenshot { + /** + * Create screenshot plugin instance. + * @param {import('../jsmind.js').default} jm - jsMind instance + * @param {Partial} options - Plugin options + */ constructor(jm, options) { var opts = {}; jsMind.util.json.merge(opts, DEFAULT_OPTIONS); jsMind.util.json.merge(opts, options); this.version = '0.2.0'; + /** @type {import('../jsmind.js').default} */ this.jm = jm; + /** @type {ScreenshotOptions} */ this.options = opts; + /** @type {number} */ this.dpr = jm.view.device_pixel_ratio; } + /** Take a screenshot of the mind map. */ shoot() { let c = this.create_canvas(); let ctx = c.getContext('2d'); @@ -53,6 +72,10 @@ class JmScreenshot { .then(() => this.clear(c)); } + /** + * Create canvas for screenshot. + * @returns {HTMLCanvasElement} Canvas element + */ create_canvas() { let c = $.c('canvas'); const w = this.jm.view.size.w; @@ -67,10 +90,19 @@ class JmScreenshot { return c; } + /** + * Clean up canvas element. + * @param {HTMLCanvasElement} c - Canvas to remove + */ clear(c) { c.parentNode.removeChild(c); } + /** + * Draw background on canvas. + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @returns {Promise} Promise resolving to context + */ draw_background(ctx) { return new Promise( function (resolve, _) { @@ -84,6 +116,11 @@ class JmScreenshot { ); } + /** + * Draw connection lines on canvas by copying from view graph. + * @param {CanvasRenderingContext2D} ctx + * @returns {Promise} + */ draw_lines(ctx) { return new Promise( function (resolve, _) { @@ -94,6 +131,11 @@ class JmScreenshot { ); } + /** + * Draw node DOM into canvas via SVG snapshot. + * @param {CanvasRenderingContext2D} ctx + * @returns {Promise} + */ draw_nodes(ctx) { return domtoimage .toSvg(this.jm.view.e_nodes, { style: { zoom: 1 } }) @@ -104,6 +146,12 @@ class JmScreenshot { }); } + /** + * Draw watermark text on canvas. + * @param {HTMLCanvasElement} c + * @param {CanvasRenderingContext2D} ctx + * @returns {CanvasRenderingContext2D} + */ draw_watermark(c, ctx) { ctx.textBaseline = 'bottom'; ctx.fillStyle = '#000'; @@ -119,6 +167,11 @@ class JmScreenshot { return ctx; } + /** + * Load image from URL and resolve img element. + * @param {string} url + * @returns {Promise} + */ load_image(url) { return new Promise(function (resolve, reject) { let img = new Image(); @@ -130,6 +183,10 @@ class JmScreenshot { }); } + /** + * Trigger download of canvas content as PNG. + * @param {HTMLCanvasElement} c + */ download(c) { var name = (this.options.filename || this.jm.mind.name) + '.png'; @@ -155,7 +212,11 @@ class JmScreenshot { } } -let screenshot_plugin = new jsMind.plugin('screenshot', function (jm, options) { +/** + * Screenshot plugin registration. + * @type {import('../jsmind.plugin.js').Plugin>} + */ +export const screenshot_plugin = new jsMind.plugin('screenshot', function (jm, options) { var jmss = new JmScreenshot(jm, options); jm.screenshot = jmss; jm.shoot = function () { @@ -164,3 +225,5 @@ let screenshot_plugin = new jsMind.plugin('screenshot', function (jm, options) { }); jsMind.register_plugin(screenshot_plugin); + +export default JmScreenshot; diff --git a/tsconfig.decls.json b/tsconfig.decls.json index dda20ff5..7a29057e 100644 --- a/tsconfig.decls.json +++ b/tsconfig.decls.json @@ -8,6 +8,7 @@ "esModuleInterop": true, "declaration": true, "emitDeclarationOnly": true, + "stripInternal": true, "allowJs": true, "checkJs": false, "outDir": "types/generated", diff --git a/types/generated/jsmind.common.d.ts b/types/generated/jsmind.common.d.ts index ae371445..f5bb9e9e 100644 --- a/types/generated/jsmind.common.d.ts +++ b/types/generated/jsmind.common.d.ts @@ -5,26 +5,37 @@ * Project Home: * https://github.com/hizzgdev/jsmind/ */ -export const __version__: "0.8.7"; -export const __author__: "hizzgdev@163.com"; -export namespace Direction { - let left: number; - let center: number; - let right: number; - function of(dir: any): any; -} +/** + * Library version string. + * @type {string} + */ +export const __version__: string; +/** + * Library author. + * @type {string} + */ +export const __author__: string; +/** + * Direction constants and parser. + * @typedef {{left:number,center:number,right:number,of:(dir:(string|number))=>number|undefined}} DirectionType + */ +/** @type {DirectionType} */ +export const Direction: DirectionType; +export type EventType = number; export namespace EventType { let show: number; let resize: number; let edit: number; let select: number; } +export type Key = number; export namespace Key { let meta: number; let ctrl: number; let alt: number; let shift: number; } +export type LogLevel = number; export namespace LogLevel { let debug: number; let info: number; @@ -32,32 +43,24 @@ export namespace LogLevel { let error: number; let disable: number; } -export namespace logger { - export { setup_logger_level as level }; - export let log: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; - }; - let debug_1: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; - }; - export { debug_1 as debug }; - let info_1: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; - }; - export { info_1 as info }; - let warn_1: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; - }; - export { warn_1 as warn }; - let error_1: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; - }; - export { error_1 as error }; -} -declare function setup_logger_level(log_level: any): void; -export {}; +/** + * Logger facade with dynamic level. + * @type {{level:(lvl:number)=>void,log:Function,debug:Function,info:Function,warn:Function,error:Function}} + */ +export let logger: { + level: (lvl: number) => void; + log: Function; + debug: Function; + info: Function; + warn: Function; + error: Function; +}; +/** + * Direction constants and parser. + */ +export type DirectionType = { + left: number; + center: number; + right: number; + of: (dir: (string | number)) => number | undefined; +}; diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts index 3f573bfd..31f93c7f 100644 --- a/types/generated/jsmind.d.ts +++ b/types/generated/jsmind.d.ts @@ -1,12 +1,10 @@ +/** + * jsMind runtime: orchestrates data/layout/view/shortcut and exposes public API. + */ export default class jsMind { static mind: typeof Mind; static node: typeof Node; - static direction: { - left: number; - center: number; - right: number; - of: (dir: any) => any; - }; + static direction: import("./jsmind.common.js").DirectionType; static event_type: { show: number; resize: number; @@ -16,116 +14,210 @@ export default class jsMind { static $: { w: any; d: any; - g: (id: any) => any; - c: (tag: any) => any; - t: (n: any, t: any) => void; - h: (n: any, t: any) => void; - i: (el: any) => boolean; - on: (t: any, e: any, h: any) => void; + g: (id: string) => HTMLElement | null; + c: (tag: string) => HTMLElement; + t: (n: HTMLElement, t: string) => void; + h: (n: HTMLElement, t: string | HTMLElement) => void; + i: (el: any) => el is HTMLElement; + on: (t: HTMLElement, e: string, h: (ev: Event) => void) => void; }; static plugin: typeof Plugin; static register_plugin: typeof _register_plugin; static util: { file: { - read: (file_data: any, fn_callback: any) => void; - save: (file_data: any, type: any, name: any) => void; + read: (file: File, cb: (result: string, name: string) => void) => void; + save: (data: string, type: string, name: string) => void; }; json: { - json2string: (json: any) => string; - string2json: (json_str: any) => any; + json2string: (v: any) => string; + string2json: (s: string) => any; merge: (b: any, a: any) => any; }; uuid: { newid: () => string; }; text: { - is_empty: (s: any) => boolean; + is_empty: (s?: string) => boolean; }; }; - static show(options: any, mind: any): jsMind; - constructor(options: any); - options: {}; + /** + * Deprecated: static show constructor helper. + * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options + * @param {any} mind + * @returns {jsMind} + */ + static show(options: import("./jsmind.option.js").JsMindRuntimeOptions, mind: any): jsMind; + /** + * Create a jsMind instance. + * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options + */ + constructor(options: import("./jsmind.option.js").JsMindRuntimeOptions); + options: import("./jsmind.option.js").JsMindRuntimeOptions; version: string; initialized: boolean; mind: Mind; event_handles: any[]; + /** Initialize sub-systems and plugins. */ init(): void; data: DataProvider; layout: LayoutProvider; view: ViewProvider; shortcut: ShortcutProvider; - get_editable(): any; + /** @returns {boolean} whether current mind map is editable */ + get_editable(): boolean; + /** enable editing */ enable_edit(): void; + /** disable editing */ disable_edit(): void; - get_view_draggable(): any; + /** @returns {boolean} whether view is draggable */ + get_view_draggable(): boolean; + /** enable view dragging */ enable_view_draggable(): void; + /** disable view dragging */ disable_view_draggable(): void; - enable_event_handle(event_handle: any): void; - disable_event_handle(event_handle: any): void; - set_theme(theme: any): void; + /** + * Enable default event handle. + * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle + */ + enable_event_handle(event_handle: "mousedown" | "click" | "dblclick" | "mousewheel"): void; + /** + * Disable default event handle. + * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle + */ + disable_event_handle(event_handle: "mousedown" | "click" | "dblclick" | "mousewheel"): void; + /** + * Set theme name. + * @param {string|null} theme + */ + set_theme(theme: string | null): void; + /** bind internal DOM events */ _event_bind(): void; - mousedown_handle(e: any): void; - click_handle(e: any): void; - dblclick_handle(e: any): void; - mousewheel_handle(e: any): void; - begin_edit(node: any): any; + /** @param {MouseEvent} e */ + mousedown_handle(e: MouseEvent): void; + /** @param {MouseEvent} e */ + click_handle(e: MouseEvent): void; + /** @param {MouseEvent} e */ + dblclick_handle(e: MouseEvent): void; + /** @param {WheelEvent} e */ + mousewheel_handle(e: WheelEvent): void; + /** + * Begin editing a node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {boolean|void} + */ + begin_edit(node: string | import("./jsmind.node.js").Node): boolean | void; + /** End editing */ end_edit(): void; - toggle_node(node: any): any; - expand_node(node: any): any; - collapse_node(node: any): any; + /** + * Toggle a node's expanded state. + * @param {string | import('./jsmind.node.js').Node} node + */ + toggle_node(node: string | import("./jsmind.node.js").Node): any; + /** + * Expand a node. + * @param {string | import('./jsmind.node.js').Node} node + */ + expand_node(node: string | import("./jsmind.node.js").Node): any; + /** + * Collapse a node. + * @param {string | import('./jsmind.node.js').Node} node + */ + collapse_node(node: string | import("./jsmind.node.js").Node): any; + /** Expand all nodes */ expand_all(): void; + /** Collapse all nodes */ collapse_all(): void; - expand_to_depth(depth: any): void; + /** @param {number} depth */ + expand_to_depth(depth: number): void; + /** reset view/layout/data */ _reset(): void; - _show(mind: any, skip_centering: any): void; - show(mind: any, skip_centering: any): void; + /** + * Internal show flow. + * @param {any} mind + * @param {boolean=} skip_centering + */ + _show(mind: any, skip_centering?: boolean | undefined): void; + /** + * Show a mind (or example) on the canvas. + * @param {any} mind + * @param {boolean=} skip_centering + */ + show(mind: any, skip_centering?: boolean | undefined): void; + /** @returns {{name:string,author:string,version:string}} */ get_meta(): { - name: any; - author: any; - version: any; + name: string; + author: string; + version: string; }; - get_data(data_format: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: { - id: any; - topic: any; - expanded: boolean; - }; - } | { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: any[]; - } | { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: string; - }; - get_root(): Node; - get_node(node: any): any; - add_node(parent_node: any, node_id: any, topic: any, data: any, direction: any): Node; - insert_node_before(node_before: any, node_id: any, topic: any, data: any, direction: any): Node; - insert_node_after(node_after: any, node_id: any, topic: any, data: any, direction: any): Node; - remove_node(node: any): any; - update_node(node_id: any, topic: any): void; - move_node(node_id: any, before_id: any, parent_id: any, direction: any): void; - select_node(node: any): any; - get_selected_node(): any; + /** + * Serialize current mind to given format. + * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] + * @returns {any} + */ + get_data(data_format?: "node_tree" | "node_array" | "freemind" | "text"): any; + /** @returns {import('./jsmind.node.js').Node} */ + get_root(): import("./jsmind.node.js").Node; + /** + * @param {string | import('./jsmind.node.js').Node} node + * @returns {import('./jsmind.node.js').Node} + */ + get_node(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node; + /** + * Add a node under parent. + * @param {string | import('./jsmind.node.js').Node} parent_node + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ + add_node(parent_node: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + /** + * Insert a node before target node. + * @param {string | import('./jsmind.node.js').Node} node_before + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ + insert_node_before(node_before: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + /** + * Insert a node after target node. + * @param {string | import('./jsmind.node.js').Node} node_after + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {import('./jsmind.node.js').Node|null} + */ + insert_node_after(node_after: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + /** + * Remove a node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {boolean} + */ + remove_node(node: string | import("./jsmind.node.js").Node): boolean; + /** @param {string} node_id @param {string} topic */ + update_node(node_id: string, topic: string): void; + /** + * Move a node and optionally change direction. + * @param {string} node_id + * @param {string=} before_id + * @param {string=} parent_id + * @param {number=} direction + */ + move_node(node_id: string, before_id?: string | undefined, parent_id?: string | undefined, direction?: number | undefined): void; + /** @param {string | import('./jsmind.node.js').Node} node */ + select_node(node: string | import("./jsmind.node.js").Node): any; + /** @returns {import('./jsmind.node.js').Node|null} */ + get_selected_node(): import("./jsmind.node.js").Node | null; + /** clear selection */ select_clear(): void; - is_node_visible(node: any): boolean; - scroll_node_to_center(node: any): void; + /** @param {string | import('./jsmind.node.js').Node} node */ + is_node_visible(node: string | import("./jsmind.node.js").Node): boolean; + /** @param {string | import('./jsmind.node.js').Node} node */ + scroll_node_to_center(node: string | import("./jsmind.node.js").Node): void; /** * Find the previous sibling node of the given node. * @@ -133,16 +225,38 @@ export default class jsMind { * @returns {import('./jsmind.node.js').Node | null} */ find_node_before(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; - find_node_after(node: any): any; - set_node_color(node_id: any, bg_color: any, fg_color: any): any; - set_node_font_style(node_id: any, size: any, weight: any, style: any): any; - set_node_background_image(node_id: any, image: any, width: any, height: any, rotation: any): any; - set_node_background_rotation(node_id: any, rotation: any): any; + /** + * Find the next sibling node of the given node. + * @param {string | import('./jsmind.node.js').Node} node + * @returns {import('./jsmind.node.js').Node | null} + */ + find_node_after(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; + /** @param {string} node_id @param {string=} bg_color @param {string=} fg_color */ + set_node_color(node_id: string, bg_color?: string | undefined, fg_color?: string | undefined): any; + /** @param {string} node_id @param {number=} size @param {string=} weight @param {string=} style */ + set_node_font_style(node_id: string, size?: number | undefined, weight?: string | undefined, style?: string | undefined): any; + /** @param {string} node_id @param {string} image @param {number=} width @param {number=} height @param {number=} rotation */ + set_node_background_image(node_id: string, image: string, width?: number | undefined, height?: number | undefined, rotation?: number | undefined): any; + /** @param {string} node_id @param {number} rotation */ + set_node_background_rotation(node_id: string, rotation: number): any; + /** trigger view resize */ resize(): void; - add_event_listener(callback: any): void; + /** @param {(type:number, data:any)=>void} callback */ + add_event_listener(callback: (type: number, data: any) => void): void; + /** clear event listeners */ clear_event_listener(): void; - invoke_event_handle(type: any, data: any): void; - _invoke_event_handle(type: any, data: any): void; + /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ + invoke_event_handle(type: number, data: { + evt?: string; + data?: any[]; + node?: string; + }): void; + /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ + _invoke_event_handle(type: number, data: { + evt?: string; + data?: any[]; + node?: string; + }): void; } import { Mind } from './jsmind.mind.js'; import { DataProvider } from './jsmind.data_provider.js'; diff --git a/types/generated/jsmind.data_provider.d.ts b/types/generated/jsmind.data_provider.d.ts index 573f68e2..10959201 100644 --- a/types/generated/jsmind.data_provider.d.ts +++ b/types/generated/jsmind.data_provider.d.ts @@ -1,36 +1,24 @@ export class DataProvider { - constructor(jm: any); - jm: any; + /** + * Data provider: loads and serializes mind data by format. + * @param {import('./jsmind.js').default} jm - jsMind instance + */ + constructor(jm: import("./jsmind.js").default); + jm: import("./jsmind.js").default; + /** Initialize data provider. */ init(): void; + /** Reset data provider state. */ reset(): void; - load(mind_data: any): import("./jsmind.mind.js").Mind; - get_data(data_format: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: { - id: any; - topic: any; - expanded: boolean; - }; - } | { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: any[]; - } | { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: string; - }; + /** + * Load a Mind from mixed source. + * @param {any} mind_data - object with {format,data} or a format-specific payload + * @returns {import('./jsmind.mind.js').Mind|null} + */ + load(mind_data: any): import("./jsmind.mind.js").Mind | null; + /** + * Serialize current mind to target format. + * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format + * @returns {any} + */ + get_data(data_format: "node_tree" | "node_array" | "freemind" | "text"): any; } diff --git a/types/generated/jsmind.dom.d.ts b/types/generated/jsmind.dom.d.ts index 00027953..6d8056f9 100644 --- a/types/generated/jsmind.dom.d.ts +++ b/types/generated/jsmind.dom.d.ts @@ -6,15 +6,49 @@ export const $: Dom; * Project Home: * https://github.com/hizzgdev/jsmind/ */ +/** + * Lightweight DOM helpers bound to a window. + */ declare class Dom { constructor(w: any); w: any; d: any; - g: (id: any) => any; - c: (tag: any) => any; - t: (n: any, t: any) => void; - h: (n: any, t: any) => void; - i: (el: any) => boolean; - on: (t: any, e: any, h: any) => void; + /** + * Get element by id. + * @param {string} id + * @returns {HTMLElement|null} + */ + g: (id: string) => HTMLElement | null; + /** + * Create element with given tag. + * @param {string} tag + * @returns {HTMLElement} + */ + c: (tag: string) => HTMLElement; + /** + * Set text content for element. + * @param {HTMLElement} n + * @param {string} t + */ + t: (n: HTMLElement, t: string) => void; + /** + * Set inner HTML or append element. + * @param {HTMLElement} n + * @param {string|HTMLElement} t + */ + h: (n: HTMLElement, t: string | HTMLElement) => void; + /** + * Runtime check for HTMLElement. + * @param {any} el + * @returns {el is HTMLElement} + */ + i: (el: any) => el is HTMLElement; + /** + * Add event listener with legacy fallback. + * @param {HTMLElement} t + * @param {string} e + * @param {(ev:Event)=>void} h + */ + on: (t: HTMLElement, e: string, h: (ev: Event) => void) => void; } export {}; diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts index caa4cf54..40e785af 100644 --- a/types/generated/jsmind.format.d.ts +++ b/types/generated/jsmind.format.d.ts @@ -1,131 +1,53 @@ -export namespace format { - namespace node_tree { - namespace example { - export { DEFAULT_META as meta }; - export let format: string; - export namespace data { - let id: string; - let topic: string; - } - } - function get_mind(source: any): Mind; - function get_data(mind: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; - data: { - id: any; - topic: any; - expanded: boolean; - }; +/** + * Mind data format handlers. + * @type {{ + * node_tree: { example:{meta:MindMapMeta,format:'node_tree',data:any}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * node_array: { example:{meta:MindMapMeta,format:'node_array',data:any[]}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } + * }} + */ +export const format: { + node_tree: { + example: { + meta: MindMapMeta; + format: "node_tree"; + data: any; }; - function _parse(mind: any, node_root: any): void; - function _extract_data(node_json: any): {}; - function _extract_subnode(mind: any, node_parent: any, node_json: any): void; - function _build_node(node: any): { - id: any; - topic: any; - expanded: boolean; - }; - } - namespace node_array { - export namespace example_1 { - export { DEFAULT_META as meta }; - let format_1: string; - export { format_1 as format }; - let data_1: { - id: string; - topic: string; - isroot: boolean; - }[]; - export { data_1 as data }; - } - export { example_1 as example }; - export function get_mind_1(source: any): Mind; - export { get_mind_1 as get_mind }; - export function get_data_1(mind: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; + get_mind: (src: any) => Mind; + get_data: (mind: Mind) => any; + }; + node_array: { + example: { + meta: MindMapMeta; + format: "node_array"; data: any[]; }; - export { get_data_1 as get_data }; - export function _parse_1(mind: any, node_array: any): void; - export { _parse_1 as _parse }; - export function _extract_root(mind: any, node_array: any): any; - export function _extract_subnode_1(mind: any, parent_node: any, node_array: any): number; - export { _extract_subnode_1 as _extract_subnode }; - export function _extract_data_1(node_json: any): {}; - export { _extract_data_1 as _extract_data }; - export function _array(mind: any, node_array: any): void; - export function _array_node(node: any, node_array: any): void; - } - namespace freemind { - export namespace example_2 { - export { DEFAULT_META as meta }; - let format_2: string; - export { format_2 as format }; - let data_2: string; - export { data_2 as data }; - } - export { example_2 as example }; - export function get_mind_2(source: any): Mind; - export { get_mind_2 as get_mind }; - export function get_data_2(mind: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; + get_mind: (src: any) => Mind; + get_data: (mind: Mind) => any; + }; + freemind: { + example: { + meta: MindMapMeta; + format: "freemind"; data: string; }; - export { get_data_2 as get_data }; - export function _parse_xml(xml: any): any; - export function _find_root(xml_doc: any): any; - export function _load_node(mind: any, parent_node: any, xml_node: any): void; - export function _load_attributes(xml_node: any): {}; - export function _build_map(node: any, xml_lines: any): void; - export function _escape(text: any): any; - } - namespace text { - export namespace example_3 { - export { DEFAULT_META as meta }; - let format_3: string; - export { format_3 as format }; - let data_3: string; - export { data_3 as data }; - } - export { example_3 as example }; - export let _line_regex: RegExp; - export function get_mind_3(source: any): Mind; - export { get_mind_3 as get_mind }; - export function _fill_nodes(mind: any, lines: any): void; - export function get_data_3(mind: any): { - meta: { - name: any; - author: any; - version: any; - }; - format: string; + get_mind: (src: any) => Mind; + get_data: (mind: Mind) => any; + }; + text: { + example: { + meta: MindMapMeta; + format: "text"; data: string; }; - export { get_data_3 as get_data }; - export function _build_lines(lines: any, nodes: any, level: any): void; - } -} -declare namespace DEFAULT_META { - export let name: string; - export { __author__ as author }; - export { __version__ as version }; -} + get_mind: (src: any) => Mind; + get_data: (mind: Mind) => any; + }; +}; +export type MindMapMeta = { + name: string; + author: string; + version: string; +}; import { Mind } from './jsmind.mind.js'; -import { __author__ } from './jsmind.common.js'; -import { __version__ } from './jsmind.common.js'; -export {}; diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts index 63ef9a26..60fe12c8 100644 --- a/types/generated/jsmind.graph.d.ts +++ b/types/generated/jsmind.graph.d.ts @@ -1,9 +1,43 @@ -export function init_graph(view: any, engine: any): SvgGraph | CanvasGraph; +/** + * Initialize graph renderer based on engine type. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + * @param {'canvas'|'svg'} engine - Rendering engine type + * @returns {SvgGraph|CanvasGraph} Graph renderer instance + */ +export function init_graph(view: import("./jsmind.view_provider.js").ViewProvider, engine: "canvas" | "svg"): SvgGraph | CanvasGraph; +/** + * SVG-based graph renderer. + */ declare class SvgGraph { - static c(tag: any): any; - constructor(view: any); - view: any; - opts: any; + /** @param {string} tag */ + static c(tag: string): any; + /** + * Create SVG graph renderer. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + */ + constructor(view: import("./jsmind.view_provider.js").ViewProvider); + view: import("./jsmind.view_provider.js").ViewProvider; + opts: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }; e_svg: any; size: { w: number; @@ -11,41 +45,133 @@ declare class SvgGraph { }; lines: any[]; line_drawing: { - straight: (path: any, x1: any, y1: any, x2: any, y2: any) => void; - curved: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; + curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; }; + /** Choose line drawing renderer. */ init_line_render(): void; - drawing: any; - element(): any; - set_size(w: any, h: any): void; + drawing: ((path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void) | ((path: any, x1: any, y1: any, x2: any, y2: any) => void); + /** @returns {SVGSVGElement} */ + element(): SVGSVGElement; + /** @param {number} w @param {number} h */ + set_size(w: number, h: number): void; clear(): void; - draw_line(pout: any, pin: any, offset: any, color: any): void; - copy_to(dest_canvas_ctx: any, callback: any): void; - _bezier_to(path: any, x1: any, y1: any, x2: any, y2: any): void; - _line_to(path: any, x1: any, y1: any, x2: any, y2: any): void; + /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ + draw_line(pout: { + x: number; + y: number; + }, pin: { + x: number; + y: number; + }, offset: { + x: number; + y: number; + }, color?: string | undefined): void; + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + /** + * Draw bezier curve to SVG path. + * @internal + * @param {SVGPathElement} path - SVG path element + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ + _bezier_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; + /** + * Draw straight line to SVG path. + * @internal + * @param {SVGPathElement} path - SVG path element + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ + _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; } +/** + * Canvas-based graph renderer. + */ declare class CanvasGraph { - constructor(view: any); - opts: any; - e_canvas: any; + /** + * Create canvas graph renderer. + * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance + */ + constructor(view: import("./jsmind.view_provider.js").ViewProvider); + opts: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }; + e_canvas: HTMLElement; canvas_ctx: any; size: { w: number; h: number; }; line_drawing: { - straight: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; - curved: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; + curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; }; dpr: any; + /** Choose line drawing renderer. */ init_line_render(): void; - drawing: any; - element(): any; - set_size(w: any, h: any): void; + drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); + /** @returns {HTMLCanvasElement} */ + element(): HTMLCanvasElement; + /** @param {number} w @param {number} h */ + set_size(w: number, h: number): void; + /** Clear the canvas. */ clear(): void; - draw_line(pout: any, pin: any, offset: any, color: any): void; - copy_to(dest_canvas_ctx: any, callback: any): void; - _bezier_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; - _line_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; + /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ + draw_line(pout: { + x: number; + y: number; + }, pin: { + x: number; + y: number; + }, offset: { + x: number; + y: number; + }, color?: string | undefined): void; + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + /** + * Draw bezier curve on canvas. + * @internal + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ + _bezier_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; + /** + * Draw straight line on canvas. + * @internal + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @param {number} x1 - Start x coordinate + * @param {number} y1 - Start y coordinate + * @param {number} x2 - End x coordinate + * @param {number} y2 - End y coordinate + */ + _line_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; } export {}; diff --git a/types/generated/jsmind.layout_provider.d.ts b/types/generated/jsmind.layout_provider.d.ts index 5e92c83e..2381b639 100644 --- a/types/generated/jsmind.layout_provider.d.ts +++ b/types/generated/jsmind.layout_provider.d.ts @@ -1,7 +1,24 @@ export class LayoutProvider { - constructor(jm: any, options: any); - opts: any; - jm: any; + /** + * Layout engine for positioning nodes and lines. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{mode:'full'|'side', hspace:number, vspace:number, pspace:number, cousin_space:number}} options - Layout configuration options + */ + constructor(jm: import("./jsmind.js").default, options: { + mode: "full" | "side"; + hspace: number; + vspace: number; + pspace: number; + cousin_space: number; + }); + opts: { + mode: "full" | "side"; + hspace: number; + vspace: number; + pspace: number; + cousin_space: number; + }; + jm: import("./jsmind.js").default; isside: boolean; bounds: { n: number; @@ -10,40 +27,156 @@ export class LayoutProvider { e: number; }; cache_valid: boolean; + /** Initialize layout provider. */ init(): void; + /** Reset layout state and bounds. */ reset(): void; - calculate_next_child_direction(node: any): number; + /** + * Decide the next child's direction for a parent node. + * @param {import('./jsmind.node.js').Node} node + * @returns {number} + */ + calculate_next_child_direction(node: import("./jsmind.node.js").Node): number; + /** Perform layout and offsets recalculation. */ layout(): void; + /** Calculate and set direction for all nodes. */ layout_direction(): void; - _layout_direction_root(): void; - _layout_direction_side(node: any, direction: any, side_index: any): void; + /** + * Set direction layout for root node and its children. + * @private + */ + private _layout_direction_root; + /** + * Set direction layout for a node and its descendants. + * @private + * @param {import('./jsmind.node.js').Node} node - Target node + * @param {number} direction - Direction constant (-1, 0, 1) + * @param {number} side_index - Index among siblings + */ + private _layout_direction_side; + /** Calculate and set position offsets for all nodes. */ layout_offset(): void; - _layout_offset_subnodes(nodes: any): number; - _layout_offset_subnodes_height(nodes: any): number; - _should_reserve_cousin_space(node: any): boolean; - get_node_offset(node: any): any; - get_node_point(node: any): { - x: any; + /** + * Layout both the x and y axis for subnodes. + * @private + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout + * @returns {number} Total height of all nodes + */ + private _layout_offset_subnodes; + /** + * Layout the y axis only, for collapse/expand a node. + * @private + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout + * @returns {number} Total height of all nodes + */ + private _layout_offset_subnodes_height; + /** + * Check if node should reserve cousin space. + * @private + * @param {import('./jsmind.node.js').Node} node - Node to check + * @returns {boolean} True if cousin space should be reserved + */ + private _should_reserve_cousin_space; + /** + * Get absolute offset for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Absolute position offset + */ + get_node_offset(node: import("./jsmind.node.js").Node): { + x: number; + y: number; + }; + /** + * Get anchor point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Anchor point coordinates + */ + get_node_point(node: import("./jsmind.node.js").Node): { + x: number; + y: number; + }; + /** + * Get input point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Input point coordinates + */ + get_node_point_in(node: import("./jsmind.node.js").Node): { + x: number; + y: number; + }; + /** + * Get output point for lines on a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Output point coordinates + */ + get_node_point_out(node: import("./jsmind.node.js").Node): { + x: number; y: number; }; - get_node_point_in(node: any): any; - get_node_point_out(node: any): any; - get_expander_point(node: any): { - x: any; + /** + * Get expander point for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {{x:number, y:number}} Expander point coordinates + */ + get_expander_point(node: import("./jsmind.node.js").Node): { + x: number; y: number; }; + /** + * Get minimal canvas size to contain all nodes. + * @returns {{w:number, h:number}} Minimum size required + */ get_min_size(): { w: number; h: number; }; - toggle_node(node: any): void; - expand_node(node: any): void; - collapse_node(node: any): void; + /** + * Toggle node expanded/collapsed state. + * @param {import('./jsmind.node.js').Node} node - Target node + */ + toggle_node(node: import("./jsmind.node.js").Node): void; + /** + * Expand a node and show its children. + * @param {import('./jsmind.node.js').Node} node - Target node + */ + expand_node(node: import("./jsmind.node.js").Node): void; + /** + * Collapse a node and hide its children. + * @param {import('./jsmind.node.js').Node} node - Target node + */ + collapse_node(node: import("./jsmind.node.js").Node): void; + /** Expand all nodes in the mind map. */ expand_all(): void; + /** Collapse all nodes in the mind map. */ collapse_all(): void; - expand_to_depth(target_depth: any, curr_nodes: any, curr_depth: any): void; - part_layout(node: any): void; - set_visible(nodes: any, visible: any): void; - is_expand(node: any): any; - is_visible(node: any): boolean; + /** + * Expand nodes to a specific depth level. + * @param {number} target_depth - Target depth level + * @param {import('./jsmind.node.js').Node[]=} curr_nodes - Current nodes to process + * @param {number=} curr_depth - Current depth level + */ + expand_to_depth(target_depth: number, curr_nodes?: import("./jsmind.node.js").Node[] | undefined, curr_depth?: number | undefined): void; + /** + * Perform partial layout for a node and its subtree. + * @param {import('./jsmind.node.js').Node} node - Target node + */ + part_layout(node: import("./jsmind.node.js").Node): void; + /** + * Set visibility for nodes and their children. + * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes + * @param {boolean} visible - Visibility state + */ + set_visible(nodes: import("./jsmind.node.js").Node[], visible: boolean): void; + /** + * Check if a node is expanded. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {boolean} True if node is expanded + */ + is_expand(node: import("./jsmind.node.js").Node): boolean; + /** + * Check if a node is visible. + * @param {import('./jsmind.node.js').Node} node - Target node + * @returns {boolean} True if node is visible + */ + is_visible(node: import("./jsmind.node.js").Node): boolean; } diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts index 03c771f7..7c6994bc 100644 --- a/types/generated/jsmind.mind.d.ts +++ b/types/generated/jsmind.mind.d.ts @@ -5,19 +5,111 @@ export class Mind { root: Node; selected: any; nodes: {}; - get_node(node_id: any): any; - set_root(node_id: any, topic: any, data: any): Node; - add_node(parent_node: any, node_id: any, topic: any, data: any, direction: any, expanded: any, idx: any): Node; - insert_node_before(node_before: any, node_id: any, topic: any, data: any, direction: any): Node; - get_node_before(node: any): any; - insert_node_after(node_after: any, node_id: any, topic: any, data: any, direction: any): Node; - get_node_after(node: any): any; - move_node(node: any, before_id: any, parent_id: any, direction: any): any; - _flow_node_direction(node: any, direction: any): void; - _move_node_internal(node: any, before_id: any): any; - _move_node(node: any, before_id: any, parent_id: any, direction: any): any; - remove_node(node: any): boolean; - _put_node(node: any): boolean; - _update_index(node: any): void; + /** + * Get a node by id. + * @param {string} node_id + * @returns {Node | null} + */ + get_node(node_id: string): Node | null; + /** + * Set the root node, only once. + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @returns {Node | null} + */ + set_root(node_id: string, topic: string, data?: Record | undefined): Node | null; + /** + * Add a child node under parent. + * @param {Node} parent_node + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @param {boolean=} expanded + * @param {number=} idx + * @returns {Node | null} + */ + add_node(parent_node: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined, expanded?: boolean | undefined, idx?: number | undefined): Node | null; + /** + * Insert a node before target node. + * @param {Node} node_before + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {Node | null} + */ + insert_node_before(node_before: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): Node | null; + /** + * Get previous sibling of a node or node id. + * @param {string | Node} node + * @returns {Node | null} + */ + get_node_before(node: string | Node): Node | null; + /** + * Insert a node after target node. + * @param {Node} node_after + * @param {string} node_id + * @param {string} topic + * @param {Record=} data + * @param {number=} direction + * @returns {Node | null} + */ + insert_node_after(node_after: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): Node | null; + /** + * Get next sibling of a node or node id. + * @param {string | Node} node + * @returns {Node | null} + */ + get_node_after(node: string | Node): Node | null; + /** + * Move a node to new parent/position. + * @param {Node} node + * @param {string=} before_id + * @param {string=} parent_id + * @param {number=} direction + * @returns {Node | null} + */ + move_node(node: Node, before_id?: string | undefined, parent_id?: string | undefined, direction?: number | undefined): Node | null; + /** + * Propagate direction to descendants. + * @param {Node} node + * @param {number=} direction + */ + _flow_node_direction(node: Node, direction?: number | undefined): void; + /** + * Re-index node among siblings based on before_id marker. + * @param {Node} node + * @param {string} before_id + * @returns {Node} + */ + _move_node_internal(node: Node, before_id: string): Node; + /** + * Internal move implementation. + * @param {Node} node + * @param {string} before_id + * @param {string} parent_id + * @param {number=} direction + * @returns {Node | null} + */ + _move_node(node: Node, before_id: string, parent_id: string, direction?: number | undefined): Node | null; + /** + * Remove a node from the mind. + * @param {Node} node + * @returns {boolean} + */ + remove_node(node: Node): boolean; + /** + * Put node into the map if id is not taken. + * @param {Node} node + * @returns {boolean} + */ + _put_node(node: Node): boolean; + /** + * Re-index children by Node.compare. + * @param {Node} node + */ + _update_index(node: Node): void; } import { Node } from './jsmind.node.js'; diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts index fb149351..f6aab536 100644 --- a/types/generated/jsmind.node.d.ts +++ b/types/generated/jsmind.node.d.ts @@ -1,24 +1,60 @@ export class Node { - static compare(node1: any, node2: any): number; - static inherited(parent_node: any, node: any): boolean; - static is_node(n: any): boolean; - constructor(sId: any, iIndex: any, sTopic: any, oData: any, bIsRoot: any, oParent: any, eDirection: any, bExpanded: any); - id: any; + /** + * Compare two nodes by index for ordering. + * @param {Node} node1 + * @param {Node} node2 + * @returns {number} + */ + static compare(node1: Node, node2: Node): number; + /** + * Check if node is the same as or a descendant of parent_node. + * @param {Node} parent_node + * @param {Node} node + * @returns {boolean} + */ + static inherited(parent_node: Node, node: Node): boolean; + /** + * Runtime check for Node instance. + * @param {any} n + * @returns {n is Node} + */ + static is_node(n: any): n is Node; + /** + * Create a Node instance. + * @param {string} sId - Node id + * @param {number} iIndex - Node index (order among siblings). Use -1 for tail + * @param {string} sTopic - Node topic text + * @param {Record=} oData - Arbitrary node data + * @param {boolean=} bIsRoot - Whether it is the root node + * @param {Node | null=} oParent - Parent node + * @param {number=} eDirection - Direction for children under root (-1 left, 0 center, 1 right) + * @param {boolean=} bExpanded - Expanded state + */ + constructor(sId: string, iIndex: number, sTopic: string, oData?: Record | undefined, bIsRoot?: boolean | undefined, oParent?: (Node | null) | undefined, eDirection?: number | undefined, bExpanded?: boolean | undefined); + id: string; index: number; - topic: any; - data: any; - isroot: any; - parent: any; - direction: any; + topic: string; + data: Record; + isroot: boolean; + parent: Node; + direction: number; expanded: boolean; children: any[]; _data: {}; + /** + * Get absolute location of this node in view coordinates. + * @returns {{x:number,y:number}} + */ get_location(): { - x: any; - y: any; + x: number; + y: number; }; + /** + * Get rendered size of this node. + * @returns {{w:number,h:number}} + */ get_size(): { - w: any; - h: any; + w: number; + h: number; }; } diff --git a/types/generated/jsmind.option.d.ts b/types/generated/jsmind.option.d.ts index 6f993b90..1ead2a7b 100644 --- a/types/generated/jsmind.option.d.ts +++ b/types/generated/jsmind.option.d.ts @@ -1 +1,53 @@ -export function merge_option(options: any): {}; +/** + * Merge user options with defaults. Throws if container missing. + * @param {Partial} options + * @returns {JsMindRuntimeOptions} + */ +export function merge_option(options: Partial): JsMindRuntimeOptions; +export type JsMindRuntimeOptions = { + container: string | HTMLElement; + editable: boolean; + theme: (string | null); + mode: ("full" | "side"); + support_html: boolean; + log_level: "debug" | "info" | "warn" | "error" | "disable"; + view: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render: (null | ((arg0: any, arg1: HTMLElement, arg2: any) => void)); + expander_style: "char" | "number"; + }; + layout: { + hspace: number; + vspace: number; + pspace: number; + cousin_space: number; + }; + default_event_handle: { + enable_mousedown_handle: boolean; + enable_click_handle: boolean; + enable_dblclick_handle: boolean; + enable_mousewheel_handle: boolean; + }; + shortcut: { + enable: boolean; + handles: Record; + mapping: Record; + }; + plugin: Record; +}; diff --git a/types/generated/jsmind.plugin.d.ts b/types/generated/jsmind.plugin.d.ts index 3ad9668e..20c0f7f4 100644 --- a/types/generated/jsmind.plugin.d.ts +++ b/types/generated/jsmind.plugin.d.ts @@ -1,7 +1,21 @@ -export function register(plugin: any): void; -export function apply(jm: any, options: any): void; +/** + * Register a plugin instance. + * @param {Plugin} plugin + */ +export function register(plugin: Plugin): void; +/** + * Apply registered plugins asynchronously. + * @param {import('./jsmind.js').default} jm + * @param {Record} options + */ +export function apply(jm: import("./jsmind.js").default, options: Record): void; export class Plugin { - constructor(name: any, fn_init: any); - name: any; - fn_init: any; + /** + * @template [TOptions=any] + * @param {string} name + * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init + */ + constructor(name: string, fn_init: (jm: import("./jsmind.js").default, options: TOptions) => void); + name: string; + fn_init: (jm: import("./jsmind.js").default, options: TOptions) => void; } diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts index e481395d..b301661f 100644 --- a/types/generated/jsmind.shortcut_provider.d.ts +++ b/types/generated/jsmind.shortcut_provider.d.ts @@ -1,23 +1,92 @@ export class ShortcutProvider { - constructor(jm: any, options: any); - jm: any; - opts: any; - mapping: any; - handles: any; + /** + * Keyboard shortcut handler. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{enable:boolean, handles:Record, mapping:Record}} options - Shortcut configuration options + */ + constructor(jm: import("./jsmind.js").default, options: { + enable: boolean; + handles: Record; + mapping: Record; + }); + jm: import("./jsmind.js").default; + opts: { + enable: boolean; + handles: Record; + mapping: Record; + }; + mapping: Record; + handles: Record; _newid: any; _mapping: {}; + /** Initialize keyboard listeners and mapping. */ init(): void; + /** Enable shortcuts. */ enable_shortcut(): void; + /** Disable shortcuts. */ disable_shortcut(): void; - handler(e: any): boolean; - handle_addchild(_jm: any, e: any): void; - handle_addbrother(_jm: any, e: any): void; - handle_editnode(_jm: any, e: any): void; - handle_delnode(_jm: any, e: any): void; - handle_toggle(_jm: any, e: any): void; - handle_up(_jm: any, e: any): void; - handle_down(_jm: any, e: any): void; - handle_left(_jm: any, e: any): void; - handle_right(_jm: any, e: any): void; - _handle_direction(_jm: any, e: any, d: any): void; + /** @param {KeyboardEvent} e */ + handler(e: KeyboardEvent): boolean; + /** + * Handle add child node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_addchild(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle add brother node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_addbrother(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle edit node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_editnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle delete node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_delnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle toggle node shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_toggle(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle up arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_up(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle down arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_down(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle left arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_left(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle right arrow key shortcut. + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + */ + handle_right(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** + * Handle directional navigation. + * @private + * @param {import('./jsmind.js').default} _jm - jsMind instance + * @param {KeyboardEvent} e - Keyboard event + * @param {number} d - Direction constant + */ + private _handle_direction; } diff --git a/types/generated/jsmind.util.d.ts b/types/generated/jsmind.util.d.ts index d774469a..c62e3f89 100644 --- a/types/generated/jsmind.util.d.ts +++ b/types/generated/jsmind.util.d.ts @@ -1,17 +1,26 @@ -export namespace util { - namespace file { - function read(file_data: any, fn_callback: any): void; - function save(file_data: any, type: any, name: any): void; - } - namespace json { - function json2string(json: any): string; - function string2json(json_str: any): any; - function merge(b: any, a: any): any; - } - namespace uuid { - function newid(): string; - } - namespace text { - function is_empty(s: any): boolean; - } -} +/** + * Misc utility collection. + * @type {{ + * file: { read: (file: File, cb:(result:string,name:string)=>void)=>void, save:(data:string,type:string,name:string)=>void}, + * json: { json2string:(v:any)=>string, string2json:(s:string)=>any, merge:(b:any,a:any)=>any }, + * uuid: { newid:()=>string }, + * text: { is_empty:(s?:string)=>boolean } + * }} + */ +export const util: { + file: { + read: (file: File, cb: (result: string, name: string) => void) => void; + save: (data: string, type: string, name: string) => void; + }; + json: { + json2string: (v: any) => string; + string2json: (s: string) => any; + merge: (b: any, a: any) => any; + }; + uuid: { + newid: () => string; + }; + text: { + is_empty: (s?: string) => boolean; + }; +}; diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts index 963f7469..de2dddb0 100644 --- a/types/generated/jsmind.view_provider.d.ts +++ b/types/generated/jsmind.view_provider.d.ts @@ -1,20 +1,100 @@ export class ViewProvider { - constructor(jm: any, options: any); - opts: any; - jm: any; - layout: any; + /** + * View layer: DOM nodes, editor, graph and zoom. + * @param {import('./jsmind.js').default} jm - jsMind instance + * @param {{ + * engine: 'canvas'|'svg', + * enable_device_pixel_ratio: boolean, + * hmargin: number, + * vmargin: number, + * line_width: number, + * line_color: string, + * line_style: 'curved'|'straight', + * custom_line_render?: Function, + * draggable: boolean, + * hide_scrollbars_when_draggable: boolean, + * node_overflow: 'hidden'|'wrap', + * zoom: {min:number, max:number, step:number, mask_key:number}, + * custom_node_render?: Function, + * expander_style: 'char'|'number' + * }} options - View configuration options + */ + constructor(jm: import("./jsmind.js").default, options: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }); + opts: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }; + jm: import("./jsmind.js").default; + layout: import("./jsmind.layout_provider.js").LayoutProvider; container: any; - e_panel: any; - e_nodes: any; + e_panel: HTMLElement; + e_nodes: HTMLElement; size: { w: number; h: number; }; - selected_node: any; - editing_node: any; + selected_node: import("./jsmind.node.js").Node; + editing_node: import("./jsmind.node.js").Node; graph: { - view: any; - opts: any; + view: ViewProvider; + opts: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }; e_svg: any; size: { w: number; @@ -22,96 +102,228 @@ export class ViewProvider { }; lines: any[]; line_drawing: { - straight: (path: any, x1: any, y1: any, x2: any, y2: any) => void; - curved: (path: any, x1: any, y1: any, x2: any, y2: any) => void; + straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; + curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; }; init_line_render(): void; - drawing: any; - element(): any; - set_size(w: any, h: any): void; + drawing: ((path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void) | ((path: any, x1: any, y1: any, x2: any, y2: any) => void); + element(): SVGSVGElement; + set_size(w: number, h: number): void; clear(): void; - draw_line(pout: any, pin: any, offset: any, color: any): void; - copy_to(dest_canvas_ctx: any, callback: any): void; - _bezier_to(path: any, x1: any, y1: any, x2: any, y2: any): void; - _line_to(path: any, x1: any, y1: any, x2: any, y2: any): void; + draw_line(pout: { + x: number; + y: number; + }, pin: { + x: number; + y: number; + }, offset: { + x: number; + y: number; + }, color?: string | undefined): void; + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + _bezier_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; + _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; } | { - opts: any; - e_canvas: any; + opts: { + engine: "canvas" | "svg"; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: "curved" | "straight"; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: "hidden" | "wrap"; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: "char" | "number"; + }; + e_canvas: HTMLElement; canvas_ctx: any; size: { w: number; h: number; }; line_drawing: { - straight: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; - curved: (ctx: any, x1: any, y1: any, x2: any, y2: any) => void; + straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; + curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; }; dpr: any; init_line_render(): void; - drawing: any; - element(): any; - set_size(w: any, h: any): void; + drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); + element(): HTMLCanvasElement; + set_size(w: number, h: number): void; clear(): void; - draw_line(pout: any, pin: any, offset: any, color: any): void; - copy_to(dest_canvas_ctx: any, callback: any): void; - _bezier_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; - _line_to(ctx: any, x1: any, y1: any, x2: any, y2: any): void; + draw_line(pout: { + x: number; + y: number; + }, pin: { + x: number; + y: number; + }, offset: { + x: number; + y: number; + }, color?: string | undefined): void; + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + _bezier_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; + _line_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; }; - render_node: (ele: any, node: any) => void; + render_node: (ele: HTMLElement, node: import("./jsmind.node.js").Node) => void; zoom_current: number; device_pixel_ratio: any; _initialized: boolean; + /** Initialize DOM structure, graph and editor. */ init(): void; - e_editor: any; - add_event(obj: any, event_name: any, event_handle: any, capture_by_panel: any): void; - get_binded_nodeid(element: any): any; - is_node(element: any): any; - is_expander(element: any): boolean; + e_editor: HTMLElement; + /** + * Add a delegated event handler. + * @param {any} obj + * @param {string} event_name + * @param {(e:Event)=>void} event_handle + * @param {boolean=} capture_by_panel + */ + add_event(obj: any, event_name: string, event_handle: (e: Event) => void, capture_by_panel?: boolean | undefined): void; + /** @param {HTMLElement|null} element */ + get_binded_nodeid(element: HTMLElement | null): any; + /** @param {HTMLElement|null} element */ + is_node(element: HTMLElement | null): any; + /** @param {HTMLElement} element */ + is_expander(element: HTMLElement): boolean; reset(): void; reset_theme(): void; + /** Reset custom styles for all nodes. */ reset_custom_style(): void; + /** Load and initialize the view. */ load(): void; + /** Calculate and set the expanded canvas size. */ expand_size(): void; - init_nodes_size(node: any): void; + /** + * Initialize size data for a node. + * @param {import('./jsmind.node.js').Node} node - Target node + */ + init_nodes_size(node: import("./jsmind.node.js").Node): void; + /** Initialize DOM elements for all nodes. */ init_nodes(): void; - add_node(node: any): void; - run_in_c11y_mode_if_needed(func: any): void; - create_node_element(node: any, parent_node: any): void; - remove_node(node: any): void; - update_node(node: any): void; - select_node(node: any): void; + /** + * Add a new node to the view. + * @param {import('./jsmind.node.js').Node} node - Node to add + */ + add_node(node: import("./jsmind.node.js").Node): void; + /** + * Run function in compatibility mode if container is not visible. + * @param {Function} func - Function to execute + */ + run_in_c11y_mode_if_needed(func: Function): void; + /** + * Create a DOM element for a node and append to parent container. + * @param {import('./jsmind.node.js').Node} node + * @param {HTMLElement} parent_node + */ + create_node_element(node: import("./jsmind.node.js").Node, parent_node: HTMLElement): void; + /** + * Remove a node from the view. + * @param {import('./jsmind.node.js').Node} node - Node to remove + */ + remove_node(node: import("./jsmind.node.js").Node): void; + /** + * Update a node's display. + * @param {import('./jsmind.node.js').Node} node - Node to update + */ + update_node(node: import("./jsmind.node.js").Node): void; + /** + * Select a node visually. + * @param {import('./jsmind.node.js').Node|null} node - Node to select + */ + select_node(node: import("./jsmind.node.js").Node | null): void; + /** Clear node selection. */ select_clear(): void; - get_editing_node(): any; + /** + * Get currently editing node. + * @returns {import('./jsmind.node.js').Node|null} Currently editing node + */ + get_editing_node(): import("./jsmind.node.js").Node | null; + /** + * Check if any node is being edited. + * @returns {boolean} True if editing + */ is_editing(): boolean; - edit_node_begin(node: any): void; + /** + * Begin editing a node. + * @param {import('./jsmind.node.js').Node} node - Node to edit + */ + edit_node_begin(node: import("./jsmind.node.js").Node): void; + /** End editing current node. */ edit_node_end(): void; + /** @returns {{x:number,y:number}} */ get_view_offset(): { x: number; y: number; }; + /** Resize the view to fit container. */ resize(): void; - _show(): void; - zoom_in(e: any): boolean; - zoom_out(e: any): boolean; - set_zoom(zoom: any, e: any): boolean; + /** + * Internal show implementation. + * @private + */ + private _show; + /** + * Zoom in the view. + * @param {MouseEvent=} e - Mouse event for zoom center + * @returns {boolean} True if zoom succeeded + */ + zoom_in(e?: MouseEvent | undefined): boolean; + /** + * Zoom out the view. + * @param {MouseEvent=} e - Mouse event for zoom center + * @returns {boolean} True if zoom succeeded + */ + zoom_out(e?: MouseEvent | undefined): boolean; + /** + * Set zoom level and keep scroll around zoom center. + * @param {number} zoom + * @param {MouseEvent=} e + */ + set_zoom(zoom: number, e?: MouseEvent | undefined): boolean; show(keep_center: any): void; relayout(): void; - save_location(node: any): void; - restore_location(node: any): void; + /** @param {import('./jsmind.node.js').Node} node */ + save_location(node: import("./jsmind.node.js").Node): void; + /** @param {import('./jsmind.node.js').Node} node */ + restore_location(node: import("./jsmind.node.js").Node): void; clear_nodes(): void; + /** Render node elements and expanders to screen. */ show_nodes(): void; - _show_expander(node: any, view_offset: any): void; + /** @param {import('./jsmind.node.js').Node} node */ + _show_expander(node: import("./jsmind.node.js").Node, view_offset: any): void; _get_expander_text(node: any): any; - _default_node_render(ele: any, node: any): void; - _custom_node_render(ele: any, node: any): void; - reset_node_custom_style(node: any): void; - _reset_node_custom_style(node_element: any, node_data: any): void; - restore_selected_node_custom_style(node: any): void; - clear_selected_node_custom_style(node: any): void; + /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ + _default_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; + /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ + _custom_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; + /** @param {import('./jsmind.node.js').Node} node */ + reset_node_custom_style(node: import("./jsmind.node.js").Node): void; + /** @param {HTMLElement} node_element @param {Record} node_data */ + _reset_node_custom_style(node_element: HTMLElement, node_data: Record): void; + /** @param {import('./jsmind.node.js').Node} node */ + restore_selected_node_custom_style(node: import("./jsmind.node.js").Node): void; + /** @param {import('./jsmind.node.js').Node} node */ + clear_selected_node_custom_style(node: import("./jsmind.node.js").Node): void; clear_lines(): void; show_lines(): void; - setup_canvas_draggable(enabled: any): void; - center_node(node: any): boolean; + /** + * Enable/disable dragging the whole canvas with mouse. + * @param {boolean} enabled + */ + setup_canvas_draggable(enabled: boolean): void; + /** @param {import('./jsmind.node.js').Node} node */ + center_node(node: import("./jsmind.node.js").Node): boolean; zoomIn(e: any): boolean; zoomOut(e: any): boolean; setZoom(zoom: any, e: any): boolean; diff --git a/types/generated/plugins/jsmind.draggable-node.d.ts b/types/generated/plugins/jsmind.draggable-node.d.ts index cb0ff5c3..b2ffdf32 100644 --- a/types/generated/plugins/jsmind.draggable-node.d.ts +++ b/types/generated/plugins/jsmind.draggable-node.d.ts @@ -1 +1,229 @@ -export {}; +/** + * Draggable node plugin for jsMind. + */ +export class DraggableNode { + /** + * Create draggable node plugin instance. + * @param {import('../jsmind.js').default} jm - jsMind instance + * @param {Partial} options - Plugin options + */ + constructor(jm: import("../jsmind.js").default, options: Partial); + version: string; + /** @type {import('../jsmind.js').default} */ + jm: import("../jsmind.js").default; + /** @type {DraggableNodeOptions} */ + options: DraggableNodeOptions; + /** @type {HTMLCanvasElement|null} */ + e_canvas: HTMLCanvasElement | null; + /** @type {CanvasRenderingContext2D|null} */ + canvas_ctx: CanvasRenderingContext2D | null; + /** @type {HTMLElement|null} */ + shadow: HTMLElement | null; + /** @type {number} */ + shadow_p_x: number; + /** @type {number} */ + shadow_p_y: number; + /** @type {number} */ + shadow_w: number; + /** @type {number} */ + shadow_h: number; + /** @type {import('../jsmind.node.js').Node|null} */ + active_node: import("../jsmind.node.js").Node | null; + /** @type {import('../jsmind.node.js').Node|null} */ + target_node: import("../jsmind.node.js").Node | null; + /** @type {number|null} */ + target_direct: number | null; + /** @type {number} */ + client_w: number; + /** @type {number} */ + client_h: number; + /** @type {number} */ + offset_x: number; + /** @type {number} */ + offset_y: number; + /** @type {number} */ + hlookup_delay: number; + /** @type {number} */ + hlookup_timer: number; + /** @type {boolean} */ + capture: boolean; + /** @type {boolean} */ + moved: boolean; + /** @type {boolean} */ + canvas_draggable: boolean; + /** @type {HTMLElement} */ + view_panel: HTMLElement; + /** @type {DOMRect|null} */ + view_panel_rect: DOMRect | null; + /** Initialize the draggable node plugin. */ + init(): void; + /** Resize canvas and shadow elements. */ + resize(): void; + /** Create canvas for drawing drag lines. */ + create_canvas(): void; + create_shadow(): void; + /** + * Reset shadow element style and cache its size. + * @param {HTMLElement} el - The node element to mirror as shadow + */ + reset_shadow(el: HTMLElement): void; + /** Show the shadow element. */ + show_shadow(): void; + /** Hide the shadow element. */ + hide_shadow(): void; + /** + * Draw a helper line between the shadow and target node. + * @param {{x:number,y:number}} shadow_p - Shadow anchor point + * @param {{x:number,y:number}} node_p - Target node anchor point + * @param {boolean} invalid - Whether current target is invalid + */ + magnet_shadow(shadow_p: { + x: number; + y: number; + }, node_p: { + x: number; + y: number; + }, invalid: boolean): void; + /** Clear helper lines from canvas. */ + clear_lines(): void; + /** + * Draw a straight helper line. + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + */ + canvas_lineto(x1: number, y1: number, x2: number, y2: number): void; + /** Bind mouse/touch events for dragging. */ + event_bind(): void; + /** + * Begin dragging interaction. + * @param {MouseEvent|TouchEvent} e - Pointer down event + */ + dragstart(e: MouseEvent | TouchEvent): void; + view_draggable: boolean; + client_hw: number; + client_hh: number; + /** + * Drag handler to move shadow and auto-scroll container. + * @param {MouseEvent|TouchEvent} e - Pointer move event + */ + drag(e: MouseEvent | TouchEvent): void; + /** + * Finish dragging, move the node if applicable. + * @param {MouseEvent|TouchEvent} e - Pointer up event + */ + dragend(e: MouseEvent | TouchEvent): void; + /** + * Find the closest node element from an event target. + * @param {HTMLElement} el - Current DOM element + * @returns {HTMLElement|null} Matched node element or null + */ + find_node_element(el: HTMLElement): HTMLElement | null; + /** Recompute target node under the shadow and draw helper. */ + lookup_target_node(): void; + /** + * Get X coordinate of root node center. + * @returns {number} + */ + get_root_x(): number; + /** + * Lookup overlapping node's parent near the shadow position. + * @param {number} direction - Direction constant + * @returns {import('../jsmind.node.js').Node|null} + */ + lookup_overlapping_node_parent(direction: number): import("../jsmind.node.js").Node | null; + /** + * Find node's parent by a screen location. + * @param {number} x - Client X + * @param {number} y - Client Y + * @returns {import('../jsmind.node.js').Node|null} + */ + lookup_node_parent_by_location(x: number, y: number): import("../jsmind.node.js").Node | null; + /** + * Lookup the closest node along a direction. + * @param {number} direction + * @returns {import('../jsmind.node.js').Node} + */ + lookup_close_node(direction: number): import("../jsmind.node.js").Node; + /** + * Check if shadow is on the target side of a node. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {boolean} + */ + shadow_on_target_side(node: import("../jsmind.node.js").Node, dir: number): boolean; + /** + * Distance from shadow to the right side of a node. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ + shadow_to_right_of_node(node: import("../jsmind.node.js").Node): number; + /** + * Distance from shadow to the left side of a node. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ + shadow_to_left_of_node(node: import("../jsmind.node.js").Node): number; + /** + * Vertical distance between shadow centerline and node centerline. + * @param {import('../jsmind.node.js').Node} node + * @returns {number} + */ + shadow_to_base_line_of_node(node: import("../jsmind.node.js").Node): number; + /** + * Manhattan distance to a node along a direction. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {number} + */ + shadow_to_node(node: import("../jsmind.node.js").Node, dir: number): number; + /** + * Calculate connection points of a node and the shadow. + * @param {import('../jsmind.node.js').Node} node + * @param {number} dir + * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}} + */ + calc_point_of_node(node: import("../jsmind.node.js").Node, dir: number): { + sp: { + x: number; + y: number; + }; + np: { + x: number; + y: number; + }; + }; + /** + * Move a node to a new parent/position. + * @param {import('../jsmind.node.js').Node} src_node + * @param {import('../jsmind.node.js').Node|null} target_node + * @param {number|null} target_direct + */ + move_node(src_node: import("../jsmind.node.js").Node, target_node: import("../jsmind.node.js").Node | null, target_direct: number | null): void; + /** + * Handle jsMind events. + * @param {number|string} type - Event type + * @param {any} [data] - Event data + */ + jm_event_handle(type: number | string, data?: any): void; +} +/** + * Draggable node plugin registration. + * @type {import('../jsmind.plugin.js').Plugin>} + */ +export const draggable_plugin: import("../jsmind.plugin.js").Plugin>; +export default DraggableNode; +/** + * Default options for draggable node plugin. + */ +export type DraggableNodeOptions = { + line_width?: number; + line_color?: string; + line_color_invalid?: string; + lookup_delay?: number; + lookup_interval?: number; + scrolling_trigger_width?: number; + scrolling_step_length?: number; + shadow_node_class_name?: string; +}; diff --git a/types/generated/plugins/jsmind.screenshot.d.ts b/types/generated/plugins/jsmind.screenshot.d.ts index cb0ff5c3..2fb9abdd 100644 --- a/types/generated/plugins/jsmind.screenshot.d.ts +++ b/types/generated/plugins/jsmind.screenshot.d.ts @@ -1 +1,83 @@ -export {}; +/** + * Screenshot plugin for jsMind. + */ +export class JmScreenshot { + /** + * Create screenshot plugin instance. + * @param {import('../jsmind.js').default} jm - jsMind instance + * @param {Partial} options - Plugin options + */ + constructor(jm: import("../jsmind.js").default, options: Partial); + version: string; + /** @type {import('../jsmind.js').default} */ + jm: import("../jsmind.js").default; + /** @type {ScreenshotOptions} */ + options: ScreenshotOptions; + /** @type {number} */ + dpr: number; + /** Take a screenshot of the mind map. */ + shoot(): void; + /** + * Create canvas for screenshot. + * @returns {HTMLCanvasElement} Canvas element + */ + create_canvas(): HTMLCanvasElement; + /** + * Clean up canvas element. + * @param {HTMLCanvasElement} c - Canvas to remove + */ + clear(c: HTMLCanvasElement): void; + /** + * Draw background on canvas. + * @param {CanvasRenderingContext2D} ctx - Canvas context + * @returns {Promise} Promise resolving to context + */ + draw_background(ctx: CanvasRenderingContext2D): Promise; + /** + * Draw connection lines on canvas by copying from view graph. + * @param {CanvasRenderingContext2D} ctx + * @returns {Promise} + */ + draw_lines(ctx: CanvasRenderingContext2D): Promise; + /** + * Draw node DOM into canvas via SVG snapshot. + * @param {CanvasRenderingContext2D} ctx + * @returns {Promise} + */ + draw_nodes(ctx: CanvasRenderingContext2D): Promise; + /** + * Draw watermark text on canvas. + * @param {HTMLCanvasElement} c + * @param {CanvasRenderingContext2D} ctx + * @returns {CanvasRenderingContext2D} + */ + draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + /** + * Load image from URL and resolve img element. + * @param {string} url + * @returns {Promise} + */ + load_image(url: string): Promise; + /** + * Trigger download of canvas content as PNG. + * @param {HTMLCanvasElement} c + */ + download(c: HTMLCanvasElement): void; +} +/** + * Screenshot plugin registration. + * @type {import('../jsmind.plugin.js').Plugin>} + */ +export const screenshot_plugin: import("../jsmind.plugin.js").Plugin>; +export default JmScreenshot; +/** + * Default options for screenshot plugin. + */ +export type ScreenshotOptions = { + filename?: string | null; + watermark?: { + left?: string | Location; + right?: string; + }; + background?: string; +}; From d63514c87a2206997cad174ce9c1c928a4f02936 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 13:39:14 +0800 Subject: [PATCH 14/24] feat(types): migrate and regenerate TypeScript declarations; align core sources - Move declarations to types/generated and add central types/index.d.ts - Remove legacy types under types/ (jsmind.d.ts, draggable-node.d.ts, screenshot.d.ts) - Update tsconfig for declaration output; tweak strictness - Update package.json types entry and related scripts - Sync core modules and plugins with typings (dom/format/mind/node/shortcut/util/view_provider, draggable-node) - Update tests/fixtures/typescript-test.ts to reflect new types --- package.json | 8 +- src/jsmind.dom.js | 7 +- src/jsmind.format.js | 62 ++- src/jsmind.js | 70 ++- src/jsmind.mind.js | 6 + src/jsmind.node.js | 3 +- src/jsmind.shortcut_provider.js | 61 --- src/jsmind.util.js | 2 +- src/jsmind.view_provider.js | 15 +- src/plugins/jsmind.draggable-node.js | 2 +- tests/fixtures/typescript-test.ts | 76 ++-- tsconfig.json | 16 +- types/generated/jsmind.d.ts | 117 +++-- types/generated/jsmind.dom.d.ts | 15 +- types/generated/jsmind.format.d.ts | 63 ++- types/generated/jsmind.graph.d.ts | 6 +- types/generated/jsmind.mind.d.ts | 18 +- types/generated/jsmind.node.d.ts | 7 +- types/generated/jsmind.shortcut_provider.d.ts | 101 +---- types/generated/jsmind.util.d.ts | 8 +- types/generated/jsmind.view_provider.d.ts | 25 +- .../plugins/jsmind.draggable-node.d.ts | 4 +- types/index.d.ts | 24 ++ types/jsmind.d.ts | 407 ------------------ types/jsmind.draggable-node.d.ts | 93 ---- types/jsmind.screenshot.d.ts | 49 --- 26 files changed, 402 insertions(+), 863 deletions(-) create mode 100644 types/index.d.ts delete mode 100644 types/jsmind.d.ts delete mode 100644 types/jsmind.draggable-node.d.ts delete mode 100644 types/jsmind.screenshot.d.ts diff --git a/package.json b/package.json index 06f22c29..aa488d0b 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,22 @@ "version": "0.8.7", "description": "jsMind is a pure javascript library for mindmap, it base on html5 canvas. jsMind was released under BSD license, you can embed it in any project, if only you observe the license.", "main": "es6/jsmind.js", - "types": "types/jsmind.d.ts", + "types": "types/index.d.ts", "exports": { ".": { "import": "./es6/jsmind.js", "require": "./es6/jsmind.js", - "types": "./types/jsmind.d.ts" + "types": "./types/index.d.ts" }, "./draggable-node": { "import": "./es6/jsmind.draggable-node.js", "require": "./es6/jsmind.draggable-node.js", - "types": "./types/jsmind.draggable-node.d.ts" + "types": "./types/generated/plugins/jsmind.draggable-node.d.ts" }, "./screenshot": { "import": "./es6/jsmind.screenshot.js", "require": "./es6/jsmind.screenshot.js", - "types": "./types/jsmind.screenshot.d.ts" + "types": "./types/generated/plugins/jsmind.screenshot.d.ts" }, "./style/jsmind.css": "./style/jsmind.css" }, diff --git a/src/jsmind.dom.js b/src/jsmind.dom.js index 39308f50..c29d4dd3 100644 --- a/src/jsmind.dom.js +++ b/src/jsmind.dom.js @@ -10,8 +10,13 @@ * Lightweight DOM helpers bound to a window. */ class Dom { + /** + * @param {Window} w + */ constructor(w) { + /** @type {Window} */ this.w = w; + /** @type {Document} */ this.d = w.document; /** * Get element by id. @@ -58,7 +63,7 @@ class Dom { // detect isElement /** * Runtime check for HTMLElement. - * @param {any} el + * @param {unknown} el * @returns {el is HTMLElement} */ this.i = function (el) { diff --git a/src/jsmind.format.js b/src/jsmind.format.js index 5c1b8978..4abbc281 100644 --- a/src/jsmind.format.js +++ b/src/jsmind.format.js @@ -12,14 +12,53 @@ import { Node } from './jsmind.node.js'; import { util } from './jsmind.util.js'; /** @typedef {{name:string,author:string,version:string}} MindMapMeta */ +/** + * Node tree data item + * @typedef {{ + * id: string, + * topic: string, + * data?: Record, + * direction?: (number|string), + * expanded?: boolean, + * children?: NodeTreeData[] + * }} NodeTreeData + */ +/** + * Node tree formatted payload + * @typedef {{ + * meta?: MindMapMeta, + * format: 'node_tree', + * data: NodeTreeData + * }} NodeTreeFormat + */ +/** + * Node array data item + * @typedef {{ + * id: string, + * topic: string, + * parentid?: string, + * data?: Record, + * direction?: (number|string), + * expanded?: boolean, + * isroot?: boolean + * }} NodeArrayItem + */ +/** + * Node array formatted payload + * @typedef {{ + * meta?: MindMapMeta, + * format: 'node_array', + * data: NodeArrayItem[] + * }} NodeArrayFormat + */ /** @type {MindMapMeta} */ const DEFAULT_META = { name: 'jsMind', author: __author__, version: __version__ }; /** * Mind data format handlers. * @type {{ - * node_tree: { example:{meta:MindMapMeta,format:'node_tree',data:any}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, - * node_array: { example:{meta:MindMapMeta,format:'node_array',data:any[]}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * node_tree: { example:NodeTreeFormat, get_mind:(src:NodeTreeFormat)=>Mind, get_data:(mind:Mind)=>NodeTreeFormat }, + * node_array: { example:NodeArrayFormat, get_mind:(src:NodeArrayFormat)=>Mind, get_data:(mind:Mind)=>NodeArrayFormat }, * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } * }} @@ -31,7 +70,7 @@ export const format = { format: 'node_tree', data: { id: 'root', topic: 'jsMind node_tree example' }, }, - /** @param {{meta:MindMapMeta,data:any}} source @returns {Mind} */ + /** @param {NodeTreeFormat} source @returns {Mind} */ get_mind: function (source) { var df = format.node_tree; var mind = new Mind(); @@ -55,7 +94,7 @@ export const format = { return json; }, - /** @param {Mind} mind @param {{id:string,topic:string,children?:any[]}} node_root */ + /** @param {Mind} mind @param {NodeTreeData} node_root */ _parse: function (mind, node_root) { var df = format.node_tree; var data = df._extract_data(node_root); @@ -91,7 +130,7 @@ export const format = { return data; }, - /** @param {Mind} mind @param {Node} node_parent @param {{id:string,topic:string,children?:any[]}} node_json */ + /** @param {Mind} mind @param {Node} node_parent @param {NodeTreeData} node_json */ _extract_subnode: function (mind, node_parent, node_json) { var df = format.node_tree; var data = df._extract_data(node_json); @@ -121,6 +160,7 @@ export const format = { * @param {Node} node - Node to convert * @returns {any} JSON representation of node */ + /** @returns {NodeTreeData} */ _build_node: function (node) { var df = format.node_tree; if (!(node instanceof Node)) { @@ -158,7 +198,7 @@ export const format = { data: [{ id: 'root', topic: 'jsMind node_array example', isroot: true }], }, - /** @param {{meta:MindMapMeta,data:any[]}} source @returns {Mind} */ + /** @param {NodeArrayFormat} source @returns {Mind} */ get_mind: function (source) { var df = format.node_array; var mind = new Mind(); @@ -184,7 +224,7 @@ export const format = { return json; }, - /** @param {Mind} mind @param {any[]} node_array */ + /** @param {Mind} mind @param {NodeArrayItem[]} node_array */ _parse: function (mind, node_array) { var df = format.node_array; var nodes = node_array.slice(0); @@ -198,7 +238,7 @@ export const format = { } }, - /** @param {Mind} mind @param {any[]} node_array */ + /** @param {Mind} mind @param {NodeArrayItem[]} node_array */ _extract_root: function (mind, node_array) { var df = format.node_array; var i = node_array.length; @@ -214,7 +254,7 @@ export const format = { return null; }, - /** @param {Mind} mind @param {Node} parent_node @param {any[]} node_array */ + /** @param {Mind} mind @param {Node} parent_node @param {NodeArrayItem[]} node_array */ _extract_subnode: function (mind, parent_node, node_array) { var df = format.node_array; var i = node_array.length; @@ -269,13 +309,13 @@ export const format = { return data; }, - /** @param {Mind} mind @param {any[]} node_array */ + /** @param {Mind} mind @param {NodeArrayItem[]} node_array */ _array: function (mind, node_array) { var df = format.node_array; df._array_node(mind.root, node_array); }, - /** @param {Node} node @param {any[]} node_array */ + /** @param {Node} node @param {NodeArrayItem[]} node_array */ _array_node: function (node, node_array) { var df = format.node_array; if (!(node instanceof Node)) { diff --git a/src/jsmind.js b/src/jsmind.js index 4525853f..5e6b55f6 100644 --- a/src/jsmind.js +++ b/src/jsmind.js @@ -19,6 +19,11 @@ import { format } from './jsmind.format.js'; import { $ } from './jsmind.dom.js'; import { util as _util } from './jsmind.util.js'; +/** + * Event callback payload + * @typedef {{ evt?: string, data?: unknown[], node?: string }} EventData + */ + /** * jsMind runtime: orchestrates data/layout/view/shortcut and exposes public API. */ @@ -43,6 +48,7 @@ export default class jsMind { this.version = __version__; this.initialized = false; this.mind = null; + /** @type {Array<(type: number, data: EventData) => void>} */ this.event_handles = []; this.init(); } @@ -249,6 +255,7 @@ export default class jsMind { /** * Toggle a node's expanded state. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ toggle_node(node) { if (!Node.is_node(node)) { @@ -257,7 +264,8 @@ export default class jsMind { logger.error('the node[id=' + node + '] can not be found.'); return; } else { - return this.toggle_node(the_node); + this.toggle_node(the_node); + return; } } if (node.isroot) { @@ -271,6 +279,7 @@ export default class jsMind { /** * Expand a node. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ expand_node(node) { if (!Node.is_node(node)) { @@ -279,7 +288,8 @@ export default class jsMind { logger.error('the node[id=' + node + '] can not be found.'); return; } else { - return this.expand_node(the_node); + this.expand_node(the_node); + return; } } if (node.isroot) { @@ -293,6 +303,7 @@ export default class jsMind { /** * Collapse a node. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ collapse_node(node) { if (!Node.is_node(node)) { @@ -301,7 +312,8 @@ export default class jsMind { logger.error('the node[id=' + node + '] can not be found.'); return; } else { - return this.collapse_node(the_node); + this.collapse_node(the_node); + return; } } if (node.isroot) { @@ -335,7 +347,7 @@ export default class jsMind { } /** * Internal show flow. - * @param {any} mind + * @param {object | null} mind * @param {boolean=} skip_centering */ _show(mind, skip_centering) { @@ -361,7 +373,7 @@ export default class jsMind { } /** * Show a mind (or example) on the canvas. - * @param {any} mind + * @param {object | null} mind * @param {boolean=} skip_centering */ show(mind, skip_centering) { @@ -379,7 +391,7 @@ export default class jsMind { /** * Serialize current mind to given format. * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] - * @returns {any} + * @returns {object} */ get_data(data_format) { var df = data_format || 'node_tree'; @@ -595,7 +607,10 @@ export default class jsMind { return; } } - /** @param {string | import('./jsmind.node.js').Node} node */ + /** + * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} + */ select_node(node) { if (!Node.is_node(node)) { var the_node = this.get_node(node); @@ -603,7 +618,8 @@ export default class jsMind { logger.error('the node[id=' + node + '] can not be found.'); return; } else { - return this.select_node(the_node); + this.select_node(the_node); + return; } } if (!this.layout.is_visible(node)) { @@ -723,7 +739,12 @@ export default class jsMind { } return n; } - /** @param {string} node_id @param {string=} bg_color @param {string=} fg_color */ + /** + * @param {string} node_id + * @param {string=} bg_color + * @param {string=} fg_color + * @returns {void} + */ set_node_color(node_id, bg_color, fg_color) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -741,7 +762,13 @@ export default class jsMind { return null; } } - /** @param {string} node_id @param {number=} size @param {string=} weight @param {string=} style */ + /** + * @param {string} node_id + * @param {number=} size + * @param {string=} weight + * @param {string=} style + * @returns {void} + */ set_node_font_style(node_id, size, weight, style) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -765,7 +792,14 @@ export default class jsMind { return null; } } - /** @param {string} node_id @param {string} image @param {number=} width @param {number=} height @param {number=} rotation */ + /** + * @param {string} node_id + * @param {string} image + * @param {number=} width + * @param {number=} height + * @param {number=} rotation + * @returns {void} + */ set_node_background_image(node_id, image, width, height, rotation) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -792,7 +826,11 @@ export default class jsMind { return null; } } - /** @param {string} node_id @param {number} rotation */ + /** + * @param {string} node_id + * @param {number} rotation + * @returns {void} + */ set_node_background_rotation(node_id, rotation) { if (this.get_editable()) { var node = this.mind.get_node(node_id); @@ -819,7 +857,7 @@ export default class jsMind { this.view.resize(); } // callback(type ,data) - /** @param {(type:number, data:any)=>void} callback */ + /** @param {(type:number, data: EventData)=>void} callback */ add_event_listener(callback) { if (typeof callback === 'function') { this.event_handles.push(callback); @@ -829,14 +867,14 @@ export default class jsMind { clear_event_listener() { this.event_handles = []; } - /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ + /** @param {number} type @param {EventData} data */ invoke_event_handle(type, data) { var j = this; $.w.setTimeout(function () { j._invoke_event_handle(type, data); }, 0); } - /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ + /** @param {number} type @param {EventData} data */ _invoke_event_handle(type, data) { var l = this.event_handles.length; for (var i = 0; i < l; i++) { @@ -847,7 +885,7 @@ export default class jsMind { /** * Deprecated: static show constructor helper. * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options - * @param {any} mind + * @param {object | null} mind * @returns {jsMind} */ static show(options, mind) { diff --git a/src/jsmind.mind.js b/src/jsmind.mind.js index 5815f923..1c0ec6ef 100644 --- a/src/jsmind.mind.js +++ b/src/jsmind.mind.js @@ -14,11 +14,17 @@ export class Mind { * Mind model: holds nodes and selection. */ constructor() { + /** @type {string | null} */ this.name = null; + /** @type {string | null} */ this.author = null; + /** @type {string | null} */ this.version = null; + /** @type {Node | null} */ this.root = null; + /** @type {Node | null} */ this.selected = null; + /** @type {Record} */ this.nodes = {}; } /** diff --git a/src/jsmind.node.js b/src/jsmind.node.js index 537313ba..d1e44be6 100644 --- a/src/jsmind.node.js +++ b/src/jsmind.node.js @@ -39,6 +39,7 @@ export class Node { this.parent = oParent; this.direction = eDirection; this.expanded = !!bExpanded; + /** @type {Node[]} */ this.children = []; this._data = {}; } @@ -117,7 +118,7 @@ export class Node { } /** * Runtime check for Node instance. - * @param {any} n + * @param {unknown} n * @returns {n is Node} */ static is_node(n) { diff --git a/src/jsmind.shortcut_provider.js b/src/jsmind.shortcut_provider.js index 9e460e65..c0255288 100644 --- a/src/jsmind.shortcut_provider.js +++ b/src/jsmind.shortcut_provider.js @@ -11,11 +11,6 @@ import { util } from './jsmind.util.js'; import { Direction } from './jsmind.common.js'; export class ShortcutProvider { - /** - * Keyboard shortcut handler. - * @param {import('./jsmind.js').default} jm - jsMind instance - * @param {{enable:boolean, handles:Record, mapping:Record}} options - Shortcut configuration options - */ constructor(jm, options) { this.jm = jm; this.opts = options; @@ -24,7 +19,6 @@ export class ShortcutProvider { this._newid = null; this._mapping = {}; } - /** Initialize keyboard listeners and mapping. */ init() { $.on(this.jm.view.e_panel, 'keydown', this.handler.bind(this)); @@ -56,15 +50,12 @@ export class ShortcutProvider { this._newid = util.uuid.newid; } } - /** Enable shortcuts. */ enable_shortcut() { this.opts.enable = true; } - /** Disable shortcuts. */ disable_shortcut() { this.opts.enable = false; } - /** @param {KeyboardEvent} e */ handler(e) { if (e.which == 9) { e.preventDefault(); @@ -86,11 +77,6 @@ export class ShortcutProvider { this._mapping[kc].call(this, this.jm, e); } } - /** - * Handle add child node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_addchild(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { @@ -102,11 +88,6 @@ export class ShortcutProvider { } } } - /** - * Handle add brother node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_addbrother(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -118,22 +99,12 @@ export class ShortcutProvider { } } } - /** - * Handle edit node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_editnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { _jm.begin_edit(selected_node); } } - /** - * Handle delete node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_delnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -141,11 +112,6 @@ export class ShortcutProvider { _jm.remove_node(selected_node); } } - /** - * Handle toggle node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_toggle(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -155,11 +121,6 @@ export class ShortcutProvider { evt.preventDefault(); } } - /** - * Handle up arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_up(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -178,11 +139,6 @@ export class ShortcutProvider { evt.preventDefault(); } } - /** - * Handle down arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_down(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -201,29 +157,12 @@ export class ShortcutProvider { evt.preventDefault(); } } - /** - * Handle left arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_left(_jm, e) { this._handle_direction(_jm, e, Direction.left); } - /** - * Handle right arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ handle_right(_jm, e) { this._handle_direction(_jm, e, Direction.right); } - /** - * Handle directional navigation. - * @private - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - * @param {number} d - Direction constant - */ _handle_direction(_jm, e, d) { var evt = e || event; var selected_node = _jm.get_selected_node(); diff --git a/src/jsmind.util.js b/src/jsmind.util.js index d84af91c..bf1b2c22 100644 --- a/src/jsmind.util.js +++ b/src/jsmind.util.js @@ -12,7 +12,7 @@ import { $ } from './jsmind.dom.js'; * Misc utility collection. * @type {{ * file: { read: (file: File, cb:(result:string,name:string)=>void)=>void, save:(data:string,type:string,name:string)=>void}, - * json: { json2string:(v:any)=>string, string2json:(s:string)=>any, merge:(b:any,a:any)=>any }, + * json: { json2string:(v:unknown)=>string, string2json:(s:string)=>unknown, merge:(b:object,a:object)=>object }, * uuid: { newid:()=>string }, * text: { is_empty:(s?:string)=>boolean } * }} diff --git a/src/jsmind.view_provider.js b/src/jsmind.view_provider.js index 8affa918..f8340a93 100644 --- a/src/jsmind.view_provider.js +++ b/src/jsmind.view_provider.js @@ -116,7 +116,10 @@ export class ViewProvider { event_handle.call(obj, evt); }); } - /** @param {HTMLElement|null} element */ + /** + * @param {HTMLElement|null} element + * @returns {string|null} + */ get_binded_nodeid(element) { if (element == null) { return null; @@ -130,7 +133,10 @@ export class ViewProvider { return this.get_binded_nodeid(element.parentElement); } } - /** @param {HTMLElement|null} element */ + /** + * @param {HTMLElement|null} element + * @returns {boolean} + */ is_node(element) { if (element == null) { return false; @@ -144,7 +150,10 @@ export class ViewProvider { return this.is_node(element.parentElement); } } - /** @param {HTMLElement} element */ + /** + * @param {HTMLElement} element + * @returns {boolean} + */ is_expander(element) { return element.tagName.toLowerCase() == 'jmexpander'; } diff --git a/src/plugins/jsmind.draggable-node.js b/src/plugins/jsmind.draggable-node.js index e12da618..d676486d 100644 --- a/src/plugins/jsmind.draggable-node.js +++ b/src/plugins/jsmind.draggable-node.js @@ -602,7 +602,7 @@ export class DraggableNode { /** * Handle jsMind events. * @param {number|string} type - Event type - * @param {any} [data] - Event data + * @param {object} [data] - Event data */ jm_event_handle(type, data) { if (type === jsMind.event_type.resize) { diff --git a/tests/fixtures/typescript-test.ts b/tests/fixtures/typescript-test.ts index 995f8cd4..d7dbb1fe 100644 --- a/tests/fixtures/typescript-test.ts +++ b/tests/fixtures/typescript-test.ts @@ -4,7 +4,14 @@ */ // Import core library (resolved via package name to types/) -import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from 'jsmind'; +import jsMind, { + Node, + Mind, + JsMindOptions, + MindMapMeta, + NodeTreeFormat, + NodeTreeData, +} from 'jsmind'; // Note: in real usage, plugins should be imported to register themselves // import 'jsmind/draggable-node'; // import 'jsmind/screenshot'; @@ -13,7 +20,7 @@ import jsMind, { Node, Mind, JsMindOptions, NodeTreeFormat, MindMapData } from ' // Basic options // ============================================================================ -// Minimal options +// Minimal options (must satisfy JsMindRuntimeOptions strict fields) const basicOptions: JsMindOptions = { container: 'jsmind_container', editable: true, @@ -21,6 +28,30 @@ const basicOptions: JsMindOptions = { mode: 'full', support_html: true, log_level: 'info', + view: { + engine: 'canvas', + enable_device_pixel_ratio: true, + hmargin: 120, + vmargin: 60, + line_width: 3, + line_color: '#333', + line_style: 'straight', + draggable: true, + hide_scrollbars_when_draggable: true, + node_overflow: 'wrap', + zoom: { min: 0.3, max: 3.0, step: 0.2, mask_key: 4096 }, + custom_node_render: null, + expander_style: 'number', + }, + layout: { hspace: 40, vspace: 25, pspace: 15, cousin_space: 5 }, + default_event_handle: { + enable_mousedown_handle: true, + enable_click_handle: true, + enable_dblclick_handle: false, + enable_mousewheel_handle: true, + }, + shortcut: { enable: true, handles: {}, mapping: {} }, + plugin: {}, }; // Full options @@ -103,21 +134,14 @@ const fullOptions: JsMindOptions = { // Data formats // ============================================================================ -// NodeTreeFormat specimen +// Strictly typed NodeTree data using generated MindMapMeta const nodeTreeData: NodeTreeFormat = { - meta: { - name: 'Test Mind Map', - author: 'TypeScript Tester', - version: '1.0', - }, + meta: { name: 'Test Mind Map', author: 'TypeScript Tester', version: '1.0' }, format: 'node_tree', data: { id: 'root', topic: 'Root Topic', - data: { - background: '#ff0000', - foreground: '#ffffff', - }, + data: { background: '#ff0000', foreground: '#ffffff' }, children: [ { id: 'child1', @@ -125,19 +149,10 @@ const nodeTreeData: NodeTreeFormat = { direction: 1, expanded: true, children: [ - { - id: 'grandchild1', - topic: 'Grandchild 1', - data: { note: 'This is a note' }, - }, + { id: 'grandchild1', topic: 'Grandchild 1', data: { note: 'This is a note' } }, ], }, - { - id: 'child2', - topic: 'Child 2', - direction: -1, - expanded: false, - }, + { id: 'child2', topic: 'Child 2', direction: -1, expanded: false }, ], }, }; @@ -173,7 +188,6 @@ const resizeEvent: number = eventType.resize; // Show mind map jm.show(nodeTreeData); -jm.show(); // Show an empty mind map // Query state const meta = jm.get_meta(); @@ -198,7 +212,7 @@ if (root) { // Edit operations jm.enable_edit(); const isEditable: boolean = jm.get_editable(); -jm.begin_edit(); +// begin_edit requires a node id or Node jm.end_edit(); jm.disable_edit(); @@ -213,8 +227,10 @@ const isDraggable: boolean = jm.get_view_draggable(); jm.disable_view_draggable(); jm.resize(); -// Event listener -jm.add_event_listener((type: number, data: any) => { +// Event listener with stricter data shape + +jm.add_event_listener((type, data) => { + // data: { evt?: string; data?: unknown[]; node?: string } console.log(`Event ${type} triggered with data:`, data); }); @@ -245,8 +261,8 @@ const comparison: number = Node.compare(testNode, testNode); // JSON utils const jsonString: string = util.json.json2string({ test: 'data' }); -const jsonObject: any = util.json.string2json('{"test":"data"}'); -const mergedObject: any = util.json.merge({}, { test: 'data' }); +const jsonObject = util.json.string2json('{"test":"data"}') as { test: string }; +const mergedObject = util.json.merge({}, { test: 'data' }) as object; // UUID utils const newId: string = util.uuid.newid(); @@ -274,7 +290,7 @@ function validateTypes() { const config: JsMindOptions = basicOptions; // Validate data format types - const mindData: MindMapData = nodeTreeData; + const mindData: NodeTreeFormat = nodeTreeData; // Validate return types const rootNode: Node | null = jm.get_root(); diff --git a/tsconfig.json b/tsconfig.json index 5db373a5..865a7c0b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,17 +13,11 @@ "noEmit": true, "baseUrl": ".", "paths": { - "jsmind": ["types/jsmind.d.ts"], - "jsmind/draggable-node": ["types/jsmind.draggable-node.d.ts"], - "jsmind/screenshot": ["types/jsmind.screenshot.d.ts"] + "jsmind": ["types/index.d.ts"], + "jsmind/draggable-node": ["types/generated/plugins/jsmind.draggable-node.d.ts"], + "jsmind/screenshot": ["types/generated/plugins/jsmind.screenshot.d.ts"] } }, - "include": [ - "types/*.d.ts", - "tests/fixtures/typescript-test.ts" - ], - "exclude": [ - "node_modules", - "dist" - ] + "include": ["types/**/*.d.ts", "tests/fixtures/typescript-test.ts"], + "exclude": ["node_modules", "dist"] } diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts index 31f93c7f..eace4e2e 100644 --- a/types/generated/jsmind.d.ts +++ b/types/generated/jsmind.d.ts @@ -1,3 +1,7 @@ +/** + * Event callback payload + * @typedef {{ evt?: string, data?: unknown[], node?: string }} EventData + */ /** * jsMind runtime: orchestrates data/layout/view/shortcut and exposes public API. */ @@ -12,13 +16,13 @@ export default class jsMind { select: number; }; static $: { - w: any; - d: any; + w: Window; + d: Document; g: (id: string) => HTMLElement | null; c: (tag: string) => HTMLElement; t: (n: HTMLElement, t: string) => void; h: (n: HTMLElement, t: string | HTMLElement) => void; - i: (el: any) => el is HTMLElement; + i: (el: unknown) => el is HTMLElement; on: (t: HTMLElement, e: string, h: (ev: Event) => void) => void; }; static plugin: typeof Plugin; @@ -29,9 +33,9 @@ export default class jsMind { save: (data: string, type: string, name: string) => void; }; json: { - json2string: (v: any) => string; - string2json: (s: string) => any; - merge: (b: any, a: any) => any; + json2string: (v: unknown) => string; + string2json: (s: string) => unknown; + merge: (b: object, a: object) => object; }; uuid: { newid: () => string; @@ -43,10 +47,10 @@ export default class jsMind { /** * Deprecated: static show constructor helper. * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options - * @param {any} mind + * @param {object | null} mind * @returns {jsMind} */ - static show(options: import("./jsmind.option.js").JsMindRuntimeOptions, mind: any): jsMind; + static show(options: import("./jsmind.option.js").JsMindRuntimeOptions, mind: object | null): jsMind; /** * Create a jsMind instance. * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options @@ -56,7 +60,8 @@ export default class jsMind { version: string; initialized: boolean; mind: Mind; - event_handles: any[]; + /** @type {Array<(type: number, data: EventData) => void>} */ + event_handles: Array<(type: number, data: EventData) => void>; /** Initialize sub-systems and plugins. */ init(): void; data: DataProvider; @@ -111,18 +116,21 @@ export default class jsMind { /** * Toggle a node's expanded state. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ - toggle_node(node: string | import("./jsmind.node.js").Node): any; + toggle_node(node: string | import("./jsmind.node.js").Node): void; /** * Expand a node. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ - expand_node(node: string | import("./jsmind.node.js").Node): any; + expand_node(node: string | import("./jsmind.node.js").Node): void; /** * Collapse a node. * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} */ - collapse_node(node: string | import("./jsmind.node.js").Node): any; + collapse_node(node: string | import("./jsmind.node.js").Node): void; /** Expand all nodes */ expand_all(): void; /** Collapse all nodes */ @@ -133,16 +141,16 @@ export default class jsMind { _reset(): void; /** * Internal show flow. - * @param {any} mind + * @param {object | null} mind * @param {boolean=} skip_centering */ - _show(mind: any, skip_centering?: boolean | undefined): void; + _show(mind: object | null, skip_centering?: boolean | undefined): void; /** * Show a mind (or example) on the canvas. - * @param {any} mind + * @param {object | null} mind * @param {boolean=} skip_centering */ - show(mind: any, skip_centering?: boolean | undefined): void; + show(mind: object | null, skip_centering?: boolean | undefined): void; /** @returns {{name:string,author:string,version:string}} */ get_meta(): { name: string; @@ -152,9 +160,9 @@ export default class jsMind { /** * Serialize current mind to given format. * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] - * @returns {any} + * @returns {object} */ - get_data(data_format?: "node_tree" | "node_array" | "freemind" | "text"): any; + get_data(data_format?: "node_tree" | "node_array" | "freemind" | "text"): object; /** @returns {import('./jsmind.node.js').Node} */ get_root(): import("./jsmind.node.js").Node; /** @@ -208,8 +216,11 @@ export default class jsMind { * @param {number=} direction */ move_node(node_id: string, before_id?: string | undefined, parent_id?: string | undefined, direction?: number | undefined): void; - /** @param {string | import('./jsmind.node.js').Node} node */ - select_node(node: string | import("./jsmind.node.js").Node): any; + /** + * @param {string | import('./jsmind.node.js').Node} node + * @returns {void} + */ + select_node(node: string | import("./jsmind.node.js").Node): void; /** @returns {import('./jsmind.node.js').Node|null} */ get_selected_node(): import("./jsmind.node.js").Node | null; /** clear selection */ @@ -231,33 +242,55 @@ export default class jsMind { * @returns {import('./jsmind.node.js').Node | null} */ find_node_after(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; - /** @param {string} node_id @param {string=} bg_color @param {string=} fg_color */ - set_node_color(node_id: string, bg_color?: string | undefined, fg_color?: string | undefined): any; - /** @param {string} node_id @param {number=} size @param {string=} weight @param {string=} style */ - set_node_font_style(node_id: string, size?: number | undefined, weight?: string | undefined, style?: string | undefined): any; - /** @param {string} node_id @param {string} image @param {number=} width @param {number=} height @param {number=} rotation */ - set_node_background_image(node_id: string, image: string, width?: number | undefined, height?: number | undefined, rotation?: number | undefined): any; - /** @param {string} node_id @param {number} rotation */ - set_node_background_rotation(node_id: string, rotation: number): any; + /** + * @param {string} node_id + * @param {string=} bg_color + * @param {string=} fg_color + * @returns {void} + */ + set_node_color(node_id: string, bg_color?: string | undefined, fg_color?: string | undefined): void; + /** + * @param {string} node_id + * @param {number=} size + * @param {string=} weight + * @param {string=} style + * @returns {void} + */ + set_node_font_style(node_id: string, size?: number | undefined, weight?: string | undefined, style?: string | undefined): void; + /** + * @param {string} node_id + * @param {string} image + * @param {number=} width + * @param {number=} height + * @param {number=} rotation + * @returns {void} + */ + set_node_background_image(node_id: string, image: string, width?: number | undefined, height?: number | undefined, rotation?: number | undefined): void; + /** + * @param {string} node_id + * @param {number} rotation + * @returns {void} + */ + set_node_background_rotation(node_id: string, rotation: number): void; /** trigger view resize */ resize(): void; - /** @param {(type:number, data:any)=>void} callback */ - add_event_listener(callback: (type: number, data: any) => void): void; + /** @param {(type:number, data: EventData)=>void} callback */ + add_event_listener(callback: (type: number, data: EventData) => void): void; /** clear event listeners */ clear_event_listener(): void; - /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ - invoke_event_handle(type: number, data: { - evt?: string; - data?: any[]; - node?: string; - }): void; - /** @param {number} type @param {{evt?:string, data?:any[], node?:string}} data */ - _invoke_event_handle(type: number, data: { - evt?: string; - data?: any[]; - node?: string; - }): void; + /** @param {number} type @param {EventData} data */ + invoke_event_handle(type: number, data: EventData): void; + /** @param {number} type @param {EventData} data */ + _invoke_event_handle(type: number, data: EventData): void; } +/** + * Event callback payload + */ +export type EventData = { + evt?: string; + data?: unknown[]; + node?: string; +}; import { Mind } from './jsmind.mind.js'; import { DataProvider } from './jsmind.data_provider.js'; import { LayoutProvider } from './jsmind.layout_provider.js'; diff --git a/types/generated/jsmind.dom.d.ts b/types/generated/jsmind.dom.d.ts index 6d8056f9..5ae171e3 100644 --- a/types/generated/jsmind.dom.d.ts +++ b/types/generated/jsmind.dom.d.ts @@ -10,9 +10,14 @@ export const $: Dom; * Lightweight DOM helpers bound to a window. */ declare class Dom { - constructor(w: any); - w: any; - d: any; + /** + * @param {Window} w + */ + constructor(w: Window); + /** @type {Window} */ + w: Window; + /** @type {Document} */ + d: Document; /** * Get element by id. * @param {string} id @@ -39,10 +44,10 @@ declare class Dom { h: (n: HTMLElement, t: string | HTMLElement) => void; /** * Runtime check for HTMLElement. - * @param {any} el + * @param {unknown} el * @returns {el is HTMLElement} */ - i: (el: any) => el is HTMLElement; + i: (el: unknown) => el is HTMLElement; /** * Add event listener with legacy fallback. * @param {HTMLElement} t diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts index 40e785af..fba01857 100644 --- a/types/generated/jsmind.format.d.ts +++ b/types/generated/jsmind.format.d.ts @@ -1,30 +1,22 @@ /** * Mind data format handlers. * @type {{ - * node_tree: { example:{meta:MindMapMeta,format:'node_tree',data:any}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, - * node_array: { example:{meta:MindMapMeta,format:'node_array',data:any[]}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, + * node_tree: { example:NodeTreeFormat, get_mind:(src:NodeTreeFormat)=>Mind, get_data:(mind:Mind)=>NodeTreeFormat }, + * node_array: { example:NodeArrayFormat, get_mind:(src:NodeArrayFormat)=>Mind, get_data:(mind:Mind)=>NodeArrayFormat }, * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } * }} */ export const format: { node_tree: { - example: { - meta: MindMapMeta; - format: "node_tree"; - data: any; - }; - get_mind: (src: any) => Mind; - get_data: (mind: Mind) => any; + example: NodeTreeFormat; + get_mind: (src: NodeTreeFormat) => Mind; + get_data: (mind: Mind) => NodeTreeFormat; }; node_array: { - example: { - meta: MindMapMeta; - format: "node_array"; - data: any[]; - }; - get_mind: (src: any) => Mind; - get_data: (mind: Mind) => any; + example: NodeArrayFormat; + get_mind: (src: NodeArrayFormat) => Mind; + get_data: (mind: Mind) => NodeArrayFormat; }; freemind: { example: { @@ -50,4 +42,43 @@ export type MindMapMeta = { author: string; version: string; }; +/** + * Node tree data item + */ +export type NodeTreeData = { + id: string; + topic: string; + data?: Record; + direction?: (number | string); + expanded?: boolean; + children?: NodeTreeData[]; +}; +/** + * Node tree formatted payload + */ +export type NodeTreeFormat = { + meta?: MindMapMeta; + format: "node_tree"; + data: NodeTreeData; +}; +/** + * Node array data item + */ +export type NodeArrayItem = { + id: string; + topic: string; + parentid?: string; + data?: Record; + direction?: (number | string); + expanded?: boolean; + isroot?: boolean; +}; +/** + * Node array formatted payload + */ +export type NodeArrayFormat = { + meta?: MindMapMeta; + format: "node_array"; + data: NodeArrayItem[]; +}; import { Mind } from './jsmind.mind.js'; diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts index 60fe12c8..2a7bb416 100644 --- a/types/generated/jsmind.graph.d.ts +++ b/types/generated/jsmind.graph.d.ts @@ -10,7 +10,7 @@ export function init_graph(view: import("./jsmind.view_provider.js").ViewProvide */ declare class SvgGraph { /** @param {string} tag */ - static c(tag: string): any; + static c(tag: string): SVGElement; /** * Create SVG graph renderer. * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance @@ -38,7 +38,7 @@ declare class SvgGraph { custom_node_render?: Function; expander_style: "char" | "number"; }; - e_svg: any; + e_svg: SVGElement; size: { w: number; h: number; @@ -130,7 +130,7 @@ declare class CanvasGraph { straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; }; - dpr: any; + dpr: number; /** Choose line drawing renderer. */ init_line_render(): void; drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts index 7c6994bc..a4e4e6be 100644 --- a/types/generated/jsmind.mind.d.ts +++ b/types/generated/jsmind.mind.d.ts @@ -1,10 +1,16 @@ export class Mind { - name: any; - author: any; - version: any; - root: Node; - selected: any; - nodes: {}; + /** @type {string | null} */ + name: string | null; + /** @type {string | null} */ + author: string | null; + /** @type {string | null} */ + version: string | null; + /** @type {Node | null} */ + root: Node | null; + /** @type {Node | null} */ + selected: Node | null; + /** @type {Record} */ + nodes: Record; /** * Get a node by id. * @param {string} node_id diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts index f6aab536..1fa2a2f0 100644 --- a/types/generated/jsmind.node.d.ts +++ b/types/generated/jsmind.node.d.ts @@ -15,10 +15,10 @@ export class Node { static inherited(parent_node: Node, node: Node): boolean; /** * Runtime check for Node instance. - * @param {any} n + * @param {unknown} n * @returns {n is Node} */ - static is_node(n: any): n is Node; + static is_node(n: unknown): n is Node; /** * Create a Node instance. * @param {string} sId - Node id @@ -39,7 +39,8 @@ export class Node { parent: Node; direction: number; expanded: boolean; - children: any[]; + /** @type {Node[]} */ + children: Node[]; _data: {}; /** * Get absolute location of this node in view coordinates. diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts index b301661f..e481395d 100644 --- a/types/generated/jsmind.shortcut_provider.d.ts +++ b/types/generated/jsmind.shortcut_provider.d.ts @@ -1,92 +1,23 @@ export class ShortcutProvider { - /** - * Keyboard shortcut handler. - * @param {import('./jsmind.js').default} jm - jsMind instance - * @param {{enable:boolean, handles:Record, mapping:Record}} options - Shortcut configuration options - */ - constructor(jm: import("./jsmind.js").default, options: { - enable: boolean; - handles: Record; - mapping: Record; - }); - jm: import("./jsmind.js").default; - opts: { - enable: boolean; - handles: Record; - mapping: Record; - }; - mapping: Record; - handles: Record; + constructor(jm: any, options: any); + jm: any; + opts: any; + mapping: any; + handles: any; _newid: any; _mapping: {}; - /** Initialize keyboard listeners and mapping. */ init(): void; - /** Enable shortcuts. */ enable_shortcut(): void; - /** Disable shortcuts. */ disable_shortcut(): void; - /** @param {KeyboardEvent} e */ - handler(e: KeyboardEvent): boolean; - /** - * Handle add child node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_addchild(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle add brother node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_addbrother(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle edit node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_editnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle delete node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_delnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle toggle node shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_toggle(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle up arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_up(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle down arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_down(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle left arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_left(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle right arrow key shortcut. - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - */ - handle_right(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; - /** - * Handle directional navigation. - * @private - * @param {import('./jsmind.js').default} _jm - jsMind instance - * @param {KeyboardEvent} e - Keyboard event - * @param {number} d - Direction constant - */ - private _handle_direction; + handler(e: any): boolean; + handle_addchild(_jm: any, e: any): void; + handle_addbrother(_jm: any, e: any): void; + handle_editnode(_jm: any, e: any): void; + handle_delnode(_jm: any, e: any): void; + handle_toggle(_jm: any, e: any): void; + handle_up(_jm: any, e: any): void; + handle_down(_jm: any, e: any): void; + handle_left(_jm: any, e: any): void; + handle_right(_jm: any, e: any): void; + _handle_direction(_jm: any, e: any, d: any): void; } diff --git a/types/generated/jsmind.util.d.ts b/types/generated/jsmind.util.d.ts index c62e3f89..0bb33766 100644 --- a/types/generated/jsmind.util.d.ts +++ b/types/generated/jsmind.util.d.ts @@ -2,7 +2,7 @@ * Misc utility collection. * @type {{ * file: { read: (file: File, cb:(result:string,name:string)=>void)=>void, save:(data:string,type:string,name:string)=>void}, - * json: { json2string:(v:any)=>string, string2json:(s:string)=>any, merge:(b:any,a:any)=>any }, + * json: { json2string:(v:unknown)=>string, string2json:(s:string)=>unknown, merge:(b:object,a:object)=>object }, * uuid: { newid:()=>string }, * text: { is_empty:(s?:string)=>boolean } * }} @@ -13,9 +13,9 @@ export const util: { save: (data: string, type: string, name: string) => void; }; json: { - json2string: (v: any) => string; - string2json: (s: string) => any; - merge: (b: any, a: any) => any; + json2string: (v: unknown) => string; + string2json: (s: string) => unknown; + merge: (b: object, a: object) => object; }; uuid: { newid: () => string; diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts index de2dddb0..e8cd2a0a 100644 --- a/types/generated/jsmind.view_provider.d.ts +++ b/types/generated/jsmind.view_provider.d.ts @@ -95,7 +95,7 @@ export class ViewProvider { custom_node_render?: Function; expander_style: "char" | "number"; }; - e_svg: any; + e_svg: SVGElement; size: { w: number; h: number; @@ -155,7 +155,7 @@ export class ViewProvider { straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; }; - dpr: any; + dpr: number; init_line_render(): void; drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); element(): HTMLCanvasElement; @@ -177,7 +177,7 @@ export class ViewProvider { }; render_node: (ele: HTMLElement, node: import("./jsmind.node.js").Node) => void; zoom_current: number; - device_pixel_ratio: any; + device_pixel_ratio: number; _initialized: boolean; /** Initialize DOM structure, graph and editor. */ init(): void; @@ -190,11 +190,20 @@ export class ViewProvider { * @param {boolean=} capture_by_panel */ add_event(obj: any, event_name: string, event_handle: (e: Event) => void, capture_by_panel?: boolean | undefined): void; - /** @param {HTMLElement|null} element */ - get_binded_nodeid(element: HTMLElement | null): any; - /** @param {HTMLElement|null} element */ - is_node(element: HTMLElement | null): any; - /** @param {HTMLElement} element */ + /** + * @param {HTMLElement|null} element + * @returns {string|null} + */ + get_binded_nodeid(element: HTMLElement | null): string | null; + /** + * @param {HTMLElement|null} element + * @returns {boolean} + */ + is_node(element: HTMLElement | null): boolean; + /** + * @param {HTMLElement} element + * @returns {boolean} + */ is_expander(element: HTMLElement): boolean; reset(): void; reset_theme(): void; diff --git a/types/generated/plugins/jsmind.draggable-node.d.ts b/types/generated/plugins/jsmind.draggable-node.d.ts index b2ffdf32..d5fe862f 100644 --- a/types/generated/plugins/jsmind.draggable-node.d.ts +++ b/types/generated/plugins/jsmind.draggable-node.d.ts @@ -204,9 +204,9 @@ export class DraggableNode { /** * Handle jsMind events. * @param {number|string} type - Event type - * @param {any} [data] - Event data + * @param {object} [data] - Event data */ - jm_event_handle(type: number | string, data?: any): void; + jm_event_handle(type: number | string, data?: object): void; } /** * Draggable node plugin registration. diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 00000000..b02b6a9f --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,24 @@ +// Aggregated public typings entry: re-export generated types without compatibility layer +export { default } from './generated/jsmind'; + +// Legacy named exports back-compat: re-export classes and key option/data types if present +export { Node } from './generated/jsmind.node'; +export { Mind } from './generated/jsmind.mind'; + +// Export strict options and meta types from generated +export type { JsMindRuntimeOptions as JsMindOptions } from './generated/jsmind.option'; +export type { + MindMapMeta, + NodeTreeData, + NodeTreeFormat, + NodeArrayItem, + NodeArrayFormat, +} from './generated/jsmind.format'; + +// Static singletons / enums passthrough +export { Direction as direction, EventType as event_type } from './generated/jsmind.common'; +export { $ } from './generated/jsmind.dom'; +export { util } from './generated/jsmind.util'; + +// Plugin export paths remain under subpath exports +// typings for subpath are referenced from package.json exports.types diff --git a/types/jsmind.d.ts b/types/jsmind.d.ts deleted file mode 100644 index 9c5a0f1a..00000000 --- a/types/jsmind.d.ts +++ /dev/null @@ -1,407 +0,0 @@ -/** - * TypeScript definitions for jsMind - * @version 0.8.7 - * @author jsMind Community - * @license BSD-3-Clause - */ - -// ============================================================================ -// Basic enums and constants -// ============================================================================ - -export interface DirectionType { - left: -1; - center: 0; - right: 1; - of(dir: string | number): number | undefined; -} - -export interface EventTypeEnum { - show: 1; - resize: 2; - edit: 3; - select: 4; -} - -export interface LogLevelEnum { - debug: 1; - info: 2; - warn: 3; - error: 4; - disable: 9; -} - -export interface KeyEnum { - meta: 8192; - ctrl: 4096; - alt: 2048; - shift: 1024; -} - -// ============================================================================ -// Data format interfaces -// ============================================================================ - -export interface NodeData { - // Arbitrary custom data attached to a node - [key: string]: any; -} - -export interface MindMapMeta { - name?: string; - author?: string; - version?: string; -} - -export interface NodeTreeFormat { - meta?: MindMapMeta; - format: 'node_tree'; - data: NodeTreeData; -} - -export interface NodeTreeData { - id: string; - topic: string; - data?: NodeData; - direction?: number; - expanded?: boolean; - children?: NodeTreeData[]; -} - -export interface NodeArrayFormat { - meta?: MindMapMeta; - format: 'node_array'; - data: NodeArrayData[]; -} - -export interface NodeArrayData { - id: string; - topic: string; - parentid?: string; - data?: NodeData; - direction?: number; - expanded?: boolean; - isroot?: boolean; -} - -export type MindMapData = NodeTreeFormat | NodeArrayFormat | string; - -// ============================================================================ -// Options interfaces -// ============================================================================ - -export interface ZoomOptions { - min?: number; - max?: number; - step?: number; - mask_key?: number; -} - -export interface ViewOptions { - engine?: 'canvas' | 'svg'; - enable_device_pixel_ratio?: boolean; - hmargin?: number; - vmargin?: number; - line_width?: number; - line_color?: string; - line_style?: 'curved' | 'straight'; - draggable?: boolean; - hide_scrollbars_when_draggable?: boolean; - node_overflow?: 'hidden' | 'wrap'; - zoom?: ZoomOptions; - custom_node_render?: ((jm: jsMind, element: HTMLElement, node: Node) => void) | null; - expander_style?: 'char' | 'number'; -} - -export interface LayoutOptions { - hspace?: number; - vspace?: number; - pspace?: number; - cousin_space?: number; -} - -export interface DefaultEventHandleOptions { - enable_mousedown_handle?: boolean; - enable_click_handle?: boolean; - enable_dblclick_handle?: boolean; - enable_mousewheel_handle?: boolean; -} - -export interface ShortcutMapping { - addchild?: number | number[]; - addbrother?: number | number[]; - editnode?: number | number[]; - delnode?: number | number[]; - toggle?: number | number[]; - left?: number | number[]; - up?: number | number[]; - right?: number | number[]; - down?: number | number[]; - [key: string]: number | number[] | undefined; -} - -export interface ShortcutOptions { - enable?: boolean; - handles?: { [key: string]: () => void }; - mapping?: ShortcutMapping; -} - -export interface PluginOptions { - [pluginName: string]: any; -} - -export interface JsMindOptions { - container: string; - editable?: boolean; - theme?: string | null; - mode?: 'full' | 'side'; - support_html?: boolean; - log_level?: 'debug' | 'info' | 'warn' | 'error' | 'disable'; - view?: ViewOptions; - layout?: LayoutOptions; - default_event_handle?: DefaultEventHandleOptions; - shortcut?: ShortcutOptions; - plugin?: PluginOptions; -} - -// ============================================================================ -// Core class interfaces -// ============================================================================ - -export interface NodeLocation { - x: number; - y: number; -} - -export interface NodeSize { - w: number; - h: number; -} - -export class Node { - id: string; - index: number; - topic: string; - data: NodeData; - isroot: boolean; - parent: Node | null; - direction: number; - expanded: boolean; - children: Node[]; - _data: any; - - constructor( - sId: string, - iIndex: number, - sTopic: string, - oData?: NodeData, - bIsRoot?: boolean, - oParent?: Node | null, - eDirection?: number, - bExpanded?: boolean - ); - - get_location(): NodeLocation; - get_size(): NodeSize; - - static compare(node1: Node, node2: Node): number; - static inherited(parent_node: Node, node: Node): boolean; - static is_node(n: any): n is Node; -} - -export class Mind { - name: string | null; - author: string | null; - version: string | null; - root: Node | null; - selected: Node | null; - nodes: { [id: string]: Node }; - - constructor(); - - get_node(node_id: string): Node | null; - set_root(node_id: string, topic: string, data?: NodeData): Node | null; - add_node( - parent_node: Node, - node_id: string, - topic: string, - data?: NodeData, - direction?: number, - expanded?: boolean, - idx?: number - ): Node | null; - insert_node_before( - node_before: Node, - node_id: string, - topic: string, - data?: NodeData - ): Node | null; - insert_node_after( - node_after: Node, - node_id: string, - topic: string, - data?: NodeData - ): Node | null; - remove_node(node: Node): boolean; - move_node(node: Node, before_id?: string, parent_id?: string, direction?: number): Node | null; -} - -// ============================================================================ -// Utility interfaces -// ============================================================================ - -export interface FileUtil { - read(file_data: File, fn_callback: (result: string, name: string) => void): void; - save(file_data: string, type: string, name: string): void; -} - -export interface JsonUtil { - json2string(json: any): string; - string2json(json_str: string): any; - merge(target: any, source: any): any; -} - -export interface UuidUtil { - newid(): string; -} - -export interface TextUtil { - is_empty(s?: string | null): boolean; -} - -export interface Util { - file: FileUtil; - json: JsonUtil; - uuid: UuidUtil; - text: TextUtil; -} - -export interface Dom { - w: Window; - d: Document; - g(id: string): HTMLElement | null; - c(tag: string): HTMLElement; - t(n: HTMLElement, t: string): void; - h(n: HTMLElement, t: string | HTMLElement): void; - i(el: any): el is HTMLElement; - on(t: HTMLElement, e: string, h: EventListener): void; -} - -// ============================================================================ -// Event handling interfaces -// ============================================================================ - -export interface EventData { - evt?: string; - data?: any[]; - node?: string; -} - -export type EventHandler = (type: number, data: EventData) => void; - -// ============================================================================ -// Main class -// ============================================================================ - -export default class jsMind { - static mind: typeof Mind; - static node: typeof Node; - static direction: DirectionType; - static event_type: EventTypeEnum; - static $: Dom; - static plugin: any; - static register_plugin(plugin_name: string, plugin_init: (jm: jsMind) => void): void; - static util: Util; - static current: jsMind; - - version: string; - options: JsMindOptions; - initialized: boolean; - mind: Mind | null; - event_handles: EventHandler[]; - data: any; - layout: any; - view: any; - shortcut: any; - - constructor(options: JsMindOptions); - - init(): void; - show(mind?: MindMapData, skip_centering?: boolean): void; - get_editable(): boolean; - enable_edit(): void; - disable_edit(): void; - get_view_draggable(): boolean; - enable_view_draggable(): void; - disable_view_draggable(): void; - get_meta(): MindMapMeta; - get_data(data_format?: 'node_tree' | 'node_array' | 'freemind' | 'text'): any; - get_root(): Node | null; - get_node(node: string | Node): Node | null; - add_node( - parent_node: Node | string, - node_id: string, - topic: string, - data?: NodeData, - direction?: number - ): Node | null; - insert_node_before( - node_before: Node | string, - node_id: string, - topic: string, - data?: NodeData - ): Node | null; - insert_node_after( - node_after: Node | string, - node_id: string, - topic: string, - data?: NodeData - ): Node | null; - remove_node(node: Node | string): boolean; - update_node(node_id: string, topic: string): void; - move_node( - node: Node | string, - before_id?: string, - parent_id?: string, - direction?: number - ): void; - select_node(node: Node | string): void; - select_clear(): void; - get_selected_node(): Node | null; - is_node_visible(node: Node | string): boolean; - find_node_before(node: Node | string): Node | null; - find_node_after(node: Node | string): Node | null; - set_node_color(node_id: string, bg_color?: string, fg_color?: string): void; - set_node_font_style(node_id: string, size?: number, weight?: string, style?: string): void; - set_node_background_image( - node_id: string, - image: string, - width?: number, - height?: number, - rotation?: number - ): void; - set_node_background_rotation(node_id: string, rotation: number): void; - resize(): void; - begin_edit(node?: Node | string): void; - end_edit(): void; - toggle_node(node?: Node | string): void; - expand_node(node: Node | string): void; - collapse_node(node: Node | string): void; - expand_all(): void; - collapse_all(): void; - expand_to_depth(depth: number): void; - scroll_node_to_center(node: Node | string): void; - scroll_node_to_visible(node: Node | string): void; - add_event_listener(event_listener: EventHandler): void; - invoke_event_handle(type: number, data: EventData): void; -} - -// ============================================================================ -// Module exports -// ============================================================================ - -export { jsMind }; -export const direction: DirectionType; -export const event_type: EventTypeEnum; -export const $: Dom; -export const util: Util; diff --git a/types/jsmind.draggable-node.d.ts b/types/jsmind.draggable-node.d.ts deleted file mode 100644 index 1012ab97..00000000 --- a/types/jsmind.draggable-node.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** - * TypeScript definitions for jsMind draggable-node plugin - * @version 0.4.0 - */ - -import jsMind, { Node } from './jsmind'; - -export interface DraggableNodeOptions { - line_width?: number; - line_color?: string; - line_color_invalid?: string; - lookup_delay?: number; - lookup_interval?: number; - scrolling_trigger_width?: number; - scrolling_step_length?: number; - shadow_node_class_name?: string; -} - -export class DraggableNode { - version: string; - jm: jsMind; - options: Required; - e_canvas: HTMLCanvasElement | null; - canvas_ctx: CanvasRenderingContext2D | null; - shadow: HTMLElement | null; - shadow_p_x: number; - shadow_p_y: number; - shadow_w: number; - shadow_h: number; - active_node: Node | null; - target_node: Node | null; - target_direct: number | null; - client_w: number; - client_h: number; - offset_x: number; - offset_y: number; - hlookup_delay: number; - hlookup_timer: number; - capture: boolean; - moved: boolean; - canvas_draggable: boolean; - view_panel: HTMLElement; - view_panel_rect: DOMRect | null; - - constructor(jm: jsMind, options?: DraggableNodeOptions); - init(): void; - resize(): void; - create_canvas(): void; - create_shadow(): void; - reset_shadow(element: HTMLElement): void; - show_shadow(): void; - hide_shadow(): void; - magnet_shadow( - shadow_p: { x: number; y: number }, - node_p: { x: number; y: number }, - invalid: boolean - ): void; - clear_lines(): void; - canvas_lineto(x1: number, y1: number, x2: number, y2: number): void; - event_bind(): void; - dragstart(e: MouseEvent | TouchEvent): void; - drag(e: MouseEvent | TouchEvent): void; - dragend(e: MouseEvent | TouchEvent): void; - find_node_element(element: HTMLElement): HTMLElement | null; - get_root_x(): number; - lookup_target_node(): void; - lookup_overlapping_node_parent(direction: number): Node | null; - lookup_node_parent_by_location(x: number, y: number): Node | null; - lookup_close_node(direction: number): Node; - shadow_on_target_side(node: Node, direction: number): boolean; - shadow_to_left_of_node(node: Node): number; - shadow_to_right_of_node(node: Node): number; - shadow_to_base_line_of_node(node: Node): number; - shadow_to_node(node: Node, dir: number): number; - calc_point_of_node( - node: Node, - dir: number - ): { - sp: { x: number; y: number }; - np: { x: number; y: number }; - }; - move_node(src_node: Node, target_node: Node | null, target_direct: number | null): void; - jm_event_handle(type: number, data: any): void; -} - -declare module 'jsmind' { - interface PluginOptions { - draggable_node?: DraggableNodeOptions; - } -} - -export const draggable_plugin: any; -export default DraggableNode; diff --git a/types/jsmind.screenshot.d.ts b/types/jsmind.screenshot.d.ts deleted file mode 100644 index d1f5cd9b..00000000 --- a/types/jsmind.screenshot.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * TypeScript definitions for jsMind screenshot plugin - * @version 0.2.0 - */ - -import jsMind from './jsmind'; - -export interface WatermarkOptions { - left?: string | Location; - right?: string; -} - -export interface ScreenshotOptions { - filename?: string | null; - watermark?: WatermarkOptions; - background?: string; -} - -export class JmScreenshot { - version: string; - jm: jsMind; - options: Required; - dpr: number; - - constructor(jm: jsMind, options?: ScreenshotOptions); - shoot(): void; - create_canvas(): HTMLCanvasElement; - clear(c: HTMLCanvasElement): void; - draw_background(ctx: CanvasRenderingContext2D): Promise; - draw_lines(ctx: CanvasRenderingContext2D): Promise; - draw_nodes(ctx: CanvasRenderingContext2D): Promise; - draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; - load_image(url: string): Promise; - download(c: HTMLCanvasElement): void; -} - -declare module 'jsmind' { - interface PluginOptions { - screenshot?: ScreenshotOptions; - } - - interface jsMind { - screenshot?: JmScreenshot; - shoot?(): void; - } -} - -export const screenshot_plugin: any; -export default JmScreenshot; From a52076a7a6d997d2e37aa843e023224cd9226c19 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 13:45:14 +0800 Subject: [PATCH 15/24] docs(changelog): document PR changes (typings migration, CI, scripts, deps) --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b3b666a..413b89c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ ## Changelog / 变更日志 +### 2025-08-10 + +- Added + + - Central typings entry `types/index.d.ts` and regenerated declaration files under `types/generated/` for core and plugins (dom, format, graph, layout_provider, mind, node, option, plugin, shortcut_provider, util, view_provider, draggable-node, screenshot). + - Declaration build config `tsconfig.decls.json` and npm scripts: `gen:dts`, `gen:dts:check`. + - TypeScript typings validation: `tests/unit/typescript.types.test.js` with fixture `tests/fixtures/typescript-test.ts` using TypeScript Compiler API. + +- Changed + + - Updated `package.json` to expose `types` via `types/index.d.ts` and added scripts for generating/checking declarations. + - Enriched JSDoc and in-source documentation across core modules and plugins to improve generated typings (data_provider, dom, format, graph, layout_provider, mind, node, option, plugin, util, view_provider, draggable-node, screenshot). + - Updated `tsconfig.json` strictness and paths; CI updated to run `npm run gen:dts` before build and include `gen:dts:check` in install pipeline. + - Dev dependencies refreshed, adding `typescript`, `tsd-jsdoc`, and updating various `@types/*`, jest, jsdoc toolchain packages. + +- Removed + + - Legacy type files under `types/` (`jsmind.d.ts`, `jsmind.draggable-node.d.ts`, `jsmind.screenshot.d.ts`) in favor of `types/generated/`. + +- Notes + + - Running `npm test` now validates both runtime tests and TypeScript definitions. Consumers can rely on the aggregated public typings from the package root; plugin typings are exposed under `plugins/` paths. + ### 2025-08-09 - Added / 新增 From ff6d27fb6fdc344813b8782e4d26a5661d95d00c Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 14:45:01 +0800 Subject: [PATCH 16/24] chore(typings): regenerate declarations; sync JSDoc/comments across core; update changelog - Regenerate types under types/generated for core and plugins - Improve in-source JSDoc to enhance emitted d.ts (data_provider/format/graph/mind/node/option/plugin/shortcut_provider/view_provider) - Update CHANGELOG.md entry for 2025-08-10 --- CHANGELOG.md | 46 ++++++------- src/jsmind.data_provider.js | 4 +- src/jsmind.format.js | 11 ++-- src/jsmind.graph.js | 11 +++- src/jsmind.js | 6 +- src/jsmind.mind.js | 8 +-- src/jsmind.node.js | 1 + src/jsmind.option.js | 8 +-- src/jsmind.plugin.js | 10 +-- src/jsmind.shortcut_provider.js | 19 ++++++ src/jsmind.view_provider.js | 15 +++-- types/generated/jsmind.d.ts | 6 +- types/generated/jsmind.data_provider.d.ts | 40 ++++++++++-- types/generated/jsmind.format.d.ts | 28 ++++++-- types/generated/jsmind.graph.d.ts | 19 +++--- types/generated/jsmind.mind.d.ts | 8 +-- types/generated/jsmind.node.d.ts | 1 + types/generated/jsmind.option.d.ts | 19 ++++-- types/generated/jsmind.plugin.d.ts | 10 +-- types/generated/jsmind.shortcut_provider.d.ts | 65 ++++++++++++++----- types/generated/jsmind.view_provider.d.ts | 42 +++++++----- 21 files changed, 253 insertions(+), 124 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 413b89c6..8a2e6f34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,38 +2,34 @@ ### 2025-08-10 -- Added +- Added - - Central typings entry `types/index.d.ts` and regenerated declaration files under `types/generated/` for core and plugins (dom, format, graph, layout_provider, mind, node, option, plugin, shortcut_provider, util, view_provider, draggable-node, screenshot). - - Declaration build config `tsconfig.decls.json` and npm scripts: `gen:dts`, `gen:dts:check`. - - TypeScript typings validation: `tests/unit/typescript.types.test.js` with fixture `tests/fixtures/typescript-test.ts` using TypeScript Compiler API. + - Central typings entry `types/index.d.ts` and regenerated declaration files under `types/generated/` for core and plugins (dom, format, graph, layout_provider, mind, node, option, plugin, shortcut_provider, util, view_provider, draggable-node, screenshot). + - Declaration build config `tsconfig.decls.json` and npm scripts: `gen:dts`, `gen:dts:check`. + - TypeScript typings validation: `tests/unit/typescript.types.test.js` with fixture `tests/fixtures/typescript-test.ts` using TypeScript Compiler API. +- Changed -- Changed + - Updated `package.json` to expose `types` via `types/index.d.ts` and added scripts for generating/checking declarations. + - Enriched JSDoc and in-source documentation across core modules and plugins to improve generated typings (data_provider, dom, format, graph, layout_provider, mind, node, option, plugin, util, view_provider, draggable-node, screenshot). + - Updated `tsconfig.json` strictness and paths; CI updated to run `npm run gen:dts` before build and include `gen:dts:check` in install pipeline. + - Dev dependencies refreshed, adding `typescript`, `tsd-jsdoc`, and updating various `@types/*`, jest, jsdoc toolchain packages. +- Removed - - Updated `package.json` to expose `types` via `types/index.d.ts` and added scripts for generating/checking declarations. - - Enriched JSDoc and in-source documentation across core modules and plugins to improve generated typings (data_provider, dom, format, graph, layout_provider, mind, node, option, plugin, util, view_provider, draggable-node, screenshot). - - Updated `tsconfig.json` strictness and paths; CI updated to run `npm run gen:dts` before build and include `gen:dts:check` in install pipeline. - - Dev dependencies refreshed, adding `typescript`, `tsd-jsdoc`, and updating various `@types/*`, jest, jsdoc toolchain packages. + - Legacy type files under `types/` (`jsmind.d.ts`, `jsmind.draggable-node.d.ts`, `jsmind.screenshot.d.ts`) in favor of `types/generated/`. +- Notes -- Removed - - - Legacy type files under `types/` (`jsmind.d.ts`, `jsmind.draggable-node.d.ts`, `jsmind.screenshot.d.ts`) in favor of `types/generated/`. - -- Notes - - - Running `npm test` now validates both runtime tests and TypeScript definitions. Consumers can rely on the aggregated public typings from the package root; plugin typings are exposed under `plugins/` paths. + - Running `npm test` now validates both runtime tests and TypeScript definitions. Consumers can rely on the aggregated public typings from the package root; plugin typings are exposed under `plugins/` paths. ### 2025-08-09 -- Added / 新增 - - - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). - - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). +- Added -- Changed / 调整 + - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). + - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). +- Changed - - Updated root `package.json` to expose `types` and proper `exports` fields for typings. + - Updated root `package.json` to expose `types` and proper `exports` fields for typings. +- Notes -- Notes / 说明 - - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. - - Running `npm test` will now validate TypeScript definitions. + - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. + - Running `npm test` will now validate TypeScript definitions. diff --git a/src/jsmind.data_provider.js b/src/jsmind.data_provider.js index 016bf26c..627f5345 100644 --- a/src/jsmind.data_provider.js +++ b/src/jsmind.data_provider.js @@ -28,7 +28,7 @@ export class DataProvider { } /** * Load a Mind from mixed source. - * @param {any} mind_data - object with {format,data} or a format-specific payload + * @param {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta?:{name:string,author:string,version:string},format:'freemind',data:string}|{meta?:{name:string,author:string,version:string},format:'text',data:string}} mind_data - object with {format,data} or a format-specific payload * @returns {import('./jsmind.mind.js').Mind|null} */ load(mind_data) { @@ -60,7 +60,7 @@ export class DataProvider { /** * Serialize current mind to target format. * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format - * @returns {any} + * @returns {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta:{name:string,author:string,version:string},format:'freemind',data:string}|{meta:{name:string,author:string,version:string},format:'text',data:string}} */ get_data(data_format) { var data = null; diff --git a/src/jsmind.format.js b/src/jsmind.format.js index 4abbc281..d077883a 100644 --- a/src/jsmind.format.js +++ b/src/jsmind.format.js @@ -59,8 +59,8 @@ const DEFAULT_META = { name: 'jsMind', author: __author__, version: __version__ * @type {{ * node_tree: { example:NodeTreeFormat, get_mind:(src:NodeTreeFormat)=>Mind, get_data:(mind:Mind)=>NodeTreeFormat }, * node_array: { example:NodeArrayFormat, get_mind:(src:NodeArrayFormat)=>Mind, get_data:(mind:Mind)=>NodeArrayFormat }, - * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, - * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } + * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'freemind',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'freemind',data:string} }, + * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'text',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'text',data:string} } * }} */ export const format = { @@ -110,7 +110,7 @@ export const format = { /** * Extract custom data from node JSON, excluding standard properties. * @private - * @param {any} node_json - Node JSON object + * @param {Record} node_json - Node JSON object * @returns {Record} Custom data object */ _extract_data: function (node_json) { @@ -158,9 +158,8 @@ export const format = { * Build JSON object from a node. * @private * @param {Node} node - Node to convert - * @returns {any} JSON representation of node + * @returns {NodeTreeData} JSON representation of node */ - /** @returns {NodeTreeData} */ _build_node: function (node) { var df = format.node_tree; if (!(node instanceof Node)) { @@ -291,6 +290,7 @@ export const format = { return extract_count; }, + /** @param {Record} node_json */ _extract_data: function (node_json) { var data = {}; for (var k in node_json) { @@ -369,6 +369,7 @@ export const format = { return mind; }, + /** @param {Mind} mind */ get_data: function (mind) { var df = format.freemind; var json = {}; diff --git a/src/jsmind.graph.js b/src/jsmind.graph.js index 080da94c..0c91ca81 100644 --- a/src/jsmind.graph.js +++ b/src/jsmind.graph.js @@ -23,6 +23,7 @@ class SvgGraph { this.e_svg = SvgGraph.c('svg'); this.e_svg.setAttribute('class', 'jsmind'); this.size = { w: 0, h: 0 }; + /** @type {SVGPathElement[]} */ this.lines = []; this.line_drawing = { straight: this._line_to, @@ -37,6 +38,7 @@ class SvgGraph { /** Choose line drawing renderer. */ init_line_render() { if (typeof this.opts.custom_line_render === 'function') { + /** @type {(path:SVGPathElement,x1:number,y1:number,x2:number,y2:number)=>void} */ this.drawing = (path, x1, y1, x2, y2) => { try { this.opts.custom_line_render.call(this, { @@ -49,6 +51,7 @@ class SvgGraph { } }; } else { + /** @type {(path:SVGPathElement,x1:number,y1:number,x2:number,y2:number)=>void} */ this.drawing = this.line_drawing[this.opts.line_style] || this.line_drawing.curved; } } @@ -87,7 +90,7 @@ class SvgGraph { ); } - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ copy_to(dest_canvas_ctx, callback) { var img = new Image(); img.onload = function () { @@ -153,7 +156,7 @@ class CanvasGraph { this.opts = view.opts; this.e_canvas = $.c('canvas'); this.e_canvas.className = 'jsmind'; - this.canvas_ctx = this.e_canvas.getContext('2d'); + this.canvas_ctx = /** @type {CanvasRenderingContext2D} */ (this.e_canvas.getContext('2d')); this.size = { w: 0, h: 0 }; this.line_drawing = { straight: this._line_to, @@ -165,6 +168,7 @@ class CanvasGraph { /** Choose line drawing renderer. */ init_line_render() { if (typeof this.opts.custom_line_render === 'function') { + /** @type {(ctx:CanvasRenderingContext2D,x1:number,y1:number,x2:number,y2:number)=>void} */ this.drawing = (ctx, x1, y1, x2, y2) => { try { this.opts.custom_line_render.call(this, { @@ -177,6 +181,7 @@ class CanvasGraph { } }; } else { + /** @type {(ctx:CanvasRenderingContext2D,x1:number,y1:number,x2:number,y2:number)=>void} */ this.drawing = this.line_drawing[this.opts.line_style] || this.line_drawing.curved; } } @@ -213,7 +218,7 @@ class CanvasGraph { ctx.lineCap = 'round'; this.drawing(ctx, pin.x + offset.x, pin.y + offset.y, pout.x + offset.x, pout.y + offset.y); } - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ copy_to(dest_canvas_ctx, callback) { dest_canvas_ctx.drawImage(this.e_canvas, 0, 0, this.size.w, this.size.h); !!callback && callback(); diff --git a/src/jsmind.js b/src/jsmind.js index 5e6b55f6..c0819658 100644 --- a/src/jsmind.js +++ b/src/jsmind.js @@ -416,7 +416,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} parent_node * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ @@ -451,7 +451,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node_before * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ @@ -484,7 +484,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node_after * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ diff --git a/src/jsmind.mind.js b/src/jsmind.mind.js index 1c0ec6ef..42355ade 100644 --- a/src/jsmind.mind.js +++ b/src/jsmind.mind.js @@ -44,7 +44,7 @@ export class Mind { * Set the root node, only once. * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @returns {Node | null} */ set_root(node_id, topic, data) { @@ -62,7 +62,7 @@ export class Mind { * @param {Node} parent_node * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @param {boolean=} expanded * @param {number=} idx @@ -101,7 +101,7 @@ export class Mind { * @param {Node} node_before * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {Node | null} */ @@ -143,7 +143,7 @@ export class Mind { * @param {Node} node_after * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {Node | null} */ diff --git a/src/jsmind.node.js b/src/jsmind.node.js index d1e44be6..84253a44 100644 --- a/src/jsmind.node.js +++ b/src/jsmind.node.js @@ -34,6 +34,7 @@ export class Node { this.id = sId; this.index = iIndex; this.topic = sTopic; + /** @type {Record} */ this.data = oData || {}; this.isroot = bIsRoot; this.parent = oParent; diff --git a/src/jsmind.option.js b/src/jsmind.option.js index 466352b9..1c1ec6ac 100644 --- a/src/jsmind.option.js +++ b/src/jsmind.option.js @@ -24,18 +24,18 @@ import { util } from './jsmind.util.js'; * line_width: number, * line_color: string, * line_style: 'curved'|'straight', - * custom_line_render?: Function, + * custom_line_render?: (this: object, arg:{ ctx: CanvasRenderingContext2D|SVGPathElement, start_point:{x:number,y:number}, end_point:{x:number,y:number} })=>void, * draggable: boolean, * hide_scrollbars_when_draggable: boolean, * node_overflow: 'hidden'|'wrap', * zoom: { min:number, max:number, step:number, mask_key:number }, - * custom_node_render: (null|function(any,HTMLElement, any):void), + * custom_node_render: (null|((jm: import('./jsmind.js').default, ele: HTMLElement, node: import('./jsmind.node.js').Node)=>void)), * expander_style: 'char'|'number' * }, * layout: { hspace:number, vspace:number, pspace:number, cousin_space:number }, * default_event_handle: { enable_mousedown_handle:boolean, enable_click_handle:boolean, enable_dblclick_handle:boolean, enable_mousewheel_handle:boolean }, - * shortcut: { enable:boolean, handles: Record, mapping: Record }, - * plugin: Record + * shortcut: { enable:boolean, handles: Recordvoid>, mapping: Record, id_generator?: ()=>string }, + * plugin: Record * }} JsMindRuntimeOptions */ /** @type {JsMindRuntimeOptions} */ diff --git a/src/jsmind.plugin.js b/src/jsmind.plugin.js index 06d94288..739807c9 100644 --- a/src/jsmind.plugin.js +++ b/src/jsmind.plugin.js @@ -8,14 +8,14 @@ import { $ } from './jsmind.dom.js'; -/** @type {{ plugins: Array> }} */ +/** @type {{ plugins: Array> }} */ const plugin_data = { plugins: [], }; /** * Register a plugin instance. - * @param {Plugin} plugin + * @param {Plugin} plugin */ export function register(plugin) { if (!(plugin instanceof Plugin)) { @@ -30,7 +30,7 @@ export function register(plugin) { /** * Apply registered plugins asynchronously. * @param {import('./jsmind.js').default} jm - * @param {Record} options + * @param {Record} options */ export function apply(jm, options) { $.w.setTimeout(function () { @@ -40,14 +40,14 @@ export function apply(jm, options) { /** * @param {import('./jsmind.js').default} jm - * @param {Record} options */ + * @param {Record} options */ function _apply(jm, options) { plugin_data.plugins.forEach(p => p.fn_init(jm, options[p.name])); } export class Plugin { /** - * @template [TOptions=any] + * @template [TOptions=object] * @param {string} name * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init */ diff --git a/src/jsmind.shortcut_provider.js b/src/jsmind.shortcut_provider.js index c0255288..6115ce27 100644 --- a/src/jsmind.shortcut_provider.js +++ b/src/jsmind.shortcut_provider.js @@ -11,12 +11,20 @@ import { util } from './jsmind.util.js'; import { Direction } from './jsmind.common.js'; export class ShortcutProvider { + /** + * @param {import('./jsmind.js').default} jm + * @param {{ enable:boolean, handles: Recordvoid>, mapping: Record, id_generator?: ()=>string }} options + */ constructor(jm, options) { this.jm = jm; this.opts = options; + /** @type {Record} */ this.mapping = options.mapping; + /** @type {Recordvoid>} */ this.handles = options.handles; + /** @type {()=>string|null} */ this._newid = null; + /** @type {Recordvoid>} */ this._mapping = {}; } init() { @@ -56,6 +64,7 @@ export class ShortcutProvider { disable_shortcut() { this.opts.enable = false; } + /** @param {KeyboardEvent} e */ handler(e) { if (e.which == 9) { e.preventDefault(); @@ -77,6 +86,7 @@ export class ShortcutProvider { this._mapping[kc].call(this, this.jm, e); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_addchild(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { @@ -88,6 +98,7 @@ export class ShortcutProvider { } } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_addbrother(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -99,12 +110,14 @@ export class ShortcutProvider { } } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_editnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node) { _jm.begin_edit(selected_node); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_delnode(_jm, e) { var selected_node = _jm.get_selected_node(); if (!!selected_node && !selected_node.isroot) { @@ -112,6 +125,7 @@ export class ShortcutProvider { _jm.remove_node(selected_node); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_toggle(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -121,6 +135,7 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_up(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -139,6 +154,7 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_down(_jm, e) { var evt = e || event; var selected_node = _jm.get_selected_node(); @@ -157,12 +173,15 @@ export class ShortcutProvider { evt.preventDefault(); } } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_left(_jm, e) { this._handle_direction(_jm, e, Direction.left); } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ handle_right(_jm, e) { this._handle_direction(_jm, e, Direction.right); } + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e @param {number} d */ _handle_direction(_jm, e, d) { var evt = e || event; var selected_node = _jm.get_selected_node(); diff --git a/src/jsmind.view_provider.js b/src/jsmind.view_provider.js index f8340a93..d5cd5c2d 100644 --- a/src/jsmind.view_provider.js +++ b/src/jsmind.view_provider.js @@ -60,7 +60,9 @@ export class ViewProvider { logger.debug(this.opts); logger.debug('view.init'); - this.container = $.i(this.opts.container) ? this.opts.container : $.g(this.opts.container); + this.container = $.i(this.opts.container) + ? /** @type {HTMLElement} */ (this.opts.container) + : /** @type {HTMLElement} */ ($.g(this.opts.container)); if (!this.container) { logger.error('the options.view.container was not be found in dom'); return; @@ -104,7 +106,7 @@ export class ViewProvider { /** * Add a delegated event handler. - * @param {any} obj + * @param {import('./jsmind.js').default} obj * @param {string} event_name * @param {(e:Event)=>void} event_handle * @param {boolean=} capture_by_panel @@ -499,6 +501,7 @@ export class ViewProvider { this.e_panel.scrollTop = panel_scroll_y; return true; } + /** @param {boolean=} keep_center */ show(keep_center) { logger.debug(`view.show: {keep_center: ${keep_center}}`); this.expand_size(); @@ -567,7 +570,7 @@ export class ViewProvider { this._show_expander(node, view_offset); } } - /** @param {import('./jsmind.node.js').Node} node */ + /** @param {import('./jsmind.node.js').Node} node @param {{x:number,y:number}} view_offset */ _show_expander(node, view_offset) { if (node.isroot) { return; @@ -590,6 +593,7 @@ export class ViewProvider { expander.style.visibility = 'visible'; } + /** @param {import('./jsmind.node.js').Node} node */ _get_expander_text(node) { let style = !!this.opts.expander_style ? this.opts.expander_style.toLowerCase() : 'char'; if (style === 'number') { @@ -619,7 +623,7 @@ export class ViewProvider { reset_node_custom_style(node) { this._reset_node_custom_style(node._data.view.element, node.data); } - /** @param {HTMLElement} node_element @param {Record} node_data */ + /** @param {HTMLElement} node_element @param {Record} node_data */ _reset_node_custom_style(node_element, node_data) { if ('background-color' in node_data) { node_element.style.backgroundColor = node_data['background-color']; @@ -778,14 +782,17 @@ export class ViewProvider { return true; } + /** @param {MouseEvent=} e */ zoomIn(e) { logger.warn('please use zoom_in instead'); return this.zoom_in(e); } + /** @param {MouseEvent=} e */ zoomOut(e) { logger.warn('please use zoom_out instead'); return this.zoom_out(e); } + /** @param {number} zoom @param {MouseEvent=} e */ setZoom(zoom, e) { logger.warn('please use set_zoom instead'); return this.set_zoom(zoom, e); diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts index eace4e2e..77f876d7 100644 --- a/types/generated/jsmind.d.ts +++ b/types/generated/jsmind.d.ts @@ -175,7 +175,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} parent_node * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ @@ -185,7 +185,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node_before * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ @@ -195,7 +195,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node_after * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ diff --git a/types/generated/jsmind.data_provider.d.ts b/types/generated/jsmind.data_provider.d.ts index 10959201..deffa5bc 100644 --- a/types/generated/jsmind.data_provider.d.ts +++ b/types/generated/jsmind.data_provider.d.ts @@ -11,14 +11,46 @@ export class DataProvider { reset(): void; /** * Load a Mind from mixed source. - * @param {any} mind_data - object with {format,data} or a format-specific payload + * @param {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta?:{name:string,author:string,version:string},format:'freemind',data:string}|{meta?:{name:string,author:string,version:string},format:'text',data:string}} mind_data - object with {format,data} or a format-specific payload * @returns {import('./jsmind.mind.js').Mind|null} */ - load(mind_data: any): import("./jsmind.mind.js").Mind | null; + load(mind_data: import("./jsmind.format.js").NodeTreeFormat | import("./jsmind.format.js").NodeArrayFormat | { + meta?: { + name: string; + author: string; + version: string; + }; + format: "freemind"; + data: string; + } | { + meta?: { + name: string; + author: string; + version: string; + }; + format: "text"; + data: string; + }): import("./jsmind.mind.js").Mind | null; /** * Serialize current mind to target format. * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format - * @returns {any} + * @returns {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta:{name:string,author:string,version:string},format:'freemind',data:string}|{meta:{name:string,author:string,version:string},format:'text',data:string}} */ - get_data(data_format: "node_tree" | "node_array" | "freemind" | "text"): any; + get_data(data_format: "node_tree" | "node_array" | "freemind" | "text"): import("./jsmind.format.js").NodeTreeFormat | import("./jsmind.format.js").NodeArrayFormat | { + meta: { + name: string; + author: string; + version: string; + }; + format: "freemind"; + data: string; + } | { + meta: { + name: string; + author: string; + version: string; + }; + format: "text"; + data: string; + }; } diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts index fba01857..5d0b265a 100644 --- a/types/generated/jsmind.format.d.ts +++ b/types/generated/jsmind.format.d.ts @@ -3,8 +3,8 @@ * @type {{ * node_tree: { example:NodeTreeFormat, get_mind:(src:NodeTreeFormat)=>Mind, get_data:(mind:Mind)=>NodeTreeFormat }, * node_array: { example:NodeArrayFormat, get_mind:(src:NodeArrayFormat)=>Mind, get_data:(mind:Mind)=>NodeArrayFormat }, - * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any }, - * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:any)=>Mind, get_data:(mind:Mind)=>any } + * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'freemind',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'freemind',data:string} }, + * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'text',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'text',data:string} } * }} */ export const format: { @@ -24,8 +24,16 @@ export const format: { format: "freemind"; data: string; }; - get_mind: (src: any) => Mind; - get_data: (mind: Mind) => any; + get_mind: (src: { + meta?: MindMapMeta; + format: "freemind"; + data: string; + }) => Mind; + get_data: (mind: Mind) => { + meta: MindMapMeta; + format: "freemind"; + data: string; + }; }; text: { example: { @@ -33,8 +41,16 @@ export const format: { format: "text"; data: string; }; - get_mind: (src: any) => Mind; - get_data: (mind: Mind) => any; + get_mind: (src: { + meta?: MindMapMeta; + format: "text"; + data: string; + }) => Mind; + get_data: (mind: Mind) => { + meta: MindMapMeta; + format: "text"; + data: string; + }; }; }; export type MindMapMeta = { diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts index 2a7bb416..836d0f83 100644 --- a/types/generated/jsmind.graph.d.ts +++ b/types/generated/jsmind.graph.d.ts @@ -43,14 +43,16 @@ declare class SvgGraph { w: number; h: number; }; - lines: any[]; + /** @type {SVGPathElement[]} */ + lines: SVGPathElement[]; line_drawing: { straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; }; /** Choose line drawing renderer. */ init_line_render(): void; - drawing: ((path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void) | ((path: any, x1: any, y1: any, x2: any, y2: any) => void); + /** @type {(path:SVGPathElement,x1:number,y1:number,x2:number,y2:number)=>void} */ + drawing: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; /** @returns {SVGSVGElement} */ element(): SVGSVGElement; /** @param {number} w @param {number} h */ @@ -67,8 +69,8 @@ declare class SvgGraph { x: number; y: number; }, color?: string | undefined): void; - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; /** * Draw bezier curve to SVG path. * @internal @@ -121,7 +123,7 @@ declare class CanvasGraph { expander_style: "char" | "number"; }; e_canvas: HTMLElement; - canvas_ctx: any; + canvas_ctx: CanvasRenderingContext2D; size: { w: number; h: number; @@ -133,7 +135,8 @@ declare class CanvasGraph { dpr: number; /** Choose line drawing renderer. */ init_line_render(): void; - drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); + /** @type {(ctx:CanvasRenderingContext2D,x1:number,y1:number,x2:number,y2:number)=>void} */ + drawing: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; /** @returns {HTMLCanvasElement} */ element(): HTMLCanvasElement; /** @param {number} w @param {number} h */ @@ -151,8 +154,8 @@ declare class CanvasGraph { x: number; y: number; }, color?: string | undefined): void; - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {Function=} callback */ - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; /** * Draw bezier curve on canvas. * @internal diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts index a4e4e6be..f648946e 100644 --- a/types/generated/jsmind.mind.d.ts +++ b/types/generated/jsmind.mind.d.ts @@ -21,7 +21,7 @@ export class Mind { * Set the root node, only once. * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @returns {Node | null} */ set_root(node_id: string, topic: string, data?: Record | undefined): Node | null; @@ -30,7 +30,7 @@ export class Mind { * @param {Node} parent_node * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @param {boolean=} expanded * @param {number=} idx @@ -42,7 +42,7 @@ export class Mind { * @param {Node} node_before * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {Node | null} */ @@ -58,7 +58,7 @@ export class Mind { * @param {Node} node_after * @param {string} node_id * @param {string} topic - * @param {Record=} data + * @param {Record=} data * @param {number=} direction * @returns {Node | null} */ diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts index 1fa2a2f0..e2da323c 100644 --- a/types/generated/jsmind.node.d.ts +++ b/types/generated/jsmind.node.d.ts @@ -34,6 +34,7 @@ export class Node { id: string; index: number; topic: string; + /** @type {Record} */ data: Record; isroot: boolean; parent: Node; diff --git a/types/generated/jsmind.option.d.ts b/types/generated/jsmind.option.d.ts index 1ead2a7b..7e1d0438 100644 --- a/types/generated/jsmind.option.d.ts +++ b/types/generated/jsmind.option.d.ts @@ -19,7 +19,17 @@ export type JsMindRuntimeOptions = { line_width: number; line_color: string; line_style: "curved" | "straight"; - custom_line_render?: Function; + custom_line_render?: (this: object, arg: { + ctx: CanvasRenderingContext2D | SVGPathElement; + start_point: { + x: number; + y: number; + }; + end_point: { + x: number; + y: number; + }; + }) => void; draggable: boolean; hide_scrollbars_when_draggable: boolean; node_overflow: "hidden" | "wrap"; @@ -29,7 +39,7 @@ export type JsMindRuntimeOptions = { step: number; mask_key: number; }; - custom_node_render: (null | ((arg0: any, arg1: HTMLElement, arg2: any) => void)); + custom_node_render: (null | ((jm: import("./jsmind.js").default, ele: HTMLElement, node: import("./jsmind.node.js").Node) => void)); expander_style: "char" | "number"; }; layout: { @@ -46,8 +56,9 @@ export type JsMindRuntimeOptions = { }; shortcut: { enable: boolean; - handles: Record; + handles: Record void>; mapping: Record; + id_generator?: () => string; }; - plugin: Record; + plugin: Record; }; diff --git a/types/generated/jsmind.plugin.d.ts b/types/generated/jsmind.plugin.d.ts index 20c0f7f4..86f078ba 100644 --- a/types/generated/jsmind.plugin.d.ts +++ b/types/generated/jsmind.plugin.d.ts @@ -1,17 +1,17 @@ /** * Register a plugin instance. - * @param {Plugin} plugin + * @param {Plugin} plugin */ -export function register(plugin: Plugin): void; +export function register(plugin: Plugin): void; /** * Apply registered plugins asynchronously. * @param {import('./jsmind.js').default} jm - * @param {Record} options + * @param {Record} options */ -export function apply(jm: import("./jsmind.js").default, options: Record): void; +export function apply(jm: import("./jsmind.js").default, options: Record): void; export class Plugin { /** - * @template [TOptions=any] + * @template [TOptions=object] * @param {string} name * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init */ diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts index e481395d..c07a73b2 100644 --- a/types/generated/jsmind.shortcut_provider.d.ts +++ b/types/generated/jsmind.shortcut_provider.d.ts @@ -1,23 +1,52 @@ export class ShortcutProvider { - constructor(jm: any, options: any); - jm: any; - opts: any; - mapping: any; - handles: any; - _newid: any; - _mapping: {}; + /** + * @param {import('./jsmind.js').default} jm + * @param {{ enable:boolean, handles: Recordvoid>, mapping: Record, id_generator?: ()=>string }} options + */ + constructor(jm: import("./jsmind.js").default, options: { + enable: boolean; + handles: Record void>; + mapping: Record; + id_generator?: () => string; + }); + jm: import("./jsmind.js").default; + opts: { + enable: boolean; + handles: Record void>; + mapping: Record; + id_generator?: () => string; + }; + /** @type {Record} */ + mapping: Record; + /** @type {Recordvoid>} */ + handles: Record void>; + /** @type {()=>string|null} */ + _newid: () => string | null; + /** @type {Recordvoid>} */ + _mapping: Record void>; init(): void; enable_shortcut(): void; disable_shortcut(): void; - handler(e: any): boolean; - handle_addchild(_jm: any, e: any): void; - handle_addbrother(_jm: any, e: any): void; - handle_editnode(_jm: any, e: any): void; - handle_delnode(_jm: any, e: any): void; - handle_toggle(_jm: any, e: any): void; - handle_up(_jm: any, e: any): void; - handle_down(_jm: any, e: any): void; - handle_left(_jm: any, e: any): void; - handle_right(_jm: any, e: any): void; - _handle_direction(_jm: any, e: any, d: any): void; + /** @param {KeyboardEvent} e */ + handler(e: KeyboardEvent): boolean; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_addchild(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_addbrother(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_editnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_delnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_toggle(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_up(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_down(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_left(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ + handle_right(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e @param {number} d */ + _handle_direction(_jm: import("./jsmind.js").default, e: KeyboardEvent, d: number): void; } diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts index e8cd2a0a..ef7833d4 100644 --- a/types/generated/jsmind.view_provider.d.ts +++ b/types/generated/jsmind.view_provider.d.ts @@ -63,7 +63,7 @@ export class ViewProvider { }; jm: import("./jsmind.js").default; layout: import("./jsmind.layout_provider.js").LayoutProvider; - container: any; + container: HTMLElement; e_panel: HTMLElement; e_nodes: HTMLElement; size: { @@ -100,13 +100,13 @@ export class ViewProvider { w: number; h: number; }; - lines: any[]; + lines: SVGPathElement[]; line_drawing: { straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; }; init_line_render(): void; - drawing: ((path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void) | ((path: any, x1: any, y1: any, x2: any, y2: any) => void); + drawing: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; element(): SVGSVGElement; set_size(w: number, h: number): void; clear(): void; @@ -120,7 +120,7 @@ export class ViewProvider { x: number; y: number; }, color?: string | undefined): void; - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; _bezier_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; } | { @@ -146,7 +146,7 @@ export class ViewProvider { expander_style: "char" | "number"; }; e_canvas: HTMLElement; - canvas_ctx: any; + canvas_ctx: CanvasRenderingContext2D; size: { w: number; h: number; @@ -157,7 +157,7 @@ export class ViewProvider { }; dpr: number; init_line_render(): void; - drawing: ((ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void) | ((ctx: any, x1: any, y1: any, x2: any, y2: any) => void); + drawing: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; element(): HTMLCanvasElement; set_size(w: number, h: number): void; clear(): void; @@ -171,7 +171,7 @@ export class ViewProvider { x: number; y: number; }, color?: string | undefined): void; - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: Function | undefined): void; + copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; _bezier_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; _line_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; }; @@ -184,12 +184,12 @@ export class ViewProvider { e_editor: HTMLElement; /** * Add a delegated event handler. - * @param {any} obj + * @param {import('./jsmind.js').default} obj * @param {string} event_name * @param {(e:Event)=>void} event_handle * @param {boolean=} capture_by_panel */ - add_event(obj: any, event_name: string, event_handle: (e: Event) => void, capture_by_panel?: boolean | undefined): void; + add_event(obj: import("./jsmind.js").default, event_name: string, event_handle: (e: Event) => void, capture_by_panel?: boolean | undefined): void; /** * @param {HTMLElement|null} element * @returns {string|null} @@ -300,7 +300,8 @@ export class ViewProvider { * @param {MouseEvent=} e */ set_zoom(zoom: number, e?: MouseEvent | undefined): boolean; - show(keep_center: any): void; + /** @param {boolean=} keep_center */ + show(keep_center?: boolean | undefined): void; relayout(): void; /** @param {import('./jsmind.node.js').Node} node */ save_location(node: import("./jsmind.node.js").Node): void; @@ -309,17 +310,21 @@ export class ViewProvider { clear_nodes(): void; /** Render node elements and expanders to screen. */ show_nodes(): void; + /** @param {import('./jsmind.node.js').Node} node @param {{x:number,y:number}} view_offset */ + _show_expander(node: import("./jsmind.node.js").Node, view_offset: { + x: number; + y: number; + }): void; /** @param {import('./jsmind.node.js').Node} node */ - _show_expander(node: import("./jsmind.node.js").Node, view_offset: any): void; - _get_expander_text(node: any): any; + _get_expander_text(node: import("./jsmind.node.js").Node): number | "..." | "-" | "+"; /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ _default_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ _custom_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; /** @param {import('./jsmind.node.js').Node} node */ reset_node_custom_style(node: import("./jsmind.node.js").Node): void; - /** @param {HTMLElement} node_element @param {Record} node_data */ - _reset_node_custom_style(node_element: HTMLElement, node_data: Record): void; + /** @param {HTMLElement} node_element @param {Record} node_data */ + _reset_node_custom_style(node_element: HTMLElement, node_data: Record): void; /** @param {import('./jsmind.node.js').Node} node */ restore_selected_node_custom_style(node: import("./jsmind.node.js").Node): void; /** @param {import('./jsmind.node.js').Node} node */ @@ -333,7 +338,10 @@ export class ViewProvider { setup_canvas_draggable(enabled: boolean): void; /** @param {import('./jsmind.node.js').Node} node */ center_node(node: import("./jsmind.node.js").Node): boolean; - zoomIn(e: any): boolean; - zoomOut(e: any): boolean; - setZoom(zoom: any, e: any): boolean; + /** @param {MouseEvent=} e */ + zoomIn(e?: MouseEvent | undefined): boolean; + /** @param {MouseEvent=} e */ + zoomOut(e?: MouseEvent | undefined): boolean; + /** @param {number} zoom @param {MouseEvent=} e */ + setZoom(zoom: number, e?: MouseEvent | undefined): boolean; } From ad21b4a8924b8fed64a7bd6cfb06c5060201c255 Mon Sep 17 00:00:00 2001 From: umbraci Date: Sun, 10 Aug 2025 20:10:30 +0800 Subject: [PATCH 17/24] chore: format code --- CHANGELOG.md | 47 +- pnpm-lock.yaml | 7427 ++++++++++------- src/jsmind.plugin.js | 2 +- types/generated/jsmind.common.d.ts | 2 +- types/generated/jsmind.d.ts | 99 +- types/generated/jsmind.data_provider.d.ts | 82 +- types/generated/jsmind.format.d.ts | 28 +- types/generated/jsmind.graph.d.ts | 101 +- types/generated/jsmind.layout_provider.d.ts | 53 +- types/generated/jsmind.mind.d.ts | 40 +- types/generated/jsmind.node.d.ts | 11 +- types/generated/jsmind.option.d.ts | 49 +- types/generated/jsmind.plugin.d.ts | 9 +- types/generated/jsmind.shortcut_provider.d.ts | 43 +- types/generated/jsmind.view_provider.d.ts | 398 +- .../plugins/jsmind.draggable-node.d.ts | 55 +- .../generated/plugins/jsmind.screenshot.d.ts | 6 +- 17 files changed, 4946 insertions(+), 3506 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a2e6f34..a2b1dd32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,34 +2,39 @@ ### 2025-08-10 -- Added +- Added - - Central typings entry `types/index.d.ts` and regenerated declaration files under `types/generated/` for core and plugins (dom, format, graph, layout_provider, mind, node, option, plugin, shortcut_provider, util, view_provider, draggable-node, screenshot). - - Declaration build config `tsconfig.decls.json` and npm scripts: `gen:dts`, `gen:dts:check`. - - TypeScript typings validation: `tests/unit/typescript.types.test.js` with fixture `tests/fixtures/typescript-test.ts` using TypeScript Compiler API. -- Changed + - Central typings entry `types/index.d.ts` and regenerated declaration files under `types/generated/` for core and plugins (dom, format, graph, layout_provider, mind, node, option, plugin, shortcut_provider, util, view_provider, draggable-node, screenshot). + - Declaration build config `tsconfig.decls.json` and npm scripts: `gen:dts`, `gen:dts:check`. + - TypeScript typings validation: `tests/unit/typescript.types.test.js` with fixture `tests/fixtures/typescript-test.ts` using TypeScript Compiler API. - - Updated `package.json` to expose `types` via `types/index.d.ts` and added scripts for generating/checking declarations. - - Enriched JSDoc and in-source documentation across core modules and plugins to improve generated typings (data_provider, dom, format, graph, layout_provider, mind, node, option, plugin, util, view_provider, draggable-node, screenshot). - - Updated `tsconfig.json` strictness and paths; CI updated to run `npm run gen:dts` before build and include `gen:dts:check` in install pipeline. - - Dev dependencies refreshed, adding `typescript`, `tsd-jsdoc`, and updating various `@types/*`, jest, jsdoc toolchain packages. -- Removed +- Changed - - Legacy type files under `types/` (`jsmind.d.ts`, `jsmind.draggable-node.d.ts`, `jsmind.screenshot.d.ts`) in favor of `types/generated/`. -- Notes + - Updated `package.json` to expose `types` via `types/index.d.ts` and added scripts for generating/checking declarations. + - Enriched JSDoc and in-source documentation across core modules and plugins to improve generated typings (data_provider, dom, format, graph, layout_provider, mind, node, option, plugin, util, view_provider, draggable-node, screenshot). + - Updated `tsconfig.json` strictness and paths; CI updated to run `npm run gen:dts` before build and include `gen:dts:check` in install pipeline. + - Dev dependencies refreshed, adding `typescript`, `tsd-jsdoc`, and updating various `@types/*`, jest, jsdoc toolchain packages. - - Running `npm test` now validates both runtime tests and TypeScript definitions. Consumers can rely on the aggregated public typings from the package root; plugin typings are exposed under `plugins/` paths. +- Removed + + - Legacy type files under `types/` (`jsmind.d.ts`, `jsmind.draggable-node.d.ts`, `jsmind.screenshot.d.ts`) in favor of `types/generated/`. + +- Notes + + - Running `npm test` now validates both runtime tests and TypeScript definitions. Consumers can rely on the aggregated public typings from the package root; plugin typings are exposed under `plugins/` paths. ### 2025-08-09 -- Added +- Added + + - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). + - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). + +- Changed - - TypeScript support: publish `.d.ts` for core and plugins (`es6/jsmind.d.ts`, `es6/jsmind.draggable-node.d.ts`, `es6/jsmind.screenshot.d.ts`). - - Type checking in CI: added Jest test `tests/unit/typescript.types.test.js` using TypeScript Compiler API to verify typings with `tsconfig.json` (noEmit). -- Changed + - Updated root `package.json` to expose `types` and proper `exports` fields for typings. - - Updated root `package.json` to expose `types` and proper `exports` fields for typings. -- Notes +- Notes - - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. - - Running `npm test` will now validate TypeScript definitions. + - The TS example `example/typescript-test.ts` is included in `tsconfig.json#includes` for compile-time verification. + - Running `npm test` will now validate TypeScript definitions. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 91e7558a..d0048cb9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,3122 +1,4321 @@ lockfileVersion: '6.0' settings: - autoInstallPeers: true - excludeLinksFromLockfile: false + autoInstallPeers: true + excludeLinksFromLockfile: false devDependencies: - '@rollup/plugin-terser': - specifier: ^0.4.4 - version: 0.4.4(rollup@2.79.2) - http-server: - specifier: ^14.1.1 - version: 14.1.1 - jest: - specifier: ^28.1.0 - version: 28.1.3 - jest-environment-jsdom: - specifier: ^28.1.0 - version: 28.1.3 - prettier: - specifier: 2.6.2 - version: 2.6.2 - rollup: - specifier: 2.79.2 - version: 2.79.2 - rollup-plugin-cleanup: - specifier: ^3.2.1 - version: 3.2.1(rollup@2.79.2) - tsd-jsdoc: - specifier: ^2.5.0 - version: 2.5.0(jsdoc@3.6.11) - typescript: - specifier: ^5.9.2 - version: 5.9.2 + '@rollup/plugin-terser': + specifier: ^0.4.4 + version: 0.4.4(rollup@2.79.2) + http-server: + specifier: ^14.1.1 + version: 14.1.1 + jest: + specifier: ^28.1.0 + version: 28.1.3 + jest-environment-jsdom: + specifier: ^28.1.0 + version: 28.1.3 + prettier: + specifier: 2.6.2 + version: 2.6.2 + rollup: + specifier: 2.79.2 + version: 2.79.2 + rollup-plugin-cleanup: + specifier: ^3.2.1 + version: 3.2.1(rollup@2.79.2) + tsd-jsdoc: + specifier: ^2.5.0 + version: 2.5.0(jsdoc@3.6.11) + typescript: + specifier: ^5.9.2 + version: 5.9.2 packages: - - /@ampproject/remapping@2.3.0: - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - dev: true - - /@babel/code-frame@7.27.1: - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - dev: true - - /@babel/compat-data@7.28.0: - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.28.0: - resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.28.2 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - convert-source-map: 2.0.0 - debug: 4.4.1 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.28.0: - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - jsesc: 3.1.0 - dev: true - - /@babel/helper-compilation-targets@7.27.2: - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.28.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.2 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - - /@babel/helper-globals@7.28.0: - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-module-imports@7.27.1: - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0): - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-plugin-utils@7.27.1: - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-string-parser@7.27.1: - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.27.1: - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.27.1: - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.28.2: - resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - dev: true - - /@babel/parser@7.28.0: - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.28.2 - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0): - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0): - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - dev: true - - /@babel/template@7.27.2: - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - dev: true - - /@babel/traverse@7.28.0: - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.28.2: - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - dev: true - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console@28.1.3: - resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - chalk: 4.1.2 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/core@28.1.3: - resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 28.1.3 - '@jest/reporters': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 28.1.3 - jest-config: 28.1.3(@types/node@24.2.1) - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-resolve-dependencies: 28.1.3 - jest-runner: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - jest-watcher: 28.1.3 - micromatch: 4.0.8 - pretty-format: 28.1.3 - rimraf: 3.0.2 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /@jest/environment@28.1.3: - resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - jest-mock: 28.1.3 - dev: true - - /@jest/expect-utils@28.1.3: - resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - dev: true - - /@jest/expect@28.1.3: - resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - expect: 28.1.3 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers@28.1.3: - resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@sinonjs/fake-timers': 9.1.2 - '@types/node': 24.2.1 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /@jest/globals@28.1.3: - resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/types': 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters@28.1.3: - resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.29 - '@types/node': 24.2.1 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - jest-worker: 28.1.3 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - terminal-link: 2.1.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas@28.1.3: - resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@sinclair/typebox': 0.24.51 - dev: true - - /@jest/source-map@28.1.2: - resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.29 - callsites: 3.1.0 - graceful-fs: 4.2.11 - dev: true - - /@jest/test-result@28.1.3: - resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/types': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - dev: true - - /@jest/test-sequencer@28.1.3: - resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/transform@28.1.3: - resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.28.0 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.29 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 1.9.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types@28.1.3: - resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 24.2.1 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping@0.3.12: - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 - dev: true - - /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/source-map@0.3.10: - resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==} - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - dev: true - - /@jridgewell/sourcemap-codec@1.5.4: - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - dev: true - - /@jridgewell/trace-mapping@0.3.29: - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 - dev: true - - /@rollup/plugin-terser@0.4.4(rollup@2.79.2): - resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - rollup: 2.79.2 - serialize-javascript: 6.0.2 - smob: 1.5.0 - terser: 5.43.1 - dev: true - - /@sinclair/typebox@0.24.51: - resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} - dev: true - - /@sinonjs/commons@1.8.6: - resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers@9.1.2: - resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} - dependencies: - '@sinonjs/commons': 1.8.6 - dev: true - - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - dev: true - - /@types/babel__core@7.20.5: - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 - dev: true - - /@types/babel__generator@7.27.0: - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - dependencies: - '@babel/types': 7.28.2 - dev: true - - /@types/babel__template@7.4.4: - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - dev: true - - /@types/babel__traverse@7.28.0: - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - dependencies: - '@babel/types': 7.28.2 - dev: true - - /@types/graceful-fs@4.1.9: - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - dependencies: - '@types/node': 24.2.1 - dev: true - - /@types/istanbul-lib-coverage@2.0.6: - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - dev: true - - /@types/istanbul-lib-report@3.0.3: - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - dev: true - - /@types/istanbul-reports@3.0.4: - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - dependencies: - '@types/istanbul-lib-report': 3.0.3 - dev: true - - /@types/jsdom@16.2.15: - resolution: {integrity: sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==} - dependencies: - '@types/node': 24.2.1 - '@types/parse5': 6.0.3 - '@types/tough-cookie': 4.0.5 - dev: true - - /@types/linkify-it@5.0.0: - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - dev: true - - /@types/markdown-it@12.2.3: - resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - dev: true - - /@types/mdurl@2.0.0: - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - dev: true - - /@types/node@24.2.1: - resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==} - dependencies: - undici-types: 7.10.0 - dev: true - - /@types/parse5@6.0.3: - resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - dev: true - - /@types/prettier@2.7.3: - resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - dev: true - - /@types/stack-utils@2.0.3: - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - dev: true - - /@types/tough-cookie@4.0.5: - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - dev: true - - /@types/yargs-parser@21.0.3: - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - dev: true - - /@types/yargs@17.0.33: - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - dependencies: - '@types/yargs-parser': 21.0.3 - dev: true - - /abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead - dev: true - - /acorn-globals@6.0.0: - resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} - dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 - dev: true - - /acorn-walk@7.2.0: - resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - dev: true - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true - - /babel-jest@28.1.3(@babel/core@7.28.0): - resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.28.0 - '@jest/transform': 28.1.3 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 28.1.3(@babel/core@7.28.0) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.27.1 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist@28.1.3: - resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 - dev: true - - /babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.0): - resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} - peerDependencies: - '@babel/core': ^7.0.0 || ^8.0.0-0 - dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0) - dev: true - - /babel-preset-jest@28.1.3(@babel/core@7.28.0): - resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.28.0 - babel-plugin-jest-hoist: 28.1.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /basic-auth@2.0.1: - resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} - engines: {node: '>= 0.8'} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: true - - /brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.1.1 - dev: true - - /browser-process-hrtime@1.0.0: - resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} - dev: true - - /browserslist@4.25.2: - resolution: {integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001733 - electron-to-chromium: 1.5.199 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.2) - dev: true - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - dev: true - - /call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - dev: true - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true - - /caniuse-lite@1.0.30001733: - resolution: {integrity: sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==} - dev: true - - /catharsis@0.9.0: - resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} - engines: {node: '>= 10'} - dependencies: - lodash: 4.17.21 - dev: true - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - dev: true - - /cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - dev: true - - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - dev: true - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: true - - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /corser@2.0.1: - resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==} - engines: {node: '>= 0.4.0'} - dev: true - - /cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: true - - /cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: true - - /cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} - dependencies: - cssom: 0.3.8 - dev: true - - /data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} - dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - dev: true - - /debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - dev: true - - /dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - dev: true - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: true - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /diff-sequences@28.1.1: - resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead - dependencies: - webidl-conversions: 7.0.0 - dev: true - - /dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - dev: true - - /electron-to-chromium@1.5.199: - resolution: {integrity: sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ==} - dev: true - - /emittery@0.10.2: - resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} - engines: {node: '>=12'} - dev: true - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /entities@2.1.0: - resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} - dev: true - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - dev: true - - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - dev: true - - /es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - dev: true - - /es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - dev: true - - /escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - dev: true - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - dev: true - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - /estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - dev: true - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: true - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expect@28.1.3: - resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/expect-utils': 28.1.3 - jest-get-type: 28.0.2 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: true - - /form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - dev: true - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - dev: true - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - dev: true - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - dev: true - - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.1.0 - dev: true - - /hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - dependencies: - function-bind: 1.1.2 - dev: true - - /he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - dev: true - - /html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} - dependencies: - whatwg-encoding: 2.0.0 - dev: true - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /http-proxy@1.18.1: - resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} - engines: {node: '>=8.0.0'} - dependencies: - eventemitter3: 4.0.7 - follow-redirects: 1.15.11 - requires-port: 1.0.0 - transitivePeerDependencies: - - debug - dev: true - - /http-server@14.1.1: - resolution: {integrity: sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==} - engines: {node: '>=12'} - hasBin: true - dependencies: - basic-auth: 2.0.1 - chalk: 4.1.2 - corser: 2.0.1 - he: 1.2.0 - html-encoding-sniffer: 3.0.0 - http-proxy: 1.18.1 - mime: 1.6.0 - minimist: 1.2.8 - opener: 1.5.2 - portfinder: 1.0.37 - secure-compare: 3.0.1 - union: 0.5.0 - url-join: 4.0.1 - transitivePeerDependencies: - - debug - - supports-color - dev: true - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - dependencies: - hasown: 2.0.2 - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - dev: true - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.28.0 - '@babel/parser': 7.28.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.4.1 - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - dev: true - - /jest-changed-files@28.1.3: - resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus@28.1.3: - resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - p-limit: 3.1.0 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-cli@28.1.3: - resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.2.0 - jest-config: 28.1.3(@types/node@24.2.1) - jest-util: 28.1.3 - jest-validate: 28.1.3 - prompts: 2.4.2 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jest-config@28.1.3(@types/node@24.2.1): - resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': + /@ampproject/remapping@2.3.0: + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: '>=6.0.0' } + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@babel/code-frame@7.27.1: + resolution: + { + integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + dev: true + + /@babel/compat-data@7.28.0: + resolution: + { + integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/core@7.28.0: + resolution: + { + integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.28.2 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.28.0: + resolution: + { + integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + dev: true + + /@babel/helper-compilation-targets@7.27.2: + resolution: + { + integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.2 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-globals@7.28.0: + resolution: + { + integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/helper-module-imports@7.27.1: + resolution: + { + integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils@7.27.1: + resolution: + { + integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/helper-string-parser@7.27.1: + resolution: + { + integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/helper-validator-identifier@7.27.1: + resolution: + { + integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/helper-validator-option@7.27.1: + resolution: + { + integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, + } + engines: { node: '>=6.9.0' } + dev: true + + /@babel/helpers@7.28.2: + resolution: + { + integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + dev: true + + /@babel/parser@7.28.0: + resolution: + { + integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==, + } + engines: { node: '>=6.0.0' } + hasBin: true + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0): + resolution: + { + integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0): + resolution: + { + integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0): + resolution: + { + integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0): + resolution: + { + integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0): + resolution: + { + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0): + resolution: + { + integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0): + resolution: + { + integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, + } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0): + resolution: + { + integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0): + resolution: + { + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0): + resolution: + { + integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==, + } + engines: { node: '>=6.9.0' } + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + + /@babel/template@7.27.2: + resolution: + { + integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + dev: true + + /@babel/traverse@7.28.0: + resolution: + { + integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.28.2: + resolution: + { + integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==, + } + engines: { node: '>=6.9.0' } + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: + { + integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, + } + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: + { + integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, + } + engines: { node: '>=8' } + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: + { + integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, + } + engines: { node: '>=8' } + dev: true + + /@jest/console@28.1.3: + resolution: + { + integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + dev: true + + /@jest/core@28.1.3: + resolution: + { + integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 28.1.3 + '@jest/reporters': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 28.1.3 + jest-config: 28.1.3(@types/node@24.2.1) + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-resolve-dependencies: 28.1.3 + jest-runner: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + jest-watcher: 28.1.3 + micromatch: 4.0.8 + pretty-format: 28.1.3 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /@jest/environment@28.1.3: + resolution: + { + integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + dev: true + + /@jest/expect-utils@28.1.3: + resolution: + { + integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + jest-get-type: 28.0.2 + dev: true + + /@jest/expect@28.1.3: + resolution: + { + integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + expect: 28.1.3 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@28.1.3: + resolution: + { + integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + '@sinonjs/fake-timers': 9.1.2 + '@types/node': 24.2.1 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /@jest/globals@28.1.3: + resolution: + { + integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/types': 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@28.1.3: + resolution: + { + integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.29 + '@types/node': 24.2.1 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + jest-worker: 28.1.3 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + terminal-link: 2.1.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas@28.1.3: + resolution: + { + integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@sinclair/typebox': 0.24.51 + dev: true + + /@jest/source-map@28.1.2: + resolution: + { + integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@28.1.3: + resolution: + { + integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/console': 28.1.3 + '@jest/types': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@28.1.3: + resolution: + { + integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/test-result': 28.1.3 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + slash: 3.0.0 + dev: true + + /@jest/transform@28.1.3: + resolution: + { + integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@babel/core': 7.28.0 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.29 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@28.1.3: + resolution: + { + integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/schemas': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.2.1 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.12: + resolution: + { + integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==, + } + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: '>=6.0.0' } + dev: true + + /@jridgewell/source-map@0.3.10: + resolution: + { + integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==, + } + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + dev: true + + /@jridgewell/sourcemap-codec@1.5.4: + resolution: + { + integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==, + } + dev: true + + /@jridgewell/trace-mapping@0.3.29: + resolution: + { + integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==, + } + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.4 + dev: true + + /@rollup/plugin-terser@0.4.4(rollup@2.79.2): + resolution: + { + integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==, + } + engines: { node: '>=14.0.0' } + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 2.79.2 + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.43.1 + dev: true + + /@sinclair/typebox@0.24.51: + resolution: + { + integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==, + } + dev: true + + /@sinonjs/commons@1.8.6: + resolution: + { + integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==, + } + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@9.1.2: + resolution: + { + integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==, + } + dependencies: + '@sinonjs/commons': 1.8.6 + dev: true + + /@tootallnate/once@2.0.0: + resolution: + { + integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==, + } + engines: { node: '>= 10' } + dev: true + + /@types/babel__core@7.20.5: + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + dev: true + + /@types/babel__generator@7.27.0: + resolution: + { + integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==, + } + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@types/babel__template@7.4.4: + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + dev: true + + /@types/babel__traverse@7.28.0: + resolution: + { + integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==, + } + dependencies: + '@babel/types': 7.28.2 + dev: true + + /@types/graceful-fs@4.1.9: + resolution: + { + integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, + } + dependencies: + '@types/node': 24.2.1 + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: + { + integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, + } + dev: true + + /@types/istanbul-lib-report@3.0.3: + resolution: + { + integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, + } + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: + { + integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, + } + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true + + /@types/jsdom@16.2.15: + resolution: + { + integrity: sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==, + } + dependencies: + '@types/node': 24.2.1 + '@types/parse5': 6.0.3 + '@types/tough-cookie': 4.0.5 + dev: true + + /@types/linkify-it@5.0.0: + resolution: + { + integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==, + } + dev: true + + /@types/markdown-it@12.2.3: + resolution: + { + integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==, + } + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: true + + /@types/mdurl@2.0.0: + resolution: + { + integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==, + } + dev: true + + /@types/node@24.2.1: + resolution: + { + integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==, + } + dependencies: + undici-types: 7.10.0 + dev: true + + /@types/parse5@6.0.3: + resolution: + { + integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==, + } + dev: true + + /@types/prettier@2.7.3: + resolution: + { + integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==, + } + dev: true + + /@types/stack-utils@2.0.3: + resolution: + { + integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, + } + dev: true + + /@types/tough-cookie@4.0.5: + resolution: + { + integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==, + } + dev: true + + /@types/yargs-parser@21.0.3: + resolution: + { + integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, + } + dev: true + + /@types/yargs@17.0.33: + resolution: + { + integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, + } + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /abab@2.0.6: + resolution: + { + integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==, + } + deprecated: Use your platform's native atob() and btoa() methods instead + dev: true + + /acorn-globals@6.0.0: + resolution: + { + integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==, + } + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + dev: true + + /acorn-walk@7.2.0: + resolution: + { + integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==, + } + engines: { node: '>=0.4.0' } + dev: true + + /acorn@7.4.1: + resolution: + { + integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==, + } + engines: { node: '>=0.4.0' } + hasBin: true + dev: true + + /acorn@8.15.0: + resolution: + { + integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==, + } + engines: { node: '>=0.4.0' } + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: '>= 6.0.0' } + dependencies: + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /ansi-escapes@4.3.2: + resolution: + { + integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, + } + engines: { node: '>=8' } + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } + dev: true + + /ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: '>=10' } + dev: true + + /anymatch@3.1.3: + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: '>= 8' } + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse@1.0.10: + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } + dev: true + + /async@3.2.6: + resolution: + { + integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==, + } + dev: true + + /asynckit@0.4.0: + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } + dev: true + + /babel-jest@28.1.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.28.0 + '@jest/transform': 28.1.3 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 28.1.3(@babel/core@7.28.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: + { + integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, + } + engines: { node: '>=8' } + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@28.1.3: + resolution: + { + integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + dev: true + + /babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.0): + resolution: + { + integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==, + } + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0) + dev: true + + /babel-preset-jest@28.1.3(@babel/core@7.28.0): + resolution: + { + integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.28.0 + babel-plugin-jest-hoist: 28.1.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) + dev: true + + /balanced-match@1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + dev: true + + /basic-auth@2.0.1: + resolution: + { + integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==, + } + engines: { node: '>= 0.8' } + dependencies: + safe-buffer: 5.1.2 + dev: true + + /bluebird@3.7.2: + resolution: + { + integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==, + } + dev: true + + /brace-expansion@1.1.12: + resolution: + { + integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, + } + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces@3.0.3: + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: '>=8' } + dependencies: + fill-range: 7.1.1 + dev: true + + /browser-process-hrtime@1.0.0: + resolution: + { + integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==, + } + dev: true + + /browserslist@4.25.2: + resolution: + { + integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + hasBin: true + dependencies: + caniuse-lite: 1.0.30001733 + electron-to-chromium: 1.5.199 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.2) + dev: true + + /bser@2.1.1: + resolution: + { + integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, + } + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } + dev: true + + /call-bind-apply-helpers@1.0.2: + resolution: + { + integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, + } + engines: { node: '>= 0.4' } + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + dev: true + + /call-bound@1.0.4: + resolution: + { + integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, + } + engines: { node: '>= 0.4' } + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: true + + /callsites@3.1.0: + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: '>=6' } + dev: true + + /camelcase@5.3.1: + resolution: + { + integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, + } + engines: { node: '>=6' } + dev: true + + /camelcase@6.3.0: + resolution: + { + integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, + } + engines: { node: '>=10' } + dev: true + + /caniuse-lite@1.0.30001733: + resolution: + { + integrity: sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==, + } + dev: true + + /catharsis@0.9.0: + resolution: + { + integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==, + } + engines: { node: '>= 10' } + dependencies: + lodash: 4.17.21 + dev: true + + /chalk@4.1.2: + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: '>=10' } + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /char-regex@1.0.2: + resolution: + { + integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, + } + engines: { node: '>=10' } + dev: true + + /ci-info@3.9.0: + resolution: + { + integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, + } + engines: { node: '>=8' } + dev: true + + /cjs-module-lexer@1.4.3: + resolution: + { + integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==, + } + dev: true + + /cliui@8.0.1: + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: '>=12' } + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /co@4.6.0: + resolution: + { + integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, + } + engines: { iojs: '>= 1.0.0', node: '>= 0.12.0' } + dev: true + + /collect-v8-coverage@1.0.2: + resolution: + { + integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, + } + dev: true + + /color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + dev: true + + /combined-stream@1.0.8: + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: '>= 0.8' } + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander@2.20.3: + resolution: + { + integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, + } + dev: true + + /concat-map@0.0.1: + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } + dev: true + + /convert-source-map@1.9.0: + resolution: + { + integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, + } + dev: true + + /convert-source-map@2.0.0: + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } + dev: true + + /corser@2.0.1: + resolution: + { + integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==, + } + engines: { node: '>= 0.4.0' } + dev: true + + /cross-spawn@7.0.6: + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: '>= 8' } + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /cssom@0.3.8: + resolution: + { + integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==, + } + dev: true + + /cssom@0.5.0: + resolution: + { + integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==, + } + dev: true + + /cssstyle@2.3.0: + resolution: + { + integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==, + } + engines: { node: '>=8' } + dependencies: + cssom: 0.3.8 + dev: true + + /data-urls@3.0.2: + resolution: + { + integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==, + } + engines: { node: '>=12' } + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + dev: true + + /debug@4.4.1: + resolution: + { + integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==, + } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /decimal.js@10.6.0: + resolution: + { + integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==, + } + dev: true + + /dedent@0.7.0: + resolution: + { + integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==, + } + dev: true + + /deepmerge@4.3.1: + resolution: + { + integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, + } + engines: { node: '>=0.10.0' } + dev: true + + /delayed-stream@1.0.0: + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: '>=0.4.0' } + dev: true + + /detect-newline@3.1.0: + resolution: + { + integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, + } + engines: { node: '>=8' } + dev: true + + /diff-sequences@28.1.1: + resolution: + { + integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dev: true + + /domexception@4.0.0: + resolution: + { + integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==, + } + engines: { node: '>=12' } + deprecated: Use your platform's native DOMException instead + dependencies: + webidl-conversions: 7.0.0 + dev: true + + /dunder-proto@1.0.1: + resolution: + { + integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, + } + engines: { node: '>= 0.4' } + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: true + + /electron-to-chromium@1.5.199: + resolution: + { + integrity: sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ==, + } + dev: true + + /emittery@0.10.2: + resolution: + { + integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==, + } + engines: { node: '>=12' } + dev: true + + /emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + dev: true + + /entities@2.1.0: + resolution: + { + integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==, + } + dev: true + + /error-ex@1.3.2: + resolution: + { + integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, + } + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-define-property@1.0.1: + resolution: + { + integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, + } + engines: { node: '>= 0.4' } + dev: true + + /es-errors@1.3.0: + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: '>= 0.4' } + dev: true + + /es-object-atoms@1.1.1: + resolution: + { + integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, + } + engines: { node: '>= 0.4' } + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.1.0: + resolution: + { + integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, + } + engines: { node: '>= 0.4' } + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /escalade@3.2.0: + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: '>=6' } + dev: true + + /escape-string-regexp@2.0.0: + resolution: + { + integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, + } + engines: { node: '>=8' } + dev: true + + /escodegen@2.1.0: + resolution: + { + integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==, + } + engines: { node: '>=6.0' } + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esprima@4.0.1: + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: '>=4' } + hasBin: true + dev: true + + /estraverse@5.3.0: + resolution: + { + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, + } + engines: { node: '>=4.0' } + dev: true + + /estree-walker@0.6.1: + resolution: + { + integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==, + } + dev: true + + /esutils@2.0.3: + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: '>=0.10.0' } + dev: true + + /eventemitter3@4.0.7: + resolution: + { + integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, + } + dev: true + + /execa@5.1.1: + resolution: + { + integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, + } + engines: { node: '>=10' } + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exit@0.1.2: + resolution: + { + integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, + } + engines: { node: '>= 0.8.0' } + dev: true + + /expect@28.1.3: + resolution: + { + integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/expect-utils': 28.1.3 + jest-get-type: 28.0.2 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } + dev: true + + /fb-watchman@2.0.2: + resolution: + { + integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, + } + dependencies: + bser: 2.1.1 + dev: true + + /fill-range@7.1.1: + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: '>=8' } + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@4.1.0: + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: '>=8' } + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /follow-redirects@1.15.11: + resolution: + { + integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==, + } + engines: { node: '>=4.0' } + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /form-data@4.0.4: + resolution: + { + integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==, + } + engines: { node: '>= 6' } + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + dev: true + + /fs.realpath@1.0.0: + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } + dev: true + + /fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + requiresBuild: true + dev: true optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.28.0 - '@jest/test-sequencer': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - babel-jest: 28.1.3(@babel/core@7.28.0) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 28.1.3 - jest-environment-node: 28.1.3 - jest-get-type: 28.0.2 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-runner: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 28.1.3 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-diff@28.1.3: - resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 28.1.1 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-docblock@28.1.1: - resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each@28.1.3: - resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - chalk: 4.1.2 - jest-get-type: 28.0.2 - jest-util: 28.1.3 - pretty-format: 28.1.3 - dev: true - - /jest-environment-jsdom@28.1.3: - resolution: {integrity: sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/jsdom': 16.2.15 - '@types/node': 24.2.1 - jest-mock: 28.1.3 - jest-util: 28.1.3 - jsdom: 19.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - dev: true - - /jest-environment-node@28.1.3: - resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /jest-get-type@28.0.2: - resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-haste-map@28.1.3: - resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 24.2.1 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - jest-worker: 28.1.3 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /jest-leak-detector@28.1.3: - resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-matcher-utils@28.1.3: - resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-message-util@28.1.3: - resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/code-frame': 7.27.1 - '@jest/types': 28.1.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.6 - dev: true - - /jest-mock@28.1.3: - resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - dev: true - - /jest-pnp-resolver@1.2.3(jest-resolve@28.1.3): - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 28.1.3 - dev: true - - /jest-regex-util@28.0.2: - resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-resolve-dependencies@28.1.3: - resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-regex-util: 28.0.2 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve@28.1.3: - resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - jest-pnp-resolver: 1.2.3(jest-resolve@28.1.3) - jest-util: 28.1.3 - jest-validate: 28.1.3 - resolve: 1.22.10 - resolve.exports: 1.1.1 - slash: 3.0.0 - dev: true - - /jest-runner@28.1.3: - resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/environment': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - chalk: 4.1.2 - emittery: 0.10.2 - graceful-fs: 4.2.11 - jest-docblock: 28.1.1 - jest-environment-node: 28.1.3 - jest-haste-map: 28.1.3 - jest-leak-detector: 28.1.3 - jest-message-util: 28.1.3 - jest-resolve: 28.1.3 - jest-runtime: 28.1.3 - jest-util: 28.1.3 - jest-watcher: 28.1.3 - jest-worker: 28.1.3 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime@28.1.3: - resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/globals': 28.1.3 - '@jest/source-map': 28.1.2 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 - execa: 5.1.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot@28.1.3: - resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.28.0 - '@babel/generator': 7.28.0 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - '@jest/expect-utils': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/babel__traverse': 7.28.0 - '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) - chalk: 4.1.2 - expect: 28.1.3 - graceful-fs: 4.2.11 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - jest-haste-map: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - natural-compare: 1.4.0 - pretty-format: 28.1.3 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util@28.1.3: - resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - dev: true - - /jest-validate@28.1.3: - resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 28.0.2 - leven: 3.1.0 - pretty-format: 28.1.3 - dev: true - - /jest-watcher@28.1.3: - resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 24.2.1 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.10.2 - jest-util: 28.1.3 - string-length: 4.0.2 - dev: true - - /jest-worker@28.1.3: - resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@types/node': 24.2.1 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest@28.1.3: - resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3 - '@jest/types': 28.1.3 - import-local: 3.2.0 - jest-cli: 28.1.3 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /js-cleanup@1.2.0: - resolution: {integrity: sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==} - engines: {node: ^10.14.2 || >=12.0.0} - dependencies: - magic-string: 0.25.9 - perf-regexes: 1.0.1 - skip-regex: 1.0.2 - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /js2xmlparser@4.0.2: - resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} - dependencies: - xmlcreate: 2.0.4 - dev: true - - /jsdoc@3.6.11: - resolution: {integrity: sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==} - engines: {node: '>=12.0.0'} - hasBin: true - dependencies: - '@babel/parser': 7.28.0 - '@types/markdown-it': 12.2.3 - bluebird: 3.7.2 - catharsis: 0.9.0 - escape-string-regexp: 2.0.0 - js2xmlparser: 4.0.2 - klaw: 3.0.0 - markdown-it: 12.3.2 - markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) - marked: 4.3.0 - mkdirp: 1.0.4 - requizzle: 0.2.4 - strip-json-comments: 3.1.1 - taffydb: 2.6.2 - underscore: 1.13.7 - dev: true - - /jsdom@19.0.0: - resolution: {integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==} - engines: {node: '>=12'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - dependencies: - abab: 2.0.6 - acorn: 8.15.0 - acorn-globals: 6.0.0 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 - decimal.js: 10.6.0 - domexception: 4.0.0 - escodegen: 2.1.0 - form-data: 4.0.4 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 - parse5: 6.0.1 - saxes: 5.0.1 - symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 3.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 10.0.0 - ws: 8.18.3 - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - - /jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /klaw@3.0.0: - resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} - dependencies: - graceful-fs: 4.2.11 - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /linkify-it@3.0.3: - resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - dependencies: - uc.micro: 1.0.6 - dev: true - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true - - /magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - dependencies: - sourcemap-codec: 1.4.8 - dev: true - - /make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - dependencies: - semver: 7.7.2 - dev: true - - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true - - /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): - resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} - peerDependencies: - '@types/markdown-it': '*' - markdown-it: '*' - dependencies: - '@types/markdown-it': 12.2.3 - markdown-it: 12.3.2 - dev: true - - /markdown-it@12.3.2: - resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 2.1.0 - linkify-it: 3.0.3 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: true - - /marked@4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - dev: true - - /math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - dev: true - - /mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: true - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: true - - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.12 - dev: true - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true - - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true - - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true - - /node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - dev: true - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /nwsapi@2.2.21: - resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} - dev: true - - /object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - dev: true - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - - /opener@1.5.2: - resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} - hasBin: true - dev: true - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /parse5@6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /perf-regexes@1.0.1: - resolution: {integrity: sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==} - engines: {node: '>=6.14'} - dev: true - - /picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - dev: true - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - dev: true - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /portfinder@1.0.37: - resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==} - engines: {node: '>= 10.12'} - dependencies: - async: 3.2.6 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - dev: true - - /prettier@2.6.2: - resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-format@28.1.3: - resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 18.3.1 - dev: true - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - dependencies: - punycode: 2.3.1 - dev: true - - /punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - dev: true - - /qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.1.0 - dev: true - - /querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true - - /randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - dev: true - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: true - - /requizzle@0.2.4: - resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} - dependencies: - lodash: 4.17.21 - dev: true - - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve.exports@1.1.1: - resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} - engines: {node: '>=10'} - dev: true - - /resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /rollup-plugin-cleanup@3.2.1(rollup@2.79.2): - resolution: {integrity: sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==} - engines: {node: ^10.14.2 || >=12.0.0} - peerDependencies: - rollup: '>=2.0' - dependencies: - js-cleanup: 1.2.0 - rollup: 2.79.2 - rollup-pluginutils: 2.8.2 - dev: true - - /rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - dependencies: - estree-walker: 0.6.1 - dev: true - - /rollup@2.79.2: - resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} - engines: {node: '>=10.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - - /saxes@5.0.1: - resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} - engines: {node: '>=10'} - dependencies: - xmlchars: 2.2.0 - dev: true - - /secure-compare@3.0.1: - resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==} - dev: true - - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true - - /semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - dependencies: - randombytes: 2.1.0 - dev: true - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - dev: true - - /side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - dev: true - - /side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - dev: true - - /side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - dev: true - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /skip-regex@1.0.2: - resolution: {integrity: sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==} - engines: {node: '>=4.2'} - dev: true - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /smob@1.5.0: - resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} - dev: true - - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - dev: true - - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-hyperlinks@2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: true - - /taffydb@2.6.2: - resolution: {integrity: sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==} - dev: true - - /terminal-link@2.1.1: - resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} - engines: {node: '>=8'} - dependencies: - ansi-escapes: 4.3.2 - supports-hyperlinks: 2.3.0 - dev: true - - /terser@5.43.1: - resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@jridgewell/source-map': 0.3.10 - acorn: 8.15.0 - commander: 2.20.3 - source-map-support: 0.5.21 - dev: true - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - dev: true - - /tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} - dependencies: - punycode: 2.3.1 - dev: true - - /tsd-jsdoc@2.5.0(jsdoc@3.6.11): - resolution: {integrity: sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g==} - peerDependencies: - jsdoc: ^3.6.3 - dependencies: - jsdoc: 3.6.11 - typescript: 3.9.10 - dev: true - - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - - /typescript@3.9.10: - resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - /uc.micro@1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - dev: true - - /underscore@1.13.7: - resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} - dev: true - - /undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} - dev: true - - /union@0.5.0: - resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==} - engines: {node: '>= 0.8.0'} - dependencies: - qs: 6.14.0 - dev: true - - /universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - dev: true - - /update-browserslist-db@1.1.3(browserslist@4.25.2): - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.25.2 - escalade: 3.2.0 - picocolors: 1.1.1 - dev: true - - /url-join@4.0.1: - resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - dev: true - - /url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - dev: true - - /v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.29 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - dev: true - - /w3c-hr-time@1.0.2: - resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} - deprecated: Use your platform's native performance.now() and performance.timeOrigin. - dependencies: - browser-process-hrtime: 1.0.0 - dev: true - - /w3c-xmlserializer@3.0.0: - resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} - engines: {node: '>=12'} - dependencies: - xml-name-validator: 4.0.0 - dev: true - - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true - - /webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: true - - /whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} - dependencies: - iconv-lite: 0.6.3 - dev: true - - /whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - dev: true - - /whatwg-url@10.0.0: - resolution: {integrity: sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: true - - /whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: true - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - - /xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - dev: true - - /xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: true - - /xmlcreate@2.0.4: - resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} - dev: true - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + + /function-bind@1.1.2: + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } + dev: true + + /gensync@1.0.0-beta.2: + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: '>=6.9.0' } + dev: true + + /get-caller-file@2.0.5: + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + dev: true + + /get-intrinsic@1.3.0: + resolution: + { + integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, + } + engines: { node: '>= 0.4' } + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + dev: true + + /get-package-type@0.1.0: + resolution: + { + integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, + } + engines: { node: '>=8.0.0' } + dev: true + + /get-proto@1.0.1: + resolution: + { + integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, + } + engines: { node: '>= 0.4' } + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + dev: true + + /get-stream@6.0.1: + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: '>=10' } + dev: true + + /glob@7.2.3: + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /gopd@1.2.0: + resolution: + { + integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, + } + engines: { node: '>= 0.4' } + dev: true + + /graceful-fs@4.2.11: + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } + dev: true + + /has-flag@4.0.0: + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: '>=8' } + dev: true + + /has-symbols@1.1.0: + resolution: + { + integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, + } + engines: { node: '>= 0.4' } + dev: true + + /has-tostringtag@1.0.2: + resolution: + { + integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, + } + engines: { node: '>= 0.4' } + dependencies: + has-symbols: 1.1.0 + dev: true + + /hasown@2.0.2: + resolution: + { + integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, + } + engines: { node: '>= 0.4' } + dependencies: + function-bind: 1.1.2 + dev: true + + /he@1.2.0: + resolution: + { + integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, + } + hasBin: true + dev: true + + /html-encoding-sniffer@3.0.0: + resolution: + { + integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==, + } + engines: { node: '>=12' } + dependencies: + whatwg-encoding: 2.0.0 + dev: true + + /html-escaper@2.0.2: + resolution: + { + integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, + } + dev: true + + /http-proxy-agent@5.0.0: + resolution: + { + integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==, + } + engines: { node: '>= 6' } + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /http-proxy@1.18.1: + resolution: + { + integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==, + } + engines: { node: '>=8.0.0' } + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: true + + /http-server@14.1.1: + resolution: + { + integrity: sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==, + } + engines: { node: '>=12' } + hasBin: true + dependencies: + basic-auth: 2.0.1 + chalk: 4.1.2 + corser: 2.0.1 + he: 1.2.0 + html-encoding-sniffer: 3.0.0 + http-proxy: 1.18.1 + mime: 1.6.0 + minimist: 1.2.8 + opener: 1.5.2 + portfinder: 1.0.37 + secure-compare: 3.0.1 + union: 0.5.0 + url-join: 4.0.1 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: '>= 6' } + dependencies: + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: + { + integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, + } + engines: { node: '>=10.17.0' } + dev: true + + /iconv-lite@0.6.3: + resolution: + { + integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, + } + engines: { node: '>=0.10.0' } + dependencies: + safer-buffer: 2.1.2 + dev: true + + /import-local@3.2.0: + resolution: + { + integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, + } + engines: { node: '>=8' } + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: '>=0.8.19' } + dev: true + + /inflight@1.0.6: + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + dev: true + + /is-arrayish@0.2.1: + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } + dev: true + + /is-core-module@2.16.1: + resolution: + { + integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==, + } + engines: { node: '>= 0.4' } + dependencies: + hasown: 2.0.2 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } + dev: true + + /is-generator-fn@2.1.0: + resolution: + { + integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, + } + engines: { node: '>=6' } + dev: true + + /is-number@7.0.0: + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: '>=0.12.0' } + dev: true + + /is-potential-custom-element-name@1.0.1: + resolution: + { + integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, + } + dev: true + + /is-stream@2.0.1: + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: '>=8' } + dev: true + + /isexe@2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: + { + integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, + } + engines: { node: '>=8' } + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: + { + integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, + } + engines: { node: '>=8' } + dependencies: + '@babel/core': 7.28.0 + '@babel/parser': 7.28.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.1: + resolution: + { + integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, + } + engines: { node: '>=10' } + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: + { + integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, + } + engines: { node: '>=10' } + dependencies: + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.7: + resolution: + { + integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, + } + engines: { node: '>=8' } + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jest-changed-files@28.1.3: + resolution: + { + integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + execa: 5.1.1 + p-limit: 3.1.0 + dev: true + + /jest-circus@28.1.3: + resolution: + { + integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/environment': 28.1.3 + '@jest/expect': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-runtime: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + p-limit: 3.1.0 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-cli@28.1.3: + resolution: + { + integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.2.0 + jest-config: 28.1.3(@types/node@24.2.1) + jest-util: 28.1.3 + jest-validate: 28.1.3 + prompts: 2.4.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest-config@28.1.3(@types/node@24.2.1): + resolution: + { + integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.28.0 + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + babel-jest: 28.1.3(@babel/core@7.28.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 28.1.3 + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 28.1.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-diff@28.1.3: + resolution: + { + integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + chalk: 4.1.2 + diff-sequences: 28.1.1 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-docblock@28.1.1: + resolution: + { + integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@28.1.3: + resolution: + { + integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + chalk: 4.1.2 + jest-get-type: 28.0.2 + jest-util: 28.1.3 + pretty-format: 28.1.3 + dev: true + + /jest-environment-jsdom@28.1.3: + resolution: + { + integrity: sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/jsdom': 16.2.15 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + jest-util: 28.1.3 + jsdom: 19.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node@28.1.3: + resolution: + { + integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + jest-mock: 28.1.3 + jest-util: 28.1.3 + dev: true + + /jest-get-type@28.0.2: + resolution: + { + integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dev: true + + /jest-haste-map@28.1.3: + resolution: + { + integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 24.2.1 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + jest-worker: 28.1.3 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-leak-detector@28.1.3: + resolution: + { + integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-matcher-utils@28.1.3: + resolution: + { + integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + chalk: 4.1.2 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + dev: true + + /jest-message-util@28.1.3: + resolution: + { + integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 28.1.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@28.1.3: + resolution: + { + integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@28.1.3): + resolution: + { + integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, + } + engines: { node: '>=6' } + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 28.1.3 + dev: true + + /jest-regex-util@28.0.2: + resolution: + { + integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dev: true + + /jest-resolve-dependencies@28.1.3: + resolution: + { + integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + jest-regex-util: 28.0.2 + jest-snapshot: 28.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@28.1.3: + resolution: + { + integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-pnp-resolver: 1.2.3(jest-resolve@28.1.3) + jest-util: 28.1.3 + jest-validate: 28.1.3 + resolve: 1.22.10 + resolve.exports: 1.1.1 + slash: 3.0.0 + dev: true + + /jest-runner@28.1.3: + resolution: + { + integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/console': 28.1.3 + '@jest/environment': 28.1.3 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + emittery: 0.10.2 + graceful-fs: 4.2.11 + jest-docblock: 28.1.1 + jest-environment-node: 28.1.3 + jest-haste-map: 28.1.3 + jest-leak-detector: 28.1.3 + jest-message-util: 28.1.3 + jest-resolve: 28.1.3 + jest-runtime: 28.1.3 + jest-util: 28.1.3 + jest-watcher: 28.1.3 + jest-worker: 28.1.3 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@28.1.3: + resolution: + { + integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/environment': 28.1.3 + '@jest/fake-timers': 28.1.3 + '@jest/globals': 28.1.3 + '@jest/source-map': 28.1.2 + '@jest/test-result': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + execa: 5.1.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-message-util: 28.1.3 + jest-mock: 28.1.3 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-snapshot: 28.1.3 + jest-util: 28.1.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot@28.1.3: + resolution: + { + integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@babel/core': 7.28.0 + '@babel/generator': 7.28.0 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + '@jest/expect-utils': 28.1.3 + '@jest/transform': 28.1.3 + '@jest/types': 28.1.3 + '@types/babel__traverse': 7.28.0 + '@types/prettier': 2.7.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) + chalk: 4.1.2 + expect: 28.1.3 + graceful-fs: 4.2.11 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + jest-haste-map: 28.1.3 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + natural-compare: 1.4.0 + pretty-format: 28.1.3 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@28.1.3: + resolution: + { + integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@28.1.3: + resolution: + { + integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/types': 28.1.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 28.0.2 + leven: 3.1.0 + pretty-format: 28.1.3 + dev: true + + /jest-watcher@28.1.3: + resolution: + { + integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.10.2 + jest-util: 28.1.3 + string-length: 4.0.2 + dev: true + + /jest-worker@28.1.3: + resolution: + { + integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@types/node': 24.2.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@28.1.3: + resolution: + { + integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/types': 28.1.3 + import-local: 3.2.0 + jest-cli: 28.1.3 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /js-cleanup@1.2.0: + resolution: + { + integrity: sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==, + } + engines: { node: ^10.14.2 || >=12.0.0 } + dependencies: + magic-string: 0.25.9 + perf-regexes: 1.0.1 + skip-regex: 1.0.2 + dev: true + + /js-tokens@4.0.0: + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } + dev: true + + /js-yaml@3.14.1: + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js2xmlparser@4.0.2: + resolution: + { + integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==, + } + dependencies: + xmlcreate: 2.0.4 + dev: true + + /jsdoc@3.6.11: + resolution: + { + integrity: sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==, + } + engines: { node: '>=12.0.0' } + hasBin: true + dependencies: + '@babel/parser': 7.28.0 + '@types/markdown-it': 12.2.3 + bluebird: 3.7.2 + catharsis: 0.9.0 + escape-string-regexp: 2.0.0 + js2xmlparser: 4.0.2 + klaw: 3.0.0 + markdown-it: 12.3.2 + markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) + marked: 4.3.0 + mkdirp: 1.0.4 + requizzle: 0.2.4 + strip-json-comments: 3.1.1 + taffydb: 2.6.2 + underscore: 1.13.7 + dev: true + + /jsdom@19.0.0: + resolution: + { + integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==, + } + engines: { node: '>=12' } + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.15.0 + acorn-globals: 6.0.0 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.6.0 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.4 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.21 + parse5: 6.0.1 + saxes: 5.0.1 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 3.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 10.0.0 + ws: 8.18.3 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc@3.1.0: + resolution: + { + integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, + } + engines: { node: '>=6' } + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } + dev: true + + /json5@2.2.3: + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: '>=6' } + hasBin: true + dev: true + + /klaw@3.0.0: + resolution: + { + integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==, + } + dependencies: + graceful-fs: 4.2.11 + dev: true + + /kleur@3.0.3: + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: '>=6' } + dev: true + + /leven@3.1.0: + resolution: + { + integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, + } + engines: { node: '>=6' } + dev: true + + /lines-and-columns@1.2.4: + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } + dev: true + + /linkify-it@3.0.3: + resolution: + { + integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==, + } + dependencies: + uc.micro: 1.0.6 + dev: true + + /locate-path@5.0.0: + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: '>=8' } + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash@4.17.21: + resolution: + { + integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, + } + dev: true + + /lru-cache@5.1.1: + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } + dependencies: + yallist: 3.1.1 + dev: true + + /magic-string@0.25.9: + resolution: + { + integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==, + } + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /make-dir@4.0.0: + resolution: + { + integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, + } + engines: { node: '>=10' } + dependencies: + semver: 7.7.2 + dev: true + + /makeerror@1.0.12: + resolution: + { + integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, + } + dependencies: + tmpl: 1.0.5 + dev: true + + /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): + resolution: + { + integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==, + } + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + dependencies: + '@types/markdown-it': 12.2.3 + markdown-it: 12.3.2 + dev: true + + /markdown-it@12.3.2: + resolution: + { + integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==, + } + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: true + + /marked@4.3.0: + resolution: + { + integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==, + } + engines: { node: '>= 12' } + hasBin: true + dev: true + + /math-intrinsics@1.1.0: + resolution: + { + integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, + } + engines: { node: '>= 0.4' } + dev: true + + /mdurl@1.0.1: + resolution: + { + integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==, + } + dev: true + + /merge-stream@2.0.0: + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } + dev: true + + /micromatch@4.0.8: + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, + } + engines: { node: '>=8.6' } + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: '>= 0.6' } + dev: true + + /mime-types@2.1.35: + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: '>= 0.6' } + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: + { + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, + } + engines: { node: '>=4' } + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: '>=6' } + dev: true + + /minimatch@3.1.2: + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } + dependencies: + brace-expansion: 1.1.12 + dev: true + + /minimist@1.2.8: + resolution: + { + integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, + } + dev: true + + /mkdirp@1.0.4: + resolution: + { + integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==, + } + engines: { node: '>=10' } + hasBin: true + dev: true + + /ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + dev: true + + /natural-compare@1.4.0: + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } + dev: true + + /node-int64@0.4.0: + resolution: + { + integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, + } + dev: true + + /node-releases@2.0.19: + resolution: + { + integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==, + } + dev: true + + /normalize-path@3.0.0: + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: '>=0.10.0' } + dev: true + + /npm-run-path@4.0.1: + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: '>=8' } + dependencies: + path-key: 3.1.1 + dev: true + + /nwsapi@2.2.21: + resolution: + { + integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==, + } + dev: true + + /object-inspect@1.13.4: + resolution: + { + integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, + } + engines: { node: '>= 0.4' } + dev: true + + /once@1.4.0: + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: '>=6' } + dependencies: + mimic-fn: 2.1.0 + dev: true + + /opener@1.5.2: + resolution: + { + integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==, + } + hasBin: true + dev: true + + /p-limit@2.3.0: + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: '>=6' } + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: '>=10' } + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: '>=8' } + dependencies: + p-limit: 2.3.0 + dev: true + + /p-try@2.2.0: + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: '>=6' } + dev: true + + /parse-json@5.2.0: + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: '>=8' } + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse5@6.0.1: + resolution: + { + integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==, + } + dev: true + + /path-exists@4.0.0: + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: '>=8' } + dev: true + + /path-is-absolute@1.0.1: + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: '>=0.10.0' } + dev: true + + /path-key@3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } + dev: true + + /path-parse@1.0.7: + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } + dev: true + + /perf-regexes@1.0.1: + resolution: + { + integrity: sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==, + } + engines: { node: '>=6.14' } + dev: true + + /picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + dev: true + + /picomatch@2.3.1: + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: '>=8.6' } + dev: true + + /pirates@4.0.7: + resolution: + { + integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==, + } + engines: { node: '>= 6' } + dev: true + + /pkg-dir@4.2.0: + resolution: + { + integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, + } + engines: { node: '>=8' } + dependencies: + find-up: 4.1.0 + dev: true + + /portfinder@1.0.37: + resolution: + { + integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==, + } + engines: { node: '>= 10.12' } + dependencies: + async: 3.2.6 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /prettier@2.6.2: + resolution: + { + integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==, + } + engines: { node: '>=10.13.0' } + hasBin: true + dev: true + + /pretty-format@28.1.3: + resolution: + { + integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==, + } + engines: { node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0 } + dependencies: + '@jest/schemas': 28.1.3 + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 18.3.1 + dev: true + + /prompts@2.4.2: + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: '>= 6' } + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /psl@1.15.0: + resolution: + { + integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==, + } + dependencies: + punycode: 2.3.1 + dev: true + + /punycode@2.3.1: + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: '>=6' } + dev: true + + /qs@6.14.0: + resolution: + { + integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==, + } + engines: { node: '>=0.6' } + dependencies: + side-channel: 1.1.0 + dev: true + + /querystringify@2.2.0: + resolution: + { + integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, + } + dev: true + + /randombytes@2.1.0: + resolution: + { + integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==, + } + dependencies: + safe-buffer: 5.2.1 + dev: true + + /react-is@18.3.1: + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } + dev: true + + /require-directory@2.1.1: + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: '>=0.10.0' } + dev: true + + /requires-port@1.0.0: + resolution: + { + integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, + } + dev: true + + /requizzle@0.2.4: + resolution: + { + integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==, + } + dependencies: + lodash: 4.17.21 + dev: true + + /resolve-cwd@3.0.0: + resolution: + { + integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, + } + engines: { node: '>=8' } + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from@5.0.0: + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: '>=8' } + dev: true + + /resolve.exports@1.1.1: + resolution: + { + integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==, + } + engines: { node: '>=10' } + dev: true + + /resolve@1.22.10: + resolution: + { + integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==, + } + engines: { node: '>= 0.4' } + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /rimraf@3.0.2: + resolution: + { + integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, + } + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-cleanup@3.2.1(rollup@2.79.2): + resolution: + { + integrity: sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==, + } + engines: { node: ^10.14.2 || >=12.0.0 } + peerDependencies: + rollup: '>=2.0' + dependencies: + js-cleanup: 1.2.0 + rollup: 2.79.2 + rollup-pluginutils: 2.8.2 + dev: true + + /rollup-pluginutils@2.8.2: + resolution: + { + integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==, + } + dependencies: + estree-walker: 0.6.1 + dev: true + + /rollup@2.79.2: + resolution: + { + integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==, + } + engines: { node: '>=10.0.0' } + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /safe-buffer@5.1.2: + resolution: + { + integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, + } + dev: true + + /safe-buffer@5.2.1: + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } + dev: true + + /safer-buffer@2.1.2: + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } + dev: true + + /saxes@5.0.1: + resolution: + { + integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==, + } + engines: { node: '>=10' } + dependencies: + xmlchars: 2.2.0 + dev: true + + /secure-compare@3.0.1: + resolution: + { + integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==, + } + dev: true + + /semver@6.3.1: + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } + hasBin: true + dev: true + + /semver@7.7.2: + resolution: + { + integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==, + } + engines: { node: '>=10' } + hasBin: true + dev: true + + /serialize-javascript@6.0.2: + resolution: + { + integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, + } + dependencies: + randombytes: 2.1.0 + dev: true + + /shebang-command@2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: '>=8' } + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: '>=8' } + dev: true + + /side-channel-list@1.0.0: + resolution: + { + integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==, + } + engines: { node: '>= 0.4' } + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-map@1.0.1: + resolution: + { + integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, + } + engines: { node: '>= 0.4' } + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-weakmap@1.0.2: + resolution: + { + integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, + } + engines: { node: '>= 0.4' } + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: true + + /side-channel@1.1.0: + resolution: + { + integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==, + } + engines: { node: '>= 0.4' } + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: true + + /signal-exit@3.0.7: + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } + dev: true + + /sisteransi@1.0.5: + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } + dev: true + + /skip-regex@1.0.2: + resolution: + { + integrity: sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==, + } + engines: { node: '>=4.2' } + dev: true + + /slash@3.0.0: + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: '>=8' } + dev: true + + /smob@1.5.0: + resolution: + { + integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==, + } + dev: true + + /source-map-support@0.5.13: + resolution: + { + integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, + } + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-support@0.5.21: + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: '>=0.10.0' } + dev: true + + /sourcemap-codec@1.4.8: + resolution: + { + integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==, + } + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /sprintf-js@1.0.3: + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } + dev: true + + /stack-utils@2.0.6: + resolution: + { + integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, + } + engines: { node: '>=10' } + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /string-length@4.0.2: + resolution: + { + integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, + } + engines: { node: '>=10' } + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@4.0.0: + resolution: + { + integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, + } + engines: { node: '>=8' } + dev: true + + /strip-final-newline@2.0.0: + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: '>=6' } + dev: true + + /strip-json-comments@3.1.1: + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: '>=8' } + dev: true + + /supports-color@7.2.0: + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: '>=8' } + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: '>=10' } + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks@2.3.0: + resolution: + { + integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==, + } + engines: { node: '>=8' } + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: '>= 0.4' } + dev: true + + /symbol-tree@3.2.4: + resolution: + { + integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==, + } + dev: true + + /taffydb@2.6.2: + resolution: + { + integrity: sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==, + } + dev: true + + /terminal-link@2.1.1: + resolution: + { + integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==, + } + engines: { node: '>=8' } + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + dev: true + + /terser@5.43.1: + resolution: + { + integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==, + } + engines: { node: '>=10' } + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.10 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /test-exclude@6.0.0: + resolution: + { + integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, + } + engines: { node: '>=8' } + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /tmpl@1.0.5: + resolution: + { + integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, + } + dev: true + + /to-regex-range@5.0.1: + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: '>=8.0' } + dependencies: + is-number: 7.0.0 + dev: true + + /tough-cookie@4.1.4: + resolution: + { + integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==, + } + engines: { node: '>=6' } + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + + /tr46@3.0.0: + resolution: + { + integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==, + } + engines: { node: '>=12' } + dependencies: + punycode: 2.3.1 + dev: true + + /tsd-jsdoc@2.5.0(jsdoc@3.6.11): + resolution: + { + integrity: sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g==, + } + peerDependencies: + jsdoc: ^3.6.3 + dependencies: + jsdoc: 3.6.11 + typescript: 3.9.10 + dev: true + + /type-detect@4.0.8: + resolution: + { + integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, + } + engines: { node: '>=4' } + dev: true + + /type-fest@0.21.3: + resolution: + { + integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, + } + engines: { node: '>=10' } + dev: true + + /typescript@3.9.10: + resolution: + { + integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==, + } + engines: { node: '>=4.2.0' } + hasBin: true + dev: true + + /typescript@5.9.2: + resolution: + { + integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==, + } + engines: { node: '>=14.17' } + hasBin: true + dev: true + + /uc.micro@1.0.6: + resolution: + { + integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==, + } + dev: true + + /underscore@1.13.7: + resolution: + { + integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==, + } + dev: true + + /undici-types@7.10.0: + resolution: + { + integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==, + } + dev: true + + /union@0.5.0: + resolution: + { + integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==, + } + engines: { node: '>= 0.8.0' } + dependencies: + qs: 6.14.0 + dev: true + + /universalify@0.2.0: + resolution: + { + integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==, + } + engines: { node: '>= 4.0.0' } + dev: true + + /update-browserslist-db@1.1.3(browserslist@4.25.2): + resolution: + { + integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==, + } + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.25.2 + escalade: 3.2.0 + picocolors: 1.1.1 + dev: true + + /url-join@4.0.1: + resolution: + { + integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==, + } + dev: true + + /url-parse@1.5.10: + resolution: + { + integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, + } + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + /v8-to-istanbul@9.3.0: + resolution: + { + integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, + } + engines: { node: '>=10.12.0' } + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + + /w3c-hr-time@1.0.2: + resolution: + { + integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==, + } + deprecated: Use your platform's native performance.now() and performance.timeOrigin. + dependencies: + browser-process-hrtime: 1.0.0 + dev: true + + /w3c-xmlserializer@3.0.0: + resolution: + { + integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==, + } + engines: { node: '>=12' } + dependencies: + xml-name-validator: 4.0.0 + dev: true + + /walker@1.0.8: + resolution: + { + integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, + } + dependencies: + makeerror: 1.0.12 + dev: true + + /webidl-conversions@7.0.0: + resolution: + { + integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==, + } + engines: { node: '>=12' } + dev: true + + /whatwg-encoding@2.0.0: + resolution: + { + integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==, + } + engines: { node: '>=12' } + dependencies: + iconv-lite: 0.6.3 + dev: true + + /whatwg-mimetype@3.0.0: + resolution: + { + integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==, + } + engines: { node: '>=12' } + dev: true + + /whatwg-url@10.0.0: + resolution: + { + integrity: sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==, + } + engines: { node: '>=12' } + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + + /whatwg-url@11.0.0: + resolution: + { + integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==, + } + engines: { node: '>=12' } + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + + /which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: '>= 8' } + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: '>=10' } + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } + dev: true + + /write-file-atomic@4.0.2: + resolution: + { + integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /ws@8.18.3: + resolution: + { + integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==, + } + engines: { node: '>=10.0.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml-name-validator@4.0.0: + resolution: + { + integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, + } + engines: { node: '>=12' } + dev: true + + /xmlchars@2.2.0: + resolution: + { + integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==, + } + dev: true + + /xmlcreate@2.0.4: + resolution: + { + integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==, + } + dev: true + + /y18n@5.0.8: + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: '>=10' } + dev: true + + /yallist@3.1.1: + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } + dev: true + + /yargs-parser@21.1.1: + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: '>=12' } + dev: true + + /yargs@17.7.2: + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: '>=12' } + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: '>=10' } + dev: true diff --git a/src/jsmind.plugin.js b/src/jsmind.plugin.js index 739807c9..becd47f3 100644 --- a/src/jsmind.plugin.js +++ b/src/jsmind.plugin.js @@ -38,7 +38,7 @@ export function apply(jm, options) { }, 0); } -/** +/** * @param {import('./jsmind.js').default} jm * @param {Record} options */ function _apply(jm, options) { diff --git a/types/generated/jsmind.common.d.ts b/types/generated/jsmind.common.d.ts index f5bb9e9e..af91b37e 100644 --- a/types/generated/jsmind.common.d.ts +++ b/types/generated/jsmind.common.d.ts @@ -62,5 +62,5 @@ export type DirectionType = { left: number; center: number; right: number; - of: (dir: (string | number)) => number | undefined; + of: (dir: string | number) => number | undefined; }; diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts index 77f876d7..9a6c5a29 100644 --- a/types/generated/jsmind.d.ts +++ b/types/generated/jsmind.d.ts @@ -8,7 +8,7 @@ export default class jsMind { static mind: typeof Mind; static node: typeof Node; - static direction: import("./jsmind.common.js").DirectionType; + static direction: import('./jsmind.common.js').DirectionType; static event_type: { show: number; resize: number; @@ -50,13 +50,16 @@ export default class jsMind { * @param {object | null} mind * @returns {jsMind} */ - static show(options: import("./jsmind.option.js").JsMindRuntimeOptions, mind: object | null): jsMind; + static show( + options: import('./jsmind.option.js').JsMindRuntimeOptions, + mind: object | null + ): jsMind; /** * Create a jsMind instance. * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options */ - constructor(options: import("./jsmind.option.js").JsMindRuntimeOptions); - options: import("./jsmind.option.js").JsMindRuntimeOptions; + constructor(options: import('./jsmind.option.js').JsMindRuntimeOptions); + options: import('./jsmind.option.js').JsMindRuntimeOptions; version: string; initialized: boolean; mind: Mind; @@ -84,12 +87,12 @@ export default class jsMind { * Enable default event handle. * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle */ - enable_event_handle(event_handle: "mousedown" | "click" | "dblclick" | "mousewheel"): void; + enable_event_handle(event_handle: 'mousedown' | 'click' | 'dblclick' | 'mousewheel'): void; /** * Disable default event handle. * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle */ - disable_event_handle(event_handle: "mousedown" | "click" | "dblclick" | "mousewheel"): void; + disable_event_handle(event_handle: 'mousedown' | 'click' | 'dblclick' | 'mousewheel'): void; /** * Set theme name. * @param {string|null} theme @@ -110,7 +113,7 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node * @returns {boolean|void} */ - begin_edit(node: string | import("./jsmind.node.js").Node): boolean | void; + begin_edit(node: string | import('./jsmind.node.js').Node): boolean | void; /** End editing */ end_edit(): void; /** @@ -118,19 +121,19 @@ export default class jsMind { * @param {string | import('./jsmind.node.js').Node} node * @returns {void} */ - toggle_node(node: string | import("./jsmind.node.js").Node): void; + toggle_node(node: string | import('./jsmind.node.js').Node): void; /** * Expand a node. * @param {string | import('./jsmind.node.js').Node} node * @returns {void} */ - expand_node(node: string | import("./jsmind.node.js").Node): void; + expand_node(node: string | import('./jsmind.node.js').Node): void; /** * Collapse a node. * @param {string | import('./jsmind.node.js').Node} node * @returns {void} */ - collapse_node(node: string | import("./jsmind.node.js").Node): void; + collapse_node(node: string | import('./jsmind.node.js').Node): void; /** Expand all nodes */ expand_all(): void; /** Collapse all nodes */ @@ -162,14 +165,14 @@ export default class jsMind { * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] * @returns {object} */ - get_data(data_format?: "node_tree" | "node_array" | "freemind" | "text"): object; + get_data(data_format?: 'node_tree' | 'node_array' | 'freemind' | 'text'): object; /** @returns {import('./jsmind.node.js').Node} */ - get_root(): import("./jsmind.node.js").Node; + get_root(): import('./jsmind.node.js').Node; /** * @param {string | import('./jsmind.node.js').Node} node * @returns {import('./jsmind.node.js').Node} */ - get_node(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node; + get_node(node: string | import('./jsmind.node.js').Node): import('./jsmind.node.js').Node; /** * Add a node under parent. * @param {string | import('./jsmind.node.js').Node} parent_node @@ -179,7 +182,13 @@ export default class jsMind { * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ - add_node(parent_node: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + add_node( + parent_node: string | import('./jsmind.node.js').Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined + ): import('./jsmind.node.js').Node | null; /** * Insert a node before target node. * @param {string | import('./jsmind.node.js').Node} node_before @@ -189,7 +198,13 @@ export default class jsMind { * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ - insert_node_before(node_before: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + insert_node_before( + node_before: string | import('./jsmind.node.js').Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined + ): import('./jsmind.node.js').Node | null; /** * Insert a node after target node. * @param {string | import('./jsmind.node.js').Node} node_after @@ -199,13 +214,19 @@ export default class jsMind { * @param {number=} direction * @returns {import('./jsmind.node.js').Node|null} */ - insert_node_after(node_after: string | import("./jsmind.node.js").Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): import("./jsmind.node.js").Node | null; + insert_node_after( + node_after: string | import('./jsmind.node.js').Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined + ): import('./jsmind.node.js').Node | null; /** * Remove a node. * @param {string | import('./jsmind.node.js').Node} node * @returns {boolean} */ - remove_node(node: string | import("./jsmind.node.js").Node): boolean; + remove_node(node: string | import('./jsmind.node.js').Node): boolean; /** @param {string} node_id @param {string} topic */ update_node(node_id: string, topic: string): void; /** @@ -215,40 +236,53 @@ export default class jsMind { * @param {string=} parent_id * @param {number=} direction */ - move_node(node_id: string, before_id?: string | undefined, parent_id?: string | undefined, direction?: number | undefined): void; + move_node( + node_id: string, + before_id?: string | undefined, + parent_id?: string | undefined, + direction?: number | undefined + ): void; /** * @param {string | import('./jsmind.node.js').Node} node * @returns {void} */ - select_node(node: string | import("./jsmind.node.js").Node): void; + select_node(node: string | import('./jsmind.node.js').Node): void; /** @returns {import('./jsmind.node.js').Node|null} */ - get_selected_node(): import("./jsmind.node.js").Node | null; + get_selected_node(): import('./jsmind.node.js').Node | null; /** clear selection */ select_clear(): void; /** @param {string | import('./jsmind.node.js').Node} node */ - is_node_visible(node: string | import("./jsmind.node.js").Node): boolean; + is_node_visible(node: string | import('./jsmind.node.js').Node): boolean; /** @param {string | import('./jsmind.node.js').Node} node */ - scroll_node_to_center(node: string | import("./jsmind.node.js").Node): void; + scroll_node_to_center(node: string | import('./jsmind.node.js').Node): void; /** * Find the previous sibling node of the given node. * * @param {string | import('./jsmind.node.js').Node} node - Node id or Node instance * @returns {import('./jsmind.node.js').Node | null} */ - find_node_before(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; + find_node_before( + node: string | import('./jsmind.node.js').Node + ): import('./jsmind.node.js').Node | null; /** * Find the next sibling node of the given node. * @param {string | import('./jsmind.node.js').Node} node * @returns {import('./jsmind.node.js').Node | null} */ - find_node_after(node: string | import("./jsmind.node.js").Node): import("./jsmind.node.js").Node | null; + find_node_after( + node: string | import('./jsmind.node.js').Node + ): import('./jsmind.node.js').Node | null; /** * @param {string} node_id * @param {string=} bg_color * @param {string=} fg_color * @returns {void} */ - set_node_color(node_id: string, bg_color?: string | undefined, fg_color?: string | undefined): void; + set_node_color( + node_id: string, + bg_color?: string | undefined, + fg_color?: string | undefined + ): void; /** * @param {string} node_id * @param {number=} size @@ -256,7 +290,12 @@ export default class jsMind { * @param {string=} style * @returns {void} */ - set_node_font_style(node_id: string, size?: number | undefined, weight?: string | undefined, style?: string | undefined): void; + set_node_font_style( + node_id: string, + size?: number | undefined, + weight?: string | undefined, + style?: string | undefined + ): void; /** * @param {string} node_id * @param {string} image @@ -265,7 +304,13 @@ export default class jsMind { * @param {number=} rotation * @returns {void} */ - set_node_background_image(node_id: string, image: string, width?: number | undefined, height?: number | undefined, rotation?: number | undefined): void; + set_node_background_image( + node_id: string, + image: string, + width?: number | undefined, + height?: number | undefined, + rotation?: number | undefined + ): void; /** * @param {string} node_id * @param {number} rotation diff --git a/types/generated/jsmind.data_provider.d.ts b/types/generated/jsmind.data_provider.d.ts index deffa5bc..489c06d4 100644 --- a/types/generated/jsmind.data_provider.d.ts +++ b/types/generated/jsmind.data_provider.d.ts @@ -3,8 +3,8 @@ export class DataProvider { * Data provider: loads and serializes mind data by format. * @param {import('./jsmind.js').default} jm - jsMind instance */ - constructor(jm: import("./jsmind.js").default); - jm: import("./jsmind.js").default; + constructor(jm: import('./jsmind.js').default); + jm: import('./jsmind.js').default; /** Initialize data provider. */ init(): void; /** Reset data provider state. */ @@ -14,43 +14,53 @@ export class DataProvider { * @param {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta?:{name:string,author:string,version:string},format:'freemind',data:string}|{meta?:{name:string,author:string,version:string},format:'text',data:string}} mind_data - object with {format,data} or a format-specific payload * @returns {import('./jsmind.mind.js').Mind|null} */ - load(mind_data: import("./jsmind.format.js").NodeTreeFormat | import("./jsmind.format.js").NodeArrayFormat | { - meta?: { - name: string; - author: string; - version: string; - }; - format: "freemind"; - data: string; - } | { - meta?: { - name: string; - author: string; - version: string; - }; - format: "text"; - data: string; - }): import("./jsmind.mind.js").Mind | null; + load( + mind_data: + | import('./jsmind.format.js').NodeTreeFormat + | import('./jsmind.format.js').NodeArrayFormat + | { + meta?: { + name: string; + author: string; + version: string; + }; + format: 'freemind'; + data: string; + } + | { + meta?: { + name: string; + author: string; + version: string; + }; + format: 'text'; + data: string; + } + ): import('./jsmind.mind.js').Mind | null; /** * Serialize current mind to target format. * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format * @returns {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta:{name:string,author:string,version:string},format:'freemind',data:string}|{meta:{name:string,author:string,version:string},format:'text',data:string}} */ - get_data(data_format: "node_tree" | "node_array" | "freemind" | "text"): import("./jsmind.format.js").NodeTreeFormat | import("./jsmind.format.js").NodeArrayFormat | { - meta: { - name: string; - author: string; - version: string; - }; - format: "freemind"; - data: string; - } | { - meta: { - name: string; - author: string; - version: string; - }; - format: "text"; - data: string; - }; + get_data(data_format: 'node_tree' | 'node_array' | 'freemind' | 'text'): + | import('./jsmind.format.js').NodeTreeFormat + | import('./jsmind.format.js').NodeArrayFormat + | { + meta: { + name: string; + author: string; + version: string; + }; + format: 'freemind'; + data: string; + } + | { + meta: { + name: string; + author: string; + version: string; + }; + format: 'text'; + data: string; + }; } diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts index 5d0b265a..1a98044b 100644 --- a/types/generated/jsmind.format.d.ts +++ b/types/generated/jsmind.format.d.ts @@ -21,34 +21,26 @@ export const format: { freemind: { example: { meta: MindMapMeta; - format: "freemind"; + format: 'freemind'; data: string; }; - get_mind: (src: { - meta?: MindMapMeta; - format: "freemind"; - data: string; - }) => Mind; + get_mind: (src: { meta?: MindMapMeta; format: 'freemind'; data: string }) => Mind; get_data: (mind: Mind) => { meta: MindMapMeta; - format: "freemind"; + format: 'freemind'; data: string; }; }; text: { example: { meta: MindMapMeta; - format: "text"; + format: 'text'; data: string; }; - get_mind: (src: { - meta?: MindMapMeta; - format: "text"; - data: string; - }) => Mind; + get_mind: (src: { meta?: MindMapMeta; format: 'text'; data: string }) => Mind; get_data: (mind: Mind) => { meta: MindMapMeta; - format: "text"; + format: 'text'; data: string; }; }; @@ -65,7 +57,7 @@ export type NodeTreeData = { id: string; topic: string; data?: Record; - direction?: (number | string); + direction?: number | string; expanded?: boolean; children?: NodeTreeData[]; }; @@ -74,7 +66,7 @@ export type NodeTreeData = { */ export type NodeTreeFormat = { meta?: MindMapMeta; - format: "node_tree"; + format: 'node_tree'; data: NodeTreeData; }; /** @@ -85,7 +77,7 @@ export type NodeArrayItem = { topic: string; parentid?: string; data?: Record; - direction?: (number | string); + direction?: number | string; expanded?: boolean; isroot?: boolean; }; @@ -94,7 +86,7 @@ export type NodeArrayItem = { */ export type NodeArrayFormat = { meta?: MindMapMeta; - format: "node_array"; + format: 'node_array'; data: NodeArrayItem[]; }; import { Mind } from './jsmind.mind.js'; diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts index 836d0f83..97ab46bd 100644 --- a/types/generated/jsmind.graph.d.ts +++ b/types/generated/jsmind.graph.d.ts @@ -4,7 +4,10 @@ * @param {'canvas'|'svg'} engine - Rendering engine type * @returns {SvgGraph|CanvasGraph} Graph renderer instance */ -export function init_graph(view: import("./jsmind.view_provider.js").ViewProvider, engine: "canvas" | "svg"): SvgGraph | CanvasGraph; +export function init_graph( + view: import('./jsmind.view_provider.js').ViewProvider, + engine: 'canvas' | 'svg' +): SvgGraph | CanvasGraph; /** * SVG-based graph renderer. */ @@ -15,20 +18,20 @@ declare class SvgGraph { * Create SVG graph renderer. * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance */ - constructor(view: import("./jsmind.view_provider.js").ViewProvider); - view: import("./jsmind.view_provider.js").ViewProvider; + constructor(view: import('./jsmind.view_provider.js').ViewProvider); + view: import('./jsmind.view_provider.js').ViewProvider; opts: { - engine: "canvas" | "svg"; + engine: 'canvas' | 'svg'; enable_device_pixel_ratio: boolean; hmargin: number; vmargin: number; line_width: number; line_color: string; - line_style: "curved" | "straight"; + line_style: 'curved' | 'straight'; custom_line_render?: Function; draggable: boolean; hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; + node_overflow: 'hidden' | 'wrap'; zoom: { min: number; max: number; @@ -36,7 +39,7 @@ declare class SvgGraph { mask_key: number; }; custom_node_render?: Function; - expander_style: "char" | "number"; + expander_style: 'char' | 'number'; }; e_svg: SVGElement; size: { @@ -59,16 +62,21 @@ declare class SvgGraph { set_size(w: number, h: number): void; clear(): void; /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ - draw_line(pout: { - x: number; - y: number; - }, pin: { - x: number; - y: number; - }, offset: { - x: number; - y: number; - }, color?: string | undefined): void; + draw_line( + pout: { + x: number; + y: number; + }, + pin: { + x: number; + y: number; + }, + offset: { + x: number; + y: number; + }, + color?: string | undefined + ): void; /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; /** @@ -100,19 +108,19 @@ declare class CanvasGraph { * Create canvas graph renderer. * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance */ - constructor(view: import("./jsmind.view_provider.js").ViewProvider); + constructor(view: import('./jsmind.view_provider.js').ViewProvider); opts: { - engine: "canvas" | "svg"; + engine: 'canvas' | 'svg'; enable_device_pixel_ratio: boolean; hmargin: number; vmargin: number; line_width: number; line_color: string; - line_style: "curved" | "straight"; + line_style: 'curved' | 'straight'; custom_line_render?: Function; draggable: boolean; hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; + node_overflow: 'hidden' | 'wrap'; zoom: { min: number; max: number; @@ -120,7 +128,7 @@ declare class CanvasGraph { mask_key: number; }; custom_node_render?: Function; - expander_style: "char" | "number"; + expander_style: 'char' | 'number'; }; e_canvas: HTMLElement; canvas_ctx: CanvasRenderingContext2D; @@ -129,14 +137,32 @@ declare class CanvasGraph { h: number; }; line_drawing: { - straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; - curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; + straight: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + curved: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; }; dpr: number; /** Choose line drawing renderer. */ init_line_render(): void; /** @type {(ctx:CanvasRenderingContext2D,x1:number,y1:number,x2:number,y2:number)=>void} */ - drawing: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; + drawing: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; /** @returns {HTMLCanvasElement} */ element(): HTMLCanvasElement; /** @param {number} w @param {number} h */ @@ -144,16 +170,21 @@ declare class CanvasGraph { /** Clear the canvas. */ clear(): void; /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ - draw_line(pout: { - x: number; - y: number; - }, pin: { - x: number; - y: number; - }, offset: { - x: number; - y: number; - }, color?: string | undefined): void; + draw_line( + pout: { + x: number; + y: number; + }, + pin: { + x: number; + y: number; + }, + offset: { + x: number; + y: number; + }, + color?: string | undefined + ): void; /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; /** diff --git a/types/generated/jsmind.layout_provider.d.ts b/types/generated/jsmind.layout_provider.d.ts index 2381b639..272e161e 100644 --- a/types/generated/jsmind.layout_provider.d.ts +++ b/types/generated/jsmind.layout_provider.d.ts @@ -4,21 +4,24 @@ export class LayoutProvider { * @param {import('./jsmind.js').default} jm - jsMind instance * @param {{mode:'full'|'side', hspace:number, vspace:number, pspace:number, cousin_space:number}} options - Layout configuration options */ - constructor(jm: import("./jsmind.js").default, options: { - mode: "full" | "side"; - hspace: number; - vspace: number; - pspace: number; - cousin_space: number; - }); + constructor( + jm: import('./jsmind.js').default, + options: { + mode: 'full' | 'side'; + hspace: number; + vspace: number; + pspace: number; + cousin_space: number; + } + ); opts: { - mode: "full" | "side"; + mode: 'full' | 'side'; hspace: number; vspace: number; pspace: number; cousin_space: number; }; - jm: import("./jsmind.js").default; + jm: import('./jsmind.js').default; isside: boolean; bounds: { n: number; @@ -36,7 +39,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node * @returns {number} */ - calculate_next_child_direction(node: import("./jsmind.node.js").Node): number; + calculate_next_child_direction(node: import('./jsmind.node.js').Node): number; /** Perform layout and offsets recalculation. */ layout(): void; /** Calculate and set direction for all nodes. */ @@ -82,7 +85,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node - Target node * @returns {{x:number, y:number}} Absolute position offset */ - get_node_offset(node: import("./jsmind.node.js").Node): { + get_node_offset(node: import('./jsmind.node.js').Node): { x: number; y: number; }; @@ -91,7 +94,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node - Target node * @returns {{x:number, y:number}} Anchor point coordinates */ - get_node_point(node: import("./jsmind.node.js").Node): { + get_node_point(node: import('./jsmind.node.js').Node): { x: number; y: number; }; @@ -100,7 +103,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node - Target node * @returns {{x:number, y:number}} Input point coordinates */ - get_node_point_in(node: import("./jsmind.node.js").Node): { + get_node_point_in(node: import('./jsmind.node.js').Node): { x: number; y: number; }; @@ -109,7 +112,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node - Target node * @returns {{x:number, y:number}} Output point coordinates */ - get_node_point_out(node: import("./jsmind.node.js").Node): { + get_node_point_out(node: import('./jsmind.node.js').Node): { x: number; y: number; }; @@ -118,7 +121,7 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node} node - Target node * @returns {{x:number, y:number}} Expander point coordinates */ - get_expander_point(node: import("./jsmind.node.js").Node): { + get_expander_point(node: import('./jsmind.node.js').Node): { x: number; y: number; }; @@ -134,17 +137,17 @@ export class LayoutProvider { * Toggle node expanded/collapsed state. * @param {import('./jsmind.node.js').Node} node - Target node */ - toggle_node(node: import("./jsmind.node.js").Node): void; + toggle_node(node: import('./jsmind.node.js').Node): void; /** * Expand a node and show its children. * @param {import('./jsmind.node.js').Node} node - Target node */ - expand_node(node: import("./jsmind.node.js").Node): void; + expand_node(node: import('./jsmind.node.js').Node): void; /** * Collapse a node and hide its children. * @param {import('./jsmind.node.js').Node} node - Target node */ - collapse_node(node: import("./jsmind.node.js").Node): void; + collapse_node(node: import('./jsmind.node.js').Node): void; /** Expand all nodes in the mind map. */ expand_all(): void; /** Collapse all nodes in the mind map. */ @@ -155,28 +158,32 @@ export class LayoutProvider { * @param {import('./jsmind.node.js').Node[]=} curr_nodes - Current nodes to process * @param {number=} curr_depth - Current depth level */ - expand_to_depth(target_depth: number, curr_nodes?: import("./jsmind.node.js").Node[] | undefined, curr_depth?: number | undefined): void; + expand_to_depth( + target_depth: number, + curr_nodes?: import('./jsmind.node.js').Node[] | undefined, + curr_depth?: number | undefined + ): void; /** * Perform partial layout for a node and its subtree. * @param {import('./jsmind.node.js').Node} node - Target node */ - part_layout(node: import("./jsmind.node.js").Node): void; + part_layout(node: import('./jsmind.node.js').Node): void; /** * Set visibility for nodes and their children. * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes * @param {boolean} visible - Visibility state */ - set_visible(nodes: import("./jsmind.node.js").Node[], visible: boolean): void; + set_visible(nodes: import('./jsmind.node.js').Node[], visible: boolean): void; /** * Check if a node is expanded. * @param {import('./jsmind.node.js').Node} node - Target node * @returns {boolean} True if node is expanded */ - is_expand(node: import("./jsmind.node.js").Node): boolean; + is_expand(node: import('./jsmind.node.js').Node): boolean; /** * Check if a node is visible. * @param {import('./jsmind.node.js').Node} node - Target node * @returns {boolean} True if node is visible */ - is_visible(node: import("./jsmind.node.js").Node): boolean; + is_visible(node: import('./jsmind.node.js').Node): boolean; } diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts index f648946e..4a9a3c66 100644 --- a/types/generated/jsmind.mind.d.ts +++ b/types/generated/jsmind.mind.d.ts @@ -36,7 +36,15 @@ export class Mind { * @param {number=} idx * @returns {Node | null} */ - add_node(parent_node: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined, expanded?: boolean | undefined, idx?: number | undefined): Node | null; + add_node( + parent_node: Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined, + expanded?: boolean | undefined, + idx?: number | undefined + ): Node | null; /** * Insert a node before target node. * @param {Node} node_before @@ -46,7 +54,13 @@ export class Mind { * @param {number=} direction * @returns {Node | null} */ - insert_node_before(node_before: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): Node | null; + insert_node_before( + node_before: Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined + ): Node | null; /** * Get previous sibling of a node or node id. * @param {string | Node} node @@ -62,7 +76,13 @@ export class Mind { * @param {number=} direction * @returns {Node | null} */ - insert_node_after(node_after: Node, node_id: string, topic: string, data?: Record | undefined, direction?: number | undefined): Node | null; + insert_node_after( + node_after: Node, + node_id: string, + topic: string, + data?: Record | undefined, + direction?: number | undefined + ): Node | null; /** * Get next sibling of a node or node id. * @param {string | Node} node @@ -77,7 +97,12 @@ export class Mind { * @param {number=} direction * @returns {Node | null} */ - move_node(node: Node, before_id?: string | undefined, parent_id?: string | undefined, direction?: number | undefined): Node | null; + move_node( + node: Node, + before_id?: string | undefined, + parent_id?: string | undefined, + direction?: number | undefined + ): Node | null; /** * Propagate direction to descendants. * @param {Node} node @@ -99,7 +124,12 @@ export class Mind { * @param {number=} direction * @returns {Node | null} */ - _move_node(node: Node, before_id: string, parent_id: string, direction?: number | undefined): Node | null; + _move_node( + node: Node, + before_id: string, + parent_id: string, + direction?: number | undefined + ): Node | null; /** * Remove a node from the mind. * @param {Node} node diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts index e2da323c..d1af95bf 100644 --- a/types/generated/jsmind.node.d.ts +++ b/types/generated/jsmind.node.d.ts @@ -30,7 +30,16 @@ export class Node { * @param {number=} eDirection - Direction for children under root (-1 left, 0 center, 1 right) * @param {boolean=} bExpanded - Expanded state */ - constructor(sId: string, iIndex: number, sTopic: string, oData?: Record | undefined, bIsRoot?: boolean | undefined, oParent?: (Node | null) | undefined, eDirection?: number | undefined, bExpanded?: boolean | undefined); + constructor( + sId: string, + iIndex: number, + sTopic: string, + oData?: Record | undefined, + bIsRoot?: boolean | undefined, + oParent?: (Node | null) | undefined, + eDirection?: number | undefined, + bExpanded?: boolean | undefined + ); id: string; index: number; topic: string; diff --git a/types/generated/jsmind.option.d.ts b/types/generated/jsmind.option.d.ts index 7e1d0438..e5d3b54e 100644 --- a/types/generated/jsmind.option.d.ts +++ b/types/generated/jsmind.option.d.ts @@ -7,40 +7,49 @@ export function merge_option(options: Partial): JsMindRunt export type JsMindRuntimeOptions = { container: string | HTMLElement; editable: boolean; - theme: (string | null); - mode: ("full" | "side"); + theme: string | null; + mode: 'full' | 'side'; support_html: boolean; - log_level: "debug" | "info" | "warn" | "error" | "disable"; + log_level: 'debug' | 'info' | 'warn' | 'error' | 'disable'; view: { - engine: "canvas" | "svg"; + engine: 'canvas' | 'svg'; enable_device_pixel_ratio: boolean; hmargin: number; vmargin: number; line_width: number; line_color: string; - line_style: "curved" | "straight"; - custom_line_render?: (this: object, arg: { - ctx: CanvasRenderingContext2D | SVGPathElement; - start_point: { - x: number; - y: number; - }; - end_point: { - x: number; - y: number; - }; - }) => void; + line_style: 'curved' | 'straight'; + custom_line_render?: ( + this: object, + arg: { + ctx: CanvasRenderingContext2D | SVGPathElement; + start_point: { + x: number; + y: number; + }; + end_point: { + x: number; + y: number; + }; + } + ) => void; draggable: boolean; hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; + node_overflow: 'hidden' | 'wrap'; zoom: { min: number; max: number; step: number; mask_key: number; }; - custom_node_render: (null | ((jm: import("./jsmind.js").default, ele: HTMLElement, node: import("./jsmind.node.js").Node) => void)); - expander_style: "char" | "number"; + custom_node_render: + | null + | (( + jm: import('./jsmind.js').default, + ele: HTMLElement, + node: import('./jsmind.node.js').Node + ) => void); + expander_style: 'char' | 'number'; }; layout: { hspace: number; @@ -56,7 +65,7 @@ export type JsMindRuntimeOptions = { }; shortcut: { enable: boolean; - handles: Record void>; + handles: Record void>; mapping: Record; id_generator?: () => string; }; diff --git a/types/generated/jsmind.plugin.d.ts b/types/generated/jsmind.plugin.d.ts index 86f078ba..af058080 100644 --- a/types/generated/jsmind.plugin.d.ts +++ b/types/generated/jsmind.plugin.d.ts @@ -8,14 +8,17 @@ export function register(plugin: Plugin): void; * @param {import('./jsmind.js').default} jm * @param {Record} options */ -export function apply(jm: import("./jsmind.js").default, options: Record): void; +export function apply(jm: import('./jsmind.js').default, options: Record): void; export class Plugin { /** * @template [TOptions=object] * @param {string} name * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init */ - constructor(name: string, fn_init: (jm: import("./jsmind.js").default, options: TOptions) => void); + constructor( + name: string, + fn_init: (jm: import('./jsmind.js').default, options: TOptions) => void + ); name: string; - fn_init: (jm: import("./jsmind.js").default, options: TOptions) => void; + fn_init: (jm: import('./jsmind.js').default, options: TOptions) => void; } diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts index c07a73b2..99cc4ddd 100644 --- a/types/generated/jsmind.shortcut_provider.d.ts +++ b/types/generated/jsmind.shortcut_provider.d.ts @@ -3,50 +3,53 @@ export class ShortcutProvider { * @param {import('./jsmind.js').default} jm * @param {{ enable:boolean, handles: Recordvoid>, mapping: Record, id_generator?: ()=>string }} options */ - constructor(jm: import("./jsmind.js").default, options: { - enable: boolean; - handles: Record void>; - mapping: Record; - id_generator?: () => string; - }); - jm: import("./jsmind.js").default; + constructor( + jm: import('./jsmind.js').default, + options: { + enable: boolean; + handles: Record void>; + mapping: Record; + id_generator?: () => string; + } + ); + jm: import('./jsmind.js').default; opts: { enable: boolean; - handles: Record void>; + handles: Record void>; mapping: Record; id_generator?: () => string; }; /** @type {Record} */ mapping: Record; /** @type {Recordvoid>} */ - handles: Record void>; + handles: Record void>; /** @type {()=>string|null} */ _newid: () => string | null; /** @type {Recordvoid>} */ - _mapping: Record void>; + _mapping: Record void>; init(): void; enable_shortcut(): void; disable_shortcut(): void; /** @param {KeyboardEvent} e */ handler(e: KeyboardEvent): boolean; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_addchild(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_addchild(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_addbrother(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_addbrother(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_editnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_editnode(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_delnode(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_delnode(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_toggle(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_toggle(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_up(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_up(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_down(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_down(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_left(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_left(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_right(_jm: import("./jsmind.js").default, e: KeyboardEvent): void; + handle_right(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e @param {number} d */ - _handle_direction(_jm: import("./jsmind.js").default, e: KeyboardEvent, d: number): void; + _handle_direction(_jm: import('./jsmind.js').default, e: KeyboardEvent, d: number): void; } diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts index ef7833d4..e126883b 100644 --- a/types/generated/jsmind.view_provider.d.ts +++ b/types/generated/jsmind.view_provider.d.ts @@ -19,39 +19,42 @@ export class ViewProvider { * expander_style: 'char'|'number' * }} options - View configuration options */ - constructor(jm: import("./jsmind.js").default, options: { - engine: "canvas" | "svg"; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: "curved" | "straight"; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: "char" | "number"; - }); + constructor( + jm: import('./jsmind.js').default, + options: { + engine: 'canvas' | 'svg'; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: 'curved' | 'straight'; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: 'hidden' | 'wrap'; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: 'char' | 'number'; + } + ); opts: { - engine: "canvas" | "svg"; + engine: 'canvas' | 'svg'; enable_device_pixel_ratio: boolean; hmargin: number; vmargin: number; line_width: number; line_color: string; - line_style: "curved" | "straight"; + line_style: 'curved' | 'straight'; custom_line_render?: Function; draggable: boolean; hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; + node_overflow: 'hidden' | 'wrap'; zoom: { min: number; max: number; @@ -59,10 +62,10 @@ export class ViewProvider { mask_key: number; }; custom_node_render?: Function; - expander_style: "char" | "number"; + expander_style: 'char' | 'number'; }; - jm: import("./jsmind.js").default; - layout: import("./jsmind.layout_provider.js").LayoutProvider; + jm: import('./jsmind.js').default; + layout: import('./jsmind.layout_provider.js').LayoutProvider; container: HTMLElement; e_panel: HTMLElement; e_nodes: HTMLElement; @@ -70,112 +73,184 @@ export class ViewProvider { w: number; h: number; }; - selected_node: import("./jsmind.node.js").Node; - editing_node: import("./jsmind.node.js").Node; - graph: { - view: ViewProvider; - opts: { - engine: "canvas" | "svg"; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: "curved" | "straight"; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: "char" | "number"; - }; - e_svg: SVGElement; - size: { - w: number; - h: number; - }; - lines: SVGPathElement[]; - line_drawing: { - straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - }; - init_line_render(): void; - drawing: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - element(): SVGSVGElement; - set_size(w: number, h: number): void; - clear(): void; - draw_line(pout: { - x: number; - y: number; - }, pin: { - x: number; - y: number; - }, offset: { - x: number; - y: number; - }, color?: string | undefined): void; - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; - _bezier_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; - _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; - } | { - opts: { - engine: "canvas" | "svg"; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: "curved" | "straight"; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: "hidden" | "wrap"; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: "char" | "number"; - }; - e_canvas: HTMLElement; - canvas_ctx: CanvasRenderingContext2D; - size: { - w: number; - h: number; - }; - line_drawing: { - straight: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; - curved: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; - }; - dpr: number; - init_line_render(): void; - drawing: (ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number) => void; - element(): HTMLCanvasElement; - set_size(w: number, h: number): void; - clear(): void; - draw_line(pout: { - x: number; - y: number; - }, pin: { - x: number; - y: number; - }, offset: { - x: number; - y: number; - }, color?: string | undefined): void; - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; - _bezier_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; - _line_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; - }; - render_node: (ele: HTMLElement, node: import("./jsmind.node.js").Node) => void; + selected_node: import('./jsmind.node.js').Node; + editing_node: import('./jsmind.node.js').Node; + graph: + | { + view: ViewProvider; + opts: { + engine: 'canvas' | 'svg'; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: 'curved' | 'straight'; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: 'hidden' | 'wrap'; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: 'char' | 'number'; + }; + e_svg: SVGElement; + size: { + w: number; + h: number; + }; + lines: SVGPathElement[]; + line_drawing: { + straight: ( + path: SVGPathElement, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + curved: ( + path: SVGPathElement, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + }; + init_line_render(): void; + drawing: ( + path: SVGPathElement, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + element(): SVGSVGElement; + set_size(w: number, h: number): void; + clear(): void; + draw_line( + pout: { + x: number; + y: number; + }, + pin: { + x: number; + y: number; + }, + offset: { + x: number; + y: number; + }, + color?: string | undefined + ): void; + copy_to( + dest_canvas_ctx: CanvasRenderingContext2D, + callback?: (() => void) | undefined + ): void; + _bezier_to( + path: SVGPathElement, + x1: number, + y1: number, + x2: number, + y2: number + ): void; + _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; + } + | { + opts: { + engine: 'canvas' | 'svg'; + enable_device_pixel_ratio: boolean; + hmargin: number; + vmargin: number; + line_width: number; + line_color: string; + line_style: 'curved' | 'straight'; + custom_line_render?: Function; + draggable: boolean; + hide_scrollbars_when_draggable: boolean; + node_overflow: 'hidden' | 'wrap'; + zoom: { + min: number; + max: number; + step: number; + mask_key: number; + }; + custom_node_render?: Function; + expander_style: 'char' | 'number'; + }; + e_canvas: HTMLElement; + canvas_ctx: CanvasRenderingContext2D; + size: { + w: number; + h: number; + }; + line_drawing: { + straight: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + curved: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + }; + dpr: number; + init_line_render(): void; + drawing: ( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ) => void; + element(): HTMLCanvasElement; + set_size(w: number, h: number): void; + clear(): void; + draw_line( + pout: { + x: number; + y: number; + }, + pin: { + x: number; + y: number; + }, + offset: { + x: number; + y: number; + }, + color?: string | undefined + ): void; + copy_to( + dest_canvas_ctx: CanvasRenderingContext2D, + callback?: (() => void) | undefined + ): void; + _bezier_to( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ): void; + _line_to( + ctx: CanvasRenderingContext2D, + x1: number, + y1: number, + x2: number, + y2: number + ): void; + }; + render_node: (ele: HTMLElement, node: import('./jsmind.node.js').Node) => void; zoom_current: number; device_pixel_ratio: number; _initialized: boolean; @@ -189,7 +264,12 @@ export class ViewProvider { * @param {(e:Event)=>void} event_handle * @param {boolean=} capture_by_panel */ - add_event(obj: import("./jsmind.js").default, event_name: string, event_handle: (e: Event) => void, capture_by_panel?: boolean | undefined): void; + add_event( + obj: import('./jsmind.js').default, + event_name: string, + event_handle: (e: Event) => void, + capture_by_panel?: boolean | undefined + ): void; /** * @param {HTMLElement|null} element * @returns {string|null} @@ -217,14 +297,14 @@ export class ViewProvider { * Initialize size data for a node. * @param {import('./jsmind.node.js').Node} node - Target node */ - init_nodes_size(node: import("./jsmind.node.js").Node): void; + init_nodes_size(node: import('./jsmind.node.js').Node): void; /** Initialize DOM elements for all nodes. */ init_nodes(): void; /** * Add a new node to the view. * @param {import('./jsmind.node.js').Node} node - Node to add */ - add_node(node: import("./jsmind.node.js").Node): void; + add_node(node: import('./jsmind.node.js').Node): void; /** * Run function in compatibility mode if container is not visible. * @param {Function} func - Function to execute @@ -235,29 +315,29 @@ export class ViewProvider { * @param {import('./jsmind.node.js').Node} node * @param {HTMLElement} parent_node */ - create_node_element(node: import("./jsmind.node.js").Node, parent_node: HTMLElement): void; + create_node_element(node: import('./jsmind.node.js').Node, parent_node: HTMLElement): void; /** * Remove a node from the view. * @param {import('./jsmind.node.js').Node} node - Node to remove */ - remove_node(node: import("./jsmind.node.js").Node): void; + remove_node(node: import('./jsmind.node.js').Node): void; /** * Update a node's display. * @param {import('./jsmind.node.js').Node} node - Node to update */ - update_node(node: import("./jsmind.node.js").Node): void; + update_node(node: import('./jsmind.node.js').Node): void; /** * Select a node visually. * @param {import('./jsmind.node.js').Node|null} node - Node to select */ - select_node(node: import("./jsmind.node.js").Node | null): void; + select_node(node: import('./jsmind.node.js').Node | null): void; /** Clear node selection. */ select_clear(): void; /** * Get currently editing node. * @returns {import('./jsmind.node.js').Node|null} Currently editing node */ - get_editing_node(): import("./jsmind.node.js").Node | null; + get_editing_node(): import('./jsmind.node.js').Node | null; /** * Check if any node is being edited. * @returns {boolean} True if editing @@ -267,7 +347,7 @@ export class ViewProvider { * Begin editing a node. * @param {import('./jsmind.node.js').Node} node - Node to edit */ - edit_node_begin(node: import("./jsmind.node.js").Node): void; + edit_node_begin(node: import('./jsmind.node.js').Node): void; /** End editing current node. */ edit_node_end(): void; /** @returns {{x:number,y:number}} */ @@ -304,31 +384,37 @@ export class ViewProvider { show(keep_center?: boolean | undefined): void; relayout(): void; /** @param {import('./jsmind.node.js').Node} node */ - save_location(node: import("./jsmind.node.js").Node): void; + save_location(node: import('./jsmind.node.js').Node): void; /** @param {import('./jsmind.node.js').Node} node */ - restore_location(node: import("./jsmind.node.js").Node): void; + restore_location(node: import('./jsmind.node.js').Node): void; clear_nodes(): void; /** Render node elements and expanders to screen. */ show_nodes(): void; /** @param {import('./jsmind.node.js').Node} node @param {{x:number,y:number}} view_offset */ - _show_expander(node: import("./jsmind.node.js").Node, view_offset: { - x: number; - y: number; - }): void; + _show_expander( + node: import('./jsmind.node.js').Node, + view_offset: { + x: number; + y: number; + } + ): void; /** @param {import('./jsmind.node.js').Node} node */ - _get_expander_text(node: import("./jsmind.node.js").Node): number | "..." | "-" | "+"; + _get_expander_text(node: import('./jsmind.node.js').Node): number | '...' | '-' | '+'; /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ - _default_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; + _default_node_render(ele: HTMLElement, node: import('./jsmind.node.js').Node): void; /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ - _custom_node_render(ele: HTMLElement, node: import("./jsmind.node.js").Node): void; + _custom_node_render(ele: HTMLElement, node: import('./jsmind.node.js').Node): void; /** @param {import('./jsmind.node.js').Node} node */ - reset_node_custom_style(node: import("./jsmind.node.js").Node): void; + reset_node_custom_style(node: import('./jsmind.node.js').Node): void; /** @param {HTMLElement} node_element @param {Record} node_data */ - _reset_node_custom_style(node_element: HTMLElement, node_data: Record): void; + _reset_node_custom_style( + node_element: HTMLElement, + node_data: Record + ): void; /** @param {import('./jsmind.node.js').Node} node */ - restore_selected_node_custom_style(node: import("./jsmind.node.js").Node): void; + restore_selected_node_custom_style(node: import('./jsmind.node.js').Node): void; /** @param {import('./jsmind.node.js').Node} node */ - clear_selected_node_custom_style(node: import("./jsmind.node.js").Node): void; + clear_selected_node_custom_style(node: import('./jsmind.node.js').Node): void; clear_lines(): void; show_lines(): void; /** @@ -337,7 +423,7 @@ export class ViewProvider { */ setup_canvas_draggable(enabled: boolean): void; /** @param {import('./jsmind.node.js').Node} node */ - center_node(node: import("./jsmind.node.js").Node): boolean; + center_node(node: import('./jsmind.node.js').Node): boolean; /** @param {MouseEvent=} e */ zoomIn(e?: MouseEvent | undefined): boolean; /** @param {MouseEvent=} e */ diff --git a/types/generated/plugins/jsmind.draggable-node.d.ts b/types/generated/plugins/jsmind.draggable-node.d.ts index d5fe862f..a83fa8a6 100644 --- a/types/generated/plugins/jsmind.draggable-node.d.ts +++ b/types/generated/plugins/jsmind.draggable-node.d.ts @@ -7,10 +7,10 @@ export class DraggableNode { * @param {import('../jsmind.js').default} jm - jsMind instance * @param {Partial} options - Plugin options */ - constructor(jm: import("../jsmind.js").default, options: Partial); + constructor(jm: import('../jsmind.js').default, options: Partial); version: string; /** @type {import('../jsmind.js').default} */ - jm: import("../jsmind.js").default; + jm: import('../jsmind.js').default; /** @type {DraggableNodeOptions} */ options: DraggableNodeOptions; /** @type {HTMLCanvasElement|null} */ @@ -28,9 +28,9 @@ export class DraggableNode { /** @type {number} */ shadow_h: number; /** @type {import('../jsmind.node.js').Node|null} */ - active_node: import("../jsmind.node.js").Node | null; + active_node: import('../jsmind.node.js').Node | null; /** @type {import('../jsmind.node.js').Node|null} */ - target_node: import("../jsmind.node.js").Node | null; + target_node: import('../jsmind.node.js').Node | null; /** @type {number|null} */ target_direct: number | null; /** @type {number} */ @@ -77,13 +77,17 @@ export class DraggableNode { * @param {{x:number,y:number}} node_p - Target node anchor point * @param {boolean} invalid - Whether current target is invalid */ - magnet_shadow(shadow_p: { - x: number; - y: number; - }, node_p: { - x: number; - y: number; - }, invalid: boolean): void; + magnet_shadow( + shadow_p: { + x: number; + y: number; + }, + node_p: { + x: number; + y: number; + }, + invalid: boolean + ): void; /** Clear helper lines from canvas. */ clear_lines(): void; /** @@ -132,59 +136,62 @@ export class DraggableNode { * @param {number} direction - Direction constant * @returns {import('../jsmind.node.js').Node|null} */ - lookup_overlapping_node_parent(direction: number): import("../jsmind.node.js").Node | null; + lookup_overlapping_node_parent(direction: number): import('../jsmind.node.js').Node | null; /** * Find node's parent by a screen location. * @param {number} x - Client X * @param {number} y - Client Y * @returns {import('../jsmind.node.js').Node|null} */ - lookup_node_parent_by_location(x: number, y: number): import("../jsmind.node.js").Node | null; + lookup_node_parent_by_location(x: number, y: number): import('../jsmind.node.js').Node | null; /** * Lookup the closest node along a direction. * @param {number} direction * @returns {import('../jsmind.node.js').Node} */ - lookup_close_node(direction: number): import("../jsmind.node.js").Node; + lookup_close_node(direction: number): import('../jsmind.node.js').Node; /** * Check if shadow is on the target side of a node. * @param {import('../jsmind.node.js').Node} node * @param {number} dir * @returns {boolean} */ - shadow_on_target_side(node: import("../jsmind.node.js").Node, dir: number): boolean; + shadow_on_target_side(node: import('../jsmind.node.js').Node, dir: number): boolean; /** * Distance from shadow to the right side of a node. * @param {import('../jsmind.node.js').Node} node * @returns {number} */ - shadow_to_right_of_node(node: import("../jsmind.node.js").Node): number; + shadow_to_right_of_node(node: import('../jsmind.node.js').Node): number; /** * Distance from shadow to the left side of a node. * @param {import('../jsmind.node.js').Node} node * @returns {number} */ - shadow_to_left_of_node(node: import("../jsmind.node.js").Node): number; + shadow_to_left_of_node(node: import('../jsmind.node.js').Node): number; /** * Vertical distance between shadow centerline and node centerline. * @param {import('../jsmind.node.js').Node} node * @returns {number} */ - shadow_to_base_line_of_node(node: import("../jsmind.node.js").Node): number; + shadow_to_base_line_of_node(node: import('../jsmind.node.js').Node): number; /** * Manhattan distance to a node along a direction. * @param {import('../jsmind.node.js').Node} node * @param {number} dir * @returns {number} */ - shadow_to_node(node: import("../jsmind.node.js").Node, dir: number): number; + shadow_to_node(node: import('../jsmind.node.js').Node, dir: number): number; /** * Calculate connection points of a node and the shadow. * @param {import('../jsmind.node.js').Node} node * @param {number} dir * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}} */ - calc_point_of_node(node: import("../jsmind.node.js").Node, dir: number): { + calc_point_of_node( + node: import('../jsmind.node.js').Node, + dir: number + ): { sp: { x: number; y: number; @@ -200,7 +207,11 @@ export class DraggableNode { * @param {import('../jsmind.node.js').Node|null} target_node * @param {number|null} target_direct */ - move_node(src_node: import("../jsmind.node.js").Node, target_node: import("../jsmind.node.js").Node | null, target_direct: number | null): void; + move_node( + src_node: import('../jsmind.node.js').Node, + target_node: import('../jsmind.node.js').Node | null, + target_direct: number | null + ): void; /** * Handle jsMind events. * @param {number|string} type - Event type @@ -212,7 +223,7 @@ export class DraggableNode { * Draggable node plugin registration. * @type {import('../jsmind.plugin.js').Plugin>} */ -export const draggable_plugin: import("../jsmind.plugin.js").Plugin>; +export const draggable_plugin: import('../jsmind.plugin.js').Plugin>; export default DraggableNode; /** * Default options for draggable node plugin. diff --git a/types/generated/plugins/jsmind.screenshot.d.ts b/types/generated/plugins/jsmind.screenshot.d.ts index 2fb9abdd..06eeb283 100644 --- a/types/generated/plugins/jsmind.screenshot.d.ts +++ b/types/generated/plugins/jsmind.screenshot.d.ts @@ -7,10 +7,10 @@ export class JmScreenshot { * @param {import('../jsmind.js').default} jm - jsMind instance * @param {Partial} options - Plugin options */ - constructor(jm: import("../jsmind.js").default, options: Partial); + constructor(jm: import('../jsmind.js').default, options: Partial); version: string; /** @type {import('../jsmind.js').default} */ - jm: import("../jsmind.js").default; + jm: import('../jsmind.js').default; /** @type {ScreenshotOptions} */ options: ScreenshotOptions; /** @type {number} */ @@ -68,7 +68,7 @@ export class JmScreenshot { * Screenshot plugin registration. * @type {import('../jsmind.plugin.js').Plugin>} */ -export const screenshot_plugin: import("../jsmind.plugin.js").Plugin>; +export const screenshot_plugin: import('../jsmind.plugin.js').Plugin>; export default JmScreenshot; /** * Default options for screenshot plugin. From b867eaf52d10c600ef977b2c71ec81e8bfd385a4 Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 00:52:44 +0800 Subject: [PATCH 18/24] chore(types): ignore generated d.ts; auto-generate on test/prepare/publish; add npm files whitelist --- .gitignore | 1 + package.json | 11 +- types/generated/jsmind.common.d.ts | 66 --- types/generated/jsmind.d.ts | 346 -------------- types/generated/jsmind.data_provider.d.ts | 66 --- types/generated/jsmind.dom.d.ts | 59 --- types/generated/jsmind.format.d.ts | 92 ---- types/generated/jsmind.graph.d.ts | 211 --------- types/generated/jsmind.layout_provider.d.ts | 189 -------- types/generated/jsmind.mind.d.ts | 151 ------ types/generated/jsmind.node.d.ts | 71 --- types/generated/jsmind.option.d.ts | 73 --- types/generated/jsmind.plugin.d.ts | 24 - types/generated/jsmind.shortcut_provider.d.ts | 55 --- types/generated/jsmind.util.d.ts | 26 -- types/generated/jsmind.view_provider.d.ts | 433 ------------------ .../plugins/jsmind.draggable-node.d.ts | 240 ---------- .../generated/plugins/jsmind.screenshot.d.ts | 83 ---- 18 files changed, 11 insertions(+), 2186 deletions(-) delete mode 100644 types/generated/jsmind.common.d.ts delete mode 100644 types/generated/jsmind.d.ts delete mode 100644 types/generated/jsmind.data_provider.d.ts delete mode 100644 types/generated/jsmind.dom.d.ts delete mode 100644 types/generated/jsmind.format.d.ts delete mode 100644 types/generated/jsmind.graph.d.ts delete mode 100644 types/generated/jsmind.layout_provider.d.ts delete mode 100644 types/generated/jsmind.mind.d.ts delete mode 100644 types/generated/jsmind.node.d.ts delete mode 100644 types/generated/jsmind.option.d.ts delete mode 100644 types/generated/jsmind.plugin.d.ts delete mode 100644 types/generated/jsmind.shortcut_provider.d.ts delete mode 100644 types/generated/jsmind.util.d.ts delete mode 100644 types/generated/jsmind.view_provider.d.ts delete mode 100644 types/generated/plugins/jsmind.draggable-node.d.ts delete mode 100644 types/generated/plugins/jsmind.screenshot.d.ts diff --git a/.gitignore b/.gitignore index 9036ae2b..6d9c8121 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ es6/*.js es6/*.js.map +types/generated/ diff --git a/package.json b/package.json index aa488d0b..7e4e32fd 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,13 @@ "doc": "docs", "example": "example" }, + "files": [ + "es6", + "style", + "types", + "LICENSE", + "README.md" + ], "scripts": { "server": "http-server", "build": "rollup -c .config/rollup.config.js", @@ -36,7 +43,9 @@ "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", "format": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --write .", "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check .", - "prepublishOnly": "npm run gen:dts" + "pretest": "npm run gen:dts", + "prepare": "npm run gen:dts", + "prepublishOnly": "npm run build && npm run gen:dts" }, "repository": { "type": "git", diff --git a/types/generated/jsmind.common.d.ts b/types/generated/jsmind.common.d.ts deleted file mode 100644 index af91b37e..00000000 --- a/types/generated/jsmind.common.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @license BSD - * @copyright 2014-2025 hizzgdev@163.com - * - * Project Home: - * https://github.com/hizzgdev/jsmind/ - */ -/** - * Library version string. - * @type {string} - */ -export const __version__: string; -/** - * Library author. - * @type {string} - */ -export const __author__: string; -/** - * Direction constants and parser. - * @typedef {{left:number,center:number,right:number,of:(dir:(string|number))=>number|undefined}} DirectionType - */ -/** @type {DirectionType} */ -export const Direction: DirectionType; -export type EventType = number; -export namespace EventType { - let show: number; - let resize: number; - let edit: number; - let select: number; -} -export type Key = number; -export namespace Key { - let meta: number; - let ctrl: number; - let alt: number; - let shift: number; -} -export type LogLevel = number; -export namespace LogLevel { - let debug: number; - let info: number; - let warn: number; - let error: number; - let disable: number; -} -/** - * Logger facade with dynamic level. - * @type {{level:(lvl:number)=>void,log:Function,debug:Function,info:Function,warn:Function,error:Function}} - */ -export let logger: { - level: (lvl: number) => void; - log: Function; - debug: Function; - info: Function; - warn: Function; - error: Function; -}; -/** - * Direction constants and parser. - */ -export type DirectionType = { - left: number; - center: number; - right: number; - of: (dir: string | number) => number | undefined; -}; diff --git a/types/generated/jsmind.d.ts b/types/generated/jsmind.d.ts deleted file mode 100644 index 9a6c5a29..00000000 --- a/types/generated/jsmind.d.ts +++ /dev/null @@ -1,346 +0,0 @@ -/** - * Event callback payload - * @typedef {{ evt?: string, data?: unknown[], node?: string }} EventData - */ -/** - * jsMind runtime: orchestrates data/layout/view/shortcut and exposes public API. - */ -export default class jsMind { - static mind: typeof Mind; - static node: typeof Node; - static direction: import('./jsmind.common.js').DirectionType; - static event_type: { - show: number; - resize: number; - edit: number; - select: number; - }; - static $: { - w: Window; - d: Document; - g: (id: string) => HTMLElement | null; - c: (tag: string) => HTMLElement; - t: (n: HTMLElement, t: string) => void; - h: (n: HTMLElement, t: string | HTMLElement) => void; - i: (el: unknown) => el is HTMLElement; - on: (t: HTMLElement, e: string, h: (ev: Event) => void) => void; - }; - static plugin: typeof Plugin; - static register_plugin: typeof _register_plugin; - static util: { - file: { - read: (file: File, cb: (result: string, name: string) => void) => void; - save: (data: string, type: string, name: string) => void; - }; - json: { - json2string: (v: unknown) => string; - string2json: (s: string) => unknown; - merge: (b: object, a: object) => object; - }; - uuid: { - newid: () => string; - }; - text: { - is_empty: (s?: string) => boolean; - }; - }; - /** - * Deprecated: static show constructor helper. - * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options - * @param {object | null} mind - * @returns {jsMind} - */ - static show( - options: import('./jsmind.option.js').JsMindRuntimeOptions, - mind: object | null - ): jsMind; - /** - * Create a jsMind instance. - * @param {import('./jsmind.option.js').JsMindRuntimeOptions} options - */ - constructor(options: import('./jsmind.option.js').JsMindRuntimeOptions); - options: import('./jsmind.option.js').JsMindRuntimeOptions; - version: string; - initialized: boolean; - mind: Mind; - /** @type {Array<(type: number, data: EventData) => void>} */ - event_handles: Array<(type: number, data: EventData) => void>; - /** Initialize sub-systems and plugins. */ - init(): void; - data: DataProvider; - layout: LayoutProvider; - view: ViewProvider; - shortcut: ShortcutProvider; - /** @returns {boolean} whether current mind map is editable */ - get_editable(): boolean; - /** enable editing */ - enable_edit(): void; - /** disable editing */ - disable_edit(): void; - /** @returns {boolean} whether view is draggable */ - get_view_draggable(): boolean; - /** enable view dragging */ - enable_view_draggable(): void; - /** disable view dragging */ - disable_view_draggable(): void; - /** - * Enable default event handle. - * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle - */ - enable_event_handle(event_handle: 'mousedown' | 'click' | 'dblclick' | 'mousewheel'): void; - /** - * Disable default event handle. - * @param {'mousedown'|'click'|'dblclick'|'mousewheel'} event_handle - */ - disable_event_handle(event_handle: 'mousedown' | 'click' | 'dblclick' | 'mousewheel'): void; - /** - * Set theme name. - * @param {string|null} theme - */ - set_theme(theme: string | null): void; - /** bind internal DOM events */ - _event_bind(): void; - /** @param {MouseEvent} e */ - mousedown_handle(e: MouseEvent): void; - /** @param {MouseEvent} e */ - click_handle(e: MouseEvent): void; - /** @param {MouseEvent} e */ - dblclick_handle(e: MouseEvent): void; - /** @param {WheelEvent} e */ - mousewheel_handle(e: WheelEvent): void; - /** - * Begin editing a node. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {boolean|void} - */ - begin_edit(node: string | import('./jsmind.node.js').Node): boolean | void; - /** End editing */ - end_edit(): void; - /** - * Toggle a node's expanded state. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {void} - */ - toggle_node(node: string | import('./jsmind.node.js').Node): void; - /** - * Expand a node. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {void} - */ - expand_node(node: string | import('./jsmind.node.js').Node): void; - /** - * Collapse a node. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {void} - */ - collapse_node(node: string | import('./jsmind.node.js').Node): void; - /** Expand all nodes */ - expand_all(): void; - /** Collapse all nodes */ - collapse_all(): void; - /** @param {number} depth */ - expand_to_depth(depth: number): void; - /** reset view/layout/data */ - _reset(): void; - /** - * Internal show flow. - * @param {object | null} mind - * @param {boolean=} skip_centering - */ - _show(mind: object | null, skip_centering?: boolean | undefined): void; - /** - * Show a mind (or example) on the canvas. - * @param {object | null} mind - * @param {boolean=} skip_centering - */ - show(mind: object | null, skip_centering?: boolean | undefined): void; - /** @returns {{name:string,author:string,version:string}} */ - get_meta(): { - name: string; - author: string; - version: string; - }; - /** - * Serialize current mind to given format. - * @param {'node_tree'|'node_array'|'freemind'|'text'} [data_format] - * @returns {object} - */ - get_data(data_format?: 'node_tree' | 'node_array' | 'freemind' | 'text'): object; - /** @returns {import('./jsmind.node.js').Node} */ - get_root(): import('./jsmind.node.js').Node; - /** - * @param {string | import('./jsmind.node.js').Node} node - * @returns {import('./jsmind.node.js').Node} - */ - get_node(node: string | import('./jsmind.node.js').Node): import('./jsmind.node.js').Node; - /** - * Add a node under parent. - * @param {string | import('./jsmind.node.js').Node} parent_node - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @returns {import('./jsmind.node.js').Node|null} - */ - add_node( - parent_node: string | import('./jsmind.node.js').Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined - ): import('./jsmind.node.js').Node | null; - /** - * Insert a node before target node. - * @param {string | import('./jsmind.node.js').Node} node_before - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @returns {import('./jsmind.node.js').Node|null} - */ - insert_node_before( - node_before: string | import('./jsmind.node.js').Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined - ): import('./jsmind.node.js').Node | null; - /** - * Insert a node after target node. - * @param {string | import('./jsmind.node.js').Node} node_after - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @returns {import('./jsmind.node.js').Node|null} - */ - insert_node_after( - node_after: string | import('./jsmind.node.js').Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined - ): import('./jsmind.node.js').Node | null; - /** - * Remove a node. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {boolean} - */ - remove_node(node: string | import('./jsmind.node.js').Node): boolean; - /** @param {string} node_id @param {string} topic */ - update_node(node_id: string, topic: string): void; - /** - * Move a node and optionally change direction. - * @param {string} node_id - * @param {string=} before_id - * @param {string=} parent_id - * @param {number=} direction - */ - move_node( - node_id: string, - before_id?: string | undefined, - parent_id?: string | undefined, - direction?: number | undefined - ): void; - /** - * @param {string | import('./jsmind.node.js').Node} node - * @returns {void} - */ - select_node(node: string | import('./jsmind.node.js').Node): void; - /** @returns {import('./jsmind.node.js').Node|null} */ - get_selected_node(): import('./jsmind.node.js').Node | null; - /** clear selection */ - select_clear(): void; - /** @param {string | import('./jsmind.node.js').Node} node */ - is_node_visible(node: string | import('./jsmind.node.js').Node): boolean; - /** @param {string | import('./jsmind.node.js').Node} node */ - scroll_node_to_center(node: string | import('./jsmind.node.js').Node): void; - /** - * Find the previous sibling node of the given node. - * - * @param {string | import('./jsmind.node.js').Node} node - Node id or Node instance - * @returns {import('./jsmind.node.js').Node | null} - */ - find_node_before( - node: string | import('./jsmind.node.js').Node - ): import('./jsmind.node.js').Node | null; - /** - * Find the next sibling node of the given node. - * @param {string | import('./jsmind.node.js').Node} node - * @returns {import('./jsmind.node.js').Node | null} - */ - find_node_after( - node: string | import('./jsmind.node.js').Node - ): import('./jsmind.node.js').Node | null; - /** - * @param {string} node_id - * @param {string=} bg_color - * @param {string=} fg_color - * @returns {void} - */ - set_node_color( - node_id: string, - bg_color?: string | undefined, - fg_color?: string | undefined - ): void; - /** - * @param {string} node_id - * @param {number=} size - * @param {string=} weight - * @param {string=} style - * @returns {void} - */ - set_node_font_style( - node_id: string, - size?: number | undefined, - weight?: string | undefined, - style?: string | undefined - ): void; - /** - * @param {string} node_id - * @param {string} image - * @param {number=} width - * @param {number=} height - * @param {number=} rotation - * @returns {void} - */ - set_node_background_image( - node_id: string, - image: string, - width?: number | undefined, - height?: number | undefined, - rotation?: number | undefined - ): void; - /** - * @param {string} node_id - * @param {number} rotation - * @returns {void} - */ - set_node_background_rotation(node_id: string, rotation: number): void; - /** trigger view resize */ - resize(): void; - /** @param {(type:number, data: EventData)=>void} callback */ - add_event_listener(callback: (type: number, data: EventData) => void): void; - /** clear event listeners */ - clear_event_listener(): void; - /** @param {number} type @param {EventData} data */ - invoke_event_handle(type: number, data: EventData): void; - /** @param {number} type @param {EventData} data */ - _invoke_event_handle(type: number, data: EventData): void; -} -/** - * Event callback payload - */ -export type EventData = { - evt?: string; - data?: unknown[]; - node?: string; -}; -import { Mind } from './jsmind.mind.js'; -import { DataProvider } from './jsmind.data_provider.js'; -import { LayoutProvider } from './jsmind.layout_provider.js'; -import { ViewProvider } from './jsmind.view_provider.js'; -import { ShortcutProvider } from './jsmind.shortcut_provider.js'; -import { Node } from './jsmind.node.js'; -import { Plugin } from './jsmind.plugin.js'; -import { register as _register_plugin } from './jsmind.plugin.js'; diff --git a/types/generated/jsmind.data_provider.d.ts b/types/generated/jsmind.data_provider.d.ts deleted file mode 100644 index 489c06d4..00000000 --- a/types/generated/jsmind.data_provider.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -export class DataProvider { - /** - * Data provider: loads and serializes mind data by format. - * @param {import('./jsmind.js').default} jm - jsMind instance - */ - constructor(jm: import('./jsmind.js').default); - jm: import('./jsmind.js').default; - /** Initialize data provider. */ - init(): void; - /** Reset data provider state. */ - reset(): void; - /** - * Load a Mind from mixed source. - * @param {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta?:{name:string,author:string,version:string},format:'freemind',data:string}|{meta?:{name:string,author:string,version:string},format:'text',data:string}} mind_data - object with {format,data} or a format-specific payload - * @returns {import('./jsmind.mind.js').Mind|null} - */ - load( - mind_data: - | import('./jsmind.format.js').NodeTreeFormat - | import('./jsmind.format.js').NodeArrayFormat - | { - meta?: { - name: string; - author: string; - version: string; - }; - format: 'freemind'; - data: string; - } - | { - meta?: { - name: string; - author: string; - version: string; - }; - format: 'text'; - data: string; - } - ): import('./jsmind.mind.js').Mind | null; - /** - * Serialize current mind to target format. - * @param {'node_tree'|'node_array'|'freemind'|'text'} data_format - * @returns {import('./jsmind.format.js').NodeTreeFormat|import('./jsmind.format.js').NodeArrayFormat|{meta:{name:string,author:string,version:string},format:'freemind',data:string}|{meta:{name:string,author:string,version:string},format:'text',data:string}} - */ - get_data(data_format: 'node_tree' | 'node_array' | 'freemind' | 'text'): - | import('./jsmind.format.js').NodeTreeFormat - | import('./jsmind.format.js').NodeArrayFormat - | { - meta: { - name: string; - author: string; - version: string; - }; - format: 'freemind'; - data: string; - } - | { - meta: { - name: string; - author: string; - version: string; - }; - format: 'text'; - data: string; - }; -} diff --git a/types/generated/jsmind.dom.d.ts b/types/generated/jsmind.dom.d.ts deleted file mode 100644 index 5ae171e3..00000000 --- a/types/generated/jsmind.dom.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -export const $: Dom; -/** - * @license BSD - * @copyright 2014-2025 hizzgdev@163.com - * - * Project Home: - * https://github.com/hizzgdev/jsmind/ - */ -/** - * Lightweight DOM helpers bound to a window. - */ -declare class Dom { - /** - * @param {Window} w - */ - constructor(w: Window); - /** @type {Window} */ - w: Window; - /** @type {Document} */ - d: Document; - /** - * Get element by id. - * @param {string} id - * @returns {HTMLElement|null} - */ - g: (id: string) => HTMLElement | null; - /** - * Create element with given tag. - * @param {string} tag - * @returns {HTMLElement} - */ - c: (tag: string) => HTMLElement; - /** - * Set text content for element. - * @param {HTMLElement} n - * @param {string} t - */ - t: (n: HTMLElement, t: string) => void; - /** - * Set inner HTML or append element. - * @param {HTMLElement} n - * @param {string|HTMLElement} t - */ - h: (n: HTMLElement, t: string | HTMLElement) => void; - /** - * Runtime check for HTMLElement. - * @param {unknown} el - * @returns {el is HTMLElement} - */ - i: (el: unknown) => el is HTMLElement; - /** - * Add event listener with legacy fallback. - * @param {HTMLElement} t - * @param {string} e - * @param {(ev:Event)=>void} h - */ - on: (t: HTMLElement, e: string, h: (ev: Event) => void) => void; -} -export {}; diff --git a/types/generated/jsmind.format.d.ts b/types/generated/jsmind.format.d.ts deleted file mode 100644 index 1a98044b..00000000 --- a/types/generated/jsmind.format.d.ts +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Mind data format handlers. - * @type {{ - * node_tree: { example:NodeTreeFormat, get_mind:(src:NodeTreeFormat)=>Mind, get_data:(mind:Mind)=>NodeTreeFormat }, - * node_array: { example:NodeArrayFormat, get_mind:(src:NodeArrayFormat)=>Mind, get_data:(mind:Mind)=>NodeArrayFormat }, - * freemind: { example:{meta:MindMapMeta,format:'freemind',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'freemind',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'freemind',data:string} }, - * text: { example:{meta:MindMapMeta,format:'text',data:string}, get_mind:(src:{meta?:MindMapMeta,format:'text',data:string})=>Mind, get_data:(mind:Mind)=>{meta:MindMapMeta,format:'text',data:string} } - * }} - */ -export const format: { - node_tree: { - example: NodeTreeFormat; - get_mind: (src: NodeTreeFormat) => Mind; - get_data: (mind: Mind) => NodeTreeFormat; - }; - node_array: { - example: NodeArrayFormat; - get_mind: (src: NodeArrayFormat) => Mind; - get_data: (mind: Mind) => NodeArrayFormat; - }; - freemind: { - example: { - meta: MindMapMeta; - format: 'freemind'; - data: string; - }; - get_mind: (src: { meta?: MindMapMeta; format: 'freemind'; data: string }) => Mind; - get_data: (mind: Mind) => { - meta: MindMapMeta; - format: 'freemind'; - data: string; - }; - }; - text: { - example: { - meta: MindMapMeta; - format: 'text'; - data: string; - }; - get_mind: (src: { meta?: MindMapMeta; format: 'text'; data: string }) => Mind; - get_data: (mind: Mind) => { - meta: MindMapMeta; - format: 'text'; - data: string; - }; - }; -}; -export type MindMapMeta = { - name: string; - author: string; - version: string; -}; -/** - * Node tree data item - */ -export type NodeTreeData = { - id: string; - topic: string; - data?: Record; - direction?: number | string; - expanded?: boolean; - children?: NodeTreeData[]; -}; -/** - * Node tree formatted payload - */ -export type NodeTreeFormat = { - meta?: MindMapMeta; - format: 'node_tree'; - data: NodeTreeData; -}; -/** - * Node array data item - */ -export type NodeArrayItem = { - id: string; - topic: string; - parentid?: string; - data?: Record; - direction?: number | string; - expanded?: boolean; - isroot?: boolean; -}; -/** - * Node array formatted payload - */ -export type NodeArrayFormat = { - meta?: MindMapMeta; - format: 'node_array'; - data: NodeArrayItem[]; -}; -import { Mind } from './jsmind.mind.js'; diff --git a/types/generated/jsmind.graph.d.ts b/types/generated/jsmind.graph.d.ts deleted file mode 100644 index 97ab46bd..00000000 --- a/types/generated/jsmind.graph.d.ts +++ /dev/null @@ -1,211 +0,0 @@ -/** - * Initialize graph renderer based on engine type. - * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance - * @param {'canvas'|'svg'} engine - Rendering engine type - * @returns {SvgGraph|CanvasGraph} Graph renderer instance - */ -export function init_graph( - view: import('./jsmind.view_provider.js').ViewProvider, - engine: 'canvas' | 'svg' -): SvgGraph | CanvasGraph; -/** - * SVG-based graph renderer. - */ -declare class SvgGraph { - /** @param {string} tag */ - static c(tag: string): SVGElement; - /** - * Create SVG graph renderer. - * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance - */ - constructor(view: import('./jsmind.view_provider.js').ViewProvider); - view: import('./jsmind.view_provider.js').ViewProvider; - opts: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - }; - e_svg: SVGElement; - size: { - w: number; - h: number; - }; - /** @type {SVGPathElement[]} */ - lines: SVGPathElement[]; - line_drawing: { - straight: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - curved: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - }; - /** Choose line drawing renderer. */ - init_line_render(): void; - /** @type {(path:SVGPathElement,x1:number,y1:number,x2:number,y2:number)=>void} */ - drawing: (path: SVGPathElement, x1: number, y1: number, x2: number, y2: number) => void; - /** @returns {SVGSVGElement} */ - element(): SVGSVGElement; - /** @param {number} w @param {number} h */ - set_size(w: number, h: number): void; - clear(): void; - /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ - draw_line( - pout: { - x: number; - y: number; - }, - pin: { - x: number; - y: number; - }, - offset: { - x: number; - y: number; - }, - color?: string | undefined - ): void; - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; - /** - * Draw bezier curve to SVG path. - * @internal - * @param {SVGPathElement} path - SVG path element - * @param {number} x1 - Start x coordinate - * @param {number} y1 - Start y coordinate - * @param {number} x2 - End x coordinate - * @param {number} y2 - End y coordinate - */ - _bezier_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; - /** - * Draw straight line to SVG path. - * @internal - * @param {SVGPathElement} path - SVG path element - * @param {number} x1 - Start x coordinate - * @param {number} y1 - Start y coordinate - * @param {number} x2 - End x coordinate - * @param {number} y2 - End y coordinate - */ - _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; -} -/** - * Canvas-based graph renderer. - */ -declare class CanvasGraph { - /** - * Create canvas graph renderer. - * @param {import('./jsmind.view_provider.js').ViewProvider} view - View provider instance - */ - constructor(view: import('./jsmind.view_provider.js').ViewProvider); - opts: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - }; - e_canvas: HTMLElement; - canvas_ctx: CanvasRenderingContext2D; - size: { - w: number; - h: number; - }; - line_drawing: { - straight: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - curved: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - }; - dpr: number; - /** Choose line drawing renderer. */ - init_line_render(): void; - /** @type {(ctx:CanvasRenderingContext2D,x1:number,y1:number,x2:number,y2:number)=>void} */ - drawing: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - /** @returns {HTMLCanvasElement} */ - element(): HTMLCanvasElement; - /** @param {number} w @param {number} h */ - set_size(w: number, h: number): void; - /** Clear the canvas. */ - clear(): void; - /** @param {{x:number,y:number}} pout @param {{x:number,y:number}} pin @param {{x:number,y:number}} offset @param {string=} color */ - draw_line( - pout: { - x: number; - y: number; - }, - pin: { - x: number; - y: number; - }, - offset: { - x: number; - y: number; - }, - color?: string | undefined - ): void; - /** @param {CanvasRenderingContext2D} dest_canvas_ctx @param {(()=>void)=} callback */ - copy_to(dest_canvas_ctx: CanvasRenderingContext2D, callback?: (() => void) | undefined): void; - /** - * Draw bezier curve on canvas. - * @internal - * @param {CanvasRenderingContext2D} ctx - Canvas context - * @param {number} x1 - Start x coordinate - * @param {number} y1 - Start y coordinate - * @param {number} x2 - End x coordinate - * @param {number} y2 - End y coordinate - */ - _bezier_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; - /** - * Draw straight line on canvas. - * @internal - * @param {CanvasRenderingContext2D} ctx - Canvas context - * @param {number} x1 - Start x coordinate - * @param {number} y1 - Start y coordinate - * @param {number} x2 - End x coordinate - * @param {number} y2 - End y coordinate - */ - _line_to(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; -} -export {}; diff --git a/types/generated/jsmind.layout_provider.d.ts b/types/generated/jsmind.layout_provider.d.ts deleted file mode 100644 index 272e161e..00000000 --- a/types/generated/jsmind.layout_provider.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -export class LayoutProvider { - /** - * Layout engine for positioning nodes and lines. - * @param {import('./jsmind.js').default} jm - jsMind instance - * @param {{mode:'full'|'side', hspace:number, vspace:number, pspace:number, cousin_space:number}} options - Layout configuration options - */ - constructor( - jm: import('./jsmind.js').default, - options: { - mode: 'full' | 'side'; - hspace: number; - vspace: number; - pspace: number; - cousin_space: number; - } - ); - opts: { - mode: 'full' | 'side'; - hspace: number; - vspace: number; - pspace: number; - cousin_space: number; - }; - jm: import('./jsmind.js').default; - isside: boolean; - bounds: { - n: number; - s: number; - w: number; - e: number; - }; - cache_valid: boolean; - /** Initialize layout provider. */ - init(): void; - /** Reset layout state and bounds. */ - reset(): void; - /** - * Decide the next child's direction for a parent node. - * @param {import('./jsmind.node.js').Node} node - * @returns {number} - */ - calculate_next_child_direction(node: import('./jsmind.node.js').Node): number; - /** Perform layout and offsets recalculation. */ - layout(): void; - /** Calculate and set direction for all nodes. */ - layout_direction(): void; - /** - * Set direction layout for root node and its children. - * @private - */ - private _layout_direction_root; - /** - * Set direction layout for a node and its descendants. - * @private - * @param {import('./jsmind.node.js').Node} node - Target node - * @param {number} direction - Direction constant (-1, 0, 1) - * @param {number} side_index - Index among siblings - */ - private _layout_direction_side; - /** Calculate and set position offsets for all nodes. */ - layout_offset(): void; - /** - * Layout both the x and y axis for subnodes. - * @private - * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout - * @returns {number} Total height of all nodes - */ - private _layout_offset_subnodes; - /** - * Layout the y axis only, for collapse/expand a node. - * @private - * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes to layout - * @returns {number} Total height of all nodes - */ - private _layout_offset_subnodes_height; - /** - * Check if node should reserve cousin space. - * @private - * @param {import('./jsmind.node.js').Node} node - Node to check - * @returns {boolean} True if cousin space should be reserved - */ - private _should_reserve_cousin_space; - /** - * Get absolute offset for a node. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {{x:number, y:number}} Absolute position offset - */ - get_node_offset(node: import('./jsmind.node.js').Node): { - x: number; - y: number; - }; - /** - * Get anchor point for lines on a node. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {{x:number, y:number}} Anchor point coordinates - */ - get_node_point(node: import('./jsmind.node.js').Node): { - x: number; - y: number; - }; - /** - * Get input point for lines on a node. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {{x:number, y:number}} Input point coordinates - */ - get_node_point_in(node: import('./jsmind.node.js').Node): { - x: number; - y: number; - }; - /** - * Get output point for lines on a node. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {{x:number, y:number}} Output point coordinates - */ - get_node_point_out(node: import('./jsmind.node.js').Node): { - x: number; - y: number; - }; - /** - * Get expander point for a node. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {{x:number, y:number}} Expander point coordinates - */ - get_expander_point(node: import('./jsmind.node.js').Node): { - x: number; - y: number; - }; - /** - * Get minimal canvas size to contain all nodes. - * @returns {{w:number, h:number}} Minimum size required - */ - get_min_size(): { - w: number; - h: number; - }; - /** - * Toggle node expanded/collapsed state. - * @param {import('./jsmind.node.js').Node} node - Target node - */ - toggle_node(node: import('./jsmind.node.js').Node): void; - /** - * Expand a node and show its children. - * @param {import('./jsmind.node.js').Node} node - Target node - */ - expand_node(node: import('./jsmind.node.js').Node): void; - /** - * Collapse a node and hide its children. - * @param {import('./jsmind.node.js').Node} node - Target node - */ - collapse_node(node: import('./jsmind.node.js').Node): void; - /** Expand all nodes in the mind map. */ - expand_all(): void; - /** Collapse all nodes in the mind map. */ - collapse_all(): void; - /** - * Expand nodes to a specific depth level. - * @param {number} target_depth - Target depth level - * @param {import('./jsmind.node.js').Node[]=} curr_nodes - Current nodes to process - * @param {number=} curr_depth - Current depth level - */ - expand_to_depth( - target_depth: number, - curr_nodes?: import('./jsmind.node.js').Node[] | undefined, - curr_depth?: number | undefined - ): void; - /** - * Perform partial layout for a node and its subtree. - * @param {import('./jsmind.node.js').Node} node - Target node - */ - part_layout(node: import('./jsmind.node.js').Node): void; - /** - * Set visibility for nodes and their children. - * @param {import('./jsmind.node.js').Node[]} nodes - Array of nodes - * @param {boolean} visible - Visibility state - */ - set_visible(nodes: import('./jsmind.node.js').Node[], visible: boolean): void; - /** - * Check if a node is expanded. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {boolean} True if node is expanded - */ - is_expand(node: import('./jsmind.node.js').Node): boolean; - /** - * Check if a node is visible. - * @param {import('./jsmind.node.js').Node} node - Target node - * @returns {boolean} True if node is visible - */ - is_visible(node: import('./jsmind.node.js').Node): boolean; -} diff --git a/types/generated/jsmind.mind.d.ts b/types/generated/jsmind.mind.d.ts deleted file mode 100644 index 4a9a3c66..00000000 --- a/types/generated/jsmind.mind.d.ts +++ /dev/null @@ -1,151 +0,0 @@ -export class Mind { - /** @type {string | null} */ - name: string | null; - /** @type {string | null} */ - author: string | null; - /** @type {string | null} */ - version: string | null; - /** @type {Node | null} */ - root: Node | null; - /** @type {Node | null} */ - selected: Node | null; - /** @type {Record} */ - nodes: Record; - /** - * Get a node by id. - * @param {string} node_id - * @returns {Node | null} - */ - get_node(node_id: string): Node | null; - /** - * Set the root node, only once. - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @returns {Node | null} - */ - set_root(node_id: string, topic: string, data?: Record | undefined): Node | null; - /** - * Add a child node under parent. - * @param {Node} parent_node - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @param {boolean=} expanded - * @param {number=} idx - * @returns {Node | null} - */ - add_node( - parent_node: Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined, - expanded?: boolean | undefined, - idx?: number | undefined - ): Node | null; - /** - * Insert a node before target node. - * @param {Node} node_before - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @returns {Node | null} - */ - insert_node_before( - node_before: Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined - ): Node | null; - /** - * Get previous sibling of a node or node id. - * @param {string | Node} node - * @returns {Node | null} - */ - get_node_before(node: string | Node): Node | null; - /** - * Insert a node after target node. - * @param {Node} node_after - * @param {string} node_id - * @param {string} topic - * @param {Record=} data - * @param {number=} direction - * @returns {Node | null} - */ - insert_node_after( - node_after: Node, - node_id: string, - topic: string, - data?: Record | undefined, - direction?: number | undefined - ): Node | null; - /** - * Get next sibling of a node or node id. - * @param {string | Node} node - * @returns {Node | null} - */ - get_node_after(node: string | Node): Node | null; - /** - * Move a node to new parent/position. - * @param {Node} node - * @param {string=} before_id - * @param {string=} parent_id - * @param {number=} direction - * @returns {Node | null} - */ - move_node( - node: Node, - before_id?: string | undefined, - parent_id?: string | undefined, - direction?: number | undefined - ): Node | null; - /** - * Propagate direction to descendants. - * @param {Node} node - * @param {number=} direction - */ - _flow_node_direction(node: Node, direction?: number | undefined): void; - /** - * Re-index node among siblings based on before_id marker. - * @param {Node} node - * @param {string} before_id - * @returns {Node} - */ - _move_node_internal(node: Node, before_id: string): Node; - /** - * Internal move implementation. - * @param {Node} node - * @param {string} before_id - * @param {string} parent_id - * @param {number=} direction - * @returns {Node | null} - */ - _move_node( - node: Node, - before_id: string, - parent_id: string, - direction?: number | undefined - ): Node | null; - /** - * Remove a node from the mind. - * @param {Node} node - * @returns {boolean} - */ - remove_node(node: Node): boolean; - /** - * Put node into the map if id is not taken. - * @param {Node} node - * @returns {boolean} - */ - _put_node(node: Node): boolean; - /** - * Re-index children by Node.compare. - * @param {Node} node - */ - _update_index(node: Node): void; -} -import { Node } from './jsmind.node.js'; diff --git a/types/generated/jsmind.node.d.ts b/types/generated/jsmind.node.d.ts deleted file mode 100644 index d1af95bf..00000000 --- a/types/generated/jsmind.node.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -export class Node { - /** - * Compare two nodes by index for ordering. - * @param {Node} node1 - * @param {Node} node2 - * @returns {number} - */ - static compare(node1: Node, node2: Node): number; - /** - * Check if node is the same as or a descendant of parent_node. - * @param {Node} parent_node - * @param {Node} node - * @returns {boolean} - */ - static inherited(parent_node: Node, node: Node): boolean; - /** - * Runtime check for Node instance. - * @param {unknown} n - * @returns {n is Node} - */ - static is_node(n: unknown): n is Node; - /** - * Create a Node instance. - * @param {string} sId - Node id - * @param {number} iIndex - Node index (order among siblings). Use -1 for tail - * @param {string} sTopic - Node topic text - * @param {Record=} oData - Arbitrary node data - * @param {boolean=} bIsRoot - Whether it is the root node - * @param {Node | null=} oParent - Parent node - * @param {number=} eDirection - Direction for children under root (-1 left, 0 center, 1 right) - * @param {boolean=} bExpanded - Expanded state - */ - constructor( - sId: string, - iIndex: number, - sTopic: string, - oData?: Record | undefined, - bIsRoot?: boolean | undefined, - oParent?: (Node | null) | undefined, - eDirection?: number | undefined, - bExpanded?: boolean | undefined - ); - id: string; - index: number; - topic: string; - /** @type {Record} */ - data: Record; - isroot: boolean; - parent: Node; - direction: number; - expanded: boolean; - /** @type {Node[]} */ - children: Node[]; - _data: {}; - /** - * Get absolute location of this node in view coordinates. - * @returns {{x:number,y:number}} - */ - get_location(): { - x: number; - y: number; - }; - /** - * Get rendered size of this node. - * @returns {{w:number,h:number}} - */ - get_size(): { - w: number; - h: number; - }; -} diff --git a/types/generated/jsmind.option.d.ts b/types/generated/jsmind.option.d.ts deleted file mode 100644 index e5d3b54e..00000000 --- a/types/generated/jsmind.option.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Merge user options with defaults. Throws if container missing. - * @param {Partial} options - * @returns {JsMindRuntimeOptions} - */ -export function merge_option(options: Partial): JsMindRuntimeOptions; -export type JsMindRuntimeOptions = { - container: string | HTMLElement; - editable: boolean; - theme: string | null; - mode: 'full' | 'side'; - support_html: boolean; - log_level: 'debug' | 'info' | 'warn' | 'error' | 'disable'; - view: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: ( - this: object, - arg: { - ctx: CanvasRenderingContext2D | SVGPathElement; - start_point: { - x: number; - y: number; - }; - end_point: { - x: number; - y: number; - }; - } - ) => void; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render: - | null - | (( - jm: import('./jsmind.js').default, - ele: HTMLElement, - node: import('./jsmind.node.js').Node - ) => void); - expander_style: 'char' | 'number'; - }; - layout: { - hspace: number; - vspace: number; - pspace: number; - cousin_space: number; - }; - default_event_handle: { - enable_mousedown_handle: boolean; - enable_click_handle: boolean; - enable_dblclick_handle: boolean; - enable_mousewheel_handle: boolean; - }; - shortcut: { - enable: boolean; - handles: Record void>; - mapping: Record; - id_generator?: () => string; - }; - plugin: Record; -}; diff --git a/types/generated/jsmind.plugin.d.ts b/types/generated/jsmind.plugin.d.ts deleted file mode 100644 index af058080..00000000 --- a/types/generated/jsmind.plugin.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Register a plugin instance. - * @param {Plugin} plugin - */ -export function register(plugin: Plugin): void; -/** - * Apply registered plugins asynchronously. - * @param {import('./jsmind.js').default} jm - * @param {Record} options - */ -export function apply(jm: import('./jsmind.js').default, options: Record): void; -export class Plugin { - /** - * @template [TOptions=object] - * @param {string} name - * @param {(jm: import('./jsmind.js').default, options: TOptions)=>void} fn_init - */ - constructor( - name: string, - fn_init: (jm: import('./jsmind.js').default, options: TOptions) => void - ); - name: string; - fn_init: (jm: import('./jsmind.js').default, options: TOptions) => void; -} diff --git a/types/generated/jsmind.shortcut_provider.d.ts b/types/generated/jsmind.shortcut_provider.d.ts deleted file mode 100644 index 99cc4ddd..00000000 --- a/types/generated/jsmind.shortcut_provider.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class ShortcutProvider { - /** - * @param {import('./jsmind.js').default} jm - * @param {{ enable:boolean, handles: Recordvoid>, mapping: Record, id_generator?: ()=>string }} options - */ - constructor( - jm: import('./jsmind.js').default, - options: { - enable: boolean; - handles: Record void>; - mapping: Record; - id_generator?: () => string; - } - ); - jm: import('./jsmind.js').default; - opts: { - enable: boolean; - handles: Record void>; - mapping: Record; - id_generator?: () => string; - }; - /** @type {Record} */ - mapping: Record; - /** @type {Recordvoid>} */ - handles: Record void>; - /** @type {()=>string|null} */ - _newid: () => string | null; - /** @type {Recordvoid>} */ - _mapping: Record void>; - init(): void; - enable_shortcut(): void; - disable_shortcut(): void; - /** @param {KeyboardEvent} e */ - handler(e: KeyboardEvent): boolean; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_addchild(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_addbrother(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_editnode(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_delnode(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_toggle(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_up(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_down(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_left(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e */ - handle_right(_jm: import('./jsmind.js').default, e: KeyboardEvent): void; - /** @param {import('./jsmind.js').default} _jm @param {KeyboardEvent} e @param {number} d */ - _handle_direction(_jm: import('./jsmind.js').default, e: KeyboardEvent, d: number): void; -} diff --git a/types/generated/jsmind.util.d.ts b/types/generated/jsmind.util.d.ts deleted file mode 100644 index 0bb33766..00000000 --- a/types/generated/jsmind.util.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Misc utility collection. - * @type {{ - * file: { read: (file: File, cb:(result:string,name:string)=>void)=>void, save:(data:string,type:string,name:string)=>void}, - * json: { json2string:(v:unknown)=>string, string2json:(s:string)=>unknown, merge:(b:object,a:object)=>object }, - * uuid: { newid:()=>string }, - * text: { is_empty:(s?:string)=>boolean } - * }} - */ -export const util: { - file: { - read: (file: File, cb: (result: string, name: string) => void) => void; - save: (data: string, type: string, name: string) => void; - }; - json: { - json2string: (v: unknown) => string; - string2json: (s: string) => unknown; - merge: (b: object, a: object) => object; - }; - uuid: { - newid: () => string; - }; - text: { - is_empty: (s?: string) => boolean; - }; -}; diff --git a/types/generated/jsmind.view_provider.d.ts b/types/generated/jsmind.view_provider.d.ts deleted file mode 100644 index e126883b..00000000 --- a/types/generated/jsmind.view_provider.d.ts +++ /dev/null @@ -1,433 +0,0 @@ -export class ViewProvider { - /** - * View layer: DOM nodes, editor, graph and zoom. - * @param {import('./jsmind.js').default} jm - jsMind instance - * @param {{ - * engine: 'canvas'|'svg', - * enable_device_pixel_ratio: boolean, - * hmargin: number, - * vmargin: number, - * line_width: number, - * line_color: string, - * line_style: 'curved'|'straight', - * custom_line_render?: Function, - * draggable: boolean, - * hide_scrollbars_when_draggable: boolean, - * node_overflow: 'hidden'|'wrap', - * zoom: {min:number, max:number, step:number, mask_key:number}, - * custom_node_render?: Function, - * expander_style: 'char'|'number' - * }} options - View configuration options - */ - constructor( - jm: import('./jsmind.js').default, - options: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - } - ); - opts: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - }; - jm: import('./jsmind.js').default; - layout: import('./jsmind.layout_provider.js').LayoutProvider; - container: HTMLElement; - e_panel: HTMLElement; - e_nodes: HTMLElement; - size: { - w: number; - h: number; - }; - selected_node: import('./jsmind.node.js').Node; - editing_node: import('./jsmind.node.js').Node; - graph: - | { - view: ViewProvider; - opts: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - }; - e_svg: SVGElement; - size: { - w: number; - h: number; - }; - lines: SVGPathElement[]; - line_drawing: { - straight: ( - path: SVGPathElement, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - curved: ( - path: SVGPathElement, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - }; - init_line_render(): void; - drawing: ( - path: SVGPathElement, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - element(): SVGSVGElement; - set_size(w: number, h: number): void; - clear(): void; - draw_line( - pout: { - x: number; - y: number; - }, - pin: { - x: number; - y: number; - }, - offset: { - x: number; - y: number; - }, - color?: string | undefined - ): void; - copy_to( - dest_canvas_ctx: CanvasRenderingContext2D, - callback?: (() => void) | undefined - ): void; - _bezier_to( - path: SVGPathElement, - x1: number, - y1: number, - x2: number, - y2: number - ): void; - _line_to(path: SVGPathElement, x1: number, y1: number, x2: number, y2: number): void; - } - | { - opts: { - engine: 'canvas' | 'svg'; - enable_device_pixel_ratio: boolean; - hmargin: number; - vmargin: number; - line_width: number; - line_color: string; - line_style: 'curved' | 'straight'; - custom_line_render?: Function; - draggable: boolean; - hide_scrollbars_when_draggable: boolean; - node_overflow: 'hidden' | 'wrap'; - zoom: { - min: number; - max: number; - step: number; - mask_key: number; - }; - custom_node_render?: Function; - expander_style: 'char' | 'number'; - }; - e_canvas: HTMLElement; - canvas_ctx: CanvasRenderingContext2D; - size: { - w: number; - h: number; - }; - line_drawing: { - straight: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - curved: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - }; - dpr: number; - init_line_render(): void; - drawing: ( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) => void; - element(): HTMLCanvasElement; - set_size(w: number, h: number): void; - clear(): void; - draw_line( - pout: { - x: number; - y: number; - }, - pin: { - x: number; - y: number; - }, - offset: { - x: number; - y: number; - }, - color?: string | undefined - ): void; - copy_to( - dest_canvas_ctx: CanvasRenderingContext2D, - callback?: (() => void) | undefined - ): void; - _bezier_to( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ): void; - _line_to( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ): void; - }; - render_node: (ele: HTMLElement, node: import('./jsmind.node.js').Node) => void; - zoom_current: number; - device_pixel_ratio: number; - _initialized: boolean; - /** Initialize DOM structure, graph and editor. */ - init(): void; - e_editor: HTMLElement; - /** - * Add a delegated event handler. - * @param {import('./jsmind.js').default} obj - * @param {string} event_name - * @param {(e:Event)=>void} event_handle - * @param {boolean=} capture_by_panel - */ - add_event( - obj: import('./jsmind.js').default, - event_name: string, - event_handle: (e: Event) => void, - capture_by_panel?: boolean | undefined - ): void; - /** - * @param {HTMLElement|null} element - * @returns {string|null} - */ - get_binded_nodeid(element: HTMLElement | null): string | null; - /** - * @param {HTMLElement|null} element - * @returns {boolean} - */ - is_node(element: HTMLElement | null): boolean; - /** - * @param {HTMLElement} element - * @returns {boolean} - */ - is_expander(element: HTMLElement): boolean; - reset(): void; - reset_theme(): void; - /** Reset custom styles for all nodes. */ - reset_custom_style(): void; - /** Load and initialize the view. */ - load(): void; - /** Calculate and set the expanded canvas size. */ - expand_size(): void; - /** - * Initialize size data for a node. - * @param {import('./jsmind.node.js').Node} node - Target node - */ - init_nodes_size(node: import('./jsmind.node.js').Node): void; - /** Initialize DOM elements for all nodes. */ - init_nodes(): void; - /** - * Add a new node to the view. - * @param {import('./jsmind.node.js').Node} node - Node to add - */ - add_node(node: import('./jsmind.node.js').Node): void; - /** - * Run function in compatibility mode if container is not visible. - * @param {Function} func - Function to execute - */ - run_in_c11y_mode_if_needed(func: Function): void; - /** - * Create a DOM element for a node and append to parent container. - * @param {import('./jsmind.node.js').Node} node - * @param {HTMLElement} parent_node - */ - create_node_element(node: import('./jsmind.node.js').Node, parent_node: HTMLElement): void; - /** - * Remove a node from the view. - * @param {import('./jsmind.node.js').Node} node - Node to remove - */ - remove_node(node: import('./jsmind.node.js').Node): void; - /** - * Update a node's display. - * @param {import('./jsmind.node.js').Node} node - Node to update - */ - update_node(node: import('./jsmind.node.js').Node): void; - /** - * Select a node visually. - * @param {import('./jsmind.node.js').Node|null} node - Node to select - */ - select_node(node: import('./jsmind.node.js').Node | null): void; - /** Clear node selection. */ - select_clear(): void; - /** - * Get currently editing node. - * @returns {import('./jsmind.node.js').Node|null} Currently editing node - */ - get_editing_node(): import('./jsmind.node.js').Node | null; - /** - * Check if any node is being edited. - * @returns {boolean} True if editing - */ - is_editing(): boolean; - /** - * Begin editing a node. - * @param {import('./jsmind.node.js').Node} node - Node to edit - */ - edit_node_begin(node: import('./jsmind.node.js').Node): void; - /** End editing current node. */ - edit_node_end(): void; - /** @returns {{x:number,y:number}} */ - get_view_offset(): { - x: number; - y: number; - }; - /** Resize the view to fit container. */ - resize(): void; - /** - * Internal show implementation. - * @private - */ - private _show; - /** - * Zoom in the view. - * @param {MouseEvent=} e - Mouse event for zoom center - * @returns {boolean} True if zoom succeeded - */ - zoom_in(e?: MouseEvent | undefined): boolean; - /** - * Zoom out the view. - * @param {MouseEvent=} e - Mouse event for zoom center - * @returns {boolean} True if zoom succeeded - */ - zoom_out(e?: MouseEvent | undefined): boolean; - /** - * Set zoom level and keep scroll around zoom center. - * @param {number} zoom - * @param {MouseEvent=} e - */ - set_zoom(zoom: number, e?: MouseEvent | undefined): boolean; - /** @param {boolean=} keep_center */ - show(keep_center?: boolean | undefined): void; - relayout(): void; - /** @param {import('./jsmind.node.js').Node} node */ - save_location(node: import('./jsmind.node.js').Node): void; - /** @param {import('./jsmind.node.js').Node} node */ - restore_location(node: import('./jsmind.node.js').Node): void; - clear_nodes(): void; - /** Render node elements and expanders to screen. */ - show_nodes(): void; - /** @param {import('./jsmind.node.js').Node} node @param {{x:number,y:number}} view_offset */ - _show_expander( - node: import('./jsmind.node.js').Node, - view_offset: { - x: number; - y: number; - } - ): void; - /** @param {import('./jsmind.node.js').Node} node */ - _get_expander_text(node: import('./jsmind.node.js').Node): number | '...' | '-' | '+'; - /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ - _default_node_render(ele: HTMLElement, node: import('./jsmind.node.js').Node): void; - /** @param {HTMLElement} ele @param {import('./jsmind.node.js').Node} node */ - _custom_node_render(ele: HTMLElement, node: import('./jsmind.node.js').Node): void; - /** @param {import('./jsmind.node.js').Node} node */ - reset_node_custom_style(node: import('./jsmind.node.js').Node): void; - /** @param {HTMLElement} node_element @param {Record} node_data */ - _reset_node_custom_style( - node_element: HTMLElement, - node_data: Record - ): void; - /** @param {import('./jsmind.node.js').Node} node */ - restore_selected_node_custom_style(node: import('./jsmind.node.js').Node): void; - /** @param {import('./jsmind.node.js').Node} node */ - clear_selected_node_custom_style(node: import('./jsmind.node.js').Node): void; - clear_lines(): void; - show_lines(): void; - /** - * Enable/disable dragging the whole canvas with mouse. - * @param {boolean} enabled - */ - setup_canvas_draggable(enabled: boolean): void; - /** @param {import('./jsmind.node.js').Node} node */ - center_node(node: import('./jsmind.node.js').Node): boolean; - /** @param {MouseEvent=} e */ - zoomIn(e?: MouseEvent | undefined): boolean; - /** @param {MouseEvent=} e */ - zoomOut(e?: MouseEvent | undefined): boolean; - /** @param {number} zoom @param {MouseEvent=} e */ - setZoom(zoom: number, e?: MouseEvent | undefined): boolean; -} diff --git a/types/generated/plugins/jsmind.draggable-node.d.ts b/types/generated/plugins/jsmind.draggable-node.d.ts deleted file mode 100644 index a83fa8a6..00000000 --- a/types/generated/plugins/jsmind.draggable-node.d.ts +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Draggable node plugin for jsMind. - */ -export class DraggableNode { - /** - * Create draggable node plugin instance. - * @param {import('../jsmind.js').default} jm - jsMind instance - * @param {Partial} options - Plugin options - */ - constructor(jm: import('../jsmind.js').default, options: Partial); - version: string; - /** @type {import('../jsmind.js').default} */ - jm: import('../jsmind.js').default; - /** @type {DraggableNodeOptions} */ - options: DraggableNodeOptions; - /** @type {HTMLCanvasElement|null} */ - e_canvas: HTMLCanvasElement | null; - /** @type {CanvasRenderingContext2D|null} */ - canvas_ctx: CanvasRenderingContext2D | null; - /** @type {HTMLElement|null} */ - shadow: HTMLElement | null; - /** @type {number} */ - shadow_p_x: number; - /** @type {number} */ - shadow_p_y: number; - /** @type {number} */ - shadow_w: number; - /** @type {number} */ - shadow_h: number; - /** @type {import('../jsmind.node.js').Node|null} */ - active_node: import('../jsmind.node.js').Node | null; - /** @type {import('../jsmind.node.js').Node|null} */ - target_node: import('../jsmind.node.js').Node | null; - /** @type {number|null} */ - target_direct: number | null; - /** @type {number} */ - client_w: number; - /** @type {number} */ - client_h: number; - /** @type {number} */ - offset_x: number; - /** @type {number} */ - offset_y: number; - /** @type {number} */ - hlookup_delay: number; - /** @type {number} */ - hlookup_timer: number; - /** @type {boolean} */ - capture: boolean; - /** @type {boolean} */ - moved: boolean; - /** @type {boolean} */ - canvas_draggable: boolean; - /** @type {HTMLElement} */ - view_panel: HTMLElement; - /** @type {DOMRect|null} */ - view_panel_rect: DOMRect | null; - /** Initialize the draggable node plugin. */ - init(): void; - /** Resize canvas and shadow elements. */ - resize(): void; - /** Create canvas for drawing drag lines. */ - create_canvas(): void; - create_shadow(): void; - /** - * Reset shadow element style and cache its size. - * @param {HTMLElement} el - The node element to mirror as shadow - */ - reset_shadow(el: HTMLElement): void; - /** Show the shadow element. */ - show_shadow(): void; - /** Hide the shadow element. */ - hide_shadow(): void; - /** - * Draw a helper line between the shadow and target node. - * @param {{x:number,y:number}} shadow_p - Shadow anchor point - * @param {{x:number,y:number}} node_p - Target node anchor point - * @param {boolean} invalid - Whether current target is invalid - */ - magnet_shadow( - shadow_p: { - x: number; - y: number; - }, - node_p: { - x: number; - y: number; - }, - invalid: boolean - ): void; - /** Clear helper lines from canvas. */ - clear_lines(): void; - /** - * Draw a straight helper line. - * @param {number} x1 - * @param {number} y1 - * @param {number} x2 - * @param {number} y2 - */ - canvas_lineto(x1: number, y1: number, x2: number, y2: number): void; - /** Bind mouse/touch events for dragging. */ - event_bind(): void; - /** - * Begin dragging interaction. - * @param {MouseEvent|TouchEvent} e - Pointer down event - */ - dragstart(e: MouseEvent | TouchEvent): void; - view_draggable: boolean; - client_hw: number; - client_hh: number; - /** - * Drag handler to move shadow and auto-scroll container. - * @param {MouseEvent|TouchEvent} e - Pointer move event - */ - drag(e: MouseEvent | TouchEvent): void; - /** - * Finish dragging, move the node if applicable. - * @param {MouseEvent|TouchEvent} e - Pointer up event - */ - dragend(e: MouseEvent | TouchEvent): void; - /** - * Find the closest node element from an event target. - * @param {HTMLElement} el - Current DOM element - * @returns {HTMLElement|null} Matched node element or null - */ - find_node_element(el: HTMLElement): HTMLElement | null; - /** Recompute target node under the shadow and draw helper. */ - lookup_target_node(): void; - /** - * Get X coordinate of root node center. - * @returns {number} - */ - get_root_x(): number; - /** - * Lookup overlapping node's parent near the shadow position. - * @param {number} direction - Direction constant - * @returns {import('../jsmind.node.js').Node|null} - */ - lookup_overlapping_node_parent(direction: number): import('../jsmind.node.js').Node | null; - /** - * Find node's parent by a screen location. - * @param {number} x - Client X - * @param {number} y - Client Y - * @returns {import('../jsmind.node.js').Node|null} - */ - lookup_node_parent_by_location(x: number, y: number): import('../jsmind.node.js').Node | null; - /** - * Lookup the closest node along a direction. - * @param {number} direction - * @returns {import('../jsmind.node.js').Node} - */ - lookup_close_node(direction: number): import('../jsmind.node.js').Node; - /** - * Check if shadow is on the target side of a node. - * @param {import('../jsmind.node.js').Node} node - * @param {number} dir - * @returns {boolean} - */ - shadow_on_target_side(node: import('../jsmind.node.js').Node, dir: number): boolean; - /** - * Distance from shadow to the right side of a node. - * @param {import('../jsmind.node.js').Node} node - * @returns {number} - */ - shadow_to_right_of_node(node: import('../jsmind.node.js').Node): number; - /** - * Distance from shadow to the left side of a node. - * @param {import('../jsmind.node.js').Node} node - * @returns {number} - */ - shadow_to_left_of_node(node: import('../jsmind.node.js').Node): number; - /** - * Vertical distance between shadow centerline and node centerline. - * @param {import('../jsmind.node.js').Node} node - * @returns {number} - */ - shadow_to_base_line_of_node(node: import('../jsmind.node.js').Node): number; - /** - * Manhattan distance to a node along a direction. - * @param {import('../jsmind.node.js').Node} node - * @param {number} dir - * @returns {number} - */ - shadow_to_node(node: import('../jsmind.node.js').Node, dir: number): number; - /** - * Calculate connection points of a node and the shadow. - * @param {import('../jsmind.node.js').Node} node - * @param {number} dir - * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}} - */ - calc_point_of_node( - node: import('../jsmind.node.js').Node, - dir: number - ): { - sp: { - x: number; - y: number; - }; - np: { - x: number; - y: number; - }; - }; - /** - * Move a node to a new parent/position. - * @param {import('../jsmind.node.js').Node} src_node - * @param {import('../jsmind.node.js').Node|null} target_node - * @param {number|null} target_direct - */ - move_node( - src_node: import('../jsmind.node.js').Node, - target_node: import('../jsmind.node.js').Node | null, - target_direct: number | null - ): void; - /** - * Handle jsMind events. - * @param {number|string} type - Event type - * @param {object} [data] - Event data - */ - jm_event_handle(type: number | string, data?: object): void; -} -/** - * Draggable node plugin registration. - * @type {import('../jsmind.plugin.js').Plugin>} - */ -export const draggable_plugin: import('../jsmind.plugin.js').Plugin>; -export default DraggableNode; -/** - * Default options for draggable node plugin. - */ -export type DraggableNodeOptions = { - line_width?: number; - line_color?: string; - line_color_invalid?: string; - lookup_delay?: number; - lookup_interval?: number; - scrolling_trigger_width?: number; - scrolling_step_length?: number; - shadow_node_class_name?: string; -}; diff --git a/types/generated/plugins/jsmind.screenshot.d.ts b/types/generated/plugins/jsmind.screenshot.d.ts deleted file mode 100644 index 06eeb283..00000000 --- a/types/generated/plugins/jsmind.screenshot.d.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Screenshot plugin for jsMind. - */ -export class JmScreenshot { - /** - * Create screenshot plugin instance. - * @param {import('../jsmind.js').default} jm - jsMind instance - * @param {Partial} options - Plugin options - */ - constructor(jm: import('../jsmind.js').default, options: Partial); - version: string; - /** @type {import('../jsmind.js').default} */ - jm: import('../jsmind.js').default; - /** @type {ScreenshotOptions} */ - options: ScreenshotOptions; - /** @type {number} */ - dpr: number; - /** Take a screenshot of the mind map. */ - shoot(): void; - /** - * Create canvas for screenshot. - * @returns {HTMLCanvasElement} Canvas element - */ - create_canvas(): HTMLCanvasElement; - /** - * Clean up canvas element. - * @param {HTMLCanvasElement} c - Canvas to remove - */ - clear(c: HTMLCanvasElement): void; - /** - * Draw background on canvas. - * @param {CanvasRenderingContext2D} ctx - Canvas context - * @returns {Promise} Promise resolving to context - */ - draw_background(ctx: CanvasRenderingContext2D): Promise; - /** - * Draw connection lines on canvas by copying from view graph. - * @param {CanvasRenderingContext2D} ctx - * @returns {Promise} - */ - draw_lines(ctx: CanvasRenderingContext2D): Promise; - /** - * Draw node DOM into canvas via SVG snapshot. - * @param {CanvasRenderingContext2D} ctx - * @returns {Promise} - */ - draw_nodes(ctx: CanvasRenderingContext2D): Promise; - /** - * Draw watermark text on canvas. - * @param {HTMLCanvasElement} c - * @param {CanvasRenderingContext2D} ctx - * @returns {CanvasRenderingContext2D} - */ - draw_watermark(c: HTMLCanvasElement, ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; - /** - * Load image from URL and resolve img element. - * @param {string} url - * @returns {Promise} - */ - load_image(url: string): Promise; - /** - * Trigger download of canvas content as PNG. - * @param {HTMLCanvasElement} c - */ - download(c: HTMLCanvasElement): void; -} -/** - * Screenshot plugin registration. - * @type {import('../jsmind.plugin.js').Plugin>} - */ -export const screenshot_plugin: import('../jsmind.plugin.js').Plugin>; -export default JmScreenshot; -/** - * Default options for screenshot plugin. - */ -export type ScreenshotOptions = { - filename?: string | null; - watermark?: { - left?: string | Location; - right?: string; - }; - background?: string; -}; From 121c28c6406bead2f51bafbc72bc6c98ca09ad79 Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 00:59:33 +0800 Subject: [PATCH 19/24] chore(build): fix UMD plugin bundles by adding output.name and using named exports Add output.name for draggable-node and screenshot UMD outputs Set exports: 'named' to avoid mixed default/named export warning No runtime/export path changes; only build stability --- .config/rollup.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.config/rollup.config.js b/.config/rollup.config.js index 599a93f3..fa1d3471 100644 --- a/.config/rollup.config.js +++ b/.config/rollup.config.js @@ -25,6 +25,7 @@ export default [ { input: 'src/plugins/jsmind.draggable-node.js', output: { + name: 'jsMindDraggableNode', file: 'es6/jsmind.draggable-node.js', format: 'umd', banner: '/**\n* @license BSD-3-Clause\n* @copyright 2014-2025 hizzgdev@163.com\n*\n* Project Home:\n* https://github.com/hizzgdev/jsmind/\n*/', @@ -32,6 +33,7 @@ export default [ globals: { jsmind: 'jsMind', }, + exports: 'named', }, external: ['jsmind'], plugins: [ @@ -48,6 +50,7 @@ export default [ { input: 'src/plugins/jsmind.screenshot.js', output: { + name: 'jsMindScreenshot', file: 'es6/jsmind.screenshot.js', format: 'umd', banner: '/**\n* @license BSD-3-Clause\n* @copyright 2014-2025 hizzgdev@163.com\n*\n* Project Home:\n* https://github.com/hizzgdev/jsmind/\n*/', @@ -56,6 +59,7 @@ export default [ 'jsmind': 'jsMind', 'dom-to-image': 'domtoimage', }, + exports: 'named', }, external: ['jsmind', 'dom-to-image'], plugins: [ From f1dbc0ccf7a10baf9c9422b7980db1d5b40031bc Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 01:12:26 +0800 Subject: [PATCH 20/24] chore: format package.json --- package.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 7e4e32fd..de0e8be8 100644 --- a/package.json +++ b/package.json @@ -26,13 +26,13 @@ "doc": "docs", "example": "example" }, - "files": [ - "es6", - "style", - "types", - "LICENSE", - "README.md" - ], + "files": [ + "es6", + "style", + "types", + "LICENSE", + "README.md" + ], "scripts": { "server": "http-server", "build": "rollup -c .config/rollup.config.js", @@ -43,9 +43,9 @@ "gen:dts:check": "npm run gen:dts && test -d types/generated && ls types/generated >/dev/null", "format": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --write .", "format-check": "prettier --config .config/prettierrc.json --ignore-path .config/prettierignore --check .", - "pretest": "npm run gen:dts", - "prepare": "npm run gen:dts", - "prepublishOnly": "npm run build && npm run gen:dts" + "pretest": "npm run gen:dts", + "prepare": "npm run gen:dts", + "prepublishOnly": "npm run build && npm run gen:dts" }, "repository": { "type": "git", From fc4c4a71ba1e4005d4b0a9af4ba3990382fc0efd Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 01:19:55 +0800 Subject: [PATCH 21/24] chore(ci): exclude generated declaration files from Prettier check (types/generated) --- .config/prettierignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.config/prettierignore b/.config/prettierignore index 4d106a8c..75c07993 100644 --- a/.config/prettierignore +++ b/.config/prettierignore @@ -8,3 +8,4 @@ node_modules screenshots LICENSE package-lock.json +types/generated From 6e57fb6c2c3e0ce9b15d5a1af8f6618a3a013741 Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 01:23:36 +0800 Subject: [PATCH 22/24] chore(ci): fix Prettier ignore paths for CI by using paths relative to ignore file --- .config/prettierignore | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/prettierignore b/.config/prettierignore index 75c07993..67d30674 100644 --- a/.config/prettierignore +++ b/.config/prettierignore @@ -1,11 +1,11 @@ .config -.github -.vscode -docs -es6 -js-legacy -node_modules -screenshots -LICENSE -package-lock.json -types/generated +../.github +../.vscode +../docs +../es6 +../js-legacy +../node_modules +../screenshots +../LICENSE +../package-lock.json +../types/generated From 33c39627acad75f6908a770a896648907d60928f Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 01:58:54 +0800 Subject: [PATCH 23/24] chore(types): generate top-level types entry from src and ignore handwritten index.d.ts Add src/types-index.ts and emit types/generated/types-index.d.ts via tsconfig.decls.json; point package.json exports.types and top-level types to the generated file; remove types/index.d.ts from VCS --- package.json | 4 ++-- types/index.d.ts => src/types-index.ts | 18 ++++++++++-------- tsconfig.decls.json | 2 +- tsconfig.json | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) rename types/index.d.ts => src/types-index.ts (59%) diff --git a/package.json b/package.json index de0e8be8..c90885a6 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,12 @@ "version": "0.8.7", "description": "jsMind is a pure javascript library for mindmap, it base on html5 canvas. jsMind was released under BSD license, you can embed it in any project, if only you observe the license.", "main": "es6/jsmind.js", - "types": "types/index.d.ts", + "types": "types/generated/types-index.d.ts", "exports": { ".": { "import": "./es6/jsmind.js", "require": "./es6/jsmind.js", - "types": "./types/index.d.ts" + "types": "./types/generated/types-index.d.ts" }, "./draggable-node": { "import": "./es6/jsmind.draggable-node.js", diff --git a/types/index.d.ts b/src/types-index.ts similarity index 59% rename from types/index.d.ts rename to src/types-index.ts index b02b6a9f..11a9e500 100644 --- a/types/index.d.ts +++ b/src/types-index.ts @@ -1,24 +1,26 @@ // Aggregated public typings entry: re-export generated types without compatibility layer -export { default } from './generated/jsmind'; +export { default } from './jsmind'; // Legacy named exports back-compat: re-export classes and key option/data types if present -export { Node } from './generated/jsmind.node'; -export { Mind } from './generated/jsmind.mind'; +export { Node } from './jsmind.node'; +export { Mind } from './jsmind.mind'; // Export strict options and meta types from generated -export type { JsMindRuntimeOptions as JsMindOptions } from './generated/jsmind.option'; +export type { JsMindRuntimeOptions as JsMindOptions } from './jsmind.option'; export type { MindMapMeta, NodeTreeData, NodeTreeFormat, NodeArrayItem, NodeArrayFormat, -} from './generated/jsmind.format'; +} from './jsmind.format'; // Static singletons / enums passthrough -export { Direction as direction, EventType as event_type } from './generated/jsmind.common'; -export { $ } from './generated/jsmind.dom'; -export { util } from './generated/jsmind.util'; +export { Direction as direction, EventType as event_type } from './jsmind.common'; +export { $ } from './jsmind.dom'; +export { util } from './jsmind.util'; // Plugin export paths remain under subpath exports // typings for subpath are referenced from package.json exports.types + + diff --git a/tsconfig.decls.json b/tsconfig.decls.json index 7a29057e..4b4ef31d 100644 --- a/tsconfig.decls.json +++ b/tsconfig.decls.json @@ -15,6 +15,6 @@ "rootDir": "src", "baseUrl": "." }, - "include": ["src/**/*.js"], + "include": ["src/**/*.js", "src/**/*.ts"], "exclude": ["node_modules", "dist", "tests", "example", "es6", "js-legacy", "js-legacy/**/*.js"] } diff --git a/tsconfig.json b/tsconfig.json index 865a7c0b..afc73871 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "noEmit": true, "baseUrl": ".", "paths": { - "jsmind": ["types/index.d.ts"], + "jsmind": ["types/generated/types-index.d.ts"], "jsmind/draggable-node": ["types/generated/plugins/jsmind.draggable-node.d.ts"], "jsmind/screenshot": ["types/generated/plugins/jsmind.screenshot.d.ts"] } From d0828613e46d6b1347c1e4c645d3f48f3103d8fc Mon Sep 17 00:00:00 2001 From: umbraci Date: Mon, 11 Aug 2025 02:03:39 +0800 Subject: [PATCH 24/24] chore: format types-index.ts --- src/types-index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/types-index.ts b/src/types-index.ts index 11a9e500..a3aea304 100644 --- a/src/types-index.ts +++ b/src/types-index.ts @@ -22,5 +22,3 @@ export { util } from './jsmind.util'; // Plugin export paths remain under subpath exports // typings for subpath are referenced from package.json exports.types - -