blocfeed 0.6.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0 — 2026-02-20
4
+
5
+ ### New features
6
+
7
+ - **XHR network capture** — Network diagnostics now intercept `XMLHttpRequest` in addition to `fetch`. Apps using axios, jQuery, or other XHR-based libraries get full network error capture.
8
+ - **Conditional display (`showOn`)** — `config.ui.showOn` restricts widget visibility to specific routes. Accepts an array of route patterns (with wildcard `*` suffix) or a custom predicate function. Default: show on all pages.
9
+ - **Programmatic API** — `BlocFeedWidget` now accepts a React ref exposing `open()`, `close()`, `submit(message)`, and `isOpen`. New `BlocFeedHandle` type exported for TypeScript consumers.
10
+ - **Feedback categories** — Pill selector in the feedback form: Bug, Feature, UX, General. Selection is included as `category` in the payload. Configurable via `config.ui.categories` and fully localizable via `config.ui.strings`.
11
+ - **Dark / Light mode** — `config.ui.theme.mode` supports `"light"`, `"dark"`, or `"auto"` (uses `prefers-color-scheme`). Default remains `"dark"`. Light theme includes fully styled panel, textarea, highlight, and overlay.
12
+
13
+ ### Improvements
14
+
15
+ - New types exported: `BlocFeedHandle`, `FeedbackCategory`.
16
+ - `BlocFeedStrings` extended with `categoryBug`, `categoryFeature`, `categoryUx`, `categoryGeneral`.
17
+ - `FeedbackPayload` now includes optional `category` field.
18
+ - SPA route detection for `showOn`: patches `history.pushState` / `replaceState` and listens for `popstate`.
19
+ - Backlog updated: shipped items tracked, remaining ideas reorganized.
20
+
21
+ ---
22
+
23
+ ## 0.6.1 — 2026-02-20
24
+
25
+ - Re-publish of 0.6.0 with all features included (diagnostics, i18n, watermark).
26
+
27
+ ---
28
+
3
29
  ## 0.6.0 — 2026-02-20
4
30
 
5
31
  ### New features
package/README.md CHANGED
@@ -11,6 +11,10 @@ Drop-in in-app feedback widget for **Next.js** and **React**:
11
11
  - **Offline queue** — failed submissions are stored and retried automatically
12
12
  - **Customizable position, theme, and retry behavior**
13
13
  - **Accessible** — keyboard navigation, focus trapping, ARIA attributes
14
+ - **Feedback categories** — pill selector (Bug, Feature, UX, General) included in payload
15
+ - **Dark / Light mode** — `"dark"`, `"light"`, or `"auto"` (follows system preference)
16
+ - **Conditional display** — show/hide widget by route pattern or custom predicate
17
+ - **Programmatic API** — `ref.open()`, `ref.close()`, `ref.submit(msg)` via React ref
14
18
 
15
19
  Docs live in `docs/` (start at `docs/index.md`). Architecture pointers are in `ARCHITECTURE.md`.
16
20
 
@@ -114,13 +118,16 @@ All configuration is passed via the `config` prop on `<BlocFeedWidget>` or `<Blo
114
118
  panelBackground: "rgba(0, 0, 0, 0.95)",
115
119
  panelForeground: "#ffffff",
116
120
  fontFamily: "Inter, sans-serif",
121
+ mode: "dark", // "dark" | "light" | "auto"
117
122
  },
123
+ categories: ["bug", "feature", "ux", "general"], // feedback category pills
124
+ showOn: ["/dashboard/*", "/app/*"], // route-based visibility
118
125
  },
119
126
 
120
- // Diagnostics (console + network capture)
127
+ // Diagnostics (console + network capture, including XHR)
121
128
  diagnostics: {
122
129
  console: true,
123
- network: true,
130
+ network: true, // captures both fetch and XMLHttpRequest
124
131
  },
125
132
 
126
133
  // Screenshot defaults
@@ -271,7 +278,103 @@ config={{
271
278
  }}
272
279
  ```
273
280
 
274
- All fields are optional — only override the ones you need.
281
+ All fields are optional — only override the ones you need. Category labels are also localizable:
282
+
283
+ ```tsx
284
+ strings: {
285
+ categoryBug: "Fehler",
286
+ categoryFeature: "Funktion",
287
+ categoryUx: "UX",
288
+ categoryGeneral: "Allgemein",
289
+ }
290
+ ```
291
+
292
+ ## Feedback Categories
293
+
294
+ Show a pill selector in the feedback form so users can tag their feedback:
295
+
296
+ ```tsx
297
+ config={{
298
+ ui: {
299
+ categories: ["bug", "feature", "ux", "general"],
300
+ },
301
+ }}
302
+ ```
303
+
304
+ The selected category is included in the payload as `category`. All four categories are shown by default. To show only a subset:
305
+
306
+ ```tsx
307
+ config={{
308
+ ui: {
309
+ categories: ["bug", "feature"], // only Bug and Feature pills
310
+ },
311
+ }}
312
+ ```
313
+
314
+ Set `categories: []` to hide the pill selector entirely.
315
+
316
+ ## Conditional Display (`showOn`)
317
+
318
+ Restrict widget visibility to specific routes. By default the widget shows on all pages.
319
+
320
+ ### Route patterns
321
+
322
+ ```tsx
323
+ config={{
324
+ ui: {
325
+ showOn: ["/dashboard/*", "/app/*", "/settings"],
326
+ },
327
+ }}
328
+ ```
329
+
330
+ Patterns support exact matching or wildcard `*` suffix (matches any path starting with the prefix).
331
+
332
+ ### Custom predicate
333
+
334
+ ```tsx
335
+ config={{
336
+ ui: {
337
+ showOn: (pathname) => !pathname.startsWith("/admin"),
338
+ },
339
+ }}
340
+ ```
341
+
342
+ The widget automatically detects SPA navigation (`pushState`, `replaceState`, `popstate`) and re-evaluates on every route change.
343
+
344
+ ## Programmatic API
345
+
346
+ Control the widget programmatically via a React ref:
347
+
348
+ ```tsx
349
+ import { useRef } from "react";
350
+ import { BlocFeedWidget, type BlocFeedHandle } from "blocfeed";
351
+
352
+ function App() {
353
+ const feedbackRef = useRef<BlocFeedHandle>(null);
354
+
355
+ return (
356
+ <>
357
+ <button onClick={() => feedbackRef.current?.open()}>
358
+ Report a Bug
359
+ </button>
360
+
361
+ <BlocFeedWidget
362
+ ref={feedbackRef}
363
+ blocfeed_id="bf_..."
364
+ />
365
+ </>
366
+ );
367
+ }
368
+ ```
369
+
370
+ ### `BlocFeedHandle` methods
371
+
372
+ | Method | Description |
373
+ |--------|-------------|
374
+ | `open()` | Open the widget (starts element picking) |
375
+ | `close()` | Close the widget and reset state |
376
+ | `submit(message)` | Submit feedback programmatically (returns `Promise<SubmitResult>`) |
377
+ | `isOpen` | `boolean` — whether the widget is currently active |
275
378
 
276
379
  ## Console & Network Diagnostics
277
380
 
@@ -283,7 +386,7 @@ config={{
283
386
  console: true, // capture console.error & console.warn
284
387
  consoleLevels: ["error", "warn"], // which levels to capture
285
388
  consoleLimit: 20, // max entries retained
286
- network: true, // capture failed fetch requests
389
+ network: true, // capture failed fetch & XHR requests
287
390
  networkLimit: 15, // max entries retained
288
391
  },
289
392
  }}
