@cognicatch/react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CogniCatch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # 🧠 CogniCatch React
2
+
3
+ **Premium B2B React Error Boundaries & API Fallbacks powered by GenUI.**
4
+
5
+ Stop losing users to the dreaded "White Screen of Death" (WSOD) or scaring them away with raw, technical stack traces. **CogniCatch React** is a React library that intercepts runtime crashes and API failures, gracefully degrading them into elegant, accessible, and user-friendly recovery interfaces.
6
+
7
+ Powered by a **GenUI** (Generative UI) engine, it automatically analyzes error logs, sanitizes sensitive data, and generates the perfect UI fallback—all in real-time, automatically translated to your user's native language.
8
+
9
+ ---
10
+
11
+ ## 🔒 Enterprise-Grade Security & Privacy (Zero-PII)
12
+
13
+ When selling to or building for enterprises, security is non-negotiable. Our library was architected from the ground up to be fully compliant with strict data privacy laws like **GDPR, LGPD, HIPAA, and SOC2**.
14
+
15
+ We guarantee that **no user data or sensitive values ever leave the browser**:
16
+
17
+ * **Sandboxed by Design:** React Error Boundaries natively only catch the `Error` object and the component tree. They physically cannot read form inputs, component `state`, or `props`.
18
+ * **Client-Side Zero-PII Sanitizer:** Before any error log is transmitted to the AI or your backend, our aggressive redaction engine scrubs the payload directly in the browser's memory.
19
+ * **What gets redacted?** Emails, JWTs, API Keys, Bearer Tokens, Phone Numbers, Credit Cards, SSNs, and IP Addresses are instantly replaced with tags like `[EMAIL_REDACTED]` or `[JWT_REDACTED]`.
20
+ * **The Result:** The AI and your servers only receive the structural skeleton of the crash (e.g., *"Payment failed for user [EMAIL_REDACTED] using [JWT_REDACTED]"*), keeping your company safe from data leaks.
21
+
22
+ ---
23
+
24
+ ## ✨ The GenUI Engine (Auto Mode)
25
+
26
+ In traditional development, you have to manually map every possible error with a `try/catch` and hardcode generic fallback messages.
27
+
28
+ With our Auto Mode, Artificial Intelligence takes the wheel:
29
+
30
+ 1. The boundary or hook catches the crash/API failure.
31
+ 2. The Zero-PII Sanitizer scrubs the payload.
32
+ 3. The anonymized log is sent to the API, where an LLM analyzes the technical context.
33
+ 4. The AI generates an empathetic title, description, and action button **in the user's native language**.
34
+ 5. The perfectly sized interface (Banner, Toast, or Modal) is rendered dynamically to the user.
35
+
36
+ ## 🛠️ Tech Stack
37
+
38
+ * **Core:** React 18 / 19
39
+ * **Styling:** Tailwind CSS v4 (Isolated styles, won't clash with your app)
40
+ * **Accessibility:** Radix UI (100% accessible and screen-reader friendly Modals)
41
+ * **Notifications:** Sonner (High-performance, beautiful Toasts)
42
+ * **Type Safety:** TypeScript (Strict Mode)
43
+
44
+ ---
45
+
46
+ ## 📦 Installation
47
+
48
+ ```bash
49
+ npm install @cognicatch/react
50
+ # or
51
+ pnpm add @cognicatch/react
52
+ # or
53
+ yarn add @cognicatch/react
54
+ ```
55
+
56
+ Import the global styles at the root of your application (e.g., main.tsx, app.tsx, or layout.tsx):
57
+
58
+ ```typescript
59
+ import '@cognicatch/react/style.css';
60
+ ```
61
+
62
+ ## 💻 Usage
63
+
64
+ The library is designed to scale from indie open-source projects to enterprise SaaS platforms.
65
+
66
+ ### 1. Pro / SaaS Tier (Auto Mode via GenUI)
67
+
68
+ To unlock the full potential of GenUI, set up the AdaptiveProvider at the root of your application. This prevents you from prop-drilling your API key and automatically handles internationalization (i18n).
69
+
70
+ * A. Global Setup:
71
+
72
+ ```typescript
73
+ import { AdaptiveProvider, AdaptiveToastProvider } from '@cognicatch/react';
74
+
75
+ export default function App() {
76
+ return (
77
+ // Automatically detects navigator.language, or you can force a locale via the `language` prop.
78
+ <AdaptiveProvider apiKey="your_api_key_here">
79
+ <AdaptiveToastProvider />
80
+ <YourAppRoutes />
81
+ </AdaptiveProvider>
82
+ );
83
+ }
84
+ ```
85
+
86
+ * B. Catching UI Crashes (Component Errors):
87
+
88
+ Wrap fragile components. The boundary will automatically inherit the API key from the Provider.
89
+
90
+ ```typescript
91
+ import { AdaptiveErrorBoundary } from '@cognicatch/react';
92
+
93
+ export function CheckoutPage() {
94
+ return (
95
+ <AdaptiveErrorBoundary
96
+ mode="auto"
97
+ onRecover={() => console.log("User clicked to recover")}
98
+ >
99
+ <ComplexWidget />
100
+ </AdaptiveErrorBoundary>
101
+ );
102
+ }
103
+ ```
104
+
105
+ * C. Catching API Failures (Async Errors):
106
+
107
+ Use our hook to gracefully handle backend failures (e.g., `400 Bad Request` or `500 Server Error`). It sanitizes the error, sends it to the AI, and renders a Premium Toast.
108
+
109
+ ```typescript
110
+ import { useAdaptive } from '@cognicatch/react';
111
+
112
+ export function PaymentForm() {
113
+ const { captureAsyncError } = useAdaptive();
114
+
115
+ const handlePayment = async () => {
116
+ try {
117
+ await api.post('/checkout', data);
118
+ } catch (error) {
119
+ // Magically turns raw backend errors into empathetic UI Toasts
120
+ captureAsyncError(error);
121
+ }
122
+ };
123
+
124
+ return <button onClick={handlePayment}>Pay Now</button>;
125
+ }
126
+ ```
127
+
128
+ ### 2. Open Source Tier (Manual Mode)
129
+
130
+ Don't have an API key? You can still wrap fragile components to prevent a localized error from taking down the entire page. You define the severity, and the UI adapts automatically:
131
+
132
+ * low: Triggers a Toast and allows the component to attempt a re-render.
133
+
134
+ * medium: Replaces the broken component with an elegant inline Banner.
135
+
136
+ * high: Locks the screen with a Critical Modal (ideal for root-level routing errors).
137
+
138
+ ```typescript
139
+ import { AdaptiveErrorBoundary } from '@cognicatch/react';
140
+
141
+ export function Dashboard() {
142
+ return (
143
+ <AdaptiveErrorBoundary
144
+ mode="manual"
145
+ severity="medium"
146
+ title="Widget Failed"
147
+ description="We couldn't load the financial data at this moment."
148
+ actionLabel="Try Again"
149
+ onRecover={() => window.location.reload()}
150
+ >
151
+ <ComplexWidget />
152
+ </AdaptiveErrorBoundary>
153
+ );
154
+ }
155
+ ```
156
+
157
+ ### 3. The Free Swiss Army Knife (Generic Toasts)
158
+
159
+ Even if you don't use the Error Boundaries, you get a premium, white-label notification system out of the box. Assuming you added the `AdaptiveToastProvider` to your root, you can trigger beautiful toasts anywhere.
160
+
161
+ **In your Root/Layout:**
162
+
163
+ ```typescript
164
+ import { AdaptiveToastProvider } from '@cognicatch/react';
165
+
166
+ export default function App() {
167
+ return (
168
+ <>
169
+ <AdaptiveToastProvider />
170
+ <YourApp />
171
+ </>
172
+ );
173
+ }
174
+ ```
175
+
176
+ **Triggering alerts in your components:**
177
+
178
+ ```typescript
179
+ import { adaptiveToast } from '@cognicatch/react';
180
+
181
+ function handleSave() {
182
+ // Beautiful notifications with native Light/Dark mode support
183
+ adaptiveToast.success("Profile Updated", "Your changes have been saved successfully.");
184
+
185
+ // adaptiveToast.error("Connection Failed", "Please try again later.");
186
+ // adaptiveToast.warning("Warning", "Your session is about to expire.");
187
+ // adaptiveToast.info("Update Available", "A new version is ready to be installed.");
188
+ }
189
+ ```
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-purple-500:oklch(62.7% .265 303.9);--color-zinc-50:oklch(98.5% 0 0);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-zinc-950:oklch(14.1% .005 285.823);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.right-0{right:calc(var(--spacing)*0)}.bottom-0{bottom:calc(var(--spacing)*0)}.left-0{left:calc(var(--spacing)*0)}.z-50{z-index:50}.mx-auto{margin-inline:auto}.\!mt-0\.5{margin-top:calc(var(--spacing)*.5)!important}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.\!line-clamp-2{-webkit-line-clamp:2!important;-webkit-box-orient:vertical!important;display:-webkit-box!important;overflow:hidden!important}.flex{display:flex}.grid{display:grid}.inline{display:inline}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-8{height:calc(var(--spacing)*8)}.h-16{height:calc(var(--spacing)*16)}.h-full{height:100%}.min-h-\[70vh\]{min-height:70vh}.min-h-\[100px\]{min-height:100px}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-\[280px\]{max-width:280px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.\!rounded-md{border-radius:var(--radius-md)!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-3xl{border-top-left-radius:var(--radius-3xl);border-top-right-radius:var(--radius-3xl)}.\!border{border-style:var(--tw-border-style)!important;border-width:1px!important}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-transparent{border-color:#0000!important}.\!border-zinc-200{border-color:var(--color-zinc-200)!important}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-200\/60{border-color:#fee68599}@supports (color:color-mix(in lab,red,red)){.border-amber-200\/60{border-color:color-mix(in oklab,var(--color-amber-200)60%,transparent)}}.border-indigo-500\/30{border-color:#625fff4d}@supports (color:color-mix(in lab,red,red)){.border-indigo-500\/30{border-color:color-mix(in oklab,var(--color-indigo-500)30%,transparent)}}.border-red-100{border-color:var(--color-red-100)}.border-red-200{border-color:var(--color-red-200)}.border-transparent{border-color:#0000}.border-zinc-200{border-color:var(--color-zinc-200)}.border-zinc-200\/50{border-color:#e4e4e780}@supports (color:color-mix(in lab,red,red)){.border-zinc-200\/50{border-color:color-mix(in oklab,var(--color-zinc-200)50%,transparent)}}.border-zinc-300{border-color:var(--color-zinc-300)}.border-t-indigo-500{border-top-color:var(--color-indigo-500)}.\!bg-white\/90{background-color:#ffffffe6!important}@supports (color:color-mix(in lab,red,red)){.\!bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)!important}}.\!bg-zinc-900{background-color:var(--color-zinc-900)!important}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-600{background-color:var(--color-red-600)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-zinc-50{background-color:var(--color-zinc-50)}.bg-zinc-50\/50{background-color:#fafafa80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-50\/50{background-color:color-mix(in oklab,var(--color-zinc-50)50%,transparent)}}.bg-zinc-100{background-color:var(--color-zinc-100)}.bg-zinc-200{background-color:var(--color-zinc-200)}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-900\/20{background-color:#18181b33}@supports (color:color-mix(in lab,red,red)){.bg-zinc-900\/20{background-color:color-mix(in oklab,var(--color-zinc-900)20%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-indigo-500\/20{--tw-gradient-from:#625fff33}@supports (color:color-mix(in lab,red,red)){.from-indigo-500\/20{--tw-gradient-from:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.from-indigo-500\/20{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-500\/20{--tw-gradient-to:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.to-purple-500\/20{--tw-gradient-to:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.to-purple-500\/20{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.\!px-3{padding-inline:calc(var(--spacing)*3)!important}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.\!py-1\.5{padding-block:calc(var(--spacing)*1.5)!important}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.pt-8{padding-top:calc(var(--spacing)*8)}.pb-10{padding-bottom:calc(var(--spacing)*10)}.pb-12{padding-bottom:calc(var(--spacing)*12)}.text-center{text-align:center}.font-sans{font-family:var(--font-sans)}.\!text-sm{font-size:var(--text-sm)!important;line-height:var(--tw-leading,var(--text-sm--line-height))!important}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\!font-medium{--tw-font-weight:var(--font-weight-medium)!important;font-weight:var(--font-weight-medium)!important}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.\!text-white{color:var(--color-white)!important}.\!text-zinc-500{color:var(--color-zinc-500)!important}.\!text-zinc-900{color:var(--color-zinc-900)!important}.text-amber-500{color:var(--color-amber-500)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-blue-500{color:var(--color-blue-500)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-indigo-500{color:var(--color-indigo-500)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.text-zinc-700{color:var(--color-zinc-700)}.text-zinc-900{color:var(--color-zinc-900)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.\!shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.\!shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-indigo-500\/20{--tw-shadow-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.shadow-indigo-500\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-indigo-500)20%,transparent)var(--tw-shadow-alpha),transparent)}}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-500{--tw-duration:.5s;transition-duration:.5s}@media(hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-\[1\.02\]:hover{scale:1.02}.hover\:border-amber-300:hover{border-color:var(--color-amber-300)}.hover\:\!bg-zinc-800:hover{background-color:var(--color-zinc-800)!important}.hover\:bg-amber-200:hover{background-color:var(--color-amber-200)}.hover\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-zinc-100:hover{background-color:var(--color-zinc-100)}.hover\:bg-zinc-300:hover{background-color:var(--color-zinc-300)}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-amber-900:hover{color:var(--color-amber-900)}.hover\:text-zinc-900:hover{color:var(--color-zinc-900)}}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-indigo-500\/50:focus{--tw-ring-color:#625fff80}@supports (color:color-mix(in lab,red,red)){.focus\:ring-indigo-500\/50:focus{--tw-ring-color:color-mix(in oklab,var(--color-indigo-500)50%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:underline:focus-visible{text-decoration-line:underline}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-amber-500\/30:focus-visible{--tw-ring-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-amber-500\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}@media(min-width:40rem){.sm\:top-\[50\%\]{top:50%}.sm\:bottom-auto{bottom:auto}.sm\:left-\[50\%\]{left:50%}.sm\:hidden{display:none}.sm\:w-full{width:100%}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-none{max-width:none}.sm\:-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.sm\:-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.sm\:rounded-2xl{border-radius:var(--radius-2xl)}.sm\:border{border-style:var(--tw-border-style);border-width:1px}}.dark\:\!border-zinc-300:where(.dark,.dark *){border-color:var(--color-zinc-300)!important}.dark\:\!border-zinc-800:where(.dark,.dark *){border-color:var(--color-zinc-800)!important}.dark\:border-amber-800\/50:where(.dark,.dark *){border-color:#953d0080}@supports (color:color-mix(in lab,red,red)){.dark\:border-amber-800\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-amber-800)50%,transparent)}}.dark\:border-amber-900\/40:where(.dark,.dark *){border-color:#7b330666}@supports (color:color-mix(in lab,red,red)){.dark\:border-amber-900\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-amber-900)40%,transparent)}}.dark\:border-red-500\/20:where(.dark,.dark *){border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/20:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.dark\:border-zinc-700:where(.dark,.dark *){border-color:var(--color-zinc-700)}.dark\:border-zinc-800:where(.dark,.dark *){border-color:var(--color-zinc-800)}.dark\:border-zinc-800\/50:where(.dark,.dark *){border-color:#27272a80}@supports (color:color-mix(in lab,red,red)){.dark\:border-zinc-800\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-zinc-800)50%,transparent)}}.dark\:\!bg-white:where(.dark,.dark *){background-color:var(--color-white)!important}.dark\:\!bg-zinc-950\/80:where(.dark,.dark *){background-color:#09090bcc!important}@supports (color:color-mix(in lab,red,red)){.dark\:\!bg-zinc-950\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-zinc-950)80%,transparent)!important}}.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.dark\:bg-amber-950\/20:where(.dark,.dark *){background-color:#46190133}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-950)20%,transparent)}}.dark\:bg-amber-950\/50:where(.dark,.dark *){background-color:#46190180}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/50:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-950)50%,transparent)}}.dark\:bg-black\/80:where(.dark,.dark *){background-color:#000c}@supports (color:color-mix(in lab,red,red)){.dark\:bg-black\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.dark\:bg-emerald-500\/10:where(.dark,.dark *){background-color:#00bb7f1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-emerald-500)10%,transparent)}}.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.dark\:bg-zinc-100:where(.dark,.dark *){background-color:var(--color-zinc-100)}.dark\:bg-zinc-800:where(.dark,.dark *){background-color:var(--color-zinc-800)}.dark\:bg-zinc-900\/20:where(.dark,.dark *){background-color:#18181b33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-zinc-900\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-zinc-900)20%,transparent)}}.dark\:bg-zinc-900\/50:where(.dark,.dark *){background-color:#18181b80}@supports (color:color-mix(in lab,red,red)){.dark\:bg-zinc-900\/50:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-zinc-900)50%,transparent)}}.dark\:bg-zinc-950:where(.dark,.dark *){background-color:var(--color-zinc-950)}.dark\:\!text-black:where(.dark,.dark *){color:var(--color-black)!important}.dark\:\!text-zinc-50:where(.dark,.dark *){color:var(--color-zinc-50)!important}.dark\:\!text-zinc-400:where(.dark,.dark *){color:var(--color-zinc-400)!important}.dark\:text-amber-100:where(.dark,.dark *){color:var(--color-amber-100)}.dark\:text-amber-200\/70:where(.dark,.dark *){color:#fee685b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-amber-200\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-amber-200)70%,transparent)}}.dark\:text-amber-200\/80:where(.dark,.dark *){color:#fee685cc}@supports (color:color-mix(in lab,red,red)){.dark\:text-amber-200\/80:where(.dark,.dark *){color:color-mix(in oklab,var(--color-amber-200)80%,transparent)}}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-red-500:where(.dark,.dark *){color:var(--color-red-500)}.dark\:text-white:where(.dark,.dark *){color:var(--color-white)}.dark\:text-zinc-50:where(.dark,.dark *){color:var(--color-zinc-50)}.dark\:text-zinc-100:where(.dark,.dark *){color:var(--color-zinc-100)}.dark\:text-zinc-300:where(.dark,.dark *){color:var(--color-zinc-300)}.dark\:text-zinc-400:where(.dark,.dark *){color:var(--color-zinc-400)}.dark\:text-zinc-900:where(.dark,.dark *){color:var(--color-zinc-900)}.dark\:\!shadow-2xl:where(.dark,.dark *){--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.dark\:shadow-\[0_1px_2px_rgba\(0\,0\,0\,0\.1\)\]:where(.dark,.dark *){--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(hover:hover){.dark\:hover\:border-amber-700\/50:where(.dark,.dark *):hover{border-color:#b7500080}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:border-amber-700\/50:where(.dark,.dark *):hover{border-color:color-mix(in oklab,var(--color-amber-700)50%,transparent)}}.dark\:hover\:border-zinc-800:where(.dark,.dark *):hover{border-color:var(--color-zinc-800)}.dark\:hover\:\!bg-zinc-100:where(.dark,.dark *):hover{background-color:var(--color-zinc-100)!important}.dark\:hover\:bg-amber-900\/70:where(.dark,.dark *):hover{background-color:#7b3306b3}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-amber-900\/70:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-amber-900)70%,transparent)}}.dark\:hover\:bg-white:where(.dark,.dark *):hover{background-color:var(--color-white)}.dark\:hover\:bg-zinc-700:where(.dark,.dark *):hover{background-color:var(--color-zinc-700)}.dark\:hover\:bg-zinc-900:where(.dark,.dark *):hover{background-color:var(--color-zinc-900)}.dark\:hover\:text-amber-100:where(.dark,.dark *):hover{color:var(--color-amber-100)}.dark\:hover\:text-zinc-200:where(.dark,.dark *):hover{color:var(--color-zinc-200)}}}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}@keyframes overlayShow{0%{opacity:0}to{opacity:1}}@keyframes overlayHide{0%{opacity:1}to{opacity:0}}@keyframes contentShowDesktop{0%{opacity:0;transform:translateY(8px)scale(.96)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes contentHideDesktop{0%{opacity:1;transform:translateY(0)scale(1)}to{opacity:0;transform:translateY(8px)scale(.96)}}@keyframes contentShowMobile{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes contentHideMobile{0%{transform:translateY(0)}to{transform:translateY(100%)}}.radix-overlay[data-state=open]{animation:.4s cubic-bezier(.16,1,.3,1) overlayShow}.radix-overlay[data-state=closed]{animation:.3s cubic-bezier(.16,1,.3,1) overlayHide}.radix-content[data-state=open]{animation:.4s cubic-bezier(.16,1,.3,1) contentShowMobile}.radix-content[data-state=closed]{animation:.3s cubic-bezier(.16,1,.3,1) contentHideMobile}@media(min-width:640px){.radix-content[data-state=open]{animation:.5s cubic-bezier(.16,1,.3,1) contentShowDesktop}.radix-content[data-state=closed]{animation:.4s cubic-bezier(.16,1,.3,1) contentHideDesktop}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),g=require("react"),p=require("lucide-react"),C=require("clsx"),N=require("tailwind-merge"),E=require("@radix-ui/react-dialog"),l=require("sonner");function P(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const a in r)if(a!=="default"){const s=Object.getOwnPropertyDescriptor(r,a);Object.defineProperty(e,a,s.get?s:{enumerable:!0,get:()=>r[a]})}}return e.default=r,Object.freeze(e)}const b=P(E),D=[{name:"email",pattern:/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,replacement:"[EMAIL_REDACTED]"},{name:"bearer_token",pattern:/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,replacement:"Bearer [TOKEN_REDACTED]"},{name:"jwt",pattern:/eyJ[A-Za-z0-9\-_]+\.eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+/g,replacement:"[JWT_REDACTED]"},{name:"api_key",pattern:/\b([A-Za-z0-9]{32,})\b/g,replacement:"[KEY_REDACTED]"},{name:"phone",pattern:/(\+?\d[\d\s\-().]{7,}\d)/g,replacement:"[PHONE_REDACTED]"},{name:"ipv4",pattern:/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,replacement:"[IP_REDACTED]"},{name:"url_query_params",pattern:/([?&](?:token|key|secret|auth|email|user|access_token|refresh_token|api_key|apikey|password|passwd|pwd)=[^&\s]+)/gi,replacement:"[PARAM_REDACTED]"},{name:"ssn",pattern:/\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/g,replacement:"[SSN_REDACTED]"},{name:"credit_card",pattern:/\b(?:\d[ -]?){13,19}\b/g,replacement:"[CC_REDACTED]"}];function f(r){let e=r;for(const{pattern:a,replacement:s}of D)e=e.replace(a,s);return e}function c(...r){return N.twMerge(C.clsx(r))}function A({title:r,description:e,primaryAction:a,secondaryAction:s,theme:o,className:i}){return t.jsx("div",{className:c("rounded-xl border p-4 transition-colors","bg-amber-50 border-amber-200/60 shadow-sm","dark:bg-amber-950/20 dark:border-amber-900/40 dark:shadow-[0_1px_2px_rgba(0,0,0,0.1)]",o?.fontFamily,i),style:{backgroundColor:o?.backgroundColor,borderColor:o?.primaryColor?`${o.primaryColor}30`:void 0},children:t.jsxs("div",{className:"flex gap-3",children:[t.jsx(p.AlertTriangle,{className:"h-5 w-5 shrink-0 mt-0.5 text-amber-500 dark:text-amber-400"}),t.jsxs("div",{className:"flex-1",children:[t.jsx("h3",{className:"text-sm font-medium leading-none text-amber-900 dark:text-amber-100",children:r}),t.jsx("p",{className:"mt-2 text-sm leading-relaxed text-amber-800 dark:text-amber-200/80",children:e}),(a||s)&&t.jsxs("div",{className:"mt-4 flex items-center gap-3",children:[a&&t.jsx("button",{onClick:a.onClick,className:c("text-xs font-medium px-3 py-1.5 rounded-md transition-colors","focus-visible:ring-2 focus-visible:ring-amber-500/30 focus:outline-none","bg-amber-100 border border-amber-200 text-amber-900 hover:bg-amber-200 hover:border-amber-300","dark:bg-amber-950/50 dark:border-amber-800/50 dark:text-amber-100 dark:hover:bg-amber-900/70 dark:hover:border-amber-700/50"),children:a.label}),s&&t.jsx("button",{onClick:s.onClick,className:c("text-xs font-medium transition-colors focus-visible:underline focus:outline-none","text-amber-700 hover:text-amber-900","dark:text-amber-200/70 dark:hover:text-amber-100"),children:s.label})]})]})]})})}function w({title:r,description:e,statusUrl:a,isOpen:s,onOpenChange:o,theme:i}){return t.jsx(b.Root,{open:s,onOpenChange:o,children:t.jsxs(b.Portal,{children:[t.jsx(b.Overlay,{className:"radix-overlay fixed inset-0 z-50 bg-zinc-900/20 dark:bg-black/80 backdrop-blur-sm"}),t.jsxs(b.Content,{className:c("radix-content fixed z-50 flex flex-col items-center text-center shadow-2xl transition-colors","bg-white border-zinc-200 dark:bg-zinc-950 dark:border-zinc-800","bottom-0 left-0 right-0 border-t rounded-t-3xl p-8 pb-10","sm:bottom-auto sm:top-[50%] sm:left-[50%] sm:-translate-x-1/2 sm:-translate-y-1/2 sm:w-full sm:max-w-md sm:rounded-2xl sm:border",i?.fontFamily),children:[t.jsx("div",{className:"mx-auto w-12 h-1.5 rounded-full bg-zinc-200 dark:bg-zinc-800 mb-6 sm:hidden"}),t.jsx("div",{className:"w-16 h-16 rounded-full flex items-center justify-center mb-6 border bg-red-50 border-red-100 dark:bg-red-500/10 dark:border-red-500/20",children:t.jsx(p.AlertOctagon,{className:"w-8 h-8 text-red-600 dark:text-red-500"})}),t.jsx(b.Title,{className:"text-xl font-semibold text-zinc-900 dark:text-zinc-50 mb-3 tracking-tight",children:r}),t.jsx(b.Description,{className:"text-sm leading-relaxed mb-8 max-w-[280px] sm:max-w-none text-zinc-600 dark:text-zinc-400",children:e}),t.jsxs("div",{className:"flex flex-col w-full gap-3",children:[t.jsxs("button",{onClick:()=>window.location.reload(),className:c("flex items-center justify-center gap-2 w-full py-3 px-4 rounded-xl font-medium transition-all shadow-sm","bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-white hover:scale-[1.02] active:scale-95"),children:[t.jsx(p.RefreshCcw,{className:"w-4 h-4"}),"Atualizar a página"]}),a&&t.jsxs("a",{href:a,target:"_blank",rel:"noopener noreferrer",className:c("flex items-center justify-center gap-2 w-full py-3 px-4 rounded-xl font-medium transition-colors border border-transparent","text-zinc-500 hover:text-zinc-900 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:text-zinc-200 dark:hover:bg-zinc-900 dark:hover:border-zinc-800"),children:["Verificar status do sistema",t.jsx(p.ExternalLink,{className:"w-4 h-4 opacity-70"})]})]})]})]})})}function _({customTheme:r,toastOptions:e,position:a="top-right",...s}){return t.jsx(l.Toaster,{position:a,toastOptions:{...e,classNames:{...e?.classNames,toast:c("backdrop-blur-md font-sans rounded-xl px-4 py-3 transition-colors","!bg-white/90 !border !border-zinc-200 !text-zinc-900 !shadow-xl","dark:!bg-zinc-950/80 dark:!border-zinc-800 dark:!text-zinc-50 dark:!shadow-2xl",r?.fontFamily,e?.classNames?.toast),title:c("!font-medium !text-sm !text-zinc-900 dark:!text-zinc-50",e?.classNames?.title),description:c("!mt-0.5 !text-sm !text-zinc-500 dark:!text-zinc-400 !line-clamp-2",e?.classNames?.description),actionButton:c("!font-medium !rounded-md !shadow-sm transition-colors !px-3 !py-1.5 !border","!bg-zinc-900 !text-white !border-transparent hover:!bg-zinc-800","dark:!bg-white dark:!text-black dark:!border-zinc-300 dark:hover:!bg-zinc-100",e?.classNames?.actionButton)},style:{backgroundColor:r?.backgroundColor,color:r?.textColor,borderColor:r?.primaryColor?`${r.primaryColor}40`:void 0,...e?.style}}})}function z(r,e,a,s){l.toast(r,{description:e,icon:t.jsx(p.AlertCircle,{className:"w-5 h-5 text-red-500 dark:text-red-400"}),action:a?{label:a,onClick:()=>{s&&s()}}:void 0})}const R={success:(r,e)=>l.toast(r,{description:e,icon:t.jsx(p.CheckCircle2,{className:"w-5 h-5 text-emerald-500 dark:text-emerald-400"})}),error:(r,e)=>l.toast(r,{description:e,icon:t.jsx(p.AlertCircle,{className:"w-5 h-5 text-red-500 dark:text-red-400"})}),warning:(r,e)=>l.toast(r,{description:e,icon:t.jsx(p.AlertTriangle,{className:"w-5 h-5 text-amber-500 dark:text-amber-400"})}),info:(r,e)=>l.toast(r,{description:e,icon:t.jsx(p.Info,{className:"w-5 h-5 text-blue-500 dark:text-blue-400"})}),message:(r,e)=>l.toast(r,{description:e}),customTheme:(r,e,a)=>{l.toast.custom(s=>t.jsxs("div",{className:c("w-full flex gap-3 p-4 shadow-2xl transition-all",a.fontFamily),style:{backgroundColor:a.backgroundColor||"#ffffff",color:a.textColor||"#000000",border:`1px solid ${a.primaryColor||"#e4e4e7"}`,borderRadius:a.borderRadius||"12px"},children:[t.jsx("div",{className:"w-1.5 rounded-full shrink-0",style:{backgroundColor:a.primaryColor||"#3b82f6"}}),t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx("span",{className:"font-medium text-sm leading-none",children:r}),t.jsx("span",{className:"text-sm opacity-80 leading-relaxed mt-1",children:e})]})]}))}},v=g.createContext(void 0);function T({apiKey:r,apiUrl:e,language:a,children:s}){const o=async i=>{const d=i instanceof Error?i:new Error(String(i)),n=l.toast.loading("Analyzing error context...",{description:"Applying AI recovery heuristics..."});try{const m=f(d.message).slice(0,500),k=f(d.stack||"").slice(0,1500),h=e||"https://api.cognicatch.dev/v1/analyze-error",u=typeof navigator<"u"?navigator.language:"en-US",j=a||u,y=await fetch(h,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({error:m,stack:k,language:j})});if(!y.ok)throw new Error("SaaS API Error");const x=await y.json();x&&((x.severity||x.level)==="low"?l.toast.info(x.title,{id:n,description:x.description}):l.toast.error(x.title,{id:n,description:x.description}))}catch(m){console.error("AdaptiveUI API Request failed:",m),l.toast.error("Analysis Failed",{id:n,description:"We couldn't reach the AI servers. Please try again later."})}};return t.jsx(v.Provider,{value:{apiKey:r,apiUrl:e,language:a,captureAsyncError:o},children:s})}function S(){const r=g.useContext(v);if(!r)throw new Error("❌ AdaptiveUI Developer Error: You tried to use the 'useAdaptive' hook outside of an <AdaptiveProvider>. Please wrap the root of your application (e.g., App.tsx) with <AdaptiveProvider apiKey='YOUR_KEY'>");return r}class I extends g.Component{static contextType=v;constructor(e){super(e),this.state={hasError:!1,error:null,aiData:null,isProcessingAuto:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,a){const{mode:s}=this.props;s==="manual"&&this.props.severity==="low"&&z(this.props.title,this.props.description,this.props.actionLabel??void 0,this.handleRecover),s==="auto"&&(this.setState({isProcessingAuto:!0}),this.processAutoMode(e))}processAutoMode=async e=>{const a=this.props,s=a.apiKey||this.context?.apiKey,o=a.apiUrl||this.context?.apiUrl,i=typeof navigator<"u"?navigator.language:"en-US",d=a.language||this.context?.language||i;if(!s){console.error("AdaptiveUI: Missing API Key for auto mode. Provide it via props or <AdaptiveProvider>."),this.setState({isProcessingAuto:!1});return}if(s==="sk_test_mock"){setTimeout(()=>{this.setState({isProcessingAuto:!1,aiData:{severity:"medium",title:"Incomplete data",description:"The dashboard encountered an error while attempting to read user information. Our team has already been notified.",actionLabel:"Reload Widget"}})},1500);return}try{const n=f(e.message).slice(0,500),m=f(e.stack||"").slice(0,1500),h=await fetch(o||"https://api.cognicatch.dev/v1/analyze-error",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({error:n,stack:m,language:d})});if(!h.ok)throw new Error(`SaaS API returned ${h.status}`);const u=await h.json();u&&(u.severity==="low"?(z(u.title,u.description,u.actionLabel??void 0,this.handleRecover),this.setState({isProcessingAuto:!1,hasError:!1,error:null})):this.setState({isProcessingAuto:!1,aiData:u}))}catch(n){console.error("AdaptiveUI AI Request failed:",n),this.setState({isProcessingAuto:!1,aiData:{severity:"medium",title:"Communication Error",description:"We were unable to connect to the analytics servers at this time. Our team has already been notified.",actionLabel:"Reload Component"}})}};handleRecover=()=>{this.setState({hasError:!1,error:null,aiData:null}),this.props.onRecover&&this.props.onRecover()};render(){if(!this.state.hasError)return this.props.children;const{mode:e,theme:a,className:s}=this.props;if(e==="manual"){const{severity:o,title:i,description:d,actionLabel:n}=this.props;if(o==="high")return t.jsx(w,{isOpen:!0,onOpenChange:m=>{m||this.handleRecover()},title:i,description:d,theme:a});if(o==="medium")return t.jsx(A,{title:i,description:d,primaryAction:n?{label:n,onClick:this.handleRecover}:void 0,theme:a,className:s});if(o==="low")return null}if(e==="auto"){if(this.state.isProcessingAuto)return t.jsxs("div",{className:"w-full h-full min-h-[100px] rounded-xl border border-zinc-200/50 dark:border-zinc-800/50 bg-zinc-50/50 dark:bg-zinc-900/20 flex flex-col items-center justify-center p-6 animate-pulse",children:[t.jsx("div",{className:"w-5 h-5 border-2 border-indigo-500/30 border-t-indigo-500 rounded-full animate-spin mb-3"}),t.jsx("p",{className:"text-xs font-medium text-zinc-500 dark:text-zinc-400",children:"Analyzing error context..."})]});if(this.state.aiData){const{severity:o,title:i,description:d,actionLabel:n}=this.state.aiData;if(o==="high")return t.jsx(w,{isOpen:!0,onOpenChange:m=>{m||this.handleRecover()},title:i,description:d,theme:a});if(o==="medium")return t.jsx(A,{title:i,description:d,primaryAction:n?{label:n,onClick:this.handleRecover}:void 0,theme:a,className:s})}}return null}}exports.AdaptiveErrorBoundary=I;exports.AdaptiveProvider=T;exports.AdaptiveToastProvider=_;exports.adaptiveToast=R;exports.useAdaptive=S;
@@ -0,0 +1,138 @@
1
+ import { Component } from 'react';
2
+ import { default as default_2 } from 'react';
3
+ import { ErrorInfo } from 'react';
4
+ import { JSX } from 'react/jsx-runtime';
5
+ import { ReactNode } from 'react';
6
+ import { Toaster } from 'sonner';
7
+ import { z } from 'zod';
8
+
9
+ declare const AdaptiveContext: default_2.Context<AdaptiveContextType | undefined>;
10
+
11
+ declare interface AdaptiveContextType {
12
+ apiKey: string;
13
+ apiUrl?: string;
14
+ language?: string;
15
+ captureAsyncError: (error: Error | unknown) => Promise<void>;
16
+ }
17
+
18
+ export declare class AdaptiveErrorBoundary extends Component<Props, State> {
19
+ static contextType: default_2.Context<AdaptiveContextType | undefined>;
20
+ context: default_2.ContextType<typeof AdaptiveContext>;
21
+ constructor(props: Props);
22
+ static getDerivedStateFromError(error: Error): Partial<State>;
23
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
24
+ processAutoMode: (error: Error) => Promise<void>;
25
+ handleRecover: () => void;
26
+ render(): string | number | bigint | boolean | JSX.Element | Iterable<default_2.ReactNode> | Promise<string | number | bigint | boolean | default_2.ReactPortal | default_2.ReactElement<unknown, string | default_2.JSXElementConstructor<any>> | Iterable<default_2.ReactNode> | null | undefined> | null | undefined;
27
+ }
28
+
29
+ export declare type AdaptiveErrorProps = ManualModeProps | AutoModeProps;
30
+
31
+ export declare function AdaptiveProvider({ apiKey, apiUrl, language, children }: {
32
+ apiKey: string;
33
+ apiUrl?: string;
34
+ language?: string;
35
+ children: ReactNode;
36
+ }): JSX.Element;
37
+
38
+ export declare const adaptiveToast: {
39
+ success: (title: string, description?: string) => string | number;
40
+ error: (title: string, description?: string) => string | number;
41
+ warning: (title: string, description?: string) => string | number;
42
+ info: (title: string, description?: string) => string | number;
43
+ message: (title: string, description?: string) => string | number;
44
+ customTheme: (title: string, description: string, theme: ThemeOptions) => void;
45
+ };
46
+
47
+ export declare function AdaptiveToastProvider({ customTheme, toastOptions, position, ...props }: AdaptiveToastProviderProps): JSX.Element;
48
+
49
+ declare type AdaptiveToastProviderProps = default_2.ComponentProps<typeof Toaster> & {
50
+ customTheme?: ThemeOptions;
51
+ };
52
+
53
+ export declare interface AutoModeProps extends BaseAdaptiveProps {
54
+ mode: 'auto';
55
+ apiKey?: string;
56
+ apiUrl?: string;
57
+ error?: Error;
58
+ language?: string;
59
+ }
60
+
61
+ export declare interface BaseAdaptiveProps {
62
+ theme?: ThemeOptions;
63
+ onRecover?: () => void;
64
+ className?: string;
65
+ }
66
+
67
+ declare type GenUIResponse = z.infer<typeof GenUIResponseSchema>;
68
+
69
+ declare const GenUIResponseSchema: z.ZodObject<{
70
+ severity: z.ZodEnum<{
71
+ low: "low";
72
+ medium: "medium";
73
+ high: "high";
74
+ }>;
75
+ title: z.ZodString;
76
+ description: z.ZodString;
77
+ actionLabel: z.ZodNullable<z.ZodString>;
78
+ }, z.core.$strip>;
79
+
80
+ export declare interface ManualModeProps extends BaseAdaptiveProps {
81
+ mode: 'manual';
82
+ severity: SeverityLevel;
83
+ title: string;
84
+ description: string;
85
+ actionLabel?: string;
86
+ }
87
+
88
+ declare type Props = AdaptiveErrorProps & {
89
+ children: ReactNode;
90
+ };
91
+
92
+ declare type SeverityLevel = 'low' | 'medium' | 'high';
93
+
94
+ declare interface State {
95
+ hasError: boolean;
96
+ error: Error | null;
97
+ aiData: GenUIResponse | null;
98
+ isProcessingAuto: boolean;
99
+ }
100
+
101
+ export declare interface ThemeOptions {
102
+ primaryColor?: string;
103
+ backgroundColor?: string;
104
+ textColor?: string;
105
+ borderRadius?: string;
106
+ fontFamily?: string;
107
+ }
108
+
109
+ export declare function useAdaptive(): AdaptiveContextType;
110
+
111
+ export { }
112
+
113
+
114
+ declare module '@tanstack/react-router' {
115
+ interface Register {
116
+ router: ReturnType<typeof getRouter>;
117
+ }
118
+ }
119
+
120
+
121
+ declare module '@tanstack/react-router' {
122
+ interface FileRoutesByPath {
123
+ '/': {
124
+ id: '/';
125
+ path: '/';
126
+ fullPath: '/';
127
+ preLoaderRoute: typeof IndexRouteImport;
128
+ parentRoute: typeof rootRouteImport;
129
+ };
130
+ }
131
+ }
132
+
133
+
134
+ declare module '@tanstack/react-start' {
135
+ interface Register {
136
+ router: Awaited<ReturnType<typeof getRouter>>;
137
+ }
138
+ }
package/dist/index.js ADDED
@@ -0,0 +1,458 @@
1
+ import { jsx as a, jsxs as d } from "react/jsx-runtime";
2
+ import { createContext as E, useContext as D, Component as R } from "react";
3
+ import { AlertTriangle as z, AlertOctagon as _, RefreshCcw as P, ExternalLink as S, Info as T, AlertCircle as C, CheckCircle2 as I } from "lucide-react";
4
+ import { clsx as j } from "clsx";
5
+ import { twMerge as L } from "tailwind-merge";
6
+ import * as b from "@radix-ui/react-dialog";
7
+ import { Toaster as O, toast as l } from "sonner";
8
+ const B = [
9
+ // Emails
10
+ {
11
+ name: "email",
12
+ pattern: /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,
13
+ replacement: "[EMAIL_REDACTED]"
14
+ },
15
+ // Bearer / API tokens in Authorization headers
16
+ {
17
+ name: "bearer_token",
18
+ pattern: /Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,
19
+ replacement: "Bearer [TOKEN_REDACTED]"
20
+ },
21
+ // JWT tokens (three base64url segments)
22
+ {
23
+ name: "jwt",
24
+ pattern: /eyJ[A-Za-z0-9\-_]+\.eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+/g,
25
+ replacement: "[JWT_REDACTED]"
26
+ },
27
+ // Generic API keys (long hex or base64-looking strings 32+ chars)
28
+ {
29
+ name: "api_key",
30
+ pattern: /\b([A-Za-z0-9]{32,})\b/g,
31
+ replacement: "[KEY_REDACTED]"
32
+ },
33
+ // Phone numbers (loose match)
34
+ {
35
+ name: "phone",
36
+ pattern: /(\+?\d[\d\s\-().]{7,}\d)/g,
37
+ replacement: "[PHONE_REDACTED]"
38
+ },
39
+ // IP addresses
40
+ {
41
+ name: "ipv4",
42
+ pattern: /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,
43
+ replacement: "[IP_REDACTED]"
44
+ },
45
+ // URL query parameters that could carry tokens/emails
46
+ {
47
+ name: "url_query_params",
48
+ pattern: /([?&](?:token|key|secret|auth|email|user|access_token|refresh_token|api_key|apikey|password|passwd|pwd)=[^&\s]+)/gi,
49
+ replacement: "[PARAM_REDACTED]"
50
+ },
51
+ // Potential SSNs
52
+ {
53
+ name: "ssn",
54
+ pattern: /\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/g,
55
+ replacement: "[SSN_REDACTED]"
56
+ },
57
+ // Credit card numbers (Luhn-ish pattern)
58
+ {
59
+ name: "credit_card",
60
+ pattern: /\b(?:\d[ -]?){13,19}\b/g,
61
+ replacement: "[CC_REDACTED]"
62
+ }
63
+ ];
64
+ function x(r) {
65
+ let e = r;
66
+ for (const { pattern: t, replacement: o } of B)
67
+ e = e.replace(t, o);
68
+ return e;
69
+ }
70
+ function c(...r) {
71
+ return L(j(r));
72
+ }
73
+ function y({
74
+ title: r,
75
+ description: e,
76
+ primaryAction: t,
77
+ secondaryAction: o,
78
+ theme: i,
79
+ className: n
80
+ }) {
81
+ return /* @__PURE__ */ a(
82
+ "div",
83
+ {
84
+ className: c(
85
+ "rounded-xl border p-4 transition-colors",
86
+ "bg-amber-50 border-amber-200/60 shadow-sm",
87
+ "dark:bg-amber-950/20 dark:border-amber-900/40 dark:shadow-[0_1px_2px_rgba(0,0,0,0.1)]",
88
+ i?.fontFamily,
89
+ n
90
+ ),
91
+ style: {
92
+ backgroundColor: i?.backgroundColor,
93
+ borderColor: i?.primaryColor ? `${i.primaryColor}30` : void 0
94
+ },
95
+ children: /* @__PURE__ */ d("div", { className: "flex gap-3", children: [
96
+ /* @__PURE__ */ a(z, { className: "h-5 w-5 shrink-0 mt-0.5 text-amber-500 dark:text-amber-400" }),
97
+ /* @__PURE__ */ d("div", { className: "flex-1", children: [
98
+ /* @__PURE__ */ a("h3", { className: "text-sm font-medium leading-none text-amber-900 dark:text-amber-100", children: r }),
99
+ /* @__PURE__ */ a("p", { className: "mt-2 text-sm leading-relaxed text-amber-800 dark:text-amber-200/80", children: e }),
100
+ (t || o) && /* @__PURE__ */ d("div", { className: "mt-4 flex items-center gap-3", children: [
101
+ t && /* @__PURE__ */ a(
102
+ "button",
103
+ {
104
+ onClick: t.onClick,
105
+ className: c(
106
+ "text-xs font-medium px-3 py-1.5 rounded-md transition-colors",
107
+ "focus-visible:ring-2 focus-visible:ring-amber-500/30 focus:outline-none",
108
+ "bg-amber-100 border border-amber-200 text-amber-900 hover:bg-amber-200 hover:border-amber-300",
109
+ "dark:bg-amber-950/50 dark:border-amber-800/50 dark:text-amber-100 dark:hover:bg-amber-900/70 dark:hover:border-amber-700/50"
110
+ ),
111
+ children: t.label
112
+ }
113
+ ),
114
+ o && /* @__PURE__ */ a(
115
+ "button",
116
+ {
117
+ onClick: o.onClick,
118
+ className: c(
119
+ "text-xs font-medium transition-colors focus-visible:underline focus:outline-none",
120
+ "text-amber-700 hover:text-amber-900",
121
+ "dark:text-amber-200/70 dark:hover:text-amber-100"
122
+ ),
123
+ children: o.label
124
+ }
125
+ )
126
+ ] })
127
+ ] })
128
+ ] })
129
+ }
130
+ );
131
+ }
132
+ function w({
133
+ title: r,
134
+ description: e,
135
+ statusUrl: t,
136
+ isOpen: o,
137
+ onOpenChange: i,
138
+ theme: n
139
+ }) {
140
+ return /* @__PURE__ */ a(b.Root, { open: o, onOpenChange: i, children: /* @__PURE__ */ d(b.Portal, { children: [
141
+ /* @__PURE__ */ a(
142
+ b.Overlay,
143
+ {
144
+ className: "radix-overlay fixed inset-0 z-50 bg-zinc-900/20 dark:bg-black/80 backdrop-blur-sm"
145
+ }
146
+ ),
147
+ /* @__PURE__ */ d(
148
+ b.Content,
149
+ {
150
+ className: c(
151
+ "radix-content fixed z-50 flex flex-col items-center text-center shadow-2xl transition-colors",
152
+ "bg-white border-zinc-200 dark:bg-zinc-950 dark:border-zinc-800",
153
+ "bottom-0 left-0 right-0 border-t rounded-t-3xl p-8 pb-10",
154
+ "sm:bottom-auto sm:top-[50%] sm:left-[50%] sm:-translate-x-1/2 sm:-translate-y-1/2 sm:w-full sm:max-w-md sm:rounded-2xl sm:border",
155
+ n?.fontFamily
156
+ ),
157
+ children: [
158
+ /* @__PURE__ */ a("div", { className: "mx-auto w-12 h-1.5 rounded-full bg-zinc-200 dark:bg-zinc-800 mb-6 sm:hidden" }),
159
+ /* @__PURE__ */ a("div", { className: "w-16 h-16 rounded-full flex items-center justify-center mb-6 border bg-red-50 border-red-100 dark:bg-red-500/10 dark:border-red-500/20", children: /* @__PURE__ */ a(_, { className: "w-8 h-8 text-red-600 dark:text-red-500" }) }),
160
+ /* @__PURE__ */ a(b.Title, { className: "text-xl font-semibold text-zinc-900 dark:text-zinc-50 mb-3 tracking-tight", children: r }),
161
+ /* @__PURE__ */ a(b.Description, { className: "text-sm leading-relaxed mb-8 max-w-[280px] sm:max-w-none text-zinc-600 dark:text-zinc-400", children: e }),
162
+ /* @__PURE__ */ d("div", { className: "flex flex-col w-full gap-3", children: [
163
+ /* @__PURE__ */ d(
164
+ "button",
165
+ {
166
+ onClick: () => window.location.reload(),
167
+ className: c(
168
+ "flex items-center justify-center gap-2 w-full py-3 px-4 rounded-xl font-medium transition-all shadow-sm",
169
+ "bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-white hover:scale-[1.02] active:scale-95"
170
+ ),
171
+ children: [
172
+ /* @__PURE__ */ a(P, { className: "w-4 h-4" }),
173
+ "Atualizar a página"
174
+ ]
175
+ }
176
+ ),
177
+ t && /* @__PURE__ */ d(
178
+ "a",
179
+ {
180
+ href: t,
181
+ target: "_blank",
182
+ rel: "noopener noreferrer",
183
+ className: c(
184
+ "flex items-center justify-center gap-2 w-full py-3 px-4 rounded-xl font-medium transition-colors border border-transparent",
185
+ "text-zinc-500 hover:text-zinc-900 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:text-zinc-200 dark:hover:bg-zinc-900 dark:hover:border-zinc-800"
186
+ ),
187
+ children: [
188
+ "Verificar status do sistema",
189
+ /* @__PURE__ */ a(S, { className: "w-4 h-4 opacity-70" })
190
+ ]
191
+ }
192
+ )
193
+ ] })
194
+ ]
195
+ }
196
+ )
197
+ ] }) });
198
+ }
199
+ function W({
200
+ customTheme: r,
201
+ toastOptions: e,
202
+ position: t = "top-right",
203
+ ...o
204
+ }) {
205
+ return /* @__PURE__ */ a(
206
+ O,
207
+ {
208
+ position: t,
209
+ toastOptions: {
210
+ ...e,
211
+ classNames: {
212
+ ...e?.classNames,
213
+ toast: c(
214
+ "backdrop-blur-md font-sans rounded-xl px-4 py-3 transition-colors",
215
+ "!bg-white/90 !border !border-zinc-200 !text-zinc-900 !shadow-xl",
216
+ "dark:!bg-zinc-950/80 dark:!border-zinc-800 dark:!text-zinc-50 dark:!shadow-2xl",
217
+ r?.fontFamily,
218
+ e?.classNames?.toast
219
+ ),
220
+ title: c(
221
+ "!font-medium !text-sm !text-zinc-900 dark:!text-zinc-50",
222
+ e?.classNames?.title
223
+ ),
224
+ description: c(
225
+ "!mt-0.5 !text-sm !text-zinc-500 dark:!text-zinc-400 !line-clamp-2",
226
+ e?.classNames?.description
227
+ ),
228
+ actionButton: c(
229
+ "!font-medium !rounded-md !shadow-sm transition-colors !px-3 !py-1.5 !border",
230
+ "!bg-zinc-900 !text-white !border-transparent hover:!bg-zinc-800",
231
+ "dark:!bg-white dark:!text-black dark:!border-zinc-300 dark:hover:!bg-zinc-100",
232
+ e?.classNames?.actionButton
233
+ )
234
+ },
235
+ style: {
236
+ backgroundColor: r?.backgroundColor,
237
+ color: r?.textColor,
238
+ borderColor: r?.primaryColor ? `${r.primaryColor}40` : void 0,
239
+ ...e?.style
240
+ }
241
+ }
242
+ }
243
+ );
244
+ }
245
+ function A(r, e, t, o) {
246
+ l(r, {
247
+ description: e,
248
+ icon: /* @__PURE__ */ a(C, { className: "w-5 h-5 text-red-500 dark:text-red-400" }),
249
+ action: t ? {
250
+ label: t,
251
+ onClick: () => {
252
+ o && o();
253
+ }
254
+ } : void 0
255
+ });
256
+ }
257
+ const Y = {
258
+ success: (r, e) => l(r, {
259
+ description: e,
260
+ icon: /* @__PURE__ */ a(I, { className: "w-5 h-5 text-emerald-500 dark:text-emerald-400" })
261
+ }),
262
+ error: (r, e) => l(r, {
263
+ description: e,
264
+ icon: /* @__PURE__ */ a(C, { className: "w-5 h-5 text-red-500 dark:text-red-400" })
265
+ }),
266
+ warning: (r, e) => l(r, {
267
+ description: e,
268
+ icon: /* @__PURE__ */ a(z, { className: "w-5 h-5 text-amber-500 dark:text-amber-400" })
269
+ }),
270
+ info: (r, e) => l(r, {
271
+ description: e,
272
+ icon: /* @__PURE__ */ a(T, { className: "w-5 h-5 text-blue-500 dark:text-blue-400" })
273
+ }),
274
+ message: (r, e) => l(r, { description: e }),
275
+ customTheme: (r, e, t) => {
276
+ l.custom((o) => /* @__PURE__ */ d(
277
+ "div",
278
+ {
279
+ className: c("w-full flex gap-3 p-4 shadow-2xl transition-all", t.fontFamily),
280
+ style: {
281
+ backgroundColor: t.backgroundColor || "#ffffff",
282
+ color: t.textColor || "#000000",
283
+ border: `1px solid ${t.primaryColor || "#e4e4e7"}`,
284
+ borderRadius: t.borderRadius || "12px"
285
+ },
286
+ children: [
287
+ /* @__PURE__ */ a(
288
+ "div",
289
+ {
290
+ className: "w-1.5 rounded-full shrink-0",
291
+ style: { backgroundColor: t.primaryColor || "#3b82f6" }
292
+ }
293
+ ),
294
+ /* @__PURE__ */ d("div", { className: "flex flex-col gap-1", children: [
295
+ /* @__PURE__ */ a("span", { className: "font-medium text-sm leading-none", children: r }),
296
+ /* @__PURE__ */ a("span", { className: "text-sm opacity-80 leading-relaxed mt-1", children: e })
297
+ ] })
298
+ ]
299
+ }
300
+ ));
301
+ }
302
+ }, g = E(void 0);
303
+ function q({
304
+ apiKey: r,
305
+ apiUrl: e,
306
+ language: t,
307
+ children: o
308
+ }) {
309
+ const i = async (n) => {
310
+ const m = n instanceof Error ? n : new Error(String(n)), s = l.loading("Analyzing error context...", {
311
+ description: "Applying AI recovery heuristics..."
312
+ });
313
+ try {
314
+ const p = x(m.message).slice(0, 500), v = x(m.stack || "").slice(0, 1500), f = e || "https://api.cognicatch.dev/v1/analyze-error", u = typeof navigator < "u" ? navigator.language : "en-US", N = t || u, k = await fetch(f, {
315
+ method: "POST",
316
+ headers: {
317
+ Authorization: `Bearer ${r}`,
318
+ "Content-Type": "application/json"
319
+ },
320
+ body: JSON.stringify({ error: p, stack: v, language: N })
321
+ });
322
+ if (!k.ok) throw new Error("SaaS API Error");
323
+ const h = await k.json();
324
+ h && ((h.severity || h.level) === "low" ? l.info(h.title, { id: s, description: h.description }) : l.error(h.title, { id: s, description: h.description }));
325
+ } catch (p) {
326
+ console.error("AdaptiveUI API Request failed:", p), l.error("Analysis Failed", {
327
+ id: s,
328
+ description: "We couldn't reach the AI servers. Please try again later."
329
+ });
330
+ }
331
+ };
332
+ return /* @__PURE__ */ a(g.Provider, { value: { apiKey: r, apiUrl: e, language: t, captureAsyncError: i }, children: o });
333
+ }
334
+ function H() {
335
+ const r = D(g);
336
+ if (!r)
337
+ throw new Error(
338
+ "❌ AdaptiveUI Developer Error: You tried to use the 'useAdaptive' hook outside of an <AdaptiveProvider>. Please wrap the root of your application (e.g., App.tsx) with <AdaptiveProvider apiKey='YOUR_KEY'>"
339
+ );
340
+ return r;
341
+ }
342
+ class V extends R {
343
+ static contextType = g;
344
+ constructor(e) {
345
+ super(e), this.state = {
346
+ hasError: !1,
347
+ error: null,
348
+ aiData: null,
349
+ isProcessingAuto: !1
350
+ };
351
+ }
352
+ static getDerivedStateFromError(e) {
353
+ return { hasError: !0, error: e };
354
+ }
355
+ componentDidCatch(e, t) {
356
+ const { mode: o } = this.props;
357
+ o === "manual" && this.props.severity === "low" && A(
358
+ this.props.title,
359
+ this.props.description,
360
+ this.props.actionLabel ?? void 0,
361
+ this.handleRecover
362
+ ), o === "auto" && (this.setState({ isProcessingAuto: !0 }), this.processAutoMode(e));
363
+ }
364
+ processAutoMode = async (e) => {
365
+ const t = this.props, o = t.apiKey || this.context?.apiKey, i = t.apiUrl || this.context?.apiUrl, n = typeof navigator < "u" ? navigator.language : "en-US", m = t.language || this.context?.language || n;
366
+ if (!o) {
367
+ console.error("AdaptiveUI: Missing API Key for auto mode. Provide it via props or <AdaptiveProvider>."), this.setState({ isProcessingAuto: !1 });
368
+ return;
369
+ }
370
+ if (o === "sk_test_mock") {
371
+ setTimeout(() => {
372
+ this.setState({
373
+ isProcessingAuto: !1,
374
+ aiData: {
375
+ severity: "medium",
376
+ title: "Incomplete data",
377
+ description: "The dashboard encountered an error while attempting to read user information. Our team has already been notified.",
378
+ actionLabel: "Reload Widget"
379
+ }
380
+ });
381
+ }, 1500);
382
+ return;
383
+ }
384
+ try {
385
+ const s = x(e.message).slice(0, 500), p = x(e.stack || "").slice(0, 1500), f = await fetch(i || "https://api.cognicatch.dev/v1/analyze-error", {
386
+ method: "POST",
387
+ headers: {
388
+ Authorization: `Bearer ${o}`,
389
+ "Content-Type": "application/json"
390
+ },
391
+ body: JSON.stringify({
392
+ error: s,
393
+ stack: p,
394
+ language: m
395
+ })
396
+ });
397
+ if (!f.ok)
398
+ throw new Error(`SaaS API returned ${f.status}`);
399
+ const u = await f.json();
400
+ u && (u.severity === "low" ? (A(
401
+ u.title,
402
+ u.description,
403
+ u.actionLabel ?? void 0,
404
+ this.handleRecover
405
+ ), this.setState({ isProcessingAuto: !1, hasError: !1, error: null })) : this.setState({ isProcessingAuto: !1, aiData: u }));
406
+ } catch (s) {
407
+ console.error("AdaptiveUI AI Request failed:", s), this.setState({
408
+ isProcessingAuto: !1,
409
+ aiData: {
410
+ severity: "medium",
411
+ title: "Communication Error",
412
+ description: "We were unable to connect to the analytics servers at this time. Our team has already been notified.",
413
+ actionLabel: "Reload Component"
414
+ }
415
+ });
416
+ }
417
+ };
418
+ handleRecover = () => {
419
+ this.setState({ hasError: !1, error: null, aiData: null }), this.props.onRecover && this.props.onRecover();
420
+ };
421
+ render() {
422
+ if (!this.state.hasError)
423
+ return this.props.children;
424
+ const { mode: e, theme: t, className: o } = this.props;
425
+ if (e === "manual") {
426
+ const { severity: i, title: n, description: m, actionLabel: s } = this.props;
427
+ if (i === "high") return /* @__PURE__ */ a(w, { isOpen: !0, onOpenChange: (p) => {
428
+ p || this.handleRecover();
429
+ }, title: n, description: m, theme: t });
430
+ if (i === "medium") return /* @__PURE__ */ a(y, { title: n, description: m, primaryAction: s ? { label: s, onClick: this.handleRecover } : void 0, theme: t, className: o });
431
+ if (i === "low") return null;
432
+ }
433
+ if (e === "auto") {
434
+ if (this.state.isProcessingAuto)
435
+ return /* @__PURE__ */ d("div", { className: "w-full h-full min-h-[100px] rounded-xl border border-zinc-200/50 dark:border-zinc-800/50 bg-zinc-50/50 dark:bg-zinc-900/20 flex flex-col items-center justify-center p-6 animate-pulse", children: [
436
+ /* @__PURE__ */ a("div", { className: "w-5 h-5 border-2 border-indigo-500/30 border-t-indigo-500 rounded-full animate-spin mb-3" }),
437
+ /* @__PURE__ */ a("p", { className: "text-xs font-medium text-zinc-500 dark:text-zinc-400", children: "Analyzing error context..." })
438
+ ] });
439
+ if (this.state.aiData) {
440
+ const { severity: i, title: n, description: m, actionLabel: s } = this.state.aiData;
441
+ if (i === "high")
442
+ return /* @__PURE__ */ a(w, { isOpen: !0, onOpenChange: (p) => {
443
+ p || this.handleRecover();
444
+ }, title: n, description: m, theme: t });
445
+ if (i === "medium")
446
+ return /* @__PURE__ */ a(y, { title: n, description: m, primaryAction: s ? { label: s, onClick: this.handleRecover } : void 0, theme: t, className: o });
447
+ }
448
+ }
449
+ return null;
450
+ }
451
+ }
452
+ export {
453
+ V as AdaptiveErrorBoundary,
454
+ q as AdaptiveProvider,
455
+ W as AdaptiveToastProvider,
456
+ Y as adaptiveToast,
457
+ H as useAdaptive
458
+ };
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "@cognicatch/react",
3
+ "version": "1.0.0",
4
+ "description": "GenUI Error Boundaries and AI Recovery UIs for React",
5
+ "private": false,
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/CogniCatch/react.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/CogniCatch/react/issues"
13
+ },
14
+ "homepage": "https://github.com/CogniCatch/react#readme",
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.cjs",
22
+ "types": "./dist/index.d.ts"
23
+ },
24
+ "./style.css": "./dist/cognicatch-react.css"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "imports": {
30
+ "#/*": "./src/*"
31
+ },
32
+ "scripts": {
33
+ "dev": "vite dev --port 3000",
34
+ "build": "vite build -c vite.config.build.ts",
35
+ "preview": "vite preview",
36
+ "test": "vitest run",
37
+ "format": "biome format",
38
+ "lint": "biome lint",
39
+ "check": "biome check"
40
+ },
41
+ "peerDependencies": {
42
+ "react": "^18.0.0 || ^19.0.0",
43
+ "react-dom": "^18.0.0 || ^19.0.0"
44
+ },
45
+ "dependencies": {
46
+ "@radix-ui/react-dialog": "^1.1.15",
47
+ "@radix-ui/react-slot": "^1.2.4",
48
+ "class-variance-authority": "^0.7.1",
49
+ "clsx": "^2.1.1",
50
+ "lucide-react": "^0.545.0",
51
+ "sonner": "^2.0.7",
52
+ "tailwind-merge": "^3.5.0",
53
+ "zod": "^4.3.6"
54
+ },
55
+ "devDependencies": {
56
+ "@biomejs/biome": "2.2.4",
57
+ "@tailwindcss/vite": "^4.1.18",
58
+ "@tanstack/devtools-vite": "^0.3.11",
59
+ "@tanstack/react-devtools": "^0.7.0",
60
+ "@tanstack/react-router": "^1.132.0",
61
+ "@tanstack/react-router-devtools": "^1.132.0",
62
+ "@tanstack/react-router-ssr-query": "^1.131.7",
63
+ "@tanstack/react-start": "^1.132.0",
64
+ "@tanstack/router-plugin": "^1.132.0",
65
+ "@testing-library/dom": "^10.4.0",
66
+ "@testing-library/react": "^16.2.0",
67
+ "@types/node": "^22.10.2",
68
+ "@types/react": "^19.2.0",
69
+ "@types/react-dom": "^19.2.0",
70
+ "@vitejs/plugin-react": "^5.0.4",
71
+ "jsdom": "^27.0.0",
72
+ "nitro": "npm:nitro-nightly@latest",
73
+ "react": "^19.2.0",
74
+ "react-dom": "^19.2.0",
75
+ "tailwindcss": "^4.1.18",
76
+ "typescript": "^5.7.2",
77
+ "vite": "^7.1.7",
78
+ "vite-plugin-dts": "^4.5.4",
79
+ "vite-tsconfig-paths": "^5.1.4",
80
+ "vitest": "^3.0.5"
81
+ },
82
+ "packageManager": "pnpm@8.6.12+sha1.a2f983fbf8f2531dc85db2a5d7f398063d51a6f3"
83
+ }