blocfeed 0.6.1 → 0.7.1

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.
@@ -30,6 +30,15 @@ interface ThemeConfig {
30
30
  panelBackground?: string;
31
31
  panelForeground?: string;
32
32
  fontFamily?: string;
33
+ /** Color mode. Default: "dark" */
34
+ mode?: "light" | "dark" | "auto";
35
+ }
36
+ type FeedbackCategory = "bug" | "feature" | "ux" | "general";
37
+ interface BlocFeedHandle {
38
+ open: () => void;
39
+ close: () => void;
40
+ submit: (message: string) => Promise<SubmitResult>;
41
+ isOpen: boolean;
33
42
  }
34
43
  interface BlocFeedStrings {
35
44
  triggerLabel?: string;
@@ -46,6 +55,10 @@ interface BlocFeedStrings {
46
55
  successText?: string;
47
56
  toastText?: string;
48
57
  sendButton?: string;
58
+ categoryBug?: string;
59
+ categoryFeature?: string;
60
+ categoryUx?: string;
61
+ categoryGeneral?: string;
49
62
  }
50
63
  interface ConsoleEntry {
51
64
  level: "error" | "warn" | "log";
@@ -73,6 +86,36 @@ interface DiagnosticsConfig {
73
86
  /** Max network entries to retain. Default: 15 */
74
87
  networkLimit?: number;
75
88
  }
89
+ type SecurityScanTarget = "hydration" | "scripts" | "meta" | "dom";
90
+ interface SecurityConfig {
91
+ /** Enable secret leak scanning. Default: true when security config is present. */
92
+ secretScan?: boolean;
93
+ /** Additional regex patterns to scan for. */
94
+ customPatterns?: Array<{
95
+ name: string;
96
+ pattern: RegExp;
97
+ }>;
98
+ /** What to scan. Default: all targets. */
99
+ scanTargets?: SecurityScanTarget[];
100
+ /** Where to report findings. Default: "both" */
101
+ notify?: "dashboard" | "console" | "both";
102
+ }
103
+ interface SecurityFinding {
104
+ /** Which pattern matched. */
105
+ rule: string;
106
+ /** Where it was found. */
107
+ source: SecurityScanTarget;
108
+ /** Truncated/redacted hint (first 6 chars + "***") — NEVER the full secret. */
109
+ hint: string;
110
+ /** Location details (e.g. script index, meta name). */
111
+ location?: string;
112
+ /** Timestamp. */
113
+ timestamp: number;
114
+ }
115
+ interface SecuritySnapshot {
116
+ findings: SecurityFinding[];
117
+ scannedAt: number;
118
+ }
76
119
  interface Rect {
77
120
  x: number;
78
121
  y: number;
@@ -190,6 +233,8 @@ interface BlocFeedConfig {
190
233
  transport?: TransportConfig;
191
234
  /** Diagnostics capture (console logs + failed network requests). */
192
235
  diagnostics?: DiagnosticsConfig;
236
+ /** Client-side secret leak detection. */
237
+ security?: SecurityConfig;
193
238
  ui?: {
194
239
  /** z-index for the widget overlay/panel. */
195
240
  zIndex?: number;
@@ -207,6 +252,15 @@ interface BlocFeedConfig {
207
252
  strings?: BlocFeedStrings;
208
253
  /** Show "Powered by BlocFeed" watermark. Default: true */
209
254
  branding?: boolean;
255
+ /**
256
+ * Restrict widget visibility to specific routes.
257
+ * - `string[]` — route patterns (exact match or wildcard `*` suffix)
258
+ * - `(pathname: string) => boolean` — custom predicate
259
+ * - `undefined` — show on all pages (default)
260
+ */
261
+ showOn?: string[] | ((pathname: string) => boolean);
262
+ /** Which feedback categories to show as pills. Default: all four. */
263
+ categories?: FeedbackCategory[];
210
264
  };
211
265
  }
212
266
  interface ScreenshotIntent {
@@ -226,6 +280,8 @@ interface FeedbackPayload {
226
280
  createdAt: string;
227
281
  blocfeed_id: string;
228
282
  message: string;
283
+ /** Feedback category selected by the user. */
284
+ category?: FeedbackCategory;
229
285
  selection?: ElementDescriptor;
230
286
  screenshots?: CaptureResult;
231
287
  /** Lightweight screenshot metadata sent instead of base64 dataUrls. */
@@ -277,6 +333,7 @@ interface BlocFeedController {
277
333
  setConfig: (nextConfig: BlocFeedConfig) => void;
278
334
  submit: (message: string, options?: {
279
335
  capture?: CaptureConfig;
336
+ category?: FeedbackCategory;
280
337
  }) => Promise<SubmitResult>;
281
338
  /** Internal: used by UI to access the live element handle. */
282
339
  __unsafeGetSelectedElement: () => Element | null;
@@ -284,4 +341,4 @@ interface BlocFeedController {
284
341
  }
285
342
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
286
343
 
287
- export { type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackApiResponse as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type NetworkEntry as N, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedState as a, type BlocFeedController as b, type BlocFeedError as c, type BlocFeedStrings as d, type BlocFeedUser as e, type CaptureDiagnostics as f, type CaptureResult as g, type ConsoleEntry as h, type FeedbackPayload as i, type MetadataConfig as j, type MetadataContext as k, type ScreenshotAdapter as l, type ScreenshotAdapterOptions as m, type ScreenshotIntent as n, type ScreenshotMime as o, type SessionPhase as p, type TransportConfig as q, type TransportResult as r, type TriggerStyle as s, type StateListener as t, createBlocFeedController as u };
344
+ export { type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackCategory as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type NetworkEntry as N, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedHandle as a, type BlocFeedState as b, type BlocFeedController as c, type BlocFeedError as d, type BlocFeedStrings as e, type BlocFeedUser as f, type CaptureDiagnostics as g, type CaptureResult as h, type ConsoleEntry as i, type FeedbackApiResponse as j, type FeedbackPayload as k, type MetadataConfig as l, type MetadataContext as m, type ScreenshotAdapter as n, type ScreenshotAdapterOptions as o, type ScreenshotIntent as p, type ScreenshotMime as q, type SecurityConfig as r, type SecurityFinding as s, type SecuritySnapshot as t, type SessionPhase as u, type TransportConfig as v, type TransportResult as w, type TriggerStyle as x, type StateListener as y, createBlocFeedController as z };
package/dist/engine.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkD5SBICBQ_cjs=require('./chunk-D5SBICBQ.cjs');function c(o){if(o?.aborted)throw new Error("Aborted")}async function b(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function d(o,t){let{width:e,height:r}=await b(o);return {dataUrl:o,mime:t,width:e,height:r}}function E(o){return {async captureElement(t,e){if(!chunkD5SBICBQ_cjs.a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await d(n,e.mime)},async captureFullPage(t){if(!chunkD5SBICBQ_cjs.a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a)),height:Math.max(1,Math.round(n*a)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await d(i,t.mime)}}}function B(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}Object.defineProperty(exports,"clearDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.n}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.h}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.e}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.j}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.c}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.g}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.m}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.f}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.i}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.k}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.d}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.l}});exports.createModernScreenshotAdapter=E;exports.dataUrlToBlob=B;
1
+ 'use strict';var chunkJVY6JTXP_cjs=require('./chunk-JVY6JTXP.cjs');function c(o){if(o?.aborted)throw new Error("Aborted")}async function P(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await P(o);return {dataUrl:o,mime:t,width:e,height:r}}function B(o){return {async captureElement(t,e){if(!chunkJVY6JTXP_cjs.a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!chunkJVY6JTXP_cjs.a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a)),height:Math.max(1,Math.round(n*a)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await l(i,t.mime)}}}function T(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}Object.defineProperty(exports,"clearDiagnostics",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.n}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.h}});Object.defineProperty(exports,"clearSecurityFindings",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.q}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.e}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.j}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.c}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.g}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.m}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.f}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.i}});Object.defineProperty(exports,"getSecurityFindings",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.p}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.k}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.d}});Object.defineProperty(exports,"runSecretScan",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.o}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkJVY6JTXP_cjs.l}});exports.createModernScreenshotAdapter=B;exports.dataUrlToBlob=T;
package/dist/engine.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { l as ScreenshotAdapter, C as CaptureConfig, g as CaptureResult, j as MetadataConfig, k as MetadataContext, e as BlocFeedUser, i as FeedbackPayload } from './controller-DfhbkHXc.cjs';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, d as BlocFeedStrings, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, t as StateListener, S as SubmitResult, T as ThemeConfig, q as TransportConfig, s as TriggerStyle, W as WidgetPosition, u as createBlocFeedController } from './controller-DfhbkHXc.cjs';
1
+ import { n as ScreenshotAdapter, C as CaptureConfig, h as CaptureResult, l as MetadataConfig, m as MetadataContext, f as BlocFeedUser, k as FeedbackPayload, t as SecuritySnapshot, r as SecurityConfig } from './controller-BPsU7cuY.cjs';
2
+ export { B as BlocFeedConfig, c as BlocFeedController, d as BlocFeedError, a as BlocFeedHandle, b as BlocFeedState, e as BlocFeedStrings, i as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, j as FeedbackApiResponse, F as FeedbackCategory, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, o as ScreenshotAdapterOptions, p as ScreenshotIntent, q as ScreenshotMime, s as SecurityFinding, u as SessionPhase, y as StateListener, S as SubmitResult, T as ThemeConfig, v as TransportConfig, x as TriggerStyle, W as WidgetPosition, z as createBlocFeedController } from './controller-BPsU7cuY.cjs';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
@@ -110,6 +110,19 @@ declare function drainDiagnostics(): DiagnosticsSnapshot;
110
110
  */