@@ -291,6 +394,8 @@ config={{
291
394
 
292
395
  Captured data is attached to `metadata._consoleLogs` and `metadata._networkErrors` in the payload. BlocFeed's own API calls are excluded. Messages and stacks are truncated at 2KB.
293
396
 
397
+ Both `fetch` and `XMLHttpRequest` are intercepted, so apps using axios, jQuery, or other XHR-based libraries get full network error capture.
398
+
294
399
  ### Headless diagnostics
295
400
 
296
401
  ```ts
@@ -314,11 +419,24 @@ config={{
314
419
  panelBackground: "rgba(0,0,0,0.95)", // panel & trigger background
315
420
  panelForeground: "#ffffff", // text color
316
421
  fontFamily: "Inter, sans-serif", // font stack
422
+ mode: "auto", // "dark" | "light" | "auto"
317
423
  },
318
424
  },
319
425
  }}
320
426
  ```
321
427
 
428
+ ### Dark / Light Mode
429
+
430
+ The widget defaults to dark mode. Set `theme.mode` to change the color scheme:
431
+
432
+ | Mode | Behavior |
433
+ |------|----------|
434
+ | `"dark"` | Dark panel, light text (default) |
435
+ | `"light"` | Light panel, dark text |
436
+ | `"auto"` | Follows the user's system preference (`prefers-color-scheme`) and updates live |
437
+
438
+ Explicit `panelBackground` / `panelForeground` overrides take precedence over the mode defaults.
439
+
322
440
  ## Retry & Transport
323
441
 
324
442
  Configure retry behavior for unreliable networks:
@@ -489,15 +607,17 @@ All types are exported from both entry points:
489
607
  ```ts
490
608
  import type {
491
609
  BlocFeedConfig,
610
+ BlocFeedHandle,
492
611
  BlocFeedUser,
493
- TransportConfig,
494
- TriggerStyle,
495
- WidgetPosition,
496
- ThemeConfig,
612
+ FeedbackCategory,
497
613
  FeedbackPayload,
498
614
  FeedbackApiResponse,
499
615
  BlocFeedState,
500
616
  SessionPhase,
617
+ ThemeConfig,
618
+ TransportConfig,
619
+ TriggerStyle,
620
+ WidgetPosition,
501
621
  // ... and more
502
622
  } from "blocfeed";
503
623
  ```
@@ -0,0 +1,2 @@
1
+ 'use strict';function w(){return typeof window<"u"&&typeof document<"u"}function se(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function J(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Me(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Le(e){return e.replace(/\s+/g," ").trim()}function Be(e,t=140){let n=e.textContent;if(!n)return;let r=Le(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ie(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var ue=["data-testid","data-test-id","data-test","data-qa","data-cy"],ae="data-blocfeed-component";function De(e){let t=e.closest(`[${ae}]`);if(!t)return;let r=t.getAttribute(ae)?.trim();return r||void 0}function Ne(e){for(let t of ue){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function T(e){if(e.length<=1||e.length===2&&e[0]===e[0].toLowerCase())return true;let t=e[0];return t>="a"&&t<="z"}function B(e){if(e){for(let t of e)if(typeof t.name=="string"&&t.name&&!T(t.name))return t.name}}function v(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return v(o)}}}function Oe(e){let t=le(e);if(!t)return;let n=B(t._debugInfo);if(n)return n;let r=t._debugOwner!==void 0;if(r){let s=t._debugOwner;for(let l=0;s&&l<50;l+=1){let d=B(s._debugInfo);if(d)return d;let g=v(s.type)??v(s.elementType);if(g&&!T(g))return g;s=s._debugOwner;}}if(t._owner!==void 0&&t._owner!==t._debugOwner){let s=t._owner;for(let l=0;s&&l<50;l+=1){let d=B(s._debugInfo);if(d)return d;let g=v(s.type)??v(s.elementType);if(g&&!T(g))return g;s=s._owner;}}let i=t,c=r?80:25;for(let s=0;i&&s<c;s+=1){let l=B(i._debugInfo);if(l)return l;let d=v(i.type)??v(i.elementType);if(d&&!T(d))return d;i=i.return;}let a=e.parentElement;for(let s=0;a&&s<15;s+=1){let l=le(a);if(l){let d=B(l._debugInfo);if(d)return d;let g=v(l.type)??v(l.elementType);if(g&&!T(g))return g;if(l._debugOwner){let h=v(l._debugOwner.type)??v(l._debugOwner.elementType);if(h&&!T(h))return h}if(l._owner&&l._owner!==l._debugOwner){let h=v(l._owner.type)??v(l._owner.elementType);if(h&&!T(h))return h}}a=a.parentElement;}}function He(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${se(n)}`;for(let r of ue){let o=e.getAttribute(r);if(o)return `${t}[${r}="${se(o)}"]`}return `${t}:nth-of-type(${Ie(e)})`}function Ue(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=He(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function ce(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function Y(e,t){if(!e||ce(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(ce(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??qe(n))return n;n=n.parentElement;}return null}function qe(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function de(e){let t=e.getBoundingClientRect(),n={selector:Ue(e),tagName:e.tagName.toLowerCase(),rect:J(t),pageRect:Me(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Be(e);i&&(n.textSnippet=i);let c=De(e)??Oe(e);c&&(n.componentName=c);let a=Ne(e);return a&&(n.testId=a),n}var K=null;async function fe(){return K||(K=import('html-to-image')),K}async function Xe(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function me(e,t){let{width:n,height:r}=await Xe(e);return {dataUrl:e,mime:t,width:n,height:r}}function M(e){if(e?.aborted)throw new Error("Aborted")}function pe(){return {async captureElement(e,t){if(!w())throw new Error("captureElement can only run in the browser");M(t.signal);let n=await fe();M(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return M(t.signal),await me(r,t.mime)},async captureFullPage(e){if(!w())throw new Error("captureFullPage can only run in the browser");M(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),c=Math.max(1,Math.round(r*o)),a=await fe();M(e.signal);let s=e.mime==="image/jpeg"?await a.toJpeg(t,{width:i,height:c,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await a.toPng(t,{width:i,height:c,pixelRatio:e.pixelRatio});return M(e.signal),await me(s,e.mime)}}}function $e(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function y(e,t,n){let r={kind:e,message:$e(t)};return n&&(r.detail=n),r}var je=12e3,Qe=2048,ze=.92;function ge(){return Date.now()}function We(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function he(e,t,n){let r=new Promise((i,c)=>{let a=setTimeout(()=>c(new Error("Timeout")),t);typeof a.unref=="function"&&a.unref();}),o=[e,r];return n&&o.push(We(n)),await Promise.race(o)}function Je(e){if(!w())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function Ye(e){return !!(e?.element||e?.fullPage)}function we(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function ye(e){let{selectionElement:t,capture:n,signal:r}=e;if(!w()||!Ye(n))return;let o=ge(),i=[],c=n?.timeoutMs??je,a=n?.maxDimension??Qe,s=n?.mime??"image/png",l=n?.quality??ze,d=n?.adapter??pe(),g={},h=Je(n);if(n?.element&&t)try{let f=t.getBoundingClientRect(),m=Math.min(1,a/Math.max(f.width,f.height)),P=Math.min(h,h*m),R=await he(Promise.resolve(d.captureElement(t,{...we({mime:s,quality:l,pixelRatio:P,maxDimension:a,includeQuality:s==="image/jpeg",...r?{signal:r}:{}})})),c,r);g.element=R;}catch(f){if(r?.aborted)throw f;i.push(y("capture_failed",f,{target:"element"}));}if(n?.fullPage)try{let f=await he(Promise.resolve(d.captureFullPage(we({mime:s,quality:l,pixelRatio:h,maxDimension:a,includeQuality:s==="image/jpeg",...r?{signal:r}:{}}))),c,r);g.fullPage=f;}catch(f){if(r?.aborted)throw f;i.push(y("capture_failed",f,{target:"fullPage"}));}let b=ge(),u={startedAt:o,finishedAt:b,durationMs:Math.max(0,b-o)};return i.length>0&&(u.errors=i),{...g,diagnostics:u}}function Ke(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Ge(){return w()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:Ke()}:{}}function Ze(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function be(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Ge(),...Ze(r)},i=t?.enrich;if(!i)return o;try{let c=await i(n);return {...o,...c}}catch(c){let a=y("unknown",c);return {...o,blocfeedMetadataError:a.message}}}var G="blocfeed-queue",Ve=50;function Z(){if(!w())return [];try{let e=localStorage.getItem(G);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function V(e){if(w())try{e.length===0?localStorage.removeItem(G):localStorage.setItem(G,JSON.stringify(e));}catch{}}function et(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function ee(e){let t=Z(),n=et(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ve;)t.shift();V(t);}function Ee(){let e=Z();return e.length===0?[]:(V([]),e.map(t=>t.payload))}function Ft(){V([]);}function Tt(){return Z().length}function te(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function X(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function $(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ke(e,t){if(!w())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,c=null,a=(u,f=false)=>{if(!u){i=null,c=null,t.onHover(null);return}let m=J(u.getBoundingClientRect()),P=`${Math.round(m.x)}:${Math.round(m.y)}:${Math.round(m.width)}:${Math.round(m.height)}`;!f&&u===i&&P===c||(i=u,c=P,t.onHover({element:u,rect:m}));},s=te(u=>{if(X(u.target))return;let f=document.elementFromPoint(u.clientX,u.clientY),m=Y(f,o);a(m);}),l=te(()=>{i&&a(i,true);}),d=u=>{X(u.target)||($(u),u.pointerType==="mouse"&&u.preventDefault());},g=u=>{X(u.target)||($(u),u.pointerType==="mouse"&&u.preventDefault());},h=u=>{if(X(u.target))return;$(u),u.preventDefault();let f=document.elementFromPoint(u.clientX,u.clientY),m=Y(f,o);m&&t.onSelect({element:m,descriptor:de(m)});},b=u=>{u.key==="Escape"&&($(u),u.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",s,{capture:true,passive:true}),window.addEventListener("pointerdown",d,{capture:true}),window.addEventListener("pointerup",g,{capture:true}),window.addEventListener("click",h,{capture:true}),window.addEventListener("keydown",b,{capture:true}),window.addEventListener("scroll",l,{capture:true,passive:true}),window.addEventListener("resize",l,{passive:true}),{stop(){window.removeEventListener("pointermove",s,{capture:true}),window.removeEventListener("pointerdown",d,{capture:true}),window.removeEventListener("pointerup",g,{capture:true}),window.removeEventListener("click",h,{capture:true}),window.removeEventListener("keydown",b,{capture:true}),window.removeEventListener("scroll",l,{capture:true}),window.removeEventListener("resize",l),s.cancel(),l.cancel(),t.onHover(null);}}}var tt=12e3,nt=2,rt=500,ot=2e3,xe="https://blocfeed.com/api/feedback",Se=0;function ve(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function it(e){return e>=500&&e<=599}function st(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:o})}function at(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function Pe(e,t,n){let r=st(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function lt(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${xe}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Re(e){let{signal:t,transport:n}=e;if(Date.now()-Se<ot)return {ok:false,error:y("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??tt,i=n?.maxAttempts??nt,c=n?.backoffMs??rt,a=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:s,extracted:l}=a?at(e.payload):{lean:e.payload,extracted:{}},d={...l,...e.screenshotDataUrls};for(let g=1;g<=i;g+=1){let h=new AbortController,b=setTimeout(()=>h.abort(),o),u=()=>h.abort();t&&t.addEventListener("abort",u,{once:true});try{let f=await fetch(xe,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s),signal:h.signal});if(f.ok){Se=Date.now();let m;try{m=await f.json();}catch{}if((d.element||d.fullPage)&&m){let p=m.upload_urls;if(p){let k=[];d.element&&p.element&&k.push(Pe(p.element,d.element,t)),d.fullPage&&p.fullPage&&k.push(Pe(p.fullPage,d.fullPage,t));try{await Promise.all(k);}catch{}}else if(m.feedback_id)try{await lt({feedbackId:m.feedback_id,extracted:d,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let R={ok:!0,status:f.status};return m&&(R.apiResponse=m),R}if(g<i&&it(f.status)){let m=.85+Math.random()*.3,P=Math.round(c*2**(g-1)*m);await ve(P,t);continue}return {ok:!1,status:f.status,error:y("api_failed",new Error(`HTTP ${f.status}`))}}catch(f){if(h.signal.aborted||t?.aborted)return {ok:false,error:y("aborted",f)};if(g<i){let m=.85+Math.random()*.3,P=Math.round(c*2**(g-1)*m);await ve(P,t);continue}return {ok:false,error:y("api_failed",f)}}finally{clearTimeout(b),t&&t.removeEventListener("abort",u);}}return {ok:false,error:y("api_failed",new Error("Failed"))}}async function ne(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Re(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:y("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var ct=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function ut(e){let t=[...ct,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function Fe(){return {phase:"idle"}}function dt(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function zt(e){let t=e,n=Fe(),r=new Set,o=new Set,i=null,c=null,a=null,s=null,l=0,d=null,g=()=>{for(let p of r)p(n);},h=p=>{for(let k of o)k(p);},b=p=>{n=p,g();},u=()=>{l+=1,s?.abort(),s=null;},f=()=>{i?.stop(),i=null,h(null),a!==null&&w()&&(document.documentElement.style.cursor=a,a=null);},m=()=>{u(),f(),c=null,b(Fe());},P=()=>{if(!w())return;f(),c=null;let p=ut(t.picker);a=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",b({phase:"picking"}),i=ke(p,{onHover:h,onSelect:({element:k,descriptor:q})=>{c=k,f(),b({phase:"review",selection:q});},onCancel:()=>{m();}});},R=()=>{let p=Ee();if(p.length!==0)for(let k of p)ne({payload:k,...t.transport?{transport:t.transport}:{}}).catch(()=>{ee(k);});};if(w()){setTimeout(R,1e3);let p=()=>R();window.addEventListener("online",p),d=()=>window.removeEventListener("online",p);}return {getState:()=>n,subscribe(p){return r.add(p),()=>r.delete(p)},subscribeHover(p){return o.add(p),()=>o.delete(p)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&P();},stop(){m();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||P();},setConfig(p){t=p;},async submit(p,k){if(!w()){let E=y("configuration",new Error("BlocFeed submit can only run in the browser"));return b({phase:"error",lastError:E}),{ok:false}}let q=t.blocfeed_id?.trim?.()??"";if(!q){let F={phase:"error",lastError:y("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),b(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let L=l+1;l=L,s?.abort(),s=new AbortController;let A=s.signal,S=n.selection,Q=k?.capture?{...t.capture,...k.capture}:t.capture,oe=!!(Q?.element||Q?.fullPage),ie={phase:oe?"capturing":"submitting"};S&&(ie.selection=S),b(ie);try{let E=oe?await ye({selectionElement:c,capture:Q,signal:A}):void 0;if(A.aborted||l!==L)return {ok:!1};let F={phase:"submitting"};S&&(F.selection=S),E&&(F.capture=E),b(F);let C={};S&&(C.selection=S),E&&(C.capture=E);let Ce=await be({config:t.metadata,context:C,...t.user?{user:t.user}:{}}),_={version:1,createdAt:new Date().toISOString(),blocfeed_id:q,message:p,metadata:Ce};k?.category&&(_.category=k.category),t.user&&(_.user=t.user),S&&(_.selection=S),E&&(_.screenshots=E);let{result:x}=await ne({payload:_,signal:A,...t.transport?{transport:t.transport}:{}});if(A.aborted||l!==L)return x;if(x.ok){let W={phase:"success",lastSubmit:x};return S&&(W.selection=S),E&&(W.capture=E),b(W),x}dt(x)&&ee(_);let _e=x.api?.error??y("unknown",new Error("Submission failed")),z={phase:"error",lastSubmit:x,lastError:_e};return S&&(z.selection=S),E&&(z.capture=E),b(z),x}catch(E){if(A.aborted||l!==L)return {ok:false};let C={phase:"error",lastError:A.aborted?y("aborted",E):y("unknown",E)};return S&&(C.selection=S),b(C),{ok:false}}finally{l===L&&(s=null);}},__unsafeGetSelectedElement(){return c},destroy(){m(),r.clear(),o.clear(),d?.(),d=null;}}}var I=[],D=[],Te=20,Ae=15,N={},O=null,H=null,U=null,j=false;function ft(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function mt(e,t){let n=t.map(ft).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),I.push(o);I.length>Te;)I.shift();}function re(e){if(!e.url.includes("blocfeed.com"))for(D.push(e);D.length>Ae;)D.shift();}function Yt(e={}){if(!(j||!w())){if(j=true,Te=e.consoleLimit??20,Ae=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)N[n]=console[n],console[n]=(...r)=>{mt(n,r),N[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){O=window.fetch;let t=O;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,c=(o?.method??"GET").toUpperCase(),a=Date.now();try{let s=await t.call(window,r,o);return s.ok||re({url:i.slice(0,500),method:c,status:s.status,statusText:s.statusText,timestamp:a,durationMs:Date.now()-a}),s}catch(s){throw re({url:i.slice(0,500),method:c,status:0,statusText:s instanceof Error?s.message:"Network error",timestamp:a,durationMs:Date.now()-a}),s}};}if(e.network!==false&&typeof XMLHttpRequest<"u"){H=XMLHttpRequest.prototype.open,U=XMLHttpRequest.prototype.send;let t=H,n=U;XMLHttpRequest.prototype.open=function(r,o,...i){return this.__bf_method=r.toUpperCase(),this.__bf_url=String(o),t.apply(this,[r,o,...i])},XMLHttpRequest.prototype.send=function(...r){let o=this.__bf_method||"GET",i=this.__bf_url||"",c=Date.now();return this.addEventListener("loadend",function(){if(this.status>=400||this.status===0){let a={url:i.slice(0,500),method:o,status:this.status,timestamp:c,durationMs:Date.now()-c};this.statusText&&(a.statusText=this.statusText),re(a);}}),n.apply(this,r)};}}}function Kt(){if(j){for(let[e,t]of Object.entries(N))console[e]=t;for(let e of Object.keys(N))delete N[e];O&&(window.fetch=O,O=null),H&&(XMLHttpRequest.prototype.open=H,H=null),U&&(XMLHttpRequest.prototype.send=U,U=null),j=false;}}function Gt(){return {consoleLogs:[...I],networkErrors:[...D]}}function Zt(){I=[],D=[];}
2
+ exports.a=w;exports.b=J;exports.c=pe;exports.d=ye;exports.e=be;exports.f=ee;exports.g=Ee;exports.h=Ft;exports.i=Tt;exports.j=zt;exports.k=Yt;exports.l=Kt;exports.m=Gt;exports.n=Zt;
@@ -0,0 +1,2 @@
1
+ function w(){return typeof window<"u"&&typeof document<"u"}function se(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function J(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Me(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Le(e){return e.replace(/\s+/g," ").trim()}function Be(e,t=140){let n=e.textContent;if(!n)return;let r=Le(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ie(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var ue=["data-testid","data-test-id","data-test","data-qa","data-cy"],ae="data-blocfeed-component";function De(e){let t=e.closest(`[${ae}]`);if(!t)return;let r=t.getAttribute(ae)?.trim();return r||void 0}function Ne(e){for(let t of ue){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function T(e){if(e.length<=1||e.length===2&&e[0]===e[0].toLowerCase())return true;let t=e[0];return t>="a"&&t<="z"}function B(e){if(e){for(let t of e)if(typeof t.name=="string"&&t.name&&!T(t.name))return t.name}}function v(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return v(o)}}}function Oe(e){let t=le(e);if(!t)return;let n=B(t._debugInfo);if(n)return n;let r=t._debugOwner!==void 0;if(r){let s=t._debugOwner;for(let l=0;s&&l<50;l+=1){let d=B(s._debugInfo);if(d)return d;let g=v(s.type)??v(s.elementType);if(g&&!T(g))return g;s=s._debugOwner;}}if(t._owner!==void 0&&t._owner!==t._debugOwner){let s=t._owner;for(let l=0;s&&l<50;l+=1){let d=B(s._debugInfo);if(d)return d;let g=v(s.type)??v(s.elementType);if(g&&!T(g))return g;s=s._owner;}}let i=t,c=r?80:25;for(let s=0;i&&s<c;s+=1){let l=B(i._debugInfo);if(l)return l;let d=v(i.type)??v(i.elementType);if(d&&!T(d))return d;i=i.return;}let a=e.parentElement;for(let s=0;a&&s<15;s+=1){let l=le(a);if(l){let d=B(l._debugInfo);if(d)return d;let g=v(l.type)??v(l.elementType);if(g&&!T(g))return g;if(l._debugOwner){let h=v(l._debugOwner.type)??v(l._debugOwner.elementType);if(h&&!T(h))return h}if(l._owner&&l._owner!==l._debugOwner){let h=v(l._owner.type)??v(l._owner.elementType);if(h&&!T(h))return h}}a=a.parentElement;}}function He(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${se(n)}`;for(let r of ue){let o=e.getAttribute(r);if(o)return `${t}[${r}="${se(o)}"]`}return `${t}:nth-of-type(${Ie(e)})`}function Ue(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=He(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function ce(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function Y(e,t){if(!e||ce(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(ce(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??qe(n))return n;n=n.parentElement;}return null}function qe(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function de(e){let t=e.getBoundingClientRect(),n={selector:Ue(e),tagName:e.tagName.toLowerCase(),rect:J(t),pageRect:Me(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Be(e);i&&(n.textSnippet=i);let c=De(e)??Oe(e);c&&(n.componentName=c);let a=Ne(e);return a&&(n.testId=a),n}var K=null;async function fe(){return K||(K=import('html-to-image')),K}async function Xe(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function me(e,t){let{width:n,height:r}=await Xe(e);return {dataUrl:e,mime:t,width:n,height:r}}function M(e){if(e?.aborted)throw new Error("Aborted")}function pe(){return {async captureElement(e,t){if(!w())throw new Error("captureElement can only run in the browser");M(t.signal);let n=await fe();M(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return M(t.signal),await me(r,t.mime)},async captureFullPage(e){if(!w())throw new Error("captureFullPage can only run in the browser");M(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),c=Math.max(1,Math.round(r*o)),a=await fe();M(e.signal);let s=e.mime==="image/jpeg"?await a.toJpeg(t,{width:i,height:c,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await a.toPng(t,{width:i,height:c,pixelRatio:e.pixelRatio});return M(e.signal),await me(s,e.mime)}}}function $e(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function y(e,t,n){let r={kind:e,message:$e(t)};return n&&(r.detail=n),r}var je=12e3,Qe=2048,ze=.92;function ge(){return Date.now()}function We(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function he(e,t,n){let r=new Promise((i,c)=>{let a=setTimeout(()=>c(new Error("Timeout")),t);typeof a.unref=="function"&&a.unref();}),o=[e,r];return n&&o.push(We(n)),await Promise.race(o)}function Je(e){if(!w())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function Ye(e){return !!(e?.element||e?.fullPage)}function we(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function ye(e){let{selectionElement:t,capture:n,signal:r}=e;if(!w()||!Ye(n))return;let o=ge(),i=[],c=n?.timeoutMs??je,a=n?.maxDimension??Qe,s=n?.mime??"image/png",l=n?.quality??ze,d=n?.adapter??pe(),g={},h=Je(n);if(n?.element&&t)try{let f=t.getBoundingClientRect(),m=Math.min(1,a/Math.max(f.width,f.height)),P=Math.min(h,h*m),R=await he(Promise.resolve(d.captureElement(t,{...we({mime:s,quality:l,pixelRatio:P,maxDimension:a,includeQuality:s==="image/jpeg",...r?{signal:r}:{}})})),c,r);g.element=R;}catch(f){if(r?.aborted)throw f;i.push(y("capture_failed",f,{target:"element"}));}if(n?.fullPage)try{let f=await he(Promise.resolve(d.captureFullPage(we({mime:s,quality:l,pixelRatio:h,maxDimension:a,includeQuality:s==="image/jpeg",...r?{signal:r}:{}}))),c,r);g.fullPage=f;}catch(f){if(r?.aborted)throw f;i.push(y("capture_failed",f,{target:"fullPage"}));}let b=ge(),u={startedAt:o,finishedAt:b,durationMs:Math.max(0,b-o)};return i.length>0&&(u.errors=i),{...g,diagnostics:u}}function Ke(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Ge(){return w()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:Ke()}:{}}function Ze(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function be(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Ge(),...Ze(r)},i=t?.enrich;if(!i)return o;try{let c=await i(n);return {...o,...c}}catch(c){let a=y("unknown",c);return {...o,blocfeedMetadataError:a.message}}}var G="blocfeed-queue",Ve=50;function Z(){if(!w())return [];try{let e=localStorage.getItem(G);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function V(e){if(w())try{e.length===0?localStorage.removeItem(G):localStorage.setItem(G,JSON.stringify(e));}catch{}}function et(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function ee(e){let t=Z(),n=et(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ve;)t.shift();V(t);}function Ee(){let e=Z();return e.length===0?[]:(V([]),e.map(t=>t.payload))}function Ft(){V([]);}function Tt(){return Z().length}function te(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function X(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function $(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ke(e,t){if(!w())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,c=null,a=(u,f=false)=>{if(!u){i=null,c=null,t.onHover(null);return}let m=J(u.getBoundingClientRect()),P=`${Math.round(m.x)}:${Math.round(m.y)}:${Math.round(m.width)}:${Math.round(m.height)}`;!f&&u===i&&P===c||(i=u,c=P,t.onHover({element:u,rect:m}));},s=te(u=>{if(X(u.target))return;let f=document.elementFromPoint(u.clientX,u.clientY),m=Y(f,o);a(m);}),l=te(()=>{i&&a(i,true);}),d=u=>{X(u.target)||($(u),u.pointerType==="mouse"&&u.preventDefault());},g=u=>{X(u.target)||($(u),u.pointerType==="mouse"&&u.preventDefault());},h=u=>{if(X(u.target))return;$(u),u.preventDefault();let f=document.elementFromPoint(u.clientX,u.clientY),m=Y(f,o);m&&t.onSelect({element:m,descriptor:de(m)});},b=u=>{u.key==="Escape"&&($(u),u.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",s,{capture:true,passive:true}),window.addEventListener("pointerdown",d,{capture:true}),window.addEventListener("pointerup",g,{capture:true}),window.addEventListener("click",h,{capture:true}),window.addEventListener("keydown",b,{capture:true}),window.addEventListener("scroll",l,{capture:true,passive:true}),window.addEventListener("resize",l,{passive:true}),{stop(){window.removeEventListener("pointermove",s,{capture:true}),window.removeEventListener("pointerdown",d,{capture:true}),window.removeEventListener("pointerup",g,{capture:true}),window.removeEventListener("click",h,{capture:true}),window.removeEventListener("keydown",b,{capture:true}),window.removeEventListener("scroll",l,{capture:true}),window.removeEventListener("resize",l),s.cancel(),l.cancel(),t.onHover(null);}}}var tt=12e3,nt=2,rt=500,ot=2e3,xe="https://blocfeed.com/api/feedback",Se=0;function ve(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function it(e){return e>=500&&e<=599}function st(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),c=new Uint8Array(i.length);for(let a=0;a<i.length;a+=1)c[a]=i.charCodeAt(a);return new Blob([c],{type:o})}function at(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function Pe(e,t,n){let r=st(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function lt(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${xe}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Re(e){let{signal:t,transport:n}=e;if(Date.now()-Se<ot)return {ok:false,error:y("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??tt,i=n?.maxAttempts??nt,c=n?.backoffMs??rt,a=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:s,extracted:l}=a?at(e.payload):{lean:e.payload,extracted:{}},d={...l,...e.screenshotDataUrls};for(let g=1;g<=i;g+=1){let h=new AbortController,b=setTimeout(()=>h.abort(),o),u=()=>h.abort();t&&t.addEventListener("abort",u,{once:true});try{let f=await fetch(xe,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s),signal:h.signal});if(f.ok){Se=Date.now();let m;try{m=await f.json();}catch{}if((d.element||d.fullPage)&&m){let p=m.upload_urls;if(p){let k=[];d.element&&p.element&&k.push(Pe(p.element,d.element,t)),d.fullPage&&p.fullPage&&k.push(Pe(p.fullPage,d.fullPage,t));try{await Promise.all(k);}catch{}}else if(m.feedback_id)try{await lt({feedbackId:m.feedback_id,extracted:d,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let R={ok:!0,status:f.status};return m&&(R.apiResponse=m),R}if(g<i&&it(f.status)){let m=.85+Math.random()*.3,P=Math.round(c*2**(g-1)*m);await ve(P,t);continue}return {ok:!1,status:f.status,error:y("api_failed",new Error(`HTTP ${f.status}`))}}catch(f){if(h.signal.aborted||t?.aborted)return {ok:false,error:y("aborted",f)};if(g<i){let m=.85+Math.random()*.3,P=Math.round(c*2**(g-1)*m);await ve(P,t);continue}return {ok:false,error:y("api_failed",f)}}finally{clearTimeout(b),t&&t.removeEventListener("abort",u);}}return {ok:false,error:y("api_failed",new Error("Failed"))}}async function ne(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Re(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:y("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var ct=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function ut(e){let t=[...ct,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function Fe(){return {phase:"idle"}}function dt(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function zt(e){let t=e,n=Fe(),r=new Set,o=new Set,i=null,c=null,a=null,s=null,l=0,d=null,g=()=>{for(let p of r)p(n);},h=p=>{for(let k of o)k(p);},b=p=>{n=p,g();},u=()=>{l+=1,s?.abort(),s=null;},f=()=>{i?.stop(),i=null,h(null),a!==null&&w()&&(document.documentElement.style.cursor=a,a=null);},m=()=>{u(),f(),c=null,b(Fe());},P=()=>{if(!w())return;f(),c=null;let p=ut(t.picker);a=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",b({phase:"picking"}),i=ke(p,{onHover:h,onSelect:({element:k,descriptor:q})=>{c=k,f(),b({phase:"review",selection:q});},onCancel:()=>{m();}});},R=()=>{let p=Ee();if(p.length!==0)for(let k of p)ne({payload:k,...t.transport?{transport:t.transport}:{}}).catch(()=>{ee(k);});};if(w()){setTimeout(R,1e3);let p=()=>R();window.addEventListener("online",p),d=()=>window.removeEventListener("online",p);}return {getState:()=>n,subscribe(p){return r.add(p),()=>r.delete(p)},subscribeHover(p){return o.add(p),()=>o.delete(p)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&P();},stop(){m();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||P();},setConfig(p){t=p;},async submit(p,k){if(!w()){let E=y("configuration",new Error("BlocFeed submit can only run in the browser"));return b({phase:"error",lastError:E}),{ok:false}}let q=t.blocfeed_id?.trim?.()??"";if(!q){let F={phase:"error",lastError:y("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),b(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let L=l+1;l=L,s?.abort(),s=new AbortController;let A=s.signal,S=n.selection,Q=k?.capture?{...t.capture,...k.capture}:t.capture,oe=!!(Q?.element||Q?.fullPage),ie={phase:oe?"capturing":"submitting"};S&&(ie.selection=S),b(ie);try{let E=oe?await ye({selectionElement:c,capture:Q,signal:A}):void 0;if(A.aborted||l!==L)return {ok:!1};let F={phase:"submitting"};S&&(F.selection=S),E&&(F.capture=E),b(F);let C={};S&&(C.selection=S),E&&(C.capture=E);let Ce=await be({config:t.metadata,context:C,...t.user?{user:t.user}:{}}),_={version:1,createdAt:new Date().toISOString(),blocfeed_id:q,message:p,metadata:Ce};k?.category&&(_.category=k.category),t.user&&(_.user=t.user),S&&(_.selection=S),E&&(_.screenshots=E);let{result:x}=await ne({payload:_,signal:A,...t.transport?{transport:t.transport}:{}});if(A.aborted||l!==L)return x;if(x.ok){let W={phase:"success",lastSubmit:x};return S&&(W.selection=S),E&&(W.capture=E),b(W),x}dt(x)&&ee(_);let _e=x.api?.error??y("unknown",new Error("Submission failed")),z={phase:"error",lastSubmit:x,lastError:_e};return S&&(z.selection=S),E&&(z.capture=E),b(z),x}catch(E){if(A.aborted||l!==L)return {ok:false};let C={phase:"error",lastError:A.aborted?y("aborted",E):y("unknown",E)};return S&&(C.selection=S),b(C),{ok:false}}finally{l===L&&(s=null);}},__unsafeGetSelectedElement(){return c},destroy(){m(),r.clear(),o.clear(),d?.(),d=null;}}}var I=[],D=[],Te=20,Ae=15,N={},O=null,H=null,U=null,j=false;function ft(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function mt(e,t){let n=t.map(ft).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),I.push(o);I.length>Te;)I.shift();}function re(e){if(!e.url.includes("blocfeed.com"))for(D.push(e);D.length>Ae;)D.shift();}function Yt(e={}){if(!(j||!w())){if(j=true,Te=e.consoleLimit??20,Ae=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)N[n]=console[n],console[n]=(...r)=>{mt(n,r),N[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){O=window.fetch;let t=O;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,c=(o?.method??"GET").toUpperCase(),a=Date.now();try{let s=await t.call(window,r,o);return s.ok||re({url:i.slice(0,500),method:c,status:s.status,statusText:s.statusText,timestamp:a,durationMs:Date.now()-a}),s}catch(s){throw re({url:i.slice(0,500),method:c,status:0,statusText:s instanceof Error?s.message:"Network error",timestamp:a,durationMs:Date.now()-a}),s}};}if(e.network!==false&&typeof XMLHttpRequest<"u"){H=XMLHttpRequest.prototype.open,U=XMLHttpRequest.prototype.send;let t=H,n=U;XMLHttpRequest.prototype.open=function(r,o,...i){return this.__bf_method=r.toUpperCase(),this.__bf_url=String(o),t.apply(this,[r,o,...i])},XMLHttpRequest.prototype.send=function(...r){let o=this.__bf_method||"GET",i=this.__bf_url||"",c=Date.now();return this.addEventListener("loadend",function(){if(this.status>=400||this.status===0){let a={url:i.slice(0,500),method:o,status:this.status,timestamp:c,durationMs:Date.now()-c};this.statusText&&(a.statusText=this.statusText),re(a);}}),n.apply(this,r)};}}}function Kt(){if(j){for(let[e,t]of Object.entries(N))console[e]=t;for(let e of Object.keys(N))delete N[e];O&&(window.fetch=O,O=null),H&&(XMLHttpRequest.prototype.open=H,H=null),U&&(XMLHttpRequest.prototype.send=U,U=null),j=false;}}function Gt(){return {consoleLogs:[...I],networkErrors:[...D]}}function Zt(){I=[],D=[];}
2
+ export{w as a,J as b,pe as c,ye as d,be as e,ee as f,Ee as g,Ft as h,Tt as i,zt as j,Yt as k,Kt as l,Gt as m,Zt as n};
@@ -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";
@@ -207,6 +220,15 @@ interface BlocFeedConfig {
207
220
  strings?: BlocFeedStrings;
208
221
  /** Show "Powered by BlocFeed" watermark. Default: true */
209
222
  branding?: boolean;
223
+ /**
224
+ * Restrict widget visibility to specific routes.
225
+ * - `string[]` — route patterns (exact match or wildcard `*` suffix)
226
+ * - `(pathname: string) => boolean` — custom predicate
227
+ * - `undefined` — show on all pages (default)
228
+ */
229
+ showOn?: string[] | ((pathname: string) => boolean);
230
+ /** Which feedback categories to show as pills. Default: all four. */
231
+ categories?: FeedbackCategory[];
210
232
  };
211
233
  }
212
234
  interface ScreenshotIntent {
@@ -226,6 +248,8 @@ interface FeedbackPayload {
226
248
  createdAt: string;
227
249
  blocfeed_id: string;
228
250
  message: string;
251
+ /** Feedback category selected by the user. */
252
+ category?: FeedbackCategory;
229
253
  selection?: ElementDescriptor;
230
254
  screenshots?: CaptureResult;
231
255
  /** Lightweight screenshot metadata sent instead of base64 dataUrls. */
@@ -277,6 +301,7 @@ interface BlocFeedController {
277
301
  setConfig: (nextConfig: BlocFeedConfig) => void;
278
302
  submit: (message: string, options?: {
279
303
  capture?: CaptureConfig;
304
+ category?: FeedbackCategory;
280
305
  }) => Promise<SubmitResult>;
281
306
  /** Internal: used by UI to access the live element handle. */
282
307
  __unsafeGetSelectedElement: () => Element | null;
@@ -284,4 +309,4 @@ interface BlocFeedController {
284
309
  }
285
310
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
286
311
 
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 };
312
+ 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 SessionPhase as r, type TransportConfig as s, type TransportResult as t, type TriggerStyle as u, type StateListener as v, createBlocFeedController as w };
@@ -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";
@@ -207,6 +220,15 @@ interface BlocFeedConfig {
207
220
  strings?: BlocFeedStrings;
208
221
  /** Show "Powered by BlocFeed" watermark. Default: true */
209
222
  branding?: boolean;
223
+ /**
224
+ * Restrict widget visibility to specific routes.
225
+ * - `string[]` — route patterns (exact match or wildcard `*` suffix)
226
+ * - `(pathname: string) => boolean` — custom predicate
227
+ * - `undefined` — show on all pages (default)
228
+ */
229
+ showOn?: string[] | ((pathname: string) => boolean);
230
+ /** Which feedback categories to show as pills. Default: all four. */
231
+ categories?: FeedbackCategory[];
210
232
  };
211
233
  }
212
234
  interface ScreenshotIntent {
@@ -226,6 +248,8 @@ interface FeedbackPayload {
226
248
  createdAt: string;
227
249
  blocfeed_id: string;
228
250
  message: string;
251
+ /** Feedback category selected by the user. */
252
+ category?: FeedbackCategory;
229
253
  selection?: ElementDescriptor;
230
254
  screenshots?: CaptureResult;
231
255
  /** Lightweight screenshot metadata sent instead of base64 dataUrls. */
@@ -277,6 +301,7 @@ interface BlocFeedController {
277
301
  setConfig: (nextConfig: BlocFeedConfig) => void;
278
302
  submit: (message: string, options?: {
279
303
  capture?: CaptureConfig;
304
+ category?: FeedbackCategory;
280
305
  }) => Promise<SubmitResult>;
281
306
  /** Internal: used by UI to access the live element handle. */
282
307
  __unsafeGetSelectedElement: () => Element | null;
@@ -284,4 +309,4 @@ interface BlocFeedController {
284
309
  }
285
310
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
286
311
 
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 };
312
+ 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 SessionPhase as r, type TransportConfig as s, type TransportResult as t, type TriggerStyle as u, type StateListener as v, createBlocFeedController as w };
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 chunkCHN4RORX_cjs=require('./chunk-CHN4RORX.cjs');function c(o){if(o?.aborted)throw new Error("Aborted")}async function M(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 M(o);return {dataUrl:o,mime:t,width:e,height:r}}function F(o){return {async captureElement(t,e){if(!chunkCHN4RORX_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(!chunkCHN4RORX_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 chunkCHN4RORX_cjs.n}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.h}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.e}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.j}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.c}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.g}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.m}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.f}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.i}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.k}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.d}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkCHN4RORX_cjs.l}});exports.createModernScreenshotAdapter=F;exports.dataUrlToBlob=B;
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 } from './controller-hJ_lZRbR.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, r as SessionPhase, v as StateListener, S as SubmitResult, T as ThemeConfig, s as TransportConfig, u as TriggerStyle, W as WidgetPosition, w as createBlocFeedController } from './controller-hJ_lZRbR.cjs';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
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 } from './controller-hJ_lZRbR.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, r as SessionPhase, v as StateListener, S as SubmitResult, T as ThemeConfig, s as TransportConfig, u as TriggerStyle, W as WidgetPosition, w as createBlocFeedController } from './controller-hJ_lZRbR.js';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
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-DVNOWOIG.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-DVNOWOIG.js';function c(o){if(o?.aborted)throw new Error("Aborted")}async function M(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 M(o);return {dataUrl:o,mime:t,width:e,height:r}}function F(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{F as createModernScreenshotAdapter,B 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 chunkCHN4RORX_cjs=require('./chunk-CHN4RORX.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var U=react.createContext(null);function J(e){let t=react.useMemo(()=>chunkCHN4RORX_cjs.j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[i,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:i},children:e.children})}var he="blocfeed-styles-v1",ft=`
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
  /* ------------------------------------------------------------------ */
@@ -499,5 +584,5 @@
499
584
  animation: none;
500
585
  }
501
586
  }
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;
587
+ `;function xe(){if(!chunkCHN4RORX_cjs.a()||document.getElementById(he))return;let e=document.createElement("style");e.id=he,e.textContent=ft,document.head.appendChild(e);}var ye={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 we(e){return e?{...ye,...e}:ye}function Z(){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 x(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 ve({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 ke({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 Pe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){return i?jsxRuntime.jsxs("button",{className:x(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 m(){let[e,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return react.useEffect(()=>{let i=window.matchMedia("(prefers-reduced-motion: reduce)"),o=r=>t(r.matches);return i.addEventListener("change",o),()=>i.removeEventListener("change",o)},[]),e}var yt={duration:.18,ease:"easeOut"},wt={duration:0};function Ce({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?wt:yt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:x(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:n?1:[1,1.2,1],boxShadow:n?"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:n||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&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 Pt={duration:.18,ease:"easeOut"},Fe={duration:0};function Ne({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?Fe:Pt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsxs(framerMotion.motion.div,{className:x(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:n&&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?Fe:{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(ve,{size:16}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var St={duration:.2,ease:"easeOut"},Ft={duration:0};function Me(e){return e==="bottom-left"||e==="top-left"}function Bt(e){return `bf-trigger-edge ${Me(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Le({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=Me(e),s=m(),h=s?Ft:St;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:Bt(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,width:0},animate:{opacity:1,width:n?140:22,height:n?40:90},exit:{width:0,opacity:0},transition:h,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},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(b,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:s||n?0:a?-90:90,opacity:n?1:.6},transition:h,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[n&&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:n?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 Mt={duration:.18,ease:"easeOut"},Lt={duration:0};function ze({delay:e,hovered:t,reduced:i}){return i?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 We({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?Lt:Mt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:x(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(ze,{delay:0,hovered:n,reduced:a}),jsxRuntime.jsx(ze,{delay:.7,hovered:n,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:n&&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 Wt={duration:.18,ease:"easeOut"},_t={duration:0};function Ht(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 Oe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?_t:Wt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:Ht(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:a?0:5},animate:{opacity:n?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:n?1:0},transition:s})]},"minimal")})}var Kt={duration:.18,ease:"easeOut"},$t={duration:0};function Ke({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?$t:Kt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:x(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?{}:n?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:n||a?s:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(ke,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&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 Gt={duration:.18,ease:"easeOut"},Qt={duration:0};function Xe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),a=m(),s=a?Qt:Gt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:x(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:n?1:[.5,1,.5],boxShadow:n?"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:n||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),!n&&!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:n&&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 Zt={duration:.18,ease:"easeOut"},eo={duration:0};function je({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=react.useState(false),[a,s]=react.useState(0),h=m(),u=h?eo:Zt,f=react.useRef(null);react.useEffect(()=>{if(f.current&&(clearInterval(f.current),f.current=null),!i||n||h){s(n||h?o.length:0);return}let y=8,$=o.length*2+y*2,k=0;return f.current=setInterval(()=>{k=(k+1)%$,k<=o.length?s(k):k<=o.length+y?s(o.length):k<=o.length*2+y?s(o.length*2+y-k):s(0);},100),()=>{f.current&&(clearInterval(f.current),f.current=null);}},[i,n,h,o]);let g=o.slice(0,a);return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:i&&jsxRuntime.jsx(framerMotion.motion.button,{className:x(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:h?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:h?0:5},transition:u,whileTap:{scale:.95},style:{minWidth:"44px"},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(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:[g,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 Ve(e){switch(e){case "dot":return Ce;case "bubble":return Ne;case "edge-tab":return Le;case "pulse-ring":return We;case "minimal":return Oe;case "icon-pop":return Ke;case "beacon":return Xe;case "typewriter":return je;default:return Pe}}function Je(e,t,i){return Math.max(t,Math.min(i,e))}function no(e,t,i="bottom-right"){let r=window.innerWidth,c=window.innerHeight,n;n=Je(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:n}}function io(e){let{rect:t}=e,i={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:i,"aria-hidden":"true"})}function so(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 n=c[0],l=c[c.length-1];r.shiftKey&&document.activeElement===n?(r.preventDefault(),l.focus()):!r.shiftKey&&document.activeElement===l&&(r.preventDefault(),n.focus());};return document.addEventListener("keydown",o,{capture:true}),()=>document.removeEventListener("keydown",o,{capture:true})},[e]),t}function lo(e,t){return e?typeof e=="function"?e(t):e.some(i=>i.endsWith("*")?t.startsWith(i.slice(0,-1)):t===i):true}function co(e){let[t,i]=react.useState(()=>typeof window<"u"?window.location.pathname:"/");return react.useEffect(()=>{if(typeof window>"u")return;let o=()=>i(window.location.pathname);window.addEventListener("popstate",o);let r=history.pushState,c=history.replaceState;return history.pushState=function(...n){r.apply(this,n),o();},history.replaceState=function(...n){c.apply(this,n),o();},()=>{window.removeEventListener("popstate",o),history.pushState=r,history.replaceState=c;}},[]),lo(e,t)}function po(e){let[t,i]=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"){i(e==="light"?"light":"dark");return}let o=window.matchMedia("(prefers-color-scheme: dark)"),r=c=>i(c.matches?"dark":"light");return i(o.matches?"dark":"light"),o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e]),t}var fo=["bug","feature","ux","general"],uo={bug:"categoryBug",feature:"categoryFeature",ux:"categoryUx",general:"categoryGeneral"};function bo(e){let{state:t,controller:i,start:o,stop:r,clearSelection:c,submit:n}=Z(),l=e.config.ui?.position,a=we(e.config.ui?.strings),s=e.config.ui?.branding!==false,[h,u]=react.useState(null),[f,g]=react.useState(""),[y,$]=react.useState(e.config.capture?.element??true),[k,te]=react.useState(e.config.capture?.fullPage??false),[et,oe]=react.useState(null),[H,re]=react.useState(void 0),ae=e.config.ui?.categories??fo;react.useImperativeHandle(e.handleRef,()=>({open:o,close:r,submit:d=>n(d),get isOpen(){return t.phase!=="idle"}}),[o,r,n,t.phase]);let ne=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",tt=so(ne),[ot,rt]=react.useState(0);react.useEffect(()=>{t.phase==="idle"&&rt(chunkCHN4RORX_cjs.i());},[t.phase]);let[at,ie]=react.useState(false),se=react.useRef(t.phase);react.useEffect(()=>{if(se.current==="success"&&t.phase==="idle"){ie(true);let d=window.setTimeout(()=>ie(false),1500);return ()=>window.clearTimeout(d)}se.current=t.phase;},[t.phase]),react.useEffect(()=>{let d=e.config.ui?.shortcut;if(!d)return;let z=d.toLowerCase().split("+").map(C=>C.trim()),I=z[z.length-1]||"",R=new Set(z.slice(0,-1)),ce=C=>{let st=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(R.has("mod")){if(st?!C.metaKey:!C.ctrlKey)return}else if(R.has("ctrl")&&!C.ctrlKey||(R.has("meta")||R.has("cmd"))&&!C.metaKey)return;R.has("shift")&&!C.shiftKey||(R.has("alt")||R.has("option"))&&!C.altKey||C.key.toLowerCase()===I&&(C.preventDefault(),t.phase==="idle"?o():r());};return document.addEventListener("keydown",ce),()=>document.removeEventListener("keydown",ce)},[e.config.ui?.shortcut,t.phase,o,r]),react.useEffect(()=>i.subscribeHover(u),[i]),react.useEffect(()=>{let d=i.__unsafeGetSelectedElement();if(!d||t.phase==="idle"||t.phase==="picking"){oe(null);return}let z=()=>{oe(chunkCHN4RORX_cjs.b(d.getBoundingClientRect()));};z();let I=()=>z();return window.addEventListener("scroll",I,{capture:true,passive:true}),window.addEventListener("resize",I,{passive:true}),()=>{window.removeEventListener("scroll",I,{capture:true}),window.removeEventListener("resize",I);}},[i,t.phase,t.selection?.selector]),react.useEffect(()=>{t.phase==="review"&&(g(""),$(e.config.capture?.element??true),te(e.config.capture?.fullPage??false),re(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 E=t.phase==="capturing"||t.phase==="submitting",B=t.phase==="picking"?h?.rect??null:et??t.selection?.rect??null,j=react.useMemo(()=>B?no(B,360,l):null,[B?.x,B?.y,B?.width,B?.height,l]),le=t.lastError?.message,V=react.useCallback(()=>{let d={capture:{element:y,fullPage:k}};H&&(d.category=H),n(f,d);},[n,f,y,k,H]),nt=react.useCallback(d=>{(d.metaKey||d.ctrlKey)&&d.key==="Enter"&&f.trim().length>0&&!E&&(d.preventDefault(),V());},[V,f,E]),it=Ve(e.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(it,{position:l,onClick:()=>o(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??a.triggerLabel,queueCount:ot,showSuccess:at}),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(io,{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})]}),ne&&j&&jsxRuntime.jsxs("div",{ref:tt,className:"bf-panel",style:{left:j.left,top:j.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:E,"aria-label":a.rePickButton,children:a.rePickButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:E,"aria-label":a.closeButton,children:a.closeButton})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:a.textareaPlaceholder,value:f,onChange:d=>g(d.target.value),onKeyDown:nt,disabled:E,"aria-label":a.panelTitle}),ae.length>0&&jsxRuntime.jsx("div",{className:"bf-pills",role:"group","aria-label":"Feedback category",children:ae.map(d=>jsxRuntime.jsx("button",{type:"button",className:`bf-pill${H===d?" bf-pill-active":""}`,onClick:()=>re(H===d?void 0:d),disabled:E,children:a[uo[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:y,onChange:d=>$(d.target.checked),disabled:E}),a.screenshotElement]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:k,onChange:d=>te(d.target.checked),disabled:E}),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"&&le&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:le}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:E,"aria-label":a.cancelButton,children:a.cancelButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:E||f.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})]})}var go=react.forwardRef(function(t,i){let o={...t.config??{},blocfeed_id:t.blocfeed_id},[r,c]=react.useState(null),n=co(o.ui?.showOn),l=po(o.ui?.theme?.mode),a=!!o.diagnostics;react.useEffect(()=>{if(a)return chunkCHN4RORX_cjs.k(o.diagnostics),()=>chunkCHN4RORX_cjs.l()},[a]);let s=react.useRef(t.config?.metadata?.enrich);s.current=t.config?.metadata?.enrich;let h=react.useMemo(()=>{if(t.config)return {...t.config,metadata:{...t.config.metadata,enrich:async u=>{let f=s.current,g=f?await f(u):{},y=chunkCHN4RORX_cjs.m();return {...g,...y.consoleLogs.length>0?{_consoleLogs:y.consoleLogs}:{},...y.networkErrors.length>0?{_networkErrors:y.networkErrors}:{}}}}}},[]);return react.useEffect(()=>{xe();let u=document.createElement("div");u.setAttribute("data-blocfeed-ui-root","true"),u.setAttribute("data-blocfeed-ui","true"),u.setAttribute("data-bf-theme",l);let f=o.ui?.zIndex;typeof f=="number"&&u.style.setProperty("--bf-z",String(f));let g=o.ui?.theme;return g&&(g.accentColor&&u.style.setProperty("--bf-accent",g.accentColor),g.panelBackground&&u.style.setProperty("--bf-panel-bg",g.panelBackground),g.panelForeground&&u.style.setProperty("--bf-panel-fg",g.panelForeground),g.fontFamily&&u.style.setProperty("--bf-font",g.fontFamily)),document.body.appendChild(u),c(u),()=>{u.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]),!n||!r?null:reactDom.createPortal(jsxRuntime.jsx(J,{blocfeed_id:o.blocfeed_id,...h?{config:h}:{},children:jsxRuntime.jsx(bo,{config:o,handleRef:i})}),r)});
588
+ exports.BlocFeedProvider=J;exports.BlocFeedWidget=go;exports.useBlocFeed=Z;
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-hJ_lZRbR.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 SessionPhase, T as ThemeConfig, s as TransportConfig, t as TransportResult, u as TriggerStyle, W as WidgetPosition } from './controller-hJ_lZRbR.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-hJ_lZRbR.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 SessionPhase, T as ThemeConfig, s as TransportConfig, t as TransportResult, u as TriggerStyle, W as WidgetPosition } from './controller-hJ_lZRbR.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 };
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import {j,k,l,m as m$1,a,i,b as b$1}from'./chunk-QPAFC4IL.js';import {createContext,useMemo,useState,useEffect,useContext,useRef,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var $=createContext(null);function J(e){let t=useMemo(()=>j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[l,i]=useState(()=>t.getState());return useEffect(()=>t.subscribe(i),[t]),useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),useEffect(()=>()=>t.destroy(),[t]),jsx($.Provider,{value:{controller:t,state:l},children:e.children})}var be="blocfeed-styles-v1",ct=`
2
+ import {k,l,m as m$1,a,j,i,b as b$1}from'./chunk-DVNOWOIG.js';import {createContext,forwardRef,useState,useEffect,useRef,useMemo,useImperativeHandle,useCallback,useContext}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var U=createContext(null);function J(e){let t=useMemo(()=>j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[i,o]=useState(()=>t.getState());return useEffect(()=>t.subscribe(o),[t]),useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),useEffect(()=>()=>t.destroy(),[t]),jsx(U.Provider,{value:{controller:t,state:i},children:e.children})}var he="blocfeed-styles-v1",ft=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -20,6 +20,52 @@ import {j,k,l,m as m$1,a,i,b as b$1}from'./chunk-QPAFC4IL.js';import {createCont
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 @@ import {j,k,l,m as m$1,a,i,b as b$1}from'./chunk-QPAFC4IL.js';import {createCont
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
  /* ------------------------------------------------------------------ */
@@ -499,5 +584,5 @@ import {j,k,l,m as m$1,a,i,b as b$1}from'./chunk-QPAFC4IL.js';import {createCont
499
584
  animation: none;
500
585
  }
501
586
  }
502
- `;function ge(){if(!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=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 jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function xe({size:e=14}){return jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children: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 jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[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"}),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?jsxs("button",{className:m(e),type:"button",onClick:t,"aria-label":i,children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function b(){let[e,t]=useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return 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]=useState(false),o=b(),n=o?ht:mt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(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"}}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(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&&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]=useState(false),o=b(),n=o?Ee:wt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsxs(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:[jsx(AnimatePresence,{mode:"wait",children:a&&jsx(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")}),jsxs(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:16})},"success"):jsx(xe,{size:16}),r>0&&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]=useState(false),o=Be(e),n=b(),u=n?Et:Pt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs(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&&jsx(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]}),jsx(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&&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:jsx(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]=useState(false),o=b(),n=o?Ft:Bt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(Me,{delay:0,hovered:a,reduced:o}),jsx(Me,{delay:.7,hovered:a,reduced:o}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(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&&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]=useState(false),o=b(),n=o?It:zt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsxs(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?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{children:i}),r>0&&jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!o&&jsx(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]=useState(false),o=b(),n=o?Ht:Ot;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(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:jsx(ye,{size:16})}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(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&&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]=useState(false),o=b(),n=o?Yt:Xt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(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&&jsx(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"}})]}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(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&&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]=useState(false),[o,n]=useState(0),u=b(),H=u?Jt:Gt,g=useRef(null);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 jsx(AnimatePresence,{mode:"wait",children:l&&jsx(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:H,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[D,jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&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 jsx("div",{className:"bf-highlight",style:l,"aria-hidden":"true"})}function oo(e){let t=useRef(null);return 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$1,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]=useState(null),[g,D]=useState(""),[E,K]=useState(e.config.capture?.element??true),[x,ee]=useState(e.config.capture?.fullPage??false),[Je,te]=useState(null),oe=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",Ze=oo(oe),[qe,et]=useState(0);useEffect(()=>{t.phase==="idle"&&et(i());},[t.phase]);let[tt,re]=useState(false),ie=useRef(t.phase);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]),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$1():r());};return document.addEventListener("keydown",ae),()=>document.removeEventListener("keydown",ae)},[e.config.ui?.shortcut,t.phase,i$1,r]),useEffect(()=>l.subscribeHover(H),[l]),useEffect(()=>{let p=l.__unsafeGetSelectedElement();if(!p||t.phase==="idle"||t.phase==="picking"){te(null);return}let L=()=>{te(b$1(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]),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]),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=useMemo(()=>S?eo(S,360,s):null,[S?.x,S?.y,S?.width,S?.height,s]),ne=t.lastError?.message,V=useCallback(()=>{a(g,{capture:{element:E,fullPage:x}});},[a,g,E,x]),ot=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 jsxs(Fragment,{children:[jsx(rt,{position:s,onClick:()=>i$1(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??o.triggerLabel,queueCount:qe,showSuccess:tt}),t.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),S&&jsx(to,{rect:S}),t.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsx("p",{id:"bf-hint-text",children:o.hintText}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":o.cancelButton,children:o.cancelButton})]}),oe&&Q&&jsxs("div",{ref:Ze,className:"bf-panel",style:{left:Q.left,top:Q.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:o.panelTitle}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:k,"aria-label":o.rePickButton,children:o.rePickButton}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.closeButton,children:o.closeButton})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:o.textareaPlaceholder,value:g,onChange:p=>D(p.target.value),onKeyDown:ot,disabled:k,"aria-label":o.panelTitle}),jsxs("div",{className:"bf-row",role:"group","aria-label":o.screenshotElement,children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:E,onChange:p=>K(p.target.checked),disabled:k}),o.screenshotElement]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:x,onChange:p=>ee(p.target.checked),disabled:k}),o.screenshotFullPage]})]}),t.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.capturingText]}),t.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.submittingText]}),t.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:o.successText}),t.phase==="error"&&ne&&jsx("div",{className:"bf-error",role:"alert",children:ne}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.cancelButton,children:o.cancelButton}),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&&jsx("div",{className:"bf-watermark",children:jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&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$1,i]=useState(null),r=!!t.diagnostics;useEffect(()=>{if(r)return k(t.diagnostics),()=>l()},[r]);let c=useRef(e.config?.metadata?.enrich);c.current=e.config?.metadata?.enrich;let a=useMemo(()=>{if(e.config)return {...e.config,metadata:{...e.config.metadata,enrich:async s=>{let o=c.current,n=o?await o(s):{},u=m$1();return {...n,...u.consoleLogs.length>0?{_consoleLogs:u.consoleLogs}:{},...u.networkErrors.length>0?{_networkErrors:u.networkErrors}:{}}}}}},[]);return 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$1?createPortal(jsx(J,{blocfeed_id:t.blocfeed_id,...a?{config:a}:{},children:jsx(ro,{config:t})}),l$1):null}
503
- export{J as BlocFeedProvider,io as BlocFeedWidget,Z as useBlocFeed};
587
+ `;function xe(){if(!a()||document.getElementById(he))return;let e=document.createElement("style");e.id=he,e.textContent=ft,document.head.appendChild(e);}var ye={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 we(e){return e?{...ye,...e}:ye}function Z(){let e=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 x(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 jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function ve({size:e=14}){return jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children: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 ke({size:e=16}){return jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[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"}),jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function Pe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){return i?jsxs("button",{className:x(e),type:"button",onClick:t,"aria-label":o,children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})}):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),o]}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function m(){let[e,t]=useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return useEffect(()=>{let i=window.matchMedia("(prefers-reduced-motion: reduce)"),o=r=>t(r.matches);return i.addEventListener("change",o),()=>i.removeEventListener("change",o)},[]),e}var yt={duration:.18,ease:"easeOut"},wt={duration:0};function Ce({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?wt:yt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:x(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{className:"bf-dot","aria-hidden":"true",animate:a?{}:{scale:n?1:[1,1.2,1],boxShadow:n?"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:n||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsx(AnimatePresence,{mode:"wait",children:n&&jsx(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&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"dot")})}var Pt={duration:.18,ease:"easeOut"},Fe={duration:0};function Ne({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?Fe:Pt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsxs(motion.div,{className:x(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:[jsx(AnimatePresence,{mode:"wait",children:n&&jsx(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")}),jsxs(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?Fe:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:16})},"success"):jsx(ve,{size:16}),r>0&&jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var St={duration:.2,ease:"easeOut"},Ft={duration:0};function Me(e){return e==="bottom-left"||e==="top-left"}function Bt(e){return `bf-trigger-edge ${Me(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Le({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=Me(e),s=m(),h=s?Ft:St;return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:Bt(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,width:0},animate:{opacity:1,width:n?140:22,height:n?40:90},exit:{width:0,opacity:0},transition:h,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:h,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsxs(motion.span,{animate:{rotate:s||n?0:a?-90:90,opacity:n?1:.6},transition:h,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[n&&jsx(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]}),jsx(motion.span,{"aria-hidden":"true",animate:{opacity:n?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[a?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"edge-tab")})}var Mt={duration:.18,ease:"easeOut"},Lt={duration:0};function ze({delay:e,hovered:t,reduced:i}){return i?null:jsx(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 We({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?Lt:Mt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:x(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(ze,{delay:0,hovered:n,reduced:a}),jsx(ze,{delay:.7,hovered:n,reduced:a}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsx(AnimatePresence,{mode:"wait",children:n&&jsx(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&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"pulse-ring")})}var Wt={duration:.18,ease:"easeOut"},_t={duration:0};function Ht(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 Oe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?_t:Wt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsxs(motion.button,{className:Ht(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:a?0:5},animate:{opacity:n?1:.65,y:0},exit:{opacity:0,y:a?0:5},transition:s,whileTap:{scale:.95},children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})}):jsxs(Fragment,{children:[jsx("span",{children:o}),r>0&&jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!a&&jsx(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:n?1:0},transition:s})]},"minimal")})}var Kt={duration:.18,ease:"easeOut"},$t={duration:0};function Ke({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?$t:Kt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:x(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{style:{display:"inline-flex",flexShrink:0},animate:a?{}:n?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:n||a?s:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsx(ke,{size:16})}),jsx(AnimatePresence,{mode:"wait",children:n&&jsx(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&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"icon-pop")})}var Gt={duration:.18,ease:"easeOut"},Qt={duration:0};function Xe({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),a=m(),s=a?Qt:Gt;return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:x(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?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:a?{}:{opacity:n?1:[.5,1,.5],boxShadow:n?"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:n||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),!n&&!a&&jsx(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"}})]}),jsx(AnimatePresence,{mode:"wait",children:n&&jsx(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&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"beacon")})}var Zt={duration:.18,ease:"easeOut"},eo={duration:0};function je({position:e,onClick:t,isVisible:i,label:o,queueCount:r,showSuccess:c}){let[n,l]=useState(false),[a,s]=useState(0),h=m(),u=h?eo:Zt,f=useRef(null);useEffect(()=>{if(f.current&&(clearInterval(f.current),f.current=null),!i||n||h){s(n||h?o.length:0);return}let y=8,$=o.length*2+y*2,k=0;return f.current=setInterval(()=>{k=(k+1)%$,k<=o.length?s(k):k<=o.length+y?s(o.length):k<=o.length*2+y?s(o.length*2+y-k):s(0);},100),()=>{f.current&&(clearInterval(f.current),f.current=null);}},[i,n,h,o]);let g=o.slice(0,a);return jsx(AnimatePresence,{mode:"wait",children:i&&jsx(motion.button,{className:x(e),type:"button",onClick:t,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":o,initial:{opacity:0,y:h?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:h?0:5},transition:u,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(b,{size:14})},"success"):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[g,jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"typewriter")})}function Ve(e){switch(e){case "dot":return Ce;case "bubble":return Ne;case "edge-tab":return Le;case "pulse-ring":return We;case "minimal":return Oe;case "icon-pop":return Ke;case "beacon":return Xe;case "typewriter":return je;default:return Pe}}function Je(e,t,i){return Math.max(t,Math.min(i,e))}function no(e,t,i="bottom-right"){let r=window.innerWidth,c=window.innerHeight,n;n=Je(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:n}}function io(e){let{rect:t}=e,i={left:`${t.x}px`,top:`${t.y}px`,width:`${Math.max(0,t.width)}px`,height:`${Math.max(0,t.height)}px`};return jsx("div",{className:"bf-highlight",style:i,"aria-hidden":"true"})}function so(e){let t=useRef(null);return 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 n=c[0],l=c[c.length-1];r.shiftKey&&document.activeElement===n?(r.preventDefault(),l.focus()):!r.shiftKey&&document.activeElement===l&&(r.preventDefault(),n.focus());};return document.addEventListener("keydown",o,{capture:true}),()=>document.removeEventListener("keydown",o,{capture:true})},[e]),t}function lo(e,t){return e?typeof e=="function"?e(t):e.some(i=>i.endsWith("*")?t.startsWith(i.slice(0,-1)):t===i):true}function co(e){let[t,i]=useState(()=>typeof window<"u"?window.location.pathname:"/");return useEffect(()=>{if(typeof window>"u")return;let o=()=>i(window.location.pathname);window.addEventListener("popstate",o);let r=history.pushState,c=history.replaceState;return history.pushState=function(...n){r.apply(this,n),o();},history.replaceState=function(...n){c.apply(this,n),o();},()=>{window.removeEventListener("popstate",o),history.pushState=r,history.replaceState=c;}},[]),lo(e,t)}function po(e){let[t,i]=useState(()=>!e||e==="dark"?"dark":e==="light"?"light":typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return useEffect(()=>{if(e!=="auto"){i(e==="light"?"light":"dark");return}let o=window.matchMedia("(prefers-color-scheme: dark)"),r=c=>i(c.matches?"dark":"light");return i(o.matches?"dark":"light"),o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e]),t}var fo=["bug","feature","ux","general"],uo={bug:"categoryBug",feature:"categoryFeature",ux:"categoryUx",general:"categoryGeneral"};function bo(e){let{state:t,controller:i$1,start:o,stop:r,clearSelection:c,submit:n}=Z(),l=e.config.ui?.position,a=we(e.config.ui?.strings),s=e.config.ui?.branding!==false,[h,u]=useState(null),[f,g]=useState(""),[y,$]=useState(e.config.capture?.element??true),[k,te]=useState(e.config.capture?.fullPage??false),[et,oe]=useState(null),[H,re]=useState(void 0),ae=e.config.ui?.categories??fo;useImperativeHandle(e.handleRef,()=>({open:o,close:r,submit:d=>n(d),get isOpen(){return t.phase!=="idle"}}),[o,r,n,t.phase]);let ne=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",tt=so(ne),[ot,rt]=useState(0);useEffect(()=>{t.phase==="idle"&&rt(i());},[t.phase]);let[at,ie]=useState(false),se=useRef(t.phase);useEffect(()=>{if(se.current==="success"&&t.phase==="idle"){ie(true);let d=window.setTimeout(()=>ie(false),1500);return ()=>window.clearTimeout(d)}se.current=t.phase;},[t.phase]),useEffect(()=>{let d=e.config.ui?.shortcut;if(!d)return;let z=d.toLowerCase().split("+").map(C=>C.trim()),I=z[z.length-1]||"",R=new Set(z.slice(0,-1)),ce=C=>{let st=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(R.has("mod")){if(st?!C.metaKey:!C.ctrlKey)return}else if(R.has("ctrl")&&!C.ctrlKey||(R.has("meta")||R.has("cmd"))&&!C.metaKey)return;R.has("shift")&&!C.shiftKey||(R.has("alt")||R.has("option"))&&!C.altKey||C.key.toLowerCase()===I&&(C.preventDefault(),t.phase==="idle"?o():r());};return document.addEventListener("keydown",ce),()=>document.removeEventListener("keydown",ce)},[e.config.ui?.shortcut,t.phase,o,r]),useEffect(()=>i$1.subscribeHover(u),[i$1]),useEffect(()=>{let d=i$1.__unsafeGetSelectedElement();if(!d||t.phase==="idle"||t.phase==="picking"){oe(null);return}let z=()=>{oe(b$1(d.getBoundingClientRect()));};z();let I=()=>z();return window.addEventListener("scroll",I,{capture:true,passive:true}),window.addEventListener("resize",I,{passive:true}),()=>{window.removeEventListener("scroll",I,{capture:true}),window.removeEventListener("resize",I);}},[i$1,t.phase,t.selection?.selector]),useEffect(()=>{t.phase==="review"&&(g(""),$(e.config.capture?.element??true),te(e.config.capture?.fullPage??false),re(void 0));},[t.phase,t.selection?.selector,e.config.capture?.element,e.config.capture?.fullPage]),useEffect(()=>{if(t.phase!=="success")return;let d=window.setTimeout(()=>r(),1200);return ()=>window.clearTimeout(d)},[t.phase,r]);let E=t.phase==="capturing"||t.phase==="submitting",B=t.phase==="picking"?h?.rect??null:et??t.selection?.rect??null,j=useMemo(()=>B?no(B,360,l):null,[B?.x,B?.y,B?.width,B?.height,l]),le=t.lastError?.message,V=useCallback(()=>{let d={capture:{element:y,fullPage:k}};H&&(d.category=H),n(f,d);},[n,f,y,k,H]),nt=useCallback(d=>{(d.metaKey||d.ctrlKey)&&d.key==="Enter"&&f.trim().length>0&&!E&&(d.preventDefault(),V());},[V,f,E]),it=Ve(e.config.ui?.triggerStyle);return jsxs(Fragment,{children:[jsx(it,{position:l,onClick:()=>o(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??a.triggerLabel,queueCount:ot,showSuccess:at}),t.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),B&&jsx(io,{rect:B}),t.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsx("p",{id:"bf-hint-text",children:a.hintText}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":a.cancelButton,children:a.cancelButton})]}),ne&&j&&jsxs("div",{ref:tt,className:"bf-panel",style:{left:j.left,top:j.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:a.panelTitle}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:E,"aria-label":a.rePickButton,children:a.rePickButton}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:E,"aria-label":a.closeButton,children:a.closeButton})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:a.textareaPlaceholder,value:f,onChange:d=>g(d.target.value),onKeyDown:nt,disabled:E,"aria-label":a.panelTitle}),ae.length>0&&jsx("div",{className:"bf-pills",role:"group","aria-label":"Feedback category",children:ae.map(d=>jsx("button",{type:"button",className:`bf-pill${H===d?" bf-pill-active":""}`,onClick:()=>re(H===d?void 0:d),disabled:E,children:a[uo[d]]},d))}),jsxs("div",{className:"bf-row",role:"group","aria-label":a.screenshotElement,children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:y,onChange:d=>$(d.target.checked),disabled:E}),a.screenshotElement]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:k,onChange:d=>te(d.target.checked),disabled:E}),a.screenshotFullPage]})]}),t.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),a.capturingText]}),t.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),a.submittingText]}),t.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:a.successText}),t.phase==="error"&&le&&jsx("div",{className:"bf-error",role:"alert",children:le}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:E,"aria-label":a.cancelButton,children:a.cancelButton}),jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:E||f.trim().length===0,"aria-label":a.sendButton,children:a.sendButton})]})]}),s&&jsx("div",{className:"bf-watermark",children:jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:a.toastText})]})}var go=forwardRef(function(t,i){let o={...t.config??{},blocfeed_id:t.blocfeed_id},[r,c]=useState(null),n=co(o.ui?.showOn),l$1=po(o.ui?.theme?.mode),a=!!o.diagnostics;useEffect(()=>{if(a)return k(o.diagnostics),()=>l()},[a]);let s=useRef(t.config?.metadata?.enrich);s.current=t.config?.metadata?.enrich;let h=useMemo(()=>{if(t.config)return {...t.config,metadata:{...t.config.metadata,enrich:async u=>{let f=s.current,g=f?await f(u):{},y=m$1();return {...g,...y.consoleLogs.length>0?{_consoleLogs:y.consoleLogs}:{},...y.networkErrors.length>0?{_networkErrors:y.networkErrors}:{}}}}}},[]);return useEffect(()=>{xe();let u=document.createElement("div");u.setAttribute("data-blocfeed-ui-root","true"),u.setAttribute("data-blocfeed-ui","true"),u.setAttribute("data-bf-theme",l$1);let f=o.ui?.zIndex;typeof f=="number"&&u.style.setProperty("--bf-z",String(f));let g=o.ui?.theme;return g&&(g.accentColor&&u.style.setProperty("--bf-accent",g.accentColor),g.panelBackground&&u.style.setProperty("--bf-panel-bg",g.panelBackground),g.panelForeground&&u.style.setProperty("--bf-panel-fg",g.panelForeground),g.fontFamily&&u.style.setProperty("--bf-font",g.fontFamily)),document.body.appendChild(u),c(u),()=>{u.remove(),c(null);}},[o.ui?.zIndex,o.ui?.theme?.accentColor,o.ui?.theme?.panelBackground,o.ui?.theme?.panelForeground,o.ui?.theme?.fontFamily,l$1]),useEffect(()=>{r&&r.setAttribute("data-bf-theme",l$1);},[r,l$1]),!n||!r?null:createPortal(jsx(J,{blocfeed_id:o.blocfeed_id,...h?{config:h}:{},children:jsx(bo,{config:o,handleRef:i})}),r)});
588
+ export{J as BlocFeedProvider,go as BlocFeedWidget,Z as useBlocFeed};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blocfeed",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Drop-in feedback + screenshot widget for React.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,2 +0,0 @@
1
- 'use strict';function m(){return typeof window<"u"&&typeof document<"u"}function te(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function Q(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Te(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Re(e){return e.replace(/\s+/g," ").trim()}function Ae(e,t=140){let n=e.textContent;if(!n)return;let r=Re(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ce(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var oe=["data-testid","data-test-id","data-test","data-qa","data-cy"],ne="data-blocfeed-component";function Me(e){let t=e.closest(`[${ne}]`);if(!t)return;let r=t.getAttribute(ne)?.trim();return r||void 0}function Be(e){for(let t of oe){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function Le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return B(o)}}}function _e(e){let t=Le(e);if(!t)return;let n=t._debugOwner!==void 0;if(n){let i=t._debugOwner;for(let a=0;i&&a<50;a+=1){let s=B(i.type)??B(i.elementType);if(s)return s;i=i._debugOwner;}}let r=t,o=n?80:10;for(let i=0;r&&i<o;i+=1){let a=B(r.type)??B(r.elementType);if(a)return a;r=r.return;}}function Ie(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${te(n)}`;for(let r of oe){let o=e.getAttribute(r);if(o)return `${t}[${r}="${te(o)}"]`}return `${t}:nth-of-type(${Ce(e)})`}function De(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=Ie(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function re(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function W(e,t){if(!e||re(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(re(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??Ne(n))return n;n=n.parentElement;}return null}function Ne(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function ie(e){let t=e.getBoundingClientRect(),n={selector:De(e),tagName:e.tagName.toLowerCase(),rect:Q(t),pageRect:Te(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Ae(e);i&&(n.textSnippet=i);let a=Me(e)??_e(e);a&&(n.componentName=a);let s=Be(e);return s&&(n.testId=s),n}var z=null;async function ae(){return z||(z=import('html-to-image')),z}async function Ue(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function se(e,t){let{width:n,height:r}=await Ue(e);return {dataUrl:e,mime:t,width:n,height:r}}function A(e){if(e?.aborted)throw new Error("Aborted")}function le(){return {async captureElement(e,t){if(!m())throw new Error("captureElement can only run in the browser");A(t.signal);let n=await ae();A(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return A(t.signal),await se(r,t.mime)},async captureFullPage(e){if(!m())throw new Error("captureFullPage can only run in the browser");A(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),a=Math.max(1,Math.round(r*o)),s=await ae();A(e.signal);let f=e.mime==="image/jpeg"?await s.toJpeg(t,{width:i,height:a,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await s.toPng(t,{width:i,height:a,pixelRatio:e.pixelRatio});return A(e.signal),await se(f,e.mime)}}}function Oe(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function p(e,t,n){let r={kind:e,message:Oe(t)};return n&&(r.detail=n),r}var He=12e3,qe=2048,$e=.92;function ce(){return Date.now()}function je(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function ue(e,t,n){let r=new Promise((i,a)=>{let s=setTimeout(()=>a(new Error("Timeout")),t);typeof s.unref=="function"&&s.unref();}),o=[e,r];return n&&o.push(je(n)),await Promise.race(o)}function Qe(e){if(!m())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function We(e){return !!(e?.element||e?.fullPage)}function de(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function fe(e){let{selectionElement:t,capture:n,signal:r}=e;if(!m()||!We(n))return;let o=ce(),i=[],a=n?.timeoutMs??He,s=n?.maxDimension??qe,f=n?.mime??"image/png",g=n?.quality??$e,w=n?.adapter??le(),y={},E=Qe(n);if(n?.element&&t)try{let c=t.getBoundingClientRect(),u=Math.min(1,s/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ue(Promise.resolve(w.captureElement(t,{...de({mime:f,quality:g,pixelRatio:v,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),a,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ue(Promise.resolve(w.captureFullPage(de({mime:f,quality:g,pixelRatio:E,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),a,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"fullPage"}));}let h=ce(),l={startedAt:o,finishedAt:h,durationMs:Math.max(0,h-o)};return i.length>0&&(l.errors=i),{...y,diagnostics:l}}function ze(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Je(){return m()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:ze()}:{}}function Ye(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function me(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Je(),...Ye(r)},i=t?.enrich;if(!i)return o;try{let a=await i(n);return {...o,...a}}catch(a){let s=p("unknown",a);return {...o,blocfeedMetadataError:s.message}}}var J="blocfeed-queue",Ke=50;function Y(){if(!m())return [];try{let e=localStorage.getItem(J);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function K(e){if(m())try{e.length===0?localStorage.removeItem(J):localStorage.setItem(J,JSON.stringify(e));}catch{}}function Xe(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function X(e){let t=Y(),n=Xe(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ke;)t.shift();K(t);}function pe(){let e=Y();return e.length===0?[]:(K([]),e.map(t=>t.payload))}function vt(){K([]);}function Pt(){return Y().length}function G(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function U(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function O(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ge(e,t){if(!m())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,a=null,s=(l,c=false)=>{if(!l){i=null,a=null,t.onHover(null);return}let u=Q(l.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&l===i&&v===a||(i=l,a=v,t.onHover({element:l,rect:u}));},f=G(l=>{if(U(l.target))return;let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);s(u);}),g=G(()=>{i&&s(i,true);}),w=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},y=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},E=l=>{if(U(l.target))return;O(l),l.preventDefault();let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);u&&t.onSelect({element:u,descriptor:ie(u)});},h=l=>{l.key==="Escape"&&(O(l),l.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",h,{capture:true}),window.addEventListener("scroll",g,{capture:true,passive:true}),window.addEventListener("resize",g,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",h,{capture:true}),window.removeEventListener("scroll",g,{capture:true}),window.removeEventListener("resize",g),f.cancel(),g.cancel(),t.onHover(null);}}}var Ge=12e3,Ze=2,Ve=500,et=2e3,ye="https://blocfeed.com/api/feedback",he=0;function we(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function tt(e){return e>=500&&e<=599}function nt(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),a=new Uint8Array(i.length);for(let s=0;s<i.length;s+=1)a[s]=i.charCodeAt(s);return new Blob([a],{type:o})}function rt(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function be(e,t,n){let r=nt(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function ot(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${ye}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Ee(e){let{signal:t,transport:n}=e;if(Date.now()-he<et)return {ok:false,error:p("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??Ge,i=n?.maxAttempts??Ze,a=n?.backoffMs??Ve,s=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:g}=s?rt(e.payload):{lean:e.payload,extracted:{}},w={...g,...e.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,h=setTimeout(()=>E.abort(),o),l=()=>E.abort();t&&t.addEventListener("abort",l,{once:true});try{let c=await fetch(ye,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){he=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let S=[];w.element&&d.element&&S.push(be(d.element,w.element,t)),w.fullPage&&d.fullPage&&S.push(be(d.fullPage,w.fullPage,t));try{await Promise.all(S);}catch{}}else if(u.feedback_id)try{await ot({feedbackId:u.feedback_id,extracted:w,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&tt(c.status)){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:!1,status:c.status,error:p("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||t?.aborted)return {ok:false,error:p("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:false,error:p("api_failed",c)}}finally{clearTimeout(h),t&&t.removeEventListener("abort",l);}}return {ok:false,error:p("api_failed",new Error("Failed"))}}async function Z(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Ee(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:p("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var it=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function at(e){let t=[...it,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function ke(){return {phase:"idle"}}function st(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function $t(e){let t=e,n=ke(),r=new Set,o=new Set,i=null,a=null,s=null,f=null,g=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let S of o)S(d);},h=d=>{n=d,y();},l=()=>{g+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),s!==null&&m()&&(document.documentElement.style.cursor=s,s=null);},u=()=>{l(),c(),a=null,h(ke());},v=()=>{if(!m())return;c(),a=null;let d=at(t.picker);s=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",h({phase:"picking"}),i=ge(d,{onHover:E,onSelect:({element:S,descriptor:N})=>{a=S,c(),h({phase:"review",selection:N});},onCancel:()=>{u();}});},x=()=>{let d=pe();if(d.length!==0)for(let S of d)Z({payload:S,...t.transport?{transport:t.transport}:{}}).catch(()=>{X(S);});};if(m()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){t=d;},async submit(d,S){if(!m()){let b=p("configuration",new Error("BlocFeed submit can only run in the browser"));return h({phase:"error",lastError:b}),{ok:false}}let N=t.blocfeed_id?.trim?.()??"";if(!N){let F={phase:"error",lastError:p("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),h(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=g+1;g=C,f?.abort(),f=new AbortController;let T=f.signal,k=n.selection,q=S?.capture?{...t.capture,...S.capture}:t.capture,V=!!(q?.element||q?.fullPage),ee={phase:V?"capturing":"submitting"};k&&(ee.selection=k),h(ee);try{let b=V?await fe({selectionElement:a,capture:q,signal:T}):void 0;if(T.aborted||g!==C)return {ok:!1};let F={phase:"submitting"};k&&(F.selection=k),b&&(F.capture=b),h(F);let R={};k&&(R.selection=k),b&&(R.capture=b);let xe=await me({config:t.metadata,context:R,...t.user?{user:t.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:N,message:d,metadata:xe};t.user&&(M.user=t.user),k&&(M.selection=k),b&&(M.screenshots=b);let{result:P}=await Z({payload:M,signal:T,...t.transport?{transport:t.transport}:{}});if(T.aborted||g!==C)return P;if(P.ok){let j={phase:"success",lastSubmit:P};return k&&(j.selection=k),b&&(j.capture=b),h(j),P}st(P)&&X(M);let Fe=P.api?.error??p("unknown",new Error("Submission failed")),$={phase:"error",lastSubmit:P,lastError:Fe};return k&&($.selection=k),b&&($.capture=b),h($),P}catch(b){if(T.aborted||g!==C)return {ok:false};let R={phase:"error",lastError:T.aborted?p("aborted",b):p("unknown",b)};return k&&(R.selection=k),h(R),{ok:false}}finally{g===C&&(f=null);}},__unsafeGetSelectedElement(){return a},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}var L=[],_=[],ve=20,Pe=15,I={},D=null,H=false;function lt(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function ct(e,t){let n=t.map(lt).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),L.push(o);L.length>ve;)L.shift();}function Se(e){if(!e.url.includes("blocfeed.com"))for(_.push(e);_.length>Pe;)_.shift();}function Wt(e={}){if(!(H||!m())){if(H=true,ve=e.consoleLimit??20,Pe=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)I[n]=console[n],console[n]=(...r)=>{ct(n,r),I[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){D=window.fetch;let t=D;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,a=(o?.method??"GET").toUpperCase(),s=Date.now();try{let f=await t.call(window,r,o);return f.ok||Se({url:i.slice(0,500),method:a,status:f.status,statusText:f.statusText,timestamp:s,durationMs:Date.now()-s}),f}catch(f){throw Se({url:i.slice(0,500),method:a,status:0,statusText:f instanceof Error?f.message:"Network error",timestamp:s,durationMs:Date.now()-s}),f}};}}}function zt(){if(H){for(let[e,t]of Object.entries(I))console[e]=t;for(let e of Object.keys(I))delete I[e];D&&(window.fetch=D,D=null),H=false;}}function Jt(){return {consoleLogs:[...L],networkErrors:[..._]}}function Yt(){L=[],_=[];}
2
- exports.a=m;exports.b=Q;exports.c=le;exports.d=fe;exports.e=me;exports.f=X;exports.g=pe;exports.h=vt;exports.i=Pt;exports.j=$t;exports.k=Wt;exports.l=zt;exports.m=Jt;exports.n=Yt;
@@ -1,2 +0,0 @@
1
- function m(){return typeof window<"u"&&typeof document<"u"}function te(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function Q(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Te(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Re(e){return e.replace(/\s+/g," ").trim()}function Ae(e,t=140){let n=e.textContent;if(!n)return;let r=Re(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ce(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var oe=["data-testid","data-test-id","data-test","data-qa","data-cy"],ne="data-blocfeed-component";function Me(e){let t=e.closest(`[${ne}]`);if(!t)return;let r=t.getAttribute(ne)?.trim();return r||void 0}function Be(e){for(let t of oe){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function Le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return B(o)}}}function _e(e){let t=Le(e);if(!t)return;let n=t._debugOwner!==void 0;if(n){let i=t._debugOwner;for(let a=0;i&&a<50;a+=1){let s=B(i.type)??B(i.elementType);if(s)return s;i=i._debugOwner;}}let r=t,o=n?80:10;for(let i=0;r&&i<o;i+=1){let a=B(r.type)??B(r.elementType);if(a)return a;r=r.return;}}function Ie(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${te(n)}`;for(let r of oe){let o=e.getAttribute(r);if(o)return `${t}[${r}="${te(o)}"]`}return `${t}:nth-of-type(${Ce(e)})`}function De(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=Ie(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function re(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function W(e,t){if(!e||re(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(re(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??Ne(n))return n;n=n.parentElement;}return null}function Ne(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function ie(e){let t=e.getBoundingClientRect(),n={selector:De(e),tagName:e.tagName.toLowerCase(),rect:Q(t),pageRect:Te(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Ae(e);i&&(n.textSnippet=i);let a=Me(e)??_e(e);a&&(n.componentName=a);let s=Be(e);return s&&(n.testId=s),n}var z=null;async function ae(){return z||(z=import('html-to-image')),z}async function Ue(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function se(e,t){let{width:n,height:r}=await Ue(e);return {dataUrl:e,mime:t,width:n,height:r}}function A(e){if(e?.aborted)throw new Error("Aborted")}function le(){return {async captureElement(e,t){if(!m())throw new Error("captureElement can only run in the browser");A(t.signal);let n=await ae();A(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return A(t.signal),await se(r,t.mime)},async captureFullPage(e){if(!m())throw new Error("captureFullPage can only run in the browser");A(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),a=Math.max(1,Math.round(r*o)),s=await ae();A(e.signal);let f=e.mime==="image/jpeg"?await s.toJpeg(t,{width:i,height:a,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await s.toPng(t,{width:i,height:a,pixelRatio:e.pixelRatio});return A(e.signal),await se(f,e.mime)}}}function Oe(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function p(e,t,n){let r={kind:e,message:Oe(t)};return n&&(r.detail=n),r}var He=12e3,qe=2048,$e=.92;function ce(){return Date.now()}function je(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function ue(e,t,n){let r=new Promise((i,a)=>{let s=setTimeout(()=>a(new Error("Timeout")),t);typeof s.unref=="function"&&s.unref();}),o=[e,r];return n&&o.push(je(n)),await Promise.race(o)}function Qe(e){if(!m())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function We(e){return !!(e?.element||e?.fullPage)}function de(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function fe(e){let{selectionElement:t,capture:n,signal:r}=e;if(!m()||!We(n))return;let o=ce(),i=[],a=n?.timeoutMs??He,s=n?.maxDimension??qe,f=n?.mime??"image/png",g=n?.quality??$e,w=n?.adapter??le(),y={},E=Qe(n);if(n?.element&&t)try{let c=t.getBoundingClientRect(),u=Math.min(1,s/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ue(Promise.resolve(w.captureElement(t,{...de({mime:f,quality:g,pixelRatio:v,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),a,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ue(Promise.resolve(w.captureFullPage(de({mime:f,quality:g,pixelRatio:E,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),a,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"fullPage"}));}let h=ce(),l={startedAt:o,finishedAt:h,durationMs:Math.max(0,h-o)};return i.length>0&&(l.errors=i),{...y,diagnostics:l}}function ze(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Je(){return m()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:ze()}:{}}function Ye(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function me(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Je(),...Ye(r)},i=t?.enrich;if(!i)return o;try{let a=await i(n);return {...o,...a}}catch(a){let s=p("unknown",a);return {...o,blocfeedMetadataError:s.message}}}var J="blocfeed-queue",Ke=50;function Y(){if(!m())return [];try{let e=localStorage.getItem(J);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function K(e){if(m())try{e.length===0?localStorage.removeItem(J):localStorage.setItem(J,JSON.stringify(e));}catch{}}function Xe(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function X(e){let t=Y(),n=Xe(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ke;)t.shift();K(t);}function pe(){let e=Y();return e.length===0?[]:(K([]),e.map(t=>t.payload))}function vt(){K([]);}function Pt(){return Y().length}function G(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function U(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function O(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ge(e,t){if(!m())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,a=null,s=(l,c=false)=>{if(!l){i=null,a=null,t.onHover(null);return}let u=Q(l.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&l===i&&v===a||(i=l,a=v,t.onHover({element:l,rect:u}));},f=G(l=>{if(U(l.target))return;let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);s(u);}),g=G(()=>{i&&s(i,true);}),w=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},y=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},E=l=>{if(U(l.target))return;O(l),l.preventDefault();let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);u&&t.onSelect({element:u,descriptor:ie(u)});},h=l=>{l.key==="Escape"&&(O(l),l.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",h,{capture:true}),window.addEventListener("scroll",g,{capture:true,passive:true}),window.addEventListener("resize",g,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",h,{capture:true}),window.removeEventListener("scroll",g,{capture:true}),window.removeEventListener("resize",g),f.cancel(),g.cancel(),t.onHover(null);}}}var Ge=12e3,Ze=2,Ve=500,et=2e3,ye="https://blocfeed.com/api/feedback",he=0;function we(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function tt(e){return e>=500&&e<=599}function nt(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),a=new Uint8Array(i.length);for(let s=0;s<i.length;s+=1)a[s]=i.charCodeAt(s);return new Blob([a],{type:o})}function rt(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function be(e,t,n){let r=nt(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function ot(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${ye}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Ee(e){let{signal:t,transport:n}=e;if(Date.now()-he<et)return {ok:false,error:p("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??Ge,i=n?.maxAttempts??Ze,a=n?.backoffMs??Ve,s=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:g}=s?rt(e.payload):{lean:e.payload,extracted:{}},w={...g,...e.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,h=setTimeout(()=>E.abort(),o),l=()=>E.abort();t&&t.addEventListener("abort",l,{once:true});try{let c=await fetch(ye,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){he=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let S=[];w.element&&d.element&&S.push(be(d.element,w.element,t)),w.fullPage&&d.fullPage&&S.push(be(d.fullPage,w.fullPage,t));try{await Promise.all(S);}catch{}}else if(u.feedback_id)try{await ot({feedbackId:u.feedback_id,extracted:w,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&tt(c.status)){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:!1,status:c.status,error:p("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||t?.aborted)return {ok:false,error:p("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:false,error:p("api_failed",c)}}finally{clearTimeout(h),t&&t.removeEventListener("abort",l);}}return {ok:false,error:p("api_failed",new Error("Failed"))}}async function Z(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Ee(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:p("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var it=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function at(e){let t=[...it,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function ke(){return {phase:"idle"}}function st(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function $t(e){let t=e,n=ke(),r=new Set,o=new Set,i=null,a=null,s=null,f=null,g=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let S of o)S(d);},h=d=>{n=d,y();},l=()=>{g+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),s!==null&&m()&&(document.documentElement.style.cursor=s,s=null);},u=()=>{l(),c(),a=null,h(ke());},v=()=>{if(!m())return;c(),a=null;let d=at(t.picker);s=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",h({phase:"picking"}),i=ge(d,{onHover:E,onSelect:({element:S,descriptor:N})=>{a=S,c(),h({phase:"review",selection:N});},onCancel:()=>{u();}});},x=()=>{let d=pe();if(d.length!==0)for(let S of d)Z({payload:S,...t.transport?{transport:t.transport}:{}}).catch(()=>{X(S);});};if(m()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){t=d;},async submit(d,S){if(!m()){let b=p("configuration",new Error("BlocFeed submit can only run in the browser"));return h({phase:"error",lastError:b}),{ok:false}}let N=t.blocfeed_id?.trim?.()??"";if(!N){let F={phase:"error",lastError:p("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),h(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=g+1;g=C,f?.abort(),f=new AbortController;let T=f.signal,k=n.selection,q=S?.capture?{...t.capture,...S.capture}:t.capture,V=!!(q?.element||q?.fullPage),ee={phase:V?"capturing":"submitting"};k&&(ee.selection=k),h(ee);try{let b=V?await fe({selectionElement:a,capture:q,signal:T}):void 0;if(T.aborted||g!==C)return {ok:!1};let F={phase:"submitting"};k&&(F.selection=k),b&&(F.capture=b),h(F);let R={};k&&(R.selection=k),b&&(R.capture=b);let xe=await me({config:t.metadata,context:R,...t.user?{user:t.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:N,message:d,metadata:xe};t.user&&(M.user=t.user),k&&(M.selection=k),b&&(M.screenshots=b);let{result:P}=await Z({payload:M,signal:T,...t.transport?{transport:t.transport}:{}});if(T.aborted||g!==C)return P;if(P.ok){let j={phase:"success",lastSubmit:P};return k&&(j.selection=k),b&&(j.capture=b),h(j),P}st(P)&&X(M);let Fe=P.api?.error??p("unknown",new Error("Submission failed")),$={phase:"error",lastSubmit:P,lastError:Fe};return k&&($.selection=k),b&&($.capture=b),h($),P}catch(b){if(T.aborted||g!==C)return {ok:false};let R={phase:"error",lastError:T.aborted?p("aborted",b):p("unknown",b)};return k&&(R.selection=k),h(R),{ok:false}}finally{g===C&&(f=null);}},__unsafeGetSelectedElement(){return a},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}var L=[],_=[],ve=20,Pe=15,I={},D=null,H=false;function lt(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function ct(e,t){let n=t.map(lt).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),L.push(o);L.length>ve;)L.shift();}function Se(e){if(!e.url.includes("blocfeed.com"))for(_.push(e);_.length>Pe;)_.shift();}function Wt(e={}){if(!(H||!m())){if(H=true,ve=e.consoleLimit??20,Pe=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)I[n]=console[n],console[n]=(...r)=>{ct(n,r),I[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){D=window.fetch;let t=D;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,a=(o?.method??"GET").toUpperCase(),s=Date.now();try{let f=await t.call(window,r,o);return f.ok||Se({url:i.slice(0,500),method:a,status:f.status,statusText:f.statusText,timestamp:s,durationMs:Date.now()-s}),f}catch(f){throw Se({url:i.slice(0,500),method:a,status:0,statusText:f instanceof Error?f.message:"Network error",timestamp:s,durationMs:Date.now()-s}),f}};}}}function zt(){if(H){for(let[e,t]of Object.entries(I))console[e]=t;for(let e of Object.keys(I))delete I[e];D&&(window.fetch=D,D=null),H=false;}}function Jt(){return {consoleLogs:[...L],networkErrors:[..._]}}function Yt(){L=[],_=[];}
2
- export{m as a,Q as b,le as c,fe as d,me as e,X as f,pe as g,vt as h,Pt as i,$t as j,Wt as k,zt as l,Jt as m,Yt as n};