From 4e411800813bae48827f6a069062a26437b1f4e3 Mon Sep 17 00:00:00 2001 From: dziksu Date: Mon, 13 Oct 2025 15:42:46 +0200 Subject: [PATCH] feature: add typescript / tsup / rebuild core script / refactor Signed-off-by: dziksu --- .eslintrc.json | 29 + .gitignore | 32 + .npmignore | 0 .prettierignore | 7 + .prettierrc | 9 + .prettierrc.json | 12 + API.md | 678 ++++--- README.md | 471 +++-- demo/demo-typescript.html | 305 +++ dist/index.d.mts | 222 +++ dist/index.d.ts | 222 +++ dist/index.js | 216 +++ dist/index.js.map | 1 + dist/index.mjs | 216 +++ dist/index.mjs.map | 1 + dist/walkthrough.min.js | 1 - package-lock.json | 3697 +++++++++++++++++++++++++++++++++++++ package.json | 65 +- src/core.ts | 616 ++++++ src/index.ts | 56 + src/styles.ts | 175 ++ src/types.ts | 136 ++ src/utils.ts | 111 ++ src/walkthrough.js | 825 --------- tsconfig.json | 24 + tsup.config.ts | 18 + 26 files changed, 6766 insertions(+), 1379 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .prettierrc.json create mode 100644 demo/demo-typescript.html create mode 100644 dist/index.d.mts create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/index.mjs create mode 100644 dist/index.mjs.map delete mode 100644 dist/walkthrough.min.js create mode 100644 package-lock.json create mode 100644 src/core.ts create mode 100644 src/index.ts create mode 100644 src/styles.ts create mode 100644 src/types.ts create mode 100644 src/utils.ts delete mode 100644 src/walkthrough.js create mode 100644 tsconfig.json create mode 100644 tsup.config.ts diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..c13dfc2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,29 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module", + "project": "./tsconfig.json" + }, + "plugins": ["@typescript-eslint", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "prettier" + ], + "rules": { + "prettier/prettier": "error", + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "warn" + }, + "env": { + "browser": true, + "es2020": true, + "node": true + } +} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bff960 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Dependencies +node_modules/ + +# Build outputs +*.tsbuildinfo + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Environment +.env +.env.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Testing +coverage/ +.nyc_output/ + diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..4d94904 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +node_modules +dist +coverage +*.min.js +*.log +.DS_Store + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..aab6511 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "all", + "arrowParens": "always", + "tabWidth": 2, + "endOfLine": "auto", + "semi": true +} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..e8b3f26 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2, + "useTabs": false, + "arrowParens": "always", + "bracketSpacing": true, + "endOfLine": "lf" +} + diff --git a/API.md b/API.md index 6388895..4ce95d6 100644 --- a/API.md +++ b/API.md @@ -1,365 +1,443 @@ -# Walkthrough.js API Reference +# WalkthroughJS TypeScript API Reference -Complete API documentation for Walkthrough.js library. +Complete TypeScript API documentation for WalkthroughJS library. ## Table of Contents -- [Core Methods](#core-methods) -- [Configuration Objects](#configuration-objects) -- [Step Objects](#step-objects) -- [Template Functions](#template-functions) -- [Event Callbacks](#event-callbacks) -- [Utility Methods](#utility-methods) +- [Core Classes](#core-classes) +- [Types & Interfaces](#types--interfaces) +- [Configuration](#configuration) +- [Methods](#methods) +- [Callbacks](#callbacks) +- [Utilities](#utilities) -## Core Methods +## Core Classes -### `walkthrough.fromAttributes(options?)` +### `Walkthrough` -Creates a walkthrough from HTML data attributes. +Main class for creating and managing walkthroughs. -**Parameters:** +```typescript +import { Walkthrough, WalkthroughOptions } from '@walkthroughjs/core'; -- `options` (Object, optional) - Configuration options +const options: WalkthroughOptions = { + progressColor: '#4CAF50', + showProgress: true +}; -**Returns:** Walkthrough instance +const tour = new Walkthrough(options); +``` -**Example:** +## Types & Interfaces + +### `WalkthroughOptions` + +Complete configuration options interface. + +```typescript +interface WalkthroughOptions { + // Visual + overlayColor?: string; + highlightPadding?: number; + animationDuration?: number; + scrollDuration?: number; + scrollOffset?: number; + zIndex?: number; + + // Popup configuration + popupWidth?: number; + popupOffset?: number; + popupClass?: string; + + // Progress + showProgress?: boolean; + progressColor?: string; + + // Buttons + showButtons?: boolean; + showSkip?: boolean; + skipText?: string; + prevText?: string; + nextText?: string; + finishText?: string; + + // Keyboard navigation + keyboard?: boolean; + escapeToExit?: boolean; + arrowNavigation?: boolean; + + // Storage + cookieName?: string; + cookieExpiry?: number; + rememberProgress?: boolean; + + // Behavior + closeOnOverlay?: boolean; + autoStart?: boolean; + startDelay?: number; + + // Attribute names for HTML config + attributePrefix?: string; + stepAttribute?: string; + titleAttribute?: string; + textAttribute?: string; + positionAttribute?: string; +} +``` -```javascript -const tour = walkthrough.fromAttributes({ - progressColor: '#667eea', - rememberProgress: false -}); +### `WalkthroughStep` + +Step configuration interface. + +```typescript +interface WalkthroughStep { + element: string | HTMLElement; + title?: string; + text?: string; + position?: PopupPosition; + step?: number; + skipText?: string; + prevText?: string; + nextText?: string; + finishText?: string; +} ``` -### `walkthrough.fromJSON(config)` +### `PopupPosition` + +Valid popup positions. + +```typescript +type PopupPosition = 'top' | 'bottom' | 'left' | 'right'; +``` -Creates a walkthrough from a JSON configuration object. +### `WalkthroughCallbacks` -**Parameters:** +Event callback functions. -- `config` (Object) - Complete configuration object +```typescript +interface WalkthroughCallbacks { + onStart?: () => void; + onStep?: (step: WalkthroughStep, index: number) => void; + onFinish?: () => void; + onEnd?: () => void; +} +``` -**Returns:** Walkthrough instance +### `WalkthroughTemplates` -**Example:** +Custom template functions. -```javascript -const tour = walkthrough.fromJSON({ - steps: [...], - options: {...}, - callbacks: {...} -}); +```typescript +interface WalkthroughTemplates { + popup?: (step: WalkthroughStep, index: number, totalSteps: number) => string; +} ``` -### `walkthrough.start(steps, options?)` +### `WalkthroughConfig` -Quick start method to create and start a walkthrough immediately. +Complete configuration object. -**Parameters:** +```typescript +interface WalkthroughConfig { + steps?: WalkthroughStep[]; + options?: WalkthroughOptions; + callbacks?: WalkthroughCallbacks; + templates?: WalkthroughTemplates; +} +``` -- `steps` (Array) - Array of step objects -- `options` (Object, optional) - Configuration options +## Configuration -**Returns:** Walkthrough instance +### Using the Constructor -**Example:** +```typescript +const tour = new Walkthrough({ + progressColor: '#667eea', + showProgress: true, + keyboard: true, + rememberProgress: true +}); +``` -```javascript -const tour = walkthrough.start([ - { element: '.header', title: 'Header', text: 'This is the header' } -], { progressColor: '#28a745' }); +### Using `configure()` Method + +```typescript +tour.configure({ + steps: [ + { element: '.step-1', title: 'Step 1', text: 'First step' }, + { element: '.step-2', title: 'Step 2', text: 'Second step' } + ], + options: { + progressColor: '#28a745' + }, + callbacks: { + onStart: () => console.log('Started'), + onFinish: () => console.log('Finished') + } +}); ``` -## Configuration Objects +## Methods -### Options Object +### Instance Methods -```javascript -{ - // Visual options - progressColor: '#007bff', // Progress indicator color - highlightPadding: 10, // Padding around highlighted elements - animationDuration: 300, // Animation duration (ms) - backdrop: true, // Show backdrop overlay - backdropColor: 'rgba(0,0,0,0.5)', // Backdrop color - - // Behavior options - rememberProgress: true, // Save progress to localStorage - showProgress: true, // Show step counter - allowClose: true, // Allow closing walkthrough - autoStart: false, // Start automatically - - // Navigation options - showButtons: true, // Show next/prev buttons - showSkip: true, // Show skip button - keyboardNavigation: true, // Enable keyboard controls - - // Positioning - defaultPosition: 'bottom', // Default popup position - offset: 10, // Distance from target element - - // Text customization - nextText: 'Next', // Default next button text - prevText: 'Previous', // Default previous button text - skipText: 'Skip', // Skip button text - finishText: 'Finish', // Finish button text - closeText: '×' // Close button text -} +#### `start(stepIndex?: number | null): void` + +Start the walkthrough from a specific step (or from the beginning). + +```typescript +tour.start(); // Start from beginning +tour.start(2); // Start from step 2 (0-indexed) ``` -### Callbacks Object - -```javascript -{ - onStart: (tour) => {}, // Called when tour starts - onStep: (step, index, tour) => {}, // Called on each step - onNext: (step, index, tour) => {}, // Called when going to next step - onPrev: (step, index, tour) => {}, // Called when going to previous step - onFinish: (tour) => {}, // Called when tour completes - onClose: (tour) => {}, // Called when tour is closed - onDestroy: (tour) => {}, // Called when tour is destroyed - - // Step-specific callbacks - beforeStep: (step, index, tour) => {}, // Before showing step - afterStep: (step, index, tour) => {}, // After showing step - - // Validation callbacks - canNext: (step, index, tour) => true, // Return false to prevent next - canPrev: (step, index, tour) => true, // Return false to prevent prev - canClose: (tour) => true // Return false to prevent close -} +#### `next(): void` + +Navigate to the next step. + +```typescript +tour.next(); ``` -## Step Objects +#### `prev(): void` -### Basic Step Object +Navigate to the previous step. -```javascript -{ - element: '.my-element', // CSS selector or DOM element - title: 'Step Title', // Step title (optional) - text: 'Step description', // Step description (optional) - position: 'bottom', // Popup position - - // Custom button text - nextText: 'Continue', // Custom next button text - prevText: 'Go Back', // Custom previous button text - - // Step-specific options - highlightPadding: 15, // Override global padding - showButtons: true, // Show/hide buttons for this step - allowClose: true, // Allow closing on this step - - // Custom data - data: { // Custom data for callbacks - category: 'onboarding', - importance: 'high' - } -} +```typescript +tour.prev(); ``` -### Advanced Step Properties +#### `finish(): void` -```javascript -{ - // Element targeting - element: '#my-id', // By ID - element: '.my-class', // By class - element: document.querySelector('.my-element'), // DOM element - element: () => document.querySelector('.dynamic'), // Function - - // Conditional steps - condition: () => true, // Only show if function returns true - - // Custom positioning - position: { - my: 'top center', // Popup anchor point - at: 'bottom center', // Target anchor point - offset: '0 10' // X Y offset - }, - - // Wait conditions - waitFor: '.async-element', // Wait for element to exist - waitTimeout: 5000, // Timeout for wait condition - - // Actions - beforeShow: (step, tour) => {}, // Before showing this step - afterShow: (step, tour) => {}, // After showing this step - onNext: (step, tour) => {}, // When leaving this step - - // Validation - validate: () => true, // Validate before proceeding - validationMessage: 'Please complete this field' -} +Complete the walkthrough normally. + +```typescript +tour.finish(); ``` -## Template Functions - -### Popup Template - -```javascript -templates: { - popup: (step, index, total, tour) => { - return ` -
-
-

${step.title || `Step ${index + 1}`}

- -
-
-

${step.text || ''}

-
- -
- `; - } -} +#### `end(): void` + +End/close the walkthrough. + +```typescript +tour.end(); ``` -### Progress Template - -```javascript -templates: { - progress: (current, total, tour) => { - const percentage = (current / total) * 100; - return ` -
-
- ${current} / ${total} -
- `; - } -} +#### `destroy(): void` + +Clean up and remove all walkthrough elements. + +```typescript +tour.destroy(); ``` -## Instance Methods - -### Navigation Methods - -```javascript -// Basic navigation -tour.start() // Start the walkthrough -tour.next() // Go to next step -tour.prev() // Go to previous step -tour.goTo(index) // Jump to specific step (0-based) -tour.finish() // Complete the walkthrough -tour.close() // Close without completing -tour.destroy() // Clean up and remove - -// Advanced navigation -tour.restart() // Restart from beginning -tour.pause() // Pause the walkthrough -tour.resume() // Resume paused walkthrough +#### `scanForAttributeSteps(): void` + +Scan the DOM for elements with walkthrough attributes. + +```typescript +tour.scanForAttributeSteps(); ``` -### State Methods - -```javascript -// Current state -tour.getCurrentStep() // Get current step object -tour.getCurrentIndex() // Get current step index (0-based) -tour.getTotalSteps() // Get total number of steps -tour.getProgress() // Get progress percentage (0-100) - -// Status checks -tour.isActive() // Check if walkthrough is running -tour.isPaused() // Check if walkthrough is paused -tour.isFinished() // Check if walkthrough completed -tour.canNext() // Check if can go to next step -tour.canPrev() // Check if can go to previous step +#### `configure(config: WalkthroughConfig): void` + +Configure the walkthrough with steps, options, callbacks, and templates. + +```typescript +tour.configure({ + steps: [...], + options: {...}, + callbacks: {...} +}); ``` -### Configuration Methods - -```javascript -// Update options -tour.setOptions(options) // Update configuration options -tour.getOptions() // Get current options - -// Step management -tour.addStep(step, index?) // Add step at index (default: end) -tour.removeStep(index) // Remove step at index -tour.updateStep(index, step) // Update step at index -tour.getStep(index) // Get step at index +### Static Helper Methods + +#### `walkthrough.start(steps, options?)` + +Quick start method. + +```typescript +import { walkthrough } from '@walkthroughjs/core'; + +walkthrough.start([ + { element: '.header', title: 'Header' } +], { + progressColor: '#667eea' +}); ``` -### Event Methods - -```javascript -// Event listeners -tour.on(event, callback) // Add event listener -tour.off(event, callback?) // Remove event listener -tour.emit(event, ...args) // Emit custom event - -// Available events -tour.on('start', (tour) => {}) -tour.on('step', (step, index) => {}) -tour.on('next', (step, index) => {}) -tour.on('prev', (step, index) => {}) -tour.on('finish', (tour) => {}) -tour.on('close', (tour) => {}) +#### `walkthrough.fromAttributes(options?)` + +Create from HTML attributes. + +```typescript +const tour = walkthrough.fromAttributes({ + progressColor: '#667eea' +}); ``` -## Utility Methods +#### `walkthrough.fromJSON(config)` -### Element Utilities +Create from JSON configuration. -```javascript -// Element helpers -walkthrough.utils.getElement(selector) // Get DOM element -walkthrough.utils.isVisible(element) // Check if element visible -walkthrough.utils.scrollToElement(element) // Scroll element into view -walkthrough.utils.getElementPosition(element) // Get element position +```typescript +const tour = walkthrough.fromJSON({ + steps: [...], + options: {...} +}); ``` -### Storage Utilities +## Callbacks + +### Event Lifecycle -```javascript -// Progress storage -walkthrough.storage.save(key, data) // Save to localStorage -walkthrough.storage.load(key) // Load from localStorage -walkthrough.storage.remove(key) // Remove from localStorage -walkthrough.storage.clear() // Clear all walkthrough data +```typescript +tour.configure({ + callbacks: { + // Called when tour starts + onStart: () => { + console.log('Tour started!'); + }, + + // Called on each step + onStep: (step, index) => { + console.log(`Now on step ${index + 1}: ${step.title}`); + analytics.track('walkthrough_step', { step: index }); + }, + + // Called when tour finishes normally + onFinish: () => { + console.log('Tour completed!'); + analytics.track('walkthrough_completed'); + }, + + // Called when tour ends (finish or skip) + onEnd: () => { + console.log('Tour ended'); + } + } +}); ``` -### Animation Utilities +## Utilities + +The library includes several utility functions (internal use, but exported): + +### `easeInOut(t: number): number` + +Easing function for animations. + +### `throttle(func: T, limit: number)` + +Throttle function execution. + +### `adjustColor(color: string, amount: number): string` + +Adjust color brightness. + +### `scrollToElement(element, offset, duration, callback)` + +Smooth scroll to element. + +## TypeScript Usage Examples + +### Basic TypeScript Setup + +```typescript +import { Walkthrough, WalkthroughOptions, WalkthroughStep } from '@walkthroughjs/core'; + +const steps: WalkthroughStep[] = [ + { + element: '#feature-1', + title: 'Feature 1', + text: 'Description of feature 1', + position: 'bottom' + }, + { + element: document.querySelector('.feature-2') as HTMLElement, + title: 'Feature 2', + text: 'Description of feature 2', + position: 'top' + } +]; + +const options: WalkthroughOptions = { + progressColor: '#667eea', + showProgress: true, + keyboard: true +}; + +const tour = new Walkthrough(options); +tour.configure({ steps }); +tour.start(); +``` + +### With Full Type Safety + +```typescript +import type { + WalkthroughConfig, + WalkthroughCallbacks, + WalkthroughStep +} from '@walkthroughjs/core'; + +const callbacks: WalkthroughCallbacks = { + onStart: () => console.log('Started'), + onStep: (step: WalkthroughStep, index: number) => { + console.log(`Step ${index}: ${step.title}`); + }, + onFinish: () => console.log('Finished') +}; + +const config: WalkthroughConfig = { + steps: [ + { element: '.step-1', title: 'Step 1' } + ], + options: { + progressColor: '#4CAF50' + }, + callbacks +}; +``` -```javascript -// Animation helpers -walkthrough.animate.fadeIn(element, duration) -walkthrough.animate.fadeOut(element, duration) -walkthrough.animate.slideIn(element, direction, duration) -walkthrough.animate.slideOut(element, direction, duration) +## Default Values + +All options have sensible defaults: + +```typescript +{ + overlayColor: 'rgba(0, 0, 0, 0.5)', + highlightPadding: 10, + animationDuration: 300, + scrollDuration: 500, + scrollOffset: 100, + zIndex: 99999, + popupWidth: 380, + popupOffset: 15, + popupClass: 'wt-popup', + showProgress: true, + progressColor: '#4CAF50', + showButtons: true, + showSkip: true, + skipText: 'Skip', + prevText: '← Previous', + nextText: 'Next →', + finishText: 'Finish', + keyboard: true, + escapeToExit: true, + arrowNavigation: true, + cookieName: 'walkthrough_progress', + cookieExpiry: 30, + rememberProgress: false, + closeOnOverlay: true, + autoStart: false, + startDelay: 0, + attributePrefix: 'wt', + stepAttribute: 'step', + titleAttribute: 'title', + textAttribute: 'text', + positionAttribute: 'position' +} ``` -## Error Handling - -```javascript -try { - const tour = walkthrough.fromJSON(config); - tour.start(); -} catch (error) { - if (error instanceof walkthrough.WalkthroughError) { - console.error('Walkthrough error:', error.message); - } else { - console.error('Unexpected error:', error); - } -} - -// Error types -walkthrough.WalkthroughError // Base error class -walkthrough.ConfigurationError // Configuration issues -walkthrough.ElementNotFoundError // Target element not found -walkthrough.ValidationError // Step validation failed -``` \ No newline at end of file diff --git a/README.md b/README.md index 8f7fe96..e5b95f6 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -# Walkthrough.js +# WalkthroughJS - TypeScript Edition -Create beautiful, interactive tutorials and onboarding experiences for your web applications with zero dependencies. +Create beautiful, interactive tutorials and onboarding experiences for your web applications with zero dependencies. Now fully rewritten in TypeScript with modern tooling! -[Live Demo](https://ronanarm.github.io/WalkthroughJS/demo/) - -![Walkthrough.js Demo](https://img.shields.io/badge/demo-live-brightgreen) ![Version](https://img.shields.io/badge/version-1.0.0-blue) ![License](https://img.shields.io/badge/license-LGPL-green) +[![npm version](https://img.shields.io/npm/v/@walkthroughjs/core.svg)](https://www.npmjs.com/package/@walkthroughjs/core) +[![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) +[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/) ## ✨ Features +- **🔷 TypeScript First** - Full type safety and IntelliSense support +- **📦 Modern Build** - ESM and CJS support with tsup - **🎨 Beautiful Design** - Modern, polished UI with smooth animations - **⌨️ Keyboard Navigation** - Full support for arrow keys, Enter, and Escape - **📱 Responsive** - Works perfectly on all screen sizes and devices @@ -17,282 +19,277 @@ Create beautiful, interactive tutorials and onboarding experiences for your web - **🎨 Customizable** - Colors, positions, templates, and styling options - **⚡ Multiple Setup Methods** - HTML attributes, JSON config, or quick start - **🧩 Custom Templates** - Complete control over popup HTML structure +- **0️⃣ Zero Dependencies** - Lightweight and fast -## 🚀 Quick Start +## 📦 Installation -### 1\. Include the Library +### NPM (Recommended) -#### A\. Local -```html - +```bash +npm install @walkthroughjs/core ``` -#### B\. UNPKG CDN -```html - -``` +### Yarn -#### C\. jsDelivr CDN -```html - +```bash +yarn add @walkthroughjs/core ``` -#### D\. NPM (Preferred) +### PNPM + ```bash -npm install @ronanarm/walkthroughjs +pnpm add @walkthroughjs/core ``` -### 2\. Add Data Attributes (Easiest Method) +## 🚀 Quick Start + +### TypeScript/JavaScript Module + +```typescript +import { walkthrough } from '@walkthroughjs/core'; + +// Quick start method +walkthrough.start([ + { + element: '.welcome-section', + title: 'Welcome! 👋', + text: 'Let me show you around.', + position: 'bottom' + }, + { + element: '#main-button', + title: 'Main Action', + text: 'Click here to get started.', + position: 'top' + } +]); +``` -```HTML -
- Content to highlight -
- - +### Using TypeScript Class + +```typescript +import { Walkthrough, WalkthroughOptions } from '@walkthroughjs/core'; + +const options: WalkthroughOptions = { + progressColor: '#667eea', + showProgress: true, + rememberProgress: true +}; + +const tour = new Walkthrough(options); + +tour.configure({ + steps: [ + { + element: '.feature-1', + title: 'Feature 1', + text: 'This is an amazing feature.' + } + ], + callbacks: { + onStart: () => console.log('Tour started!'), + onFinish: () => console.log('Tour completed!') + } +}); + +tour.start(); ``` -### 3\. Start the Walkthrough +### HTML Attributes Method -```javascript -// Start from HTML attributes -const tour = walkthrough.fromAttributes(); -tour.start(); +```html +
+ Content to highlight +
+ + + + ``` -## 📖 Usage Methods +## 📚 API Reference -### Method 1: HTML Data Attributes +### `walkthrough.start(steps, options?)` -The simplest way to add walkthroughs. Just add data attributes to your HTML elements: +Quick start method to create and start a walkthrough immediately. -```HTML -
- Dashboard Content -
- - +```typescript +walkthrough.start([ + { element: '.header', title: 'Header', text: 'This is the header' } +], { + progressColor: '#28a745', + showProgress: true +}); +``` + +### `walkthrough.fromAttributes(options?)` + +Creates a walkthrough from HTML data attributes. + +```typescript +const tour = walkthrough.fromAttributes({ + progressColor: '#667eea', + rememberProgress: false +}); +tour.start(); +``` + +### `walkthrough.fromJSON(config)` + +Creates a walkthrough from a JSON configuration object. + +```typescript +const tour = walkthrough.fromJSON({ + steps: [...], + options: {...}, + callbacks: {...} +}); +tour.start(); ``` -### Method 2: JSON Configuration - -Use JavaScript objects for programmatic control: - -```javascript -const tour = walkthrough.fromJSON({ - steps: [ - { - element: '.header', - title: 'Navigation', - text: 'This is your main navigation area', - position: 'bottom' - }, - { - element: '#sidebar', - title: 'Sidebar', - text: 'Access tools and settings here', - position: 'right', - nextText: 'Got it! →' - } - ], - options: { - progressColor: '#764ba2', - highlightPadding: 15, - animationDuration: 400 - }, - callbacks: { - onStart: () => console.log('Tour started'), - onFinish: () => console.log('Tour completed') - } -}); +### Configuration Options + +```typescript +interface WalkthroughOptions { + // Visual + overlayColor?: string; // Default: 'rgba(0, 0, 0, 0.5)' + highlightPadding?: number; // Default: 10 + animationDuration?: number; // Default: 300 + progressColor?: string; // Default: '#4CAF50' + + // Progress + showProgress?: boolean; // Default: true -tour.start(); + // Buttons + showButtons?: boolean; // Default: true + showSkip?: boolean; // Default: true + skipText?: string; // Default: 'Skip' + prevText?: string; // Default: '← Previous' + nextText?: string; // Default: 'Next →' + finishText?: string; // Default: 'Finish' + + // Keyboard + keyboard?: boolean; // Default: true + escapeToExit?: boolean; // Default: true + arrowNavigation?: boolean; // Default: true + + // Storage + rememberProgress?: boolean; // Default: false + cookieName?: string; // Default: 'walkthrough_progress' + + // Behavior + closeOnOverlay?: boolean; // Default: true + autoStart?: boolean; // Default: false +} ``` -### Method 3: Quick Start - -Perfect for rapid prototyping: - -```javascript -walkthrough.start([ - { - element: '.feature', - title: 'New Feature', - text: 'Check out this new feature!', - position: 'bottom' - } -], { - progressColor: '#28a745', - onFinish: () => alert('Tour complete!') -}); +### Step Configuration + +```typescript +interface WalkthroughStep { + element: string | HTMLElement; // Target element + title?: string; // Step title + text?: string; // Step description + position?: 'top' | 'bottom' | 'left' | 'right'; // Popup position +} ``` -## 🎛️ Configuration Options - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `progressColor` | string | `'#007bff'` | Color of the progress indicator | -| `highlightPadding` | number | `10` | Padding around highlighted elements | -| `animationDuration` | number | `300` | Animation duration in milliseconds | -| `rememberProgress` | boolean | `true` | Remember user's progress in localStorage | -| `showProgress` | boolean | `true` | Show step progress indicator | -| `allowClose` | boolean | `true` | Allow users to close the walkthrough | -| `backdrop` | boolean | `true` | Show backdrop overlay | -| `backdropColor` | string | `'rgba(0,0,0,0.5)'` | Backdrop overlay color | - -## 📍 Position Options - -- `'top'` - Above the element -- `'bottom'` - Below the element -- `'left'` - To the left of the element -- `'right'` - To the right of the element -- `'center'` - Centered on screen - -## 🎨 Custom Templates - -Take full control of the popup HTML: - -```javascript -const tour = walkthrough.fromJSON({ - steps: [...], - templates: { - popup: (step, index, total) => { - const isLast = index === total - 1; - return ` -
-