111
111
  declare function clearDiagnostics(): void;
112
112
 
113
+ /**
114
+ * Run the secret scan once. Safe to call multiple times — subsequent calls are no-ops.
115
+ */
116
+ declare function runSecretScan(config?: SecurityConfig): void;
117
+ /**
118
+ * Return a copy of all findings (non-destructive).
119
+ */
120
+ declare function getSecurityFindings(): SecuritySnapshot;
121
+ /**
122
+ * Clear all findings and reset state.
123
+ */
124
+ declare function clearSecurityFindings(): void;
125
+
113
126
  declare function dataUrlToBlob(dataUrl: string): Blob;
114
127
 
115
- export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearDiagnostics, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, installDiagnostics, runCapture, uninstallDiagnostics };
128
+ export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, SecurityConfig, SecuritySnapshot, clearDiagnostics, clearQueue, clearSecurityFindings, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, getSecurityFindings, installDiagnostics, runCapture, runSecretScan, uninstallDiagnostics };
package/dist/engine.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { l as ScreenshotAdapter, C as CaptureConfig, g as CaptureResult, j as MetadataConfig, k as MetadataContext, e as BlocFeedUser, i as FeedbackPayload } from './controller-DfhbkHXc.js';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, d as BlocFeedStrings, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, t as StateListener, S as SubmitResult, T as ThemeConfig, q as TransportConfig, s as TriggerStyle, W as WidgetPosition, u as createBlocFeedController } from './controller-DfhbkHXc.js';
1
+ import { n as ScreenshotAdapter, C as CaptureConfig, h as CaptureResult, l as MetadataConfig, m as MetadataContext, f as BlocFeedUser, k as FeedbackPayload, t as SecuritySnapshot, r as SecurityConfig } from './controller-BPsU7cuY.js';
2
+ export { B as BlocFeedConfig, c as BlocFeedController, d as BlocFeedError, a as BlocFeedHandle, b as BlocFeedState, e as BlocFeedStrings, i as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, j as FeedbackApiResponse, F as FeedbackCategory, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, o as ScreenshotAdapterOptions, p as ScreenshotIntent, q as ScreenshotMime, s as SecurityFinding, u as SessionPhase, y as StateListener, S as SubmitResult, T as ThemeConfig, v as TransportConfig, x as TriggerStyle, W as WidgetPosition, z as createBlocFeedController } from './controller-BPsU7cuY.js';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
@@ -110,6 +110,19 @@ declare function drainDiagnostics(): DiagnosticsSnapshot;
110
110
  */
111
111
  declare function clearDiagnostics(): void;
112
112
 
113
+ /**
114
+ * Run the secret scan once. Safe to call multiple times — subsequent calls are no-ops.
115
+ */
116
+ declare function runSecretScan(config?: SecurityConfig): void;
117
+ /**
118
+ * Return a copy of all findings (non-destructive).
119
+ */
120
+ declare function getSecurityFindings(): SecuritySnapshot;
121
+ /**
122
+ * Clear all findings and reset state.
123
+ */
124
+ declare function clearSecurityFindings(): void;
125
+
113
126
  declare function dataUrlToBlob(dataUrl: string): Blob;
114
127
 
