diff --git a/website/.gitignore b/website/.gitignore
new file mode 100644
index 00000000..ddfcee14
--- /dev/null
+++ b/website/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+docs/.vitepress/dist/
+docs/.vitepress/cache/
+.DS_Store
diff --git a/website/docs/.vitepress/config.ts b/website/docs/.vitepress/config.ts
new file mode 100644
index 00000000..1811bf88
--- /dev/null
+++ b/website/docs/.vitepress/config.ts
@@ -0,0 +1,177 @@
+import { defineConfig } from 'vitepress'
+
+export default defineConfig({
+ title: 'Talker',
+ description: 'Advanced error handler and logger for Dart and Flutter apps',
+
+ head: [
+ ['link', { rel: 'icon', href: '/logo.png' }],
+ ],
+
+ locales: {
+ root: {
+ label: 'English',
+ lang: 'en',
+ themeConfig: {
+ nav: [
+ { text: 'Guide', link: '/getting-started/installation' },
+ { text: 'Packages', link: '/packages/talker' },
+ { text: 'Integrations', link: '/integrations/dio' },
+ {
+ text: 'Links',
+ items: [
+ { text: 'pub.dev', link: 'https://pub.dev/packages/talker' },
+ { text: 'GitHub', link: 'https://github.com/Frezyx/talker' },
+ { text: 'Web Demo', link: 'https://frezyx.github.io/talker' },
+ ],
+ },
+ ],
+ sidebar: {
+ '/': [
+ {
+ text: 'Getting Started',
+ collapsed: false,
+ items: [
+ { text: 'Installation', link: '/getting-started/installation' },
+ { text: 'Quick Start', link: '/getting-started/quick-start' },
+ { text: 'Why Talker?', link: '/getting-started/why-talker' },
+ ],
+ },
+ {
+ text: 'Core Packages',
+ collapsed: false,
+ items: [
+ { text: 'talker', link: '/packages/talker' },
+ { text: 'talker_logger', link: '/packages/talker-logger' },
+ { text: 'talker_flutter', link: '/packages/talker-flutter' },
+ ],
+ },
+ {
+ text: 'Integrations',
+ collapsed: false,
+ items: [
+ { text: 'Dio Logger', link: '/integrations/dio' },
+ { text: 'HTTP Logger', link: '/integrations/http' },
+ { text: 'BLoC Logger', link: '/integrations/bloc' },
+ { text: 'Riverpod Logger', link: '/integrations/riverpod' },
+ { text: 'Chopper Logger', link: '/integrations/chopper' },
+ { text: 'gRPC Logger', link: '/integrations/grpc' },
+ ],
+ },
+ {
+ text: 'Guides',
+ collapsed: false,
+ items: [
+ { text: 'Custom Log Types', link: '/guides/custom-logs' },
+ { text: 'Crashlytics Integration', link: '/guides/crashlytics' },
+ { text: 'Route Logging', link: '/guides/routing' },
+ { text: 'Custom Error Messages', link: '/guides/custom-error-messages' },
+ ],
+ },
+ {
+ text: 'Examples',
+ link: '/examples',
+ },
+ ],
+ },
+ },
+ },
+ ru: {
+ label: 'Русский',
+ lang: 'ru',
+ link: '/ru/',
+ themeConfig: {
+ nav: [
+ { text: 'Руководство', link: '/ru/getting-started/installation' },
+ { text: 'Пакеты', link: '/ru/packages/talker' },
+ { text: 'Интеграции', link: '/ru/integrations/dio' },
+ {
+ text: 'Ссылки',
+ items: [
+ { text: 'pub.dev', link: 'https://pub.dev/packages/talker' },
+ { text: 'GitHub', link: 'https://github.com/Frezyx/talker' },
+ { text: 'Web Demo', link: 'https://frezyx.github.io/talker' },
+ ],
+ },
+ ],
+ sidebar: {
+ '/ru/': [
+ {
+ text: 'Начало работы',
+ collapsed: false,
+ items: [
+ { text: 'Установка', link: '/ru/getting-started/installation' },
+ { text: 'Быстрый старт', link: '/ru/getting-started/quick-start' },
+ { text: 'Почему Talker?', link: '/ru/getting-started/why-talker' },
+ ],
+ },
+ {
+ text: 'Основные пакеты',
+ collapsed: false,
+ items: [
+ { text: 'talker', link: '/ru/packages/talker' },
+ { text: 'talker_logger', link: '/ru/packages/talker-logger' },
+ { text: 'talker_flutter', link: '/ru/packages/talker-flutter' },
+ ],
+ },
+ {
+ text: 'Интеграции',
+ collapsed: false,
+ items: [
+ { text: 'Dio Logger', link: '/ru/integrations/dio' },
+ { text: 'HTTP Logger', link: '/ru/integrations/http' },
+ { text: 'BLoC Logger', link: '/ru/integrations/bloc' },
+ { text: 'Riverpod Logger', link: '/ru/integrations/riverpod' },
+ { text: 'Chopper Logger', link: '/ru/integrations/chopper' },
+ { text: 'gRPC Logger', link: '/ru/integrations/grpc' },
+ ],
+ },
+ {
+ text: 'Руководства',
+ collapsed: false,
+ items: [
+ { text: 'Пользовательские логи', link: '/ru/guides/custom-logs' },
+ { text: 'Интеграция с Crashlytics', link: '/ru/guides/crashlytics' },
+ { text: 'Логирование маршрутов', link: '/ru/guides/routing' },
+ { text: 'Кастомные сообщения об ошибках', link: '/ru/guides/custom-error-messages' },
+ ],
+ },
+ {
+ text: 'Примеры',
+ link: '/ru/examples',
+ },
+ ],
+ },
+ outline: { label: 'Содержание' },
+ docFooter: { prev: 'Предыдущая', next: 'Следующая' },
+ darkModeSwitchLabel: 'Тема',
+ sidebarMenuLabel: 'Меню',
+ returnToTopLabel: 'Наверх',
+ langMenuLabel: 'Язык',
+ },
+ },
+ },
+
+ themeConfig: {
+ logo: '/logo.png',
+ siteTitle: 'Talker',
+
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/Frezyx/talker' },
+ ],
+
+ search: {
+ provider: 'local',
+ },
+
+ editLink: {
+ pattern: 'https://github.com/Frezyx/talker/edit/master/website/docs/:path',
+ text: 'Edit this page on GitHub',
+ },
+
+ footer: {
+ message: 'Released under the MIT License.',
+ copyright: 'Copyright © 2022-present Stanislav Ilin',
+ },
+ },
+})
diff --git a/website/docs/.vitepress/theme/custom.css b/website/docs/.vitepress/theme/custom.css
new file mode 100644
index 00000000..e8262c58
--- /dev/null
+++ b/website/docs/.vitepress/theme/custom.css
@@ -0,0 +1,100 @@
+/**
+ * Talker Documentation - Purple Theme
+ *
+ * Colors based on Material Purple (#7C4DFF)
+ * @see https://vitepress.dev/reference/default-theme-config#custom-css
+ */
+
+:root {
+ /* Brand / Primary Purple */
+ --vp-c-brand-1: #7C4DFF;
+ --vp-c-brand-2: #9C6FFF;
+ --vp-c-brand-3: #651FFF;
+ --vp-c-brand-soft: rgba(124, 77, 255, 0.14);
+
+ /* Tip color - same as brand */
+ --vp-c-tip-1: var(--vp-c-brand-1);
+ --vp-c-tip-2: var(--vp-c-brand-2);
+ --vp-c-tip-3: var(--vp-c-brand-3);
+ --vp-c-tip-soft: var(--vp-c-brand-soft);
+
+ /* Button colors */
+ --vp-button-brand-border: transparent;
+ --vp-button-brand-text: #fff;
+ --vp-button-brand-bg: var(--vp-c-brand-1);
+ --vp-button-brand-hover-border: transparent;
+ --vp-button-brand-hover-text: #fff;
+ --vp-button-brand-hover-bg: var(--vp-c-brand-2);
+ --vp-button-brand-active-border: transparent;
+ --vp-button-brand-active-text: #fff;
+ --vp-button-brand-active-bg: var(--vp-c-brand-3);
+
+ /* Home hero name gradient */
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: -webkit-linear-gradient(
+ 120deg,
+ #7C4DFF 30%,
+ #B388FF
+ );
+
+ /* Home hero image glow */
+ --vp-home-hero-image-background-image: linear-gradient(
+ -45deg,
+ #7C4DFF 50%,
+ #B388FF 50%
+ );
+ --vp-home-hero-image-filter: blur(44px);
+}
+
+.dark {
+ --vp-c-brand-1: #9C6FFF;
+ --vp-c-brand-2: #B388FF;
+ --vp-c-brand-3: #7C4DFF;
+ --vp-c-brand-soft: rgba(156, 111, 255, 0.16);
+
+ --vp-home-hero-name-background: -webkit-linear-gradient(
+ 120deg,
+ #B388FF 30%,
+ #7C4DFF
+ );
+}
+
+/* Sidebar active link */
+.VPSidebar .is-active > .link > .text {
+ color: var(--vp-c-brand-1) !important;
+}
+
+/* Custom badge for package versions */
+.package-badge {
+ display: inline-block;
+ padding: 2px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 600;
+ background-color: var(--vp-c-brand-soft);
+ color: var(--vp-c-brand-1);
+}
+
+/* DartPad embed styling */
+.dartpad-embed {
+ width: 100%;
+ border: 1px solid var(--vp-c-divider);
+ border-radius: 8px;
+ overflow: hidden;
+ margin: 16px 0;
+}
+
+.dartpad-embed iframe {
+ width: 100%;
+ height: 400px;
+ border: none;
+}
+
+/* Feature cards on home page */
+.VPFeatures .VPFeature {
+ border-color: var(--vp-c-brand-soft) !important;
+}
+
+.VPFeatures .VPFeature:hover {
+ border-color: var(--vp-c-brand-1) !important;
+}
diff --git a/website/docs/.vitepress/theme/index.ts b/website/docs/.vitepress/theme/index.ts
new file mode 100644
index 00000000..42fe9a93
--- /dev/null
+++ b/website/docs/.vitepress/theme/index.ts
@@ -0,0 +1,4 @@
+import DefaultTheme from 'vitepress/theme'
+import './custom.css'
+
+export default DefaultTheme
diff --git a/website/docs/examples.md b/website/docs/examples.md
new file mode 100644
index 00000000..0922753d
--- /dev/null
+++ b/website/docs/examples.md
@@ -0,0 +1,67 @@
+# Examples
+
+## Interactive DartPad Examples
+
+### Basic Logging
+
+Try Talker's logging levels in your browser:
+
+
+
+
+
+### Error Handling
+
+See how Talker handles exceptions with stack traces:
+
+
+
+
+
+### Custom Log Types
+
+Create your own log types:
+
+
+
+
+
+## Shop App Example
+
+A full production-like Flutter application demonstrating Talker integration:
+
+- Talker setup with DI
+- HTTP logging with Dio
+- BLoC state management logging
+- TalkerScreen and TalkerMonitor
+- Error handling with TalkerWrapper
+- Route logging
+
+📂 [View Shop App on GitHub](https://github.com/Frezyx/talker/tree/master/examples/shop_app_example)
+
+## Web Demo
+
+Try the fully interactive Flutter web demo with `TalkerScreen` and `TalkerMonitor`:
+
+🌐 [Open Web Demo](https://frezyx.github.io/talker)
+
+
diff --git a/website/docs/getting-started/installation.md b/website/docs/getting-started/installation.md
new file mode 100644
index 00000000..95b9006c
--- /dev/null
+++ b/website/docs/getting-started/installation.md
@@ -0,0 +1,62 @@
+# Installation
+
+## Choose Your Package
+
+Talker is a modular ecosystem. Install only what you need:
+
+### For Dart-only projects
+
+```yaml
+dependencies:
+ talker: ^5.1.13
+```
+
+### For Flutter projects
+
+```yaml
+dependencies:
+ talker_flutter: ^5.1.13
+```
+
+::: tip
+`talker_flutter` already includes `talker` as a dependency — you don't need to add both.
+:::
+
+### Integration packages
+
+Add any of these alongside your main package:
+
+```yaml
+dependencies:
+ # HTTP logging for Dio
+ talker_dio_logger: ^5.1.13
+
+ # HTTP logging for http package
+ talker_http_logger: ^5.1.13
+
+ # BLoC state management logging
+ talker_bloc_logger: ^5.1.13
+
+ # Riverpod state management logging
+ talker_riverpod_logger: ^5.1.13
+
+ # HTTP logging for Chopper
+ talker_chopper_logger: ^5.1.13
+
+ # gRPC logging
+ talker_grpc_logger: ^5.1.13
+```
+
+## Run pub get
+
+After adding the dependencies, run:
+
+```bash
+flutter pub get
+# or for Dart-only projects
+dart pub get
+```
+
+## Next Steps
+
+Now that you have Talker installed, head over to the [Quick Start](/getting-started/quick-start) guide to start logging!
diff --git a/website/docs/getting-started/quick-start.md b/website/docs/getting-started/quick-start.md
new file mode 100644
index 00000000..9e2e69b3
--- /dev/null
+++ b/website/docs/getting-started/quick-start.md
@@ -0,0 +1,87 @@
+# Quick Start
+
+## Basic Usage (Dart)
+
+Create a Talker instance and start logging:
+
+```dart
+import 'package:talker/talker.dart';
+
+final talker = Talker();
+
+void main() {
+ // Log messages with different levels
+ talker.info('App started');
+ talker.debug('Loading configuration...');
+ talker.warning('Cache is almost full');
+ talker.good('User profile loaded!');
+ talker.verbose('Detailed trace info');
+ talker.critical('Database connection lost!');
+
+ // Handle exceptions
+ try {
+ throw Exception('Something went wrong');
+ } catch (e, st) {
+ talker.handle(e, st, 'Failed to process data');
+ }
+}
+```
+
+## Flutter Usage
+
+For Flutter apps, use `TalkerFlutter.init()` for optimal platform-specific logging:
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+void main() {
+ // Handle exceptions and errors
+ try {
+ // your code...
+ } catch (e, st) {
+ talker.handle(e, st, 'Exception in ...');
+ }
+
+ // Log your app info
+ talker.info('App is started');
+ talker.critical('Houston, we have a problem!');
+ talker.error('The service is not available');
+}
+```
+
+::: tip Why TalkerFlutter.init()?
+Most Flutter logging packages either cut messages in the console or can't display colored messages on iOS. `TalkerFlutter.init()` uses the optimal logging method for each platform:
+- **Web** — uses `print()`
+- **iOS / macOS** — uses `dart:developer.log`
+- **Android / Windows / Linux** — uses `debugPrint`
+:::
+
+## View Logs In-App
+
+Use `TalkerScreen` to browse logs directly in your app:
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+## Add HTTP Logging
+
+If you use Dio, add logging with one line:
+
+```dart
+final dio = Dio();
+dio.interceptors.add(TalkerDioLogger(talker: talker));
+```
+
+## What's Next?
+
+- Learn about [Talker core features](/packages/talker) — custom logs, colors, titles, observer
+- Explore [Flutter widgets](/packages/talker-flutter) — TalkerScreen, TalkerMonitor, TalkerWrapper
+- Set up [integrations](/integrations/dio) — Dio, BLoC, Riverpod, and more
+- Read [guides](/guides/custom-logs) — custom log types, Crashlytics integration
diff --git a/website/docs/getting-started/why-talker.md b/website/docs/getting-started/why-talker.md
new file mode 100644
index 00000000..a691b9dc
--- /dev/null
+++ b/website/docs/getting-started/why-talker.md
@@ -0,0 +1,69 @@
+# Why Talker?
+
+## The Problem
+
+When developing Dart and Flutter applications, you need to:
+
+- **Understand where errors occur** — as quickly as possible
+- **Log application actions** — HTTP requests, state changes, navigation
+- **Handle exceptions gracefully** — without crashing the app
+- **Share error reports** — with your team or crash reporting services
+- **Debug on real devices** — when there's no console available
+
+Most existing logging solutions only cover part of this. You end up with scattered tools, inconsistent formats, and no unified view.
+
+## The Solution
+
+Talker provides a **single, unified system** for all logging and error handling in your application:
+
+### Unified Logging
+
+One API for everything — from simple debug messages to HTTP requests and state management events. All logs share the same format, history, and output.
+
+### Rich Error Handling
+
+Automatically distinguish between `Exception` and `Error` types, capture `StackTrace`, and route everything through a unified handler with `TalkerObserver`.
+
+### Flutter-First UI
+
+Built-in `TalkerScreen` lets you view, filter, search, and share all logs directly in your app — no console needed. `TalkerMonitor` gives you a quick status overview.
+
+### Modular Integrations
+
+Pick only what you need. Each integration (Dio, BLoC, Riverpod, etc.) is a separate lightweight package that plugs into the same Talker instance.
+
+### Full Customization
+
+Every aspect is customizable — colors, titles, log formats, filters. Create your own log types with full control over appearance and behavior.
+
+## Key Features
+
+| Feature | Talker |
+|---------|--------|
+| Log levels (info, debug, warning, error, critical, verbose, good) | ✅ |
+| Colored console output | ✅ |
+| Custom log types | ✅ |
+| Exception/Error handling with StackTrace | ✅ |
+| Log history | ✅ |
+| In-app log viewer (TalkerScreen) | ✅ |
+| In-app status monitor (TalkerMonitor) | ✅ |
+| Error alerts UI (TalkerWrapper) | ✅ |
+| Route/Navigation logging | ✅ |
+| Dio HTTP logging | ✅ |
+| http package logging | ✅ |
+| BLoC state management logging | ✅ |
+| Riverpod state management logging | ✅ |
+| Chopper HTTP logging | ✅ |
+| gRPC logging | ✅ |
+| Observer for external services (Crashlytics, Sentry) | ✅ |
+| Platform-optimized output (iOS, Android, Web) | ✅ |
+| 100% test coverage | ✅ |
+| Works with any state management | ✅ |
+
+## Compatibility
+
+- **Dart** >= 2.15
+- **Flutter** >= 3.0
+- **Platforms**: Android, iOS, Web, macOS, Windows, Linux
+- **State management**: Works with any — BLoC, Riverpod, Provider, GetX, MobX, etc.
+- **Crash reporting**: Firebase Crashlytics, Sentry, or any custom solution
diff --git a/website/docs/guides/crashlytics.md b/website/docs/guides/crashlytics.md
new file mode 100644
index 00000000..957e6d4f
--- /dev/null
+++ b/website/docs/guides/crashlytics.md
@@ -0,0 +1,197 @@
+# Crashlytics & Sentry Integration
+
+Use `TalkerObserver` to send errors, exceptions, and logs from Talker to external crash reporting and analytics services.
+
+## How TalkerObserver Works
+
+`TalkerObserver` listens to all Talker events and provides callbacks for each type:
+
+```dart
+abstract class TalkerObserver {
+ void onError(TalkerError err) {}
+ void onException(TalkerException exception) {}
+ void onLog(TalkerDataInterface log) {}
+}
+```
+
+- **onError** — called when `talker.handle()` catches an `Error`
+- **onException** — called when `talker.handle()` catches an `Exception`
+- **onLog** — called for every log event (info, debug, HTTP, custom, etc.)
+
+## Firebase Crashlytics
+
+```dart
+import 'package:firebase_crashlytics/firebase_crashlytics.dart';
+import 'package:talker/talker.dart';
+
+class CrashlyticsTalkerObserver extends TalkerObserver {
+ CrashlyticsTalkerObserver(this.crashlytics);
+
+ final FirebaseCrashlytics crashlytics;
+
+ @override
+ void onError(TalkerError err) {
+ crashlytics.recordError(
+ err.error,
+ err.stackTrace,
+ reason: err.message,
+ fatal: err.logLevel == LogLevel.critical,
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ crashlytics.recordError(
+ exception.exception,
+ exception.stackTrace,
+ reason: exception.message,
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ // Optionally log breadcrumbs for non-error events
+ crashlytics.log(log.generateTextMessage());
+ }
+}
+```
+
+### Setup
+
+```dart
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await Firebase.initializeApp();
+
+ final crashlytics = FirebaseCrashlytics.instance;
+
+ final talker = TalkerFlutter.init(
+ observer: CrashlyticsTalkerObserver(crashlytics),
+ );
+
+ // Now all talker.handle() calls will automatically report to Crashlytics
+ try {
+ throw Exception('Payment failed');
+ } catch (e, st) {
+ talker.handle(e, st, 'Payment processing error');
+ // ^ This will log to console, save to history, AND send to Crashlytics
+ }
+}
+```
+
+## Sentry
+
+```dart
+import 'package:sentry_flutter/sentry_flutter.dart';
+import 'package:talker/talker.dart';
+
+class SentryTalkerObserver extends TalkerObserver {
+ @override
+ void onError(TalkerError err) {
+ Sentry.captureException(
+ err.error,
+ stackTrace: err.stackTrace,
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ Sentry.captureException(
+ exception.exception,
+ stackTrace: exception.stackTrace,
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ Sentry.addBreadcrumb(
+ Breadcrumb(
+ message: log.generateTextMessage(),
+ level: _mapLevel(log),
+ timestamp: DateTime.now(),
+ ),
+ );
+ }
+
+ SentryLevel _mapLevel(TalkerDataInterface log) {
+ if (log is TalkerError || log is TalkerException) {
+ return SentryLevel.error;
+ }
+ return SentryLevel.info;
+ }
+}
+```
+
+### Setup
+
+```dart
+void main() async {
+ await SentryFlutter.init(
+ (options) {
+ options.dsn = 'YOUR_SENTRY_DSN';
+ },
+ appRunner: () {
+ final talker = TalkerFlutter.init(
+ observer: SentryTalkerObserver(),
+ );
+ runApp(MyApp(talker: talker));
+ },
+ );
+}
+```
+
+## Custom Analytics Service
+
+The same pattern works for any analytics or monitoring service:
+
+```dart
+class AnalyticsTalkerObserver extends TalkerObserver {
+ AnalyticsTalkerObserver(this.analytics);
+
+ final MyAnalyticsService analytics;
+
+ @override
+ void onError(TalkerError err) {
+ analytics.trackError(
+ name: 'app_error',
+ error: err.error.toString(),
+ stackTrace: err.stackTrace?.toString(),
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ analytics.trackError(
+ name: 'app_exception',
+ error: exception.exception.toString(),
+ stackTrace: exception.stackTrace?.toString(),
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ analytics.trackEvent(
+ name: 'app_log',
+ params: {'message': log.message, 'title': log.title},
+ );
+ }
+}
+```
+
+## Best Practices
+
+1. **Don't block the main thread** — crash reporting SDKs handle this internally, but be mindful with `onLog` callbacks if you add heavy processing.
+
+2. **Use log levels wisely** — send only `error` and `critical` logs to Crashlytics, use `onLog` for breadcrumbs.
+
+3. **Combine with TalkerWrapper** — show errors to users via SnackBars while simultaneously reporting to your crash service:
+
+```dart
+TalkerWrapper(
+ talker: talker, // Same instance with CrashlyticsTalkerObserver
+ options: TalkerWrapperOptions(enableErrorAlerts: true),
+ child: MyApp(),
+)
+```
+
+4. **Test your observer** — write unit tests to verify that the observer is called correctly for each event type.
diff --git a/website/docs/guides/custom-error-messages.md b/website/docs/guides/custom-error-messages.md
new file mode 100644
index 00000000..f684a477
--- /dev/null
+++ b/website/docs/guides/custom-error-messages.md
@@ -0,0 +1,161 @@
+# Custom Error Messages
+
+Show user-friendly error alerts and custom messages in your Flutter app using Talker's Flutter widgets.
+
+## TalkerWrapper
+
+The simplest way to show error alerts. Wrap your app (or a subtree) with `TalkerWrapper`:
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ enableExceptionAlerts: true,
+ ),
+ child: MaterialApp(
+ home: HomeScreen(),
+ ),
+)
+```
+
+Now whenever `talker.handle()` catches an exception or error, a SnackBar will automatically appear at the bottom of the screen.
+
+## TalkerListener
+
+For more control over what happens on each event, use `TalkerListener`:
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ if (data is TalkerException) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Error: ${data.displayMessage}'),
+ backgroundColor: Colors.red,
+ action: SnackBarAction(
+ label: 'Details',
+ textColor: Colors.white,
+ onPressed: () {
+ Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (_) => TalkerScreen(talker: talker),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## TalkerBuilder
+
+Build UI reactively based on log events:
+
+```dart
+TalkerBuilder(
+ talker: talker,
+ builder: (context, data) {
+ final errors = data.whereType().toList();
+ final exceptions = data.whereType().toList();
+
+ if (errors.isEmpty && exceptions.isEmpty) {
+ return const SizedBox.shrink();
+ }
+
+ return Container(
+ padding: const EdgeInsets.all(8),
+ color: Colors.red.shade100,
+ child: Text(
+ '${errors.length + exceptions.length} errors occurred',
+ style: const TextStyle(color: Colors.red),
+ ),
+ );
+ },
+)
+```
+
+## Custom Dialog on Error
+
+Combine `TalkerListener` with a dialog for critical errors:
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ // Show dialog only for critical errors
+ if (data is TalkerError && data.logLevel == LogLevel.critical) {
+ showDialog(
+ context: context,
+ builder: (_) => AlertDialog(
+ title: const Text('Critical Error'),
+ content: Text(data.displayMessage),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(context),
+ child: const Text('OK'),
+ ),
+ TextButton(
+ onPressed: () {
+ Navigator.pop(context);
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => TalkerScreen(talker: talker),
+ ),
+ );
+ },
+ child: const Text('View Logs'),
+ ),
+ ],
+ ),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## Combining with Crashlytics
+
+Use `TalkerWrapper` for user-visible alerts AND `TalkerObserver` for crash reporting simultaneously:
+
+```dart
+final talker = TalkerFlutter.init(
+ observer: CrashlyticsTalkerObserver(FirebaseCrashlytics.instance),
+);
+
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ enableExceptionAlerts: true,
+ ),
+ child: MaterialApp(home: HomeScreen()),
+)
+```
+
+Now every error is:
+1. Logged to the console
+2. Saved in history
+3. Shown to the user as a SnackBar
+4. Sent to Crashlytics
+
+## Best Practices
+
+1. **Don't show technical details to users** — use `displayMessage` or create friendly messages rather than showing raw exception text.
+
+2. **Use TalkerWrapper for development** — it's a quick way to see errors during development. Disable or replace with custom UI for production.
+
+3. **Offer "View Logs" action** — let power users or testers open `TalkerScreen` from error alerts to investigate issues.
+
+4. **Rate-limit alerts** — if errors fire rapidly, use a debounce mechanism to avoid flooding the user with SnackBars.
diff --git a/website/docs/guides/custom-logs.md b/website/docs/guides/custom-logs.md
new file mode 100644
index 00000000..41479550
--- /dev/null
+++ b/website/docs/guides/custom-logs.md
@@ -0,0 +1,178 @@
+# Custom Log Types
+
+Talker allows you to create your own log types with full control over appearance, output format, and categorization.
+
+## Why Custom Logs?
+
+The built-in log types (`info`, `debug`, `warning`, etc.) cover most cases. But when you need domain-specific logs — like analytics events, business rule triggers, or custom HTTP formats — you can define your own.
+
+## Creating a Custom Log
+
+Extend the `TalkerLog` class:
+
+```dart
+import 'package:talker/talker.dart';
+
+class AnalyticsLog extends TalkerLog {
+ AnalyticsLog(String event, this.params) : super(event);
+
+ final Map params;
+
+ /// Unique key for this log type (used in settings, filters, etc.)
+ @override
+ String get key => 'analytics';
+
+ /// Title shown in console and TalkerScreen
+ @override
+ String get title => 'ANALYTICS';
+
+ /// Console color
+ @override
+ AnsiPen get pen => AnsiPen()..magenta();
+
+ /// Customize the full message output
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ return '${super.generateTextMessage(timeFormat: timeFormat)}\n'
+ 'Event: $message\n'
+ 'Params: $params';
+ }
+}
+```
+
+## Using Custom Logs
+
+Use `logCustom()` to send your custom log through Talker:
+
+```dart
+final talker = Talker();
+
+talker.logCustom(
+ AnalyticsLog('user_login', {'method': 'google', 'first_time': true}),
+);
+```
+
+This will:
+- Print a colored message to console with the title `ANALYTICS`
+- Save the log in Talker's history
+- Show the log in `TalkerScreen`
+- Broadcast it via `talker.stream`
+- Trigger `TalkerObserver.onLog()`
+
+## Registering Custom Keys
+
+To use custom colors and titles via `TalkerSettings`, register your custom key:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ // Register custom colors
+ colors: {
+ 'analytics': AnsiPen()..magenta(),
+ },
+ // Register custom titles
+ titles: {
+ 'analytics': 'ANALYTICS',
+ },
+ ),
+);
+```
+
+::: tip
+Settings-level colors and titles take priority over the log's own `pen` and `title` getters, allowing you to override them without changing the log class.
+:::
+
+## Real-World Examples
+
+### Business Event Log
+
+```dart
+class BusinessEventLog extends TalkerLog {
+ BusinessEventLog(String eventName, {this.revenue, this.userId})
+ : super(eventName);
+
+ final double? revenue;
+ final String? userId;
+
+ @override
+ String get key => 'business_event';
+
+ @override
+ String get title => 'BUSINESS';
+
+ @override
+ AnsiPen get pen => AnsiPen()..xterm(220); // Gold
+
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ var msg = super.generateTextMessage(timeFormat: timeFormat);
+ if (revenue != null) msg += '\nRevenue: \$${revenue!.toStringAsFixed(2)}';
+ if (userId != null) msg += '\nUser: $userId';
+ return msg;
+ }
+}
+
+talker.logCustom(
+ BusinessEventLog('purchase_completed', revenue: 29.99, userId: 'usr_123'),
+);
+```
+
+### Database Query Log
+
+```dart
+class DbQueryLog extends TalkerLog {
+ DbQueryLog(String query, this.duration) : super(query);
+
+ final Duration duration;
+
+ @override
+ String get key => 'db_query';
+
+ @override
+ String get title => 'DB';
+
+ @override
+ AnsiPen get pen => duration.inMilliseconds > 1000
+ ? (AnsiPen()..red()) // Slow query
+ : (AnsiPen()..green()); // Normal query
+
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ return '${super.generateTextMessage(timeFormat: timeFormat)}\n'
+ 'Query: $message\n'
+ 'Duration: ${duration.inMilliseconds}ms';
+ }
+}
+
+talker.logCustom(
+ DbQueryLog('SELECT * FROM users WHERE id = ?', Duration(milliseconds: 45)),
+);
+```
+
+## Filtering Custom Logs
+
+Custom logs can be filtered by type and title just like built-in logs:
+
+```dart
+final talker = Talker(
+ filter: BaseTalkerFilter(
+ titles: ['ANALYTICS', 'DB'],
+ ),
+);
+```
+
+## Viewing in TalkerScreen
+
+Custom logs appear in `TalkerScreen` automatically. Their color in the Flutter UI can be customized via `TalkerScreenTheme`:
+
+```dart
+TalkerScreen(
+ talker: talker,
+ theme: const TalkerScreenTheme(
+ logColors: {
+ 'analytics': Color(0xFFE040FB),
+ 'db_query': Color(0xFF4CAF50),
+ },
+ ),
+)
+```
diff --git a/website/docs/guides/routing.md b/website/docs/guides/routing.md
new file mode 100644
index 00000000..077a2bb4
--- /dev/null
+++ b/website/docs/guides/routing.md
@@ -0,0 +1,133 @@
+# Route Logging
+
+Log navigation events in your Flutter app with `TalkerRouteObserver`. Works with Navigator, go_router, auto_route, and any NavigatorObserver-compatible router.
+
+## Setup
+
+### Navigator 1.0
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+MaterialApp(
+ navigatorObservers: [
+ TalkerRouteObserver(talker),
+ ],
+ home: HomeScreen(),
+)
+```
+
+### go_router
+
+```dart
+import 'package:go_router/go_router.dart';
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+final router = GoRouter(
+ observers: [TalkerRouteObserver(talker)],
+ routes: [
+ GoRoute(path: '/', builder: (_, __) => HomeScreen()),
+ GoRoute(path: '/profile', builder: (_, __) => ProfileScreen()),
+ ],
+);
+
+MaterialApp.router(routerConfig: router)
+```
+
+### auto_route v7+
+
+```dart
+import 'package:auto_route/auto_route.dart';
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+MaterialApp.router(
+ routerConfig: _appRouter.config(
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+)
+```
+
+### auto_route (legacy)
+
+```dart
+MaterialApp.router(
+ routerDelegate: AutoRouterDelegate(
+ appRouter,
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+ routeInformationParser: appRouter.defaultRouteParser(),
+)
+```
+
+## What Gets Logged
+
+`TalkerRouteObserver` logs the following events:
+
+| Event | Description | Example |
+|-------|-------------|---------|
+| **Push** | New route pushed onto the stack | `Route pushed: /profile` |
+| **Pop** | Route popped from the stack | `Route popped: /profile` |
+| **Replace** | Route replaced | `Route replaced: /login → /home` |
+| **Remove** | Route removed | `Route removed: /splash` |
+
+All navigation logs appear in the console, TalkerScreen, and history with the default route color (purple).
+
+## Viewing in TalkerScreen
+
+Navigate to `TalkerScreen` to see all route events alongside other logs:
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+Route logs are color-coded and easily distinguishable from other log types. You can filter them in TalkerScreen by selecting the "Route" filter.
+
+## Customization
+
+### Custom Route Color
+
+Change the color of route logs in the console:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ colors: {
+ TalkerLogType.route.key: AnsiPen()..cyan(),
+ },
+ ),
+);
+```
+
+### Custom Route Title
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ titles: {
+ TalkerLogType.route.key: 'NAV',
+ },
+ ),
+);
+```
+
+## Best Practices
+
+1. **Use the same Talker instance** across your entire app — route logs, HTTP logs, BLoC events, and error reports all in one place.
+
+2. **Combine with TalkerScreen** — during development, add a debug button or shake gesture to open `TalkerScreen` and see the full navigation history.
+
+3. **Use with Crashlytics** — route logs make excellent breadcrumbs for crash reports. When combined with `TalkerObserver`, every navigation event is sent as a breadcrumb to Crashlytics or Sentry.
diff --git a/website/docs/index.md b/website/docs/index.md
new file mode 100644
index 00000000..9268de7f
--- /dev/null
+++ b/website/docs/index.md
@@ -0,0 +1,222 @@
+---
+layout: home
+
+hero:
+ name: Talker
+ text: Advanced Error Handler & Logger
+ tagline: Log your app actions, catch and handle exceptions, show alerts and share log reports for Dart & Flutter
+ image:
+ src: /logo.png
+ alt: Talker
+ actions:
+ - theme: brand
+ text: Get Started
+ link: /getting-started/installation
+ - theme: alt
+ text: View on GitHub
+ link: https://github.com/Frezyx/talker
+ - theme: alt
+ text: Web Demo
+ link: https://frezyx.github.io/talker
+
+features:
+ - icon: 📝
+ title: Powerful Logging
+ details: Log with multiple levels — info, debug, warning, error, critical, verbose, and good. Full color customization and custom log types support.
+ - icon: 🛡️
+ title: Error Handling
+ details: Catch and handle Exceptions and Errors with StackTrace. Send error data to Crashlytics, Sentry, or your own analytics service via TalkerObserver.
+ - icon: 📱
+ title: Flutter UI
+ details: Built-in TalkerScreen to view logs in-app, TalkerMonitor for quick status overview, TalkerWrapper for error alerts, and TalkerRouteObserver for navigation logging.
+ - icon: 🔌
+ title: Rich Integrations
+ details: Out-of-the-box support for Dio, http, BLoC, Riverpod, Chopper, and gRPC. Each with full customization, filtering, and color options.
+ - icon: 🎨
+ title: Fully Customizable
+ details: Custom colors, titles, formatters, and filters for every log type. Create your own log types with full control over appearance and behavior.
+ - icon: ✅
+ title: Production Ready
+ details: 100% test coverage, MIT licensed, compatible with any state management, works on all platforms — Android, iOS, Web, macOS, Windows, Linux.
+---
+
+
+
+
+
+## Try Talker Now
+
+Play with Talker directly in your browser — no setup needed:
+
+
+
+
+
+
+
+
+
+## Packages Ecosystem
+
+Talker is designed for any level of customization — pick what you need:
+
+
+
+
+
+### [talker](https://pub.dev/packages/talker)
+
+Main Dart package for logging and error handling. The core of the ecosystem.
+
+
+
+
+
+### [talker_flutter](https://pub.dev/packages/talker_flutter)
+
+Flutter extensions — colored logs, TalkerScreen, TalkerMonitor, route observer, and more.
+
+
+
+
+
+### [talker_logger](https://pub.dev/packages/talker_logger)
+
+Customizable pretty logger for Dart/Flutter apps. Can be used standalone.
+
+
+
+
+
+### [talker_dio_logger](https://pub.dev/packages/talker_dio_logger)
+
+Beautiful HTTP request/response logging for Dio http client.
+
+
+
+
+
+### [talker_http_logger](https://pub.dev/packages/talker_http_logger)
+
+HTTP logging for the standard http package with http_interceptor.
+
+
+
+
+
+### [talker_bloc_logger](https://pub.dev/packages/talker_bloc_logger)
+
+State management logging for BLoC — events, transitions, state changes.
+
+
+
+
+
+### [talker_riverpod_logger](https://pub.dev/packages/talker_riverpod_logger)
+
+Provider lifecycle logging for Riverpod — add, update, dispose, fail.
+
+
+
+
+
+### [talker_chopper_logger](https://pub.dev/packages/talker_chopper_logger)
+
+HTTP logging for Chopper client with curl command support.
+
+
+
+
+
+### [talker_grpc_logger](https://pub.dev/packages/talker_grpc_logger)
+
+gRPC request/response logging with token obfuscation.
+
+
+
+
+
+
diff --git a/website/docs/integrations/bloc.md b/website/docs/integrations/bloc.md
new file mode 100644
index 00000000..5db8cb3e
--- /dev/null
+++ b/website/docs/integrations/bloc.md
@@ -0,0 +1,98 @@
+# BLoC Logger
+
+
+
+Lightweight and customizable [BLoC](https://pub.dev/packages/bloc) state management logger built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_bloc_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Set `TalkerBlocObserver` as the global BLoC observer:
+
+```dart
+import 'package:talker_bloc_logger/talker_bloc_logger.dart';
+
+Bloc.observer = TalkerBlocObserver();
+```
+
+That's it! All BLoC events, transitions, state changes, creations, and closings will be logged.
+
+## Using with Talker
+
+Pass your existing Talker instance:
+
+```dart
+import 'package:talker_bloc_logger/talker_bloc_logger.dart';
+import 'package:talker/talker.dart';
+
+final talker = Talker();
+Bloc.observer = TalkerBlocObserver(talker: talker);
+```
+
+## Customization
+
+### Toggle Event Types
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ enabled: true,
+ printEvents: true,
+ printTransitions: true,
+ printChanges: true,
+ printCreations: true,
+ printClosings: true,
+ ),
+);
+```
+
+### Truncate State/Event Data
+
+By default, full data is printed. You can truncate it:
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ printEventFullData: false,
+ printStateFullData: false,
+ ),
+);
+```
+
+### Filter Logs
+
+Log only specific BLoCs:
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ // Only log AuthBloc transitions
+ transitionFilter: (bloc, transition) =>
+ bloc.runtimeType.toString() == 'AuthBloc',
+ // Only log AuthBloc events
+ eventFilter: (bloc, event) =>
+ bloc.runtimeType.toString() == 'AuthBloc',
+ ),
+);
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `enabled` | `bool` | `true` | Enable/disable logging |
+| `printEvents` | `bool` | `true` | Log BLoC events |
+| `printTransitions` | `bool` | `true` | Log state transitions |
+| `printChanges` | `bool` | `true` | Log state changes |
+| `printCreations` | `bool` | `true` | Log BLoC creations |
+| `printClosings` | `bool` | `true` | Log BLoC closings |
+| `printEventFullData` | `bool` | `true` | Print full event data |
+| `printStateFullData` | `bool` | `true` | Print full state data |
+| `transitionFilter` | `Function?` | `null` | Filter transitions to log |
+| `eventFilter` | `Function?` | `null` | Filter events to log |
diff --git a/website/docs/integrations/chopper.md b/website/docs/integrations/chopper.md
new file mode 100644
index 00000000..8b61ce30
--- /dev/null
+++ b/website/docs/integrations/chopper.md
@@ -0,0 +1,114 @@
+# Chopper Logger
+
+
+
+Lightweight and customizable HTTP logger for [Chopper](https://pub.dev/packages/chopper) built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_chopper_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Add `TalkerChopperLogger` as a Chopper interceptor:
+
+```dart
+import 'package:talker_chopper_logger/talker_chopper_logger.dart';
+
+final chopper = ChopperClient(
+ baseUrl: Uri.parse('https://api.example.com'),
+ interceptors: [
+ TalkerChopperLogger(
+ settings: const TalkerChopperLoggerSettings(),
+ ),
+ ],
+);
+```
+
+## Using with Talker
+
+```dart
+final talker = Talker();
+final chopper = ChopperClient(
+ interceptors: [
+ TalkerChopperLogger(talker: talker),
+ ],
+);
+```
+
+## Customization
+
+### Toggle Request/Response Logging
+
+```dart
+TalkerChopperLoggerSettings(
+ printRequestData: true,
+ printRequestHeaders: true,
+ printResponseData: true,
+ printResponseHeaders: true,
+ printResponseMessage: true,
+)
+```
+
+### Print curl Command
+
+```dart
+TalkerChopperLoggerSettings(
+ printRequestCurl: true,
+)
+```
+
+### Hide Sensitive Headers
+
+```dart
+TalkerChopperLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ hiddenHeaders: {
+ 'authorization',
+ 'cookie',
+ 'x-api-key',
+ },
+)
+```
+
+### Custom Colors
+
+```dart
+TalkerChopperLoggerSettings(
+ requestPen: AnsiPen()..cyan(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Filtering
+
+```dart
+TalkerChopperLoggerSettings(
+ requestFilter: (request) =>
+ !request.url.path.contains('/health'),
+ responseFilter: (response) =>
+ response.statusCode != 304,
+)
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `printRequestData` | `bool` | `true` | Print request body |
+| `printResponseData` | `bool` | `true` | Print response body |
+| `printRequestHeaders` | `bool` | `false` | Print request headers |
+| `printResponseHeaders` | `bool` | `false` | Print response headers |
+| `printResponseMessage` | `bool` | `true` | Print response status message |
+| `printRequestCurl` | `bool` | `false` | Print curl command for requests |
+| `hiddenHeaders` | `Set` | `{}` | Headers to hide from output |
+| `requestPen` | `AnsiPen?` | pink | Console color for requests |
+| `responsePen` | `AnsiPen?` | green | Console color for responses |
+| `errorPen` | `AnsiPen?` | red | Console color for errors |
+| `requestFilter` | `Function?` | `null` | Filter which requests to log |
+| `responseFilter` | `Function?` | `null` | Filter which responses to log |
diff --git a/website/docs/integrations/dio.md b/website/docs/integrations/dio.md
new file mode 100644
index 00000000..dc2c20a6
--- /dev/null
+++ b/website/docs/integrations/dio.md
@@ -0,0 +1,100 @@
+# Dio Logger
+
+
+
+Lightweight and customizable HTTP logger for [Dio](https://pub.dev/packages/dio) built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_dio_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Add `TalkerDioLogger` to your Dio interceptors:
+
+```dart
+import 'package:talker_dio_logger/talker_dio_logger.dart';
+
+final dio = Dio();
+dio.interceptors.add(
+ TalkerDioLogger(
+ settings: const TalkerDioLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ printResponseMessage: true,
+ ),
+ ),
+);
+```
+
+## Using with Talker
+
+Pass your existing Talker instance to unify all logs:
+
+```dart
+final talker = Talker();
+final dio = Dio();
+dio.interceptors.add(TalkerDioLogger(talker: talker));
+```
+
+Now all HTTP logs will appear in `TalkerScreen`, history, and stream alongside your other logs.
+
+## Customization
+
+### Toggle Request/Response Logging
+
+```dart
+TalkerDioLoggerSettings(
+ // Enable response body logging
+ printResponseData: true,
+ // Disable request body logging
+ printRequestData: false,
+ // Include response headers
+ printResponseHeaders: true,
+ // Exclude request headers
+ printRequestHeaders: false,
+)
+```
+
+### Custom Colors
+
+```dart
+TalkerDioLoggerSettings(
+ requestPen: AnsiPen()..blue(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Filtering
+
+Only log specific requests/responses:
+
+```dart
+TalkerDioLoggerSettings(
+ // Skip requests to /secure endpoints
+ requestFilter: (RequestOptions options) =>
+ !options.path.contains('/secure'),
+ // Skip 301 redirects
+ responseFilter: (response) =>
+ response.statusCode != 301,
+)
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `printRequestData` | `bool` | `true` | Print request body |
+| `printResponseData` | `bool` | `true` | Print response body |
+| `printRequestHeaders` | `bool` | `false` | Print request headers |
+| `printResponseHeaders` | `bool` | `false` | Print response headers |
+| `printResponseMessage` | `bool` | `true` | Print response status message |
+| `requestPen` | `AnsiPen?` | pink | Console color for requests |
+| `responsePen` | `AnsiPen?` | green | Console color for responses |
+| `errorPen` | `AnsiPen?` | red | Console color for errors |
+| `requestFilter` | `Function?` | `null` | Filter which requests to log |
+| `responseFilter` | `Function?` | `null` | Filter which responses to log |
diff --git a/website/docs/integrations/grpc.md b/website/docs/integrations/grpc.md
new file mode 100644
index 00000000..d7e93f24
--- /dev/null
+++ b/website/docs/integrations/grpc.md
@@ -0,0 +1,95 @@
+# gRPC Logger
+
+
+
+Lightweight and customizable [gRPC](https://pub.dev/packages/grpc) logger built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_grpc_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Add `TalkerGrpcLogger` as a gRPC client interceptor:
+
+```dart
+import 'package:talker_grpc_logger/talker_grpc_logger.dart';
+
+final channel = ClientChannel(
+ 'localhost',
+ port: 50051,
+ options: ChannelOptions(
+ credentials: const ChannelCredentials.insecure(),
+ ),
+);
+
+final client = YourServiceClient(
+ channel,
+ interceptors: [TalkerGrpcLogger()],
+);
+```
+
+## Using with Talker
+
+```dart
+final talker = Talker();
+final client = YourServiceClient(
+ channel,
+ interceptors: [
+ TalkerGrpcLogger(talker: talker),
+ ],
+);
+```
+
+## Customization
+
+### Token Obfuscation
+
+gRPC metadata often contains sensitive tokens. Talker can obfuscate them:
+
+```dart
+TalkerGrpcLogger(
+ settings: TalkerGrpcLoggerSettings(
+ // Token will show as "eyJh***" instead of the full value
+ printRequestHeaders: true,
+ hideTokens: true,
+ ),
+)
+```
+
+### Toggle Request/Response Logging
+
+```dart
+TalkerGrpcLoggerSettings(
+ printRequestData: true,
+ printResponseData: true,
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+)
+```
+
+### Custom Colors
+
+```dart
+TalkerGrpcLoggerSettings(
+ requestPen: AnsiPen()..cyan(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `printRequestData` | `bool` | `true` | Print request message data |
+| `printResponseData` | `bool` | `true` | Print response message data |
+| `printRequestHeaders` | `bool` | `false` | Print request metadata |
+| `printResponseHeaders` | `bool` | `false` | Print response trailers |
+| `hideTokens` | `bool` | `false` | Obfuscate tokens in metadata |
+| `requestPen` | `AnsiPen?` | pink | Console color for requests |
+| `responsePen` | `AnsiPen?` | green | Console color for responses |
+| `errorPen` | `AnsiPen?` | red | Console color for errors |
diff --git a/website/docs/integrations/http.md b/website/docs/integrations/http.md
new file mode 100644
index 00000000..fe7fa5c9
--- /dev/null
+++ b/website/docs/integrations/http.md
@@ -0,0 +1,107 @@
+# HTTP Logger
+
+
+
+Lightweight HTTP logger for the [http_interceptor](https://pub.dev/packages/http_interceptor) package built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_http_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Add `TalkerHttpLogger` to your `InterceptedClient`:
+
+```dart
+import 'package:http_interceptor/http_interceptor.dart';
+import 'package:talker_http_logger/talker_http_logger.dart';
+
+void main() async {
+ final client = InterceptedClient.build(interceptors: [
+ TalkerHttpLogger(
+ settings: const TalkerHttpLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ printResponseMessage: true,
+ ),
+ ),
+ ]);
+
+ await client.get("https://google.com".toUri());
+}
+```
+
+## Using with Talker
+
+```dart
+final talker = Talker();
+final client = InterceptedClient.build(
+ interceptors: [
+ TalkerHttpLogger(talker: talker),
+ ],
+);
+```
+
+## Customization
+
+### Print curl Command
+
+```dart
+TalkerHttpLoggerSettings(
+ printRequestCurl: true,
+)
+```
+
+### Hide Sensitive Headers
+
+```dart
+TalkerHttpLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ hiddenHeaders: {
+ 'authorization',
+ 'cookie',
+ },
+)
+```
+
+### Custom Colors
+
+```dart
+TalkerHttpLoggerSettings(
+ requestPen: AnsiPen()..blue(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Filtering
+
+```dart
+TalkerHttpLoggerSettings(
+ requestFilter: (Request request) =>
+ !request.url.path.contains('/secure'),
+ responseFilter: (Response response) =>
+ response.statusCode != 301,
+)
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `printRequestData` | `bool` | `true` | Print request body |
+| `printResponseData` | `bool` | `true` | Print response body |
+| `printRequestHeaders` | `bool` | `false` | Print request headers |
+| `printResponseHeaders` | `bool` | `false` | Print response headers |
+| `printResponseMessage` | `bool` | `true` | Print response status message |
+| `printRequestCurl` | `bool` | `false` | Print curl command for requests |
+| `hiddenHeaders` | `Set` | `{}` | Headers to hide from output |
+| `requestPen` | `AnsiPen?` | pink | Console color for requests |
+| `responsePen` | `AnsiPen?` | green | Console color for responses |
+| `errorPen` | `AnsiPen?` | red | Console color for errors |
+| `requestFilter` | `Function?` | `null` | Filter which requests to log |
+| `responseFilter` | `Function?` | `null` | Filter which responses to log |
diff --git a/website/docs/integrations/riverpod.md b/website/docs/integrations/riverpod.md
new file mode 100644
index 00000000..4ab88a6d
--- /dev/null
+++ b/website/docs/integrations/riverpod.md
@@ -0,0 +1,96 @@
+# Riverpod Logger
+
+
+
+Lightweight and customizable [Riverpod](https://pub.dev/packages/riverpod) state management logger built on Talker.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_riverpod_logger: ^5.1.13
+```
+
+## Basic Usage
+
+Add `TalkerRiverpodObserver` to your `ProviderScope`:
+
+```dart
+import 'package:talker_riverpod_logger/talker_riverpod_logger.dart';
+
+runApp(
+ ProviderScope(
+ observers: [TalkerRiverpodObserver()],
+ child: MyApp(),
+ ),
+);
+```
+
+All provider lifecycle events — add, update, dispose, and fail — will be logged automatically.
+
+## Using with Talker
+
+Pass your existing Talker instance:
+
+```dart
+final talker = Talker();
+
+runApp(
+ ProviderScope(
+ observers: [TalkerRiverpodObserver(talker: talker)],
+ child: MyApp(),
+ ),
+);
+```
+
+## Customization
+
+### Toggle Event Types
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ enabled: true,
+ printProviderAdded: true,
+ printProviderUpdated: true,
+ printProviderDisposed: true,
+ printProviderFailed: true,
+ ),
+)
+```
+
+### Truncate Data
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ printStateFullData: false,
+ ),
+)
+```
+
+### Filter Logs
+
+Only log specific providers:
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ // Only log specific providers
+ providerFilter: (provider) =>
+ provider.name?.contains('auth') ?? false,
+ ),
+)
+```
+
+## Settings Reference
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `enabled` | `bool` | `true` | Enable/disable logging |
+| `printProviderAdded` | `bool` | `true` | Log provider additions |
+| `printProviderUpdated` | `bool` | `true` | Log provider updates |
+| `printProviderDisposed` | `bool` | `true` | Log provider disposals |
+| `printProviderFailed` | `bool` | `true` | Log provider failures |
+| `printStateFullData` | `bool` | `true` | Print full state data |
+| `providerFilter` | `Function?` | `null` | Filter which providers to log |
diff --git a/website/docs/packages/talker-flutter.md b/website/docs/packages/talker-flutter.md
new file mode 100644
index 00000000..a8657f47
--- /dev/null
+++ b/website/docs/packages/talker-flutter.md
@@ -0,0 +1,242 @@
+# talker_flutter
+
+
+
+Flutter extensions for Talker — colored logs, in-app log viewer, error alerts, route observer, and more.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_flutter: ^5.1.13
+```
+
+## Setup
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+```
+
+::: tip Why TalkerFlutter.init()?
+This method uses the optimal logging output for each platform:
+- **Web** — `print()`
+- **iOS / macOS** — `dart:developer.log` (preserves colored output)
+- **Android / Windows / Linux** — `debugPrint` (avoids message truncation)
+:::
+
+You get the same `Talker` instance as `Talker()` but with platform-optimized logging.
+
+## TalkerScreen
+
+A full-featured log viewer widget. View, filter, search, and share all logs directly in your app.
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+### TalkerScreen Parameters
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `talker` | `Talker` | _required_ | Talker instance to display logs from |
+| `theme` | `TalkerScreenTheme` | `TalkerScreenTheme()` | Visual theme configuration |
+| `appBarTitle` | `String` | `'Talker'` | Custom title for the app bar |
+| `appBarLeading` | `Widget?` | `null` | Custom leading widget for the app bar |
+| `itemsBuilder` | `TalkerDataBuilder?` | `null` | Custom builder for log item cards |
+| `customSettings` | `List` | `[]` | Additional settings groups |
+| `isLogsExpanded` | `bool` | `true` | Whether logs are initially expanded |
+| `isLogOrderReversed` | `bool` | `true` | Whether latest logs appear on top |
+
+### Custom Theme Colors
+
+Customize colors for any log type in TalkerScreen:
+
+```dart
+TalkerScreen(
+ talker: talker,
+ theme: const TalkerScreenTheme(
+ logColors: {
+ // Override default log type colors
+ TalkerLogType.httpResponse.key: Color(0xFF26FF3C),
+ TalkerLogType.error.key: Colors.redAccent,
+ TalkerLogType.info.key: Color.fromARGB(255, 0, 255, 247),
+
+ // Custom log keys
+ 'custom_log_key': Colors.green,
+ },
+ ),
+)
+```
+
+### TalkerScreenTheme
+
+```dart
+TalkerScreenTheme(
+ backgroundColor: Colors.grey[800]!,
+ cardColor: Colors.grey[700]!,
+ textColor: Colors.white,
+ logColors: {
+ // Your log colors...
+ },
+)
+```
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `backgroundColor` | `Color` | Dark gray | Screen background color |
+| `cardColor` | `Color` | Gray | Log card background color |
+| `textColor` | `Color` | White | Log text color |
+| `logColors` | `Map` | _(defaults)_ | Custom colors for log types |
+
+## TalkerView
+
+Same as `TalkerScreen` but without `Scaffold` — for embedding in your own layouts:
+
+```dart
+Scaffold(
+ appBar: AppBar(title: Text('My Custom Screen')),
+ body: TalkerView(
+ talker: talker,
+ theme: const TalkerScreenTheme(),
+ ),
+)
+```
+
+## TalkerMonitor
+
+A quick status overview showing counts of HTTP requests, exceptions, errors, warnings, etc.
+
+`TalkerMonitor` is accessible from the `TalkerScreen` settings page. It provides a filtered summary of your application's health at a glance.
+
+## TalkerWrapper
+
+Show error alerts and status messages automatically in your UI:
+
+```dart
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ ),
+ child: MyApp(),
+)
+```
+
+### TalkerWrapperOptions
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `enableErrorAlerts` | `bool` | `true` | Show SnackBars for errors |
+| `enableExceptionAlerts` | `bool` | `true` | Show SnackBars for exceptions |
+
+## TalkerListener
+
+Listen to Talker events in the widget tree:
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ if (data is TalkerException || data is TalkerError) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text(data.displayMessage)),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## TalkerBuilder
+
+Build UI reactively based on Talker logs:
+
+```dart
+TalkerBuilder(
+ talker: talker,
+ builder: (context, data) {
+ return ListView.builder(
+ itemCount: data.length,
+ itemBuilder: (context, index) {
+ return ListTile(title: Text(data[index].message));
+ },
+ );
+ },
+)
+```
+
+## TalkerRouteObserver
+
+Log navigation events. Works with any routing package.
+
+### Navigator
+
+```dart
+MaterialApp(
+ navigatorObservers: [
+ TalkerRouteObserver(talker),
+ ],
+)
+```
+
+### go_router
+
+```dart
+GoRouter(
+ observers: [TalkerRouteObserver(talker)],
+)
+```
+
+### auto_route v7+
+
+```dart
+MaterialApp.router(
+ routerConfig: _appRouter.config(
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+)
+```
+
+### auto_route (legacy)
+
+```dart
+MaterialApp.router(
+ routerDelegate: AutoRouterDelegate(
+ appRouter,
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+)
+```
+
+See the full [Route Logging](/guides/routing) guide for more details.
+
+## runTalkerZonedGuarded
+
+Catch all uncaught errors in your app zone:
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+void main() {
+ final talker = TalkerFlutter.init();
+
+ runTalkerZonedGuarded(
+ talker,
+ () => runApp(MyApp()),
+ );
+}
+```
+
+## API Reference
+
+Full API documentation is available on [pub.dev](https://pub.dev/documentation/talker_flutter/latest/).
diff --git a/website/docs/packages/talker-logger.md b/website/docs/packages/talker-logger.md
new file mode 100644
index 00000000..4d91b7f3
--- /dev/null
+++ b/website/docs/packages/talker-logger.md
@@ -0,0 +1,141 @@
+# talker_logger
+
+
+
+Customizable pretty logger for Dart/Flutter apps. Can be used as a standalone package or as part of the Talker ecosystem.
+
+## Installation
+
+```yaml
+dependencies:
+ talker_logger: ^5.1.13
+```
+
+## Basic Usage
+
+```dart
+import 'package:talker_logger/talker_logger.dart';
+
+final logger = TalkerLogger();
+
+logger.debug('debug');
+logger.info('info');
+logger.warning('warning');
+logger.error('error');
+logger.critical('critical');
+logger.good('good');
+logger.verbose('verbose');
+```
+
+## Custom Log Level
+
+Use the `log()` method to specify level and color:
+
+```dart
+logger.log('custom message', level: LogLevel.info);
+logger.log('colored log', pen: AnsiPen()..xterm(49));
+```
+
+## Log Levels
+
+| Level | Description |
+|-------|-------------|
+| `LogLevel.critical` | Critical errors that require immediate attention |
+| `LogLevel.error` | Runtime errors |
+| `LogLevel.warning` | Potential issues |
+| `LogLevel.info` | Informational messages |
+| `LogLevel.debug` | Debug information |
+| `LogLevel.verbose` | Detailed tracing information |
+| `LogLevel.good` | Positive status messages |
+
+## Filtering
+
+Filter logs by setting the minimum log level:
+
+```dart
+final logger = TalkerLogger(
+ settings: const TalkerLoggerSettings(
+ level: LogLevel.critical,
+ ),
+);
+
+// This will print
+logger.critical('critical error');
+
+// This will NOT print (level is below critical)
+logger.info('info message');
+```
+
+## Custom Formatting
+
+### Built-in Formatter Customization
+
+```dart
+final logger = TalkerLogger(
+ settings: TalkerLoggerSettings(
+ colors: {
+ LogLevel.critical: AnsiPen()..yellow(),
+ LogLevel.error: AnsiPen()..yellow(),
+ LogLevel.info: AnsiPen()..yellow(),
+ },
+ maxLineWidth: 20,
+ lineSymbol: '#',
+ enableColors: true,
+ ),
+);
+```
+
+### Custom Formatter
+
+Implement your own `LoggerFormatter`:
+
+```dart
+class ColoredLoggerFormatter implements LoggerFormatter {
+ @override
+ String fmt(LogDetails details, TalkerLoggerSettings settings) {
+ final msg = details.message?.toString() ?? '';
+ final coloredMsg = msg
+ .split('\n')
+ .map((e) => details.pen.write(e))
+ .toList()
+ .join('\n');
+ return coloredMsg;
+ }
+}
+
+final logger = TalkerLogger(
+ formatter: ColoredLoggerFormatter(),
+);
+
+logger.debug('debug');
+logger.info('info');
+logger.warning('warning');
+logger.error('error');
+```
+
+## TalkerLoggerSettings
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `level` | `LogLevel` | `LogLevel.verbose` | Minimum log level to output |
+| `enableColors` | `bool` | `true` | Whether to use ANSI colors in output |
+| `maxLineWidth` | `int` | `110` | Maximum width of log line decorations |
+| `lineSymbol` | `String` | `'─'` | Character used for line decorations |
+| `colors` | `Map` | _(defaults)_ | Custom colors for each log level |
+
+## Custom Output
+
+You can redirect where logs are printed:
+
+```dart
+final logger = TalkerLogger(
+ output: (message) {
+ // Send to file, remote server, etc.
+ myCustomOutput(message);
+ },
+);
+```
+
+## API Reference
+
+Full API documentation is available on [pub.dev](https://pub.dev/documentation/talker_logger/latest/).
diff --git a/website/docs/packages/talker.md b/website/docs/packages/talker.md
new file mode 100644
index 00000000..24be247a
--- /dev/null
+++ b/website/docs/packages/talker.md
@@ -0,0 +1,265 @@
+# talker
+
+
+
+The core Dart package for logging and error handling. Works in any Dart project — server-side, CLI, or Flutter.
+
+## Installation
+
+```yaml
+dependencies:
+ talker: ^5.1.13
+```
+
+## Basic Logging
+
+```dart
+import 'package:talker/talker.dart';
+
+final talker = Talker();
+
+// Log messages with different levels
+talker.info('App started');
+talker.debug('Loading configuration...');
+talker.warning('Cache is almost full');
+talker.error('Failed to save file');
+talker.critical('Database connection lost!');
+talker.verbose('Detailed trace information');
+talker.good('Operation completed successfully!');
+```
+
+## Error Handling
+
+Handle exceptions and errors with full `StackTrace` support:
+
+```dart
+try {
+ throw Exception('Something went wrong');
+} catch (e, st) {
+ talker.handle(e, st, 'Exception in data processing');
+}
+```
+
+The `handle()` method automatically distinguishes between `Exception` and `Error` types.
+
+## Advanced Logging
+
+Use the `log()` method for maximum control:
+
+```dart
+talker.log(
+ 'Server error',
+ logLevel: LogLevel.critical,
+ exception: Exception('Connection timeout'),
+ stackTrace: stackTrace,
+ pen: AnsiPen()..red(),
+);
+```
+
+## TalkerSettings
+
+Configure Talker behavior through `TalkerSettings`:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ /// Enable/disable all talker processes
+ enabled: true,
+ /// Enable/disable saving logs in history
+ useHistory: true,
+ /// Maximum number of history items
+ maxHistoryItems: 1000,
+ /// Enable/disable console output
+ useConsoleLogs: true,
+ /// Time format for log timestamps
+ timeFormat: TimeFormat.timeAndSeconds,
+ ),
+);
+```
+
+### Settings Fields
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `enabled` | `bool` | `true` | Master switch for all Talker operations |
+| `useHistory` | `bool` | `true` | Whether to save logs in history |
+| `maxHistoryItems` | `int` | `1000` | Maximum number of stored history items |
+| `useConsoleLogs` | `bool` | `true` | Whether to print logs to console |
+| `timeFormat` | `TimeFormat` | `timeAndSeconds` | Timestamp format for logs |
+| `titles` | `Map` | _(defaults)_ | Custom titles for log types |
+| `colors` | `Map` | _(defaults)_ | Custom colors for log types |
+
+## Custom Log Colors
+
+Set your own color for any type of log:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ colors: {
+ TalkerLogType.httpResponse.key: AnsiPen()..red(),
+ TalkerLogType.error.key: AnsiPen()..green(),
+ TalkerLogType.info.key: AnsiPen()..blue(),
+
+ // Custom log keys
+ 'custom_log_key': AnsiPen()..yellow(),
+ },
+ ),
+);
+```
+
+### Default Color Scheme
+
+| Log Type | Color |
+|----------|-------|
+| `critical` | Red |
+| `error` | Red |
+| `exception` | Red |
+| `warning` | Yellow |
+| `info` | Blue |
+| `debug` | Gray |
+| `verbose` | Gray |
+| `httpRequest` | Pink (xterm 219) |
+| `httpResponse` | Green (xterm 46) |
+| `httpError` | Red |
+| `route` | Purple (xterm 135) |
+
+## Custom Log Titles
+
+Override the default titles for any log type:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ titles: {
+ TalkerLogType.exception.key: 'Whatever you want',
+ TalkerLogType.error.key: 'E',
+ TalkerLogType.info.key: 'i',
+
+ // Custom log keys
+ 'custom_log_key': 'My Custom Title',
+ },
+ ),
+);
+```
+
+## Custom Log Types
+
+Create your own log type by extending `TalkerLog`:
+
+```dart
+class HttpLog extends TalkerLog {
+ HttpLog(String super.message);
+
+ static const logKey = 'http_log';
+ static final logTitle = 'HTTP';
+ static final logPen = AnsiPen()..cyan();
+
+ @override
+ String get title => logTitle;
+
+ @override
+ String get key => logKey;
+
+ @override
+ AnsiPen get pen => logPen;
+}
+
+// Usage
+talker.logCustom(HttpLog('GET /api/users — 200 OK'));
+```
+
+See the full guide on [Custom Log Types](/guides/custom-logs).
+
+## TalkerObserver
+
+Observe all Talker events from the outside — perfect for sending data to external services:
+
+```dart
+class MyTalkerObserver extends TalkerObserver {
+ @override
+ void onError(TalkerError err) {
+ // Send to Crashlytics, Sentry, etc.
+ super.onError(err);
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ // Send to error tracking service
+ super.onException(exception);
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ // Send to Grafana, analytics backend, etc.
+ super.onLog(log);
+ }
+}
+
+final talker = Talker(observer: MyTalkerObserver());
+```
+
+See the [Crashlytics Integration](/guides/crashlytics) guide for a full example.
+
+## Stream
+
+Listen to all Talker events via a broadcast stream:
+
+```dart
+talker.stream.listen((data) {
+ print('New event: ${data.message}');
+});
+```
+
+## History
+
+Access the full log history:
+
+```dart
+// Get all history
+final logs = talker.history;
+
+// Clear history
+talker.cleanHistory();
+```
+
+## Filtering
+
+Use `TalkerFilter` to select specific logs:
+
+```dart
+final talker = Talker(
+ filter: BaseTalkerFilter(
+ titles: ['error', 'exception'],
+ types: [TalkerError, TalkerException],
+ ),
+);
+```
+
+## Enable / Disable
+
+Control Talker at runtime:
+
+```dart
+// Stop all logging and error handling
+talker.disable();
+
+// Resume operations
+talker.enable();
+```
+
+## Runtime Configuration
+
+Reconfigure Talker after creation:
+
+```dart
+talker.configure(
+ settings: TalkerSettings(enabled: true),
+ logger: TalkerLogger(),
+ observer: MyTalkerObserver(),
+);
+```
+
+## API Reference
+
+Full API documentation is available on [pub.dev](https://pub.dev/documentation/talker/latest/).
diff --git a/website/docs/ru/examples.md b/website/docs/ru/examples.md
new file mode 100644
index 00000000..42d91fa8
--- /dev/null
+++ b/website/docs/ru/examples.md
@@ -0,0 +1,67 @@
+# Примеры
+
+## Интерактивные примеры в DartPad
+
+### Базовое логирование
+
+Попробуйте уровни логирования Talker в браузере:
+
+
+
+
+
+### Обработка ошибок
+
+Посмотрите, как Talker обрабатывает исключения с stack trace:
+
+
+
+
+
+### Пользовательские типы логов
+
+Создавайте собственные типы логов:
+
+
+
+
+
+## Пример Shop App
+
+Полноценное Flutter-приложение, демонстрирующее интеграцию Talker:
+
+- Настройка Talker с DI
+- HTTP-логирование с Dio
+- Логирование BLoC state management
+- TalkerScreen и TalkerMonitor
+- Обработка ошибок с TalkerWrapper
+- Логирование маршрутов
+
+📂 [Посмотреть Shop App на GitHub](https://github.com/Frezyx/talker/tree/master/examples/shop_app_example)
+
+## Веб-демо
+
+Попробуйте полностью интерактивную Flutter веб-демку с `TalkerScreen` и `TalkerMonitor`:
+
+🌐 [Открыть веб-демо](https://frezyx.github.io/talker)
+
+
diff --git a/website/docs/ru/getting-started/installation.md b/website/docs/ru/getting-started/installation.md
new file mode 100644
index 00000000..70ddd681
--- /dev/null
+++ b/website/docs/ru/getting-started/installation.md
@@ -0,0 +1,62 @@
+# Установка
+
+## Выберите пакет
+
+Talker — это модульная экосистема. Устанавливайте только то, что вам нужно:
+
+### Для Dart-проектов
+
+```yaml
+dependencies:
+ talker: ^5.1.13
+```
+
+### Для Flutter-проектов
+
+```yaml
+dependencies:
+ talker_flutter: ^5.1.13
+```
+
+::: tip
+`talker_flutter` уже включает `talker` как зависимость — не нужно добавлять оба пакета.
+:::
+
+### Пакеты интеграций
+
+Добавьте любой из них рядом с основным пакетом:
+
+```yaml
+dependencies:
+ # HTTP-логирование для Dio
+ talker_dio_logger: ^5.1.13
+
+ # HTTP-логирование для пакета http
+ talker_http_logger: ^5.1.13
+
+ # Логирование BLoC state management
+ talker_bloc_logger: ^5.1.13
+
+ # Логирование Riverpod state management
+ talker_riverpod_logger: ^5.1.13
+
+ # HTTP-логирование для Chopper
+ talker_chopper_logger: ^5.1.13
+
+ # gRPC-логирование
+ talker_grpc_logger: ^5.1.13
+```
+
+## Запустите pub get
+
+После добавления зависимостей выполните:
+
+```bash
+flutter pub get
+# или для Dart-проектов
+dart pub get
+```
+
+## Далее
+
+Теперь, когда Talker установлен, переходите к [Быстрому старту](/ru/getting-started/quick-start)!
diff --git a/website/docs/ru/getting-started/quick-start.md b/website/docs/ru/getting-started/quick-start.md
new file mode 100644
index 00000000..01c78542
--- /dev/null
+++ b/website/docs/ru/getting-started/quick-start.md
@@ -0,0 +1,88 @@
+# Быстрый старт
+
+## Базовое использование (Dart)
+
+Создайте экземпляр Talker и начните логирование:
+
+```dart
+import 'package:talker/talker.dart';
+
+final talker = Talker();
+
+void main() {
+ // Логи с разными уровнями
+ talker.info('Приложение запущено');
+ talker.debug('Загрузка конфигурации...');
+ talker.warning('Кэш почти заполнен');
+ talker.error('Не удалось сохранить файл');
+ talker.critical('Соединение с базой данных потеряно!');
+ talker.verbose('Детальная информация трассировки');
+ talker.good('Операция выполнена успешно!');
+
+ // Обработка исключений
+ try {
+ throw Exception('Что-то пошло не так');
+ } catch (e, st) {
+ talker.handle(e, st, 'Ошибка обработки данных');
+ }
+}
+```
+
+## Использование во Flutter
+
+Для Flutter-приложений используйте `TalkerFlutter.init()` для оптимальной платформенной настройки:
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+void main() {
+ // Обработка исключений и ошибок
+ try {
+ // ваш код...
+ } catch (e, st) {
+ talker.handle(e, st, 'Исключение в ...');
+ }
+
+ // Логирование информации приложения
+ talker.info('Приложение запущено');
+ talker.critical('Хьюстон, у нас проблема!');
+ talker.error('Сервис недоступен');
+}
+```
+
+::: tip Почему TalkerFlutter.init()?
+Большинство Flutter-пакетов для логирования либо обрезают сообщения в консоли, либо не могут отображать цветные сообщения на iOS. `TalkerFlutter.init()` использует оптимальный метод для каждой платформы:
+- **Web** — `print()`
+- **iOS / macOS** — `dart:developer.log`
+- **Android / Windows / Linux** — `debugPrint`
+:::
+
+## Просмотр логов в приложении
+
+Используйте `TalkerScreen` для просмотра логов прямо в приложении:
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+## HTTP-логирование
+
+Если вы используете Dio, добавьте логирование одной строкой:
+
+```dart
+final dio = Dio();
+dio.interceptors.add(TalkerDioLogger(talker: talker));
+```
+
+## Что дальше?
+
+- Узнайте о [возможностях Talker](/ru/packages/talker) — кастомные логи, цвета, заголовки, observer
+- Изучите [Flutter-виджеты](/ru/packages/talker-flutter) — TalkerScreen, TalkerMonitor, TalkerWrapper
+- Настройте [интеграции](/ru/integrations/dio) — Dio, BLoC, Riverpod и другие
+- Прочитайте [руководства](/ru/guides/custom-logs) — пользовательские типы логов, интеграция с Crashlytics
diff --git a/website/docs/ru/getting-started/why-talker.md b/website/docs/ru/getting-started/why-talker.md
new file mode 100644
index 00000000..d6a7aa99
--- /dev/null
+++ b/website/docs/ru/getting-started/why-talker.md
@@ -0,0 +1,69 @@
+# Почему Talker?
+
+## Проблема
+
+При разработке Dart и Flutter приложений вам нужно:
+
+- **Понимать, где возникают ошибки** — как можно быстрее
+- **Логировать действия приложения** — HTTP-запросы, изменения состояний, навигацию
+- **Обрабатывать исключения корректно** — без крашей приложения
+- **Делиться отчётами об ошибках** — с командой или сервисами крэш-репортинга
+- **Отлаживать на реальных устройствах** — когда консоль недоступна
+
+Большинство существующих решений для логирования покрывают лишь часть этих задач. В итоге вы получаете разрозненные инструменты, несогласованные форматы и отсутствие единого представления.
+
+## Решение
+
+Talker предоставляет **единую систему** для логирования и обработки ошибок в вашем приложении:
+
+### Единое логирование
+
+Один API для всего — от простых отладочных сообщений до HTTP-запросов и событий state management. Все логи имеют единый формат, историю и вывод.
+
+### Богатая обработка ошибок
+
+Автоматическое различение типов `Exception` и `Error`, захват `StackTrace` и маршрутизация всего через единый обработчик с `TalkerObserver`.
+
+### Flutter-first UI
+
+Встроенный `TalkerScreen` позволяет просматривать, фильтровать, искать и делиться логами прямо в приложении — консоль не нужна. `TalkerMonitor` даёт быстрый обзор состояния.
+
+### Модульные интеграции
+
+Выбирайте только то, что нужно. Каждая интеграция (Dio, BLoC, Riverpod и т.д.) — это отдельный лёгкий пакет, подключаемый к тому же экземпляру Talker.
+
+### Полная кастомизация
+
+Настраивается всё — цвета, заголовки, форматы логов, фильтры. Создавайте свои типы логов с полным контролем.
+
+## Ключевые возможности
+
+| Возможность | Talker |
+|-------------|--------|
+| Уровни логов (info, debug, warning, error, critical, verbose, good) | ✅ |
+| Цветной вывод в консоль | ✅ |
+| Пользовательские типы логов | ✅ |
+| Обработка Exception/Error со StackTrace | ✅ |
+| История логов | ✅ |
+| Просмотр логов в приложении (TalkerScreen) | ✅ |
+| Монитор статуса (TalkerMonitor) | ✅ |
+| UI-алерты об ошибках (TalkerWrapper) | ✅ |
+| Логирование навигации | ✅ |
+| HTTP-логирование для Dio | ✅ |
+| HTTP-логирование для http | ✅ |
+| Логирование BLoC | ✅ |
+| Логирование Riverpod | ✅ |
+| HTTP-логирование для Chopper | ✅ |
+| gRPC-логирование | ✅ |
+| Observer для внешних сервисов (Crashlytics, Sentry) | ✅ |
+| Оптимизированный вывод для платформ (iOS, Android, Web) | ✅ |
+| 100% покрытие тестами | ✅ |
+| Работает с любым state management | ✅ |
+
+## Совместимость
+
+- **Dart** >= 2.15
+- **Flutter** >= 3.0
+- **Платформы**: Android, iOS, Web, macOS, Windows, Linux
+- **State management**: Работает с любым — BLoC, Riverpod, Provider, GetX, MobX и т.д.
+- **Крэш-репортинг**: Firebase Crashlytics, Sentry или любое кастомное решение
diff --git a/website/docs/ru/guides/crashlytics.md b/website/docs/ru/guides/crashlytics.md
new file mode 100644
index 00000000..f87c2cf4
--- /dev/null
+++ b/website/docs/ru/guides/crashlytics.md
@@ -0,0 +1,189 @@
+# Интеграция с Crashlytics и Sentry
+
+Используйте `TalkerObserver` для отправки ошибок, исключений и логов из Talker во внешние сервисы крэш-репортинга и аналитики.
+
+## Как работает TalkerObserver
+
+`TalkerObserver` слушает все события Talker и предоставляет колбэки для каждого типа:
+
+```dart
+abstract class TalkerObserver {
+ void onError(TalkerError err) {}
+ void onException(TalkerException exception) {}
+ void onLog(TalkerDataInterface log) {}
+}
+```
+
+- **onError** — вызывается когда `talker.handle()` перехватывает `Error`
+- **onException** — вызывается когда `talker.handle()` перехватывает `Exception`
+- **onLog** — вызывается для каждого события лога
+
+## Firebase Crashlytics
+
+```dart
+import 'package:firebase_crashlytics/firebase_crashlytics.dart';
+import 'package:talker/talker.dart';
+
+class CrashlyticsTalkerObserver extends TalkerObserver {
+ CrashlyticsTalkerObserver(this.crashlytics);
+
+ final FirebaseCrashlytics crashlytics;
+
+ @override
+ void onError(TalkerError err) {
+ crashlytics.recordError(
+ err.error,
+ err.stackTrace,
+ reason: err.message,
+ fatal: err.logLevel == LogLevel.critical,
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ crashlytics.recordError(
+ exception.exception,
+ exception.stackTrace,
+ reason: exception.message,
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ // Breadcrumbs для не-ошибочных событий
+ crashlytics.log(log.generateTextMessage());
+ }
+}
+```
+
+### Настройка
+
+```dart
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ await Firebase.initializeApp();
+
+ final crashlytics = FirebaseCrashlytics.instance;
+
+ final talker = TalkerFlutter.init(
+ observer: CrashlyticsTalkerObserver(crashlytics),
+ );
+
+ // Теперь все talker.handle() автоматически отправляются в Crashlytics
+ try {
+ throw Exception('Ошибка оплаты');
+ } catch (e, st) {
+ talker.handle(e, st, 'Ошибка обработки платежа');
+ // ^ Логирование в консоль, сохранение в историю И отправка в Crashlytics
+ }
+}
+```
+
+## Sentry
+
+```dart
+import 'package:sentry_flutter/sentry_flutter.dart';
+import 'package:talker/talker.dart';
+
+class SentryTalkerObserver extends TalkerObserver {
+ @override
+ void onError(TalkerError err) {
+ Sentry.captureException(
+ err.error,
+ stackTrace: err.stackTrace,
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ Sentry.captureException(
+ exception.exception,
+ stackTrace: exception.stackTrace,
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ Sentry.addBreadcrumb(
+ Breadcrumb(
+ message: log.generateTextMessage(),
+ level: _mapLevel(log),
+ timestamp: DateTime.now(),
+ ),
+ );
+ }
+
+ SentryLevel _mapLevel(TalkerDataInterface log) {
+ if (log is TalkerError || log is TalkerException) {
+ return SentryLevel.error;
+ }
+ return SentryLevel.info;
+ }
+}
+```
+
+### Настройка
+
+```dart
+void main() async {
+ await SentryFlutter.init(
+ (options) {
+ options.dsn = 'YOUR_SENTRY_DSN';
+ },
+ appRunner: () {
+ final talker = TalkerFlutter.init(
+ observer: SentryTalkerObserver(),
+ );
+ runApp(MyApp(talker: talker));
+ },
+ );
+}
+```
+
+## Кастомный аналитический сервис
+
+Тот же паттерн работает для любого сервиса:
+
+```dart
+class AnalyticsTalkerObserver extends TalkerObserver {
+ AnalyticsTalkerObserver(this.analytics);
+
+ final MyAnalyticsService analytics;
+
+ @override
+ void onError(TalkerError err) {
+ analytics.trackError(
+ name: 'app_error',
+ error: err.error.toString(),
+ stackTrace: err.stackTrace?.toString(),
+ );
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ analytics.trackError(
+ name: 'app_exception',
+ error: exception.exception.toString(),
+ stackTrace: exception.stackTrace?.toString(),
+ );
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ analytics.trackEvent(
+ name: 'app_log',
+ params: {'message': log.message, 'title': log.title},
+ );
+ }
+}
+```
+
+## Лучшие практики
+
+1. **Не блокируйте основной поток** — SDK крэш-репортинга обрабатывают это внутренне, но будьте внимательны с тяжёлой обработкой в `onLog`.
+
+2. **Используйте уровни логов разумно** — отправляйте только `error` и `critical` в Crashlytics, используйте `onLog` для breadcrumbs.
+
+3. **Комбинируйте с TalkerWrapper** — показывайте ошибки пользователям через SnackBar, одновременно отправляя в крэш-сервис.
+
+4. **Тестируйте observer** — пишите юнит-тесты, чтобы убедиться, что observer вызывается корректно.
diff --git a/website/docs/ru/guides/custom-error-messages.md b/website/docs/ru/guides/custom-error-messages.md
new file mode 100644
index 00000000..642d8db3
--- /dev/null
+++ b/website/docs/ru/guides/custom-error-messages.md
@@ -0,0 +1,158 @@
+# Кастомные сообщения об ошибках
+
+Показывайте user-friendly алерты и кастомные сообщения в Flutter-приложении с помощью виджетов Talker.
+
+## TalkerWrapper
+
+Самый простой способ показать алерты об ошибках. Оберните приложение (или поддерево) в `TalkerWrapper`:
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ enableExceptionAlerts: true,
+ ),
+ child: MaterialApp(
+ home: HomeScreen(),
+ ),
+)
+```
+
+Теперь при каждом вызове `talker.handle()` с исключением или ошибкой автоматически появится SnackBar внизу экрана.
+
+## TalkerListener
+
+Для большего контроля используйте `TalkerListener`:
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ if (data is TalkerException) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Ошибка: ${data.displayMessage}'),
+ backgroundColor: Colors.red,
+ action: SnackBarAction(
+ label: 'Подробнее',
+ textColor: Colors.white,
+ onPressed: () {
+ Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (_) => TalkerScreen(talker: talker),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## TalkerBuilder
+
+Реактивно стройте UI на основе логов:
+
+```dart
+TalkerBuilder(
+ talker: talker,
+ builder: (context, data) {
+ final errors = data.whereType().toList();
+ final exceptions = data.whereType().toList();
+
+ if (errors.isEmpty && exceptions.isEmpty) {
+ return const SizedBox.shrink();
+ }
+
+ return Container(
+ padding: const EdgeInsets.all(8),
+ color: Colors.red.shade100,
+ child: Text(
+ '${errors.length + exceptions.length} ошибок произошло',
+ style: const TextStyle(color: Colors.red),
+ ),
+ );
+ },
+)
+```
+
+## Диалог для критических ошибок
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ if (data is TalkerError && data.logLevel == LogLevel.critical) {
+ showDialog(
+ context: context,
+ builder: (_) => AlertDialog(
+ title: const Text('Критическая ошибка'),
+ content: Text(data.displayMessage),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(context),
+ child: const Text('OK'),
+ ),
+ TextButton(
+ onPressed: () {
+ Navigator.pop(context);
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => TalkerScreen(talker: talker),
+ ),
+ );
+ },
+ child: const Text('Просмотр логов'),
+ ),
+ ],
+ ),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## Комбинация с Crashlytics
+
+Используйте `TalkerWrapper` для алертов пользователю И `TalkerObserver` для крэш-репортинга одновременно:
+
+```dart
+final talker = TalkerFlutter.init(
+ observer: CrashlyticsTalkerObserver(FirebaseCrashlytics.instance),
+);
+
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ enableExceptionAlerts: true,
+ ),
+ child: MaterialApp(home: HomeScreen()),
+)
+```
+
+Теперь каждая ошибка:
+1. Логируется в консоль
+2. Сохраняется в историю
+3. Показывается пользователю как SnackBar
+4. Отправляется в Crashlytics
+
+## Лучшие практики
+
+1. **Не показывайте технические детали** — используйте `displayMessage` или создавайте понятные сообщения.
+
+2. **Используйте TalkerWrapper для разработки** — быстрый способ видеть ошибки. Замените на кастомный UI для продакшена.
+
+3. **Предлагайте «Просмотр логов»** — позвольте тестировщикам открыть `TalkerScreen` из алертов.
+
+4. **Ограничивайте частоту алертов** — при массовых ошибках используйте debounce, чтобы не засыпать пользователя SnackBar-ами.
diff --git a/website/docs/ru/guides/custom-logs.md b/website/docs/ru/guides/custom-logs.md
new file mode 100644
index 00000000..6116927e
--- /dev/null
+++ b/website/docs/ru/guides/custom-logs.md
@@ -0,0 +1,172 @@
+# Пользовательские типы логов
+
+Talker позволяет создавать собственные типы логов с полным контролем над внешним видом, форматом вывода и категоризацией.
+
+## Зачем свои логи?
+
+Встроенные типы логов (`info`, `debug`, `warning` и т.д.) покрывают большинство случаев. Но когда нужны доменно-специфичные логи — аналитические события, бизнес-правила или кастомные форматы HTTP — можно определить свои.
+
+## Создание пользовательского лога
+
+Расширьте класс `TalkerLog`:
+
+```dart
+import 'package:talker/talker.dart';
+
+class AnalyticsLog extends TalkerLog {
+ AnalyticsLog(String event, this.params) : super(event);
+
+ final Map params;
+
+ /// Уникальный ключ для этого типа лога
+ @override
+ String get key => 'analytics';
+
+ /// Заголовок в консоли и TalkerScreen
+ @override
+ String get title => 'ANALYTICS';
+
+ /// Цвет в консоли
+ @override
+ AnsiPen get pen => AnsiPen()..magenta();
+
+ /// Полный формат сообщения
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ return '${super.generateTextMessage(timeFormat: timeFormat)}\n'
+ 'Event: $message\n'
+ 'Params: $params';
+ }
+}
+```
+
+## Использование
+
+Используйте `logCustom()` для отправки пользовательского лога:
+
+```dart
+final talker = Talker();
+
+talker.logCustom(
+ AnalyticsLog('user_login', {'method': 'google', 'first_time': true}),
+);
+```
+
+Это:
+- Выведет цветное сообщение в консоль с заголовком `ANALYTICS`
+- Сохранит лог в истории Talker
+- Покажет в `TalkerScreen`
+- Передаст через `talker.stream`
+- Вызовет `TalkerObserver.onLog()`
+
+## Регистрация кастомных ключей
+
+Для использования кастомных цветов и заголовков через `TalkerSettings`:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ colors: {
+ 'analytics': AnsiPen()..magenta(),
+ },
+ titles: {
+ 'analytics': 'ANALYTICS',
+ },
+ ),
+);
+```
+
+::: tip
+Цвета и заголовки из настроек имеют приоритет над геттерами `pen` и `title` самого лога, что позволяет переопределять их без изменения класса.
+:::
+
+## Примеры из практики
+
+### Лог бизнес-события
+
+```dart
+class BusinessEventLog extends TalkerLog {
+ BusinessEventLog(String eventName, {this.revenue, this.userId})
+ : super(eventName);
+
+ final double? revenue;
+ final String? userId;
+
+ @override
+ String get key => 'business_event';
+
+ @override
+ String get title => 'BUSINESS';
+
+ @override
+ AnsiPen get pen => AnsiPen()..xterm(220); // Золотой
+
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ var msg = super.generateTextMessage(timeFormat: timeFormat);
+ if (revenue != null) msg += '\nВыручка: \$${revenue!.toStringAsFixed(2)}';
+ if (userId != null) msg += '\nПользователь: $userId';
+ return msg;
+ }
+}
+
+talker.logCustom(
+ BusinessEventLog('purchase_completed', revenue: 29.99, userId: 'usr_123'),
+);
+```
+
+### Лог SQL-запроса
+
+```dart
+class DbQueryLog extends TalkerLog {
+ DbQueryLog(String query, this.duration) : super(query);
+
+ final Duration duration;
+
+ @override
+ String get key => 'db_query';
+
+ @override
+ String get title => 'DB';
+
+ @override
+ AnsiPen get pen => duration.inMilliseconds > 1000
+ ? (AnsiPen()..red()) // Медленный запрос
+ : (AnsiPen()..green()); // Нормальный
+
+ @override
+ String generateTextMessage({TimeFormat? timeFormat}) {
+ return '${super.generateTextMessage(timeFormat: timeFormat)}\n'
+ 'Запрос: $message\n'
+ 'Длительность: ${duration.inMilliseconds}мс';
+ }
+}
+```
+
+## Фильтрация
+
+Пользовательские логи фильтруются так же, как встроенные:
+
+```dart
+final talker = Talker(
+ filter: BaseTalkerFilter(
+ titles: ['ANALYTICS', 'DB'],
+ ),
+);
+```
+
+## Отображение в TalkerScreen
+
+Цвет в Flutter UI можно настроить через `TalkerScreenTheme`:
+
+```dart
+TalkerScreen(
+ talker: talker,
+ theme: const TalkerScreenTheme(
+ logColors: {
+ 'analytics': Color(0xFFE040FB),
+ 'db_query': Color(0xFF4CAF50),
+ },
+ ),
+)
+```
diff --git a/website/docs/ru/guides/routing.md b/website/docs/ru/guides/routing.md
new file mode 100644
index 00000000..024c65a1
--- /dev/null
+++ b/website/docs/ru/guides/routing.md
@@ -0,0 +1,129 @@
+# Логирование маршрутов
+
+Логируйте навигационные события Flutter-приложения с `TalkerRouteObserver`. Работает с Navigator, go_router, auto_route и любым маршрутизатором, совместимым с NavigatorObserver.
+
+## Настройка
+
+### Navigator 1.0
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+MaterialApp(
+ navigatorObservers: [
+ TalkerRouteObserver(talker),
+ ],
+ home: HomeScreen(),
+)
+```
+
+### go_router
+
+```dart
+import 'package:go_router/go_router.dart';
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+final router = GoRouter(
+ observers: [TalkerRouteObserver(talker)],
+ routes: [
+ GoRoute(path: '/', builder: (_, __) => HomeScreen()),
+ GoRoute(path: '/profile', builder: (_, __) => ProfileScreen()),
+ ],
+);
+
+MaterialApp.router(routerConfig: router)
+```
+
+### auto_route v7+
+
+```dart
+import 'package:auto_route/auto_route.dart';
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+
+MaterialApp.router(
+ routerConfig: _appRouter.config(
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+)
+```
+
+### auto_route (legacy)
+
+```dart
+MaterialApp.router(
+ routerDelegate: AutoRouterDelegate(
+ appRouter,
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+ routeInformationParser: appRouter.defaultRouteParser(),
+)
+```
+
+## Что логируется
+
+`TalkerRouteObserver` логирует следующие события:
+
+| Событие | Описание | Пример |
+|---------|----------|--------|
+| **Push** | Новый маршрут добавлен в стек | `Route pushed: /profile` |
+| **Pop** | Маршрут удалён из стека | `Route popped: /profile` |
+| **Replace** | Маршрут заменён | `Route replaced: /login → /home` |
+| **Remove** | Маршрут удалён | `Route removed: /splash` |
+
+Все логи навигации отображаются в консоли, TalkerScreen и истории с фиолетовым цветом по умолчанию.
+
+## Просмотр в TalkerScreen
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+Логи маршрутов имеют цветовую маркировку и легко отличаются от других типов. Их можно фильтровать в TalkerScreen, выбрав фильтр "Route".
+
+## Кастомизация
+
+### Свой цвет маршрутов
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ colors: {
+ TalkerLogType.route.key: AnsiPen()..cyan(),
+ },
+ ),
+);
+```
+
+### Свой заголовок
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ titles: {
+ TalkerLogType.route.key: 'NAV',
+ },
+ ),
+);
+```
+
+## Лучшие практики
+
+1. **Используйте один экземпляр Talker** во всём приложении — логи маршрутов, HTTP, BLoC-событий и ошибок в одном месте.
+
+2. **Комбинируйте с TalkerScreen** — добавьте кнопку отладки или жест встряхивания для открытия `TalkerScreen` и просмотра полной истории навигации.
+
+3. **Используйте с Crashlytics** — логи маршрутов — отличные breadcrumbs для отчётов о крэшах.
diff --git a/website/docs/ru/index.md b/website/docs/ru/index.md
new file mode 100644
index 00000000..eb077781
--- /dev/null
+++ b/website/docs/ru/index.md
@@ -0,0 +1,222 @@
+---
+layout: home
+
+hero:
+ name: Talker
+ text: Продвинутый обработчик ошибок и логгер
+ tagline: Логируйте действия приложения, перехватывайте ошибки, показывайте алерты и отправляйте отчёты для Dart и Flutter
+ image:
+ src: /logo.png
+ alt: Talker
+ actions:
+ - theme: brand
+ text: Начать
+ link: /ru/getting-started/installation
+ - theme: alt
+ text: GitHub
+ link: https://github.com/Frezyx/talker
+ - theme: alt
+ text: Веб-демо
+ link: https://frezyx.github.io/talker
+
+features:
+ - icon: 📝
+ title: Мощное логирование
+ details: Логи с несколькими уровнями — info, debug, warning, error, critical, verbose и good. Полная кастомизация цветов и поддержка пользовательских типов логов.
+ - icon: 🛡️
+ title: Обработка ошибок
+ details: Перехват Exception и Error с StackTrace. Отправка данных в Crashlytics, Sentry или ваш собственный сервис через TalkerObserver.
+ - icon: 📱
+ title: Flutter UI
+ details: Встроенный TalkerScreen для просмотра логов в приложении, TalkerMonitor для быстрого обзора, TalkerWrapper для алертов об ошибках и TalkerRouteObserver для навигации.
+ - icon: 🔌
+ title: Богатые интеграции
+ details: Поддержка Dio, http, BLoC, Riverpod, Chopper и gRPC из коробки. Каждая с полной кастомизацией, фильтрацией и цветами.
+ - icon: 🎨
+ title: Полная кастомизация
+ details: Свои цвета, заголовки, форматтеры и фильтры для любого типа логов. Создавайте собственные типы логов с полным контролем.
+ - icon: ✅
+ title: Готов к продакшену
+ details: 100% покрытие тестами, MIT лицензия, совместим с любым state management, работает на всех платформах — Android, iOS, Web, macOS, Windows, Linux.
+---
+
+
+
+
+
+## Попробуйте Talker прямо сейчас
+
+Поиграйтесь с Talker прямо в браузере — без установки:
+
+
+
+
+
+
+
+
+
+## Экосистема пакетов
+
+Talker спроектирован для любого уровня кастомизации — выбирайте то, что вам нужно:
+
+
+
+
+
+### [talker](https://pub.dev/packages/talker)
+
+Основной Dart-пакет для логирования и обработки ошибок. Ядро экосистемы.
+
+
+
+
+
+### [talker_flutter](https://pub.dev/packages/talker_flutter)
+
+Flutter-расширения — цветные логи, TalkerScreen, TalkerMonitor, route observer и многое другое.
+
+
+
+
+
+### [talker_logger](https://pub.dev/packages/talker_logger)
+
+Настраиваемый pretty-логгер для Dart/Flutter приложений. Может использоваться отдельно.
+
+
+
+
+
+### [talker_dio_logger](https://pub.dev/packages/talker_dio_logger)
+
+Красивое логирование HTTP запросов/ответов для Dio.
+
+
+
+
+
+### [talker_http_logger](https://pub.dev/packages/talker_http_logger)
+
+HTTP-логирование для стандартного пакета http с http_interceptor.
+
+
+
+
+
+### [talker_bloc_logger](https://pub.dev/packages/talker_bloc_logger)
+
+Логирование state management для BLoC — события, переходы, изменения состояний.
+
+
+
+
+
+### [talker_riverpod_logger](https://pub.dev/packages/talker_riverpod_logger)
+
+Логирование жизненного цикла провайдеров Riverpod — add, update, dispose, fail.
+
+
+
+
+
+### [talker_chopper_logger](https://pub.dev/packages/talker_chopper_logger)
+
+HTTP-логирование для Chopper с поддержкой curl команд.
+
+
+
+
+
+### [talker_grpc_logger](https://pub.dev/packages/talker_grpc_logger)
+
+Логирование gRPC запросов/ответов с обфускацией токенов.
+
+
+
+
+
+
diff --git a/website/docs/ru/integrations/bloc.md b/website/docs/ru/integrations/bloc.md
new file mode 100644
index 00000000..6e8295ee
--- /dev/null
+++ b/website/docs/ru/integrations/bloc.md
@@ -0,0 +1,91 @@
+# BLoC Logger
+
+
+
+Лёгкий и настраиваемый логгер [BLoC](https://pub.dev/packages/bloc) state management на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_bloc_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Установите `TalkerBlocObserver` как глобальный BLoC observer:
+
+```dart
+import 'package:talker_bloc_logger/talker_bloc_logger.dart';
+
+Bloc.observer = TalkerBlocObserver();
+```
+
+Готово! Все события BLoC, переходы, изменения состояний, создания и закрытия будут логироваться.
+
+## Использование с Talker
+
+```dart
+final talker = Talker();
+Bloc.observer = TalkerBlocObserver(talker: talker);
+```
+
+## Настройка
+
+### Переключение типов событий
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ enabled: true,
+ printEvents: true,
+ printTransitions: true,
+ printChanges: true,
+ printCreations: true,
+ printClosings: true,
+ ),
+);
+```
+
+### Обрезка данных
+
+По умолчанию выводятся полные данные. Можно обрезать:
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ printEventFullData: false,
+ printStateFullData: false,
+ ),
+);
+```
+
+### Фильтрация логов
+
+Логировать только определённые BLoC:
+
+```dart
+Bloc.observer = TalkerBlocObserver(
+ settings: TalkerBlocLoggerSettings(
+ transitionFilter: (bloc, transition) =>
+ bloc.runtimeType.toString() == 'AuthBloc',
+ eventFilter: (bloc, event) =>
+ bloc.runtimeType.toString() == 'AuthBloc',
+ ),
+);
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `enabled` | `bool` | `true` | Включить/выключить логирование |
+| `printEvents` | `bool` | `true` | Логировать события |
+| `printTransitions` | `bool` | `true` | Логировать переходы |
+| `printChanges` | `bool` | `true` | Логировать изменения состояний |
+| `printCreations` | `bool` | `true` | Логировать создания |
+| `printClosings` | `bool` | `true` | Логировать закрытия |
+| `printEventFullData` | `bool` | `true` | Полные данные событий |
+| `printStateFullData` | `bool` | `true` | Полные данные состояний |
+| `transitionFilter` | `Function?` | `null` | Фильтр переходов |
+| `eventFilter` | `Function?` | `null` | Фильтр событий |
diff --git a/website/docs/ru/integrations/chopper.md b/website/docs/ru/integrations/chopper.md
new file mode 100644
index 00000000..9e25e2e4
--- /dev/null
+++ b/website/docs/ru/integrations/chopper.md
@@ -0,0 +1,111 @@
+# Chopper Logger
+
+
+
+Лёгкий и настраиваемый HTTP-логгер для [Chopper](https://pub.dev/packages/chopper) на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_chopper_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Добавьте `TalkerChopperLogger` как интерцептор Chopper:
+
+```dart
+import 'package:talker_chopper_logger/talker_chopper_logger.dart';
+
+final chopper = ChopperClient(
+ baseUrl: Uri.parse('https://api.example.com'),
+ interceptors: [
+ TalkerChopperLogger(
+ settings: const TalkerChopperLoggerSettings(),
+ ),
+ ],
+);
+```
+
+## Использование с Talker
+
+```dart
+final talker = Talker();
+final chopper = ChopperClient(
+ interceptors: [
+ TalkerChopperLogger(talker: talker),
+ ],
+);
+```
+
+## Настройка
+
+### Переключение логирования запросов/ответов
+
+```dart
+TalkerChopperLoggerSettings(
+ printRequestData: true,
+ printRequestHeaders: true,
+ printResponseData: true,
+ printResponseHeaders: true,
+)
+```
+
+### Вывод curl-команды
+
+```dart
+TalkerChopperLoggerSettings(
+ printRequestCurl: true,
+)
+```
+
+### Скрытие конфиденциальных заголовков
+
+```dart
+TalkerChopperLoggerSettings(
+ hiddenHeaders: {
+ 'authorization',
+ 'cookie',
+ 'x-api-key',
+ },
+)
+```
+
+### Пользовательские цвета
+
+```dart
+TalkerChopperLoggerSettings(
+ requestPen: AnsiPen()..cyan(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Фильтрация
+
+```dart
+TalkerChopperLoggerSettings(
+ requestFilter: (request) =>
+ !request.url.path.contains('/health'),
+ responseFilter: (response) =>
+ response.statusCode != 304,
+)
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `printRequestData` | `bool` | `true` | Выводить тело запроса |
+| `printResponseData` | `bool` | `true` | Выводить тело ответа |
+| `printRequestHeaders` | `bool` | `false` | Выводить заголовки запроса |
+| `printResponseHeaders` | `bool` | `false` | Выводить заголовки ответа |
+| `printResponseMessage` | `bool` | `true` | Выводить статус ответа |
+| `printRequestCurl` | `bool` | `false` | Выводить curl-команду |
+| `hiddenHeaders` | `Set` | `{}` | Скрытые заголовки |
+| `requestPen` | `AnsiPen?` | розовый | Цвет запросов |
+| `responsePen` | `AnsiPen?` | зелёный | Цвет ответов |
+| `errorPen` | `AnsiPen?` | красный | Цвет ошибок |
+| `requestFilter` | `Function?` | `null` | Фильтр запросов |
+| `responseFilter` | `Function?` | `null` | Фильтр ответов |
diff --git a/website/docs/ru/integrations/dio.md b/website/docs/ru/integrations/dio.md
new file mode 100644
index 00000000..d4c3a59e
--- /dev/null
+++ b/website/docs/ru/integrations/dio.md
@@ -0,0 +1,94 @@
+# Dio Logger
+
+
+
+Лёгкий и настраиваемый HTTP-логгер для [Dio](https://pub.dev/packages/dio) на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_dio_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Добавьте `TalkerDioLogger` в интерцепторы Dio:
+
+```dart
+import 'package:talker_dio_logger/talker_dio_logger.dart';
+
+final dio = Dio();
+dio.interceptors.add(
+ TalkerDioLogger(
+ settings: const TalkerDioLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ printResponseMessage: true,
+ ),
+ ),
+);
+```
+
+## Использование с Talker
+
+Передайте существующий экземпляр Talker для объединения всех логов:
+
+```dart
+final talker = Talker();
+final dio = Dio();
+dio.interceptors.add(TalkerDioLogger(talker: talker));
+```
+
+Теперь все HTTP-логи будут отображаться в `TalkerScreen`, истории и stream наряду с остальными логами.
+
+## Настройка
+
+### Переключение логирования запросов/ответов
+
+```dart
+TalkerDioLoggerSettings(
+ printResponseData: true,
+ printRequestData: false,
+ printResponseHeaders: true,
+ printRequestHeaders: false,
+)
+```
+
+### Пользовательские цвета
+
+```dart
+TalkerDioLoggerSettings(
+ requestPen: AnsiPen()..blue(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Фильтрация
+
+Логировать только определённые запросы/ответы:
+
+```dart
+TalkerDioLoggerSettings(
+ requestFilter: (RequestOptions options) =>
+ !options.path.contains('/secure'),
+ responseFilter: (response) =>
+ response.statusCode != 301,
+)
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `printRequestData` | `bool` | `true` | Выводить тело запроса |
+| `printResponseData` | `bool` | `true` | Выводить тело ответа |
+| `printRequestHeaders` | `bool` | `false` | Выводить заголовки запроса |
+| `printResponseHeaders` | `bool` | `false` | Выводить заголовки ответа |
+| `printResponseMessage` | `bool` | `true` | Выводить статус ответа |
+| `requestPen` | `AnsiPen?` | розовый | Цвет запросов в консоли |
+| `responsePen` | `AnsiPen?` | зелёный | Цвет ответов в консоли |
+| `errorPen` | `AnsiPen?` | красный | Цвет ошибок в консоли |
+| `requestFilter` | `Function?` | `null` | Фильтр запросов |
+| `responseFilter` | `Function?` | `null` | Фильтр ответов |
diff --git a/website/docs/ru/integrations/grpc.md b/website/docs/ru/integrations/grpc.md
new file mode 100644
index 00000000..314701d7
--- /dev/null
+++ b/website/docs/ru/integrations/grpc.md
@@ -0,0 +1,95 @@
+# gRPC Logger
+
+
+
+Лёгкий и настраиваемый [gRPC](https://pub.dev/packages/grpc) логгер на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_grpc_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Добавьте `TalkerGrpcLogger` как gRPC-интерцептор:
+
+```dart
+import 'package:talker_grpc_logger/talker_grpc_logger.dart';
+
+final channel = ClientChannel(
+ 'localhost',
+ port: 50051,
+ options: ChannelOptions(
+ credentials: const ChannelCredentials.insecure(),
+ ),
+);
+
+final client = YourServiceClient(
+ channel,
+ interceptors: [TalkerGrpcLogger()],
+);
+```
+
+## Использование с Talker
+
+```dart
+final talker = Talker();
+final client = YourServiceClient(
+ channel,
+ interceptors: [
+ TalkerGrpcLogger(talker: talker),
+ ],
+);
+```
+
+## Настройка
+
+### Обфускация токенов
+
+gRPC-метаданные часто содержат конфиденциальные токены. Talker может их обфусцировать:
+
+```dart
+TalkerGrpcLogger(
+ settings: TalkerGrpcLoggerSettings(
+ // Токен будет отображаться как "eyJh***" вместо полного значения
+ printRequestHeaders: true,
+ hideTokens: true,
+ ),
+)
+```
+
+### Переключение логирования запросов/ответов
+
+```dart
+TalkerGrpcLoggerSettings(
+ printRequestData: true,
+ printResponseData: true,
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+)
+```
+
+### Пользовательские цвета
+
+```dart
+TalkerGrpcLoggerSettings(
+ requestPen: AnsiPen()..cyan(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `printRequestData` | `bool` | `true` | Выводить данные запроса |
+| `printResponseData` | `bool` | `true` | Выводить данные ответа |
+| `printRequestHeaders` | `bool` | `false` | Выводить метаданные запроса |
+| `printResponseHeaders` | `bool` | `false` | Выводить трейлеры ответа |
+| `hideTokens` | `bool` | `false` | Обфусцировать токены |
+| `requestPen` | `AnsiPen?` | розовый | Цвет запросов |
+| `responsePen` | `AnsiPen?` | зелёный | Цвет ответов |
+| `errorPen` | `AnsiPen?` | красный | Цвет ошибок |
diff --git a/website/docs/ru/integrations/http.md b/website/docs/ru/integrations/http.md
new file mode 100644
index 00000000..81b0d654
--- /dev/null
+++ b/website/docs/ru/integrations/http.md
@@ -0,0 +1,106 @@
+# HTTP Logger
+
+
+
+Лёгкий HTTP-логгер для [http_interceptor](https://pub.dev/packages/http_interceptor) на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_http_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Добавьте `TalkerHttpLogger` в `InterceptedClient`:
+
+```dart
+import 'package:http_interceptor/http_interceptor.dart';
+import 'package:talker_http_logger/talker_http_logger.dart';
+
+void main() async {
+ final client = InterceptedClient.build(interceptors: [
+ TalkerHttpLogger(
+ settings: const TalkerHttpLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ ),
+ ),
+ ]);
+
+ await client.get("https://google.com".toUri());
+}
+```
+
+## Использование с Talker
+
+```dart
+final talker = Talker();
+final client = InterceptedClient.build(
+ interceptors: [
+ TalkerHttpLogger(talker: talker),
+ ],
+);
+```
+
+## Настройка
+
+### Вывод curl-команды
+
+```dart
+TalkerHttpLoggerSettings(
+ printRequestCurl: true,
+)
+```
+
+### Скрытие конфиденциальных заголовков
+
+```dart
+TalkerHttpLoggerSettings(
+ printRequestHeaders: true,
+ printResponseHeaders: true,
+ hiddenHeaders: {
+ 'authorization',
+ 'cookie',
+ },
+)
+```
+
+### Пользовательские цвета
+
+```dart
+TalkerHttpLoggerSettings(
+ requestPen: AnsiPen()..blue(),
+ responsePen: AnsiPen()..green(),
+ errorPen: AnsiPen()..red(),
+)
+```
+
+### Фильтрация
+
+```dart
+TalkerHttpLoggerSettings(
+ requestFilter: (Request request) =>
+ !request.url.path.contains('/secure'),
+ responseFilter: (Response response) =>
+ response.statusCode != 301,
+)
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `printRequestData` | `bool` | `true` | Выводить тело запроса |
+| `printResponseData` | `bool` | `true` | Выводить тело ответа |
+| `printRequestHeaders` | `bool` | `false` | Выводить заголовки запроса |
+| `printResponseHeaders` | `bool` | `false` | Выводить заголовки ответа |
+| `printResponseMessage` | `bool` | `true` | Выводить статус ответа |
+| `printRequestCurl` | `bool` | `false` | Выводить curl-команду |
+| `hiddenHeaders` | `Set` | `{}` | Скрытые заголовки |
+| `requestPen` | `AnsiPen?` | розовый | Цвет запросов |
+| `responsePen` | `AnsiPen?` | зелёный | Цвет ответов |
+| `errorPen` | `AnsiPen?` | красный | Цвет ошибок |
+| `requestFilter` | `Function?` | `null` | Фильтр запросов |
+| `responseFilter` | `Function?` | `null` | Фильтр ответов |
diff --git a/website/docs/ru/integrations/riverpod.md b/website/docs/ru/integrations/riverpod.md
new file mode 100644
index 00000000..1aa350ce
--- /dev/null
+++ b/website/docs/ru/integrations/riverpod.md
@@ -0,0 +1,91 @@
+# Riverpod Logger
+
+
+
+Лёгкий и настраиваемый логгер [Riverpod](https://pub.dev/packages/riverpod) state management на базе Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_riverpod_logger: ^5.1.13
+```
+
+## Базовое использование
+
+Добавьте `TalkerRiverpodObserver` в `ProviderScope`:
+
+```dart
+import 'package:talker_riverpod_logger/talker_riverpod_logger.dart';
+
+runApp(
+ ProviderScope(
+ observers: [TalkerRiverpodObserver()],
+ child: MyApp(),
+ ),
+);
+```
+
+Все события жизненного цикла провайдеров — add, update, dispose и fail — будут логироваться автоматически.
+
+## Использование с Talker
+
+```dart
+final talker = Talker();
+
+runApp(
+ ProviderScope(
+ observers: [TalkerRiverpodObserver(talker: talker)],
+ child: MyApp(),
+ ),
+);
+```
+
+## Настройка
+
+### Переключение типов событий
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ enabled: true,
+ printProviderAdded: true,
+ printProviderUpdated: true,
+ printProviderDisposed: true,
+ printProviderFailed: true,
+ ),
+)
+```
+
+### Обрезка данных
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ printStateFullData: false,
+ ),
+)
+```
+
+### Фильтрация логов
+
+```dart
+TalkerRiverpodObserver(
+ settings: TalkerRiverpodLoggerSettings(
+ providerFilter: (provider) =>
+ provider.name?.contains('auth') ?? false,
+ ),
+)
+```
+
+## Справка по настройкам
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `enabled` | `bool` | `true` | Включить/выключить логирование |
+| `printProviderAdded` | `bool` | `true` | Логировать добавление провайдеров |
+| `printProviderUpdated` | `bool` | `true` | Логировать обновление провайдеров |
+| `printProviderDisposed` | `bool` | `true` | Логировать удаление провайдеров |
+| `printProviderFailed` | `bool` | `true` | Логировать ошибки провайдеров |
+| `printStateFullData` | `bool` | `true` | Полные данные состояний |
+| `providerFilter` | `Function?` | `null` | Фильтр провайдеров |
diff --git a/website/docs/ru/packages/talker-flutter.md b/website/docs/ru/packages/talker-flutter.md
new file mode 100644
index 00000000..438e468d
--- /dev/null
+++ b/website/docs/ru/packages/talker-flutter.md
@@ -0,0 +1,190 @@
+# talker_flutter
+
+
+
+Flutter-расширения для Talker — цветные логи, просмотр логов в приложении, алерты об ошибках, observer навигации и многое другое.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_flutter: ^5.1.13
+```
+
+## Настройка
+
+```dart
+import 'package:talker_flutter/talker_flutter.dart';
+
+final talker = TalkerFlutter.init();
+```
+
+::: tip Почему TalkerFlutter.init()?
+Этот метод использует оптимальный способ вывода для каждой платформы:
+- **Web** — `print()`
+- **iOS / macOS** — `dart:developer.log` (сохраняет цвета)
+- **Android / Windows / Linux** — `debugPrint` (не обрезает сообщения)
+:::
+
+## TalkerScreen
+
+Полнофункциональный виджет просмотра логов. Просматривайте, фильтруйте, ищите и делитесь логами прямо в приложении.
+
+```dart
+Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (context) => TalkerScreen(talker: talker),
+ ),
+);
+```
+
+### Параметры TalkerScreen
+
+| Параметр | Тип | По умолч. | Описание |
+|----------|-----|-----------|----------|
+| `talker` | `Talker` | _обязат._ | Экземпляр Talker для отображения |
+| `theme` | `TalkerScreenTheme` | `TalkerScreenTheme()` | Тема оформления |
+| `appBarTitle` | `String` | `'Talker'` | Заголовок AppBar |
+| `appBarLeading` | `Widget?` | `null` | Ведущий виджет AppBar |
+| `itemsBuilder` | `TalkerDataBuilder?` | `null` | Кастомный билдер карточек |
+| `isLogsExpanded` | `bool` | `true` | Логи развёрнуты по умолчанию |
+| `isLogOrderReversed` | `bool` | `true` | Новые логи сверху |
+
+### Кастомные цвета темы
+
+```dart
+TalkerScreen(
+ talker: talker,
+ theme: const TalkerScreenTheme(
+ logColors: {
+ TalkerLogType.httpResponse.key: Color(0xFF26FF3C),
+ TalkerLogType.error.key: Colors.redAccent,
+ TalkerLogType.info.key: Color.fromARGB(255, 0, 255, 247),
+ 'custom_log_key': Colors.green,
+ },
+ ),
+)
+```
+
+## TalkerView
+
+То же, что TalkerScreen, но без `Scaffold` — для встраивания в свои layout-ы:
+
+```dart
+Scaffold(
+ appBar: AppBar(title: Text('Мой экран')),
+ body: TalkerView(
+ talker: talker,
+ theme: const TalkerScreenTheme(),
+ ),
+)
+```
+
+## TalkerMonitor
+
+Быстрый обзор статуса — количество HTTP-запросов, исключений, ошибок, предупреждений и т.д. Доступен из настроек `TalkerScreen`.
+
+## TalkerWrapper
+
+Автоматические алерты об ошибках в UI:
+
+```dart
+TalkerWrapper(
+ talker: talker,
+ options: const TalkerWrapperOptions(
+ enableErrorAlerts: true,
+ ),
+ child: MyApp(),
+)
+```
+
+## TalkerListener
+
+Слушайте события Talker в дереве виджетов:
+
+```dart
+TalkerListener(
+ talker: talker,
+ listener: (data) {
+ if (data is TalkerException || data is TalkerError) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text(data.displayMessage)),
+ );
+ }
+ },
+ child: MyApp(),
+)
+```
+
+## TalkerBuilder
+
+Реактивно стройте UI на основе логов:
+
+```dart
+TalkerBuilder(
+ talker: talker,
+ builder: (context, data) {
+ return ListView.builder(
+ itemCount: data.length,
+ itemBuilder: (context, index) {
+ return ListTile(title: Text(data[index].message));
+ },
+ );
+ },
+)
+```
+
+## TalkerRouteObserver
+
+Логируйте события навигации. Работает с любым пакетом маршрутизации.
+
+### Navigator
+
+```dart
+MaterialApp(
+ navigatorObservers: [
+ TalkerRouteObserver(talker),
+ ],
+)
+```
+
+### go_router
+
+```dart
+GoRouter(
+ observers: [TalkerRouteObserver(talker)],
+)
+```
+
+### auto_route v7+
+
+```dart
+MaterialApp.router(
+ routerConfig: _appRouter.config(
+ navigatorObservers: () => [
+ TalkerRouteObserver(talker),
+ ],
+ ),
+)
+```
+
+Подробнее в руководстве [Логирование маршрутов](/ru/guides/routing).
+
+## runTalkerZonedGuarded
+
+Перехват всех неперехваченных ошибок:
+
+```dart
+void main() {
+ final talker = TalkerFlutter.init();
+
+ runTalkerZonedGuarded(
+ talker,
+ () => runApp(MyApp()),
+ );
+}
+```
+
+## Справка по API
+
+Полная документация API доступна на [pub.dev](https://pub.dev/documentation/talker_flutter/latest/).
diff --git a/website/docs/ru/packages/talker-logger.md b/website/docs/ru/packages/talker-logger.md
new file mode 100644
index 00000000..5b46c6cb
--- /dev/null
+++ b/website/docs/ru/packages/talker-logger.md
@@ -0,0 +1,121 @@
+# talker_logger
+
+
+
+Настраиваемый pretty-логгер для Dart/Flutter приложений. Может использоваться как самостоятельный пакет или как часть экосистемы Talker.
+
+## Установка
+
+```yaml
+dependencies:
+ talker_logger: ^5.1.13
+```
+
+## Базовое использование
+
+```dart
+import 'package:talker_logger/talker_logger.dart';
+
+final logger = TalkerLogger();
+
+logger.debug('debug');
+logger.info('info');
+logger.warning('warning');
+logger.error('error');
+logger.critical('critical');
+logger.good('good');
+logger.verbose('verbose');
+```
+
+## Произвольный уровень лога
+
+```dart
+logger.log('сообщение', level: LogLevel.info);
+logger.log('цветной лог', pen: AnsiPen()..xterm(49));
+```
+
+## Уровни логов
+
+| Уровень | Описание |
+|---------|----------|
+| `LogLevel.critical` | Критические ошибки, требующие немедленного внимания |
+| `LogLevel.error` | Ошибки выполнения |
+| `LogLevel.warning` | Потенциальные проблемы |
+| `LogLevel.info` | Информационные сообщения |
+| `LogLevel.debug` | Отладочная информация |
+| `LogLevel.verbose` | Детальная информация трассировки |
+| `LogLevel.good` | Позитивные статусные сообщения |
+
+## Фильтрация
+
+Фильтруйте логи, установив минимальный уровень:
+
+```dart
+final logger = TalkerLogger(
+ settings: const TalkerLoggerSettings(
+ level: LogLevel.critical,
+ ),
+);
+
+// Это будет выведено
+logger.critical('критическая ошибка');
+
+// Это НЕ будет выведено (уровень ниже critical)
+logger.info('информационное сообщение');
+```
+
+## Пользовательское форматирование
+
+### Настройка встроенного форматтера
+
+```dart
+final logger = TalkerLogger(
+ settings: TalkerLoggerSettings(
+ colors: {
+ LogLevel.critical: AnsiPen()..yellow(),
+ LogLevel.error: AnsiPen()..yellow(),
+ LogLevel.info: AnsiPen()..yellow(),
+ },
+ maxLineWidth: 20,
+ lineSymbol: '#',
+ enableColors: true,
+ ),
+);
+```
+
+### Свой форматтер
+
+Реализуйте собственный `LoggerFormatter`:
+
+```dart
+class ColoredLoggerFormatter implements LoggerFormatter {
+ @override
+ String fmt(LogDetails details, TalkerLoggerSettings settings) {
+ final msg = details.message?.toString() ?? '';
+ final coloredMsg = msg
+ .split('\n')
+ .map((e) => details.pen.write(e))
+ .toList()
+ .join('\n');
+ return coloredMsg;
+ }
+}
+
+final logger = TalkerLogger(
+ formatter: ColoredLoggerFormatter(),
+);
+```
+
+## Настройки TalkerLoggerSettings
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `level` | `LogLevel` | `LogLevel.verbose` | Минимальный уровень для вывода |
+| `enableColors` | `bool` | `true` | Использовать ANSI-цвета |
+| `maxLineWidth` | `int` | `110` | Максимальная ширина линий-разделителей |
+| `lineSymbol` | `String` | `'─'` | Символ для линий-разделителей |
+| `colors` | `Map` | _(по умолч.)_ | Цвета для каждого уровня |
+
+## Справка по API
+
+Полная документация API доступна на [pub.dev](https://pub.dev/documentation/talker_logger/latest/).
diff --git a/website/docs/ru/packages/talker.md b/website/docs/ru/packages/talker.md
new file mode 100644
index 00000000..0b908141
--- /dev/null
+++ b/website/docs/ru/packages/talker.md
@@ -0,0 +1,253 @@
+# talker
+
+
+
+Основной Dart-пакет для логирования и обработки ошибок. Работает в любом Dart-проекте — серверном, CLI или Flutter.
+
+## Установка
+
+```yaml
+dependencies:
+ talker: ^5.1.13
+```
+
+## Базовое логирование
+
+```dart
+import 'package:talker/talker.dart';
+
+final talker = Talker();
+
+// Логи с разными уровнями
+talker.info('Приложение запущено');
+talker.debug('Загрузка конфигурации...');
+talker.warning('Кэш почти заполнен');
+talker.error('Не удалось сохранить файл');
+talker.critical('Соединение с БД потеряно!');
+talker.verbose('Детальная информация трассировки');
+talker.good('Операция завершена успешно!');
+```
+
+## Обработка ошибок
+
+Обрабатывайте исключения и ошибки с полной поддержкой `StackTrace`:
+
+```dart
+try {
+ throw Exception('Что-то пошло не так');
+} catch (e, st) {
+ talker.handle(e, st, 'Исключение при обработке данных');
+}
+```
+
+Метод `handle()` автоматически различает типы `Exception` и `Error`.
+
+## Продвинутое логирование
+
+Используйте метод `log()` для максимального контроля:
+
+```dart
+talker.log(
+ 'Ошибка сервера',
+ logLevel: LogLevel.critical,
+ exception: Exception('Тайм-аут соединения'),
+ stackTrace: stackTrace,
+ pen: AnsiPen()..red(),
+);
+```
+
+## TalkerSettings
+
+Настройте поведение Talker через `TalkerSettings`:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ /// Включить/выключить все процессы Talker
+ enabled: true,
+ /// Включить/выключить сохранение логов в истории
+ useHistory: true,
+ /// Максимальное количество записей в истории
+ maxHistoryItems: 1000,
+ /// Включить/выключить вывод в консоль
+ useConsoleLogs: true,
+ /// Формат времени для логов
+ timeFormat: TimeFormat.timeAndSeconds,
+ ),
+);
+```
+
+### Поля настроек
+
+| Поле | Тип | По умолч. | Описание |
+|------|-----|-----------|----------|
+| `enabled` | `bool` | `true` | Главный переключатель всех операций |
+| `useHistory` | `bool` | `true` | Сохранять логи в историю |
+| `maxHistoryItems` | `int` | `1000` | Максимум записей в истории |
+| `useConsoleLogs` | `bool` | `true` | Вывод логов в консоль |
+| `timeFormat` | `TimeFormat` | `timeAndSeconds` | Формат временных меток |
+| `titles` | `Map` | _(по умолч.)_ | Пользовательские заголовки |
+| `colors` | `Map` | _(по умолч.)_ | Пользовательские цвета |
+
+## Пользовательские цвета
+
+Задайте свой цвет для любого типа лога:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ colors: {
+ TalkerLogType.httpResponse.key: AnsiPen()..red(),
+ TalkerLogType.error.key: AnsiPen()..green(),
+ TalkerLogType.info.key: AnsiPen()..blue(),
+
+ // Пользовательские ключи
+ 'custom_log_key': AnsiPen()..yellow(),
+ },
+ ),
+);
+```
+
+### Цвета по умолчанию
+
+| Тип лога | Цвет |
+|----------|------|
+| `critical` | Красный |
+| `error` | Красный |
+| `exception` | Красный |
+| `warning` | Жёлтый |
+| `info` | Синий |
+| `debug` | Серый |
+| `verbose` | Серый |
+| `httpRequest` | Розовый (xterm 219) |
+| `httpResponse` | Зелёный (xterm 46) |
+| `httpError` | Красный |
+| `route` | Фиолетовый (xterm 135) |
+
+## Пользовательские заголовки
+
+Переопределите заголовки для любого типа лога:
+
+```dart
+final talker = Talker(
+ settings: TalkerSettings(
+ titles: {
+ TalkerLogType.exception.key: 'Что угодно',
+ TalkerLogType.error.key: 'О',
+ TalkerLogType.info.key: 'и',
+
+ // Пользовательские ключи
+ 'custom_log_key': 'Мой заголовок',
+ },
+ ),
+);
+```
+
+## Пользовательские типы логов
+
+Создайте собственный тип лога, расширив `TalkerLog`:
+
+```dart
+class HttpLog extends TalkerLog {
+ HttpLog(String super.message);
+
+ static const logKey = 'http_log';
+ static final logTitle = 'HTTP';
+ static final logPen = AnsiPen()..cyan();
+
+ @override
+ String get title => logTitle;
+
+ @override
+ String get key => logKey;
+
+ @override
+ AnsiPen get pen => logPen;
+}
+
+// Использование
+talker.logCustom(HttpLog('GET /api/users — 200 OK'));
+```
+
+Полное руководство — [Пользовательские логи](/ru/guides/custom-logs).
+
+## TalkerObserver
+
+Наблюдайте за всеми событиями Talker извне — идеально для отправки данных во внешние сервисы:
+
+```dart
+class MyTalkerObserver extends TalkerObserver {
+ @override
+ void onError(TalkerError err) {
+ // Отправить в Crashlytics, Sentry и т.д.
+ super.onError(err);
+ }
+
+ @override
+ void onException(TalkerException exception) {
+ // Отправить в сервис отслеживания ошибок
+ super.onException(exception);
+ }
+
+ @override
+ void onLog(TalkerDataInterface log) {
+ // Отправить в Grafana, бэкенд аналитики и т.д.
+ super.onLog(log);
+ }
+}
+
+final talker = Talker(observer: MyTalkerObserver());
+```
+
+См. руководство [Интеграция с Crashlytics](/ru/guides/crashlytics).
+
+## Stream
+
+Слушайте все события Talker через broadcast stream:
+
+```dart
+talker.stream.listen((data) {
+ print('Новое событие: ${data.message}');
+});
+```
+
+## История
+
+Доступ к полной истории логов:
+
+```dart
+// Получить всю историю
+final logs = talker.history;
+
+// Очистить историю
+talker.cleanHistory();
+```
+
+## Фильтрация
+
+Используйте `TalkerFilter` для выбора конкретных логов:
+
+```dart
+final talker = Talker(
+ filter: BaseTalkerFilter(
+ titles: ['error', 'exception'],
+ types: [TalkerError, TalkerException],
+ ),
+);
+```
+
+## Включение / Выключение
+
+Управляйте Talker во время выполнения:
+
+```dart
+// Остановить всё логирование и обработку ошибок
+talker.disable();
+
+// Возобновить работу
+talker.enable();
+```
+
+## Справка по API
+
+Полная документация API доступна на [pub.dev](https://pub.dev/documentation/talker/latest/).
diff --git a/website/package-lock.json b/website/package-lock.json
new file mode 100644
index 00000000..ff697aa4
--- /dev/null
+++ b/website/package-lock.json
@@ -0,0 +1,2518 @@
+{
+ "name": "talker-docs",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "talker-docs",
+ "version": "1.0.0",
+ "devDependencies": {
+ "vitepress": "^1.6.3"
+ }
+ },
+ "node_modules/@algolia/abtesting": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.15.0.tgz",
+ "integrity": "sha512-D1QZ8dQx5zC9yrxNao9ER9bojmmzUdL1i2P9waIRiwnZ5fI26YswcCd6VHR/Q4W3PASfVf2My4YQ2FhGGDewTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/autocomplete-core": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz",
+ "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.17.7",
+ "@algolia/autocomplete-shared": "1.17.7"
+ }
+ },
+ "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz",
+ "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "search-insights": ">= 1 < 3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz",
+ "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-shared": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz",
+ "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.49.0.tgz",
+ "integrity": "sha512-Q1MSRhh4Du9WeLIl1S9O+BDUMaL01uuQtmzCyEzOBtu1xBDr3wvqrTJtfEceEkA5/Nw1BdGSHa6sDT3xTAF90A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.49.0.tgz",
+ "integrity": "sha512-v50elhC80oyQw+8o8BwM+VvPuOo36+3W8VCfR4hsHoafQtGbMtP63U5eNcUydbVsM0py3JLoBaL1yKBK4L01sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.49.0.tgz",
+ "integrity": "sha512-BDmVDtpDvymfLE5YQ2cPnfWJUVTDJqwpJa03Fsb7yJFJmbeKsUOGsnRkYsTbdzf0FfcvyvBB5zdcbrAIL249bg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.49.0.tgz",
+ "integrity": "sha512-lDCXsnZDx7zQ5GzSi1EL3l07EbksjrdpMgixFRCdi2QqeBe42HIQJfPPqdWtwrAXjORRopsPx2z+gGYJP/79Uw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.49.0.tgz",
+ "integrity": "sha512-5k/KB+DsnesNKvMUEwTKSzExOf5zYbiPg7DVO7g1Y/+bhMb3wmxp9RFwfqwPfmoRTjptqvwhR6a0593tWVkmAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.49.0.tgz",
+ "integrity": "sha512-pjHNcrdjn7p3RQ5Ql1Baiwfdn9bkS+z4gqONJJP8kuZFqYP8Olthy4G7fl5bCB29UjdUj5EWlaElQKCtPluCtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.49.0.tgz",
+ "integrity": "sha512-uGv2P3lcviuaZy8ZOAyN60cZdhOVyjXwaDC27a1qdp3Pb5Azn+lLSJwkHU4TNRpphHmIei9HZuUxwQroujdPjw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.49.0.tgz",
+ "integrity": "sha512-sH10mftYlmvfGbvAgTtHYbCIstmNUdiAkX//0NAyBcJRB6NnZmNsdLxdFGbE8ZqlGXzoe0zcUIau+DxKpXtqCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.49.0.tgz",
+ "integrity": "sha512-RqhGcVVxLpK+lA0GZKywlQIXsI704flc12nv/hOdrwiuk/Uyhxs46KLM4ngip7wutU+7t0PYZWiVayrqBPN/ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.49.0.tgz",
+ "integrity": "sha512-kg8omGRvmIPhhqtUqSIpS3regFKWuoWh3WqyUhGk27N4T7q8I++8TsDYsV8vK7oBEzw706m2vUBtN5fw2fDjmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.49.0.tgz",
+ "integrity": "sha512-BaZ6NTI9VdSbDcsMucdKhTuFFxv6B+3dAZZBozX12fKopYsELh7dBLfZwm8evDCIicmNjIjobi4VNnNshrCSuw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.49.0.tgz",
+ "integrity": "sha512-2nxISxS5xO5DLAj6QzMImgJv6CqpZhJVkhcTFULESR/k4IpbkJTEHmViVTxw9MlrU8B5GfwHevFd7vKL3a7MXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.49.0.tgz",
+ "integrity": "sha512-S/B94C6piEUXGpN3y5ysmNKMEqdfNVAXYY+FxivEAV5IGJjbEuLZfT8zPPZUWGw9vh6lgP80Hye2G5aVBNIa8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@docsearch/css": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz",
+ "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz",
+ "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/react": "3.8.2",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/react": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz",
+ "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.2",
+ "algoliasearch": "^5.14.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@iconify-json/simple-icons": {
+ "version": "1.2.71",
+ "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.71.tgz",
+ "integrity": "sha512-rNoDFbq1fAYiEexBvrw613/xiUOPEu5MKVV/X8lI64AgdTzLQUUemr9f9fplxUMPoxCBP2rWzlhOEeTHk/Sf0Q==",
+ "dev": true,
+ "license": "CC0-1.0",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/@rollup/rollup-android-arm-eabi": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
+ "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
+ "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
+ "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
+ "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
+ "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
+ "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
+ "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
+ "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
+ "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
+ "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
+ "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
+ "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
+ "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
+ "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
+ "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
+ "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
+ "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
+ "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
+ "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
+ "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
+ "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
+ "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
+ "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@shikijs/core": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz",
+ "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.4"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz",
+ "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^3.1.0"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz",
+ "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz",
+ "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz",
+ "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz",
+ "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.28.tgz",
+ "integrity": "sha512-kviccYxTgoE8n6OCw96BNdYlBg2GOWfBuOW4Vqwrt7mSKWKwFVvI8egdTltqRgITGPsTFYtKYfxIG8ptX2PJHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@vue/shared": "3.5.28",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.28.tgz",
+ "integrity": "sha512-/1ZepxAb159jKR1btkefDP+J2xuWL5V3WtleRmxaT+K2Aqiek/Ab/+Ebrw2pPj0sdHO8ViAyyJWfhXXOP/+LQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.28",
+ "@vue/shared": "3.5.28"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.28.tgz",
+ "integrity": "sha512-6TnKMiNkd6u6VeVDhZn/07KhEZuBSn43Wd2No5zaP5s3xm8IqFTHBj84HJah4UepSUJTro5SoqqlOY22FKY96g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@vue/compiler-core": "3.5.28",
+ "@vue/compiler-dom": "3.5.28",
+ "@vue/compiler-ssr": "3.5.28",
+ "@vue/shared": "3.5.28",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.6",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.28.tgz",
+ "integrity": "sha512-JCq//9w1qmC6UGLWJX7RXzrGpKkroubey/ZFqTpvEIDJEKGgntuDMqkuWiZvzTzTA5h2qZvFBFHY7fAAa9475g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.28",
+ "@vue/shared": "3.5.28"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz",
+ "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.9"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz",
+ "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.9",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz",
+ "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.28.tgz",
+ "integrity": "sha512-gr5hEsxvn+RNyu9/9o1WtdYdwDjg5FgjUSBEkZWqgTKlo/fvwZ2+8W6AfKsc9YN2k/+iHYdS9vZYAhpi10kNaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.28"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.28.tgz",
+ "integrity": "sha512-POVHTdbgnrBBIpnbYU4y7pOMNlPn2QVxVzkvEA2pEgvzbelQq4ZOUxbp2oiyo+BOtiYlm8Q44wShHJoBvDPAjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.28",
+ "@vue/shared": "3.5.28"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.28.tgz",
+ "integrity": "sha512-4SXxSF8SXYMuhAIkT+eBRqOkWEfPu6nhccrzrkioA6l0boiq7sp18HCOov9qWJA5HML61kW8p/cB4MmBiG9dSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.28",
+ "@vue/runtime-core": "3.5.28",
+ "@vue/shared": "3.5.28",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.28.tgz",
+ "integrity": "sha512-pf+5ECKGj8fX95bNincbzJ6yp6nyzuLDhYZCeFxUNp8EBrQpPpQaLX3nNCp49+UbgbPun3CeVE+5CXVV1Xydfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.28",
+ "@vue/shared": "3.5.28"
+ },
+ "peerDependencies": {
+ "vue": "3.5.28"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.28.tgz",
+ "integrity": "sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vueuse/core": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz",
+ "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/integrations": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz",
+ "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vueuse/core": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz",
+ "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz",
+ "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/algoliasearch": {
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.49.0.tgz",
+ "integrity": "sha512-Tse7vx7WOvbU+kpq/L3BrBhSWTPbtMa59zIEhMn+Z2NoxZlpcCRUDCRxQ7kDFs1T3CHxDgvb+mDuILiBBpBaAA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@algolia/abtesting": "1.15.0",
+ "@algolia/client-abtesting": "5.49.0",
+ "@algolia/client-analytics": "5.49.0",
+ "@algolia/client-common": "5.49.0",
+ "@algolia/client-insights": "5.49.0",
+ "@algolia/client-personalization": "5.49.0",
+ "@algolia/client-query-suggestions": "5.49.0",
+ "@algolia/client-search": "5.49.0",
+ "@algolia/ingestion": "1.49.0",
+ "@algolia/monitoring": "1.49.0",
+ "@algolia/recommend": "5.49.0",
+ "@algolia/requester-browser-xhr": "5.49.0",
+ "@algolia/requester-fetch": "5.49.0",
+ "@algolia/requester-node-http": "5.49.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz",
+ "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/emoji-regex-xs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
+ "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/focus-trap": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz",
+ "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tabbable": "^6.4.0"
+ }
+ },
+ "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/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz",
+ "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/minisearch": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz",
+ "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/oniguruma-to-es": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz",
+ "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex-xs": "^1.0.0",
+ "regex": "^6.0.1",
+ "regex-recursion": "^6.0.2"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "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/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.28.4",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.4.tgz",
+ "integrity": "sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
+ "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-recursion": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz",
+ "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-utilities": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
+ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
+ "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
+ "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.59.0",
+ "@rollup/rollup-android-arm64": "4.59.0",
+ "@rollup/rollup-darwin-arm64": "4.59.0",
+ "@rollup/rollup-darwin-x64": "4.59.0",
+ "@rollup/rollup-freebsd-arm64": "4.59.0",
+ "@rollup/rollup-freebsd-x64": "4.59.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.59.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.59.0",
+ "@rollup/rollup-linux-arm64-musl": "4.59.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.59.0",
+ "@rollup/rollup-linux-loong64-musl": "4.59.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.59.0",
+ "@rollup/rollup-linux-ppc64-musl": "4.59.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.59.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.59.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.59.0",
+ "@rollup/rollup-linux-x64-gnu": "4.59.0",
+ "@rollup/rollup-linux-x64-musl": "4.59.0",
+ "@rollup/rollup-openbsd-x64": "4.59.0",
+ "@rollup/rollup-openharmony-arm64": "4.59.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.59.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.59.0",
+ "@rollup/rollup-win32-x64-gnu": "4.59.0",
+ "@rollup/rollup-win32-x64-msvc": "4.59.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/search-insights": {
+ "version": "2.17.3",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
+ "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/shiki": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz",
+ "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/langs": "2.5.0",
+ "@shikijs/themes": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz",
+ "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz",
+ "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz",
+ "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz",
+ "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz",
+ "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz",
+ "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz",
+ "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/css": "3.8.2",
+ "@docsearch/js": "3.8.2",
+ "@iconify-json/simple-icons": "^1.2.21",
+ "@shikijs/core": "^2.1.0",
+ "@shikijs/transformers": "^2.1.0",
+ "@shikijs/types": "^2.1.0",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.2.1",
+ "@vue/devtools-api": "^7.7.0",
+ "@vue/shared": "^3.5.13",
+ "@vueuse/core": "^12.4.0",
+ "@vueuse/integrations": "^12.4.0",
+ "focus-trap": "^7.6.4",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.1",
+ "shiki": "^2.1.0",
+ "vite": "^5.4.14",
+ "vue": "^3.5.13"
+ },
+ "bin": {
+ "vitepress": "bin/vitepress.js"
+ },
+ "peerDependencies": {
+ "markdown-it-mathjax3": "^4",
+ "postcss": "^8"
+ },
+ "peerDependenciesMeta": {
+ "markdown-it-mathjax3": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.28",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.28.tgz",
+ "integrity": "sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.28",
+ "@vue/compiler-sfc": "3.5.28",
+ "@vue/runtime-dom": "3.5.28",
+ "@vue/server-renderer": "3.5.28",
+ "@vue/shared": "3.5.28"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/website/package.json b/website/package.json
new file mode 100644
index 00000000..cdc25082
--- /dev/null
+++ b/website/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "talker-docs",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "docs:dev": "vitepress dev docs",
+ "docs:build": "vitepress build docs",
+ "docs:preview": "vitepress preview docs"
+ },
+ "devDependencies": {
+ "vitepress": "^1.6.3"
+ }
+}
diff --git a/website/public/logo.png b/website/public/logo.png
new file mode 100644
index 00000000..3f142731
Binary files /dev/null and b/website/public/logo.png differ