${step.title}

-

${step.text}

-
- ${index > 0 ? `` : ''} - -
-
- `; - } - } -}); +### Callbacks + +```typescript +tour.configure({ + callbacks: { + onStart: () => console.log('Started'), + onStep: (step, index) => console.log(`Step ${index}`), + onFinish: () => console.log('Finished'), + onEnd: () => console.log('Ended') + } +}); ``` -## 🔌 Event Callbacks - -```javascript -const tour = walkthrough.fromJSON({ - steps: [...], - callbacks: { - onStart: () => { - console.log('Walkthrough started'); - }, - onStep: (step, index) => { - console.log(`Now on step ${index + 1}: ${step.title}`); - }, - onNext: (step, index) => { - console.log('Moving to next step'); - }, - onPrev: (step, index) => { - console.log('Moving to previous step'); - }, - onFinish: () => { - console.log('Walkthrough completed'); - }, - onClose: () => { - console.log('Walkthrough closed'); - } - } -}); +### Methods + +```typescript +const tour = new Walkthrough(); + +tour.start(); // Start the walkthrough +tour.next(); // Go to next step +tour.prev(); // Go to previous step +tour.finish(); // Finish the walkthrough +tour.end(); // End/close the walkthrough +tour.destroy(); // Clean up and remove all elements ``` -## 🎮 API Methods +## 🎨 Customization -```javascript - const tour = walkthrough.fromJSON({...}); - -// Control methods -tour.start(); // Start the walkthrough -tour.next(); // Go to next step -tour.prev(); // Go to previous step -tour.goTo(stepIndex); // Jump to specific step -tour.finish(); // Complete the walkthrough -tour.close(); // Close without completing -tour.destroy(); // Clean up and remove - -// State methods -tour.getCurrentStep(); // Get current step object -tour.getCurrentIndex(); // Get current step index -tour.getTotalSteps(); // Get total number of steps -tour.isActive(); // Check if walkthrough is running +### Custom Colors + +```typescript +const tour = new Walkthrough({ + progressColor: '#667eea', + overlayColor: 'rgba(0, 0, 0, 0.7)' +}); +``` + +### Custom Templates + +```typescript +tour.configure({ + templates: { + popup: (step, index, total) => ` +
+

${step.title}

+

${step.text}

+
Step ${index + 1} of ${total}
+
+ ` + } +}); ``` -## ⌨️ Keyboard Navigation +## 🔧 Development -- **→ / ↓** - Next step -- **← / ↑** - Previous step -- **Enter** - Next step -- **Escape** - Close walkthrough -- **Home** - Go to first step -- **End** - Go to last step +```bash +# Install dependencies +npm install -## 🎯 HTML Data Attributes Reference +# Development mode (watch) +npm run dev -| Attribute | Description | Example | -|-----------|-------------|---------| -| `data-wt-step` | Step number (required) | `data-wt-step="1"` | -| `data-wt-title` | Step title | `data-wt-title="Welcome"` | -| `data-wt-text` | Step description | `data-wt-text="This is the main menu"` | -| `data-wt-position` | Popup position | `data-wt-position="bottom"` | -| `data-wt-next-text` | Custom next button text | `data-wt-next-text="Continue →"` | -| `data-wt-prev-text` | Custom previous button text | `data-wt-prev-text="← Back"` | +# Build for production +npm run build -## 🌟 Examples +# Lint +npm run lint -Check out the demo files for comprehensive examples of all features and configuration methods. -- [demo-quickstart.html](/src/demo-quickstart.html) -- [demo-attributes.html](/src/demo-attributes.html) -- [demo-json.html](/src/demo-json.html) -- [demo-custom-template.html](/src/demo-custom-template.html) +# Format code +npm run format -## 📄 License +# Type check +npm run type-check +``` -LGPL License - see [LICENSE](LICENSE.md) file for details. +## 📝 License + +LGPL-3.0-or-later ## 🤝 Contributing -Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details. +Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details. + +## 🙏 Credits -## 📞 Support +Originally created by Ronan Armstrong, rebuilt in TypeScript by Benjamin Rast. -- 🐛 Issues: [GitHub Issues](https://github.com/yourusername/walkthrough-js/issues) -- 💬 Discussions: [GitHub Discussions](https://github.com/yourusername/walkthrough-js/discussions) diff --git a/demo/demo-typescript.html b/demo/demo-typescript.html new file mode 100644 index 0000000..cf83d3b --- /dev/null +++ b/demo/demo-typescript.html @@ -0,0 +1,305 @@ + + + + + + WalkthroughJS TypeScript Demo + + + +
+
+

+ WalkthroughJS +

+

TypeScript Edition - Interactive Product Tours Made Easy

+
+ +
+

Try Different Demos

+
+ + + +
+
+ +
+

Key Features

+
+
+

🔷 TypeScript First

+

Full type safety with excellent IDE support and IntelliSense

+
+
+

📦 Modern Build

+

ESM and CJS support with tree-shaking capabilities

+
+
+

⌨️ Keyboard Nav

+

Arrow keys, Enter, and Escape support out of the box

+
+
+

🎨 Customizable

+

Easy theming with custom colors and templates

+
+
+

💾 Progress Tracking

+

Remember user progress across sessions

+
+
+

0️⃣ Zero Deps

+

No dependencies means smaller bundle size

+
+
+
+ +
+

Quick Example

+
+ +import { walkthrough } from '@walkthroughjs/core'; + +// Quick start +walkthrough.start([ + { + element: '.welcome-section', + title: 'Welcome! 👋', + text: 'Let me show you around.', + position: 'bottom' + } +]); + +
+
+ +
+

Built with ❤️ by the WalkthroughJS Team

+

TypeScript Edition v2.0.0