115
- export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearDiagnostics, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, installDiagnostics, runCapture, uninstallDiagnostics };
128
+ export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, SecurityConfig, SecuritySnapshot, clearDiagnostics, clearQueue, clearSecurityFindings, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, getSecurityFindings, installDiagnostics, runCapture, runSecretScan, uninstallDiagnostics };
package/dist/engine.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-QPAFC4IL.js';export{n as clearDiagnostics,h as clearQueue,e as collectMetadata,j as createBlocFeedController,c as createHtmlToImageAdapter,g as dequeueAll,m as drainDiagnostics,f as enqueue,i as getQueueSize,k as installDiagnostics,d as runCapture,l as uninstallDiagnostics}from'./chunk-QPAFC4IL.js';function c(o){if(o?.aborted)throw new Error("Aborted")}async function b(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function d(o,t){let{width:e,height:r}=await b(o);return {dataUrl:o,mime:t,width:e,height:r}}function E(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await d(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a$1=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a$1)),height:Math.max(1,Math.round(n*a$1)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await d(i,t.mime)}}}function B(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}export{E as createModernScreenshotAdapter,B as dataUrlToBlob};
1
+ import {a}from'./chunk-LAK7UUTC.js';export{n as clearDiagnostics,h as clearQueue,q as clearSecurityFindings,e as collectMetadata,j as createBlocFeedController,c as createHtmlToImageAdapter,g as dequeueAll,m as drainDiagnostics,f as enqueue,i as getQueueSize,p as getSecurityFindings,k as installDiagnostics,d as runCapture,o as runSecretScan,l as uninstallDiagnostics}from'./chunk-LAK7UUTC.js';function c(o){if(o?.aborted)throw new Error("Aborted")}async function P(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await P(o);return {dataUrl:o,mime:t,width:e,height:r}}function B(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a$1=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a$1)),height:Math.max(1,Math.round(n*a$1)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await l(i,t.mime)}}}function T(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}export{B as createModernScreenshotAdapter,T as dataUrlToBlob};
package/dist/main.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- 'use strict';var chunkD5SBICBQ_cjs=require('./chunk-D5SBICBQ.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var $=react.createContext(null);function J(e){let t=react.useMemo(()=>chunkD5SBICBQ_cjs.j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[l,i]=react.useState(()=>t.getState());return react.useEffect(()=>t.subscribe(i),[t]),react.useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),react.useEffect(()=>()=>t.destroy(),[t]),jsxRuntime.jsx($.Provider,{value:{controller:t,state:l},children:e.children})}var be="blocfeed-styles-v1",ct=`
2
+ 'use strict';var chunkJVY6JTXP_cjs=require('./chunk-JVY6JTXP.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var U=react.createContext(null);function ee(e){let t=react.useMemo(()=>chunkJVY6JTXP_cjs.j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[n,o]=react.useState(()=>t.getState());return react.useEffect(()=>t.subscribe(o),[t]),react.useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),react.useEffect(()=>()=>t.destroy(),[t]),jsxRuntime.jsx(U.Provider,{value:{controller:t,state:n},children:e.children})}var we="blocfeed-styles-v1",xt=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -20,6 +20,52 @@
20
20
  color: var(--bf-panel-fg);
21
21
  }
22
22
 
23
+ /* ------------------------------------------------------------------ */
24
+ /* Light theme */
25
+ /* ------------------------------------------------------------------ */
26
+
27
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) {
28
+ --bf-panel-bg: rgba(255, 255, 255, 0.98);
29
+ --bf-panel-fg: rgb(17, 24, 39);
30
+ --bf-muted: rgba(17, 24, 39, 0.6);
31
+ --bf-border: rgba(0, 0, 0, 0.12);
32
+ --bf-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
33
+ }
34
+
35
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-textarea {
36
+ border-color: rgba(0, 0, 0, 0.14);
37
+ background: rgba(0, 0, 0, 0.04);
38
+ color: var(--bf-panel-fg);
39
+ }
40
+
41
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-panelHeader {
42
+ border-bottom-color: rgba(0, 0, 0, 0.08);
43
+ }
44
+
45
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-title {
46
+ color: rgba(17, 24, 39, 0.85);
47
+ }
48
+
49
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-error {
50
+ color: rgb(185, 28, 28);
51
+ }
52
+
53
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-watermark a {
54
+ color: rgba(17, 24, 39, 0.35);
55
+ }
56
+
57
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-watermark {
58
+ border-top-color: rgba(0, 0, 0, 0.06);
59
+ }
60
+
61
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-highlight {
62
+ box-shadow: 0 0 0 9999px rgba(255, 255, 255, 0.42);
63
+ }
64
+
65
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-blocker {
66
+ background: rgba(255, 255, 255, 0.35);
67
+ }
68
+
23
69
  /* ------------------------------------------------------------------ */
24
70
  /* Trigger button \u2014 default bottom-right */
25
71
  /* ------------------------------------------------------------------ */
@@ -272,6 +318,45 @@
272
318
  color: rgba(243, 244, 246, 0.9);
273
319
  }
274
320
 
321
+ /* ------------------------------------------------------------------ */
322
+ /* Category pills */
323
+ /* ------------------------------------------------------------------ */
324
+
325
+ :where([data-blocfeed-ui-root]) .bf-pills {
326
+ display: flex;
327
+ flex-wrap: wrap;
328
+ gap: 6px;
329
+ }
330
+
331
+ :where([data-blocfeed-ui-root]) .bf-pill {
332
+ padding: 4px 10px;
333
+ border-radius: 999px;
334
+ border: 1px solid var(--bf-border);
335
+ background: transparent;
336
+ color: var(--bf-muted);
337
+ font-size: 12px;
338
+ font-family: var(--bf-font);
339
+ cursor: pointer;
340
+ user-select: none;
341
+ transition: border-color 0.15s, color 0.15s, background 0.15s;
342
+ }
343
+
344
+ :where([data-blocfeed-ui-root]) .bf-pill:hover {
345
+ border-color: var(--bf-accent);
346
+ color: var(--bf-panel-fg);
347
+ }
348
+
349
+ :where([data-blocfeed-ui-root]) .bf-pill-active {
350
+ border-color: var(--bf-accent);
351
+ background: var(--bf-accent);
352
+ color: white;
353
+ }
354
+
355
+ :where([data-blocfeed-ui-root]) .bf-pill[disabled] {
356
+ opacity: 0.6;
357
+ cursor: not-allowed;
358
+ }
359
+
275
360
  /* ------------------------------------------------------------------ */
276
361
  /* Capture spinner (item 12) */
277
362
  /* ------------------------------------------------------------------ */
@@ -463,6 +548,57 @@
463
548
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
464
549
  }
465
550
 
551
+ /* ------------------------------------------------------------------ */
552
+ /* Security warning banner */
553
+ /* ------------------------------------------------------------------ */
554
+
555
+ :where([data-blocfeed-ui-root]) .bf-security-banner {
556
+ position: fixed;
557
+ top: 8px;
558
+ right: 8px;
559
+ z-index: var(--bf-z);
560
+ max-width: 360px;
561
+ padding: 10px 14px;
562
+ border-radius: 10px;
563
+ border-left: 3px solid var(--bf-danger);
564
+ background: rgba(239, 68, 68, 0.12);
565
+ color: rgb(254, 202, 202);
566
+ font-family: var(--bf-font);
567
+ font-size: 12px;
568
+ line-height: 1.5;
569
+ pointer-events: auto;
570
+ animation: bf-panel-in 0.2s ease-out;
571
+ }
572
+
573
+ :where([data-blocfeed-ui-root][data-bf-theme="light"]) .bf-security-banner {
574
+ background: rgba(239, 68, 68, 0.08);
575
+ color: rgb(185, 28, 28);
576
+ }
577
+
578
+ :where([data-blocfeed-ui-root]) .bf-security-banner strong {
579
+ display: block;
580
+ margin-bottom: 4px;
581
+ font-size: 13px;
582
+ }
583
+
584
+ :where([data-blocfeed-ui-root]) .bf-security-banner-dismiss {
585
+ position: absolute;
586
+ top: 6px;
587
+ right: 6px;
588
+ background: none;
589
+ border: none;
590
+ color: inherit;
591
+ opacity: 0.6;
592
+ cursor: pointer;
593
+ padding: 2px 4px;
594
+ font-size: 14px;
595
+ line-height: 1;
596
+ }
597
+
598
+ :where([data-blocfeed-ui-root]) .bf-security-banner-dismiss:hover {
599
+ opacity: 1;
600
+ }
601
+
466
602
  /* ------------------------------------------------------------------ */
