@siteping/widget 0.9.6 → 0.9.8

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.
@@ -0,0 +1,1751 @@
1
+ function c(o){let s=document.createRange().createContextualFragment(o).firstElementChild;if(!s||s.nodeName.toLowerCase()!=="svg")throw new Error("[siteping] Invalid SVG string");for(let n of [...s.attributes])n.name.startsWith("on")&&s.removeAttribute(n.name);for(let n of s.querySelectorAll("*"))for(let i of [...n.attributes])i.name.startsWith("on")&&n.removeAttribute(i.name);return s}function r(o,e){let t=document.createElement(o);if(e)for(let[s,n]of Object.entries(e))s==="class"?t.className=n:s==="style"?t.style.cssText=n:t.setAttribute(s,n);return t}function a(o,e){o.textContent=e;}function L(o){let e=Array.from(o.childNodes).map(t=>t.cloneNode(true));return o.disabled=true,o.replaceChildren(r("div",{class:"sp-spinner sp-spinner--sm"})),()=>{o.replaceChildren(...e),o.disabled=false;}}function Re(o,e="en"){let t=Date.now()-new Date(o).getTime(),s=Math.floor(t/1e3);if(s<60)return new Intl.RelativeTimeFormat(e,{numeric:"auto"}).format(0,"second");let n=new Intl.RelativeTimeFormat(e,{numeric:"always",style:"narrow"}),i=Math.floor(s/60);if(i<60)return n.format(-i,"minute");let l=Math.floor(i/60);if(l<24)return n.format(-l,"hour");let d=Math.floor(l/24);return d<7?n.format(-d,"day"):new Date(o).toLocaleDateString(e)}var Oe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><circle cx="12" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="8" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="16" cy="10" r="1" fill="currentColor" stroke="none"/></svg>',Fe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',Ne='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/><path d="M9 3v18"/></svg>',je='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>',_e='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>',De='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',$e='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>',Pe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>',ze='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',Ie='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>',Ve='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="6" width="8" height="14" rx="4"/><path d="M19 9h2"/><path d="M3 9h2"/><path d="M19 13h2"/><path d="M3 13h2"/><path d="M19 17h2"/><path d="M3 17h2"/><path d="M10 2h4"/></svg>',Ge='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>',Ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>',Ye='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="3" fill="currentColor" stroke="none"/></svg>',Ke='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>',qe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>',Qe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>';var F="#0066ff",J=/^#[0-9a-fA-F]{6}$/,O=/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/,Z=/^#[0-9a-fA-F]{8}$/;function ee(o){if(J.test(o))return o;let e=O.test(o)?o.match(O):null;return e?`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`:Z.test(o)?o.slice(0,7):(console.warn(`[siteping] Invalid accentColor "${o}" \u2014 only hex colors (#RGB, #RRGGBB, #RRGGBBAA) are supported. Using default.`),F)}function te(o,e){let t=Math.max(0,Math.round(parseInt(o.slice(1,3),16)*(1-e))),s=Math.max(0,Math.round(parseInt(o.slice(3,5),16)*(1-e))),n=Math.max(0,Math.round(parseInt(o.slice(5,7),16)*(1-e)));return `#${t.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}function se(){return typeof window>"u"?false:window.matchMedia("(prefers-color-scheme: dark)").matches}function oe(o){return o==="dark"||o==="auto"&&se()?"dark":"light"}function Xe(o=F,e){let t=ee(o),s=te(t,.15);return oe(e)==="dark"?{accent:t,accentLight:t+"22",accentDark:s,accentGlow:t+"44",accentGradient:`linear-gradient(135deg, ${t}, ${s})`,bg:"#0f172a",bgHover:"#1e293b",text:"#f1f5f9",textSecondary:"#94a3b8",textTertiary:"#64748b",border:"#334155",shadow:"rgba(0, 0, 0, 0.3)",glassBg:"rgba(15, 23, 42, 0.78)",glassBgHeavy:"rgba(15, 23, 42, 0.88)",glassBorder:"rgba(51, 65, 85, 0.5)",glassBorderSubtle:"rgba(51, 65, 85, 0.3)",typeQuestion:"#60a5fa",typeChange:"#fbbf24",typeBug:"#f87171",typeOther:"#94a3b8",typeQuestionBg:"rgba(59, 130, 246, 0.15)",typeChangeBg:"rgba(245, 158, 11, 0.15)",typeBugBg:"rgba(239, 68, 68, 0.15)",typeOtherBg:"rgba(100, 116, 139, 0.15)",statusOpen:"#4ade80",statusOpenBg:"rgba(74, 222, 128, 0.15)",statusResolved:"#94a3b8",statusResolvedBg:"rgba(148, 163, 184, 0.15)"}:{accent:t,accentLight:t+"14",accentDark:s,accentGlow:t+"33",accentGradient:`linear-gradient(135deg, ${t}, ${s})`,bg:"#ffffff",bgHover:"#f8f9fb",text:"#0f172a",textSecondary:"#475569",textTertiary:"#64748b",border:"#e2e8f0",shadow:"rgba(0, 0, 0, 0.06)",glassBg:"rgba(255, 255, 255, 0.72)",glassBgHeavy:"rgba(255, 255, 255, 0.85)",glassBorder:"rgba(255, 255, 255, 0.35)",glassBorderSubtle:"rgba(255, 255, 255, 0.18)",typeQuestion:"#3b82f6",typeChange:"#b45309",typeBug:"#ef4444",typeOther:"#64748b",typeQuestionBg:"#eff6ff",typeChangeBg:"#fffbeb",typeBugBg:"#fef2f2",typeOtherBg:"#f8fafc",statusOpen:"#16a34a",statusOpenBg:"#f0fdf4",statusResolved:"#64748b",statusResolvedBg:"#f1f5f9"}}function A(o,e){switch(o){case "question":return e.typeQuestion;case "change":return e.typeChange;case "bug":return e.typeBug;default:return e.typeOther}}function N(o,e){switch(o){case "question":return e.typeQuestionBg;case "change":return e.typeChangeBg;case "bug":return e.typeBugBg;default:return e.typeOtherBg}}function Je(o){return `
2
+ --sp-accent: ${o.accent};
3
+ --sp-accent-light: ${o.accentLight};
4
+ --sp-accent-dark: ${o.accentDark};
5
+ --sp-accent-glow: ${o.accentGlow};
6
+ --sp-accent-gradient: ${o.accentGradient};
7
+ --sp-bg: ${o.bg};
8
+ --sp-bg-hover: ${o.bgHover};
9
+ --sp-text: ${o.text};
10
+ --sp-text-secondary: ${o.textSecondary};
11
+ --sp-text-tertiary: ${o.textTertiary};
12
+ --sp-border: ${o.border};
13
+ --sp-shadow: ${o.shadow};
14
+ --sp-glass-bg: ${o.glassBg};
15
+ --sp-glass-bg-heavy: ${o.glassBgHeavy};
16
+ --sp-glass-border: ${o.glassBorder};
17
+ --sp-glass-border-subtle: ${o.glassBorderSubtle};
18
+ --sp-type-question: ${o.typeQuestion};
19
+ --sp-type-change: ${o.typeChange};
20
+ --sp-type-bug: ${o.typeBug};
21
+ --sp-type-other: ${o.typeOther};
22
+ --sp-type-question-bg: ${o.typeQuestionBg};
23
+ --sp-type-change-bg: ${o.typeChangeBg};
24
+ --sp-type-bug-bg: ${o.typeBugBg};
25
+ --sp-type-other-bg: ${o.typeOtherBg};
26
+ --sp-radius: 12px;
27
+ --sp-radius-lg: 16px;
28
+ --sp-radius-xl: 20px;
29
+ --sp-radius-full: 9999px;
30
+ --sp-blur: 20px;
31
+ --sp-blur-heavy: 32px;
32
+ --sp-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
33
+ --sp-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.04);
34
+ --sp-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);
35
+ --sp-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.04);
36
+ --sp-shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.12), 0 8px 16px rgba(0, 0, 0, 0.06);
37
+ --sp-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
38
+ `}var j={"panel.title":"Feedbacks","panel.ariaLabel":"Siteping feedback panel","panel.feedbackList":"Feedback list","panel.loading":"Loading feedbacks","panel.close":"Close panel","panel.deleteAll":"Delete all","panel.deleteAllConfirmTitle":"Delete all","panel.deleteAllConfirmMessage":"Delete all feedbacks for this project? This action cannot be undone.","panel.search":"Search...","panel.searchAria":"Search feedbacks","panel.filterAll":"All","panel.loadError":"Failed to load","panel.retry":"Retry","panel.empty":"No feedback yet","panel.showMore":"Show more","panel.showLess":"Show less","panel.resolve":"Resolve","panel.reopen":"Reopen","panel.delete":"Delete","panel.cancel":"Cancel","panel.confirmDelete":"Delete","panel.loadMore":"Load more ({remaining} remaining)","panel.statusAll":"All","panel.statusOpen":"Open","panel.statusResolved":"Resolved","type.label":"Type","type.question":"Question","type.change":"Change","type.bug":"Bug","type.other":"Other","status.label":"Status","scope.label":"Scope","scope.thisPage":"This page","scope.thisType":"This type","scope.all":"All pages","fab.aria":"Siteping \u2014 Feedback menu","fab.messages":"Messages","fab.annotate":"Annotate","fab.annotations":"Annotations","annotator.instruction":"Draw a rectangle on the area to comment","annotator.cancel":"Cancel","popup.ariaLabel":"Feedback form","popup.placeholder":"Describe your feedback...","popup.textareaAria":"Feedback message","popup.submitHintMac":"\u2318+Enter to send","popup.submitHintOther":"Ctrl+Enter to send","popup.cancel":"Cancel","popup.submit":"Send","identity.title":"Identify yourself","identity.nameLabel":"Name","identity.namePlaceholder":"Your name","identity.emailLabel":"Email","identity.emailPlaceholder":"your@email.com","identity.cancel":"Cancel","identity.submit":"Continue","marker.approximate":"Approximate position (confidence: {confidence}%)","marker.aria":"Feedback #{number}: {type} \u2014 {message}","marker.count":"{count} feedback markers displayed","fab.badge":"{count} unresolved feedbacks","feedback.sent.confirmation":"Feedback sent successfully","feedback.error.message":"Failed to send feedback","feedback.deleted.confirmation":"Feedback deleted","badge.count":"{count} unresolved feedbacks","bulk.selectAll":"Select all","bulk.selected":"{count} selected","bulk.resolve":"Resolve","bulk.delete":"Delete","bulk.deselect":"Deselect","sort.newest":"Newest first","sort.oldest":"Oldest first","sort.byType":"By type","sort.openFirst":"Open first","sort.label":"Sort","group.byPage":"By page","group.feedbacks":"{count} feedbacks","stats.open":"Open","stats.resolved":"Resolved","stats.bugs":"Bugs","stats.progress":"{percent}% resolved","detail.back":"Back","detail.title":"Feedback #{number}","detail.status":"Status","detail.message":"Message","detail.screenshot":"Screenshot","detail.screenshotAlt":"Screenshot of the annotated area","detail.metadata":"Details","detail.annotation":"Annotation","detail.page":"Page","detail.author":"Author","detail.date":"Created","detail.viewport":"Viewport","detail.browser":"Browser","detail.resolvedAt":"Resolved at","detail.goToAnnotation":"Go to annotation","detail.element":"Element","detail.selector":"Selector","detail.position":"Position","detail.resolve":"Resolve","detail.reopen":"Reopen","detail.delete":"Delete","detail.diagnostics":"Diagnostics","detail.diagnostics.console":"Console","detail.diagnostics.network":"Failed network","detail.diagnostics.expand":"Show diagnostics","detail.diagnostics.collapse":"Hide diagnostics","detail.diagnostics.noEntries":"No entries","shortcuts.title":"Keyboard shortcuts","shortcuts.navigate":"Navigate feedbacks","shortcuts.resolve":"Resolve / Reopen","shortcuts.delete":"Delete","shortcuts.search":"Focus search","shortcuts.select":"Toggle selection","shortcuts.help":"Show shortcuts","shortcuts.close":"Close","shortcuts.hint":"Keyboard shortcuts","export.label":"Export","export.csv":"Export CSV","export.json":"Export JSON"};var w={en:j},_=new Set(["de","es","fr","it","pt","ru"]);async function st(o){let e=(o.split("-")[0]??o).toLowerCase();if(w[e])return w[e];if(!_.has(e))return null;let t;switch(e){case "de":t=await import('./de-32TXJQIE.js');break;case "es":t=await import('./es-GFAPKPTK.js');break;case "fr":t=await import('./fr-W2JZ3EUC.js');break;case "it":t=await import('./it-GASU527B.js');break;case "pt":t=await import('./pt-AYXM6FG4.js');break;case "ru":t=await import('./ru-5DW2JCKR.js');break;default:return null}let s=t[e];return s?(w[e]=s,s):null}function ot(o){let e=(o.split("-")[0]??o).toLowerCase();return e!=="en"&&!w[e]&&!_.has(e)&&console.warn(`[siteping] Unknown locale "${o}", falling back to "en"`),t=>(w[e]??w.en??{})[t]??w.en?.[t]??t}function nt(o,e){switch(o){case "question":return e("type.question");case "change":return e("type.change");case "bug":return e("type.bug");case "other":return e("type.other");default:return o}}var ne='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',re='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/></svg>',ie='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3H6a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2 2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h2"/><path d="M16 3h2a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2 2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2"/></svg>',at=`
39
+ /* ============================
40
+ Export Button & Menu
41
+ ============================ */
42
+
43
+ .sp-export-btn {
44
+ padding: 5px 12px;
45
+ border-radius: var(--sp-radius-full);
46
+ border: 1px solid var(--sp-border);
47
+ background: transparent;
48
+ color: var(--sp-text-tertiary);
49
+ font-family: var(--sp-font);
50
+ font-size: 11px;
51
+ font-weight: 500;
52
+ cursor: pointer;
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 4px;
56
+ transition: all 0.2s ease;
57
+ position: relative;
58
+ }
59
+
60
+ .sp-export-btn svg {
61
+ width: 13px;
62
+ height: 13px;
63
+ }
64
+
65
+ .sp-export-btn:hover {
66
+ border-color: var(--sp-accent);
67
+ color: var(--sp-accent);
68
+ background: var(--sp-accent-light);
69
+ }
70
+
71
+ .sp-export-btn:disabled {
72
+ opacity: 0.5;
73
+ cursor: not-allowed;
74
+ pointer-events: none;
75
+ }
76
+
77
+ .sp-export-menu {
78
+ position: absolute;
79
+ top: calc(100% + 6px);
80
+ right: 0;
81
+ min-width: 180px;
82
+ padding: 4px;
83
+ border-radius: var(--sp-radius);
84
+ background: var(--sp-glass-bg-heavy);
85
+ backdrop-filter: blur(var(--sp-blur));
86
+ -webkit-backdrop-filter: blur(var(--sp-blur));
87
+ border: 1px solid var(--sp-glass-border);
88
+ box-shadow: var(--sp-shadow-lg);
89
+ z-index: 10;
90
+ opacity: 0;
91
+ transform: translateY(-4px) scale(0.97);
92
+ transition: opacity 0.15s ease, transform 0.15s ease;
93
+ pointer-events: none;
94
+ }
95
+
96
+ .sp-export-menu--open {
97
+ opacity: 1;
98
+ transform: translateY(0) scale(1);
99
+ pointer-events: auto;
100
+ }
101
+
102
+ .sp-export-option {
103
+ display: flex;
104
+ align-items: center;
105
+ gap: 10px;
106
+ width: 100%;
107
+ padding: 8px 16px;
108
+ border: none;
109
+ border-radius: 8px;
110
+ background: transparent;
111
+ color: var(--sp-text-secondary);
112
+ font-family: var(--sp-font);
113
+ font-size: 13px;
114
+ font-weight: 500;
115
+ cursor: pointer;
116
+ transition: all 0.15s ease;
117
+ text-align: left;
118
+ }
119
+
120
+ .sp-export-option:hover,
121
+ .sp-export-option:focus-visible {
122
+ background: var(--sp-accent-light);
123
+ color: var(--sp-accent);
124
+ }
125
+
126
+ .sp-export-option-icon {
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ flex-shrink: 0;
131
+ }
132
+
133
+ .sp-export-option-icon svg {
134
+ width: 16px;
135
+ height: 16px;
136
+ }
137
+
138
+ .sp-export-option-label {
139
+ flex: 1;
140
+ }
141
+
142
+ @media (forced-colors: active) {
143
+ .sp-export-btn,
144
+ .sp-export-option,
145
+ .sp-export-menu {
146
+ border: 2px solid ButtonText !important;
147
+ background: Canvas !important;
148
+ color: ButtonText !important;
149
+ }
150
+
151
+ .sp-export-btn:focus-visible,
152
+ .sp-export-option:focus-visible {
153
+ outline: 3px solid Highlight !important;
154
+ }
155
+ }
156
+ `,D=["id","type","status","message","url","authorName","authorEmail","createdAt","resolvedAt","viewport"];function ae(o){return o.includes('"')||o.includes(",")||o.includes(`
157
+ `)||o.includes("\r")?`"${o.replace(/"/g,'""')}"`:o}function le(o){let e=D.join(","),t=o.map(s=>D.map(n=>{let i=s[n];return ae(i==null?"":String(i))}).join(","));return [e,...t].join(`
158
+ `)}function pe(o){return JSON.stringify(o,null,2)}function $(o,e,t){let s=new Blob([o],{type:t}),n=URL.createObjectURL(s),i=document.createElement("a");i.href=n,i.download=e,i.style.display="none",document.body.appendChild(i),i.click(),requestAnimationFrame(()=>{URL.revokeObjectURL(n),i.remove();});}var P=class{constructor(e,t,s){this.getFeedbacks=t;this.element=r("div",{style:"position: relative; display: inline-flex;"});let n=document.createElement("button");n.className="sp-export-btn",n.setAttribute("aria-haspopup","true"),n.setAttribute("aria-expanded","false"),n.appendChild(c(ne));let i=document.createElement("span");a(i,s("export.label")),n.appendChild(i),n.addEventListener("click",p=>{p.stopPropagation(),this.toggle();}),this.menu=r("div",{class:"sp-export-menu"}),this.menu.setAttribute("role","menu");let l=this.createOption(re,s("export.csv"),()=>{this.exportAs("csv");}),d=this.createOption(ie,s("export.json"),()=>{this.exportAs("json");});this.menu.appendChild(l),this.menu.appendChild(d),this.element.appendChild(n),this.element.appendChild(this.menu),this.onDocumentClick=p=>{this.isOpen&&!this.element.contains(p.target)&&this.close();},document.addEventListener("click",this.onDocumentClick,true);}getFeedbacks;element;menu;isOpen=false;onDocumentClick;createOption(e,t,s){let n=document.createElement("button");n.className="sp-export-option",n.setAttribute("role","menuitem");let i=r("span",{class:"sp-export-option-icon"});i.appendChild(c(e));let l=r("span",{class:"sp-export-option-label"});return a(l,t),n.appendChild(i),n.appendChild(l),n.addEventListener("click",d=>{d.stopPropagation(),s(),this.close();}),n}toggle(){this.isOpen?this.close():this.open();}open(){this.isOpen=true,this.menu.classList.add("sp-export-menu--open"),this.element.querySelector(".sp-export-btn")?.setAttribute("aria-expanded","true");}close(){this.isOpen=false,this.menu.classList.remove("sp-export-menu--open"),this.element.querySelector(".sp-export-btn")?.setAttribute("aria-expanded","false");}exportAs(e){let t=this.getFeedbacks();if(t.length===0)return;let s=t[0]?.projectName??"feedbacks",n=new Date().toISOString().slice(0,10),i=s.replace(/[^a-zA-Z0-9_-]/g,"_");if(e==="csv"){let l=le(t);$(l,`feedbacks-${i}-${n}.csv`,"text/csv;charset=utf-8");}else {let l=pe(t);$(l,`feedbacks-${i}-${n}.json`,"application/json;charset=utf-8");}}destroy(){document.removeEventListener("click",this.onDocumentClick,true),this.element.remove();}};var T='<svg viewBox="0 0 18 18" fill="none" aria-hidden="true"><rect x="1" y="1" width="16" height="16" rx="4" stroke="currentColor" stroke-width="2"/></svg>',z='<svg viewBox="0 0 18 18" fill="none" aria-hidden="true"><rect x="1" y="1" width="16" height="16" rx="4" fill="url(#sp-cb-grad)" stroke="none"/><polyline points="5 9 8 12 13 6" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><defs><linearGradient id="sp-cb-grad" x1="0" y1="0" x2="18" y2="18" gradientUnits="userSpaceOnUse"><stop offset="0%" stop-color="var(--sp-accent)"/><stop offset="100%" stop-color="var(--sp-accent-dark)"/></linearGradient></defs></svg>',dt=`
159
+ /* ============================
160
+ Bulk Checkbox
161
+ ============================ */
162
+
163
+ .sp-bulk-checkbox {
164
+ position: relative;
165
+ width: 16px;
166
+ height: 16px;
167
+ flex-shrink: 0;
168
+ cursor: pointer;
169
+ border-radius: 4px;
170
+ color: var(--sp-border);
171
+ opacity: 0;
172
+ transition: opacity 0.15s ease, color 0.15s ease, transform 0.15s ease;
173
+ display: inline-flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ }
177
+
178
+ .sp-bulk-checkbox svg {
179
+ width: 16px;
180
+ height: 16px;
181
+ display: block;
182
+ }
183
+
184
+ .sp-bulk-checkbox:hover {
185
+ color: var(--sp-accent);
186
+ transform: scale(1.1);
187
+ }
188
+
189
+ .sp-bulk-checkbox--checked {
190
+ color: var(--sp-accent);
191
+ opacity: 1 !important;
192
+ filter: drop-shadow(0 0 4px var(--sp-accent-glow));
193
+ }
194
+
195
+ /* Show checkboxes when hovering a card */
196
+ .sp-card:hover .sp-bulk-checkbox {
197
+ opacity: 1;
198
+ }
199
+
200
+ /* When any card has selection, show ALL checkboxes */
201
+ .sp-list--has-selection .sp-bulk-checkbox {
202
+ opacity: 1;
203
+ }
204
+
205
+ /* ============================
206
+ Card Selected State
207
+ ============================ */
208
+
209
+ .sp-card--selected {
210
+ border-left: 3px solid var(--sp-accent) !important;
211
+ background: var(--sp-accent-light) !important;
212
+ }
213
+
214
+ .sp-card--selected:hover {
215
+ background: var(--sp-accent-light) !important;
216
+ }
217
+
218
+ /* ============================
219
+ Select All Bar
220
+ ============================ */
221
+
222
+ .sp-bulk-select-all {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: 8px;
226
+ padding: 8px 12px;
227
+ margin-bottom: 4px;
228
+ border-radius: var(--sp-radius);
229
+ background: transparent;
230
+ cursor: pointer;
231
+ opacity: 0;
232
+ transition: opacity 0.2s ease, background 0.2s ease;
233
+ user-select: none;
234
+ font-family: var(--sp-font);
235
+ font-size: 12px;
236
+ font-weight: 500;
237
+ color: var(--sp-text-secondary);
238
+ }
239
+
240
+ .sp-bulk-select-all:hover {
241
+ background: var(--sp-bg-hover);
242
+ }
243
+
244
+ /* Show select-all on list hover or when selections exist */
245
+ .sp-list:hover .sp-bulk-select-all,
246
+ .sp-list--has-selection .sp-bulk-select-all {
247
+ opacity: 1;
248
+ }
249
+
250
+ .sp-bulk-select-all .sp-bulk-checkbox {
251
+ opacity: 1;
252
+ }
253
+
254
+ /* ============================
255
+ Floating Action Bar
256
+ ============================ */
257
+
258
+ @keyframes sp-bulk-bar-in {
259
+ from {
260
+ transform: translateY(100%) scale(0.95);
261
+ opacity: 0;
262
+ }
263
+ to {
264
+ transform: translateY(0) scale(1);
265
+ opacity: 1;
266
+ }
267
+ }
268
+
269
+ @keyframes sp-bulk-bar-out {
270
+ from {
271
+ transform: translateY(0) scale(1);
272
+ opacity: 1;
273
+ }
274
+ to {
275
+ transform: translateY(100%) scale(0.95);
276
+ opacity: 0;
277
+ }
278
+ }
279
+
280
+ .sp-bulk-bar {
281
+ position: absolute;
282
+ bottom: 16px;
283
+ left: 16px;
284
+ right: 16px;
285
+ display: flex;
286
+ align-items: center;
287
+ justify-content: space-between;
288
+ gap: 12px;
289
+ padding: 12px 16px;
290
+ border-radius: 16px;
291
+ background: var(--sp-glass-bg-heavy);
292
+ backdrop-filter: blur(var(--sp-blur-heavy));
293
+ -webkit-backdrop-filter: blur(var(--sp-blur-heavy));
294
+ border: 1px solid var(--sp-glass-border);
295
+ box-shadow: var(--sp-shadow-xl);
296
+ z-index: 10;
297
+ pointer-events: none;
298
+ opacity: 0;
299
+ transform: translateY(100%) scale(0.95);
300
+ transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
301
+ opacity 0.25s ease;
302
+ font-family: var(--sp-font);
303
+ }
304
+
305
+ .sp-bulk-bar--visible {
306
+ pointer-events: auto;
307
+ opacity: 1;
308
+ transform: translateY(0) scale(1);
309
+ }
310
+
311
+ .sp-bulk-bar-count {
312
+ font-size: 13px;
313
+ font-weight: 600;
314
+ color: var(--sp-text);
315
+ white-space: nowrap;
316
+ letter-spacing: -0.01em;
317
+ }
318
+
319
+ .sp-bulk-bar-actions {
320
+ display: flex;
321
+ align-items: center;
322
+ gap: 6px;
323
+ }
324
+
325
+ .sp-bulk-btn-resolve,
326
+ .sp-bulk-btn-delete {
327
+ padding: 7px 14px;
328
+ border-radius: var(--sp-radius-full);
329
+ border: 1.5px solid transparent;
330
+ background: transparent;
331
+ font-family: var(--sp-font);
332
+ font-size: 12px;
333
+ font-weight: 600;
334
+ cursor: pointer;
335
+ display: flex;
336
+ align-items: center;
337
+ gap: 5px;
338
+ transition: all 0.2s ease;
339
+ white-space: nowrap;
340
+ }
341
+
342
+ .sp-bulk-btn-resolve {
343
+ color: #22c55e;
344
+ border-color: #22c55e;
345
+ }
346
+
347
+ .sp-bulk-btn-resolve:hover {
348
+ background: rgba(34, 197, 94, 0.1);
349
+ box-shadow: 0 0 12px rgba(34, 197, 94, 0.15);
350
+ }
351
+
352
+ .sp-bulk-btn-resolve:active {
353
+ transform: scale(0.96);
354
+ transition-duration: 0.1s;
355
+ }
356
+
357
+ .sp-bulk-btn-delete {
358
+ color: #ef4444;
359
+ border-color: #ef4444;
360
+ }
361
+
362
+ .sp-bulk-btn-delete:hover {
363
+ background: rgba(239, 68, 68, 0.1);
364
+ box-shadow: 0 0 12px rgba(239, 68, 68, 0.15);
365
+ }
366
+
367
+ .sp-bulk-btn-delete:active {
368
+ transform: scale(0.96);
369
+ transition-duration: 0.1s;
370
+ }
371
+
372
+ .sp-bulk-btn-resolve:disabled,
373
+ .sp-bulk-btn-delete:disabled {
374
+ opacity: 0.5;
375
+ cursor: not-allowed;
376
+ pointer-events: none;
377
+ }
378
+
379
+ .sp-bulk-btn-deselect {
380
+ width: 28px;
381
+ height: 28px;
382
+ border-radius: var(--sp-radius-full);
383
+ border: 1px solid var(--sp-border);
384
+ background: transparent;
385
+ color: var(--sp-text-tertiary);
386
+ cursor: pointer;
387
+ display: flex;
388
+ align-items: center;
389
+ justify-content: center;
390
+ transition: all 0.2s ease;
391
+ flex-shrink: 0;
392
+ padding: 0;
393
+ }
394
+
395
+ .sp-bulk-btn-deselect:hover {
396
+ background: var(--sp-bg-hover);
397
+ color: var(--sp-text);
398
+ border-color: var(--sp-text-tertiary);
399
+ }
400
+
401
+ .sp-bulk-btn-deselect:active {
402
+ transform: scale(0.92);
403
+ transition-duration: 0.1s;
404
+ }
405
+
406
+ .sp-bulk-btn-deselect svg {
407
+ width: 12px;
408
+ height: 12px;
409
+ }
410
+
411
+ /* Spinner inside bulk bar buttons */
412
+ .sp-bulk-btn-resolve .sp-spinner,
413
+ .sp-bulk-btn-delete .sp-spinner {
414
+ width: 14px;
415
+ height: 14px;
416
+ }
417
+
418
+ /* ============================
419
+ Forced Colors / High Contrast
420
+ ============================ */
421
+
422
+ @media (forced-colors: active) {
423
+ .sp-bulk-checkbox,
424
+ .sp-bulk-btn-resolve,
425
+ .sp-bulk-btn-delete,
426
+ .sp-bulk-btn-deselect,
427
+ .sp-bulk-bar {
428
+ border: 2px solid ButtonText !important;
429
+ background: Canvas !important;
430
+ color: ButtonText !important;
431
+ }
432
+
433
+ .sp-bulk-checkbox--checked {
434
+ background: Highlight !important;
435
+ color: HighlightText !important;
436
+ }
437
+
438
+ .sp-card--selected {
439
+ border-left: 4px solid Highlight !important;
440
+ }
441
+ }
442
+
443
+ /* ============================
444
+ Reduced Motion
445
+ ============================ */
446
+
447
+ @media (prefers-reduced-motion: reduce) {
448
+ .sp-bulk-bar {
449
+ transition-duration: 0.01ms !important;
450
+ }
451
+
452
+ .sp-bulk-checkbox {
453
+ transition-duration: 0.01ms !important;
454
+ }
455
+ }
456
+ `,I=class{constructor(e,t,s){this.callbacks=t;this.t=s,this.barElement=r("div",{class:"sp-bulk-bar"}),this.barElement.setAttribute("role","toolbar"),this.barElement.setAttribute("aria-label","Bulk actions"),this.countLabel=r("span",{class:"sp-bulk-bar-count"}),a(this.countLabel,this.t("bulk.selected").replace("{count}","0"));let n=r("div",{class:"sp-bulk-bar-actions"});this.resolveBtn=document.createElement("button"),this.resolveBtn.className="sp-bulk-btn-resolve",this.resolveBtn.type="button",this.resolveBtn.addEventListener("click",()=>this.handleResolve()),this.deleteBtn=document.createElement("button"),this.deleteBtn.className="sp-bulk-btn-delete",this.deleteBtn.type="button",this.deleteBtn.addEventListener("click",()=>this.handleDelete());let i=document.createElement("button");i.className="sp-bulk-btn-deselect",i.type="button",i.setAttribute("aria-label",this.t("bulk.deselect")),i.appendChild(c('<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>')),i.addEventListener("click",()=>this.deselectAll()),n.appendChild(this.resolveBtn),n.appendChild(this.deleteBtn),n.appendChild(i),this.barElement.appendChild(this.countLabel),this.barElement.appendChild(n),this.updateButtonLabels();}callbacks;barElement;selected=new Set;checkboxMap=new Map;countLabel;resolveBtn;deleteBtn;selectAllCheckbox=null;listContainer=null;isProcessing=false;t;createCheckbox(e){let t=r("div",{class:"sp-bulk-checkbox"});return t.setAttribute("role","checkbox"),t.setAttribute("aria-checked","false"),t.setAttribute("tabindex","0"),t.setAttribute("aria-label",`Select feedback ${e}`),t.appendChild(c(T)),t.addEventListener("click",s=>{s.stopPropagation(),this.toggle(e);}),t.addEventListener("keydown",s=>{(s.key===" "||s.key==="Enter")&&(s.preventDefault(),s.stopPropagation(),this.toggle(e));}),this.checkboxMap.set(e,t),t}createSelectAllBar(e,t){let s=r("div",{class:"sp-bulk-select-all"}),n=r("div",{class:"sp-bulk-checkbox"});n.appendChild(c(T)),this.selectAllCheckbox=n;let i=r("span");return a(i,t),s.appendChild(n),s.appendChild(i),s.addEventListener("click",()=>{this.selected.size===e.length&&e.length>0?this.deselectAll():this.selectAll(e);}),s}setListContainer(e){this.listContainer=e;}toggle(e){this.isProcessing||(this.selected.has(e)?this.selected.delete(e):this.selected.add(e),this.updateCheckbox(e),this.updateBar(),this.updateSelectAllCheckbox(),this.updateListSelectionClass(),this.updateCardSelectedState(e));}selectAll(e){if(!this.isProcessing){for(let t of e)this.selected.add(t),this.updateCheckbox(t),this.updateCardSelectedState(t);this.updateBar(),this.updateSelectAllCheckbox(),this.updateListSelectionClass();}}deselectAll(){let e=[...this.selected];this.selected.clear();for(let t of e)this.updateCheckbox(t),this.updateCardSelectedState(t);this.updateBar(),this.updateSelectAllCheckbox(),this.updateListSelectionClass();}get selectedIds(){return [...this.selected]}get count(){return this.selected.size}get hasSelection(){return this.selected.size>0}reset(){this.selected.clear(),this.checkboxMap.clear(),this.selectAllCheckbox=null,this.isProcessing=false,this.updateBar(),this.updateListSelectionClass();}destroy(){this.selected.clear(),this.checkboxMap.clear(),this.selectAllCheckbox=null,this.listContainer=null,this.barElement.remove();}updateBar(){let e=this.selected.size,t=e>0;this.barElement.classList.toggle("sp-bulk-bar--visible",t),a(this.countLabel,this.t("bulk.selected").replace("{count}",String(e))),this.updateButtonLabels();}updateButtonLabels(){let e=this.selected.size,t=this.t("bulk.resolve"),s=this.t("bulk.delete");this.resolveBtn.replaceChildren();let n=document.createElement("span");a(n,e>0?`${t} ${e}`:t),this.resolveBtn.appendChild(n),this.deleteBtn.replaceChildren();let i=document.createElement("span");a(i,e>0?`${s} ${e}`:s),this.deleteBtn.appendChild(i);}updateCheckbox(e){let t=this.checkboxMap.get(e);if(!t)return;let s=this.selected.has(e);t.classList.toggle("sp-bulk-checkbox--checked",s),t.setAttribute("aria-checked",String(s)),t.replaceChildren(),t.appendChild(c(s?z:T));}updateSelectAllCheckbox(){if(!this.selectAllCheckbox)return;let e=this.selected.size>0&&this.selected.size===this.checkboxMap.size;this.selectAllCheckbox.classList.toggle("sp-bulk-checkbox--checked",e),this.selectAllCheckbox.setAttribute("aria-checked",String(e)),this.selectAllCheckbox.replaceChildren(),this.selectAllCheckbox.appendChild(c(e?z:T));}updateListSelectionClass(){this.listContainer&&this.listContainer.classList.toggle("sp-list--has-selection",this.selected.size>0);}updateCardSelectedState(e){if(!this.listContainer)return;let t=CSS.escape(e),s=this.listContainer.querySelector(`[data-feedback-id="${t}"]`);s&&s.classList.toggle("sp-card--selected",this.selected.has(e));}async handleResolve(){if(this.isProcessing||this.selected.size===0)return;this.isProcessing=true;let e=[...this.selected],t=L(this.resolveBtn);this.deleteBtn.disabled=true;try{await this.callbacks.onResolve(e),this.reset();}catch{t(),this.deleteBtn.disabled=false;}finally{this.isProcessing=false;}}async handleDelete(){if(this.isProcessing||this.selected.size===0)return;this.isProcessing=true;let e=[...this.selected],t=L(this.deleteBtn);this.resolveBtn.disabled=true;try{await this.callbacks.onDelete(e),this.reset();}catch{t(),this.resolveBtn.disabled=false;}finally{this.isProcessing=false;}}};var de='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>',R='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>',ce='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>',he='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>',ue='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>',ge='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>',H='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>',V='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>',G='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>',be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>',ve='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="22" y1="12" x2="18" y2="12"/><line x1="6" y1="12" x2="2" y2="12"/><line x1="12" y1="6" x2="12" y2="2"/><line x1="12" y1="22" x2="12" y2="18"/></svg>',xe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>',me='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>',gt=`
457
+ /* ============================
458
+ Detail View \u2014 Panel-in-Panel
459
+ ============================ */
460
+
461
+ .sp-detail {
462
+ position: absolute;
463
+ inset: 0;
464
+ display: flex;
465
+ flex-direction: column;
466
+ background: var(--sp-glass-bg);
467
+ backdrop-filter: blur(var(--sp-blur-heavy));
468
+ -webkit-backdrop-filter: blur(var(--sp-blur-heavy));
469
+ z-index: 20;
470
+ transform: translateX(100%);
471
+ transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
472
+ will-change: transform;
473
+ overflow: hidden;
474
+ }
475
+
476
+ .sp-detail--visible {
477
+ transform: translateX(0);
478
+ }
479
+
480
+ /* ---- Header ---- */
481
+
482
+ .sp-detail-header {
483
+ display: flex;
484
+ align-items: center;
485
+ gap: 12px;
486
+ padding: 16px 20px;
487
+ border-bottom: 1px solid var(--sp-border);
488
+ background: var(--sp-glass-bg-heavy);
489
+ backdrop-filter: blur(var(--sp-blur));
490
+ -webkit-backdrop-filter: blur(var(--sp-blur));
491
+ flex-shrink: 0;
492
+ min-height: 64px;
493
+ }
494
+
495
+ .sp-detail-back {
496
+ width: 40px;
497
+ height: 40px;
498
+ border-radius: var(--sp-radius);
499
+ border: none;
500
+ background: transparent;
501
+ cursor: pointer;
502
+ display: flex;
503
+ align-items: center;
504
+ justify-content: center;
505
+ color: var(--sp-text-tertiary);
506
+ transition: all 0.2s ease;
507
+ flex-shrink: 0;
508
+ padding: 0;
509
+ }
510
+
511
+ .sp-detail-back:hover {
512
+ background: var(--sp-bg-hover);
513
+ color: var(--sp-text);
514
+ }
515
+
516
+ .sp-detail-back:active {
517
+ transform: scale(0.92);
518
+ transition-duration: 0.1s;
519
+ }
520
+
521
+ .sp-detail-back svg {
522
+ width: 18px;
523
+ height: 18px;
524
+ }
525
+
526
+ .sp-detail-title {
527
+ font-size: 16px;
528
+ font-weight: 700;
529
+ color: var(--sp-text);
530
+ letter-spacing: -0.02em;
531
+ flex: 1;
532
+ min-width: 0;
533
+ overflow: hidden;
534
+ text-overflow: ellipsis;
535
+ white-space: nowrap;
536
+ }
537
+
538
+ .sp-detail-header .sp-badge {
539
+ flex-shrink: 0;
540
+ }
541
+
542
+ /* ---- Content ---- */
543
+
544
+ .sp-detail-content {
545
+ flex: 1;
546
+ overflow-y: auto;
547
+ overflow-x: hidden;
548
+ padding: 0;
549
+ }
550
+
551
+ .sp-detail-content::-webkit-scrollbar {
552
+ width: 6px;
553
+ }
554
+
555
+ .sp-detail-content::-webkit-scrollbar-track {
556
+ background: transparent;
557
+ }
558
+
559
+ .sp-detail-content::-webkit-scrollbar-thumb {
560
+ background: var(--sp-border);
561
+ border-radius: var(--sp-radius-full);
562
+ }
563
+
564
+ .sp-detail-content::-webkit-scrollbar-thumb:hover {
565
+ background: var(--sp-text-tertiary);
566
+ }
567
+
568
+ /* ---- Section ---- */
569
+
570
+ .sp-detail-section {
571
+ padding: 20px 24px;
572
+ border-bottom: 1px solid var(--sp-border);
573
+ opacity: 0;
574
+ transform: translateY(8px);
575
+ animation: sp-detail-section-in 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
576
+ }
577
+
578
+ @keyframes sp-detail-section-in {
579
+ to {
580
+ opacity: 1;
581
+ transform: translateY(0);
582
+ }
583
+ }
584
+
585
+ .sp-detail-section:last-child {
586
+ border-bottom: none;
587
+ }
588
+
589
+ .sp-detail-section-title {
590
+ font-size: 11px;
591
+ font-weight: 600;
592
+ color: var(--sp-text-tertiary);
593
+ text-transform: uppercase;
594
+ letter-spacing: 0.06em;
595
+ margin-bottom: 14px;
596
+ display: flex;
597
+ align-items: center;
598
+ gap: 6px;
599
+ }
600
+
601
+ .sp-detail-section-title svg {
602
+ width: 14px;
603
+ height: 14px;
604
+ opacity: 0.6;
605
+ }
606
+
607
+ /* ---- Status + Actions Section ---- */
608
+
609
+ .sp-detail-status {
610
+ display: flex;
611
+ align-items: center;
612
+ gap: 10px;
613
+ margin-bottom: 16px;
614
+ }
615
+
616
+ .sp-detail-status-pill {
617
+ display: inline-flex;
618
+ align-items: center;
619
+ gap: 6px;
620
+ padding: 5px 14px;
621
+ border-radius: var(--sp-radius-full);
622
+ font-size: 12px;
623
+ font-weight: 600;
624
+ letter-spacing: 0.02em;
625
+ }
626
+
627
+ .sp-detail-status-pill--open {
628
+ background: rgba(34, 197, 94, 0.1);
629
+ color: #22c55e;
630
+ border: 1px solid rgba(34, 197, 94, 0.2);
631
+ }
632
+
633
+ .sp-detail-status-pill--resolved {
634
+ background: rgba(156, 163, 175, 0.1);
635
+ color: #9ca3af;
636
+ border: 1px solid rgba(156, 163, 175, 0.2);
637
+ }
638
+
639
+ .sp-detail-status-dot {
640
+ width: 6px;
641
+ height: 6px;
642
+ border-radius: 50%;
643
+ flex-shrink: 0;
644
+ }
645
+
646
+ .sp-detail-actions {
647
+ display: flex;
648
+ gap: 8px;
649
+ }
650
+
651
+ .sp-detail-actions button {
652
+ flex: 1;
653
+ height: 40px;
654
+ padding: 0 16px;
655
+ border-radius: var(--sp-radius);
656
+ font-family: var(--sp-font);
657
+ font-size: 13px;
658
+ font-weight: 600;
659
+ cursor: pointer;
660
+ display: flex;
661
+ align-items: center;
662
+ justify-content: center;
663
+ gap: 6px;
664
+ transition: all 0.2s ease;
665
+ }
666
+
667
+ .sp-detail-actions button svg {
668
+ width: 15px;
669
+ height: 15px;
670
+ }
671
+
672
+ .sp-detail-btn-resolve {
673
+ border: 1.5px solid #22c55e;
674
+ background: rgba(34, 197, 94, 0.06);
675
+ color: #22c55e;
676
+ }
677
+
678
+ .sp-detail-btn-resolve:hover {
679
+ background: rgba(34, 197, 94, 0.14);
680
+ box-shadow: 0 0 16px rgba(34, 197, 94, 0.12);
681
+ transform: translateY(-1px);
682
+ }
683
+
684
+ .sp-detail-btn-resolve:active {
685
+ transform: translateY(0) scale(0.98);
686
+ transition-duration: 0.1s;
687
+ }
688
+
689
+ .sp-detail-btn-reopen {
690
+ border: 1.5px solid var(--sp-accent);
691
+ background: var(--sp-accent-light);
692
+ color: var(--sp-accent);
693
+ }
694
+
695
+ .sp-detail-btn-reopen:hover {
696
+ background: rgba(var(--sp-accent), 0.14);
697
+ box-shadow: 0 0 16px var(--sp-accent-glow);
698
+ transform: translateY(-1px);
699
+ }
700
+
701
+ .sp-detail-btn-reopen:active {
702
+ transform: translateY(0) scale(0.98);
703
+ transition-duration: 0.1s;
704
+ }
705
+
706
+ .sp-detail-btn-delete {
707
+ border: 1.5px solid #ef4444;
708
+ background: rgba(239, 68, 68, 0.06);
709
+ color: #ef4444;
710
+ }
711
+
712
+ .sp-detail-btn-delete:hover {
713
+ background: rgba(239, 68, 68, 0.14);
714
+ box-shadow: 0 0 16px rgba(239, 68, 68, 0.12);
715
+ transform: translateY(-1px);
716
+ }
717
+
718
+ .sp-detail-btn-delete:active {
719
+ transform: translateY(0) scale(0.98);
720
+ transition-duration: 0.1s;
721
+ }
722
+
723
+ .sp-detail-actions button:disabled {
724
+ opacity: 0.5;
725
+ cursor: not-allowed;
726
+ pointer-events: none;
727
+ transform: none;
728
+ box-shadow: none;
729
+ }
730
+
731
+ /* ---- Message Section ---- */
732
+
733
+ .sp-detail-message {
734
+ font-size: 14px;
735
+ line-height: 1.65;
736
+ color: var(--sp-text);
737
+ padding: 14px 16px;
738
+ border-left: 3px solid var(--sp-accent);
739
+ border-radius: 0 var(--sp-radius) var(--sp-radius) 0;
740
+ background: var(--sp-glass-bg-heavy);
741
+ white-space: pre-wrap;
742
+ word-break: break-word;
743
+ }
744
+
745
+ /* ---- Screenshot Section ---- */
746
+
747
+ .sp-detail-screenshot {
748
+ display: block;
749
+ width: 100%;
750
+ height: auto;
751
+ max-height: 400px;
752
+ object-fit: contain;
753
+ border-radius: var(--sp-radius);
754
+ border: 1px solid var(--sp-glass-border);
755
+ background: var(--sp-glass-bg-heavy);
756
+ }
757
+
758
+ /* ---- Metadata Section ---- */
759
+
760
+ .sp-detail-meta {
761
+ display: flex;
762
+ flex-direction: column;
763
+ gap: 14px;
764
+ }
765
+
766
+ .sp-detail-meta-row {
767
+ display: flex;
768
+ align-items: flex-start;
769
+ gap: 12px;
770
+ }
771
+
772
+ .sp-detail-meta-row svg {
773
+ width: 14px;
774
+ height: 14px;
775
+ color: var(--sp-text-tertiary);
776
+ flex-shrink: 0;
777
+ margin-top: 1px;
778
+ }
779
+
780
+ .sp-detail-meta-content {
781
+ flex: 1;
782
+ min-width: 0;
783
+ }
784
+
785
+ .sp-detail-meta-label {
786
+ font-size: 10px;
787
+ font-weight: 600;
788
+ color: var(--sp-text-tertiary);
789
+ text-transform: uppercase;
790
+ letter-spacing: 0.06em;
791
+ line-height: 1;
792
+ margin-bottom: 4px;
793
+ }
794
+
795
+ .sp-detail-meta-value {
796
+ font-size: 13px;
797
+ line-height: 1.4;
798
+ color: var(--sp-text);
799
+ word-break: break-all;
800
+ }
801
+
802
+ .sp-detail-meta-value--mono {
803
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "Consolas", monospace;
804
+ font-size: 12px;
805
+ background: var(--sp-glass-bg-heavy);
806
+ padding: 2px 6px;
807
+ border-radius: 4px;
808
+ border: 1px solid var(--sp-glass-border-subtle);
809
+ }
810
+
811
+ .sp-detail-meta-value--secondary {
812
+ color: var(--sp-text-secondary);
813
+ font-size: 12px;
814
+ }
815
+
816
+ /* ---- Annotation Section ---- */
817
+
818
+ .sp-detail-annotation {
819
+ display: flex;
820
+ flex-direction: column;
821
+ gap: 12px;
822
+ }
823
+
824
+ .sp-detail-annotation-info {
825
+ display: flex;
826
+ flex-direction: column;
827
+ gap: 10px;
828
+ padding: 14px;
829
+ border-radius: var(--sp-radius);
830
+ background: var(--sp-glass-bg-heavy);
831
+ border: 1px solid var(--sp-glass-border-subtle);
832
+ }
833
+
834
+ .sp-detail-annotation-row {
835
+ display: flex;
836
+ align-items: flex-start;
837
+ gap: 10px;
838
+ }
839
+
840
+ .sp-detail-annotation-row svg {
841
+ width: 13px;
842
+ height: 13px;
843
+ color: var(--sp-text-tertiary);
844
+ flex-shrink: 0;
845
+ margin-top: 2px;
846
+ }
847
+
848
+ .sp-detail-annotation-label {
849
+ font-size: 10px;
850
+ font-weight: 600;
851
+ color: var(--sp-text-tertiary);
852
+ text-transform: uppercase;
853
+ letter-spacing: 0.06em;
854
+ line-height: 1;
855
+ margin-bottom: 3px;
856
+ }
857
+
858
+ .sp-detail-annotation-value {
859
+ font-size: 12px;
860
+ line-height: 1.4;
861
+ color: var(--sp-text);
862
+ word-break: break-all;
863
+ }
864
+
865
+ .sp-detail-annotation-value--mono {
866
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "Consolas", monospace;
867
+ font-size: 11px;
868
+ background: var(--sp-bg-hover);
869
+ padding: 2px 6px;
870
+ border-radius: 4px;
871
+ display: inline-block;
872
+ max-width: 100%;
873
+ overflow: hidden;
874
+ text-overflow: ellipsis;
875
+ white-space: nowrap;
876
+ }
877
+
878
+ .sp-detail-btn-goto {
879
+ width: 100%;
880
+ height: 44px;
881
+ padding: 0 20px;
882
+ border-radius: var(--sp-radius);
883
+ border: none;
884
+ background: var(--sp-accent-gradient);
885
+ color: #fff;
886
+ font-family: var(--sp-font);
887
+ font-size: 14px;
888
+ font-weight: 600;
889
+ cursor: pointer;
890
+ display: flex;
891
+ align-items: center;
892
+ justify-content: center;
893
+ gap: 8px;
894
+ transition: all 0.25s ease;
895
+ box-shadow: 0 2px 12px var(--sp-accent-glow);
896
+ }
897
+
898
+ .sp-detail-btn-goto svg {
899
+ width: 16px;
900
+ height: 16px;
901
+ }
902
+
903
+ .sp-detail-btn-goto:hover {
904
+ box-shadow: 0 4px 20px var(--sp-accent-glow);
905
+ transform: translateY(-2px);
906
+ }
907
+
908
+ .sp-detail-btn-goto:active {
909
+ transform: translateY(0) scale(0.98);
910
+ transition-duration: 0.1s;
911
+ }
912
+
913
+ /* ---- Forced Colors / High Contrast ---- */
914
+
915
+ @media (forced-colors: active) {
916
+ .sp-detail {
917
+ border: 2px solid ButtonText !important;
918
+ background: Canvas !important;
919
+ }
920
+
921
+ .sp-detail-back,
922
+ .sp-detail-btn-goto,
923
+ .sp-detail-btn-resolve,
924
+ .sp-detail-btn-reopen,
925
+ .sp-detail-btn-delete {
926
+ border: 2px solid ButtonText !important;
927
+ background: Canvas !important;
928
+ color: ButtonText !important;
929
+ }
930
+
931
+ .sp-detail-back:focus-visible,
932
+ .sp-detail-btn-goto:focus-visible,
933
+ .sp-detail-btn-resolve:focus-visible,
934
+ .sp-detail-btn-reopen:focus-visible,
935
+ .sp-detail-btn-delete:focus-visible {
936
+ outline: 3px solid Highlight !important;
937
+ }
938
+
939
+ .sp-detail-status-pill {
940
+ border: 2px solid ButtonText !important;
941
+ background: Canvas !important;
942
+ color: ButtonText !important;
943
+ }
944
+
945
+ .sp-detail-message {
946
+ border-left: 3px solid ButtonText !important;
947
+ }
948
+ }
949
+
950
+ /* ---- Diagnostics Section ---- */
951
+
952
+ .sp-detail-diag {
953
+ display: flex;
954
+ flex-direction: column;
955
+ gap: 12px;
956
+ }
957
+
958
+ .sp-detail-diag-toggle {
959
+ width: 100%;
960
+ display: flex;
961
+ align-items: center;
962
+ justify-content: space-between;
963
+ gap: 8px;
964
+ padding: 10px 12px;
965
+ border-radius: var(--sp-radius);
966
+ border: 1px solid var(--sp-glass-border-subtle);
967
+ background: var(--sp-glass-bg-heavy);
968
+ color: var(--sp-text);
969
+ font-family: var(--sp-font);
970
+ font-size: 12px;
971
+ font-weight: 600;
972
+ cursor: pointer;
973
+ transition: background 0.15s ease;
974
+ }
975
+
976
+ .sp-detail-diag-toggle:hover {
977
+ background: var(--sp-bg-hover);
978
+ }
979
+
980
+ .sp-detail-diag-toggle svg {
981
+ width: 12px;
982
+ height: 12px;
983
+ transition: transform 0.2s ease;
984
+ }
985
+
986
+ .sp-detail-diag-toggle[aria-expanded="true"] svg {
987
+ transform: rotate(90deg);
988
+ }
989
+
990
+ .sp-detail-diag-counts {
991
+ display: inline-flex;
992
+ gap: 6px;
993
+ font-weight: 500;
994
+ color: var(--sp-text-tertiary);
995
+ }
996
+
997
+ .sp-detail-diag-count {
998
+ padding: 1px 7px;
999
+ border-radius: var(--sp-radius-full);
1000
+ background: var(--sp-bg-hover);
1001
+ font-variant-numeric: tabular-nums;
1002
+ }
1003
+
1004
+ .sp-detail-diag-count--errors {
1005
+ background: rgba(239, 68, 68, 0.14);
1006
+ color: #ef4444;
1007
+ }
1008
+
1009
+ .sp-detail-diag-body {
1010
+ display: none;
1011
+ flex-direction: column;
1012
+ gap: 14px;
1013
+ }
1014
+
1015
+ .sp-detail-diag-body--open {
1016
+ display: flex;
1017
+ }
1018
+
1019
+ .sp-detail-diag-group-title {
1020
+ font-size: 10px;
1021
+ font-weight: 700;
1022
+ color: var(--sp-text-tertiary);
1023
+ text-transform: uppercase;
1024
+ letter-spacing: 0.06em;
1025
+ margin-bottom: 6px;
1026
+ }
1027
+
1028
+ .sp-detail-diag-list {
1029
+ list-style: none;
1030
+ padding: 0;
1031
+ margin: 0;
1032
+ border-radius: var(--sp-radius);
1033
+ border: 1px solid var(--sp-glass-border-subtle);
1034
+ background: var(--sp-glass-bg-heavy);
1035
+ max-height: 240px;
1036
+ overflow-y: auto;
1037
+ }
1038
+
1039
+ .sp-detail-diag-list li {
1040
+ display: flex;
1041
+ align-items: flex-start;
1042
+ gap: 8px;
1043
+ padding: 8px 10px;
1044
+ border-bottom: 1px solid var(--sp-glass-border-subtle);
1045
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "Consolas", monospace;
1046
+ font-size: 11px;
1047
+ line-height: 1.45;
1048
+ color: var(--sp-text);
1049
+ }
1050
+
1051
+ .sp-detail-diag-list li:last-child {
1052
+ border-bottom: none;
1053
+ }
1054
+
1055
+ .sp-detail-diag-level {
1056
+ flex-shrink: 0;
1057
+ font-weight: 700;
1058
+ width: 44px;
1059
+ text-transform: uppercase;
1060
+ letter-spacing: 0.04em;
1061
+ font-size: 10px;
1062
+ }
1063
+
1064
+ .sp-detail-diag-level--log {
1065
+ color: var(--sp-text-tertiary);
1066
+ }
1067
+ .sp-detail-diag-level--info {
1068
+ color: #3b82f6;
1069
+ }
1070
+ .sp-detail-diag-level--warn {
1071
+ color: #f59e0b;
1072
+ }
1073
+ .sp-detail-diag-level--error {
1074
+ color: #ef4444;
1075
+ }
1076
+
1077
+ .sp-detail-diag-message {
1078
+ flex: 1;
1079
+ min-width: 0;
1080
+ word-break: break-word;
1081
+ white-space: pre-wrap;
1082
+ }
1083
+
1084
+ .sp-detail-diag-net {
1085
+ display: grid;
1086
+ grid-template-columns: auto 1fr auto;
1087
+ gap: 8px;
1088
+ align-items: center;
1089
+ }
1090
+
1091
+ .sp-detail-diag-net-status {
1092
+ flex-shrink: 0;
1093
+ font-weight: 700;
1094
+ color: #ef4444;
1095
+ min-width: 32px;
1096
+ text-align: right;
1097
+ font-variant-numeric: tabular-nums;
1098
+ }
1099
+
1100
+ .sp-detail-diag-net-method {
1101
+ flex-shrink: 0;
1102
+ font-weight: 600;
1103
+ color: var(--sp-text-tertiary);
1104
+ min-width: 44px;
1105
+ }
1106
+
1107
+ .sp-detail-diag-net-url {
1108
+ flex: 1;
1109
+ min-width: 0;
1110
+ overflow: hidden;
1111
+ text-overflow: ellipsis;
1112
+ white-space: nowrap;
1113
+ color: var(--sp-text);
1114
+ }
1115
+
1116
+ .sp-detail-diag-empty {
1117
+ padding: 12px;
1118
+ font-style: italic;
1119
+ font-size: 11px;
1120
+ color: var(--sp-text-tertiary);
1121
+ text-align: center;
1122
+ }
1123
+
1124
+ /* ---- Reduced Motion ---- */
1125
+
1126
+ @media (prefers-reduced-motion: reduce) {
1127
+ .sp-detail {
1128
+ transition-duration: 0.01ms !important;
1129
+ }
1130
+
1131
+ .sp-detail-section {
1132
+ animation-duration: 0.01ms !important;
1133
+ }
1134
+ }
1135
+ `;function fe(o){if(/Edg\//i.test(o)){let e=o.match(/Edg\/([\d.]+)/);return e?`Edge ${e[1]}`:"Edge"}if(/OPR\//i.test(o)||/Opera/i.test(o)){let e=o.match(/OPR\/([\d.]+)/);return e?`Opera ${e[1]}`:"Opera"}if(/Firefox\//i.test(o)){let e=o.match(/Firefox\/([\d.]+)/);return e?`Firefox ${e[1]}`:"Firefox"}if(/Chrome\//i.test(o)&&!/Chromium/i.test(o)){let e=o.match(/Chrome\/([\d.]+)/);return e?`Chrome ${e[1]}`:"Chrome"}if(/Safari\//i.test(o)&&!/Chrome/i.test(o)){let e=o.match(/Version\/([\d.]+)/);return e?`Safari ${e[1]}`:"Safari"}return "Unknown"}function U(o,e){try{return new Date(o).toLocaleString(e,{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return o}}function ye(o){try{return new URL(o).pathname}catch{return o}}function ke(o){return !!(/^data:image\/(jpeg|png|webp);/i.test(o)||/^https:\/\//i.test(o))}function S(o,e){return o.length<=e?o:o.slice(0,e-1)+"\u2026"}function Ce(o){if(!o)return false;let e=Array.isArray(o.console)?o.console.length:0,t=Array.isArray(o.network)?o.network.length:0;return e>0||t>0}function we(o){return !Number.isFinite(o)||o<0?"\u2014":o<1e3?`${Math.round(o)} ms`:`${(o/1e3).toFixed(1)} s`}var Y=class{constructor(e,t,s,n){this.colors=e;this.callbacks=t;this.t=s,this.locale=n,this.element=r("div",{class:"sp-detail"}),this.element.setAttribute("role","dialog"),this.element.setAttribute("aria-label","Feedback detail"),this.element.setAttribute("aria-hidden","true");let i=r("div",{class:"sp-detail-header"}),l=document.createElement("button");l.type="button",l.className="sp-detail-back",l.setAttribute("aria-label",this.t("detail.back")),l.appendChild(c(de)),l.addEventListener("click",()=>{this.hide(),this.callbacks.onBack();}),this.element.appendChild(i),i.appendChild(l),this.content=r("div",{class:"sp-detail-content"}),this.element.appendChild(this.content);}colors;callbacks;element;_isVisible=false;currentFeedback=null;content;t;locale;resolveBtn=null;deleteBtn=null;isProcessing=false;show(e,t){this.currentFeedback=e,this.isProcessing=false;let s=this.element.querySelector(".sp-detail-header");if(!s)return;let n=s.querySelector(".sp-detail-back");if(!n)return;s.replaceChildren(n);let i=r("span",{class:"sp-detail-title"});a(i,this.t("detail.title").replace("{number}",String(t))),s.appendChild(i);let l=r("span",{class:"sp-badge"});l.style.background=N(e.type,this.colors),l.style.color=A(e.type,this.colors),a(l,e.type),s.appendChild(l),this.content.replaceChildren();let d=0,p=this.buildSection(d++);this.buildStatusActions(p,e),this.content.appendChild(p);let u=this.buildSection(d++),h=r("div",{class:"sp-detail-section-title"});a(h,this.t("detail.message")),u.appendChild(h);let v=r("div",{class:"sp-detail-message"});if(v.style.borderLeftColor=A(e.type,this.colors),a(v,e.message),u.appendChild(v),this.content.appendChild(u),e.screenshotUrl&&ke(e.screenshotUrl)){let g=this.buildSection(d++),x=r("div",{class:"sp-detail-section-title"});a(x,this.t("detail.screenshot")),g.appendChild(x);let b=document.createElement("img");b.className="sp-detail-screenshot",b.src=e.screenshotUrl,b.alt=this.t("detail.screenshotAlt"),b.loading="lazy",b.referrerPolicy="no-referrer",g.appendChild(b),this.content.appendChild(g);}let f=this.buildSection(d++),m=r("div",{class:"sp-detail-section-title"});if(a(m,this.t("detail.metadata")),f.appendChild(m),this.buildMetadata(f,e),this.content.appendChild(f),e.annotations.length>0){let g=this.buildSection(d++),x=r("div",{class:"sp-detail-section-title"});x.appendChild(c(R));let b=r("span");a(b,this.t("detail.annotation")),x.appendChild(b),g.appendChild(x),this.buildAnnotation(g,e),this.content.appendChild(g);}if(Ce(e.diagnostics)){let g=this.buildSection(d++),x=r("div",{class:"sp-detail-section-title"});x.appendChild(c(me));let b=r("span");a(b,this.t("detail.diagnostics")),x.appendChild(b),g.appendChild(x),this.buildDiagnostics(g,e),this.content.appendChild(g);}this._isVisible=true,this.element.setAttribute("aria-hidden","false"),this.element.offsetHeight,this.element.classList.add("sp-detail--visible"),requestAnimationFrame(()=>{n.focus();});}hide(){this._isVisible&&(this._isVisible=false,this.element.classList.remove("sp-detail--visible"),this.element.setAttribute("aria-hidden","true"),this.currentFeedback=null,this.resolveBtn=null,this.deleteBtn=null);}get isVisible(){return this._isVisible}destroy(){this.hide(),this.element.remove();}buildSection(e){let t=r("div",{class:"sp-detail-section"});return t.style.animationDelay=`${e*40}ms`,t}buildStatusActions(e,t){let s=t.status==="resolved",n=r("div",{class:"sp-detail-section-title"});a(n,this.t("detail.status")),e.appendChild(n);let i=r("div",{class:"sp-detail-status"}),l=r("span",{class:`sp-detail-status-pill ${s?"sp-detail-status-pill--resolved":"sp-detail-status-pill--open"}`}),d=r("span",{class:"sp-detail-status-dot"});d.style.background=s?"#9ca3af":"#22c55e",l.appendChild(d);let p=r("span");a(p,s?this.t("detail.reopen"):this.t("detail.resolve")),a(p,s?"Resolved":"Open"),l.appendChild(p),i.appendChild(l),e.appendChild(i);let u=r("div",{class:"sp-detail-actions"});if(this.resolveBtn=document.createElement("button"),this.resolveBtn.type="button",s){this.resolveBtn.className="sp-detail-btn-reopen",this.resolveBtn.appendChild(c(V));let v=document.createElement("span");a(v,this.t("detail.reopen")),this.resolveBtn.appendChild(v);}else {this.resolveBtn.className="sp-detail-btn-resolve",this.resolveBtn.appendChild(c(H));let v=document.createElement("span");a(v,this.t("detail.resolve")),this.resolveBtn.appendChild(v);}this.resolveBtn.addEventListener("click",()=>this.handleResolve()),this.deleteBtn=document.createElement("button"),this.deleteBtn.type="button",this.deleteBtn.className="sp-detail-btn-delete",this.deleteBtn.appendChild(c(G));let h=document.createElement("span");a(h,this.t("detail.delete")),this.deleteBtn.appendChild(h),this.deleteBtn.addEventListener("click",()=>this.handleDelete()),u.appendChild(this.resolveBtn),u.appendChild(this.deleteBtn),e.appendChild(u);}buildMetadata(e,t){let s=r("div",{class:"sp-detail-meta"});if(this.addMetaRow(s,ce,this.t("detail.page"),()=>{let n=r("div",{class:"sp-detail-meta-value"}),i=ye(t.url);return a(n,S(i,60)),n.title=t.url,n}),this.addMetaRow(s,he,this.t("detail.author"),()=>{let n=r("div",{class:"sp-detail-meta-value"}),i=t.authorName||"Anonymous",l=t.authorEmail;return a(n,l?`${i} (${l})`:i),n}),this.addMetaRow(s,ue,this.t("detail.date"),()=>{let n=r("div",{class:"sp-detail-meta-value"});return a(n,U(t.createdAt,this.locale.startsWith("fr")?"fr":"en")),n}),this.addMetaRow(s,ge,this.t("detail.viewport"),()=>{let n=r("div",{class:"sp-detail-meta-value sp-detail-meta-value--mono"});return a(n,t.viewport||"Unknown"),n}),this.addMetaRow(s,'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',this.t("detail.browser"),()=>{let n=r("div",{class:"sp-detail-meta-value"});return a(n,fe(t.userAgent)),n}),t.resolvedAt){let n=t.resolvedAt;this.addMetaRow(s,H,this.t("detail.resolvedAt"),()=>{let i=r("div",{class:"sp-detail-meta-value sp-detail-meta-value--secondary"});return a(i,U(n,this.locale.startsWith("fr")?"fr":"en")),i});}e.appendChild(s);}addMetaRow(e,t,s,n){let i=r("div",{class:"sp-detail-meta-row"});i.appendChild(c(t));let l=r("div",{class:"sp-detail-meta-content"}),d=r("div",{class:"sp-detail-meta-label"});a(d,s),l.appendChild(d),l.appendChild(n()),i.appendChild(l),e.appendChild(i);}buildAnnotation(e,t){let s=t.annotations[0];if(!s)return;let n=r("div",{class:"sp-detail-annotation"}),i=r("div",{class:"sp-detail-annotation-info"});this.addAnnotationRow(i,be,this.t("detail.element"),()=>{let p=r("span",{class:"sp-detail-annotation-value sp-detail-annotation-value--mono"}),u=s.elementId?`<${s.elementTag}#${s.elementId}>`:`<${s.elementTag}>`;return a(p,u),p}),this.addAnnotationRow(i,ve,this.t("detail.selector"),()=>{let p=r("span",{class:"sp-detail-annotation-value sp-detail-annotation-value--mono"});return a(p,S(s.cssSelector,60)),p.title=s.cssSelector,p}),this.addAnnotationRow(i,R,this.t("detail.position"),()=>{let p=r("span",{class:"sp-detail-annotation-value"});return a(p,`${s.xPct.toFixed(1)}%, ${s.yPct.toFixed(1)}%`+(s.wPct>0||s.hPct>0?` (${s.wPct.toFixed(1)}% \xD7 ${s.hPct.toFixed(1)}%)`:"")),p}),n.appendChild(i);let l=document.createElement("button");l.type="button",l.className="sp-detail-btn-goto",l.appendChild(c(R));let d=document.createElement("span");a(d,this.t("detail.goToAnnotation")),l.appendChild(d),l.addEventListener("click",()=>{this.currentFeedback&&this.callbacks.onGoToAnnotation(this.currentFeedback);}),n.appendChild(l),e.appendChild(n);}buildDiagnostics(e,t){let s=t.diagnostics;if(!s)return;let n=Array.isArray(s.console)?s.console:[],i=Array.isArray(s.network)?s.network:[],l=n.filter(x=>x.level==="error").length,d=r("div",{class:"sp-detail-diag"}),p=document.createElement("button");p.type="button",p.className="sp-detail-diag-toggle",p.setAttribute("aria-expanded","false"),p.setAttribute("aria-label",this.t("detail.diagnostics.expand"));let u=document.createElement("span"),h=document.createElement("span");h.style.display="inline-flex",h.style.alignItems="center",h.style.gap="8px",h.appendChild(c(xe)),a(u,this.t("detail.diagnostics")),h.appendChild(u),p.appendChild(h);let v=r("span",{class:"sp-detail-diag-counts"}),f=r("span",{class:`sp-detail-diag-count${l>0?" sp-detail-diag-count--errors":""}`});a(f,`${n.length} console`);let m=r("span",{class:`sp-detail-diag-count${i.length>0?" sp-detail-diag-count--errors":""}`});a(m,`${i.length} net`),v.appendChild(f),v.appendChild(m),p.appendChild(v);let g=r("div",{class:"sp-detail-diag-body"});if(n.length>0){let x=document.createElement("div"),b=r("div",{class:"sp-detail-diag-group-title"});a(b,this.t("detail.diagnostics.console")),x.appendChild(b);let C=document.createElement("ul");C.className="sp-detail-diag-list";for(let y of n){let k=document.createElement("li"),E=r("span",{class:`sp-detail-diag-level sp-detail-diag-level--${y.level}`});a(E,y.level);let B=r("span",{class:"sp-detail-diag-message"});a(B,S(y.message,240)),B.title=y.message,k.appendChild(E),k.appendChild(B),C.appendChild(k);}x.appendChild(C),g.appendChild(x);}if(i.length>0){let x=document.createElement("div"),b=r("div",{class:"sp-detail-diag-group-title"});a(b,this.t("detail.diagnostics.network")),x.appendChild(b);let C=document.createElement("ul");C.className="sp-detail-diag-list";for(let y of i){let k=document.createElement("li");k.classList.add("sp-detail-diag-net");let E=r("span",{class:"sp-detail-diag-net-status"});a(E,y.status===0?"ERR":String(y.status));let B=r("span",{class:"sp-detail-diag-net-method"});a(B,y.method);let M=r("span",{class:"sp-detail-diag-net-url"});a(M,S(y.url,120)),M.title=`${y.url} \u2014 ${we(y.durationMs)}`,k.appendChild(E),k.appendChild(B),k.appendChild(M),C.appendChild(k);}x.appendChild(C),g.appendChild(x);}p.addEventListener("click",()=>{let b=!(p.getAttribute("aria-expanded")==="true");p.setAttribute("aria-expanded",String(b)),p.setAttribute("aria-label",b?this.t("detail.diagnostics.collapse"):this.t("detail.diagnostics.expand")),g.classList.toggle("sp-detail-diag-body--open",b);}),d.appendChild(p),d.appendChild(g),e.appendChild(d);}addAnnotationRow(e,t,s,n){let i=r("div",{class:"sp-detail-annotation-row"});i.appendChild(c(t));let l=r("div",{class:"sp-detail-meta-content"}),d=r("div",{class:"sp-detail-annotation-label"});a(d,s),l.appendChild(d),l.appendChild(n()),i.appendChild(l),e.appendChild(i);}async handleResolve(){if(!(this.isProcessing||!this.currentFeedback)){this.isProcessing=true,this.resolveBtn&&this.setButtonLoading(this.resolveBtn),this.deleteBtn&&(this.deleteBtn.disabled=true);try{await this.callbacks.onResolve(this.currentFeedback);}catch{this.isProcessing=false,this.resolveBtn&&this.restoreResolveBtn(this.currentFeedback),this.deleteBtn&&(this.deleteBtn.disabled=false);}}}async handleDelete(){if(!(this.isProcessing||!this.currentFeedback)){this.isProcessing=true,this.deleteBtn&&this.setButtonLoading(this.deleteBtn),this.resolveBtn&&(this.resolveBtn.disabled=true);try{await this.callbacks.onDelete(this.currentFeedback);}catch{this.isProcessing=false,this.deleteBtn&&this.restoreDeleteBtn(),this.resolveBtn&&(this.resolveBtn.disabled=false);}}}setButtonLoading(e){e.disabled=true,e.replaceChildren(r("div",{class:"sp-spinner sp-spinner--sm"}));}restoreResolveBtn(e){if(!this.resolveBtn)return;this.resolveBtn.disabled=false,this.resolveBtn.replaceChildren();let t=e.status==="resolved";this.resolveBtn.appendChild(c(t?V:H));let s=document.createElement("span");a(s,t?this.t("detail.reopen"):this.t("detail.resolve")),this.resolveBtn.appendChild(s);}restoreDeleteBtn(){if(!this.deleteBtn)return;this.deleteBtn.disabled=false,this.deleteBtn.replaceChildren(),this.deleteBtn.appendChild(c(G));let e=document.createElement("span");a(e,this.t("detail.delete")),this.deleteBtn.appendChild(e);}};var Be='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 5h10"/><path d="M11 9h7"/><path d="M11 13h4"/><path d="M3 17l3 3 3-3"/><path d="M6 18V4"/></svg>',Q='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>',Ee='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>',K={question:0,change:1,bug:2,other:3};function xt(o,e){let t=[...o];switch(e){case "newest":t.sort((s,n)=>new Date(n.createdAt).getTime()-new Date(s.createdAt).getTime());break;case "oldest":t.sort((s,n)=>new Date(s.createdAt).getTime()-new Date(n.createdAt).getTime());break;case "by-type":t.sort((s,n)=>{let i=K[s.type]??99,l=K[n.type]??99;return i!==l?i-l:new Date(n.createdAt).getTime()-new Date(s.createdAt).getTime()});break;case "open-first":t.sort((s,n)=>{let i=s.status==="open"?0:1,l=n.status==="open"?0:1;return i!==l?i-l:new Date(n.createdAt).getTime()-new Date(s.createdAt).getTime()});break}return t}function Te(o){try{return new URL(o).pathname}catch{return o}}function Se(o,e){if(o.length<=e)return o;let t="\u2026",s=Math.floor((e-1)/2);return o.slice(0,s)+t+o.slice(-s)}function mt(o){let e=new Map;for(let s of o){let n=Te(s.url),i=e.get(n);i?i.push(s):e.set(n,[s]);}return new Map([...e.entries()].sort((s,n)=>n[1].length-s[1].length))}function ft(o,e,t){let s=r("div",{class:"sp-group-header"});s.setAttribute("role","button"),s.setAttribute("tabindex","0"),s.setAttribute("aria-expanded","true"),s.style.borderBottomColor=t.border;let n=r("span",{class:"sp-group-header-chevron"});n.appendChild(c(Ee)),s.appendChild(n);let i=r("span",{class:"sp-group-header-icon"});i.appendChild(c(Q)),s.appendChild(i);let l=r("span",{class:"sp-group-header-path"}),d=Se(o,40);a(l,d),o.length>40&&(l.title=o),s.appendChild(l);let p=r("span",{class:"sp-group-header-count"});p.style.background=t.accentLight,p.style.color=t.accent,a(p,String(e)),s.appendChild(p);let u=()=>{let h=s.getAttribute("aria-expanded")==="true";s.setAttribute("aria-expanded",String(!h)),s.classList.toggle("sp-group-header--collapsed",h);let v=s.nextElementSibling;v?.classList.contains("sp-group-content")&&v.classList.toggle("sp-group-content--collapsed",h);};return s.addEventListener("click",u),s.addEventListener("keydown",h=>{(h.key==="Enter"||h.key===" ")&&(h.preventDefault(),u());}),s}var q=class{element;_sortMode="newest";_groupByPage=false;menuEl=null;sortBtn;groupToggle;t;colors;onChange;outsideClickHandler=null;constructor(e,t,s){this.colors=e,this.onChange=t,this.t=s,this.element=r("div",{class:"sp-sort-controls"}),this.sortBtn=document.createElement("button"),this.sortBtn.className="sp-sort-btn",this.sortBtn.setAttribute("aria-haspopup","listbox"),this.sortBtn.setAttribute("aria-expanded","false"),this.sortBtn.setAttribute("aria-label",this.t("sort.label"));let n=c(Be);this.sortBtn.appendChild(n);let i=r("span",{class:"sp-sort-btn-label"});a(i,this.t("sort.newest")),this.sortBtn.appendChild(i),this.sortBtn.addEventListener("click",p=>{p.stopPropagation(),this.toggleMenu();}),this.groupToggle=document.createElement("button"),this.groupToggle.className="sp-group-toggle",this.groupToggle.setAttribute("aria-pressed","false");let l=c(Q);this.groupToggle.appendChild(l);let d=r("span",{class:"sp-group-toggle-label"});a(d,this.t("group.byPage")),this.groupToggle.appendChild(d),this.groupToggle.addEventListener("click",()=>{this._groupByPage=!this._groupByPage,this.groupToggle.classList.toggle("sp-group-toggle--active",this._groupByPage),this.groupToggle.setAttribute("aria-pressed",String(this._groupByPage)),this.onChange();}),this.element.appendChild(this.sortBtn),this.element.appendChild(this.groupToggle);}get sortMode(){return this._sortMode}get groupByPage(){return this._groupByPage}toggleMenu(){if(this.menuEl){this.closeMenu();return}this.openMenu();}openMenu(){this.menuEl=r("div",{class:"sp-sort-menu"}),this.menuEl.setAttribute("role","listbox"),this.menuEl.setAttribute("aria-label",this.t("sort.label")),this.sortBtn.setAttribute("aria-expanded","true");let e=[{mode:"newest",label:this.t("sort.newest")},{mode:"oldest",label:this.t("sort.oldest")},{mode:"by-type",label:this.t("sort.byType")},{mode:"open-first",label:this.t("sort.openFirst")}];for(let t of e){let s=document.createElement("button");s.className=`sp-sort-option${t.mode===this._sortMode?" sp-sort-option--active":""}`,s.setAttribute("role","option"),s.setAttribute("aria-selected",String(t.mode===this._sortMode)),t.mode===this._sortMode&&(s.style.background=this.colors.accentLight,s.style.color=this.colors.accent),a(s,t.label),s.addEventListener("click",n=>{n.stopPropagation(),this._sortMode=t.mode,this.updateSortLabel(),this.closeMenu(),this.onChange();}),this.menuEl.appendChild(s);}this.element.appendChild(this.menuEl),requestAnimationFrame(()=>{this.outsideClickHandler=t=>{this.menuEl&&!this.element.contains(t.target)&&this.closeMenu();},document.addEventListener("click",this.outsideClickHandler,true);}),this.menuEl.addEventListener("keydown",t=>{t.key==="Escape"&&(this.closeMenu(),this.sortBtn.focus());});}closeMenu(){this.menuEl&&(this.menuEl.remove(),this.menuEl=null),this.sortBtn.setAttribute("aria-expanded","false"),this.outsideClickHandler&&(document.removeEventListener("click",this.outsideClickHandler,true),this.outsideClickHandler=null);}updateSortLabel(){let e={newest:this.t("sort.newest"),oldest:this.t("sort.oldest"),"by-type":this.t("sort.byType"),"open-first":this.t("sort.openFirst")},t=this.sortBtn.querySelector(".sp-sort-btn-label");t&&a(t,e[this._sortMode]);}destroy(){this.closeMenu();}},yt=`
1136
+ /* ============================
1137
+ Sort Controls Container
1138
+ ============================ */
1139
+
1140
+ .sp-sort-controls {
1141
+ display: flex;
1142
+ align-items: center;
1143
+ gap: 6px;
1144
+ margin-top: 4px;
1145
+ padding-top: 8px;
1146
+ border-top: 1px solid var(--sp-border);
1147
+ }
1148
+
1149
+ /* ============================
1150
+ Sort Dropdown Button
1151
+ ============================ */
1152
+
1153
+ .sp-sort-btn {
1154
+ display: inline-flex;
1155
+ align-items: center;
1156
+ gap: 5px;
1157
+ padding: 5px 12px;
1158
+ border-radius: var(--sp-radius-full);
1159
+ border: 1px solid var(--sp-border);
1160
+ background: var(--sp-glass-bg-heavy);
1161
+ color: var(--sp-text-secondary);
1162
+ font-family: var(--sp-font);
1163
+ font-size: 12px;
1164
+ font-weight: 500;
1165
+ cursor: pointer;
1166
+ white-space: nowrap;
1167
+ transition: all 0.2s ease;
1168
+ position: relative;
1169
+ }
1170
+
1171
+ .sp-sort-btn svg {
1172
+ width: 14px;
1173
+ height: 14px;
1174
+ flex-shrink: 0;
1175
+ }
1176
+
1177
+ .sp-sort-btn:hover {
1178
+ border-color: var(--sp-accent);
1179
+ color: var(--sp-accent);
1180
+ background: var(--sp-accent-light);
1181
+ }
1182
+
1183
+ .sp-sort-btn[aria-expanded="true"] {
1184
+ border-color: var(--sp-accent);
1185
+ color: var(--sp-accent);
1186
+ background: var(--sp-accent-light);
1187
+ }
1188
+
1189
+ /* ============================
1190
+ Sort Floating Menu
1191
+ ============================ */
1192
+
1193
+ .sp-sort-menu {
1194
+ position: absolute;
1195
+ top: calc(100% + 6px);
1196
+ left: 0;
1197
+ min-width: 170px;
1198
+ padding: 4px;
1199
+ border-radius: var(--sp-radius);
1200
+ background: var(--sp-glass-bg-heavy);
1201
+ backdrop-filter: blur(var(--sp-blur-heavy));
1202
+ -webkit-backdrop-filter: blur(var(--sp-blur-heavy));
1203
+ border: 1px solid var(--sp-glass-border);
1204
+ box-shadow: var(--sp-shadow-md);
1205
+ z-index: 10;
1206
+ animation: sp-sort-menu-in 0.15s ease-out both;
1207
+ }
1208
+
1209
+ @keyframes sp-sort-menu-in {
1210
+ from {
1211
+ opacity: 0;
1212
+ transform: translateY(-4px) scale(0.97);
1213
+ }
1214
+ to {
1215
+ opacity: 1;
1216
+ transform: translateY(0) scale(1);
1217
+ }
1218
+ }
1219
+
1220
+ /* ============================
1221
+ Sort Menu Option
1222
+ ============================ */
1223
+
1224
+ .sp-sort-option {
1225
+ display: block;
1226
+ width: 100%;
1227
+ padding: 8px 12px;
1228
+ border: none;
1229
+ border-radius: 8px;
1230
+ background: transparent;
1231
+ color: var(--sp-text-secondary);
1232
+ font-family: var(--sp-font);
1233
+ font-size: 12px;
1234
+ font-weight: 500;
1235
+ cursor: pointer;
1236
+ text-align: left;
1237
+ transition: all 0.15s ease;
1238
+ }
1239
+
1240
+ .sp-sort-option:hover {
1241
+ background: var(--sp-bg-hover);
1242
+ color: var(--sp-text);
1243
+ }
1244
+
1245
+ .sp-sort-option--active {
1246
+ font-weight: 600;
1247
+ }
1248
+
1249
+ .sp-sort-option--active:hover {
1250
+ background: var(--sp-accent-light);
1251
+ color: var(--sp-accent);
1252
+ }
1253
+
1254
+ /* ============================
1255
+ Group by Page Toggle
1256
+ ============================ */
1257
+
1258
+ .sp-group-toggle {
1259
+ display: inline-flex;
1260
+ align-items: center;
1261
+ gap: 5px;
1262
+ padding: 5px 12px;
1263
+ border-radius: var(--sp-radius-full);
1264
+ border: 1px solid var(--sp-border);
1265
+ background: var(--sp-glass-bg-heavy);
1266
+ color: var(--sp-text-secondary);
1267
+ font-family: var(--sp-font);
1268
+ font-size: 12px;
1269
+ font-weight: 500;
1270
+ cursor: pointer;
1271
+ white-space: nowrap;
1272
+ transition: all 0.2s ease;
1273
+ }
1274
+
1275
+ .sp-group-toggle svg {
1276
+ width: 13px;
1277
+ height: 13px;
1278
+ flex-shrink: 0;
1279
+ }
1280
+
1281
+ .sp-group-toggle:hover {
1282
+ border-color: var(--sp-accent);
1283
+ color: var(--sp-accent);
1284
+ background: var(--sp-accent-light);
1285
+ }
1286
+
1287
+ .sp-group-toggle--active {
1288
+ background: var(--sp-accent-gradient);
1289
+ border-color: transparent;
1290
+ color: #fff;
1291
+ box-shadow: 0 2px 8px var(--sp-accent-glow);
1292
+ }
1293
+
1294
+ .sp-group-toggle--active:hover {
1295
+ background: var(--sp-accent-gradient);
1296
+ border-color: transparent;
1297
+ color: #fff;
1298
+ }
1299
+
1300
+ /* ============================
1301
+ Page Group Header
1302
+ ============================ */
1303
+
1304
+ .sp-group-header {
1305
+ display: flex;
1306
+ align-items: center;
1307
+ gap: 8px;
1308
+ padding: 8px 12px;
1309
+ background: var(--sp-accent-light);
1310
+ border-bottom: 1px solid var(--sp-border);
1311
+ cursor: pointer;
1312
+ user-select: none;
1313
+ position: sticky;
1314
+ top: 0;
1315
+ z-index: 2;
1316
+ transition: background 0.2s ease;
1317
+ }
1318
+
1319
+ .sp-group-header:hover {
1320
+ background: var(--sp-bg-hover);
1321
+ }
1322
+
1323
+ .sp-group-header:focus-visible {
1324
+ outline: 2px solid var(--sp-accent);
1325
+ outline-offset: -2px;
1326
+ }
1327
+
1328
+ .sp-group-header-chevron {
1329
+ display: flex;
1330
+ align-items: center;
1331
+ justify-content: center;
1332
+ width: 16px;
1333
+ height: 16px;
1334
+ flex-shrink: 0;
1335
+ transition: transform 0.2s ease;
1336
+ transform: rotate(90deg);
1337
+ }
1338
+
1339
+ .sp-group-header-chevron svg {
1340
+ width: 12px;
1341
+ height: 12px;
1342
+ color: var(--sp-text-tertiary);
1343
+ }
1344
+
1345
+ .sp-group-header--collapsed .sp-group-header-chevron {
1346
+ transform: rotate(0deg);
1347
+ }
1348
+
1349
+ .sp-group-header-icon {
1350
+ display: flex;
1351
+ align-items: center;
1352
+ flex-shrink: 0;
1353
+ }
1354
+
1355
+ .sp-group-header-icon svg {
1356
+ width: 14px;
1357
+ height: 14px;
1358
+ color: var(--sp-text-tertiary);
1359
+ }
1360
+
1361
+ .sp-group-header-path {
1362
+ font-size: 12px;
1363
+ font-weight: 600;
1364
+ color: var(--sp-text-secondary);
1365
+ flex: 1;
1366
+ min-width: 0;
1367
+ overflow: hidden;
1368
+ text-overflow: ellipsis;
1369
+ white-space: nowrap;
1370
+ }
1371
+
1372
+ .sp-group-header-count {
1373
+ font-size: 11px;
1374
+ font-weight: 700;
1375
+ padding: 1px 8px;
1376
+ border-radius: var(--sp-radius-full);
1377
+ flex-shrink: 0;
1378
+ font-variant-numeric: tabular-nums;
1379
+ }
1380
+
1381
+ /* ============================
1382
+ Page Group Content
1383
+ ============================ */
1384
+
1385
+ .sp-group-content {
1386
+ overflow: hidden;
1387
+ transition: max-height 0.25s ease, opacity 0.2s ease;
1388
+ max-height: 5000px;
1389
+ opacity: 1;
1390
+ }
1391
+
1392
+ .sp-group-content--collapsed {
1393
+ max-height: 0;
1394
+ opacity: 0;
1395
+ pointer-events: none;
1396
+ }
1397
+
1398
+ /* ============================
1399
+ Forced Colors / High Contrast
1400
+ ============================ */
1401
+
1402
+ @media (forced-colors: active) {
1403
+ .sp-sort-btn,
1404
+ .sp-group-toggle,
1405
+ .sp-sort-option,
1406
+ .sp-group-header {
1407
+ border: 2px solid ButtonText !important;
1408
+ background: Canvas !important;
1409
+ color: ButtonText !important;
1410
+ }
1411
+
1412
+ .sp-sort-btn:focus-visible,
1413
+ .sp-group-toggle:focus-visible,
1414
+ .sp-sort-option:focus-visible,
1415
+ .sp-group-header:focus-visible {
1416
+ outline: 3px solid Highlight !important;
1417
+ }
1418
+
1419
+ .sp-sort-menu {
1420
+ border: 2px solid ButtonText !important;
1421
+ background: Canvas !important;
1422
+ }
1423
+ }
1424
+
1425
+ /* ============================
1426
+ Reduced Motion
1427
+ ============================ */
1428
+
1429
+ @media (prefers-reduced-motion: reduce) {
1430
+ .sp-sort-menu {
1431
+ animation: none;
1432
+ }
1433
+ .sp-group-header-chevron {
1434
+ transition: none;
1435
+ }
1436
+ .sp-group-content {
1437
+ transition: none;
1438
+ }
1439
+ }
1440
+ `;var wt=`
1441
+ .sp-stats-bar {
1442
+ display: flex;
1443
+ flex-direction: column;
1444
+ gap: 8px;
1445
+ padding: 12px 24px;
1446
+ border-bottom: 1px solid var(--sp-border);
1447
+ user-select: none;
1448
+ }
1449
+
1450
+ .sp-stats-bar[hidden] {
1451
+ display: none;
1452
+ }
1453
+
1454
+ .sp-stats-row {
1455
+ display: flex;
1456
+ align-items: center;
1457
+ gap: 16px;
1458
+ }
1459
+
1460
+ .sp-stats-item {
1461
+ display: flex;
1462
+ align-items: center;
1463
+ gap: 6px;
1464
+ }
1465
+
1466
+ .sp-stats-dot {
1467
+ width: 6px;
1468
+ height: 6px;
1469
+ border-radius: 50%;
1470
+ flex-shrink: 0;
1471
+ }
1472
+
1473
+ .sp-stats-value {
1474
+ font-size: 16px;
1475
+ font-weight: 600;
1476
+ line-height: 1;
1477
+ color: var(--sp-text);
1478
+ font-variant-numeric: tabular-nums;
1479
+ font-feature-settings: "tnum";
1480
+ transition: opacity 0.3s ease;
1481
+ }
1482
+
1483
+ .sp-stats-label {
1484
+ font-size: 11px;
1485
+ line-height: 1;
1486
+ color: var(--sp-text-tertiary);
1487
+ text-transform: uppercase;
1488
+ letter-spacing: 0.04em;
1489
+ }
1490
+
1491
+ .sp-stats-progress {
1492
+ display: flex;
1493
+ align-items: center;
1494
+ gap: 8px;
1495
+ }
1496
+
1497
+ .sp-stats-progress-track {
1498
+ flex: 1;
1499
+ height: 4px;
1500
+ border-radius: 2px;
1501
+ background: var(--sp-border);
1502
+ overflow: hidden;
1503
+ }
1504
+
1505
+ .sp-stats-progress-fill {
1506
+ height: 100%;
1507
+ border-radius: 2px;
1508
+ background: linear-gradient(90deg, var(--sp-accent), #22c55e);
1509
+ width: 0%;
1510
+ transition: width 0.5s ease;
1511
+ }
1512
+
1513
+ .sp-stats-progress-label {
1514
+ font-size: 10px;
1515
+ line-height: 1;
1516
+ color: var(--sp-text-tertiary);
1517
+ white-space: nowrap;
1518
+ font-variant-numeric: tabular-nums;
1519
+ font-feature-settings: "tnum";
1520
+ min-width: 64px;
1521
+ text-align: right;
1522
+ }
1523
+ `,W=class{constructor(e,t){this.colors=e;this.t=t,this.element=r("div",{class:"sp-stats-bar"}),this.element.setAttribute("aria-label","Feedback statistics"),this.element.hidden=true;let s=r("div",{class:"sp-stats-row"}),n=r("div",{class:"sp-stats-item"}),i=r("span",{class:"sp-stats-dot"});i.style.background="#22c55e",this.valueOpen=r("span",{class:"sp-stats-value"}),a(this.valueOpen,"0");let l=r("span",{class:"sp-stats-label"});a(l,this.t("stats.open")),n.appendChild(i),n.appendChild(this.valueOpen),n.appendChild(l);let d=r("div",{class:"sp-stats-item"}),p=r("span",{class:"sp-stats-dot"});p.style.background="#9ca3af",this.valueResolved=r("span",{class:"sp-stats-value"}),a(this.valueResolved,"0");let u=r("span",{class:"sp-stats-label"});a(u,this.t("stats.resolved")),d.appendChild(p),d.appendChild(this.valueResolved),d.appendChild(u);let h=r("div",{class:"sp-stats-item"}),v=r("span",{class:"sp-stats-dot"});v.style.background=this.colors.typeBug,this.valueBugs=r("span",{class:"sp-stats-value"}),a(this.valueBugs,"0");let f=r("span",{class:"sp-stats-label"});a(f,this.t("stats.bugs")),h.appendChild(v),h.appendChild(this.valueBugs),h.appendChild(f),s.appendChild(n),s.appendChild(d),s.appendChild(h);let m=r("div",{class:"sp-stats-progress"}),g=r("div",{class:"sp-stats-progress-track"});this.progressFill=r("div",{class:"sp-stats-progress-fill"}),g.appendChild(this.progressFill),this.progressLabel=r("span",{class:"sp-stats-progress-label"}),a(this.progressLabel,""),m.appendChild(g),m.appendChild(this.progressLabel),this.element.appendChild(s),this.element.appendChild(m);}colors;element;valueOpen;valueResolved;valueBugs;progressFill;progressLabel;t;update(e,t){if(t===0){this.element.hidden=true;return}this.element.hidden=false;let s=0,n=0,i=0;for(let u of e)u.status==="open"&&s++,u.status==="resolved"&&n++,u.type==="bug"&&i++;a(this.valueOpen,String(s)),a(this.valueResolved,String(n)),a(this.valueBugs,String(i));let l=e.length,d=l>0?Math.round(n/l*100):0;requestAnimationFrame(()=>{this.progressFill.style.width=`${d}%`;});let p=this.t("stats.progress").replace("{percent}",String(d));a(this.progressLabel,p);}};var Me='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.01"/><path d="M10 8h.01"/><path d="M14 8h.01"/><path d="M18 8h.01"/><path d="M6 12h.01"/><path d="M18 12h.01"/><path d="M8 16h8"/></svg>';function Tt(o){let e=o.querySelectorAll(".sp-card");for(let t=0;t<e.length;t++)if(e[t]?.classList.contains("sp-card--focused"))return t;return -1}function St(o,e){let t=o.querySelectorAll(".sp-card");if(t.length===0)return;for(let i of t)i.classList.remove("sp-card--focused");let s=Math.max(0,Math.min(e,t.length-1)),n=t[s];n&&(n.classList.add("sp-card--focused"),n.scrollIntoView({block:"nearest",behavior:"smooth"}),n.focus({preventScroll:true}));}var Le=[{keys:["J","K"],label:"shortcuts.navigate"},{keys:["R"],label:"shortcuts.resolve"},{keys:["D"],label:"shortcuts.delete"},{keys:["F","/"],label:"shortcuts.search"},{keys:["X"],label:"shortcuts.select"},{keys:["?"],label:"shortcuts.help"},{keys:["Esc"],label:"shortcuts.close"}],Mt=`
1524
+ /* ---- Help overlay backdrop ---- */
1525
+
1526
+ .sp-shortcuts-overlay {
1527
+ position: fixed;
1528
+ inset: 0;
1529
+ background: var(--sp-backdrop, rgba(15, 23, 42, 0.2));
1530
+ backdrop-filter: blur(var(--sp-blur));
1531
+ -webkit-backdrop-filter: blur(var(--sp-blur));
1532
+ display: flex;
1533
+ align-items: center;
1534
+ justify-content: center;
1535
+ z-index: 10;
1536
+ opacity: 0;
1537
+ pointer-events: none;
1538
+ transition: opacity 0.2s ease;
1539
+ }
1540
+
1541
+ .sp-shortcuts-overlay--visible {
1542
+ opacity: 1;
1543
+ pointer-events: auto;
1544
+ }
1545
+
1546
+ /* ---- Glassmorphism card ---- */
1547
+
1548
+ .sp-shortcuts-card {
1549
+ width: 380px;
1550
+ max-width: calc(100vw - 32px);
1551
+ padding: 24px 28px 20px;
1552
+ border-radius: 20px;
1553
+ background: var(--sp-glass-bg-heavy);
1554
+ backdrop-filter: blur(var(--sp-blur-heavy));
1555
+ -webkit-backdrop-filter: blur(var(--sp-blur-heavy));
1556
+ border: 1px solid var(--sp-glass-border);
1557
+ box-shadow: var(--sp-shadow-xl);
1558
+ font-family: var(--sp-font);
1559
+ position: relative;
1560
+ transform: scale(0.92) translateY(8px);
1561
+ transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
1562
+ }
1563
+
1564
+ .sp-shortcuts-overlay--visible .sp-shortcuts-card {
1565
+ transform: scale(1) translateY(0);
1566
+ }
1567
+
1568
+ /* ---- Title row ---- */
1569
+
1570
+ .sp-shortcuts-title {
1571
+ display: flex;
1572
+ align-items: center;
1573
+ gap: 8px;
1574
+ font-size: 16px;
1575
+ font-weight: 700;
1576
+ color: var(--sp-text);
1577
+ margin-bottom: 18px;
1578
+ }
1579
+
1580
+ .sp-shortcuts-title svg {
1581
+ width: 18px;
1582
+ height: 18px;
1583
+ color: var(--sp-text-secondary);
1584
+ flex-shrink: 0;
1585
+ }
1586
+
1587
+ /* ---- Close button ---- */
1588
+
1589
+ .sp-shortcuts-close {
1590
+ position: absolute;
1591
+ top: 16px;
1592
+ right: 16px;
1593
+ width: 28px;
1594
+ height: 28px;
1595
+ border-radius: 8px;
1596
+ border: none;
1597
+ background: transparent;
1598
+ color: var(--sp-text-tertiary);
1599
+ cursor: pointer;
1600
+ display: flex;
1601
+ align-items: center;
1602
+ justify-content: center;
1603
+ transition: background 0.15s ease, color 0.15s ease;
1604
+ }
1605
+
1606
+ .sp-shortcuts-close:hover {
1607
+ background: var(--sp-bg-hover);
1608
+ color: var(--sp-text);
1609
+ }
1610
+
1611
+ .sp-shortcuts-close svg {
1612
+ width: 14px;
1613
+ height: 14px;
1614
+ }
1615
+
1616
+ /* ---- Two-column grid ---- */
1617
+
1618
+ .sp-shortcuts-grid {
1619
+ display: flex;
1620
+ flex-direction: column;
1621
+ gap: 10px;
1622
+ }
1623
+
1624
+ .sp-shortcuts-row {
1625
+ display: flex;
1626
+ align-items: center;
1627
+ gap: 12px;
1628
+ }
1629
+
1630
+ .sp-shortcuts-keys {
1631
+ display: flex;
1632
+ align-items: center;
1633
+ gap: 4px;
1634
+ min-width: 80px;
1635
+ justify-content: flex-end;
1636
+ }
1637
+
1638
+ .sp-shortcuts-separator {
1639
+ font-size: 11px;
1640
+ color: var(--sp-text-tertiary);
1641
+ user-select: none;
1642
+ }
1643
+
1644
+ /* ---- Key badge (<kbd> styling) ---- */
1645
+
1646
+ .sp-kbd {
1647
+ display: inline-flex;
1648
+ align-items: center;
1649
+ justify-content: center;
1650
+ min-width: 28px;
1651
+ height: 26px;
1652
+ padding: 0 7px;
1653
+ border-radius: 6px;
1654
+ background: var(--sp-bg-hover);
1655
+ border: 1px solid var(--sp-border);
1656
+ box-shadow:
1657
+ inset 0 -1px 0 rgba(0, 0, 0, 0.08),
1658
+ 0 1px 2px rgba(0, 0, 0, 0.04);
1659
+ font-family: ui-monospace, "SF Mono", "Cascadia Code", "Segoe UI Mono", Menlo, monospace;
1660
+ font-size: 12px;
1661
+ font-weight: 600;
1662
+ color: var(--sp-text);
1663
+ text-align: center;
1664
+ line-height: 1;
1665
+ user-select: none;
1666
+ }
1667
+
1668
+ /* ---- Description text ---- */
1669
+
1670
+ .sp-shortcuts-desc {
1671
+ font-size: 13px;
1672
+ color: var(--sp-text-secondary);
1673
+ line-height: 1.3;
1674
+ }
1675
+
1676
+ /* ---- Hint button (bottom-right of panel) ---- */
1677
+
1678
+ .sp-shortcuts-hint {
1679
+ width: 24px;
1680
+ height: 24px;
1681
+ border-radius: var(--sp-radius-full);
1682
+ border: 1px solid var(--sp-border);
1683
+ background: var(--sp-bg-hover);
1684
+ color: var(--sp-text-tertiary);
1685
+ font-family: ui-monospace, "SF Mono", "Cascadia Code", "Segoe UI Mono", Menlo, monospace;
1686
+ font-size: 12px;
1687
+ font-weight: 700;
1688
+ line-height: 1;
1689
+ cursor: pointer;
1690
+ display: flex;
1691
+ align-items: center;
1692
+ justify-content: center;
1693
+ transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
1694
+ position: absolute;
1695
+ bottom: 12px;
1696
+ right: 12px;
1697
+ }
1698
+
1699
+ .sp-shortcuts-hint:hover {
1700
+ background: var(--sp-accent-light);
1701
+ color: var(--sp-accent);
1702
+ border-color: var(--sp-accent);
1703
+ }
1704
+
1705
+ .sp-shortcuts-hint::after {
1706
+ content: attr(aria-label);
1707
+ position: absolute;
1708
+ bottom: calc(100% + 6px);
1709
+ right: 0;
1710
+ padding: 4px 8px;
1711
+ border-radius: 6px;
1712
+ background: var(--sp-glass-bg-heavy);
1713
+ border: 1px solid var(--sp-glass-border);
1714
+ box-shadow: var(--sp-shadow-sm);
1715
+ font-family: var(--sp-font);
1716
+ font-size: 11px;
1717
+ font-weight: 500;
1718
+ color: var(--sp-text-secondary);
1719
+ white-space: nowrap;
1720
+ opacity: 0;
1721
+ pointer-events: none;
1722
+ transform: translateY(4px);
1723
+ transition: opacity 0.15s ease, transform 0.15s ease;
1724
+ }
1725
+
1726
+ .sp-shortcuts-hint:hover::after {
1727
+ opacity: 1;
1728
+ transform: translateY(0);
1729
+ }
1730
+
1731
+ /* ---- Card focus highlight (navigation) ---- */
1732
+
1733
+ .sp-card--focused {
1734
+ outline: 2px solid var(--sp-accent);
1735
+ outline-offset: -2px;
1736
+ border-radius: inherit;
1737
+ }
1738
+
1739
+ /* ---- Reduced motion ---- */
1740
+
1741
+ @media (prefers-reduced-motion: reduce) {
1742
+ .sp-shortcuts-overlay,
1743
+ .sp-shortcuts-card,
1744
+ .sp-shortcuts-close,
1745
+ .sp-shortcuts-hint,
1746
+ .sp-shortcuts-hint::after {
1747
+ transition-duration: 0.01ms !important;
1748
+ }
1749
+ }
1750
+ `,Ae='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',X=class{constructor(e,t,s){this.t=s;this.keyMap=new Map([["j",()=>t.onNavigate("down")],["k",()=>t.onNavigate("up")],["r",()=>t.onResolve()],["d",()=>t.onDelete()],["f",()=>t.onFocusSearch()],["/",()=>t.onFocusSearch()],["x",()=>t.onToggleSelect()],["?",()=>this.toggleHelp()]]),this.helpOverlay=this.buildOverlay(),this.hintButton=this.buildHintButton(),this.boundHandler=n=>this.handleKeydown(n);}t;helpOverlay;hintButton;keyMap;boundHandler;shadowRoot=null;enabled=false;helpVisible=false;destroyed=false;enable(e){if(this.destroyed||this.enabled)return;e&&(this.shadowRoot=e),(this.shadowRoot??document).addEventListener("keydown",this.boundHandler),this.enabled=true;}disable(){if(!this.enabled)return;(this.shadowRoot??document).removeEventListener("keydown",this.boundHandler),this.enabled=false,this.helpVisible&&this.hideHelp();}toggleHelp(){this.helpVisible?this.hideHelp():this.showHelp();}destroy(){this.destroyed||(this.disable(),this.helpOverlay.remove(),this.hintButton.remove(),this.destroyed=true);}handleKeydown(e){if(e.key==="Escape"){this.helpVisible&&(e.preventDefault(),e.stopPropagation(),this.hideHelp());return}if(this.helpVisible)return;let t=e.composedPath()[0];if(t){let n=t.tagName?.toLowerCase();if(n==="input"||n==="textarea"||n==="select"||t.isContentEditable)return}if(e.ctrlKey||e.altKey||e.metaKey)return;let s=this.keyMap.get(e.key);s&&(e.preventDefault(),e.stopPropagation(),s());}showHelp(){this.helpVisible=true,this.helpOverlay.classList.add("sp-shortcuts-overlay--visible"),this.helpOverlay.querySelector(".sp-shortcuts-close")?.focus();}hideHelp(){this.helpVisible=false,this.helpOverlay.classList.remove("sp-shortcuts-overlay--visible");}buildOverlay(){let e=r("div",{class:"sp-shortcuts-overlay"});e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.t("shortcuts.title")),e.addEventListener("click",d=>{d.target===e&&this.hideHelp();});let t=r("div",{class:"sp-shortcuts-card"}),s=r("div",{class:"sp-shortcuts-title"});s.appendChild(c(Me));let n=r("span");a(n,this.t("shortcuts.title")),s.appendChild(n),t.appendChild(s);let i=document.createElement("button");i.className="sp-shortcuts-close",i.setAttribute("aria-label",this.t("shortcuts.close")),i.appendChild(c(Ae)),i.addEventListener("click",()=>this.hideHelp()),t.appendChild(i);let l=r("div",{class:"sp-shortcuts-grid"});for(let d of Le){let p=r("div",{class:"sp-shortcuts-row"}),u=r("div",{class:"sp-shortcuts-keys"});d.keys.forEach((v,f)=>{if(f>0){let g=r("span",{class:"sp-shortcuts-separator"});a(g,"/"),u.appendChild(g);}let m=r("span",{class:"sp-kbd"});a(m,v),u.appendChild(m);});let h=r("span",{class:"sp-shortcuts-desc"});a(h,this.t(d.label)),p.appendChild(u),p.appendChild(h),l.appendChild(p);}return t.appendChild(l),e.appendChild(t),e}buildHintButton(){let e=document.createElement("button");return e.className="sp-shortcuts-hint",e.setAttribute("aria-label",this.t("shortcuts.hint")),a(e,"?"),e.addEventListener("click",t=>{t.stopPropagation(),this.toggleHelp();}),e}};export{st as A,ot as B,nt as C,at as D,P as E,dt as F,I as G,gt as H,Y as I,xt as J,mt as K,ft as L,q as M,yt as N,wt as O,W as P,Tt as Q,St as R,Mt as S,X as T,c as a,r as b,a as c,L as d,Re as e,Oe as f,Fe as g,Ne as h,je as i,_e as j,De as k,$e as l,Pe as m,ze as n,Ie as o,Ve as p,Ge as q,Ue as r,Ye as s,Ke as t,qe as u,Qe as v,Xe as w,A as x,N as y,Je as z};//# sourceMappingURL=chunk-OTJZRTBK.js.map
1751
+ //# sourceMappingURL=chunk-OTJZRTBK.js.map