+
+
+ + + + + diff --git a/dist/index.d.mts b/dist/index.d.mts new file mode 100644 index 0000000..0654a01 --- /dev/null +++ b/dist/index.d.mts @@ -0,0 +1,222 @@ +/** + * Position options for popup placement + */ +type PopupPosition = 'top' | 'bottom' | 'left' | 'right'; +/** + * Step configuration + */ +interface WalkthroughStep { + /** Target element selector or HTMLElement */ + element: string | HTMLElement; + /** Step title */ + title?: string; + /** Step description text */ + text?: string; + /** Preferred popup position */ + position?: PopupPosition; + /** Step number (used for attribute-based configuration) */ + step?: number; + /** Custom skip button text */ + skipText?: string; + /** Custom previous button text */ + prevText?: string; + /** Custom next button text */ + nextText?: string; + /** Custom finish button text */ + finishText?: string; +} +/** + * Walkthrough configuration options + */ +interface WalkthroughOptions { + overlayColor?: string; + highlightPadding?: number; + animationDuration?: number; + scrollDuration?: number; + scrollOffset?: number; + zIndex?: number; + popupWidth?: number; + popupOffset?: number; + popupClass?: string; + showProgress?: boolean; + progressColor?: string; + showButtons?: boolean; + showSkip?: boolean; + skipText?: string; + prevText?: string; + nextText?: string; + finishText?: string; + keyboard?: boolean; + escapeToExit?: boolean; + arrowNavigation?: boolean; + cookieName?: string; + cookieExpiry?: number; + rememberProgress?: boolean; + closeOnOverlay?: boolean; + autoStart?: boolean; + startDelay?: number; + attributePrefix?: string; + stepAttribute?: string; + titleAttribute?: string; + textAttribute?: string; + positionAttribute?: string; +} +/** + * Callback functions + */ +interface WalkthroughCallbacks { + /** Called when walkthrough starts */ + onStart?: () => void; + /** Called on each step */ + onStep?: (step: WalkthroughStep, index: number) => void; + /** Called when walkthrough finishes normally */ + onFinish?: () => void; + /** Called when walkthrough ends (finish or skip) */ + onEnd?: () => void; +} +/** + * Template functions + */ +interface WalkthroughTemplates { + /** Custom popup template */ + popup?: (step: WalkthroughStep, index: number, totalSteps: number) => string; +} +/** + * Complete configuration object for JSON-based setup + */ +interface WalkthroughConfig { + steps?: WalkthroughStep[]; + options?: WalkthroughOptions; + callbacks?: WalkthroughCallbacks; + templates?: WalkthroughTemplates; +} + +/** + * Main Walkthrough class + */ +declare class Core { + private steps; + private currentStep; + private isActive; + private callbacks; + private templates; + private options; + private elements; + private keyHandler?; + private positionHandler?; + private throttledPositionHandler?; + constructor(options?: WalkthroughOptions); + /** + * Initialize the walkthrough + */ + private init; + /** + * Create DOM elements + */ + private createElements; + /** + * Bind event listeners + */ + private bindEvents; + /** + * Scan DOM for attribute-based steps + */ + scanForAttributeSteps(): void; + /** + * Configure walkthrough with JSON + */ + configure(config: WalkthroughConfig): void; + /** + * Start the walkthrough + */ + start(stepIndex?: number | null): void; + /** + * Show a specific step + */ + private showStep; + /** + * Position highlight and popup elements + */ + private positionElements; + /** + * Position popup relative to target element + */ + private positionPopup; + /** + * Update arrow direction + */ + private updateArrow; + /** + * Update popup content + */ + private updatePopup; + /** + * Get default popup content + */ + private getDefaultPopupContent; + /** + * Bind popup button events + */ + private bindPopupButtons; + /** + * Navigate to next step + */ + next(): void; + /** + * Navigate to previous step + */ + prev(): void; + /** + * Finish the walkthrough + */ + finish(): void; + /** + * End the walkthrough + */ + end(): void; + /** + * Save progress to cookie + */ + private saveProgress; + /** + * Load progress from cookie + */ + private loadProgress; + /** + * Clear saved progress + */ + private clearProgress; + /** + * Trigger callback function + */ + private triggerCallback; + /** + * Destroy the walkthrough and clean up + */ + destroy(): void; +} + +/** + * WalkthroughJS - TypeScript Edition + * Lightweight, powerful walkthrough library with zero dependencies + */ + +/** + * Convenience API for creating walkthroughs + */ +declare const walkthrough: { + /** + * Create walkthrough from HTML attributes + */ + fromAttributes(options?: WalkthroughOptions): Core; + /** + * Create walkthrough from JSON configuration + */ + fromJSON(config: WalkthroughConfig): Core; + /** + * Quick start a walkthrough + */ + start(steps: WalkthroughStep[], options?: WalkthroughOptions): Core; +}; + +export { Core, type PopupPosition, type WalkthroughCallbacks, type WalkthroughConfig, type WalkthroughOptions, type WalkthroughStep, type WalkthroughTemplates, walkthrough }; diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..0654a01 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,222 @@ +/** + * Position options for popup placement + */ +type PopupPosition = 'top' | 'bottom' | 'left' | 'right'; +/** + * Step configuration + */ +interface WalkthroughStep { + /** Target element selector or HTMLElement */ + element: string | HTMLElement; + /** Step title */ + title?: string; + /** Step description text */ + text?: string; + /** Preferred popup position */ + position?: PopupPosition; + /** Step number (used for attribute-based configuration) */ + step?: number; + /** Custom skip button text */ + skipText?: string; + /** Custom previous button text */ + prevText?: string; + /** Custom next button text */ + nextText?: string; + /** Custom finish button text */ + finishText?: string; +} +/** + * Walkthrough configuration options + */ +interface WalkthroughOptions { + overlayColor?: string; + highlightPadding?: number; + animationDuration?: number; + scrollDuration?: number; + scrollOffset?: number; + zIndex?: number; + popupWidth?: number; + popupOffset?: number; + popupClass?: string; + showProgress?: boolean; + progressColor?: string; + showButtons?: boolean; + showSkip?: boolean; + skipText?: string; + prevText?: string; + nextText?: string; + finishText?: string; + keyboard?: boolean; + escapeToExit?: boolean; + arrowNavigation?: boolean; + cookieName?: string; + cookieExpiry?: number; + rememberProgress?: boolean; + closeOnOverlay?: boolean; + autoStart?: boolean; + startDelay?: number; + attributePrefix?: string; + stepAttribute?: string; + titleAttribute?: string; + textAttribute?: string; + positionAttribute?: string; +} +/** + * Callback functions + */ +interface WalkthroughCallbacks { + /** Called when walkthrough starts */ + onStart?: () => void; + /** Called on each step */ + onStep?: (step: WalkthroughStep, index: number) => void; + /** Called when walkthrough finishes normally */ + onFinish?: () => void; + /** Called when walkthrough ends (finish or skip) */ + onEnd?: () => void; +} +/** + * Template functions + */ +interface WalkthroughTemplates { + /** Custom popup template */ + popup?: (step: WalkthroughStep, index: number, totalSteps: number) => string; +} +/** + * Complete configuration object for JSON-based setup + */ +interface WalkthroughConfig { + steps?: WalkthroughStep[]; + options?: WalkthroughOptions; + callbacks?: WalkthroughCallbacks; + templates?: WalkthroughTemplates; +} + +/** + * Main Walkthrough class + */ +declare class Core { + private steps; + private currentStep; + private isActive; + private callbacks; + private templates; + private options; + private elements; + private keyHandler?; + private positionHandler?; + private throttledPositionHandler?; + constructor(options?: WalkthroughOptions); + /** + * Initialize the walkthrough + */ + private init; + /** + * Create DOM elements + */ + private createElements; + /** + * Bind event listeners + */ + private bindEvents; + /** + * Scan DOM for attribute-based steps + */ + scanForAttributeSteps(): void; + /** + * Configure walkthrough with JSON + */ + configure(config: WalkthroughConfig): void; + /** + * Start the walkthrough + */ + start(stepIndex?: number | null): void; + /** + * Show a specific step + */ + private showStep; + /** + * Position highlight and popup elements + */ + private positionElements; + /** + * Position popup relative to target element + */ + private positionPopup; + /** + * Update arrow direction + */ + private updateArrow; + /** + * Update popup content + */ + private updatePopup; + /** + * Get default popup content + */ + private getDefaultPopupContent; + /** + * Bind popup button events + */ + private bindPopupButtons; + /** + * Navigate to next step + */ + next(): void; + /** + * Navigate to previous step + */ + prev(): void; + /** + * Finish the walkthrough + */ + finish(): void; + /** + * End the walkthrough + */ + end(): void; + /** + * Save progress to cookie + */ + private saveProgress; + /** + * Load progress from cookie + */ + private loadProgress; + /** + * Clear saved progress + */ + private clearProgress; + /** + * Trigger callback function + */ + private triggerCallback; + /** + * Destroy the walkthrough and clean up + */ + destroy(): void; +} + +/** + * WalkthroughJS - TypeScript Edition + * Lightweight, powerful walkthrough library with zero dependencies + */ + +/** + * Convenience API for creating walkthroughs + */ +declare const walkthrough: { + /** + * Create walkthrough from HTML attributes + */ + fromAttributes(options?: WalkthroughOptions): Core; + /** + * Create walkthrough from JSON configuration + */ + fromJSON(config: WalkthroughConfig): Core; + /** + * Quick start a walkthrough + */ + start(steps: WalkthroughStep[], options?: WalkthroughOptions): Core; +}; + +export { Core, type PopupPosition, type WalkthroughCallbacks, type WalkthroughConfig, type WalkthroughOptions, type WalkthroughStep, type WalkthroughTemplates, walkthrough }; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..5702ab2 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,216 @@ +'use strict';function $(s){return s<.5?2*s*s:-1+(4-2*s)*s}function m(s,t){let e;return function(...o){e||(s.apply(this,o),e=true,setTimeout(()=>e=false,t));}}function g(s,t){let e=s[0]==="#",o=e?s.slice(1):s,i=parseInt(o,16),n=(i>>16)+t,r=(i>>8&255)+t,p=(i&255)+t;return n=n>255?255:n<0?0:n,r=r>255?255:r<0?0:r,p=p>255?255:p<0?0:p,(e?"#":"")+(n<<16|r<<8|p).toString(16).padStart(6,"0")}function f(s,t,e){let o=new Date;o.setDate(o.getDate()+e),document.cookie=`${s}=${t};expires=${o.toUTCString()};path=/`;}function w(s){let t=document.cookie.split(";");for(let e of t){let[o,i]=e.trim().split("=");if(o===s)return i}return null}function b(s){document.cookie=`${s}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;}function v(s,t,e,o){let i=s.getBoundingClientRect();if(i.top>=0&&i.bottom<=window.innerHeight){o();return}let n=window.pageYOffset+i.top-t,r=window.pageYOffset,p=n-r,a,h=u=>{a||(a=u);let d=u-a,c=Math.min(d/e,1);window.scrollTo(0,r+p*$(c)),d{this.scanForAttributeSteps(),this.steps.length>0&&this.start();},this.options.startDelay);}createElements(){let t=document.createElement("div");t.className="wt-overlay";let e=document.createElement("style");e.textContent=k(this.options),t.appendChild(e);let o=document.createElement("div");o.className="wt-highlight";let i=document.createElement("div");i.className=this.options.popupClass,t.appendChild(o),t.appendChild(i),document.body.appendChild(t),this.elements={overlay:t,highlight:o,popup:i};}bindEvents(){this.options.closeOnOverlay&&this.elements.overlay.addEventListener("click",t=>{t.target===this.elements.overlay&&this.end();}),this.options.keyboard&&(this.keyHandler=t=>{this.isActive&&(this.options.escapeToExit&&t.key==="Escape"?this.end():this.options.arrowNavigation&&(t.key==="ArrowRight"||t.key==="Enter"?this.next():t.key==="ArrowLeft"&&this.prev()));},document.addEventListener("keydown",this.keyHandler)),this.positionHandler=()=>{this.isActive&&this.currentStep{let r=parseInt(n.getAttribute(e)||"0",10),p=n.getAttribute(`data-${t}-${this.options.titleAttribute}`)||void 0,a=n.getAttribute(`data-${t}-${this.options.textAttribute}`)||void 0,h=n.getAttribute(`data-${t}-${this.options.positionAttribute}`)||void 0;return {element:n,step:r,title:p,text:a,position:h}});i.sort((n,r)=>(n.step||0)-(r.step||0)),this.steps=i;}configure(t){t.steps&&(this.steps=t.steps.map(e=>{if(typeof e.element=="string"){let o=document.querySelector(e.element);if(!o)throw new Error(`Element not found: ${e.element}`);return {...e,element:o}}return e})),t.options&&(this.options={...this.options,...t.options}),t.callbacks&&(this.callbacks={...this.callbacks,...t.callbacks}),t.templates&&(this.templates={...this.templates,...t.templates});}start(t){if(this.steps.length===0){console.warn("Walkthrough: No steps configured");return}this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`,t==null&&(this.options.rememberProgress?t=this.loadProgress():t=0),this.currentStep=t,this.isActive=true,this.triggerCallback("onStart"),this.elements.overlay.classList.add("active"),setTimeout(()=>{this.showStep(this.currentStep);},50);}showStep(t){if(t<0||t>=this.steps.length)return;this.elements.popup.classList.remove("active");let e=this.steps[t];this.currentStep=t,this.options.rememberProgress&&this.saveProgress(t),this.triggerCallback("onStep",e,t);let o=typeof e.element=="string"?document.querySelector(e.element):e.element;o&&v(o,this.options.scrollOffset,this.options.scrollDuration,()=>{this.positionElements(),this.updatePopup(e,t),setTimeout(()=>{this.elements.popup.classList.add("active");},50);});}positionElements(){let t=this.steps[this.currentStep];if(!t)return;let e=typeof t.element=="string"?document.querySelector(t.element):t.element;if(!e)return;this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`;let o=e.getBoundingClientRect(),i=this.options.highlightPadding,n=window.pageYOffset||document.documentElement.scrollTop,r=window.pageXOffset||document.documentElement.scrollLeft,p=this.elements.highlight;p.style.left=`${o.left+r-i}px`,p.style.top=`${o.top+n-i}px`,p.style.width=`${o.width+i*2}px`,p.style.height=`${o.height+i*2}px`,this.positionPopup(o,t.position);}positionPopup(t,e){let o=this.elements.popup;o.style.visibility="hidden",o.style.display="block";let i=o.getBoundingClientRect();o.style.visibility="",o.style.display="";let n=this.options.popupOffset,r=this.options.highlightPadding,p={width:window.innerWidth,height:window.innerHeight},a={bottom:{left:t.left+t.width/2-i.width/2,top:t.bottom+r+n,arrow:"top",fits:t.bottom+r+n+i.height0},right:{left:t.right+r+n,top:t.top+t.height/2-i.height/2,arrow:"left",fits:t.right+r+n+i.width0}},h=e&&a[e]?.fits?e:Object.keys(a).find(P=>a[P].fits)||"bottom",u=a[h],d=window.pageYOffset||document.documentElement.scrollTop,c=window.pageXOffset||document.documentElement.scrollLeft,x=Math.max(10,Math.min(u.left,p.width-i.width-10))+c,y=Math.max(10,Math.min(u.top,p.height-i.height-10))+d;o.style.left=`${x}px`,o.style.top=`${y}px`,this.updateArrow(u.arrow);}updateArrow(t){let e=this.elements.popup;e.querySelector(".wt-popup-arrow")?.remove();let i=document.createElement("div");i.className=`wt-popup-arrow ${t}`,e.appendChild(i);}updatePopup(t,e){let o=this.elements.popup,i=e===0,n=e===this.steps.length-1,r;this.templates.popup?r=this.templates.popup(t,e,this.steps.length):r=this.getDefaultPopupContent(t,e,i,n),o.innerHTML=r,this.bindPopupButtons();}getDefaultPopupContent(t,e,o,i){return ` +
+ ${t.title||this.options.showProgress?` +
+ ${t.title?`

${t.title}

`:""} + ${this.options.showProgress?` +
+ Step ${e+1} of ${this.steps.length} +
+ `:""} +
+ `:""} + + ${t.text?` +
+ ${t.text} +
+ `:""} + + ${this.options.showProgress?` +
+
+
+ `:""} + + ${this.options.showButtons?` + + `:""} +
+ `}bindPopupButtons(){this.elements.popup.querySelectorAll("[data-wt-action]").forEach(e=>{e.addEventListener("click",o=>{switch(o.currentTarget.getAttribute("data-wt-action")){case "skip":this.end();break;case "prev":this.prev();break;case "next":this.next();break;case "finish":this.finish();break}});});}next(){this.currentStep0&&this.showStep(this.currentStep-1);}finish(){this.triggerCallback("onFinish"),this.clearProgress(),this.end();}end(){this.isActive&&(this.isActive=false,this.triggerCallback("onEnd"),this.elements.popup.classList.remove("active"),setTimeout(()=>{this.elements.overlay.classList.remove("active");},this.options.animationDuration));}saveProgress(t){f(this.options.cookieName,t.toString(),this.options.cookieExpiry);}loadProgress(){let t=w(this.options.cookieName);return t&&parseInt(t,10)||0}clearProgress(){b(this.options.cookieName);}triggerCallback(t,...e){let o=this.callbacks[t];typeof o=="function"&&o(...e);}destroy(){this.keyHandler&&document.removeEventListener("keydown",this.keyHandler),this.throttledPositionHandler&&(window.removeEventListener("resize",this.throttledPositionHandler),window.removeEventListener("scroll",this.throttledPositionHandler,true)),this.elements.overlay?.remove(),this.steps=[],this.currentStep=0,this.isActive=false;}};var C={fromAttributes(s){let t=new l(s);return t.scanForAttributeSteps(),t},fromJSON(s){let t=new l(s.options);return t.configure(s),t},start(s,t){let e=new l(t);return e.configure({steps:s}),e.start(),e}};typeof window<"u"&&(window.Walkthrough=l,window.walkthrough=C);exports.Core=l;exports.walkthrough=C;//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..87592a8 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/utils.ts","../src/styles.ts","../src/core.ts","../src/index.ts"],"names":["easeInOut","t","throttle","func","limit","inThrottle","args","adjustColor","color","amount","usePound","col","num","r","g","b","setCookie","name","value","days","expiry","getCookie","cookies","cookie","cookieName","deleteCookie","scrollToElement","element","offset","duration","callback","rect","targetY","startY","diff","start","scroll","timestamp","elapsed","progress","generateStyles","options","DEFAULT_OPTIONS","Core","overlay","style","highlight","popup","e","prefix","stepAttr","elements","steps","el","step","title","text","position","a","config","stepIndex","index","padding","scrollTop","scrollLeft","targetRect","preferredPosition","popupRect","viewport","positions","pos","chosen","finalLeft","finalTop","direction","arrow","isFirst","isLast","content","btn","walkthrough","wt"],"mappings":"aAOO,SAASA,CAAAA,CAAUC,CAAAA,CAAmB,CAC3C,OAAOA,CAAAA,CAAI,EAAA,CAAM,CAAA,CAAIA,CAAAA,CAAIA,CAAAA,CAAI,EAAA,CAAA,CAAM,CAAA,CAAI,CAAA,CAAIA,GAAKA,CAClD,CAKO,SAASC,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACkC,CAClC,IAAIC,CAAAA,CACJ,OAAO,SAAA,GAA4BC,CAAAA,CAAqB,CACjDD,CAAAA,GACHF,CAAAA,CAAK,KAAA,CAAM,KAAMG,CAAI,CAAA,CACrBD,CAAAA,CAAa,IAAA,CACb,UAAA,CAAW,IAAOA,CAAAA,CAAa,KAAA,CAAQD,CAAK,CAAA,EAEhD,CACF,CAKO,SAASG,CAAAA,CAAYC,CAAAA,CAAeC,CAAAA,CAAwB,CACjE,IAAMC,CAAAA,CAAWF,CAAAA,CAAM,CAAC,CAAA,GAAM,GAAA,CACxBG,CAAAA,CAAMD,CAAAA,CAAWF,EAAM,KAAA,CAAM,CAAC,CAAA,CAAIA,CAAAA,CAClCI,CAAAA,CAAM,QAAA,CAASD,CAAAA,CAAK,EAAE,EACxBE,CAAAA,CAAAA,CAAKD,CAAAA,EAAO,EAAA,EAAMH,CAAAA,CAClBK,CAAAA,CAAAA,CAAMF,CAAAA,EAAO,CAAA,CAAK,GAAA,EAAUH,CAAAA,CAC5BM,CAAAA,CAAAA,CAAKH,CAAAA,CAAM,GAAA,EAAYH,CAAAA,CAC3B,OAAAI,CAAAA,CAAIA,CAAAA,CAAI,IAAM,GAAA,CAAMA,CAAAA,CAAI,CAAA,CAAI,CAAA,CAAIA,CAAAA,CAChCC,CAAAA,CAAIA,CAAAA,CAAI,GAAA,CAAM,IAAMA,CAAAA,CAAI,CAAA,CAAI,CAAA,CAAIA,CAAAA,CAChCC,CAAAA,CAAIA,CAAAA,CAAI,GAAA,CAAM,GAAA,CAAMA,EAAI,CAAA,CAAI,CAAA,CAAIA,CAAAA,CAAAA,CACxBL,CAAAA,CAAW,GAAA,CAAM,EAAA,EAAA,CAAQG,CAAAA,EAAK,EAAA,CAAOC,CAAAA,EAAK,CAAA,CAAKC,CAAAA,EAAG,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CACxF,CAKO,SAASC,CAAAA,CAAUC,CAAAA,CAAcC,CAAAA,CAAeC,CAAAA,CAAoB,CACzE,IAAMC,CAAAA,CAAS,IAAI,IAAA,CACnBA,CAAAA,CAAO,OAAA,CAAQA,CAAAA,CAAO,OAAA,EAAQ,CAAID,CAAI,CAAA,CACtC,QAAA,CAAS,MAAA,CAAS,CAAA,EAAGF,CAAI,CAAA,CAAA,EAAIC,CAAK,CAAA,SAAA,EAAYE,CAAAA,CAAO,WAAA,EAAa,CAAA,OAAA,EACpE,CAKO,SAASC,CAAAA,CAAUJ,CAAAA,CAA6B,CACrD,IAAMK,CAAAA,CAAU,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,CACzC,IAAA,IAAWC,CAAAA,IAAUD,CAAAA,CAAS,CAC5B,GAAM,CAACE,CAAAA,CAAYN,CAAK,CAAA,CAAIK,EAAO,IAAA,EAAK,CAAE,KAAA,CAAM,GAAG,CAAA,CACnD,GAAIC,CAAAA,GAAeP,CAAAA,CACjB,OAAOC,CAEX,CACA,OAAO,IACT,CAKO,SAASO,CAAAA,CAAaR,EAAoB,CAC/C,QAAA,CAAS,MAAA,CAAS,CAAA,EAAGA,CAAI,CAAA,8CAAA,EAC3B,CAKO,SAASS,EACdC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACM,CACN,IAAMC,CAAAA,CAAOJ,CAAAA,CAAQ,uBAAsB,CAE3C,GAAII,CAAAA,CAAK,GAAA,EAAO,CAAA,EAAKA,CAAAA,CAAK,MAAA,EAAU,MAAA,CAAO,WAAA,CAAa,CACtDD,CAAAA,EAAS,CACT,MACF,CAEA,IAAME,CAAAA,CAAU,OAAO,WAAA,CAAcD,CAAAA,CAAK,GAAA,CAAMH,CAAAA,CAC1CK,CAAAA,CAAS,MAAA,CAAO,WAAA,CAChBC,CAAAA,CAAOF,EAAUC,CAAAA,CACnBE,CAAAA,CAEEC,CAAAA,CAAUC,CAAAA,EAAsB,CAC/BF,CAAAA,GAAOA,CAAAA,CAAQE,CAAAA,CAAAA,CACpB,IAAMC,CAAAA,CAAUD,CAAAA,CAAYF,CAAAA,CACtBI,CAAAA,CAAW,IAAA,CAAK,GAAA,CAAID,CAAAA,CAAUT,CAAAA,CAAU,CAAC,CAAA,CAE/C,MAAA,CAAO,QAAA,CAAS,CAAA,CAAGI,CAAAA,CAASC,CAAAA,CAAOlC,CAAAA,CAAUuC,CAAQ,CAAC,CAAA,CAElDD,CAAAA,CAAUT,CAAAA,CACZ,qBAAA,CAAsBO,CAAM,CAAA,CAE5BN,CAAAA,GAEJ,CAAA,CAEA,qBAAA,CAAsBM,CAAM,EAC9B,CCxGO,SAASI,CAAAA,CAAeC,CAAAA,CAA+C,CAC5E,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EAMQA,EAAQ,MAAM,CAAA;AAAA;AAAA;AAAA,0BAAA,EAGHA,EAAQ,iBAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAA,EAW7BA,EAAQ,iBAAiB,CAAA;AAAA,gCAAA,EACfA,EAAQ,YAAY,CAAA;AAAA;AAAA;AAAA,eAAA,EAGrCA,EAAQ,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EAOdA,CAAAA,CAAQ,OAAS,CAAC,CAAA;AAAA,iBAAA,EAChBA,EAAQ,UAAU,CAAA;AAAA;AAAA;AAAA,sBAAA,EAGbA,EAAQ,iBAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAA,EA6E7BA,EAAQ,aAAa,CAAA;AAAA;AAAA,wBAAA,EAEfA,EAAQ,iBAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAA,EA0C/BA,EAAQ,aAAa,CAAA;AAAA;AAAA;AAAA;AAAA,kBAAA,EAIrBlC,CAAAA,CAAYkC,CAAAA,CAAQ,aAAA,CAAe,GAAG,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAO3D,CC9JA,IAAMC,CAAAA,CAAgD,CACpD,YAAA,CAAc,oBAAA,CACd,gBAAA,CAAkB,EAAA,CAClB,iBAAA,CAAmB,GAAA,CACnB,cAAA,CAAgB,GAAA,CAChB,aAAc,GAAA,CACd,MAAA,CAAQ,KAAA,CACR,UAAA,CAAY,GAAA,CACZ,WAAA,CAAa,EAAA,CACb,UAAA,CAAY,UAAA,CACZ,YAAA,CAAc,IAAA,CACd,aAAA,CAAe,SAAA,CACf,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,KACV,QAAA,CAAU,MAAA,CACV,QAAA,CAAU,iBAAA,CACV,QAAA,CAAU,aAAA,CACV,UAAA,CAAY,QAAA,CACZ,QAAA,CAAU,IAAA,CACV,YAAA,CAAc,IAAA,CACd,eAAA,CAAiB,IAAA,CACjB,UAAA,CAAY,sBAAA,CACZ,aAAc,EAAA,CACd,gBAAA,CAAkB,KAAA,CAClB,cAAA,CAAgB,IAAA,CAChB,SAAA,CAAW,KAAA,CACX,UAAA,CAAY,CAAA,CACZ,eAAA,CAAiB,IAAA,CACjB,aAAA,CAAe,MAAA,CACf,cAAA,CAAgB,OAAA,CAChB,aAAA,CAAe,OACf,iBAAA,CAAmB,UACrB,CAAA,CAKaC,CAAAA,CAAN,KAAW,CAYhB,WAAA,CAAYF,CAAAA,CAA8B,EAAC,CAAG,CAX9C,IAAA,CAAQ,KAAA,CAA2B,EAAC,CACpC,IAAA,CAAQ,YAAc,CAAA,CACtB,IAAA,CAAQ,QAAA,CAAW,KAAA,CACnB,IAAA,CAAQ,SAAA,CAAkC,EAAC,CAC3C,IAAA,CAAQ,SAAA,CAAkC,EAAC,CAQzC,IAAA,CAAK,OAAA,CAAU,CAAE,GAAGC,EAAiB,GAAGD,CAAQ,CAAA,CAChD,IAAA,CAAK,IAAA,GACP,CAKQ,IAAA,EAAa,CACnB,IAAA,CAAK,cAAA,EAAe,CACpB,IAAA,CAAK,UAAA,EAAW,CAEZ,IAAA,CAAK,QAAQ,SAAA,EACf,UAAA,CAAW,IAAM,CACf,IAAA,CAAK,qBAAA,EAAsB,CACvB,IAAA,CAAK,MAAM,MAAA,CAAS,CAAA,EACtB,IAAA,CAAK,KAAA,GAET,CAAA,CAAG,IAAA,CAAK,OAAA,CAAQ,UAAU,EAE9B,CAKQ,cAAA,EAAuB,CAC7B,IAAMG,CAAAA,CAAU,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC5CA,CAAAA,CAAQ,SAAA,CAAY,YAAA,CAEpB,IAAMC,CAAAA,CAAQ,QAAA,CAAS,cAAc,OAAO,CAAA,CAC5CA,CAAAA,CAAM,WAAA,CAAcL,CAAAA,CAAe,IAAA,CAAK,OAAO,CAAA,CAC/CI,CAAAA,CAAQ,WAAA,CAAYC,CAAK,CAAA,CAEzB,IAAMC,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC9CA,CAAAA,CAAU,SAAA,CAAY,cAAA,CAEtB,IAAMC,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,CAAAA,CAAM,SAAA,CAAY,IAAA,CAAK,OAAA,CAAQ,UAAA,CAE/BH,CAAAA,CAAQ,YAAYE,CAAS,CAAA,CAC7BF,CAAAA,CAAQ,WAAA,CAAYG,CAAK,CAAA,CACzB,QAAA,CAAS,IAAA,CAAK,WAAA,CAAYH,CAAO,CAAA,CAEjC,IAAA,CAAK,QAAA,CAAW,CAAE,OAAA,CAAAA,CAAAA,CAAS,UAAAE,CAAAA,CAAW,KAAA,CAAAC,CAAM,EAC9C,CAKQ,UAAA,EAAmB,CACrB,IAAA,CAAK,OAAA,CAAQ,cAAA,EACf,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,gBAAA,CAAiB,OAAA,CAAUC,CAAAA,EAAM,CACjDA,CAAAA,CAAE,MAAA,GAAW,IAAA,CAAK,QAAA,CAAS,OAAA,EAC7B,IAAA,CAAK,GAAA,GAET,CAAC,CAAA,CAGC,IAAA,CAAK,OAAA,CAAQ,QAAA,GACf,IAAA,CAAK,UAAA,CAAcA,CAAAA,EAAqB,CACjC,IAAA,CAAK,QAAA,GAEN,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAgBA,CAAAA,CAAE,GAAA,GAAQ,QAAA,CACzC,IAAA,CAAK,GAAA,EAAI,CACA,IAAA,CAAK,OAAA,CAAQ,eAAA,GAClBA,CAAAA,CAAE,GAAA,GAAQ,cAAgBA,CAAAA,CAAE,GAAA,GAAQ,OAAA,CACtC,IAAA,CAAK,IAAA,EAAK,CACDA,CAAAA,CAAE,GAAA,GAAQ,aACnB,IAAA,CAAK,IAAA,EAAK,CAAA,EAGhB,CAAA,CACA,QAAA,CAAS,gBAAA,CAAiB,SAAA,CAAW,IAAA,CAAK,UAAU,CAAA,CAAA,CAGtD,IAAA,CAAK,eAAA,CAAkB,IAAM,CACvB,IAAA,CAAK,QAAA,EAAY,IAAA,CAAK,WAAA,CAAc,IAAA,CAAK,KAAA,CAAM,MAAA,EACjD,IAAA,CAAK,gBAAA,GAET,CAAA,CACA,KAAK,wBAAA,CAA2B9C,CAAAA,CAAS,IAAA,CAAK,eAAA,CAAiB,GAAG,CAAA,CAClE,MAAA,CAAO,gBAAA,CAAiB,QAAA,CAAU,IAAA,CAAK,wBAAwB,CAAA,CAC/D,MAAA,CAAO,gBAAA,CAAiB,QAAA,CAAU,IAAA,CAAK,yBAA0B,IAAI,EACvE,CAKO,qBAAA,EAA8B,CACnC,IAAM+C,CAAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,eAAA,CACtBC,CAAAA,CAAW,CAAA,KAAA,EAAQD,CAAM,CAAA,CAAA,EAAI,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAAA,CACvDE,CAAAA,CAAW,QAAA,CAAS,gBAAA,CAA8B,CAAA,CAAA,EAAID,CAAQ,CAAA,CAAA,CAAG,CAAA,CAEjEE,CAAAA,CAAQ,KAAA,CAAM,IAAA,CAAKD,CAAQ,CAAA,CAAE,GAAA,CAAKE,CAAAA,EAAO,CAC7C,IAAMC,CAAAA,CAAO,QAAA,CAASD,CAAAA,CAAG,YAAA,CAAaH,CAAQ,CAAA,EAAK,GAAA,CAAK,EAAE,CAAA,CACpDK,CAAAA,CAAQF,CAAAA,CAAG,YAAA,CAAa,CAAA,KAAA,EAAQJ,CAAM,CAAA,CAAA,EAAI,IAAA,CAAK,QAAQ,cAAc,CAAA,CAAE,CAAA,EAAK,MAAA,CAC5EO,CAAAA,CAAOH,CAAAA,CAAG,YAAA,CAAa,CAAA,KAAA,EAAQJ,CAAM,CAAA,CAAA,EAAI,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAAE,CAAA,EAAK,MAAA,CAC1EQ,EACHJ,CAAAA,CAAG,YAAA,CAAa,CAAA,KAAA,EAAQJ,CAAM,CAAA,CAAA,EAAI,IAAA,CAAK,OAAA,CAAQ,iBAAiB,CAAA,CAAE,CAAA,EACnE,MAAA,CAEF,OAAO,CACL,OAAA,CAASI,CAAAA,CACT,IAAA,CAAAC,EACA,KAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CACF,CACF,CAAC,EAEDL,CAAAA,CAAM,IAAA,CAAK,CAACM,CAAAA,CAAG3C,CAAAA,GAAAA,CAAO2C,CAAAA,CAAE,IAAA,EAAQ,CAAA,GAAM3C,EAAE,IAAA,EAAQ,CAAA,CAAE,CAAA,CAClD,IAAA,CAAK,KAAA,CAAQqC,EACf,CAKO,SAAA,CAAUO,CAAAA,CAAiC,CAC5CA,CAAAA,CAAO,KAAA,GACT,IAAA,CAAK,KAAA,CAAQA,CAAAA,CAAO,KAAA,CAAM,IAAKL,CAAAA,EAAS,CACtC,GAAI,OAAOA,CAAAA,CAAK,OAAA,EAAY,QAAA,CAAU,CACpC,IAAMD,CAAAA,CAAK,QAAA,CAAS,aAAA,CAA2BC,CAAAA,CAAK,OAAO,CAAA,CAC3D,GAAI,CAACD,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsBC,CAAAA,CAAK,OAAO,CAAA,CAAE,CAAA,CAEtD,OAAO,CAAE,GAAGA,CAAAA,CAAM,OAAA,CAASD,CAAG,CAChC,CACA,OAAOC,CACT,CAAC,CAAA,CAAA,CAGCK,CAAAA,CAAO,OAAA,GACT,IAAA,CAAK,OAAA,CAAU,CAAE,GAAG,IAAA,CAAK,OAAA,CAAS,GAAGA,CAAAA,CAAO,OAAQ,CAAA,CAAA,CAGlDA,EAAO,SAAA,GACT,IAAA,CAAK,SAAA,CAAY,CAAE,GAAG,IAAA,CAAK,SAAA,CAAW,GAAGA,CAAAA,CAAO,SAAU,CAAA,CAAA,CAGxDA,CAAAA,CAAO,SAAA,GACT,IAAA,CAAK,SAAA,CAAY,CAAE,GAAG,IAAA,CAAK,SAAA,CAAW,GAAGA,CAAAA,CAAO,SAAU,CAAA,EAE9D,CAKO,KAAA,CAAMC,CAAAA,CAAiC,CAC5C,GAAI,IAAA,CAAK,KAAA,CAAM,MAAA,GAAW,CAAA,CAAG,CAC3B,QAAQ,IAAA,CAAK,kCAAkC,CAAA,CAC/C,MACF,CAEA,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAS,CAAA,EAAG,QAAA,CAAS,eAAA,CAAgB,YAAY,CAAA,EAAA,CAAA,CAEzEA,CAAAA,EAAc,OACZ,IAAA,CAAK,OAAA,CAAQ,gBAAA,CACfA,CAAAA,CAAY,IAAA,CAAK,YAAA,EAAa,CAE9BA,CAAAA,CAAY,GAIhB,IAAA,CAAK,WAAA,CAAcA,CAAAA,CACnB,IAAA,CAAK,QAAA,CAAW,IAAA,CAEhB,IAAA,CAAK,eAAA,CAAgB,SAAS,CAAA,CAC9B,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA,CAE5C,UAAA,CAAW,IAAM,CACf,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,WAAW,EAChC,EAAG,EAAE,EACP,CAKQ,QAAA,CAASC,CAAAA,CAAqB,CACpC,GAAIA,CAAAA,CAAQ,CAAA,EAAKA,CAAAA,EAAS,IAAA,CAAK,KAAA,CAAM,MAAA,CAAQ,OAE7C,IAAA,CAAK,QAAA,CAAS,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA,CAE7C,IAAMP,CAAAA,CAAO,IAAA,CAAK,KAAA,CAAMO,CAAK,CAAA,CAC7B,IAAA,CAAK,WAAA,CAAcA,CAAAA,CAEf,IAAA,CAAK,OAAA,CAAQ,gBAAA,EACf,KAAK,YAAA,CAAaA,CAAK,CAAA,CAGzB,IAAA,CAAK,eAAA,CAAgB,QAAA,CAAUP,CAAAA,CAAMO,CAAK,CAAA,CAE1C,IAAMlC,CAAAA,CACJ,OAAO2B,CAAAA,CAAK,OAAA,EAAY,QAAA,CACpB,QAAA,CAAS,cAA2BA,CAAAA,CAAK,OAAO,CAAA,CAChDA,CAAAA,CAAK,OAAA,CAEP3B,CAAAA,EACFD,CAAAA,CAAgBC,CAAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,YAAA,CAAc,IAAA,CAAK,OAAA,CAAQ,cAAA,CAAgB,IAAM,CACrF,KAAK,gBAAA,EAAiB,CACtB,IAAA,CAAK,WAAA,CAAY2B,CAAAA,CAAMO,CAAK,CAAA,CAC5B,UAAA,CAAW,IAAM,CACf,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,GAAA,CAAI,QAAQ,EAC5C,CAAA,CAAG,EAAE,EACP,CAAC,EAEL,CAKQ,gBAAA,EAAyB,CAC/B,IAAMP,CAAAA,CAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA,CACxC,GAAI,CAACA,CAAAA,CAAM,OAEX,IAAM3B,CAAAA,CACJ,OAAO2B,CAAAA,CAAK,OAAA,EAAY,QAAA,CACpB,SAAS,aAAA,CAA2BA,CAAAA,CAAK,OAAO,CAAA,CAChDA,CAAAA,CAAK,OAAA,CAEX,GAAI,CAAC3B,EAAS,OAEd,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAS,CAAA,EAAG,QAAA,CAAS,eAAA,CAAgB,YAAY,CAAA,EAAA,CAAA,CAE7E,IAAMI,CAAAA,CAAOJ,CAAAA,CAAQ,qBAAA,EAAsB,CACrCmC,EAAU,IAAA,CAAK,OAAA,CAAQ,gBAAA,CAEvBC,CAAAA,CAAY,MAAA,CAAO,WAAA,EAAe,QAAA,CAAS,eAAA,CAAgB,SAAA,CAC3DC,CAAAA,CAAa,MAAA,CAAO,WAAA,EAAe,QAAA,CAAS,eAAA,CAAgB,UAAA,CAE5DlB,CAAAA,CAAY,KAAK,QAAA,CAAS,SAAA,CAChCA,CAAAA,CAAU,KAAA,CAAM,IAAA,CAAO,CAAA,EAAGf,CAAAA,CAAK,IAAA,CAAOiC,CAAAA,CAAaF,CAAO,CAAA,EAAA,CAAA,CAC1DhB,CAAAA,CAAU,KAAA,CAAM,GAAA,CAAM,CAAA,EAAGf,CAAAA,CAAK,IAAMgC,CAAAA,CAAYD,CAAO,CAAA,EAAA,CAAA,CACvDhB,CAAAA,CAAU,KAAA,CAAM,KAAA,CAAQ,CAAA,EAAGf,CAAAA,CAAK,KAAA,CAAQ+B,CAAAA,CAAU,CAAC,CAAA,EAAA,CAAA,CACnDhB,CAAAA,CAAU,KAAA,CAAM,MAAA,CAAS,CAAA,EAAGf,EAAK,MAAA,CAAS+B,CAAAA,CAAU,CAAC,CAAA,EAAA,CAAA,CAErD,IAAA,CAAK,aAAA,CAAc/B,CAAAA,CAAMuB,CAAAA,CAAK,QAAQ,EACxC,CAKQ,aAAA,CAAcW,CAAAA,CAAqBC,CAAAA,CAAyC,CAClF,IAAMnB,EAAQ,IAAA,CAAK,QAAA,CAAS,KAAA,CAC5BA,CAAAA,CAAM,KAAA,CAAM,UAAA,CAAa,QAAA,CACzBA,CAAAA,CAAM,KAAA,CAAM,OAAA,CAAU,OAAA,CACtB,IAAMoB,CAAAA,CAAYpB,CAAAA,CAAM,qBAAA,EAAsB,CAC9CA,EAAM,KAAA,CAAM,UAAA,CAAa,EAAA,CACzBA,CAAAA,CAAM,KAAA,CAAM,OAAA,CAAU,EAAA,CAEtB,IAAMnB,CAAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,WAAA,CACtBkC,CAAAA,CAAU,IAAA,CAAK,OAAA,CAAQ,gBAAA,CAEvBM,EAAW,CACf,KAAA,CAAO,MAAA,CAAO,UAAA,CACd,MAAA,CAAQ,MAAA,CAAO,WACjB,CAAA,CAEMC,EAAiD,CACrD,MAAA,CAAQ,CACN,IAAA,CAAMJ,CAAAA,CAAW,IAAA,CAAOA,CAAAA,CAAW,KAAA,CAAQ,EAAIE,CAAAA,CAAU,KAAA,CAAQ,CAAA,CACjE,GAAA,CAAKF,CAAAA,CAAW,MAAA,CAASH,CAAAA,CAAUlC,CAAAA,CACnC,KAAA,CAAO,KAAA,CACP,IAAA,CAAMqC,CAAAA,CAAW,MAAA,CAASH,CAAAA,CAAUlC,CAAAA,CAASuC,CAAAA,CAAU,OAASC,CAAAA,CAAS,MAC3E,CAAA,CACA,GAAA,CAAK,CACH,IAAA,CAAMH,CAAAA,CAAW,IAAA,CAAOA,CAAAA,CAAW,KAAA,CAAQ,CAAA,CAAIE,CAAAA,CAAU,KAAA,CAAQ,CAAA,CACjE,GAAA,CAAKF,CAAAA,CAAW,IAAMH,CAAAA,CAAUlC,CAAAA,CAASuC,CAAAA,CAAU,MAAA,CACnD,KAAA,CAAO,QAAA,CACP,IAAA,CAAMF,CAAAA,CAAW,GAAA,CAAMH,CAAAA,CAAUlC,CAAAA,CAASuC,CAAAA,CAAU,MAAA,CAAS,CAC/D,CAAA,CACA,KAAA,CAAO,CACL,IAAA,CAAMF,CAAAA,CAAW,KAAA,CAAQH,CAAAA,CAAUlC,CAAAA,CACnC,GAAA,CAAKqC,CAAAA,CAAW,GAAA,CAAMA,CAAAA,CAAW,MAAA,CAAS,CAAA,CAAIE,CAAAA,CAAU,MAAA,CAAS,CAAA,CACjE,KAAA,CAAO,MAAA,CACP,KAAMF,CAAAA,CAAW,KAAA,CAAQH,CAAAA,CAAUlC,CAAAA,CAASuC,CAAAA,CAAU,KAAA,CAAQC,CAAAA,CAAS,KACzE,CAAA,CACA,IAAA,CAAM,CACJ,IAAA,CAAMH,CAAAA,CAAW,IAAA,CAAOH,CAAAA,CAAUlC,CAAAA,CAASuC,EAAU,KAAA,CACrD,GAAA,CAAKF,CAAAA,CAAW,GAAA,CAAMA,CAAAA,CAAW,MAAA,CAAS,CAAA,CAAIE,CAAAA,CAAU,MAAA,CAAS,CAAA,CACjE,KAAA,CAAO,OAAA,CACP,IAAA,CAAMF,CAAAA,CAAW,IAAA,CAAOH,CAAAA,CAAUlC,EAASuC,CAAAA,CAAU,KAAA,CAAQ,CAC/D,CACF,CAAA,CAEMV,CAAAA,CACJS,CAAAA,EAAqBG,CAAAA,CAAUH,CAAiB,CAAA,EAAG,IAAA,CAC/CA,CAAAA,CACC,MAAA,CAAO,IAAA,CAAKG,CAAS,CAAA,CAAE,KACrBC,CAAAA,EAAQD,CAAAA,CAAUC,CAAoB,CAAA,CAAE,IAC3C,CAAA,EAAuB,QAAA,CAEvBC,CAAAA,CAASF,EAAUZ,CAAQ,CAAA,CAE3BM,CAAAA,CAAY,MAAA,CAAO,WAAA,EAAe,QAAA,CAAS,eAAA,CAAgB,SAAA,CAC3DC,EAAa,MAAA,CAAO,WAAA,EAAe,QAAA,CAAS,eAAA,CAAgB,UAAA,CAE5DQ,CAAAA,CACJ,IAAA,CAAK,GAAA,CAAI,EAAA,CAAI,IAAA,CAAK,GAAA,CAAID,CAAAA,CAAO,IAAA,CAAMH,CAAAA,CAAS,KAAA,CAAQD,CAAAA,CAAU,MAAQ,EAAE,CAAC,CAAA,CAAIH,CAAAA,CACzES,CAAAA,CACJ,IAAA,CAAK,GAAA,CAAI,EAAA,CAAI,IAAA,CAAK,GAAA,CAAIF,CAAAA,CAAO,GAAA,CAAKH,CAAAA,CAAS,MAAA,CAASD,CAAAA,CAAU,MAAA,CAAS,EAAE,CAAC,CAAA,CAAIJ,CAAAA,CAEhFhB,CAAAA,CAAM,KAAA,CAAM,IAAA,CAAO,CAAA,EAAGyB,CAAS,CAAA,EAAA,CAAA,CAC/BzB,CAAAA,CAAM,KAAA,CAAM,GAAA,CAAM,CAAA,EAAG0B,CAAQ,CAAA,EAAA,CAAA,CAE7B,IAAA,CAAK,YAAYF,CAAAA,CAAO,KAAK,EAC/B,CAKQ,WAAA,CAAYG,CAAAA,CAAgC,CAClD,IAAM3B,EAAQ,IAAA,CAAK,QAAA,CAAS,KAAA,CACNA,CAAAA,CAAM,aAAA,CAAc,iBAAiB,CAAA,EAC5C,MAAA,GAEf,IAAM4B,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,CAAAA,CAAM,SAAA,CAAY,CAAA,eAAA,EAAkBD,CAAS,CAAA,CAAA,CAC7C3B,CAAAA,CAAM,WAAA,CAAY4B,CAAK,EACzB,CAKQ,YAAYrB,CAAAA,CAAuBO,CAAAA,CAAqB,CAC9D,IAAMd,CAAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,KAAA,CACtB6B,CAAAA,CAAUf,CAAAA,GAAU,CAAA,CACpBgB,CAAAA,CAAShB,CAAAA,GAAU,IAAA,CAAK,KAAA,CAAM,MAAA,CAAS,EAEzCiB,CAAAA,CACA,IAAA,CAAK,SAAA,CAAU,KAAA,CACjBA,CAAAA,CAAU,IAAA,CAAK,SAAA,CAAU,KAAA,CAAMxB,CAAAA,CAAMO,CAAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,CAE7DiB,CAAAA,CAAU,IAAA,CAAK,uBAAuBxB,CAAAA,CAAMO,CAAAA,CAAOe,CAAAA,CAASC,CAAM,CAAA,CAGpE9B,CAAAA,CAAM,SAAA,CAAY+B,CAAAA,CAClB,KAAK,gBAAA,GACP,CAKQ,sBAAA,CACNxB,CAAAA,CACAO,CAAAA,CACAe,CAAAA,CACAC,CAAAA,CACQ,CACR,OAAO;AAAA;AAAA,QAAA,EAGDvB,CAAAA,CAAK,KAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,YAAA,CACvB;AAAA;AAAA,YAAA,EAEAA,EAAK,KAAA,CAAQ,CAAA,2BAAA,EAA8BA,CAAAA,CAAK,KAAK,QAAU,EAAE;AAAA,YAAA,EAEjE,IAAA,CAAK,QAAQ,YAAA,CACT;AAAA;AAAA,qBAAA,EAEKO,CAAAA,CAAQ,CAAC,CAAA,IAAA,EAAO,IAAA,CAAK,MAAM,MAAM;AAAA;AAAA,YAAA,CAAA,CAGtC,EACN;AAAA;AAAA,QAAA,CAAA,CAGE,EACN;;AAAA,QAAA,EAGEP,EAAK,IAAA,CACD;AAAA;AAAA,YAAA,EAEAA,EAAK,IAAI;AAAA;AAAA,QAAA,CAAA,CAGT,EACN;;AAAA,QAAA,EAGE,IAAA,CAAK,QAAQ,YAAA,CACT;AAAA;AAAA,uDAAA,EAAA,CAE6CO,CAAAA,CAAQ,CAAA,EAAK,IAAA,CAAK,KAAA,CAAM,OAAU,GAAG,CAAA;AAAA;AAAA,QAAA,CAAA,CAGlF,EACN;;AAAA,QAAA,EAGE,IAAA,CAAK,QAAQ,WAAA,CACT;AAAA;AAAA,YAAA,EAGA,IAAA,CAAK,QAAQ,QAAA,CACT;AAAA;AAAA,gBAAA,EAEAP,CAAAA,CAAK,QAAA,EAAY,IAAA,CAAK,OAAA,CAAQ,QAAQ;AAAA;AAAA,YAAA,CAAA,CAGtC,aACN;;AAAA;AAAA,cAAA,EAIKsB,EAMG,EAAA,CALA;AAAA;AAAA,kBAAA,EAEAtB,CAAAA,CAAK,QAAA,EAAY,IAAA,CAAK,OAAA,CAAQ,QAAQ;AAAA;AAAA,cAAA,CAI5C;;AAAA,oCAAA,EAEwBuB,CAAAA,CAAS,gBAAkB,aAAa,CAAA;AAAA,sCAAA,EACtCA,CAAAA,CAAS,SAAW,MAAM,CAAA;AAAA,gBAAA,EAChDA,CAAAA,CAASvB,CAAAA,CAAK,UAAA,EAAc,IAAA,CAAK,OAAA,CAAQ,WAAaA,CAAAA,CAAK,QAAA,EAAY,IAAA,CAAK,OAAA,CAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA,QAAA,CAAA,CAKhG,EACN;AAAA;AAAA,IAAA,CAGN,CAKQ,gBAAA,EAAyB,CACjB,IAAA,CAAK,SAAS,KAAA,CAEtB,gBAAA,CAAoC,kBAAkB,CAAA,CAAE,OAAA,CAASyB,CAAAA,EAAQ,CAC7EA,CAAAA,CAAI,iBAAiB,OAAA,CAAU/B,CAAAA,EAAM,CAEnC,OADgBA,CAAAA,CAAE,aAAA,CAA8B,YAAA,CAAa,gBAAgB,GAE3E,KAAK,MAAA,CACH,IAAA,CAAK,KAAI,CACT,MACF,KAAK,MAAA,CACH,KAAK,IAAA,EAAK,CACV,MACF,KAAK,MAAA,CACH,IAAA,CAAK,IAAA,EAAK,CACV,MACF,KAAK,QAAA,CACH,IAAA,CAAK,MAAA,GACL,KACJ,CACF,CAAC,EACH,CAAC,EACH,CAKO,IAAA,EAAa,CACd,IAAA,CAAK,WAAA,CAAc,IAAA,CAAK,KAAA,CAAM,OAAS,CAAA,CACzC,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,YAAc,CAAC,CAAA,CAElC,IAAA,CAAK,MAAA,GAET,CAKO,IAAA,EAAa,CACd,IAAA,CAAK,WAAA,CAAc,CAAA,EACrB,IAAA,CAAK,QAAA,CAAS,KAAK,WAAA,CAAc,CAAC,EAEtC,CAKO,MAAA,EAAe,CACpB,IAAA,CAAK,eAAA,CAAgB,UAAU,CAAA,CAC/B,IAAA,CAAK,aAAA,EAAc,CACnB,IAAA,CAAK,GAAA,GACP,CAKO,KAAY,CACZ,IAAA,CAAK,QAAA,GAEV,IAAA,CAAK,SAAW,KAAA,CAChB,IAAA,CAAK,eAAA,CAAgB,OAAO,EAE5B,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA,CAE7C,UAAA,CAAW,IAAM,CACf,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,UAAU,MAAA,CAAO,QAAQ,EACjD,CAAA,CAAG,KAAK,OAAA,CAAQ,iBAAiB,CAAA,EACnC,CAKQ,YAAA,CAAaM,CAAAA,CAAoB,CACvCtC,CAAAA,CAAU,KAAK,OAAA,CAAQ,UAAA,CAAYsC,CAAAA,CAAK,QAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,YAAY,EAC/E,CAKQ,YAAA,EAAuB,CAC7B,IAAMpC,CAAAA,CAAQG,CAAAA,CAAU,IAAA,CAAK,OAAA,CAAQ,UAAU,EAC/C,OAAOH,CAAAA,EAAQ,QAAA,CAASA,CAAAA,CAAO,EAAE,CAAA,EAAK,CACxC,CAKQ,eAAsB,CAC5BO,CAAAA,CAAa,IAAA,CAAK,OAAA,CAAQ,UAAU,EACtC,CAKQ,eAAA,CAAgBR,KAAqCX,CAAAA,CAAuB,CAClF,IAAMwB,CAAAA,CAAW,KAAK,SAAA,CAAUb,CAAI,CAAA,CAChC,OAAOa,GAAa,UAAA,EAErBA,CAAAA,CAA0C,GAAGxB,CAAI,EAEtD,CAKO,OAAA,EAAgB,CACjB,KAAK,UAAA,EACP,QAAA,CAAS,mBAAA,CAAoB,SAAA,CAAW,KAAK,UAAU,CAAA,CAErD,IAAA,CAAK,wBAAA,GACP,OAAO,mBAAA,CAAoB,QAAA,CAAU,IAAA,CAAK,wBAAwB,CAAA,CAClE,MAAA,CAAO,mBAAA,CAAoB,QAAA,CAAU,KAAK,wBAAA,CAA0B,IAAI,CAAA,CAAA,CAG1E,IAAA,CAAK,SAAS,OAAA,EAAS,MAAA,EAAO,CAE9B,IAAA,CAAK,MAAQ,EAAC,CACd,IAAA,CAAK,WAAA,CAAc,CAAA,CACnB,IAAA,CAAK,QAAA,CAAW,MAClB,CACF,ECllBO,IAAM0E,CAAAA,CAAc,CAIzB,eAAevC,CAAAA,CAAoC,CACjD,IAAMwC,CAAAA,CAAK,IAAItC,CAAAA,CAAKF,CAAO,CAAA,CAC3B,OAAAwC,CAAAA,CAAG,qBAAA,EAAsB,CAClBA,CACT,EAKA,QAAA,CAAStB,CAAAA,CAAiC,CACxC,IAAMsB,EAAK,IAAItC,CAAAA,CAAKgB,CAAAA,CAAO,OAAO,EAClC,OAAAsB,CAAAA,CAAG,SAAA,CAAUtB,CAAM,CAAA,CACZsB,CACT,CAAA,CAKA,KAAA,CAAM7B,EAA0BX,CAAAA,CAAoC,CAClE,IAAMwC,CAAAA,CAAK,IAAItC,CAAAA,CAAKF,CAAO,CAAA,CAC3B,OAAAwC,EAAG,SAAA,CAAU,CAAE,KAAA,CAAA7B,CAAM,CAAC,CAAA,CACtB6B,CAAAA,CAAG,KAAA,GACIA,CACT,CACF,EAGI,OAAO,OAAW,GAAA,GACnB,MAAA,CAAmD,WAAA,CAActC,CAAAA,CACjE,OAA0D,WAAA,CAAcqC,CAAAA,CAAAA","file":"index.js","sourcesContent":["/**\n * Utility functions for Walkthrough\n */\n\n/**\n * Easing function for smooth animations\n */\nexport function easeInOut(t: number): number {\n return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n}\n\n/**\n * Throttle function to limit execution frequency\n */\nexport function throttle void>(\n func: T,\n limit: number,\n): (...args: Parameters) => void {\n let inThrottle: boolean;\n return function (this: unknown, ...args: Parameters) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\n/**\n * Adjust color brightness\n */\nexport function adjustColor(color: string, amount: number): string {\n const usePound = color[0] === '#';\n const col = usePound ? color.slice(1) : color;\n const num = parseInt(col, 16);\n let r = (num >> 16) + amount;\n let g = ((num >> 8) & 0x00ff) + amount;\n let b = (num & 0x0000ff) + amount;\n r = r > 255 ? 255 : r < 0 ? 0 : r;\n g = g > 255 ? 255 : g < 0 ? 0 : g;\n b = b > 255 ? 255 : b < 0 ? 0 : b;\n return (usePound ? '#' : '') + ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');\n}\n\n/**\n * Save data to cookie\n */\nexport function setCookie(name: string, value: string, days: number): void {\n const expiry = new Date();\n expiry.setDate(expiry.getDate() + days);\n document.cookie = `${name}=${value};expires=${expiry.toUTCString()};path=/`;\n}\n\n/**\n * Get data from cookie\n */\nexport function getCookie(name: string): string | null {\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [cookieName, value] = cookie.trim().split('=');\n if (cookieName === name) {\n return value;\n }\n }\n return null;\n}\n\n/**\n * Delete cookie\n */\nexport function deleteCookie(name: string): void {\n document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;\n}\n\n/**\n * Scroll to element smoothly\n */\nexport function scrollToElement(\n element: HTMLElement,\n offset: number,\n duration: number,\n callback: () => void,\n): void {\n const rect = element.getBoundingClientRect();\n\n if (rect.top >= 0 && rect.bottom <= window.innerHeight) {\n callback();\n return;\n }\n\n const targetY = window.pageYOffset + rect.top - offset;\n const startY = window.pageYOffset;\n const diff = targetY - startY;\n let start: number;\n\n const scroll = (timestamp: number) => {\n if (!start) start = timestamp;\n const elapsed = timestamp - start;\n const progress = Math.min(elapsed / duration, 1);\n\n window.scrollTo(0, startY + diff * easeInOut(progress));\n\n if (elapsed < duration) {\n requestAnimationFrame(scroll);\n } else {\n callback();\n }\n };\n\n requestAnimationFrame(scroll);\n}\n","import { WalkthroughOptions } from './types';\nimport { adjustColor } from './utils';\n\n/**\n * Generate CSS styles for the walkthrough\n */\nexport function generateStyles(options: Required): string {\n return `\n .wt-overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n z-index: ${options.zIndex};\n opacity: 0;\n visibility: hidden;\n transition: opacity ${options.animationDuration}ms ease;\n pointer-events: none;\n }\n .wt-overlay.active {\n opacity: 1;\n visibility: visible;\n pointer-events: none;\n }\n .wt-highlight {\n position: absolute;\n border-radius: 8px;\n transition: all ${options.animationDuration}ms ease;\n box-shadow: 0 0 0 99999px ${options.overlayColor};\n background: transparent;\n pointer-events: none;\n z-index: ${options.zIndex};\n }\n .wt-popup {\n position: absolute;\n background: white;\n border-radius: 12px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n z-index: ${options.zIndex + 1};\n max-width: ${options.popupWidth}px;\n opacity: 0;\n transform: scale(0.9);\n transition: all ${options.animationDuration}ms ease;\n pointer-events: auto;\n }\n .wt-popup.active {\n opacity: 1;\n transform: scale(1);\n }\n .wt-popup-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n border-color: transparent;\n }\n .wt-popup-arrow.top {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-width: 0 10px 10px 10px;\n border-bottom-color: white;\n }\n .wt-popup-arrow.bottom {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-width: 10px 10px 0 10px;\n border-top-color: white;\n }\n .wt-popup-arrow.left {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-width: 10px 10px 10px 0;\n border-right-color: white;\n }\n .wt-popup-arrow.right {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-width: 10px 0 10px 10px;\n border-left-color: white;\n }\n .wt-popup-content {\n padding: 24px;\n }\n .wt-popup-header {\n margin-bottom: 16px;\n }\n .wt-popup-title {\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n margin: 0 0 8px 0;\n line-height: 1.3;\n }\n .wt-popup-step-count {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n .wt-popup-body {\n font-size: 15px;\n line-height: 1.6;\n color: #444;\n margin-bottom: 20px;\n }\n .wt-progress {\n height: 4px;\n background: #e0e0e0;\n border-radius: 2px;\n overflow: hidden;\n margin-bottom: 20px;\n }\n .wt-progress-bar {\n height: 100%;\n background: ${options.progressColor};\n border-radius: 2px;\n transition: width ${options.animationDuration}ms ease;\n }\n .wt-popup-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .wt-btn {\n padding: 10px 20px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n outline: none;\n }\n .wt-btn:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n }\n .wt-btn:active {\n transform: translateY(0);\n }\n .wt-btn-skip {\n background: none;\n color: #666;\n padding: 10px;\n }\n .wt-btn-skip:hover {\n color: #333;\n background: rgba(0,0,0,0.05);\n }\n .wt-btn-prev {\n background: #f5f5f5;\n color: #666;\n border: 1px solid #ddd;\n }\n .wt-btn-prev:hover {\n background: #e8e8e8;\n }\n .wt-btn-next, .wt-btn-finish {\n background: ${options.progressColor};\n color: white;\n }\n .wt-btn-next:hover, .wt-btn-finish:hover {\n background: ${adjustColor(options.progressColor, -20)};\n }\n .wt-btn-group {\n display: flex;\n gap: 12px;\n }\n `;\n}\n","import {\n WalkthroughOptions,\n WalkthroughStep,\n WalkthroughCallbacks,\n WalkthroughTemplates,\n WalkthroughConfig,\n WalkthroughElements,\n PopupPosition,\n PositionInfo,\n} from './types';\nimport { throttle, scrollToElement, setCookie, getCookie, deleteCookie } from './utils';\nimport { generateStyles } from './styles';\n\n/**\n * Default options for Walkthrough\n */\nconst DEFAULT_OPTIONS: Required = {\n overlayColor: 'rgba(0, 0, 0, 0.5)',\n highlightPadding: 10,\n animationDuration: 300,\n scrollDuration: 500,\n scrollOffset: 100,\n zIndex: 99999,\n popupWidth: 380,\n popupOffset: 15,\n popupClass: 'wt-popup',\n showProgress: true,\n progressColor: '#4CAF50',\n showButtons: true,\n showSkip: true,\n skipText: 'Skip',\n prevText: '← Previous',\n nextText: 'Next →',\n finishText: 'Finish',\n keyboard: true,\n escapeToExit: true,\n arrowNavigation: true,\n cookieName: 'walkthrough_progress',\n cookieExpiry: 30,\n rememberProgress: false,\n closeOnOverlay: true,\n autoStart: false,\n startDelay: 0,\n attributePrefix: 'wt',\n stepAttribute: 'step',\n titleAttribute: 'title',\n textAttribute: 'text',\n positionAttribute: 'position',\n};\n\n/**\n * Main Walkthrough class\n */\nexport class Core {\n private steps: WalkthroughStep[] = [];\n private currentStep = 0;\n private isActive = false;\n private callbacks: WalkthroughCallbacks = {};\n private templates: WalkthroughTemplates = {};\n private options: Required;\n private elements!: WalkthroughElements;\n private keyHandler?: (e: KeyboardEvent) => void;\n private positionHandler?: () => void;\n private throttledPositionHandler?: () => void;\n\n constructor(options: WalkthroughOptions = {}) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n this.init();\n }\n\n /**\n * Initialize the walkthrough\n */\n private init(): void {\n this.createElements();\n this.bindEvents();\n\n if (this.options.autoStart) {\n setTimeout(() => {\n this.scanForAttributeSteps();\n if (this.steps.length > 0) {\n this.start();\n }\n }, this.options.startDelay);\n }\n }\n\n /**\n * Create DOM elements\n */\n private createElements(): void {\n const overlay = document.createElement('div');\n overlay.className = 'wt-overlay';\n\n const style = document.createElement('style');\n style.textContent = generateStyles(this.options);\n overlay.appendChild(style);\n\n const highlight = document.createElement('div');\n highlight.className = 'wt-highlight';\n\n const popup = document.createElement('div');\n popup.className = this.options.popupClass;\n\n overlay.appendChild(highlight);\n overlay.appendChild(popup);\n document.body.appendChild(overlay);\n\n this.elements = { overlay, highlight, popup };\n }\n\n /**\n * Bind event listeners\n */\n private bindEvents(): void {\n if (this.options.closeOnOverlay) {\n this.elements.overlay.addEventListener('click', (e) => {\n if (e.target === this.elements.overlay) {\n this.end();\n }\n });\n }\n\n if (this.options.keyboard) {\n this.keyHandler = (e: KeyboardEvent) => {\n if (!this.isActive) return;\n\n if (this.options.escapeToExit && e.key === 'Escape') {\n this.end();\n } else if (this.options.arrowNavigation) {\n if (e.key === 'ArrowRight' || e.key === 'Enter') {\n this.next();\n } else if (e.key === 'ArrowLeft') {\n this.prev();\n }\n }\n };\n document.addEventListener('keydown', this.keyHandler);\n }\n\n this.positionHandler = () => {\n if (this.isActive && this.currentStep < this.steps.length) {\n this.positionElements();\n }\n };\n this.throttledPositionHandler = throttle(this.positionHandler, 100);\n window.addEventListener('resize', this.throttledPositionHandler);\n window.addEventListener('scroll', this.throttledPositionHandler, true);\n }\n\n /**\n * Scan DOM for attribute-based steps\n */\n public scanForAttributeSteps(): void {\n const prefix = this.options.attributePrefix;\n const stepAttr = `data-${prefix}-${this.options.stepAttribute}`;\n const elements = document.querySelectorAll(`[${stepAttr}]`);\n\n const steps = Array.from(elements).map((el) => {\n const step = parseInt(el.getAttribute(stepAttr) || '0', 10);\n const title = el.getAttribute(`data-${prefix}-${this.options.titleAttribute}`) || undefined;\n const text = el.getAttribute(`data-${prefix}-${this.options.textAttribute}`) || undefined;\n const position =\n (el.getAttribute(`data-${prefix}-${this.options.positionAttribute}`) as PopupPosition) ||\n undefined;\n\n return {\n element: el,\n step,\n title,\n text,\n position,\n };\n });\n\n steps.sort((a, b) => (a.step || 0) - (b.step || 0));\n this.steps = steps;\n }\n\n /**\n * Configure walkthrough with JSON\n */\n public configure(config: WalkthroughConfig): void {\n if (config.steps) {\n this.steps = config.steps.map((step) => {\n if (typeof step.element === 'string') {\n const el = document.querySelector(step.element);\n if (!el) {\n throw new Error(`Element not found: ${step.element}`);\n }\n return { ...step, element: el };\n }\n return step;\n });\n }\n\n if (config.options) {\n this.options = { ...this.options, ...config.options };\n }\n\n if (config.callbacks) {\n this.callbacks = { ...this.callbacks, ...config.callbacks };\n }\n\n if (config.templates) {\n this.templates = { ...this.templates, ...config.templates };\n }\n }\n\n /**\n * Start the walkthrough\n */\n public start(stepIndex?: number | null): void {\n if (this.steps.length === 0) {\n console.warn('Walkthrough: No steps configured');\n return;\n }\n\n this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`;\n\n if (stepIndex === null || stepIndex === undefined) {\n if (this.options.rememberProgress) {\n stepIndex = this.loadProgress();\n } else {\n stepIndex = 0;\n }\n }\n\n this.currentStep = stepIndex;\n this.isActive = true;\n\n this.triggerCallback('onStart');\n this.elements.overlay.classList.add('active');\n\n setTimeout(() => {\n this.showStep(this.currentStep);\n }, 50);\n }\n\n /**\n * Show a specific step\n */\n private showStep(index: number): void {\n if (index < 0 || index >= this.steps.length) return;\n\n this.elements.popup.classList.remove('active');\n\n const step = this.steps[index];\n this.currentStep = index;\n\n if (this.options.rememberProgress) {\n this.saveProgress(index);\n }\n\n this.triggerCallback('onStep', step, index);\n\n const element =\n typeof step.element === 'string'\n ? document.querySelector(step.element)\n : step.element;\n\n if (element) {\n scrollToElement(element, this.options.scrollOffset, this.options.scrollDuration, () => {\n this.positionElements();\n this.updatePopup(step, index);\n setTimeout(() => {\n this.elements.popup.classList.add('active');\n }, 50);\n });\n }\n }\n\n /**\n * Position highlight and popup elements\n */\n private positionElements(): void {\n const step = this.steps[this.currentStep];\n if (!step) return;\n\n const element =\n typeof step.element === 'string'\n ? document.querySelector(step.element)\n : step.element;\n\n if (!element) return;\n\n this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`;\n\n const rect = element.getBoundingClientRect();\n const padding = this.options.highlightPadding;\n\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const highlight = this.elements.highlight;\n highlight.style.left = `${rect.left + scrollLeft - padding}px`;\n highlight.style.top = `${rect.top + scrollTop - padding}px`;\n highlight.style.width = `${rect.width + padding * 2}px`;\n highlight.style.height = `${rect.height + padding * 2}px`;\n\n this.positionPopup(rect, step.position);\n }\n\n /**\n * Position popup relative to target element\n */\n private positionPopup(targetRect: DOMRect, preferredPosition?: PopupPosition): void {\n const popup = this.elements.popup;\n popup.style.visibility = 'hidden';\n popup.style.display = 'block';\n const popupRect = popup.getBoundingClientRect();\n popup.style.visibility = '';\n popup.style.display = '';\n\n const offset = this.options.popupOffset;\n const padding = this.options.highlightPadding;\n\n const viewport = {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n\n const positions: Record = {\n bottom: {\n left: targetRect.left + targetRect.width / 2 - popupRect.width / 2,\n top: targetRect.bottom + padding + offset,\n arrow: 'top',\n fits: targetRect.bottom + padding + offset + popupRect.height < viewport.height,\n },\n top: {\n left: targetRect.left + targetRect.width / 2 - popupRect.width / 2,\n top: targetRect.top - padding - offset - popupRect.height,\n arrow: 'bottom',\n fits: targetRect.top - padding - offset - popupRect.height > 0,\n },\n right: {\n left: targetRect.right + padding + offset,\n top: targetRect.top + targetRect.height / 2 - popupRect.height / 2,\n arrow: 'left',\n fits: targetRect.right + padding + offset + popupRect.width < viewport.width,\n },\n left: {\n left: targetRect.left - padding - offset - popupRect.width,\n top: targetRect.top + targetRect.height / 2 - popupRect.height / 2,\n arrow: 'right',\n fits: targetRect.left - padding - offset - popupRect.width > 0,\n },\n };\n\n const position: PopupPosition =\n preferredPosition && positions[preferredPosition]?.fits\n ? preferredPosition\n : (Object.keys(positions).find(\n (pos) => positions[pos as PopupPosition].fits,\n ) as PopupPosition) || 'bottom';\n\n const chosen = positions[position];\n\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const finalLeft =\n Math.max(10, Math.min(chosen.left, viewport.width - popupRect.width - 10)) + scrollLeft;\n const finalTop =\n Math.max(10, Math.min(chosen.top, viewport.height - popupRect.height - 10)) + scrollTop;\n\n popup.style.left = `${finalLeft}px`;\n popup.style.top = `${finalTop}px`;\n\n this.updateArrow(chosen.arrow);\n }\n\n /**\n * Update arrow direction\n */\n private updateArrow(direction: PopupPosition): void {\n const popup = this.elements.popup;\n const existingArrow = popup.querySelector('.wt-popup-arrow');\n existingArrow?.remove();\n\n const arrow = document.createElement('div');\n arrow.className = `wt-popup-arrow ${direction}`;\n popup.appendChild(arrow);\n }\n\n /**\n * Update popup content\n */\n private updatePopup(step: WalkthroughStep, index: number): void {\n const popup = this.elements.popup;\n const isFirst = index === 0;\n const isLast = index === this.steps.length - 1;\n\n let content: string;\n if (this.templates.popup) {\n content = this.templates.popup(step, index, this.steps.length);\n } else {\n content = this.getDefaultPopupContent(step, index, isFirst, isLast);\n }\n\n popup.innerHTML = content;\n this.bindPopupButtons();\n }\n\n /**\n * Get default popup content\n */\n private getDefaultPopupContent(\n step: WalkthroughStep,\n index: number,\n isFirst: boolean,\n isLast: boolean,\n ): string {\n return `\n
\n ${\n step.title || this.options.showProgress\n ? `\n
\n ${step.title ? `

${step.title}

` : ''}\n ${\n this.options.showProgress\n ? `\n
\n Step ${index + 1} of ${this.steps.length}\n
\n `\n : ''\n }\n
\n `\n : ''\n }\n\n ${\n step.text\n ? `\n
\n ${step.text}\n
\n `\n : ''\n }\n\n ${\n this.options.showProgress\n ? `\n
\n
\n
\n `\n : ''\n }\n\n ${\n this.options.showButtons\n ? `\n
\n ${\n this.options.showSkip\n ? `\n \n `\n : '
'\n }\n\n
\n ${\n !isFirst\n ? `\n \n `\n : ''\n }\n\n \n
\n
\n `\n : ''\n }\n
\n `;\n }\n\n /**\n * Bind popup button events\n */\n private bindPopupButtons(): void {\n const popup = this.elements.popup;\n\n popup.querySelectorAll('[data-wt-action]').forEach((btn) => {\n btn.addEventListener('click', (e) => {\n const action = (e.currentTarget as HTMLElement).getAttribute('data-wt-action');\n switch (action) {\n case 'skip':\n this.end();\n break;\n case 'prev':\n this.prev();\n break;\n case 'next':\n this.next();\n break;\n case 'finish':\n this.finish();\n break;\n }\n });\n });\n }\n\n /**\n * Navigate to next step\n */\n public next(): void {\n if (this.currentStep < this.steps.length - 1) {\n this.showStep(this.currentStep + 1);\n } else {\n this.finish();\n }\n }\n\n /**\n * Navigate to previous step\n */\n public prev(): void {\n if (this.currentStep > 0) {\n this.showStep(this.currentStep - 1);\n }\n }\n\n /**\n * Finish the walkthrough\n */\n public finish(): void {\n this.triggerCallback('onFinish');\n this.clearProgress();\n this.end();\n }\n\n /**\n * End the walkthrough\n */\n public end(): void {\n if (!this.isActive) return;\n\n this.isActive = false;\n this.triggerCallback('onEnd');\n\n this.elements.popup.classList.remove('active');\n\n setTimeout(() => {\n this.elements.overlay.classList.remove('active');\n }, this.options.animationDuration);\n }\n\n /**\n * Save progress to cookie\n */\n private saveProgress(step: number): void {\n setCookie(this.options.cookieName, step.toString(), this.options.cookieExpiry);\n }\n\n /**\n * Load progress from cookie\n */\n private loadProgress(): number {\n const value = getCookie(this.options.cookieName);\n return value ? parseInt(value, 10) || 0 : 0;\n }\n\n /**\n * Clear saved progress\n */\n private clearProgress(): void {\n deleteCookie(this.options.cookieName);\n }\n\n /**\n * Trigger callback function\n */\n private triggerCallback(name: keyof WalkthroughCallbacks, ...args: unknown[]): void {\n const callback = this.callbacks[name];\n if (typeof callback === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n (callback as (...args: unknown[]) => void)(...args);\n }\n }\n\n /**\n * Destroy the walkthrough and clean up\n */\n public destroy(): void {\n if (this.keyHandler) {\n document.removeEventListener('keydown', this.keyHandler);\n }\n if (this.throttledPositionHandler) {\n window.removeEventListener('resize', this.throttledPositionHandler);\n window.removeEventListener('scroll', this.throttledPositionHandler, true);\n }\n\n this.elements.overlay?.remove();\n\n this.steps = [];\n this.currentStep = 0;\n this.isActive = false;\n }\n}\n","/**\n * WalkthroughJS - TypeScript Edition\n * Lightweight, powerful walkthrough library with zero dependencies\n */\n\nexport { Core } from './core';\nexport type {\n WalkthroughOptions,\n WalkthroughStep,\n WalkthroughCallbacks,\n WalkthroughTemplates,\n WalkthroughConfig,\n PopupPosition,\n} from './types';\n\nimport { Core } from './core';\nimport { WalkthroughOptions, WalkthroughStep, WalkthroughConfig } from './types';\n\n/**\n * Convenience API for creating walkthroughs\n */\nexport const walkthrough = {\n /**\n * Create walkthrough from HTML attributes\n */\n fromAttributes(options?: WalkthroughOptions): Core {\n const wt = new Core(options);\n wt.scanForAttributeSteps();\n return wt;\n },\n\n /**\n * Create walkthrough from JSON configuration\n */\n fromJSON(config: WalkthroughConfig): Core {\n const wt = new Core(config.options);\n wt.configure(config);\n return wt;\n },\n\n /**\n * Quick start a walkthrough\n */\n start(steps: WalkthroughStep[], options?: WalkthroughOptions): Core {\n const wt = new Core(options);\n wt.configure({ steps });\n wt.start();\n return wt;\n },\n};\n\n// Make available globally for browser usage\nif (typeof window !== 'undefined') {\n (window as unknown as { Walkthrough: typeof Core }).Walkthrough = Core;\n (window as unknown as { walkthrough: typeof walkthrough }).walkthrough = walkthrough;\n}\n"]} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs new file mode 100644 index 0000000..6808413 --- /dev/null +++ b/dist/index.mjs @@ -0,0 +1,216 @@ +function $(s){return s<.5?2*s*s:-1+(4-2*s)*s}function m(s,t){let e;return function(...o){e||(s.apply(this,o),e=true,setTimeout(()=>e=false,t));}}function g(s,t){let e=s[0]==="#",o=e?s.slice(1):s,i=parseInt(o,16),n=(i>>16)+t,r=(i>>8&255)+t,p=(i&255)+t;return n=n>255?255:n<0?0:n,r=r>255?255:r<0?0:r,p=p>255?255:p<0?0:p,(e?"#":"")+(n<<16|r<<8|p).toString(16).padStart(6,"0")}function f(s,t,e){let o=new Date;o.setDate(o.getDate()+e),document.cookie=`${s}=${t};expires=${o.toUTCString()};path=/`;}function w(s){let t=document.cookie.split(";");for(let e of t){let[o,i]=e.trim().split("=");if(o===s)return i}return null}function b(s){document.cookie=`${s}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;}function v(s,t,e,o){let i=s.getBoundingClientRect();if(i.top>=0&&i.bottom<=window.innerHeight){o();return}let n=window.pageYOffset+i.top-t,r=window.pageYOffset,p=n-r,a,h=u=>{a||(a=u);let d=u-a,c=Math.min(d/e,1);window.scrollTo(0,r+p*$(c)),d{this.scanForAttributeSteps(),this.steps.length>0&&this.start();},this.options.startDelay);}createElements(){let t=document.createElement("div");t.className="wt-overlay";let e=document.createElement("style");e.textContent=k(this.options),t.appendChild(e);let o=document.createElement("div");o.className="wt-highlight";let i=document.createElement("div");i.className=this.options.popupClass,t.appendChild(o),t.appendChild(i),document.body.appendChild(t),this.elements={overlay:t,highlight:o,popup:i};}bindEvents(){this.options.closeOnOverlay&&this.elements.overlay.addEventListener("click",t=>{t.target===this.elements.overlay&&this.end();}),this.options.keyboard&&(this.keyHandler=t=>{this.isActive&&(this.options.escapeToExit&&t.key==="Escape"?this.end():this.options.arrowNavigation&&(t.key==="ArrowRight"||t.key==="Enter"?this.next():t.key==="ArrowLeft"&&this.prev()));},document.addEventListener("keydown",this.keyHandler)),this.positionHandler=()=>{this.isActive&&this.currentStep{let r=parseInt(n.getAttribute(e)||"0",10),p=n.getAttribute(`data-${t}-${this.options.titleAttribute}`)||void 0,a=n.getAttribute(`data-${t}-${this.options.textAttribute}`)||void 0,h=n.getAttribute(`data-${t}-${this.options.positionAttribute}`)||void 0;return {element:n,step:r,title:p,text:a,position:h}});i.sort((n,r)=>(n.step||0)-(r.step||0)),this.steps=i;}configure(t){t.steps&&(this.steps=t.steps.map(e=>{if(typeof e.element=="string"){let o=document.querySelector(e.element);if(!o)throw new Error(`Element not found: ${e.element}`);return {...e,element:o}}return e})),t.options&&(this.options={...this.options,...t.options}),t.callbacks&&(this.callbacks={...this.callbacks,...t.callbacks}),t.templates&&(this.templates={...this.templates,...t.templates});}start(t){if(this.steps.length===0){console.warn("Walkthrough: No steps configured");return}this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`,t==null&&(this.options.rememberProgress?t=this.loadProgress():t=0),this.currentStep=t,this.isActive=true,this.triggerCallback("onStart"),this.elements.overlay.classList.add("active"),setTimeout(()=>{this.showStep(this.currentStep);},50);}showStep(t){if(t<0||t>=this.steps.length)return;this.elements.popup.classList.remove("active");let e=this.steps[t];this.currentStep=t,this.options.rememberProgress&&this.saveProgress(t),this.triggerCallback("onStep",e,t);let o=typeof e.element=="string"?document.querySelector(e.element):e.element;o&&v(o,this.options.scrollOffset,this.options.scrollDuration,()=>{this.positionElements(),this.updatePopup(e,t),setTimeout(()=>{this.elements.popup.classList.add("active");},50);});}positionElements(){let t=this.steps[this.currentStep];if(!t)return;let e=typeof t.element=="string"?document.querySelector(t.element):t.element;if(!e)return;this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`;let o=e.getBoundingClientRect(),i=this.options.highlightPadding,n=window.pageYOffset||document.documentElement.scrollTop,r=window.pageXOffset||document.documentElement.scrollLeft,p=this.elements.highlight;p.style.left=`${o.left+r-i}px`,p.style.top=`${o.top+n-i}px`,p.style.width=`${o.width+i*2}px`,p.style.height=`${o.height+i*2}px`,this.positionPopup(o,t.position);}positionPopup(t,e){let o=this.elements.popup;o.style.visibility="hidden",o.style.display="block";let i=o.getBoundingClientRect();o.style.visibility="",o.style.display="";let n=this.options.popupOffset,r=this.options.highlightPadding,p={width:window.innerWidth,height:window.innerHeight},a={bottom:{left:t.left+t.width/2-i.width/2,top:t.bottom+r+n,arrow:"top",fits:t.bottom+r+n+i.height0},right:{left:t.right+r+n,top:t.top+t.height/2-i.height/2,arrow:"left",fits:t.right+r+n+i.width0}},h=e&&a[e]?.fits?e:Object.keys(a).find(P=>a[P].fits)||"bottom",u=a[h],d=window.pageYOffset||document.documentElement.scrollTop,c=window.pageXOffset||document.documentElement.scrollLeft,x=Math.max(10,Math.min(u.left,p.width-i.width-10))+c,y=Math.max(10,Math.min(u.top,p.height-i.height-10))+d;o.style.left=`${x}px`,o.style.top=`${y}px`,this.updateArrow(u.arrow);}updateArrow(t){let e=this.elements.popup;e.querySelector(".wt-popup-arrow")?.remove();let i=document.createElement("div");i.className=`wt-popup-arrow ${t}`,e.appendChild(i);}updatePopup(t,e){let o=this.elements.popup,i=e===0,n=e===this.steps.length-1,r;this.templates.popup?r=this.templates.popup(t,e,this.steps.length):r=this.getDefaultPopupContent(t,e,i,n),o.innerHTML=r,this.bindPopupButtons();}getDefaultPopupContent(t,e,o,i){return ` +
+ ${t.title||this.options.showProgress?` +
+ ${t.title?`

${t.title}

`:""} + ${this.options.showProgress?` +
+ Step ${e+1} of ${this.steps.length} +
+ `:""} +
+ `:""} + + ${t.text?` +
+ ${t.text} +
+ `:""} + + ${this.options.showProgress?` +
+
+
+ `:""} + + ${this.options.showButtons?` + + `:""} +
+ `}bindPopupButtons(){this.elements.popup.querySelectorAll("[data-wt-action]").forEach(e=>{e.addEventListener("click",o=>{switch(o.currentTarget.getAttribute("data-wt-action")){case "skip":this.end();break;case "prev":this.prev();break;case "next":this.next();break;case "finish":this.finish();break}});});}next(){this.currentStep0&&this.showStep(this.currentStep-1);}finish(){this.triggerCallback("onFinish"),this.clearProgress(),this.end();}end(){this.isActive&&(this.isActive=false,this.triggerCallback("onEnd"),this.elements.popup.classList.remove("active"),setTimeout(()=>{this.elements.overlay.classList.remove("active");},this.options.animationDuration));}saveProgress(t){f(this.options.cookieName,t.toString(),this.options.cookieExpiry);}loadProgress(){let t=w(this.options.cookieName);return t&&parseInt(t,10)||0}clearProgress(){b(this.options.cookieName);}triggerCallback(t,...e){let o=this.callbacks[t];typeof o=="function"&&o(...e);}destroy(){this.keyHandler&&document.removeEventListener("keydown",this.keyHandler),this.throttledPositionHandler&&(window.removeEventListener("resize",this.throttledPositionHandler),window.removeEventListener("scroll",this.throttledPositionHandler,true)),this.elements.overlay?.remove(),this.steps=[],this.currentStep=0,this.isActive=false;}};var C={fromAttributes(s){let t=new l(s);return t.scanForAttributeSteps(),t},fromJSON(s){let t=new l(s.options);return t.configure(s),t},start(s,t){let e=new l(t);return e.configure({steps:s}),e.start(),e}};typeof window<"u"&&(window.Walkthrough=l,window.walkthrough=C);export{l as Core,C as walkthrough};//# sourceMappingURL=index.mjs.map +//# sourceMappingURL=index.mjs.map \ No newline at end of file diff --git a/dist/index.mjs.map b/dist/index.mjs.map new file mode 100644 index 0000000..7adb3d5 --- /dev/null +++ b/dist/index.mjs.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/utils.ts","../src/styles.ts","../src/core.ts","../src/index.ts"],"names":["easeInOut","t","throttle","func","limit","inThrottle","args","adjustColor","color","amount","usePound","col","num","r","g","b","setCookie","name","value","days","expiry","getCookie","cookies","cookie","cookieName","deleteCookie","scrollToElement","element","offset","duration","callback","rect","targetY","startY","diff","start","scroll","timestamp","elapsed","progress","generateStyles","options","DEFAULT_OPTIONS","Core","overlay","style","highlight","popup","e","prefix","stepAttr","elements","steps","el","step","title","text","position","a","config","stepIndex","index","padding","scrollTop","scrollLeft","targetRect","preferredPosition","popupRect","viewport","positions","pos","chosen","finalLeft","finalTop","direction","arrow","isFirst","isLast","content","btn","walkthrough","wt"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Utility functions for Walkthrough\n */\n\n/**\n * Easing function for smooth animations\n */\nexport function easeInOut(t: number): number {\n return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n}\n\n/**\n * Throttle function to limit execution frequency\n */\nexport function throttle void>(\n func: T,\n limit: number,\n): (...args: Parameters) => void {\n let inThrottle: boolean;\n return function (this: unknown, ...args: Parameters) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\n/**\n * Adjust color brightness\n */\nexport function adjustColor(color: string, amount: number): string {\n const usePound = color[0] === '#';\n const col = usePound ? color.slice(1) : color;\n const num = parseInt(col, 16);\n let r = (num >> 16) + amount;\n let g = ((num >> 8) & 0x00ff) + amount;\n let b = (num & 0x0000ff) + amount;\n r = r > 255 ? 255 : r < 0 ? 0 : r;\n g = g > 255 ? 255 : g < 0 ? 0 : g;\n b = b > 255 ? 255 : b < 0 ? 0 : b;\n return (usePound ? '#' : '') + ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');\n}\n\n/**\n * Save data to cookie\n */\nexport function setCookie(name: string, value: string, days: number): void {\n const expiry = new Date();\n expiry.setDate(expiry.getDate() + days);\n document.cookie = `${name}=${value};expires=${expiry.toUTCString()};path=/`;\n}\n\n/**\n * Get data from cookie\n */\nexport function getCookie(name: string): string | null {\n const cookies = document.cookie.split(';');\n for (const cookie of cookies) {\n const [cookieName, value] = cookie.trim().split('=');\n if (cookieName === name) {\n return value;\n }\n }\n return null;\n}\n\n/**\n * Delete cookie\n */\nexport function deleteCookie(name: string): void {\n document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;\n}\n\n/**\n * Scroll to element smoothly\n */\nexport function scrollToElement(\n element: HTMLElement,\n offset: number,\n duration: number,\n callback: () => void,\n): void {\n const rect = element.getBoundingClientRect();\n\n if (rect.top >= 0 && rect.bottom <= window.innerHeight) {\n callback();\n return;\n }\n\n const targetY = window.pageYOffset + rect.top - offset;\n const startY = window.pageYOffset;\n const diff = targetY - startY;\n let start: number;\n\n const scroll = (timestamp: number) => {\n if (!start) start = timestamp;\n const elapsed = timestamp - start;\n const progress = Math.min(elapsed / duration, 1);\n\n window.scrollTo(0, startY + diff * easeInOut(progress));\n\n if (elapsed < duration) {\n requestAnimationFrame(scroll);\n } else {\n callback();\n }\n };\n\n requestAnimationFrame(scroll);\n}\n","import { WalkthroughOptions } from './types';\nimport { adjustColor } from './utils';\n\n/**\n * Generate CSS styles for the walkthrough\n */\nexport function generateStyles(options: Required): string {\n return `\n .wt-overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n z-index: ${options.zIndex};\n opacity: 0;\n visibility: hidden;\n transition: opacity ${options.animationDuration}ms ease;\n pointer-events: none;\n }\n .wt-overlay.active {\n opacity: 1;\n visibility: visible;\n pointer-events: none;\n }\n .wt-highlight {\n position: absolute;\n border-radius: 8px;\n transition: all ${options.animationDuration}ms ease;\n box-shadow: 0 0 0 99999px ${options.overlayColor};\n background: transparent;\n pointer-events: none;\n z-index: ${options.zIndex};\n }\n .wt-popup {\n position: absolute;\n background: white;\n border-radius: 12px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n z-index: ${options.zIndex + 1};\n max-width: ${options.popupWidth}px;\n opacity: 0;\n transform: scale(0.9);\n transition: all ${options.animationDuration}ms ease;\n pointer-events: auto;\n }\n .wt-popup.active {\n opacity: 1;\n transform: scale(1);\n }\n .wt-popup-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n border-color: transparent;\n }\n .wt-popup-arrow.top {\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-width: 0 10px 10px 10px;\n border-bottom-color: white;\n }\n .wt-popup-arrow.bottom {\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border-width: 10px 10px 0 10px;\n border-top-color: white;\n }\n .wt-popup-arrow.left {\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-width: 10px 10px 10px 0;\n border-right-color: white;\n }\n .wt-popup-arrow.right {\n left: 100%;\n top: 50%;\n transform: translateY(-50%);\n border-width: 10px 0 10px 10px;\n border-left-color: white;\n }\n .wt-popup-content {\n padding: 24px;\n }\n .wt-popup-header {\n margin-bottom: 16px;\n }\n .wt-popup-title {\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n margin: 0 0 8px 0;\n line-height: 1.3;\n }\n .wt-popup-step-count {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n .wt-popup-body {\n font-size: 15px;\n line-height: 1.6;\n color: #444;\n margin-bottom: 20px;\n }\n .wt-progress {\n height: 4px;\n background: #e0e0e0;\n border-radius: 2px;\n overflow: hidden;\n margin-bottom: 20px;\n }\n .wt-progress-bar {\n height: 100%;\n background: ${options.progressColor};\n border-radius: 2px;\n transition: width ${options.animationDuration}ms ease;\n }\n .wt-popup-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .wt-btn {\n padding: 10px 20px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n outline: none;\n }\n .wt-btn:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n }\n .wt-btn:active {\n transform: translateY(0);\n }\n .wt-btn-skip {\n background: none;\n color: #666;\n padding: 10px;\n }\n .wt-btn-skip:hover {\n color: #333;\n background: rgba(0,0,0,0.05);\n }\n .wt-btn-prev {\n background: #f5f5f5;\n color: #666;\n border: 1px solid #ddd;\n }\n .wt-btn-prev:hover {\n background: #e8e8e8;\n }\n .wt-btn-next, .wt-btn-finish {\n background: ${options.progressColor};\n color: white;\n }\n .wt-btn-next:hover, .wt-btn-finish:hover {\n background: ${adjustColor(options.progressColor, -20)};\n }\n .wt-btn-group {\n display: flex;\n gap: 12px;\n }\n `;\n}\n","import {\n WalkthroughOptions,\n WalkthroughStep,\n WalkthroughCallbacks,\n WalkthroughTemplates,\n WalkthroughConfig,\n WalkthroughElements,\n PopupPosition,\n PositionInfo,\n} from './types';\nimport { throttle, scrollToElement, setCookie, getCookie, deleteCookie } from './utils';\nimport { generateStyles } from './styles';\n\n/**\n * Default options for Walkthrough\n */\nconst DEFAULT_OPTIONS: Required = {\n overlayColor: 'rgba(0, 0, 0, 0.5)',\n highlightPadding: 10,\n animationDuration: 300,\n scrollDuration: 500,\n scrollOffset: 100,\n zIndex: 99999,\n popupWidth: 380,\n popupOffset: 15,\n popupClass: 'wt-popup',\n showProgress: true,\n progressColor: '#4CAF50',\n showButtons: true,\n showSkip: true,\n skipText: 'Skip',\n prevText: '← Previous',\n nextText: 'Next →',\n finishText: 'Finish',\n keyboard: true,\n escapeToExit: true,\n arrowNavigation: true,\n cookieName: 'walkthrough_progress',\n cookieExpiry: 30,\n rememberProgress: false,\n closeOnOverlay: true,\n autoStart: false,\n startDelay: 0,\n attributePrefix: 'wt',\n stepAttribute: 'step',\n titleAttribute: 'title',\n textAttribute: 'text',\n positionAttribute: 'position',\n};\n\n/**\n * Main Walkthrough class\n */\nexport class Core {\n private steps: WalkthroughStep[] = [];\n private currentStep = 0;\n private isActive = false;\n private callbacks: WalkthroughCallbacks = {};\n private templates: WalkthroughTemplates = {};\n private options: Required;\n private elements!: WalkthroughElements;\n private keyHandler?: (e: KeyboardEvent) => void;\n private positionHandler?: () => void;\n private throttledPositionHandler?: () => void;\n\n constructor(options: WalkthroughOptions = {}) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n this.init();\n }\n\n /**\n * Initialize the walkthrough\n */\n private init(): void {\n this.createElements();\n this.bindEvents();\n\n if (this.options.autoStart) {\n setTimeout(() => {\n this.scanForAttributeSteps();\n if (this.steps.length > 0) {\n this.start();\n }\n }, this.options.startDelay);\n }\n }\n\n /**\n * Create DOM elements\n */\n private createElements(): void {\n const overlay = document.createElement('div');\n overlay.className = 'wt-overlay';\n\n const style = document.createElement('style');\n style.textContent = generateStyles(this.options);\n overlay.appendChild(style);\n\n const highlight = document.createElement('div');\n highlight.className = 'wt-highlight';\n\n const popup = document.createElement('div');\n popup.className = this.options.popupClass;\n\n overlay.appendChild(highlight);\n overlay.appendChild(popup);\n document.body.appendChild(overlay);\n\n this.elements = { overlay, highlight, popup };\n }\n\n /**\n * Bind event listeners\n */\n private bindEvents(): void {\n if (this.options.closeOnOverlay) {\n this.elements.overlay.addEventListener('click', (e) => {\n if (e.target === this.elements.overlay) {\n this.end();\n }\n });\n }\n\n if (this.options.keyboard) {\n this.keyHandler = (e: KeyboardEvent) => {\n if (!this.isActive) return;\n\n if (this.options.escapeToExit && e.key === 'Escape') {\n this.end();\n } else if (this.options.arrowNavigation) {\n if (e.key === 'ArrowRight' || e.key === 'Enter') {\n this.next();\n } else if (e.key === 'ArrowLeft') {\n this.prev();\n }\n }\n };\n document.addEventListener('keydown', this.keyHandler);\n }\n\n this.positionHandler = () => {\n if (this.isActive && this.currentStep < this.steps.length) {\n this.positionElements();\n }\n };\n this.throttledPositionHandler = throttle(this.positionHandler, 100);\n window.addEventListener('resize', this.throttledPositionHandler);\n window.addEventListener('scroll', this.throttledPositionHandler, true);\n }\n\n /**\n * Scan DOM for attribute-based steps\n */\n public scanForAttributeSteps(): void {\n const prefix = this.options.attributePrefix;\n const stepAttr = `data-${prefix}-${this.options.stepAttribute}`;\n const elements = document.querySelectorAll(`[${stepAttr}]`);\n\n const steps = Array.from(elements).map((el) => {\n const step = parseInt(el.getAttribute(stepAttr) || '0', 10);\n const title = el.getAttribute(`data-${prefix}-${this.options.titleAttribute}`) || undefined;\n const text = el.getAttribute(`data-${prefix}-${this.options.textAttribute}`) || undefined;\n const position =\n (el.getAttribute(`data-${prefix}-${this.options.positionAttribute}`) as PopupPosition) ||\n undefined;\n\n return {\n element: el,\n step,\n title,\n text,\n position,\n };\n });\n\n steps.sort((a, b) => (a.step || 0) - (b.step || 0));\n this.steps = steps;\n }\n\n /**\n * Configure walkthrough with JSON\n */\n public configure(config: WalkthroughConfig): void {\n if (config.steps) {\n this.steps = config.steps.map((step) => {\n if (typeof step.element === 'string') {\n const el = document.querySelector(step.element);\n if (!el) {\n throw new Error(`Element not found: ${step.element}`);\n }\n return { ...step, element: el };\n }\n return step;\n });\n }\n\n if (config.options) {\n this.options = { ...this.options, ...config.options };\n }\n\n if (config.callbacks) {\n this.callbacks = { ...this.callbacks, ...config.callbacks };\n }\n\n if (config.templates) {\n this.templates = { ...this.templates, ...config.templates };\n }\n }\n\n /**\n * Start the walkthrough\n */\n public start(stepIndex?: number | null): void {\n if (this.steps.length === 0) {\n console.warn('Walkthrough: No steps configured');\n return;\n }\n\n this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`;\n\n if (stepIndex === null || stepIndex === undefined) {\n if (this.options.rememberProgress) {\n stepIndex = this.loadProgress();\n } else {\n stepIndex = 0;\n }\n }\n\n this.currentStep = stepIndex;\n this.isActive = true;\n\n this.triggerCallback('onStart');\n this.elements.overlay.classList.add('active');\n\n setTimeout(() => {\n this.showStep(this.currentStep);\n }, 50);\n }\n\n /**\n * Show a specific step\n */\n private showStep(index: number): void {\n if (index < 0 || index >= this.steps.length) return;\n\n this.elements.popup.classList.remove('active');\n\n const step = this.steps[index];\n this.currentStep = index;\n\n if (this.options.rememberProgress) {\n this.saveProgress(index);\n }\n\n this.triggerCallback('onStep', step, index);\n\n const element =\n typeof step.element === 'string'\n ? document.querySelector(step.element)\n : step.element;\n\n if (element) {\n scrollToElement(element, this.options.scrollOffset, this.options.scrollDuration, () => {\n this.positionElements();\n this.updatePopup(step, index);\n setTimeout(() => {\n this.elements.popup.classList.add('active');\n }, 50);\n });\n }\n }\n\n /**\n * Position highlight and popup elements\n */\n private positionElements(): void {\n const step = this.steps[this.currentStep];\n if (!step) return;\n\n const element =\n typeof step.element === 'string'\n ? document.querySelector(step.element)\n : step.element;\n\n if (!element) return;\n\n this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`;\n\n const rect = element.getBoundingClientRect();\n const padding = this.options.highlightPadding;\n\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const highlight = this.elements.highlight;\n highlight.style.left = `${rect.left + scrollLeft - padding}px`;\n highlight.style.top = `${rect.top + scrollTop - padding}px`;\n highlight.style.width = `${rect.width + padding * 2}px`;\n highlight.style.height = `${rect.height + padding * 2}px`;\n\n this.positionPopup(rect, step.position);\n }\n\n /**\n * Position popup relative to target element\n */\n private positionPopup(targetRect: DOMRect, preferredPosition?: PopupPosition): void {\n const popup = this.elements.popup;\n popup.style.visibility = 'hidden';\n popup.style.display = 'block';\n const popupRect = popup.getBoundingClientRect();\n popup.style.visibility = '';\n popup.style.display = '';\n\n const offset = this.options.popupOffset;\n const padding = this.options.highlightPadding;\n\n const viewport = {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n\n const positions: Record = {\n bottom: {\n left: targetRect.left + targetRect.width / 2 - popupRect.width / 2,\n top: targetRect.bottom + padding + offset,\n arrow: 'top',\n fits: targetRect.bottom + padding + offset + popupRect.height < viewport.height,\n },\n top: {\n left: targetRect.left + targetRect.width / 2 - popupRect.width / 2,\n top: targetRect.top - padding - offset - popupRect.height,\n arrow: 'bottom',\n fits: targetRect.top - padding - offset - popupRect.height > 0,\n },\n right: {\n left: targetRect.right + padding + offset,\n top: targetRect.top + targetRect.height / 2 - popupRect.height / 2,\n arrow: 'left',\n fits: targetRect.right + padding + offset + popupRect.width < viewport.width,\n },\n left: {\n left: targetRect.left - padding - offset - popupRect.width,\n top: targetRect.top + targetRect.height / 2 - popupRect.height / 2,\n arrow: 'right',\n fits: targetRect.left - padding - offset - popupRect.width > 0,\n },\n };\n\n const position: PopupPosition =\n preferredPosition && positions[preferredPosition]?.fits\n ? preferredPosition\n : (Object.keys(positions).find(\n (pos) => positions[pos as PopupPosition].fits,\n ) as PopupPosition) || 'bottom';\n\n const chosen = positions[position];\n\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const finalLeft =\n Math.max(10, Math.min(chosen.left, viewport.width - popupRect.width - 10)) + scrollLeft;\n const finalTop =\n Math.max(10, Math.min(chosen.top, viewport.height - popupRect.height - 10)) + scrollTop;\n\n popup.style.left = `${finalLeft}px`;\n popup.style.top = `${finalTop}px`;\n\n this.updateArrow(chosen.arrow);\n }\n\n /**\n * Update arrow direction\n */\n private updateArrow(direction: PopupPosition): void {\n const popup = this.elements.popup;\n const existingArrow = popup.querySelector('.wt-popup-arrow');\n existingArrow?.remove();\n\n const arrow = document.createElement('div');\n arrow.className = `wt-popup-arrow ${direction}`;\n popup.appendChild(arrow);\n }\n\n /**\n * Update popup content\n */\n private updatePopup(step: WalkthroughStep, index: number): void {\n const popup = this.elements.popup;\n const isFirst = index === 0;\n const isLast = index === this.steps.length - 1;\n\n let content: string;\n if (this.templates.popup) {\n content = this.templates.popup(step, index, this.steps.length);\n } else {\n content = this.getDefaultPopupContent(step, index, isFirst, isLast);\n }\n\n popup.innerHTML = content;\n this.bindPopupButtons();\n }\n\n /**\n * Get default popup content\n */\n private getDefaultPopupContent(\n step: WalkthroughStep,\n index: number,\n isFirst: boolean,\n isLast: boolean,\n ): string {\n return `\n
\n ${\n step.title || this.options.showProgress\n ? `\n
\n ${step.title ? `

${step.title}

` : ''}\n ${\n this.options.showProgress\n ? `\n
\n Step ${index + 1} of ${this.steps.length}\n
\n `\n : ''\n }\n
\n `\n : ''\n }\n\n ${\n step.text\n ? `\n
\n ${step.text}\n
\n `\n : ''\n }\n\n ${\n this.options.showProgress\n ? `\n
\n
\n
\n `\n : ''\n }\n\n ${\n this.options.showButtons\n ? `\n
\n ${\n this.options.showSkip\n ? `\n \n `\n : '
'\n }\n\n
\n ${\n !isFirst\n ? `\n \n `\n : ''\n }\n\n \n
\n
\n `\n : ''\n }\n
\n `;\n }\n\n /**\n * Bind popup button events\n */\n private bindPopupButtons(): void {\n const popup = this.elements.popup;\n\n popup.querySelectorAll('[data-wt-action]').forEach((btn) => {\n btn.addEventListener('click', (e) => {\n const action = (e.currentTarget as HTMLElement).getAttribute('data-wt-action');\n switch (action) {\n case 'skip':\n this.end();\n break;\n case 'prev':\n this.prev();\n break;\n case 'next':\n this.next();\n break;\n case 'finish':\n this.finish();\n break;\n }\n });\n });\n }\n\n /**\n * Navigate to next step\n */\n public next(): void {\n if (this.currentStep < this.steps.length - 1) {\n this.showStep(this.currentStep + 1);\n } else {\n this.finish();\n }\n }\n\n /**\n * Navigate to previous step\n */\n public prev(): void {\n if (this.currentStep > 0) {\n this.showStep(this.currentStep - 1);\n }\n }\n\n /**\n * Finish the walkthrough\n */\n public finish(): void {\n this.triggerCallback('onFinish');\n this.clearProgress();\n this.end();\n }\n\n /**\n * End the walkthrough\n */\n public end(): void {\n if (!this.isActive) return;\n\n this.isActive = false;\n this.triggerCallback('onEnd');\n\n this.elements.popup.classList.remove('active');\n\n setTimeout(() => {\n this.elements.overlay.classList.remove('active');\n }, this.options.animationDuration);\n }\n\n /**\n * Save progress to cookie\n */\n private saveProgress(step: number): void {\n setCookie(this.options.cookieName, step.toString(), this.options.cookieExpiry);\n }\n\n /**\n * Load progress from cookie\n */\n private loadProgress(): number {\n const value = getCookie(this.options.cookieName);\n return value ? parseInt(value, 10) || 0 : 0;\n }\n\n /**\n * Clear saved progress\n */\n private clearProgress(): void {\n deleteCookie(this.options.cookieName);\n }\n\n /**\n * Trigger callback function\n */\n private triggerCallback(name: keyof WalkthroughCallbacks, ...args: unknown[]): void {\n const callback = this.callbacks[name];\n if (typeof callback === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n (callback as (...args: unknown[]) => void)(...args);\n }\n }\n\n /**\n * Destroy the walkthrough and clean up\n */\n public destroy(): void {\n if (this.keyHandler) {\n document.removeEventListener('keydown', this.keyHandler);\n }\n if (this.throttledPositionHandler) {\n window.removeEventListener('resize', this.throttledPositionHandler);\n window.removeEventListener('scroll', this.throttledPositionHandler, true);\n }\n\n this.elements.overlay?.remove();\n\n this.steps = [];\n this.currentStep = 0;\n this.isActive = false;\n }\n}\n","/**\n * WalkthroughJS - TypeScript Edition\n * Lightweight, powerful walkthrough library with zero dependencies\n */\n\nexport { Core } from './core';\nexport type {\n WalkthroughOptions,\n WalkthroughStep,\n WalkthroughCallbacks,\n WalkthroughTemplates,\n WalkthroughConfig,\n PopupPosition,\n} from './types';\n\nimport { Core } from './core';\nimport { WalkthroughOptions, WalkthroughStep, WalkthroughConfig } from './types';\n\n/**\n * Convenience API for creating walkthroughs\n */\nexport const walkthrough = {\n /**\n * Create walkthrough from HTML attributes\n */\n fromAttributes(options?: WalkthroughOptions): Core {\n const wt = new Core(options);\n wt.scanForAttributeSteps();\n return wt;\n },\n\n /**\n * Create walkthrough from JSON configuration\n */\n fromJSON(config: WalkthroughConfig): Core {\n const wt = new Core(config.options);\n wt.configure(config);\n return wt;\n },\n\n /**\n * Quick start a walkthrough\n */\n start(steps: WalkthroughStep[], options?: WalkthroughOptions): Core {\n const wt = new Core(options);\n wt.configure({ steps });\n wt.start();\n return wt;\n },\n};\n\n// Make available globally for browser usage\nif (typeof window !== 'undefined') {\n (window as unknown as { Walkthrough: typeof Core }).Walkthrough = Core;\n (window as unknown as { walkthrough: typeof walkthrough }).walkthrough = walkthrough;\n}\n"]} \ No newline at end of file diff --git a/dist/walkthrough.min.js b/dist/walkthrough.min.js deleted file mode 100644 index 7ec507b..0000000 --- a/dist/walkthrough.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():t.Walkthrough=e()}("undefined"!=typeof self?self:this,(function(){"use strict";return class{constructor(t={}){this.steps=[],this.currentStep=0,this.isActive=!1,this.callbacks={},this.templates={},this.options={overlayColor:"rgba(0, 0, 0, 0.5)",highlightPadding:10,animationDuration:300,scrollDuration:500,scrollOffset:100,zIndex:99999,popupWidth:380,popupOffset:15,popupClass:"wt-popup",showProgress:!0,progressColor:"#4CAF50",showButtons:!0,showSkip:!0,skipText:"Skip",prevText:"← Previous",nextText:"Next →",finishText:"Finish",keyboard:!0,escapeToExit:!0,arrowNavigation:!0,cookieName:"walkthrough_progress",cookieExpiry:30,rememberProgress:!1,closeOnOverlay:!0,autoStart:!1,startDelay:0,attributePrefix:"wt",stepAttribute:"step",titleAttribute:"title",textAttribute:"text",positionAttribute:"position",...t},this.elements={},this.init()}init(){this.createElements(),this.bindEvents(),this.options.autoStart&&setTimeout((()=>{this.scanForAttributeSteps(),this.steps.length>0&&this.start()}),this.options.startDelay)}createElements(){const t=document.createElement("div");t.className="wt-overlay",t.innerHTML=`\n \n `;const e=document.createElement("div");e.className="wt-highlight";const n=document.createElement("div");n.className=this.options.popupClass,t.appendChild(e),t.appendChild(n),document.body.appendChild(t),this.elements={overlay:t,highlight:e,popup:n}}bindEvents(){this.options.closeOnOverlay&&this.elements.overlay.addEventListener("click",(t=>{t.target===this.elements.overlay&&this.end()})),this.options.keyboard&&(this.keyHandler=t=>{this.isActive&&(this.options.escapeToExit&&"Escape"===t.key?this.end():this.options.arrowNavigation&&("ArrowRight"===t.key||"Enter"===t.key?this.next():"ArrowLeft"===t.key&&this.prev()))},document.addEventListener("keydown",this.keyHandler)),this.positionHandler=()=>{this.isActive&&this.currentStep{const o=parseInt(n.getAttribute(e)),s=n.getAttribute(`data-${t}-${this.options.titleAttribute}`),i=n.getAttribute(`data-${t}-${this.options.textAttribute}`),r=n.getAttribute(`data-${t}-${this.options.positionAttribute}`);return{element:n,step:o,title:s,text:i,position:r}}));o.sort(((t,e)=>t.step-e.step)),this.steps=o}configure(t){t.steps&&(this.steps=t.steps.map((t=>("string"==typeof t.element&&(t.element=document.querySelector(t.element)),t)))),t.options&&Object.assign(this.options,t.options),t.callbacks&&(this.callbacks={...this.callbacks,...t.callbacks}),t.templates&&(this.templates={...this.templates,...t.templates})}start(t=null){0!==this.steps.length?(this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`,null===t&&this.options.rememberProgress&&(t=this.loadProgress()),this.currentStep=t||0,this.isActive=!0,this.triggerCallback("onStart"),this.elements.overlay.classList.add("active"),setTimeout((()=>{this.showStep(this.currentStep)}),50)):console.warn("Walkthrough: No steps configured")}showStep(t){if(t<0||t>=this.steps.length)return;this.elements.popup.classList.remove("active");const e=this.steps[t];this.currentStep=t,this.options.rememberProgress&&this.saveProgress(t),this.triggerCallback("onStep",e,t),e.element&&this.scrollToElement(e.element,(()=>{this.positionElements(),this.updatePopup(e,t),setTimeout((()=>{this.elements.popup.classList.add("active")}),50)}))}positionElements(){const t=this.steps[this.currentStep];if(!t||!t.element)return;this.elements.overlay.style.height=`${document.documentElement.scrollHeight}px`;const e=t.element.getBoundingClientRect(),n=this.options.highlightPadding,o=window.pageYOffset||document.documentElement.scrollTop,s=window.pageXOffset||document.documentElement.scrollLeft,i=this.elements.highlight;i.style.left=e.left+s-n+"px",i.style.top=e.top+o-n+"px",i.style.width=`${e.width+2*n}px`,i.style.height=`${e.height+2*n}px`,this.positionPopup(e,t.position)}positionPopup(t,e){const n=this.elements.popup;n.style.visibility="hidden",n.style.display="block";const o=n.getBoundingClientRect();n.style.visibility="",n.style.display="";const s=this.options.popupOffset,i=this.options.highlightPadding,r=window.innerWidth,p=window.innerHeight,a={bottom:{left:t.left+t.width/2-o.width/2,top:t.bottom+i+s,arrow:"top",fits:t.bottom+i+s+o.height0},right:{left:t.right+i+s,top:t.top+t.height/2-o.height/2,arrow:"left",fits:t.right+i+s+o.width0}};let h=e&&a[e]?.fits?e:Object.keys(a).find((t=>a[t].fits))||"bottom";const l=a[h],d=window.pageYOffset||document.documentElement.scrollTop,c=window.pageXOffset||document.documentElement.scrollLeft,u=Math.max(10,Math.min(l.left,r-o.width-10))+c,w=Math.max(10,Math.min(l.top,p-o.height-10))+d;n.style.left=`${u}px`,n.style.top=`${w}px`,this.updateArrow(l.arrow)}updateArrow(t){const e=this.elements.popup,n=e.querySelector(".wt-popup-arrow");n&&n.remove();const o=document.createElement("div");o.className=`wt-popup-arrow ${t}`,e.appendChild(o)}updatePopup(t,e){const n=this.elements.popup,o=0===e,s=e===this.steps.length-1;let i;i=this.templates.popup?this.templates.popup(t,e,this.steps.length):this.getDefaultPopupContent(t,e,o,s),n.innerHTML=i,this.bindPopupButtons()}getDefaultPopupContent(t,e,n,o){return`\n
\n ${t.title||this.options.showProgress?`\n
\n ${t.title?`

${t.title}

`:""}\n ${this.options.showProgress?`\n
\n Step ${e+1} of ${this.steps.length}\n
\n `:""}\n
\n `:""}\n\n ${t.text?`\n
\n ${t.text}\n
\n `:""}\n\n ${this.options.showProgress?`\n
\n
\n
\n `:""}\n\n ${this.options.showButtons?`\n \n `:""}\n
\n `}bindPopupButtons(){this.elements.popup.querySelectorAll("[data-wt-action]").forEach((t=>{t.addEventListener("click",(t=>{switch(t.currentTarget.getAttribute("data-wt-action")){case"skip":this.end();break;case"prev":this.prev();break;case"next":this.next();break;case"finish":this.finish()}}))}))}next(){this.currentStep0&&this.showStep(this.currentStep-1)}finish(){this.triggerCallback("onFinish"),this.clearProgress(),this.end()}end(){this.isActive&&(this.isActive=!1,this.triggerCallback("onEnd"),this.elements.popup.classList.remove("active"),setTimeout((()=>{this.elements.overlay.classList.remove("active")}),this.options.animationDuration))}scrollToElement(t,e){const n=t.getBoundingClientRect();if(n.top>=0&&n.bottom<=window.innerHeight)return void e();const o=this.options.scrollOffset,s=window.pageYOffset+n.top-o,i=window.pageYOffset,r=s-i,p=this.options.scrollDuration;let a;const h=t=>{a||(a=t);const n=t-a,o=Math.min(n/p,1);window.scrollTo(0,i+r*this.easeInOut(o)),nn=!1),e))}}adjustColor(t,e){const n="#"===t[0],o=n?t.slice(1):t,s=parseInt(o,16);let i=(s>>16)+e,r=(s>>8&255)+e,p=(255&s)+e;return i=i>255?255:i<0?0:i,r=r>255?255:r<0?0:r,p=p>255?255:p<0?0:p,(n?"#":"")+(i<<16|r<<8|p).toString(16).padStart(6,"0")}destroy(){this.keyHandler&&document.removeEventListener("keydown",this.keyHandler),this.throttledPositionHandler&&(window.removeEventListener("resize",this.throttledPositionHandler),window.removeEventListener("scroll",this.throttledPositionHandler,!0)),this.elements.overlay&&this.elements.overlay.remove(),this.steps=[],this.currentStep=0,this.isActive=!1}}})),window.walkthrough={fromAttributes:function(t={}){const e=new Walkthrough(t);return e.scanForAttributeSteps(),e},fromJSON:function(t){const e=new Walkthrough(t.options||{});return e.configure(t),e},start:function(t,e={}){const n=new Walkthrough(e);return n.configure({steps:t}),n.start(),n}}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..dbfe648 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3697 @@ +{ + "name": "@walkthroughjs/core", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@walkthroughjs/core", + "version": "2.0.0", + "license": "LGPL-3.0-or-later", + "devDependencies": { + "@types/node": "^20.10.0", + "@typescript-eslint/eslint-plugin": "^6.13.0", + "@typescript-eslint/parser": "^6.13.0", + "eslint": "^8.54.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.1", + "prettier": "^3.1.0", + "tsup": "^8.0.1", + "typescript": "^5.9.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.21.tgz", + "integrity": "sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "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.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsup": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.0.tgz", + "integrity": "sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.25.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 4e5da04..d182924 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,63 @@ { - "name": "@ronanarm/walkthroughjs", - "version": "1.0.0", - "description": "Lightweight, dependency-free library for interactive walkthroughs, tutorials, and onboarding.", - "main": "dist/walkthrough.min.js", + "name": "@walkthroughjs/core", + "version": "2.0.0", + "description": "Lightweight, dependency-free TypeScript library for interactive walkthroughs, tutorials, and onboarding", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./styles": "./dist/walkthrough.css" + }, "files": [ - "dist/walkthrough.min.js" + "dist", + "README.md", + "LICENSE.md" ], "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "https://github.com/ronanarm/walkthroughjs.git" + "dev": "tsup --watch", + "build": "tsup", + "lint": "eslint src --ext .ts", + "lint:fix": "eslint src --ext .ts --fix", + "format": "prettier --write \"src/**/*.ts\"", + "format:check": "prettier --check \"src/**/*.ts\"", + "type-check": "tsc --noEmit", + "prepublishOnly": "npm run lint && npm run type-check && npm run build", + "test": "echo \"Tests will be added\" && exit 0" }, "keywords": [ - "javascript", - "onboarding", - "tutorial", + "typescript", "walkthrough", + "tutorial", + "onboarding", "product-tour", - "interactive-guide" + "interactive-guide", + "user-guide", + "step-by-step" ], "author": "Ronan Armstrong", "license": "LGPL-3.0-or-later", + "repository": { + "type": "git", + "url": "https://github.com/benjaminrast/WalkthroughJS.git" + }, "bugs": { - "url": "https://github.com/ronanarm/walkthroughjs/issues" + "url": "https://github.com/benjaminrast/WalkthroughJS/issues" }, - "homepage": "https://github.com/ronanarm/walkthroughjs#readme" + "homepage": "https://github.com/benjaminrast/WalkthroughJS#readme", + "devDependencies": { + "@types/node": "^20.10.0", + "@typescript-eslint/eslint-plugin": "^6.13.0", + "@typescript-eslint/parser": "^6.13.0", + "eslint": "^8.54.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.1", + "prettier": "^3.1.0", + "tsup": "^8.0.1", + "typescript": "^5.9.3" + } } diff --git a/src/core.ts b/src/core.ts new file mode 100644 index 0000000..0453fa1 --- /dev/null +++ b/src/core.ts @@ -0,0 +1,616 @@ +import { + WalkthroughOptions, + WalkthroughStep, + WalkthroughCallbacks, + WalkthroughTemplates, + WalkthroughConfig, + WalkthroughElements, + PopupPosition, + PositionInfo, +} from './types'; +import { throttle, scrollToElement, setCookie, getCookie, deleteCookie } from './utils'; +import { generateStyles } from './styles'; + +/** + * Default options for Walkthrough + */ +const DEFAULT_OPTIONS: Required = { + overlayColor: 'rgba(0, 0, 0, 0.5)', + highlightPadding: 10, + animationDuration: 300, + scrollDuration: 500, + scrollOffset: 100, + zIndex: 99999, + popupWidth: 380, + popupOffset: 15, + popupClass: 'wt-popup', + showProgress: true, + progressColor: '#4CAF50', + showButtons: true, + showSkip: true, + skipText: 'Skip', + prevText: '← Previous', + nextText: 'Next →', + finishText: 'Finish', + keyboard: true, + escapeToExit: true, + arrowNavigation: true, + cookieName: 'walkthrough_progress', + cookieExpiry: 30, + rememberProgress: false, + closeOnOverlay: true, + autoStart: false, + startDelay: 0, + attributePrefix: 'wt', + stepAttribute: 'step', + titleAttribute: 'title', + textAttribute: 'text', + positionAttribute: 'position', +}; + +/** + * Main Walkthrough class + */ +export class Core { + private steps: WalkthroughStep[] = []; + private currentStep = 0; + private isActive = false; + private callbacks: WalkthroughCallbacks = {}; + private templates: WalkthroughTemplates = {}; + private options: Required; + private elements!: WalkthroughElements; + private keyHandler?: (e: KeyboardEvent) => void; + private positionHandler?: () => void; + private throttledPositionHandler?: () => void; + + constructor(options: WalkthroughOptions = {}) { + this.options = { ...DEFAULT_OPTIONS, ...options }; + this.init(); + } + + /** + * Initialize the walkthrough + */ + private init(): void { + this.createElements(); + this.bindEvents(); + + if (this.options.autoStart) { + setTimeout(() => { + this.scanForAttributeSteps(); + if (this.steps.length > 0) { + this.start(); + } + }, this.options.startDelay); + } + } + + /** + * Create DOM elements + */ + private createElements(): void { + const overlay = document.createElement('div'); + overlay.className = 'wt-overlay'; + + const style = document.createElement('style'); + style.textContent = generateStyles(this.options); + overlay.appendChild(style); + + const highlight = document.createElement('div'); + highlight.className = 'wt-highlight'; + + const popup = document.createElement('div'); + popup.className = this.options.popupClass; + + overlay.appendChild(highlight); + overlay.appendChild(popup); + document.body.appendChild(overlay); + + this.elements = { overlay, highlight, popup }; + } + + /** + * Bind event listeners + */ + private bindEvents(): void { + if (this.options.closeOnOverlay) { + this.elements.overlay.addEventListener('click', (e) => { + if (e.target === this.elements.overlay) { + this.end(); + } + }); + } + + if (this.options.keyboard) { + this.keyHandler = (e: KeyboardEvent) => { + if (!this.isActive) return; + + if (this.options.escapeToExit && e.key === 'Escape') { + this.end(); + } else if (this.options.arrowNavigation) { + if (e.key === 'ArrowRight' || e.key === 'Enter') { + this.next(); + } else if (e.key === 'ArrowLeft') { + this.prev(); + } + } + }; + document.addEventListener('keydown', this.keyHandler); + } + + this.positionHandler = () => { + if (this.isActive && this.currentStep < this.steps.length) { + this.positionElements(); + } + }; + this.throttledPositionHandler = throttle(this.positionHandler, 100); + window.addEventListener('resize', this.throttledPositionHandler); + window.addEventListener('scroll', this.throttledPositionHandler, true); + } + + /** + * Scan DOM for attribute-based steps + */ + public scanForAttributeSteps(): void { + const prefix = this.options.attributePrefix; + const stepAttr = `data-${prefix}-${this.options.stepAttribute}`; + const elements = document.querySelectorAll(`[${stepAttr}]`); + + const steps = Array.from(elements).map((el) => { + const step = parseInt(el.getAttribute(stepAttr) || '0', 10); + const title = el.getAttribute(`data-${prefix}-${this.options.titleAttribute}`) || undefined; + const text = el.getAttribute(`data-${prefix}-${this.options.textAttribute}`) || undefined; + const position = + (el.getAttribute(`data-${prefix}-${this.options.positionAttribute}`) as PopupPosition) || + undefined; + + return { + element: el, + step, + title, + text, + position, + }; + }); + + steps.sort((a, b) => (a.step || 0) - (b.step || 0)); + this.steps = steps; + } + + /** + * Configure walkthrough with JSON + */ + public configure(config: WalkthroughConfig): void { + if (config.steps) { + this.steps = config.steps.map((step) => { + if (typeof step.element === 'string') { + const el = document.querySelector(step.element); + if (!el) { + throw new Error(`Element not found: ${step.element}`); + } + return { ...step, element: el }; + } + return step; + }); + } + + if (config.options) { + this.options = { ...this.options, ...config.options }; + } + + if (config.callbacks) { + this.callbacks = { ...this.callbacks, ...config.callbacks }; + } + + if (config.templates) { + this.templates = { ...this.templates, ...config.templates }; + } + } + + /** + * Start the walkthrough + */ + public start(stepIndex?: number | null): void { + if (this.steps.length === 0) { + console.warn('Walkthrough: No steps configured'); + return; + } + + this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`; + + if (stepIndex === null || stepIndex === undefined) { + if (this.options.rememberProgress) { + stepIndex = this.loadProgress(); + } else { + stepIndex = 0; + } + } + + this.currentStep = stepIndex; + this.isActive = true; + + this.triggerCallback('onStart'); + this.elements.overlay.classList.add('active'); + + setTimeout(() => { + this.showStep(this.currentStep); + }, 50); + } + + /** + * Show a specific step + */ + private showStep(index: number): void { + if (index < 0 || index >= this.steps.length) return; + + this.elements.popup.classList.remove('active'); + + const step = this.steps[index]; + this.currentStep = index; + + if (this.options.rememberProgress) { + this.saveProgress(index); + } + + this.triggerCallback('onStep', step, index); + + const element = + typeof step.element === 'string' + ? document.querySelector(step.element) + : step.element; + + if (element) { + scrollToElement(element, this.options.scrollOffset, this.options.scrollDuration, () => { + this.positionElements(); + this.updatePopup(step, index); + setTimeout(() => { + this.elements.popup.classList.add('active'); + }, 50); + }); + } + } + + /** + * Position highlight and popup elements + */ + private positionElements(): void { + const step = this.steps[this.currentStep]; + if (!step) return; + + const element = + typeof step.element === 'string' + ? document.querySelector(step.element) + : step.element; + + if (!element) return; + + this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`; + + const rect = element.getBoundingClientRect(); + const padding = this.options.highlightPadding; + + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; + + const highlight = this.elements.highlight; + highlight.style.left = `${rect.left + scrollLeft - padding}px`; + highlight.style.top = `${rect.top + scrollTop - padding}px`; + highlight.style.width = `${rect.width + padding * 2}px`; + highlight.style.height = `${rect.height + padding * 2}px`; + + this.positionPopup(rect, step.position); + } + + /** + * Position popup relative to target element + */ + private positionPopup(targetRect: DOMRect, preferredPosition?: PopupPosition): void { + const popup = this.elements.popup; + popup.style.visibility = 'hidden'; + popup.style.display = 'block'; + const popupRect = popup.getBoundingClientRect(); + popup.style.visibility = ''; + popup.style.display = ''; + + const offset = this.options.popupOffset; + const padding = this.options.highlightPadding; + + const viewport = { + width: window.innerWidth, + height: window.innerHeight, + }; + + const positions: Record = { + bottom: { + left: targetRect.left + targetRect.width / 2 - popupRect.width / 2, + top: targetRect.bottom + padding + offset, + arrow: 'top', + fits: targetRect.bottom + padding + offset + popupRect.height < viewport.height, + }, + top: { + left: targetRect.left + targetRect.width / 2 - popupRect.width / 2, + top: targetRect.top - padding - offset - popupRect.height, + arrow: 'bottom', + fits: targetRect.top - padding - offset - popupRect.height > 0, + }, + right: { + left: targetRect.right + padding + offset, + top: targetRect.top + targetRect.height / 2 - popupRect.height / 2, + arrow: 'left', + fits: targetRect.right + padding + offset + popupRect.width < viewport.width, + }, + left: { + left: targetRect.left - padding - offset - popupRect.width, + top: targetRect.top + targetRect.height / 2 - popupRect.height / 2, + arrow: 'right', + fits: targetRect.left - padding - offset - popupRect.width > 0, + }, + }; + + const position: PopupPosition = + preferredPosition && positions[preferredPosition]?.fits + ? preferredPosition + : (Object.keys(positions).find( + (pos) => positions[pos as PopupPosition].fits, + ) as PopupPosition) || 'bottom'; + + const chosen = positions[position]; + + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; + + const finalLeft = + Math.max(10, Math.min(chosen.left, viewport.width - popupRect.width - 10)) + scrollLeft; + const finalTop = + Math.max(10, Math.min(chosen.top, viewport.height - popupRect.height - 10)) + scrollTop; + + popup.style.left = `${finalLeft}px`; + popup.style.top = `${finalTop}px`; + + this.updateArrow(chosen.arrow); + } + + /** + * Update arrow direction + */ + private updateArrow(direction: PopupPosition): void { + const popup = this.elements.popup; + const existingArrow = popup.querySelector('.wt-popup-arrow'); + existingArrow?.remove(); + + const arrow = document.createElement('div'); + arrow.className = `wt-popup-arrow ${direction}`; + popup.appendChild(arrow); + } + + /** + * Update popup content + */ + private updatePopup(step: WalkthroughStep, index: number): void { + const popup = this.elements.popup; + const isFirst = index === 0; + const isLast = index === this.steps.length - 1; + + let content: string; + if (this.templates.popup) { + content = this.templates.popup(step, index, this.steps.length); + } else { + content = this.getDefaultPopupContent(step, index, isFirst, isLast); + } + + popup.innerHTML = content; + this.bindPopupButtons(); + } + + /** + * Get default popup content + */ + private getDefaultPopupContent( + step: WalkthroughStep, + index: number, + isFirst: boolean, + isLast: boolean, + ): string { + return ` +
+ ${ + step.title || this.options.showProgress + ? ` +
+ ${step.title ? `

${step.title}

` : ''} + ${ + this.options.showProgress + ? ` +
+ Step ${index + 1} of ${this.steps.length} +
+ ` + : '' + } +
+ ` + : '' + } + + ${ + step.text + ? ` +
+ ${step.text} +
+ ` + : '' + } + + ${ + this.options.showProgress + ? ` +
+
+
+ ` + : '' + } + + ${ + this.options.showButtons + ? ` + + ` + : '' + } +
+ `; + } + + /** + * Bind popup button events + */ + private bindPopupButtons(): void { + const popup = this.elements.popup; + + popup.querySelectorAll('[data-wt-action]').forEach((btn) => { + btn.addEventListener('click', (e) => { + const action = (e.currentTarget as HTMLElement).getAttribute('data-wt-action'); + switch (action) { + case 'skip': + this.end(); + break; + case 'prev': + this.prev(); + break; + case 'next': + this.next(); + break; + case 'finish': + this.finish(); + break; + } + }); + }); + } + + /** + * Navigate to next step + */ + public next(): void { + if (this.currentStep < this.steps.length - 1) { + this.showStep(this.currentStep + 1); + } else { + this.finish(); + } + } + + /** + * Navigate to previous step + */ + public prev(): void { + if (this.currentStep > 0) { + this.showStep(this.currentStep - 1); + } + } + + /** + * Finish the walkthrough + */ + public finish(): void { + this.triggerCallback('onFinish'); + this.clearProgress(); + this.end(); + } + + /** + * End the walkthrough + */ + public end(): void { + if (!this.isActive) return; + + this.isActive = false; + this.triggerCallback('onEnd'); + + this.elements.popup.classList.remove('active'); + + setTimeout(() => { + this.elements.overlay.classList.remove('active'); + }, this.options.animationDuration); + } + + /** + * Save progress to cookie + */ + private saveProgress(step: number): void { + setCookie(this.options.cookieName, step.toString(), this.options.cookieExpiry); + } + + /** + * Load progress from cookie + */ + private loadProgress(): number { + const value = getCookie(this.options.cookieName); + return value ? parseInt(value, 10) || 0 : 0; + } + + /** + * Clear saved progress + */ + private clearProgress(): void { + deleteCookie(this.options.cookieName); + } + + /** + * Trigger callback function + */ + private triggerCallback(name: keyof WalkthroughCallbacks, ...args: unknown[]): void { + const callback = this.callbacks[name]; + if (typeof callback === 'function') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + (callback as (...args: unknown[]) => void)(...args); + } + } + + /** + * Destroy the walkthrough and clean up + */ + public destroy(): void { + if (this.keyHandler) { + document.removeEventListener('keydown', this.keyHandler); + } + if (this.throttledPositionHandler) { + window.removeEventListener('resize', this.throttledPositionHandler); + window.removeEventListener('scroll', this.throttledPositionHandler, true); + } + + this.elements.overlay?.remove(); + + this.steps = []; + this.currentStep = 0; + this.isActive = false; + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..08697df --- /dev/null +++ b/src/index.ts @@ -0,0 +1,56 @@ +/** + * WalkthroughJS - TypeScript Edition + * Lightweight, powerful walkthrough library with zero dependencies + */ + +export { Core } from './core'; +export type { + WalkthroughOptions, + WalkthroughStep, + WalkthroughCallbacks, + WalkthroughTemplates, + WalkthroughConfig, + PopupPosition, +} from './types'; + +import { Core } from './core'; +import { WalkthroughOptions, WalkthroughStep, WalkthroughConfig } from './types'; + +/** + * Convenience API for creating walkthroughs + */ +export const walkthrough = { + /** + * Create walkthrough from HTML attributes + */ + fromAttributes(options?: WalkthroughOptions): Core { + const wt = new Core(options); + wt.scanForAttributeSteps(); + return wt; + }, + + /** + * Create walkthrough from JSON configuration + */ + fromJSON(config: WalkthroughConfig): Core { + const wt = new Core(config.options); + wt.configure(config); + return wt; + }, + + /** + * Quick start a walkthrough + */ + start(steps: WalkthroughStep[], options?: WalkthroughOptions): Core { + const wt = new Core(options); + wt.configure({ steps }); + wt.start(); + return wt; + }, +}; + +// Make available globally for browser usage +if (typeof window !== 'undefined') { + (window as unknown as { Walkthrough: typeof Core }).Walkthrough = Core; + (window as unknown as { walkthrough: typeof walkthrough }).walkthrough = walkthrough; +} diff --git a/src/styles.ts b/src/styles.ts new file mode 100644 index 0000000..6c3861c --- /dev/null +++ b/src/styles.ts @@ -0,0 +1,175 @@ +import { WalkthroughOptions } from './types'; +import { adjustColor } from './utils'; + +/** + * Generate CSS styles for the walkthrough + */ +export function generateStyles(options: Required): string { + return ` + .wt-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: ${options.zIndex}; + opacity: 0; + visibility: hidden; + transition: opacity ${options.animationDuration}ms ease; + pointer-events: none; + } + .wt-overlay.active { + opacity: 1; + visibility: visible; + pointer-events: none; + } + .wt-highlight { + position: absolute; + border-radius: 8px; + transition: all ${options.animationDuration}ms ease; + box-shadow: 0 0 0 99999px ${options.overlayColor}; + background: transparent; + pointer-events: none; + z-index: ${options.zIndex}; + } + .wt-popup { + position: absolute; + background: white; + border-radius: 12px; + box-shadow: 0 10px 40px rgba(0,0,0,0.2); + z-index: ${options.zIndex + 1}; + max-width: ${options.popupWidth}px; + opacity: 0; + transform: scale(0.9); + transition: all ${options.animationDuration}ms ease; + pointer-events: auto; + } + .wt-popup.active { + opacity: 1; + transform: scale(1); + } + .wt-popup-arrow { + position: absolute; + width: 0; + height: 0; + border-style: solid; + border-color: transparent; + } + .wt-popup-arrow.top { + bottom: 100%; + left: 50%; + transform: translateX(-50%); + border-width: 0 10px 10px 10px; + border-bottom-color: white; + } + .wt-popup-arrow.bottom { + top: 100%; + left: 50%; + transform: translateX(-50%); + border-width: 10px 10px 0 10px; + border-top-color: white; + } + .wt-popup-arrow.left { + right: 100%; + top: 50%; + transform: translateY(-50%); + border-width: 10px 10px 10px 0; + border-right-color: white; + } + .wt-popup-arrow.right { + left: 100%; + top: 50%; + transform: translateY(-50%); + border-width: 10px 0 10px 10px; + border-left-color: white; + } + .wt-popup-content { + padding: 24px; + } + .wt-popup-header { + margin-bottom: 16px; + } + .wt-popup-title { + font-size: 20px; + font-weight: 600; + color: #1a1a1a; + margin: 0 0 8px 0; + line-height: 1.3; + } + .wt-popup-step-count { + font-size: 12px; + color: #666; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + } + .wt-popup-body { + font-size: 15px; + line-height: 1.6; + color: #444; + margin-bottom: 20px; + } + .wt-progress { + height: 4px; + background: #e0e0e0; + border-radius: 2px; + overflow: hidden; + margin-bottom: 20px; + } + .wt-progress-bar { + height: 100%; + background: ${options.progressColor}; + border-radius: 2px; + transition: width ${options.animationDuration}ms ease; + } + .wt-popup-footer { + display: flex; + justify-content: space-between; + align-items: center; + } + .wt-btn { + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + border: none; + outline: none; + } + .wt-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); + } + .wt-btn:active { + transform: translateY(0); + } + .wt-btn-skip { + background: none; + color: #666; + padding: 10px; + } + .wt-btn-skip:hover { + color: #333; + background: rgba(0,0,0,0.05); + } + .wt-btn-prev { + background: #f5f5f5; + color: #666; + border: 1px solid #ddd; + } + .wt-btn-prev:hover { + background: #e8e8e8; + } + .wt-btn-next, .wt-btn-finish { + background: ${options.progressColor}; + color: white; + } + .wt-btn-next:hover, .wt-btn-finish:hover { + background: ${adjustColor(options.progressColor, -20)}; + } + .wt-btn-group { + display: flex; + gap: 12px; + } + `; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..720dea2 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,136 @@ +/** + * Position options for popup placement + */ +export type PopupPosition = 'top' | 'bottom' | 'left' | 'right'; + +/** + * Keyboard action types + */ +export type KeyboardAction = 'next' | 'prev' | 'exit'; + +/** + * Step configuration + */ +export interface WalkthroughStep { + /** Target element selector or HTMLElement */ + element: string | HTMLElement; + /** Step title */ + title?: string; + /** Step description text */ + text?: string; + /** Preferred popup position */ + position?: PopupPosition; + /** Step number (used for attribute-based configuration) */ + step?: number; + /** Custom skip button text */ + skipText?: string; + /** Custom previous button text */ + prevText?: string; + /** Custom next button text */ + nextText?: string; + /** Custom finish button text */ + finishText?: string; +} + +/** + * Walkthrough configuration options + */ +export interface WalkthroughOptions { + // Visual + overlayColor?: string; + highlightPadding?: number; + animationDuration?: number; + scrollDuration?: number; + scrollOffset?: number; + zIndex?: number; + + // Popup configuration + popupWidth?: number; + popupOffset?: number; + popupClass?: string; + + // Progress + showProgress?: boolean; + progressColor?: string; + + // Buttons + showButtons?: boolean; + showSkip?: boolean; + skipText?: string; + prevText?: string; + nextText?: string; + finishText?: string; + + // Keyboard navigation + keyboard?: boolean; + escapeToExit?: boolean; + arrowNavigation?: boolean; + + // Storage + cookieName?: string; + cookieExpiry?: number; + rememberProgress?: boolean; + + // Behavior + closeOnOverlay?: boolean; + autoStart?: boolean; + startDelay?: number; + + // Attribute names for HTML config + attributePrefix?: string; + stepAttribute?: string; + titleAttribute?: string; + textAttribute?: string; + positionAttribute?: string; +} + +/** + * Callback functions + */ +export interface WalkthroughCallbacks { + /** Called when walkthrough starts */ + onStart?: () => void; + /** Called on each step */ + onStep?: (step: WalkthroughStep, index: number) => void; + /** Called when walkthrough finishes normally */ + onFinish?: () => void; + /** Called when walkthrough ends (finish or skip) */ + onEnd?: () => void; +} + +/** + * Template functions + */ +export interface WalkthroughTemplates { + /** Custom popup template */ + popup?: (step: WalkthroughStep, index: number, totalSteps: number) => string; +} + +/** + * Complete configuration object for JSON-based setup + */ +export interface WalkthroughConfig { + steps?: WalkthroughStep[]; + options?: WalkthroughOptions; + callbacks?: WalkthroughCallbacks; + templates?: WalkthroughTemplates; +} + +/** + * Internal DOM elements + */ +export interface WalkthroughElements { + overlay: HTMLDivElement; + highlight: HTMLDivElement; + popup: HTMLDivElement; +} + +/** + * Position calculation result + */ +export interface PositionInfo { + left: number; + top: number; + arrow: PopupPosition; + fits: boolean; +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..94dd51b --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,111 @@ +/** + * Utility functions for Walkthrough + */ + +/** + * Easing function for smooth animations + */ +export function easeInOut(t: number): number { + return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; +} + +/** + * Throttle function to limit execution frequency + */ +export function throttle void>( + func: T, + limit: number, +): (...args: Parameters) => void { + let inThrottle: boolean; + return function (this: unknown, ...args: Parameters) { + if (!inThrottle) { + func.apply(this, args); + inThrottle = true; + setTimeout(() => (inThrottle = false), limit); + } + }; +} + +/** + * Adjust color brightness + */ +export function adjustColor(color: string, amount: number): string { + const usePound = color[0] === '#'; + const col = usePound ? color.slice(1) : color; + const num = parseInt(col, 16); + let r = (num >> 16) + amount; + let g = ((num >> 8) & 0x00ff) + amount; + let b = (num & 0x0000ff) + amount; + r = r > 255 ? 255 : r < 0 ? 0 : r; + g = g > 255 ? 255 : g < 0 ? 0 : g; + b = b > 255 ? 255 : b < 0 ? 0 : b; + return (usePound ? '#' : '') + ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0'); +} + +/** + * Save data to cookie + */ +export function setCookie(name: string, value: string, days: number): void { + const expiry = new Date(); + expiry.setDate(expiry.getDate() + days); + document.cookie = `${name}=${value};expires=${expiry.toUTCString()};path=/`; +} + +/** + * Get data from cookie + */ +export function getCookie(name: string): string | null { + const cookies = document.cookie.split(';'); + for (const cookie of cookies) { + const [cookieName, value] = cookie.trim().split('='); + if (cookieName === name) { + return value; + } + } + return null; +} + +/** + * Delete cookie + */ +export function deleteCookie(name: string): void { + document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`; +} + +/** + * Scroll to element smoothly + */ +export function scrollToElement( + element: HTMLElement, + offset: number, + duration: number, + callback: () => void, +): void { + const rect = element.getBoundingClientRect(); + + if (rect.top >= 0 && rect.bottom <= window.innerHeight) { + callback(); + return; + } + + const targetY = window.pageYOffset + rect.top - offset; + const startY = window.pageYOffset; + const diff = targetY - startY; + let start: number; + + const scroll = (timestamp: number) => { + if (!start) start = timestamp; + const elapsed = timestamp - start; + const progress = Math.min(elapsed / duration, 1); + + window.scrollTo(0, startY + diff * easeInOut(progress)); + + if (elapsed < duration) { + requestAnimationFrame(scroll); + } else { + callback(); + } + }; + + requestAnimationFrame(scroll); +} diff --git a/src/walkthrough.js b/src/walkthrough.js deleted file mode 100644 index 77b1ca2..0000000 --- a/src/walkthrough.js +++ /dev/null @@ -1,825 +0,0 @@ -/** - * Walkthrough.js - Advanced Tutorial/Walkthrough Library - * Lightweight, powerful, and flexible with multiple configuration methods - */ -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define([], factory); - } else if (typeof module === 'object' && module.exports) { - module.exports = factory(); - } else { - root.Walkthrough = factory(); - } -}(typeof self !== 'undefined' ? self : this, function() { - 'use strict'; - - class Walkthrough { - constructor(options = {}) { - this.steps = []; - this.currentStep = 0; - this.isActive = false; - this.callbacks = {}; - this.templates = {}; - - // Default options - this.options = { - // Visual - overlayColor: 'rgba(0, 0, 0, 0.5)', - highlightPadding: 10, - animationDuration: 300, - scrollDuration: 500, - scrollOffset: 100, - zIndex: 99999, - - // Popup configuration - popupWidth: 380, - popupOffset: 15, - popupClass: 'wt-popup', - - // Progress - showProgress: true, - progressColor: '#4CAF50', - - // Buttons - showButtons: true, - showSkip: true, - skipText: 'Skip', - prevText: '← Previous', - nextText: 'Next →', - finishText: 'Finish', - - // Keyboard navigation - keyboard: true, - escapeToExit: true, - arrowNavigation: true, - - // Storage - cookieName: 'walkthrough_progress', - cookieExpiry: 30, // days - rememberProgress: false, - - // Behavior - closeOnOverlay: true, - autoStart: false, - startDelay: 0, - - // Attribute names for HTML config - attributePrefix: 'wt', - stepAttribute: 'step', - titleAttribute: 'title', - textAttribute: 'text', - positionAttribute: 'position', - - ...options - }; - - this.elements = {}; - this.init(); - } - - init() { - this.createElements(); - this.bindEvents(); - - // Auto-start if configured - if (this.options.autoStart) { - setTimeout(() => { - this.scanForAttributeSteps(); - if (this.steps.length > 0) { - this.start(); - } - }, this.options.startDelay); - } - } - - createElements() { - // Main overlay - const overlay = document.createElement('div'); - overlay.className = 'wt-overlay'; - overlay.innerHTML = ` - - `; - - // Highlight element - const highlight = document.createElement('div'); - highlight.className = 'wt-highlight'; - - // Popup element - const popup = document.createElement('div'); - popup.className = this.options.popupClass; - - // Append elements - overlay.appendChild(highlight); - overlay.appendChild(popup); - document.body.appendChild(overlay); - - // Store references - this.elements = { - overlay, - highlight, - popup - }; - } - - bindEvents() { - // Overlay click - if (this.options.closeOnOverlay) { - this.elements.overlay.addEventListener('click', (e) => { - if (e.target === this.elements.overlay) { - this.end(); - } - }); - } - - // Keyboard navigation - if (this.options.keyboard) { - this.keyHandler = (e) => { - if (!this.isActive) return; - - if (this.options.escapeToExit && e.key === 'Escape') { - this.end(); - } else if (this.options.arrowNavigation) { - if (e.key === 'ArrowRight' || e.key === 'Enter') { - this.next(); - } else if (e.key === 'ArrowLeft') { - this.prev(); - } - } - }; - document.addEventListener('keydown', this.keyHandler); - } - - // Add scroll and resize handler for layout changes - this.positionHandler = () => { - if (this.isActive && this.currentStep < this.steps.length) { - this.positionElements(); - } - }; - this.throttledPositionHandler = this.throttle(this.positionHandler, 100); - window.addEventListener('resize', this.throttledPositionHandler); - // The scroll handler is now mainly for edge cases like lazy-loaded content changing page height - window.addEventListener('scroll', this.throttledPositionHandler, true); - } - - // Scan DOM for attribute-based configuration - scanForAttributeSteps() { - const prefix = this.options.attributePrefix; - const stepAttr = `data-${prefix}-${this.options.stepAttribute}`; - const elements = document.querySelectorAll(`[${stepAttr}]`); - - const steps = Array.from(elements).map(el => { - const step = parseInt(el.getAttribute(stepAttr)); - const title = el.getAttribute(`data-${prefix}-${this.options.titleAttribute}`); - const text = el.getAttribute(`data-${prefix}-${this.options.textAttribute}`); - const position = el.getAttribute(`data-${prefix}-${this.options.positionAttribute}`); - - return { - element: el, - step: step, - title: title, - text: text, - position: position - }; - }); - - // Sort by step number - steps.sort((a, b) => a.step - b.step); - - this.steps = steps; - } - - // Configure with JSON - configure(config) { - if (config.steps) { - this.steps = config.steps.map(step => { - if (typeof step.element === 'string') { - step.element = document.querySelector(step.element); - } - return step; - }); - } - - if (config.options) { - Object.assign(this.options, config.options); - } - - if (config.callbacks) { - this.callbacks = { ...this.callbacks, ...config.callbacks }; - } - - if (config.templates) { - this.templates = { ...this.templates, ...config.templates }; - } - } - - // Start walkthrough - start(stepIndex = null) { - if (this.steps.length === 0) { - console.warn('Walkthrough: No steps configured'); - return; - } - - // MODIFICATION: Set the overlay height to match the document - this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`; - - // Check for saved progress - if (stepIndex === null && this.options.rememberProgress) { - stepIndex = this.loadProgress(); - } - - this.currentStep = stepIndex || 0; - this.isActive = true; - - // Trigger callback - this.triggerCallback('onStart'); - - // Show overlay - this.elements.overlay.classList.add('active'); - - // Show current step - setTimeout(() => { - this.showStep(this.currentStep); - }, 50); - } - - // Show specific step - showStep(index) { - if (index < 0 || index >= this.steps.length) return; - - this.elements.popup.classList.remove('active'); - - const step = this.steps[index]; - this.currentStep = index; - - // Save progress - if (this.options.rememberProgress) { - this.saveProgress(index); - } - - // Trigger callback - this.triggerCallback('onStep', step, index); - - // Scroll to element - if (step.element) { - this.scrollToElement(step.element, () => { - // Position elements - this.positionElements(); - - // Update popup content - this.updatePopup(step, index); - - // Show popup - setTimeout(() => { - this.elements.popup.classList.add('active'); - }, 50); - }); - } - } - - // Position highlight and popup - positionElements() { - const step = this.steps[this.currentStep]; - if (!step || !step.element) return; - - // MODIFICATION: Update overlay height on reposition in case document size changed - this.elements.overlay.style.height = `${document.documentElement.scrollHeight}px`; - - const element = step.element; - const rect = element.getBoundingClientRect(); - const padding = this.options.highlightPadding; - - // MODIFICATION: Calculate position relative to the document, not viewport - const scrollTop = window.pageYOffset || document.documentElement.scrollTop; - const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; - - // Position highlight - const highlight = this.elements.highlight; - highlight.style.left = `${rect.left + scrollLeft - padding}px`; - highlight.style.top = `${rect.top + scrollTop - padding}px`; - highlight.style.width = `${rect.width + padding * 2}px`; - highlight.style.height = `${rect.height + padding * 2}px`; - - // Position popup - this.positionPopup(rect, step.position); - } - - // Position popup relative to target - positionPopup(targetRect, preferredPosition) { - const popup = this.elements.popup; - popup.style.visibility = 'hidden'; - popup.style.display = 'block'; - const popupRect = popup.getBoundingClientRect(); - popup.style.visibility = ''; - popup.style.display = ''; - - const offset = this.options.popupOffset; - const padding = this.options.highlightPadding; - - const viewport = { - width: window.innerWidth, - height: window.innerHeight - }; - - // Determine best position (relative to viewport for fitting logic) - const positions = { - bottom: { - left: targetRect.left + targetRect.width / 2 - popupRect.width / 2, - top: targetRect.bottom + padding + offset, - arrow: 'top', - fits: targetRect.bottom + padding + offset + popupRect.height < viewport.height - }, - top: { - left: targetRect.left + targetRect.width / 2 - popupRect.width / 2, - top: targetRect.top - padding - offset - popupRect.height, - arrow: 'bottom', - fits: targetRect.top - padding - offset - popupRect.height > 0 - }, - right: { - left: targetRect.right + padding + offset, - top: targetRect.top + targetRect.height / 2 - popupRect.height / 2, - arrow: 'left', - fits: targetRect.right + padding + offset + popupRect.width < viewport.width - }, - left: { - left: targetRect.left - padding - offset - popupRect.width, - top: targetRect.top + targetRect.height / 2 - popupRect.height / 2, - arrow: 'right', - fits: targetRect.left - padding - offset - popupRect.width > 0 - } - }; - - let position = preferredPosition && positions[preferredPosition] ?.fits ? - preferredPosition : - Object.keys(positions).find(pos => positions[pos].fits) || 'bottom'; - - const chosen = positions[position]; - - // MODIFICATION: Adjust final position with scroll offset to be page-relative - const scrollTop = window.pageYOffset || document.documentElement.scrollTop; - const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; - - const finalLeft = Math.max(10, Math.min(chosen.left, viewport.width - popupRect.width - 10)) + scrollLeft; - const finalTop = Math.max(10, Math.min(chosen.top, viewport.height - popupRect.height - 10)) + scrollTop; - - popup.style.left = `${finalLeft}px`; - popup.style.top = `${finalTop}px`; - - this.updateArrow(chosen.arrow); - } - - // Update arrow direction - updateArrow(direction) { - const popup = this.elements.popup; - const existingArrow = popup.querySelector('.wt-popup-arrow'); - if (existingArrow) { - existingArrow.remove(); - } - - const arrow = document.createElement('div'); - arrow.className = `wt-popup-arrow ${direction}`; - popup.appendChild(arrow); - } - - // Update popup content - updatePopup(step, index) { - const popup = this.elements.popup; - const isFirst = index === 0; - const isLast = index === this.steps.length - 1; - - let content; - if (this.templates.popup) { - content = this.templates.popup(step, index, this.steps.length); - } else { - content = this.getDefaultPopupContent(step, index, isFirst, isLast); - } - - popup.innerHTML = content; - - this.bindPopupButtons(); - } - - // Default popup content - getDefaultPopupContent(step, index, isFirst, isLast) { - return ` -
- ${step.title || this.options.showProgress ? ` -
- ${step.title ? `

${step.title}

` : ''} - ${this.options.showProgress ? ` -
- Step ${index + 1} of ${this.steps.length} -
- ` : ''} -
- ` : ''} - - ${step.text ? ` -
- ${step.text} -
- ` : ''} - - ${this.options.showProgress ? ` -
-
-
- ` : ''} - - ${this.options.showButtons ? ` - - ` : ''} -
- `; - } - - // Bind popup button events - bindPopupButtons() { - const popup = this.elements.popup; - - popup.querySelectorAll('[data-wt-action]').forEach(btn => { - btn.addEventListener('click', (e) => { - const action = e.currentTarget.getAttribute('data-wt-action'); - switch (action) { - case 'skip': - this.end(); - break; - case 'prev': - this.prev(); - break; - case 'next': - this.next(); - break; - case 'finish': - this.finish(); - break; - } - }); - }); - } - - // Navigate to next step - next() { - if (this.currentStep < this.steps.length - 1) { - this.showStep(this.currentStep + 1); - } else { - this.finish(); - } - } - - // Navigate to previous step - prev() { - if (this.currentStep > 0) { - this.showStep(this.currentStep - 1); - } - } - - // Finish walkthrough - finish() { - this.triggerCallback('onFinish'); - this.clearProgress(); - this.end(); - } - - // End walkthrough - end() { - if (!this.isActive) return; - - this.isActive = false; - this.triggerCallback('onEnd'); - - this.elements.popup.classList.remove('active'); - - setTimeout(() => { - this.elements.overlay.classList.remove('active'); - }, this.options.animationDuration); - } - - // Scroll to element - scrollToElement(element, callback) { - const rect = element.getBoundingClientRect(); - - if (rect.top >= 0 && rect.bottom <= window.innerHeight) { - callback(); - return; - } - - const offset = this.options.scrollOffset; - const targetY = window.pageYOffset + rect.top - offset; - - const startY = window.pageYOffset; - const diff = targetY - startY; - const duration = this.options.scrollDuration; - let start; - - const scroll = (timestamp) => { - if (!start) start = timestamp; - const elapsed = timestamp - start; - const progress = Math.min(elapsed / duration, 1); - - window.scrollTo(0, startY + diff * this.easeInOut(progress)); - - if (elapsed < duration) { - requestAnimationFrame(scroll); - } else { - callback(); - } - }; - - requestAnimationFrame(scroll); - } - - // Easing function - easeInOut(t) { - return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; - } - - // Cookie management - saveProgress(step) { - const expiry = new Date(); - expiry.setDate(expiry.getDate() + this.options.cookieExpiry); - document.cookie = `${this.options.cookieName}=${step};expires=${expiry.toUTCString()};path=/`; - } - - loadProgress() { - const cookies = document.cookie.split(';'); - for (let cookie of cookies) { - const [name, value] = cookie.trim().split('='); - if (name === this.options.cookieName) { - return parseInt(value) || 0; - } - } - return 0; - } - - clearProgress() { - document.cookie = `${this.options.cookieName}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`; - } - - // Trigger callback - triggerCallback(name, ...args) { - if (typeof this.callbacks[name] === 'function') { - this.callbacks[name](...args); - } - } - - // Throttle utility - throttle(func, limit) { - let inThrottle; - return function() { - const args = arguments; - const context = this; - if (!inThrottle) { - func.apply(context, args); - inThrottle = true; - setTimeout(() => inThrottle = false, limit); - } - }; - } - - // Utility: Adjust color brightness - adjustColor(color, amount) { - const usePound = color[0] === '#'; - const col = usePound ? color.slice(1) : color; - const num = parseInt(col, 16); - let r = (num >> 16) + amount; - let g = ((num >> 8) & 0x00FF) + amount; - let b = (num & 0x0000FF) + amount; - r = r > 255 ? 255 : r < 0 ? 0 : r; - g = g > 255 ? 255 : g < 0 ? 0 : g; - b = b > 255 ? 255 : b < 0 ? 0 : b; - return (usePound ? '#' : '') + (r << 16 | g << 8 | b).toString(16).padStart(6, '0'); - } - - // Public API - destroy() { - // Remove event listeners - if (this.keyHandler) { - document.removeEventListener('keydown', this.keyHandler); - } - if (this.throttledPositionHandler) { - window.removeEventListener('resize', this.throttledPositionHandler); - window.removeEventListener('scroll', this.throttledPositionHandler, true); - } - - // Remove elements - if (this.elements.overlay) { - this.elements.overlay.remove(); - } - - // Clear data - this.steps = []; - this.currentStep = 0; - this.isActive = false; - } - } - - return Walkthrough; -})); - -// Convenience functions (unchanged) -window.walkthrough = { - fromAttributes: function(options = {}) { - const wt = new Walkthrough(options); - wt.scanForAttributeSteps(); - return wt; - }, - fromJSON: function(config) { - const wt = new Walkthrough(config.options || {}); - wt.configure(config); - return wt; - }, - start: function(steps, options = {}) { - const wt = new Walkthrough(options); - wt.configure({ - steps - }); - wt.start(); - return wt; - } -}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c6c8616 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "moduleResolution": "node", + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "demo"] +} diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..eaeffdc --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/index.ts'], + format: ['cjs', 'esm'], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + minify: true, + treeshake: true, + outExtension({ format }) { + return { + js: format === 'cjs' ? '.js' : '.mjs', + }; + }, +}); +