467
603
  /* Reduced motion */
468
604
  /* ------------------------------------------------------------------ */
@@ -499,5 +635,5 @@
499
635
  animation: none;
500
636
  }
501
637
  }
502
- `;function ge(){if(!chunkD5SBICBQ_cjs.a()||document.getElementById(be))return;let e=document.createElement("style");e.id=be,e.textContent=ct,document.head.appendChild(e);}var me={triggerLabel:"Feedback",panelTitle:"Feedback",hintText:"Click an element to attach your feedback. Press Esc to cancel.",cancelButton:"Cancel",rePickButton:"Re-pick",closeButton:"Close",textareaPlaceholder:"What's happening? What did you expect?",screenshotElement:"Screenshot element",screenshotFullPage:"Full page",capturingText:"Capturing screenshots\u2026",submittingText:"Submitting\u2026",successText:"Sent. Thank you!",toastText:"Feedback sent",sendButton:"Send"};function he(e){return e?{...me,...e}:me}function Z(){let e=react.useContext($);if(!e)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:e.state,controller:e.controller,start:e.controller.start,stop:e.controller.stop,clearSelection:e.controller.clearSelection,submit:e.controller.submit}}function m(e){switch(e){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function f({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function xe({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ye({size:e=16}){return jsxRuntime.jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function we({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){return l?jsxRuntime.jsxs("button",{className:m(e),type:"button",onClick:t,"aria-label":i,children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function b(){let[e,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return react.useEffect(()=>{let l=window.matchMedia("(prefers-reduced-motion: reduce)"),i=r=>t(r.matches);return l.addEventListener("change",i),()=>l.removeEventListener("change",i)},[]),e}var mt={duration:.18,ease:"easeOut"},ht={duration:0};function Te({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?ht:mt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:o?{}:{scale:a?1:[1,1.2,1],boxShadow:a?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"dot")})}var wt={duration:.18,ease:"easeOut"},Ee={duration:0};function Ce({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ee:wt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsxs(framerMotion.motion.div,{className:m(e),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:n,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:o?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:o?0:4},transition:n,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:i},"tooltip")}),jsxRuntime.jsxs(framerMotion.motion.button,{type:"button",onClick:t,"aria-label":i,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:o?{}:{y:[0,-3,0]},transition:o?Ee:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:16})},"success"):jsxRuntime.jsx(xe,{size:16}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var Pt={duration:.2,ease:"easeOut"},Et={duration:0};function Be(e){return e==="bottom-left"||e==="top-left"}function St(e){return `bf-trigger-edge ${Be(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Fe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=Be(e),n=b(),u=n?Et:Pt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:St(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,width:0},animate:{opacity:1,width:a?140:22,height:a?40:90},exit:{width:0,opacity:0},transition:u,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:n||a?0:o?-90:90,opacity:a?1:.6},transition:u,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),i]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:a?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[o?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"edge-tab")})}var Bt={duration:.18,ease:"easeOut"},Ft={duration:0};function Me({delay:e,hovered:t,reduced:l}){return l?null:jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:t?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:t?{duration:.15}:{duration:2,repeat:1/0,delay:e,ease:"easeOut"}})}function ze({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ft:Bt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(Me,{delay:0,hovered:a,reduced:o}),jsxRuntime.jsx(Me,{delay:.7,hovered:a,reduced:o}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"pulse-ring")})}var zt={duration:.18,ease:"easeOut"},It={duration:0};function At(e){switch(e){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function We({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?It:zt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsxs(framerMotion.motion.button,{className:At(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:o?0:5},animate:{opacity:a?1:.65,y:0},exit:{opacity:0,y:o?0:5},transition:n,whileTap:{scale:.95},children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{children:i}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!o&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:a?1:0},transition:n})]},"minimal")})}var Ot={duration:.18,ease:"easeOut"},Ht={duration:0};function Oe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ht:Ot;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:o?{}:a?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:a||o?n:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(ye,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-8},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"icon-pop")})}var Xt={duration:.18,ease:"easeOut"},Yt={duration:0};function Ke({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Yt:Xt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:o?{}:{opacity:a?1:[.5,1,.5],boxShadow:a?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),!a&&!o&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"beacon")})}var Gt={duration:.18,ease:"easeOut"},Jt={duration:0};function Ue({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),[o,n]=react.useState(0),u=b(),H=u?Jt:Gt,g=react.useRef(null);react.useEffect(()=>{if(g.current&&(clearInterval(g.current),g.current=null),!l||a||u){n(a||u?i.length:0);return}let E=8,K=i.length*2+E*2,x=0;return g.current=setInterval(()=>{x=(x+1)%K,x<=i.length?n(x):x<=i.length+E?n(i.length):x<=i.length*2+E?n(i.length*2+E-x):n(0);},100),()=>{g.current&&(clearInterval(g.current),g.current=null);}},[l,a,u,i]);let D=i.slice(0,o);return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:u?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:u?0:5},transition:H,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:H,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxRuntime.jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[D,jsxRuntime.jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"typewriter")})}function je(e){switch(e){case "dot":return Te;case "bubble":return Ce;case "edge-tab":return Fe;case "pulse-ring":return ze;case "minimal":return We;case "icon-pop":return Oe;case "beacon":return Ke;case "typewriter":return Ue;default:return we}}function Ve(e,t,l){return Math.max(t,Math.min(l,e))}function eo(e,t,l="bottom-right"){let r=window.innerWidth,c=window.innerHeight,a;a=Ve(e.x,12,Math.max(12,r-t-12));let s=e.y+e.height+12,o=Math.max(12,e.y-240);return {top:s+240<=c?s:o,left:a}}function to(e){let{rect:t}=e,l={left:`${t.x}px`,top:`${t.y}px`,width:`${Math.max(0,t.width)}px`,height:`${Math.max(0,t.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:l,"aria-hidden":"true"})}function oo(e){let t=react.useRef(null);return react.useEffect(()=>{if(!e||!t.current)return;t.current.querySelector(".bf-textarea")?.focus();let i=r=>{if(r.key!=="Tab"||!t.current)return;let c=t.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let a=c[0],s=c[c.length-1];r.shiftKey&&document.activeElement===a?(r.preventDefault(),s.focus()):!r.shiftKey&&document.activeElement===s&&(r.preventDefault(),a.focus());};return document.addEventListener("keydown",i,{capture:true}),()=>document.removeEventListener("keydown",i,{capture:true})},[e]),t}function ro(e){let{state:t,controller:l,start:i,stop:r,clearSelection:c,submit:a}=Z(),s=e.config.ui?.position,o=he(e.config.ui?.strings),n=e.config.ui?.branding!==false,[u,H]=react.useState(null),[g,D]=react.useState(""),[E,K]=react.useState(e.config.capture?.element??true),[x,ee]=react.useState(e.config.capture?.fullPage??false),[Je,te]=react.useState(null),oe=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",Ze=oo(oe),[qe,et]=react.useState(0);react.useEffect(()=>{t.phase==="idle"&&et(chunkD5SBICBQ_cjs.i());},[t.phase]);let[tt,re]=react.useState(false),ie=react.useRef(t.phase);react.useEffect(()=>{if(ie.current==="success"&&t.phase==="idle"){re(true);let p=window.setTimeout(()=>re(false),1500);return ()=>window.clearTimeout(p)}ie.current=t.phase;},[t.phase]),react.useEffect(()=>{let p=e.config.ui?.shortcut;if(!p)return;let L=p.toLowerCase().split("+").map(v=>v.trim()),z=L[L.length-1]||"",B=new Set(L.slice(0,-1)),ae=v=>{let it=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(B.has("mod")){if(it?!v.metaKey:!v.ctrlKey)return}else if(B.has("ctrl")&&!v.ctrlKey||(B.has("meta")||B.has("cmd"))&&!v.metaKey)return;B.has("shift")&&!v.shiftKey||(B.has("alt")||B.has("option"))&&!v.altKey||v.key.toLowerCase()===z&&(v.preventDefault(),t.phase==="idle"?i():r());};return document.addEventListener("keydown",ae),()=>document.removeEventListener("keydown",ae)},[e.config.ui?.shortcut,t.phase,i,r]),react.useEffect(()=>l.subscribeHover(H),[l]),react.useEffect(()=>{let p=l.__unsafeGetSelectedElement();if(!p||t.phase==="idle"||t.phase==="picking"){te(null);return}let L=()=>{te(chunkD5SBICBQ_cjs.b(p.getBoundingClientRect()));};L();let z=()=>L();return window.addEventListener("scroll",z,{capture:true,passive:true}),window.addEventListener("resize",z,{passive:true}),()=>{window.removeEventListener("scroll",z,{capture:true}),window.removeEventListener("resize",z);}},[l,t.phase,t.selection?.selector]),react.useEffect(()=>{t.phase==="review"&&(D(""),K(e.config.capture?.element??true),ee(e.config.capture?.fullPage??false));},[t.phase,t.selection?.selector,e.config.capture?.element,e.config.capture?.fullPage]),react.useEffect(()=>{if(t.phase!=="success")return;let p=window.setTimeout(()=>r(),1200);return ()=>window.clearTimeout(p)},[t.phase,r]);let k=t.phase==="capturing"||t.phase==="submitting",S=t.phase==="picking"?u?.rect??null:Je??t.selection?.rect??null,Q=react.useMemo(()=>S?eo(S,360,s):null,[S?.x,S?.y,S?.width,S?.height,s]),ne=t.lastError?.message,V=react.useCallback(()=>{a(g,{capture:{element:E,fullPage:x}});},[a,g,E,x]),ot=react.useCallback(p=>{(p.metaKey||p.ctrlKey)&&p.key==="Enter"&&g.trim().length>0&&!k&&(p.preventDefault(),V());},[V,g,k]),rt=je(e.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(rt,{position:s,onClick:()=>i(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??o.triggerLabel,queueCount:qe,showSuccess:tt}),t.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),S&&jsxRuntime.jsx(to,{rect:S}),t.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("p",{id:"bf-hint-text",children:o.hintText}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":o.cancelButton,children:o.cancelButton})]}),oe&&Q&&jsxRuntime.jsxs("div",{ref:Ze,className:"bf-panel",style:{left:Q.left,top:Q.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:o.panelTitle}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:k,"aria-label":o.rePickButton,children:o.rePickButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.closeButton,children:o.closeButton})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:o.textareaPlaceholder,value:g,onChange:p=>D(p.target.value),onKeyDown:ot,disabled:k,"aria-label":o.panelTitle}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":o.screenshotElement,children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:E,onChange:p=>K(p.target.checked),disabled:k}),o.screenshotElement]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:x,onChange:p=>ee(p.target.checked),disabled:k}),o.screenshotFullPage]})]}),t.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.capturingText]}),t.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.submittingText]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:o.successText}),t.phase==="error"&&ne&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:ne}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.cancelButton,children:o.cancelButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:k||g.trim().length===0,"aria-label":o.sendButton,children:o.sendButton})]})]}),n&&jsxRuntime.jsx("div",{className:"bf-watermark",children:jsxRuntime.jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:o.toastText})]})}function io(e){let t={...e.config??{},blocfeed_id:e.blocfeed_id},[l,i]=react.useState(null),r=!!t.diagnostics;react.useEffect(()=>{if(r)return chunkD5SBICBQ_cjs.k(t.diagnostics),()=>chunkD5SBICBQ_cjs.l()},[r]);let c=react.useRef(e.config?.metadata?.enrich);c.current=e.config?.metadata?.enrich;let a=react.useMemo(()=>{if(e.config)return {...e.config,metadata:{...e.config.metadata,enrich:async s=>{let o=c.current,n=o?await o(s):{},u=chunkD5SBICBQ_cjs.m();return {...n,...u.consoleLogs.length>0?{_consoleLogs:u.consoleLogs}:{},...u.networkErrors.length>0?{_networkErrors:u.networkErrors}:{}}}}}},[]);return react.useEffect(()=>{ge();let s=document.createElement("div");s.setAttribute("data-blocfeed-ui-root","true"),s.setAttribute("data-blocfeed-ui","true");let o=t.ui?.zIndex;typeof o=="number"&&s.style.setProperty("--bf-z",String(o));let n=t.ui?.theme;return n&&(n.accentColor&&s.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&s.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&s.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&s.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(s),i(s),()=>{s.remove(),i(null);}},[t.ui?.zIndex,t.ui?.theme?.accentColor,t.ui?.theme?.panelBackground,t.ui?.theme?.panelForeground,t.ui?.theme?.fontFamily]),l?reactDom.createPortal(jsxRuntime.jsx(J,{blocfeed_id:t.blocfeed_id,...a?{config:a}:{},children:jsxRuntime.jsx(ro,{config:t})}),l):null}
503
- exports.BlocFeedProvider=J;exports.BlocFeedWidget=io;exports.useBlocFeed=Z;
638
+ `;function ve(){if(!chunkJVY6JTXP_cjs.a()||document.getElementById(we))return;let e=document.createElement("style");e.id=we,e.textContent=xt,document.head.appendChild(e);}var ke={triggerLabel:"Feedback",panelTitle:"Feedback",hintText:"Click an element to attach your feedback. Press Esc to cancel.",cancelButton:"Cancel",rePickButton:"Re-pick",closeButton:"Close",textareaPlaceholder:"What's happening? What did you expect?",screenshotElement:"Screenshot element",screenshotFullPage:"Full page",capturingText:"Capturing screenshots\u2026",submittingText:"Submitting\u2026",successText:"Sent. Thank you!",toastText:"Feedback sent",sendButton:"Send",categoryBug:"Bug",categoryFeature:"Feature",categoryUx:"UX",categoryGeneral:"General"};function Te(e){return e?{...ke,...e}:ke}function te(){let e=react.useContext(U);if(!e)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:e.state,controller:e.controller,start:e.controller.start,stop:e.controller.stop,clearSelection:e.controller.clearSelection,submit:e.controller.submit}}function y(e){switch(e){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function b({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function Se({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function Pe({size:e=16}){return jsxRuntime.jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function Ce({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){return n?jsxRuntime.jsxs("button",{className:y(e),type:"button",onClick:t,"aria-label":o,children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),o]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function g(){let[e,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return react.useEffect(()=>{let n=window.matchMedia("(prefers-reduced-motion: reduce)"),o=r=>t(r.matches);return n.addEventListener("change",o),()=>n.removeEventListener("change",o)},[]),e}var Pt={duration:.18,ease:"easeOut"},Et={duration:0};function Be({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?Et:Pt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:y(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:a?{}:{scale:i?1:[1,1.2,1],boxShadow:i?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:i||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:o},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"dot")})}var Nt={duration:.18,ease:"easeOut"},Re={duration:0};function Le({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?Re:Nt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsxs(framerMotion.motion.div,{className:y(e),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:s,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:a?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:a?0:4},transition:s,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:o},"tooltip")}),jsxRuntime.jsxs(framerMotion.motion.button,{type:"button",onClick:t,"aria-label":o,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:a?{}:{y:[0,-3,0]},transition:a?Re:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:16})},"success"):jsxRuntime.jsx(Se,{size:16}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var Lt={duration:.2,ease:"easeOut"},zt={duration:0};function Ae(e){return e==="bottom-left"||e==="top-left"}function At(e){return `bf-trigger-edge ${Ae(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Ie({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=Ae(e),s=g(),m=s?zt:Lt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:At(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,width:0},animate:{opacity:1,width:i?140:22,height:i?40:90},exit:{width:0,opacity:0},transition:m,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:m,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:s||i?0:a?-90:90,opacity:i?1:.6},transition:m,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[i&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),o]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:i?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[a?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"edge-tab")})}var _t={duration:.18,ease:"easeOut"},Ht={duration:0};function _e({delay:e,hovered:t,reduced:n}){return n?null:jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:t?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:t?{duration:.15}:{duration:2,repeat:1/0,delay:e,ease:"easeOut"}})}function Oe({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?Ht:_t;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:y(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(_e,{delay:0,hovered:i,reduced:a}),jsxRuntime.jsx(_e,{delay:.7,hovered:i,reduced:a}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:o},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"pulse-ring")})}var $t={duration:.18,ease:"easeOut"},Ut={duration:0};function Xt(e){switch(e){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function $e({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?Ut:$t;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsxs(framerMotion.motion.button,{className:Xt(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:a?0:5},animate:{opacity:i?1:.65,y:0},exit:{opacity:0,y:a?0:5},transition:s,whileTap:{scale:.95},children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{children:o}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!a&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:i?1:0},transition:s})]},"minimal")})}var Qt={duration:.18,ease:"easeOut"},jt={duration:0};function Xe({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?jt:Qt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:y(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:a?{}:i?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:i||a?s:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(Pe,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-8},transition:s,style:{whiteSpace:"nowrap"},children:o},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"icon-pop")})}var Zt={duration:.18,ease:"easeOut"},eo={duration:0};function Qe({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),a=g(),s=a?eo:Zt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:y(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:a?{}:{opacity:i?1:[.5,1,.5],boxShadow:i?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:i||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),!i&&!a&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:o},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"beacon")})}var io={duration:.18,ease:"easeOut"},no={duration:0};function Je({position:e,onClick:t,isVisible:n,label:o,queueCount:r,showSuccess:c}){let[i,l]=react.useState(false),[a,s]=react.useState(0),m=g(),M=m?no:io,p=react.useRef(null);react.useEffect(()=>{if(p.current&&(clearInterval(p.current),p.current=null),!n||i||m){s(i||m?o.length:0);return}let u=8,E=o.length*2+u*2,x=0;return p.current=setInterval(()=>{x=(x+1)%E,x<=o.length?s(x):x<=o.length+u?s(o.length):x<=o.length*2+u?s(o.length*2+u-x):s(0);},100),()=>{p.current&&(clearInterval(p.current),p.current=null);}},[n,i,m,o]);let T=o.slice(0,a);return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:y(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:m?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:m?0:5},transition:M,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:M,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxRuntime.jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[T,jsxRuntime.jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"typewriter")})}function Ze(e){switch(e){case "dot":return Be;case "bubble":return Le;case "edge-tab":return Ie;case "pulse-ring":return Oe;case "minimal":return $e;case "icon-pop":return Xe;case "beacon":return Qe;case "typewriter":return Je;default:return Ce}}function tt(e,t,n){return Math.max(t,Math.min(n,e))}function fo(e,t,n="bottom-right"){let r=window.innerWidth,c=window.innerHeight,i;i=tt(e.x,12,Math.max(12,r-t-12));let l=e.y+e.height+12,a=Math.max(12,e.y-240);return {top:l+240<=c?l:a,left:i}}function uo(e){let{rect:t}=e,n={left:`${t.x}px`,top:`${t.y}px`,width:`${Math.max(0,t.width)}px`,height:`${Math.max(0,t.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:n,"aria-hidden":"true"})}function bo(e){let t=react.useRef(null);return react.useEffect(()=>{if(!e||!t.current)return;t.current.querySelector(".bf-textarea")?.focus();let o=r=>{if(r.key!=="Tab"||!t.current)return;let c=t.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let i=c[0],l=c[c.length-1];r.shiftKey&&document.activeElement===i?(r.preventDefault(),l.focus()):!r.shiftKey&&document.activeElement===l&&(r.preventDefault(),i.focus());};return document.addEventListener("keydown",o,{capture:true}),()=>document.removeEventListener("keydown",o,{capture:true})},[e]),t}function go(e,t){return e?typeof e=="function"?e(t):e.some(n=>n.endsWith("*")?t.startsWith(n.slice(0,-1)):t===n):true}function mo(e){let[t,n]=react.useState(()=>typeof window<"u"?window.location.pathname:"/");return react.useEffect(()=>{if(typeof window>"u")return;let o=()=>n(window.location.pathname);window.addEventListener("popstate",o);let r=history.pushState,c=history.replaceState;return history.pushState=function(...i){r.apply(this,i),o();},history.replaceState=function(...i){c.apply(this,i),o();},()=>{window.removeEventListener("popstate",o),history.pushState=r,history.replaceState=c;}},[]),go(e,t)}function ho(e){let[t,n]=react.useState(()=>!e||e==="dark"?"dark":e==="light"?"light":typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return react.useEffect(()=>{if(e!=="auto"){n(e==="light"?"light":"dark");return}let o=window.matchMedia("(prefers-color-scheme: dark)"),r=c=>n(c.matches?"dark":"light");return n(o.matches?"dark":"light"),o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e]),t}var xo=["bug","feature","ux","general"],yo={bug:"categoryBug",feature:"categoryFeature",ux:"categoryUx",general:"categoryGeneral"};function wo(e){let{state:t,controller:n,start:o,stop:r,clearSelection:c,submit:i}=te(),l=e.config.ui?.position,a=Te(e.config.ui?.strings),s=e.config.ui?.branding!==false,[m,M]=react.useState(null),[p,T]=react.useState(""),[u,E]=react.useState(e.config.capture?.element??true),[x,re]=react.useState(e.config.capture?.fullPage??false),[rt,ae]=react.useState(null),[O,ie]=react.useState(void 0),ne=e.config.ui?.categories??xo,[at,it]=react.useState(false),[j,nt]=react.useState(0);react.useEffect(()=>{let d=window.setTimeout(()=>{let N=chunkJVY6JTXP_cjs.p();nt(N.findings.length);},500);return ()=>window.clearTimeout(d)},[]),react.useImperativeHandle(e.handleRef,()=>({open:o,close:r,submit:d=>i(d),get isOpen(){return t.phase!=="idle"}}),[o,r,i,t.phase]);let se=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",st=bo(se),[lt,ct]=react.useState(0);react.useEffect(()=>{t.phase==="idle"&&ct(chunkJVY6JTXP_cjs.i());},[t.phase]);let[dt,le]=react.useState(false),ce=react.useRef(t.phase);react.useEffect(()=>{if(ce.current==="success"&&t.phase==="idle"){le(true);let d=window.setTimeout(()=>le(false),1500);return ()=>window.clearTimeout(d)}ce.current=t.phase;},[t.phase]),react.useEffect(()=>{let d=e.config.ui?.shortcut;if(!d)return;let N=d.toLowerCase().split("+").map(P=>P.trim()),W=N[N.length-1]||"",L=new Set(N.slice(0,-1)),pe=P=>{let ut=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(L.has("mod")){if(ut?!P.metaKey:!P.ctrlKey)return}else if(L.has("ctrl")&&!P.ctrlKey||(L.has("meta")||L.has("cmd"))&&!P.metaKey)return;L.has("shift")&&!P.shiftKey||(L.has("alt")||L.has("option"))&&!P.altKey||P.key.toLowerCase()===W&&(P.preventDefault(),t.phase==="idle"?o():r());};return document.addEventListener("keydown",pe),()=>document.removeEventListener("keydown",pe)},[e.config.ui?.shortcut,t.phase,o,r]),react.useEffect(()=>n.subscribeHover(M),[n]),react.useEffect(()=>{let d=n.__unsafeGetSelectedElement();if(!d||t.phase==="idle"||t.phase==="picking"){ae(null);return}let N=()=>{ae(chunkJVY6JTXP_cjs.b(d.getBoundingClientRect()));};N();let W=()=>N();return window.addEventListener("scroll",W,{capture:true,passive:true}),window.addEventListener("resize",W,{passive:true}),()=>{window.removeEventListener("scroll",W,{capture:true}),window.removeEventListener("resize",W);}},[n,t.phase,t.selection?.selector]),react.useEffect(()=>{t.phase==="review"&&(T(""),E(e.config.capture?.element??true),re(e.config.capture?.fullPage??false),ie(void 0));},[t.phase,t.selection?.selector,e.config.capture?.element,e.config.capture?.fullPage]),react.useEffect(()=>{if(t.phase!=="success")return;let d=window.setTimeout(()=>r(),1200);return ()=>window.clearTimeout(d)},[t.phase,r]);let S=t.phase==="capturing"||t.phase==="submitting",B=t.phase==="picking"?m?.rect??null:rt??t.selection?.rect??null,V=react.useMemo(()=>B?fo(B,360,l):null,[B?.x,B?.y,B?.width,B?.height,l]),de=t.lastError?.message,q=react.useCallback(()=>{let d={capture:{element:u,fullPage:x}};O&&(d.category=O),i(p,d);},[i,p,u,x,O]),pt=react.useCallback(d=>{(d.metaKey||d.ctrlKey)&&d.key==="Enter"&&p.trim().length>0&&!S&&(d.preventDefault(),q());},[q,p,S]),ft=Ze(e.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ft,{position:l,onClick:()=>o(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??a.triggerLabel,queueCount:lt,showSuccess:dt}),t.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),B&&jsxRuntime.jsx(uo,{rect:B}),t.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("p",{id:"bf-hint-text",children:a.hintText}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":a.cancelButton,children:a.cancelButton})]}),se&&V&&jsxRuntime.jsxs("div",{ref:st,className:"bf-panel",style:{left:V.left,top:V.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:a.panelTitle}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:S,"aria-label":a.rePickButton,children:a.rePickButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:S,"aria-label":a.closeButton,children:a.closeButton})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:a.textareaPlaceholder,value:p,onChange:d=>T(d.target.value),onKeyDown:pt,disabled:S,"aria-label":a.panelTitle}),ne.length>0&&jsxRuntime.jsx("div",{className:"bf-pills",role:"group","aria-label":"Feedback category",children:ne.map(d=>jsxRuntime.jsx("button",{type:"button",className:`bf-pill${O===d?" bf-pill-active":""}`,onClick:()=>ie(O===d?void 0:d),disabled:S,children:a[yo[d]]},d))}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":a.screenshotElement,children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:u,onChange:d=>E(d.target.checked),disabled:S}),a.screenshotElement]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:x,onChange:d=>re(d.target.checked),disabled:S}),a.screenshotFullPage]})]}),t.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),a.capturingText]}),t.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),a.submittingText]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:a.successText}),t.phase==="error"&&de&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:de}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:S,"aria-label":a.cancelButton,children:a.cancelButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:q,disabled:S||p.trim().length===0,"aria-label":a.sendButton,children:a.sendButton})]})]}),s&&jsxRuntime.jsx("div",{className:"bf-watermark",children:jsxRuntime.jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:a.toastText}),j>0&&!at&&jsxRuntime.jsxs("div",{className:"bf-security-banner",role:"alert",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-security-banner-dismiss",onClick:()=>it(true),"aria-label":"Dismiss",children:"\xD7"}),jsxRuntime.jsx("strong",{children:"Security Warning"}),j," potential secret",j>1?"s":""," exposed in client code. Check your environment variables."]})]})}var vo=react.forwardRef(function(t,n){let o={...t.config??{},blocfeed_id:t.blocfeed_id},[r,c]=react.useState(null),i=mo(o.ui?.showOn),l=ho(o.ui?.theme?.mode),a=!!o.diagnostics;react.useEffect(()=>{if(a)return chunkJVY6JTXP_cjs.k(o.diagnostics),()=>chunkJVY6JTXP_cjs.l()},[a]);let s=!!o.security;react.useEffect(()=>{s&&chunkJVY6JTXP_cjs.o(o.security);},[s]);let m=react.useRef(t.config?.metadata?.enrich);m.current=t.config?.metadata?.enrich;let M=react.useMemo(()=>{if(t.config)return {...t.config,metadata:{...t.config.metadata,enrich:async p=>{let T=m.current,u=T?await T(p):{},E=chunkJVY6JTXP_cjs.m(),x=chunkJVY6JTXP_cjs.p();return {...u,...E.consoleLogs.length>0?{_consoleLogs:E.consoleLogs}:{},...E.networkErrors.length>0?{_networkErrors:E.networkErrors}:{},...x.findings.length>0?{_securityFindings:x.findings}:{}}}}}},[]);return react.useEffect(()=>{ve();let p=document.createElement("div");p.setAttribute("data-blocfeed-ui-root","true"),p.setAttribute("data-blocfeed-ui","true"),p.setAttribute("data-bf-theme",l);let T=o.ui?.zIndex;typeof T=="number"&&p.style.setProperty("--bf-z",String(T));let u=o.ui?.theme;return u&&(u.accentColor&&p.style.setProperty("--bf-accent",u.accentColor),u.panelBackground&&p.style.setProperty("--bf-panel-bg",u.panelBackground),u.panelForeground&&p.style.setProperty("--bf-panel-fg",u.panelForeground),u.fontFamily&&p.style.setProperty("--bf-font",u.fontFamily)),document.body.appendChild(p),c(p),()=>{p.remove(),c(null);}},[o.ui?.zIndex,o.ui?.theme?.accentColor,o.ui?.theme?.panelBackground,o.ui?.theme?.panelForeground,o.ui?.theme?.fontFamily,l]),react.useEffect(()=>{r&&r.setAttribute("data-bf-theme",l);},[r,l]),!i||!r?null:reactDom.createPortal(jsxRuntime.jsx(ee,{blocfeed_id:o.blocfeed_id,...M?{config:M}:{},children:jsxRuntime.jsx(wo,{config:o,handleRef:n})}),r)});
639
+ exports.BlocFeedProvider=ee;exports.BlocFeedWidget=vo;exports.useBlocFeed=te;
package/dist/main.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-DfhbkHXc.cjs';
2
- export { c as BlocFeedError, d as BlocFeedStrings, e as BlocFeedUser, f as CaptureDiagnostics, g as CaptureResult, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, i as FeedbackPayload, I as ImageAsset, M as MaybePromise, j as MetadataConfig, k as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, l as ScreenshotAdapter, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, T as ThemeConfig, q as TransportConfig, r as TransportResult, s as TriggerStyle, W as WidgetPosition } from './controller-DfhbkHXc.cjs';
1
+ import { B as BlocFeedConfig, a as BlocFeedHandle, b as BlocFeedState, c as BlocFeedController, C as CaptureConfig, F as FeedbackCategory, S as SubmitResult } from './controller-BPsU7cuY.cjs';
2
+ export { d as BlocFeedError, e as BlocFeedStrings, f as BlocFeedUser, g as CaptureDiagnostics, h as CaptureResult, i as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, j as FeedbackApiResponse, k as FeedbackPayload, I as ImageAsset, M as MaybePromise, l as MetadataConfig, m as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, n as ScreenshotAdapter, o as ScreenshotAdapterOptions, p as ScreenshotIntent, q as ScreenshotMime, r as SecurityConfig, s as SecurityFinding, t as SecuritySnapshot, u as SessionPhase, T as ThemeConfig, v as TransportConfig, w as TransportResult, x as TriggerStyle, W as WidgetPosition } from './controller-BPsU7cuY.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
@@ -15,7 +15,7 @@ type BlocFeedWidgetProps = {
15
15
  blocfeed_id: string;
16
16
  config?: Omit<BlocFeedConfig, "blocfeed_id">;
17
17
  };
18
- declare function BlocFeedWidget(props: BlocFeedWidgetProps): react.ReactPortal | null;
18
+ declare const BlocFeedWidget: react.ForwardRefExoticComponent<BlocFeedWidgetProps & react.RefAttributes<BlocFeedHandle>>;
19
19
 
20
20
  type BlocFeedApi = {
21
21
  state: BlocFeedState;
@@ -25,8 +25,9 @@ type BlocFeedApi = {
25
25
  clearSelection: () => void;
26
26
  submit: (message: string, options?: {
27
27
  capture?: CaptureConfig;
28
+ category?: FeedbackCategory;
28
29
  }) => Promise<SubmitResult>;
29
30
  };
30
31
  declare function useBlocFeed(): BlocFeedApi;
31
32
 
32
- export { type BlocFeedApi, BlocFeedConfig, BlocFeedProvider, BlocFeedState, BlocFeedWidget, CaptureConfig, SubmitResult, useBlocFeed };
33
+ export { type BlocFeedApi, BlocFeedConfig, BlocFeedHandle, BlocFeedProvider, BlocFeedState, BlocFeedWidget, CaptureConfig, FeedbackCategory, SubmitResult, useBlocFeed };
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-DfhbkHXc.js';
2
- export { c as BlocFeedError, d as BlocFeedStrings, e as BlocFeedUser, f as CaptureDiagnostics, g as CaptureResult, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, i as FeedbackPayload, I as ImageAsset, M as MaybePromise, j as MetadataConfig, k as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, l as ScreenshotAdapter, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, T as ThemeConfig, q as TransportConfig, r as TransportResult, s as TriggerStyle, W as WidgetPosition } from './controller-DfhbkHXc.js';
1
+ import { B as BlocFeedConfig, a as BlocFeedHandle, b as BlocFeedState, c as BlocFeedController, C as CaptureConfig, F as FeedbackCategory, S as SubmitResult } from './controller-BPsU7cuY.js';
2
+ export { d as BlocFeedError, e as BlocFeedStrings, f as BlocFeedUser, g as CaptureDiagnostics, h as CaptureResult, i as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, j as FeedbackApiResponse, k as FeedbackPayload, I as ImageAsset, M as MaybePromise, l as MetadataConfig, m as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, n as ScreenshotAdapter, o as ScreenshotAdapterOptions, p as ScreenshotIntent, q as ScreenshotMime, r as SecurityConfig, s as SecurityFinding, t as SecuritySnapshot, u as SessionPhase, T as ThemeConfig, v as TransportConfig, w as TransportResult, x as TriggerStyle, W as WidgetPosition } from './controller-BPsU7cuY.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
@@ -15,7 +15,7 @@ type BlocFeedWidgetProps = {
15
15
  blocfeed_id: string;
16
16
  config?: Omit<BlocFeedConfig, "blocfeed_id">;
17
17
  };
18
- declare function BlocFeedWidget(props: BlocFeedWidgetProps): react.ReactPortal | null;
18
+ declare const BlocFeedWidget: react.ForwardRefExoticComponent<BlocFeedWidgetProps & react.RefAttributes<BlocFeedHandle>>;
19
19
 
20
20
  type BlocFeedApi = {
21
21
  state: BlocFeedState;
@@ -25,8 +25,9 @@ type BlocFeedApi = {
25
25
  clearSelection: () => void;
26
26
  submit: (message: string, options?: {
27
27
  capture?: CaptureConfig;
28
+ category?: FeedbackCategory;
28
29
  }) => Promise<SubmitResult>;
29
30
  };
30
31
  declare function useBlocFeed(): BlocFeedApi;
31
32
 
32
- export { type BlocFeedApi, BlocFeedConfig, BlocFeedProvider, BlocFeedState, BlocFeedWidget, CaptureConfig, SubmitResult, useBlocFeed };
33
+ export { type BlocFeedApi, BlocFeedConfig, BlocFeedHandle, BlocFeedProvider, BlocFeedState, BlocFeedWidget, CaptureConfig, FeedbackCategory, SubmitResult, useBlocFeed };