review-lens-react 0.2.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,119 +1,153 @@
1
- import { jsx as i, jsxs as o, Fragment as ie } from "react/jsx-runtime";
2
- import { createContext as st, useMemo as re, useState as k, useCallback as W, useEffect as _, useContext as ot, useRef as We, useLayoutEffect as lt } from "react";
3
- const ct = [
1
+ import { jsx as i, jsxs as o, Fragment as ae } from "react/jsx-runtime";
2
+ import { createContext as mt, useMemo as se, useState as N, useCallback as W, useEffect as B, useContext as pt, useRef as re, useLayoutEffect as gt } from "react";
3
+ const Be = [
4
4
  "https://www.googleapis.com/auth/spreadsheets",
5
5
  "https://www.googleapis.com/auth/userinfo.email"
6
- ].join(" "), dt = "https://www.googleapis.com/oauth2/v3/userinfo";
7
- function ht(e) {
8
- const t = e.feedbackSheetName ?? "Feedback", n = e.messagesSheetName ?? "Messages", r = e.usersSheetName ?? "Users";
9
- let s, c;
10
- async function g() {
11
- return s ?? (s = St(e.googleClientId)), s;
6
+ ], ft = "https://www.googleapis.com/auth/gmail.send", wt = "https://www.googleapis.com/oauth2/v3/userinfo", bt = "https://gmail.googleapis.com/gmail/v1/users/me/messages/send";
7
+ function vt(e) {
8
+ const t = e.feedbackSheetName ?? "Feedback", n = e.messagesSheetName ?? "Messages", r = e.usersSheetName ?? "Users", s = e.enableEmailNotifications ? [...Be, ft].join(" ") : Be.join(" ");
9
+ let c, h;
10
+ async function w() {
11
+ return c ?? (c = At(e.googleClientId, s)), c;
12
12
  }
13
- async function f(d, v) {
14
- const p = await g(), b = await fetch(
15
- `https://sheets.googleapis.com/v4/spreadsheets/${e.spreadsheetId}${d}`,
13
+ async function p(g, f, m) {
14
+ const S = await w(), x = await fetch(
15
+ `https://sheets.googleapis.com/v4/spreadsheets/${g}${f}`,
16
16
  {
17
- ...v,
17
+ ...m,
18
18
  headers: {
19
- Authorization: `Bearer ${p}`,
19
+ Authorization: `Bearer ${S}`,
20
20
  "Content-Type": "application/json",
21
- ...v == null ? void 0 : v.headers
21
+ ...m == null ? void 0 : m.headers
22
22
  }
23
23
  }
24
24
  );
25
- if (!b.ok)
26
- throw new Error(`Google Sheets request failed with ${b.status}`);
27
- return b.json();
25
+ if (!x.ok)
26
+ throw new Error(`Google Sheets request failed with ${x.status}`);
27
+ return x.json();
28
28
  }
29
- async function u(d) {
30
- return (await f(
31
- `/values/${encodeURIComponent(d)}`
29
+ async function b(g, f) {
30
+ return (await p(
31
+ g,
32
+ `/values/${encodeURIComponent(f)}`
32
33
  )).values ?? [];
33
34
  }
34
35
  return {
35
36
  async getCurrentUser() {
36
- if (!c) {
37
- const d = await g(), v = await fetch(dt, {
38
- headers: { Authorization: `Bearer ${d}` }
37
+ if (!h) {
38
+ const g = await w(), f = await fetch(wt, {
39
+ headers: { Authorization: `Bearer ${g}` }
39
40
  });
40
- if (!v.ok)
41
- throw new Error(`Google userinfo request failed with ${v.status}`);
42
- c = (await v.json()).email;
41
+ if (!f.ok)
42
+ throw new Error(`Google userinfo request failed with ${f.status}`);
43
+ h = (await f.json()).email;
43
44
  }
44
- if (!c)
45
+ if (!h)
45
46
  throw new Error("Google account did not return an email address");
46
- return { email: c };
47
+ return { email: h };
47
48
  },
48
- async getPermissions(d) {
49
- const [{ email: v }, p] = await Promise.all([this.getCurrentUser(), u(r)]), b = ce(p), E = v.toLowerCase(), x = b.find(
50
- (A) => {
51
- var h;
52
- return ((h = A.email) == null ? void 0 : h.toLowerCase()) === E && A.active !== "false" && (!A.projectKey || A.projectKey === d);
49
+ async getPermissions(g) {
50
+ const [{ email: f }, m] = await Promise.all([
51
+ this.getCurrentUser(),
52
+ b(e.usersSpreadsheetId, r)
53
+ ]), S = ue(m), x = f.toLowerCase(), E = S.find(
54
+ (l) => {
55
+ var A;
56
+ return ((A = l.email) == null ? void 0 : A.toLowerCase()) === x && l.active !== "false" && (!l.projectKey || l.projectKey === g);
53
57
  }
54
58
  );
55
- return gt((x == null ? void 0 : x.role) ?? "designer");
59
+ return Nt((E == null ? void 0 : E.role) ?? "designer");
56
60
  },
57
- async listFeedback(d) {
58
- return ce(await u(t)).map(Te).filter((p) => p !== null).filter(
59
- (p) => p.projectKey === d.projectKey && p.contentId === d.contentId && p.normalizedPath === d.normalizedPath
60
- ).sort((p, b) => b.createdAt.localeCompare(p.createdAt));
61
+ async listFeedback(g) {
62
+ return ue(await b(e.contentSpreadsheetId, t)).map(je).filter((m) => m !== null).filter(
63
+ (m) => m.projectKey === g.projectKey && m.contentId === g.contentId && m.normalizedPath === g.normalizedPath
64
+ ).sort((m, S) => S.createdAt.localeCompare(m.createdAt));
61
65
  },
62
- async createFeedback(d) {
63
- const v = (/* @__PURE__ */ new Date()).toISOString(), p = {
64
- ...d,
66
+ async createFeedback(g) {
67
+ const f = (/* @__PURE__ */ new Date()).toISOString(), m = {
68
+ ...g,
65
69
  id: crypto.randomUUID(),
66
70
  attachments: [],
67
- createdAt: v,
68
- updatedAt: v
71
+ createdAt: f,
72
+ updatedAt: f
69
73
  };
70
- return await f(`/values/${encodeURIComponent(t)}:append?valueInputOption=RAW`, {
71
- method: "POST",
72
- body: JSON.stringify({ values: [Ie(p)] })
73
- }), p;
74
+ return await p(
75
+ e.contentSpreadsheetId,
76
+ `/values/${encodeURIComponent(t)}:append?valueInputOption=RAW`,
77
+ {
78
+ method: "POST",
79
+ body: JSON.stringify({ values: [_e(m)] })
80
+ }
81
+ ), m;
74
82
  },
75
- async updateFeedback(d, v) {
76
- const p = await u(t), b = p[0] ?? Me, E = b.indexOf("id");
77
- if (E === -1)
83
+ async updateFeedback(g, f) {
84
+ const m = await b(e.contentSpreadsheetId, t), S = m[0] ?? Pe, x = S.indexOf("id");
85
+ if (x === -1)
78
86
  throw new Error(`Sheet ${t} is missing an id column`);
79
- const x = p.findIndex((w, C) => C > 0 && w[E] === d);
80
- if (x < 1)
81
- throw new Error(`Feedback ${d} was not found`);
82
- const A = (/* @__PURE__ */ new Date()).toISOString(), h = Te(De(b, p[x]));
83
- if (!h)
84
- throw new Error(`Feedback ${d} could not be parsed before updating`);
85
- const R = {
86
- ...h,
87
- ...v,
88
- updatedAt: A
89
- }, y = Ie(R);
90
- return await f(
91
- `/values/${encodeURIComponent(t)}!A${x + 1}:${yt(
92
- Me.length
93
- )}${x + 1}?valueInputOption=RAW`,
87
+ const E = m.findIndex((C, F) => F > 0 && C[x] === g);
88
+ if (E < 1)
89
+ throw new Error(`Feedback ${g} was not found`);
90
+ const l = (/* @__PURE__ */ new Date()).toISOString(), A = je(Ke(S, m[E]));
91
+ if (!A)
92
+ throw new Error(`Feedback ${g} could not be parsed before updating`);
93
+ const v = {
94
+ ...A,
95
+ ...f,
96
+ updatedAt: l
97
+ }, y = _e(v);
98
+ return await p(
99
+ e.contentSpreadsheetId,
100
+ `/values/${encodeURIComponent(t)}!A${E + 1}:${Ft(
101
+ Pe.length
102
+ )}${E + 1}?valueInputOption=RAW`,
94
103
  {
95
104
  method: "PUT",
96
105
  body: JSON.stringify({ values: [y] })
97
106
  }
98
- ), R;
107
+ ), v;
99
108
  },
100
- async listMessages(d) {
101
- return ce(await u(n)).map(mt).filter((p) => p !== null).filter((p) => p.feedbackId === d).sort((p, b) => p.createdAt.localeCompare(b.createdAt));
109
+ async listMessages(g) {
110
+ return ue(await b(e.contentSpreadsheetId, n)).map(kt).filter((m) => m !== null).filter((m) => m.feedbackId === g).sort((m, S) => m.createdAt.localeCompare(S.createdAt));
102
111
  },
103
- async createMessage(d) {
104
- const v = {
105
- ...d,
112
+ async createMessage(g) {
113
+ const f = {
114
+ ...g,
106
115
  id: crypto.randomUUID(),
107
116
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
108
117
  };
109
- return await f(`/values/${encodeURIComponent(n)}:append?valueInputOption=RAW`, {
118
+ return await p(
119
+ e.contentSpreadsheetId,
120
+ `/values/${encodeURIComponent(n)}:append?valueInputOption=RAW`,
121
+ {
122
+ method: "POST",
123
+ body: JSON.stringify({ values: [St(f)] })
124
+ }
125
+ ), f;
126
+ },
127
+ async sendEmail(g) {
128
+ if (!e.enableEmailNotifications || g.to.length === 0)
129
+ return;
130
+ const f = await w(), m = await this.getCurrentUser(), S = await fetch(bt, {
110
131
  method: "POST",
111
- body: JSON.stringify({ values: [pt(v)] })
112
- }), v;
132
+ headers: {
133
+ Authorization: `Bearer ${f}`,
134
+ "Content-Type": "application/json"
135
+ },
136
+ body: JSON.stringify({
137
+ raw: It({
138
+ from: m.email,
139
+ to: g.to,
140
+ subject: g.subject,
141
+ text: g.text
142
+ })
143
+ })
144
+ });
145
+ if (!S.ok)
146
+ throw new Error(`Gmail send request failed with ${S.status}`);
113
147
  }
114
148
  };
115
149
  }
116
- const Me = [
150
+ const Pe = [
117
151
  "id",
118
152
  "projectKey",
119
153
  "contentId",
@@ -142,8 +176,8 @@ const Me = [
142
176
  "fixedBy",
143
177
  "resolvedAt",
144
178
  "resolvedBy"
145
- ], ut = ["id", "feedbackId", "body", "authorEmail", "createdAt"];
146
- function Ie(e) {
179
+ ], yt = ["id", "feedbackId", "body", "authorEmail", "createdAt"];
180
+ function _e(e) {
147
181
  return [
148
182
  e.id,
149
183
  e.projectKey,
@@ -175,17 +209,17 @@ function Ie(e) {
175
209
  e.resolvedBy ?? ""
176
210
  ];
177
211
  }
178
- function pt(e) {
179
- return ut.map((t) => e[t]);
212
+ function St(e) {
213
+ return yt.map((t) => e[t]);
180
214
  }
181
- function ce(e) {
215
+ function ue(e) {
182
216
  const [t, ...n] = e;
183
- return t ? n.map((r) => De(t, r)) : [];
217
+ return t ? n.map((r) => Ke(t, r)) : [];
184
218
  }
185
- function De(e, t) {
219
+ function Ke(e, t) {
186
220
  return Object.fromEntries(e.map((n, r) => [n, t[r] ?? ""]));
187
221
  }
188
- function Te(e) {
222
+ function je(e) {
189
223
  return e.id ? {
190
224
  id: e.id,
191
225
  projectKey: e.projectKey,
@@ -194,24 +228,24 @@ function Te(e) {
194
228
  originalUrl: e.originalUrl,
195
229
  selector: e.selector,
196
230
  selectorStrategy: e.selectorStrategy === "stable-attribute" ? "stable-attribute" : "css-path",
197
- elementFingerprint: he(e.elementFingerprintJson, {
231
+ elementFingerprint: fe(e.elementFingerprintJson, {
198
232
  tagName: "",
199
233
  width: 0,
200
234
  height: 0
201
235
  }),
202
- createdCssSnapshot: Re(e.createdCssSnapshotJson),
203
- fixedCssSnapshot: e.fixedCssSnapshotJson ? Re(e.fixedCssSnapshotJson) : void 0,
236
+ createdCssSnapshot: Ue(e.createdCssSnapshotJson),
237
+ fixedCssSnapshot: e.fixedCssSnapshotJson ? Ue(e.fixedCssSnapshotJson) : void 0,
204
238
  comment: e.comment,
205
- status: ft(e.status),
206
- severity: bt(e.severity),
207
- category: vt(e.category),
239
+ status: Ct(e.status),
240
+ severity: xt(e.severity),
241
+ category: Et(e.category),
208
242
  assigneeEmail: e.assigneeEmail || void 0,
209
243
  viewportWidth: Number(e.viewportWidth) || 0,
210
244
  viewportHeight: Number(e.viewportHeight) || 0,
211
- viewportPreset: wt(e.viewportPreset),
245
+ viewportPreset: Lt(e.viewportPreset),
212
246
  screenshotUrl: e.screenshotUrl || void 0,
213
247
  screenshotThumbnailUrl: e.screenshotThumbnailUrl || void 0,
214
- attachments: he(e.attachmentJson, []),
248
+ attachments: fe(e.attachmentJson, []),
215
249
  authorEmail: e.authorEmail,
216
250
  createdAt: e.createdAt,
217
251
  updatedAt: e.updatedAt,
@@ -221,7 +255,7 @@ function Te(e) {
221
255
  resolvedBy: e.resolvedBy || void 0
222
256
  } : null;
223
257
  }
224
- function mt(e) {
258
+ function kt(e) {
225
259
  return !e.id || !e.feedbackId ? null : {
226
260
  id: e.id,
227
261
  feedbackId: e.feedbackId,
@@ -230,15 +264,15 @@ function mt(e) {
230
264
  createdAt: e.createdAt
231
265
  };
232
266
  }
233
- function he(e, t) {
267
+ function fe(e, t) {
234
268
  try {
235
269
  return e ? JSON.parse(e) : t;
236
270
  } catch {
237
271
  return t;
238
272
  }
239
273
  }
240
- function Re(e) {
241
- const t = he(e, {});
274
+ function Ue(e) {
275
+ const t = fe(e, {});
242
276
  return {
243
277
  margin: t.margin ?? "",
244
278
  marginTop: t.marginTop ?? "",
@@ -265,22 +299,22 @@ function Re(e) {
265
299
  height: t.height ?? 0
266
300
  };
267
301
  }
268
- function gt(e) {
302
+ function Nt(e) {
269
303
  return e === "admin" ? ["create", "read", "reply", "update", "assign"] : e === "developer" ? ["read", "reply", "update", "assign"] : ["create", "read", "reply"];
270
304
  }
271
- function ft(e) {
305
+ function Ct(e) {
272
306
  return e === "in_progress" || e === "needs_clarification" || e === "fixed" || e === "wontfix" || e === "resolved" ? e : "open";
273
307
  }
274
- function bt(e) {
308
+ function xt(e) {
275
309
  return e === "low" || e === "high" ? e : "medium";
276
310
  }
277
- function vt(e) {
311
+ function Et(e) {
278
312
  return e === "visual" || e === "copy" || e === "accessibility" || e === "responsive" ? e : "bug";
279
313
  }
280
- function wt(e) {
314
+ function Lt(e) {
281
315
  return e === "mobile" || e === "tablet" || e === "desktop" ? e : "custom";
282
316
  }
283
- function yt(e) {
317
+ function Ft(e) {
284
318
  let t = e, n = "";
285
319
  for (; t > 0; ) {
286
320
  const r = (t - 1) % 26;
@@ -288,24 +322,24 @@ function yt(e) {
288
322
  }
289
323
  return n;
290
324
  }
291
- async function St(e) {
292
- return await kt(), new Promise((t, n) => {
293
- var s;
294
- const r = (s = window.google) == null ? void 0 : s.accounts.oauth2.initTokenClient({
325
+ async function At(e, t) {
326
+ return await Rt(), new Promise((n, r) => {
327
+ var c;
328
+ const s = (c = window.google) == null ? void 0 : c.accounts.oauth2.initTokenClient({
295
329
  client_id: e,
296
- scope: ct,
297
- callback: (c) => {
298
- if (c.error || !c.access_token) {
299
- n(new Error(c.error ?? "Google OAuth did not return an access token"));
330
+ scope: t,
331
+ callback: (h) => {
332
+ if (h.error || !h.access_token) {
333
+ r(new Error(h.error ?? "Google OAuth did not return an access token"));
300
334
  return;
301
335
  }
302
- t(c.access_token);
336
+ n(h.access_token);
303
337
  }
304
338
  });
305
- r == null || r.requestAccessToken({ prompt: "" });
339
+ s == null || s.requestAccessToken({ prompt: "" });
306
340
  });
307
341
  }
308
- function kt() {
342
+ function Rt() {
309
343
  var e;
310
344
  return (e = window.google) != null && e.accounts.oauth2 ? Promise.resolve() : new Promise((t, n) => {
311
345
  const r = document.querySelector(
@@ -321,136 +355,245 @@ function kt() {
321
355
  s.src = "https://accounts.google.com/gsi/client", s.async = !0, s.defer = !0, s.onload = () => t(), s.onerror = () => n(new Error("Google Identity failed to load")), document.head.append(s);
322
356
  });
323
357
  }
324
- function Ct(e) {
358
+ function It(e) {
359
+ const t = [
360
+ `From: ${e.from}`,
361
+ `To: ${e.to.join(", ")}`,
362
+ `Subject: ${e.subject}`,
363
+ "Content-Type: text/plain; charset=UTF-8",
364
+ "",
365
+ e.text
366
+ ].join(`\r
367
+ `);
368
+ return Mt(t);
369
+ }
370
+ function Mt(e) {
371
+ const t = new TextEncoder().encode(e);
372
+ let n = "";
373
+ return t.forEach((r) => {
374
+ n += String.fromCharCode(r);
375
+ }), btoa(n).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
376
+ }
377
+ function $t(e) {
325
378
  return new URL(e, window.location.href).pathname.replace(/\/+$/, "") || "/";
326
379
  }
327
- const ze = st(null);
328
- function Qt({ config: e, children: t }) {
329
- const n = re(() => e.adapter ? e.adapter : ht({
330
- googleClientId: Be(e.googleClientId, "googleClientId"),
331
- spreadsheetId: Be(e.spreadsheetId, "spreadsheetId"),
332
- feedbackSheetName: e.sheetName ?? "Feedback"
333
- }), [e.adapter, e.googleClientId, e.sheetName, e.spreadsheetId]), r = e.currentUrl ?? window.location.href, s = (e.normalizeUrl ?? Ct)(r), [c, g] = k(), [f, u] = k([]), [d, v] = k([]), p = W(async () => {
334
- const y = await n.listFeedback({
380
+ const Je = mt(null);
381
+ function wn({ config: e, children: t }) {
382
+ const n = se(() => e.adapter ? e.adapter : vt({
383
+ googleClientId: me(e.googleClientId, "googleClientId"),
384
+ contentSpreadsheetId: me(e.contentSpreadsheetId, "contentSpreadsheetId"),
385
+ usersSpreadsheetId: me(e.usersSpreadsheetId, "usersSpreadsheetId"),
386
+ feedbackSheetName: e.sheetName ?? "Feedback",
387
+ enableEmailNotifications: Oe(e)
388
+ }), [
389
+ e.adapter,
390
+ e.contentSpreadsheetId,
391
+ e.emailNotifications,
392
+ e.googleClientId,
393
+ e.sheetName,
394
+ e.usersSpreadsheetId
395
+ ]), r = e.currentUrl ?? window.location.href, s = (e.normalizeUrl ?? $t)(r), [c, h] = N(), [w, p] = N([]), [b, g] = N([]), f = W(async () => {
396
+ const v = await n.listFeedback({
335
397
  projectKey: e.projectKey,
336
398
  contentId: e.contentId,
337
399
  normalizedPath: s
338
400
  });
339
- v(y);
401
+ g(v);
340
402
  }, [n, e.contentId, e.projectKey, s]);
341
- _(() => {
342
- let y = !0;
343
- async function w() {
344
- const [C, B] = await Promise.all([
403
+ B(() => {
404
+ let v = !0;
405
+ async function y() {
406
+ const [C, F] = await Promise.all([
345
407
  n.getCurrentUser(),
346
408
  n.getPermissions(e.projectKey)
347
409
  ]);
348
- y && (g(C), u(B), await p());
410
+ v && (h(C), p(F), await f());
349
411
  }
350
- return w(), () => {
351
- y = !1;
412
+ return y(), () => {
413
+ v = !1;
352
414
  };
353
- }, [n, e.projectKey, p]);
354
- const b = W(
355
- async (y) => {
356
- const w = await n.createFeedback(y);
357
- return v((C) => [w, ...C]), w;
415
+ }, [n, e.projectKey, f]);
416
+ const m = W(
417
+ async (v) => {
418
+ const y = await n.createFeedback(v);
419
+ return g((C) => [y, ...C]), pe(e, n, {
420
+ actorEmail: (c == null ? void 0 : c.email) ?? v.authorEmail,
421
+ item: y,
422
+ kind: "created"
423
+ }), y;
358
424
  },
359
- [n]
360
- ), E = W(
361
- async (y, w) => {
362
- const C = await n.updateFeedback(y, w);
363
- return v(
364
- (B) => B.map((D) => D.id === y ? C : D)
365
- ), C;
425
+ [n, e, c == null ? void 0 : c.email]
426
+ ), S = W(
427
+ async (v, y) => {
428
+ const C = b.find((_) => _.id === v), F = await n.updateFeedback(v, y);
429
+ return g(
430
+ (_) => _.map((H) => H.id === v ? F : H)
431
+ ), pe(e, n, {
432
+ actorEmail: c == null ? void 0 : c.email,
433
+ item: F,
434
+ kind: Bt(y),
435
+ previousItem: C
436
+ }), F;
366
437
  },
367
- [n]
438
+ [n, e, c == null ? void 0 : c.email, b]
368
439
  ), x = W(
369
- (y) => n.listMessages(y),
370
- [n]
371
- ), A = W(
372
- (y) => n.createMessage(y),
440
+ (v) => n.listMessages(v),
373
441
  [n]
374
- ), h = W(
375
- async (y, w) => {
442
+ ), E = W(
443
+ async (v) => {
444
+ const y = await n.createMessage(v), C = b.find((F) => F.id === v.feedbackId);
445
+ return C && pe(e, n, {
446
+ actorEmail: v.authorEmail,
447
+ item: C,
448
+ kind: "reply",
449
+ replyBody: v.body
450
+ }), y;
451
+ },
452
+ [n, e, b]
453
+ ), l = W(
454
+ async (v, y) => {
376
455
  const C = e.uploadAttachment ?? n.uploadAttachment;
377
456
  if (!C)
378
457
  throw new Error("Review Lens attachment upload is not configured");
379
- return C(y, w);
458
+ return C(v, y);
380
459
  },
381
460
  [n, e]
382
- ), R = re(
461
+ ), A = se(
383
462
  () => ({
384
463
  config: e,
385
464
  adapter: n,
386
465
  currentUser: c,
387
- permissions: f,
388
- feedback: d,
466
+ permissions: w,
467
+ feedback: b,
389
468
  normalizedPath: s,
390
- refreshFeedback: p,
391
- createFeedback: b,
392
- updateFeedback: E,
469
+ refreshFeedback: f,
470
+ createFeedback: m,
471
+ updateFeedback: S,
393
472
  listMessages: x,
394
- createMessage: A,
395
- uploadAttachment: h
473
+ createMessage: E,
474
+ uploadAttachment: l
396
475
  }),
397
476
  [
398
477
  n,
399
478
  e,
400
- b,
479
+ m,
401
480
  c,
402
- d,
481
+ b,
403
482
  s,
483
+ w,
404
484
  f,
405
- p,
406
- E,
485
+ S,
407
486
  x,
408
- A,
409
- h
487
+ E,
488
+ l
410
489
  ]
411
490
  );
412
- return /* @__PURE__ */ i(ze.Provider, { value: R, children: t });
491
+ return /* @__PURE__ */ i(Je.Provider, { value: A, children: t });
413
492
  }
414
- function Nt() {
415
- const e = ot(ze);
493
+ function Tt() {
494
+ const e = pt(Je);
416
495
  if (!e)
417
496
  throw new Error("useReviewLens must be used inside ReviewLensProvider");
418
497
  return e;
419
498
  }
420
- function Be(e, t) {
499
+ function me(e, t) {
421
500
  if (!e)
422
501
  throw new Error(`review-lens-react requires config.${t} when no adapter is provided`);
423
502
  return e;
424
503
  }
425
- const xt = [
504
+ function Oe(e) {
505
+ return typeof e.emailNotifications == "object" ? e.emailNotifications.enabled !== !1 : !!e.emailNotifications;
506
+ }
507
+ function Bt(e) {
508
+ return e.status === "resolved" ? "resolved" : e.status === "fixed" || e.fixedAt || e.fixedBy ? "fixed" : e.status ? "status" : "assigneeEmail" in e ? "assigned" : "updated";
509
+ }
510
+ async function pe(e, t, n) {
511
+ if (!Oe(e) || !t.sendEmail)
512
+ return;
513
+ const r = Pt(n);
514
+ if (r.length !== 0)
515
+ try {
516
+ await t.sendEmail({
517
+ to: r,
518
+ subject: _t(e, n),
519
+ text: jt(n)
520
+ });
521
+ } catch (s) {
522
+ console.warn("Review Lens email notification failed", s);
523
+ }
524
+ }
525
+ function Pt(e) {
526
+ var n;
527
+ const t = /* @__PURE__ */ new Set();
528
+ return t.add(e.item.authorEmail), (n = e.previousItem) != null && n.assigneeEmail && t.add(e.previousItem.assigneeEmail), e.item.assigneeEmail && t.add(e.item.assigneeEmail), [...t].filter((r) => {
529
+ var s;
530
+ return r ? r.toLowerCase() !== ((s = e.actorEmail) == null ? void 0 : s.toLowerCase()) : !1;
531
+ });
532
+ }
533
+ function _t(e, t) {
534
+ return `${(typeof e.emailNotifications == "object" ? e.emailNotifications : {}).subjectPrefix ?? "Review Lens"}: ${qe(t)}`;
535
+ }
536
+ function jt(e) {
537
+ const t = [
538
+ "[Review Lens]",
539
+ qe(e),
540
+ Ut(e),
541
+ "",
542
+ `Review: ${e.item.comment}`,
543
+ `Status: ${Ve(e.item.status)}`,
544
+ `Author: ${e.item.authorEmail}`,
545
+ `Assignee: ${e.item.assigneeEmail ?? "Unassigned"}`,
546
+ `Link: ${Wt(e.item)}`
547
+ ];
548
+ return e.replyBody && t.splice(2, 0, `Reply: ${e.replyBody}`, ""), t.join(`
549
+ `);
550
+ }
551
+ function Ut(e) {
552
+ return e.actorEmail ? `Sent by Review Lens on behalf of ${e.actorEmail}.` : "Sent by Review Lens on behalf of the signed-in Google user.";
553
+ }
554
+ function qe(e) {
555
+ return e.kind === "created" ? "New review feedback" : e.kind === "assigned" ? `Review assignment changed to ${e.item.assigneeEmail ?? "unassigned"}` : e.kind === "status" ? `Review status changed to ${Ve(e.item.status)}` : e.kind === "fixed" ? "Review marked fixed" : e.kind === "resolved" ? "Review resolved" : e.kind === "reply" ? "New review reply" : "Review updated";
556
+ }
557
+ function Wt(e) {
558
+ try {
559
+ const t = new URL(e.originalUrl);
560
+ return t.searchParams.set("reviewLensFeedback", e.id), t.toString();
561
+ } catch {
562
+ return e.originalUrl;
563
+ }
564
+ }
565
+ function Ve(e) {
566
+ return e.replace(/_/g, " ");
567
+ }
568
+ const Dt = [
426
569
  "data-review-id",
427
570
  "data-testid",
428
571
  "data-test-id",
429
572
  "aria-label",
430
573
  "name"
431
574
  ];
432
- function X(e) {
433
- const t = e.getBoundingClientRect(), n = Et(e);
575
+ function Q(e) {
576
+ const t = e.getBoundingClientRect(), n = zt(e);
434
577
  return {
435
578
  selector: n.selector,
436
579
  selectorStrategy: n.strategy,
437
- fingerprint: Lt(e, t),
438
- cssSnapshot: Ft(e, t),
580
+ fingerprint: Kt(e, t),
581
+ cssSnapshot: Jt(e, t),
439
582
  rect: t
440
583
  };
441
584
  }
442
- function Et(e) {
443
- for (const t of xt) {
585
+ function zt(e) {
586
+ for (const t of Dt) {
444
587
  const n = e.getAttribute(t);
445
588
  if (n)
446
589
  return {
447
- selector: `[${t}="${$e(n)}"]`,
590
+ selector: `[${t}="${We(n)}"]`,
448
591
  strategy: "stable-attribute"
449
592
  };
450
593
  }
451
- return e.id ? { selector: `#${$e(e.id)}`, strategy: "stable-attribute" } : { selector: At(e), strategy: "css-path" };
594
+ return e.id ? { selector: `#${We(e.id)}`, strategy: "stable-attribute" } : { selector: Ht(e), strategy: "css-path" };
452
595
  }
453
- function At(e) {
596
+ function Ht(e) {
454
597
  const t = [];
455
598
  let n = e;
456
599
  for (; n && n.nodeType === Node.ELEMENT_NODE && n !== document.body; ) {
@@ -459,14 +602,14 @@ function At(e) {
459
602
  t.unshift(s);
460
603
  break;
461
604
  }
462
- const c = n.tagName, g = Array.from(r.children).filter(
463
- (u) => u.tagName === c
464
- ), f = g.indexOf(n) + 1;
465
- t.unshift(g.length > 1 ? `${s}:nth-of-type(${f})` : s), n = r;
605
+ const c = n.tagName, h = Array.from(r.children).filter(
606
+ (p) => p.tagName === c
607
+ ), w = h.indexOf(n) + 1;
608
+ t.unshift(h.length > 1 ? `${s}:nth-of-type(${w})` : s), n = r;
466
609
  }
467
610
  return t.join(" > ");
468
611
  }
469
- function Lt(e, t) {
612
+ function Kt(e, t) {
470
613
  var n;
471
614
  return {
472
615
  tagName: e.tagName.toLowerCase(),
@@ -478,15 +621,15 @@ function Lt(e, t) {
478
621
  height: Math.round(t.height)
479
622
  };
480
623
  }
481
- function Ft(e, t) {
624
+ function Jt(e, t) {
482
625
  const n = window.getComputedStyle(e);
483
626
  return {
484
- margin: de(n.marginTop, n.marginRight, n.marginBottom, n.marginLeft),
627
+ margin: ge(n.marginTop, n.marginRight, n.marginBottom, n.marginLeft),
485
628
  marginTop: n.marginTop,
486
629
  marginRight: n.marginRight,
487
630
  marginBottom: n.marginBottom,
488
631
  marginLeft: n.marginLeft,
489
- padding: de(
632
+ padding: ge(
490
633
  n.paddingTop,
491
634
  n.paddingRight,
492
635
  n.paddingBottom,
@@ -496,7 +639,7 @@ function Ft(e, t) {
496
639
  paddingRight: n.paddingRight,
497
640
  paddingBottom: n.paddingBottom,
498
641
  paddingLeft: n.paddingLeft,
499
- border: de(
642
+ border: ge(
500
643
  n.borderTopWidth,
501
644
  n.borderRightWidth,
502
645
  n.borderBottomWidth,
@@ -516,265 +659,322 @@ function Ft(e, t) {
516
659
  height: Math.round(t.height)
517
660
  };
518
661
  }
519
- function de(e, t, n, r) {
662
+ function ge(e, t, n, r) {
520
663
  return e === t && t === n && n === r ? e : `${e} ${t} ${n} ${r}`;
521
664
  }
522
- function $e(e) {
665
+ function We(e) {
523
666
  return typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(e) : e.replace(/["\\]/g, "\\$&");
524
667
  }
525
- const Mt = [
668
+ function Ot({ className: e, title: t = "Review Lens logo" }) {
669
+ return /* @__PURE__ */ o(
670
+ "svg",
671
+ {
672
+ className: e,
673
+ role: "img",
674
+ "aria-label": t,
675
+ viewBox: "0 0 40 40",
676
+ fill: "none",
677
+ xmlns: "http://www.w3.org/2000/svg",
678
+ children: [
679
+ /* @__PURE__ */ i("rect", { x: "4", y: "6", width: "28", height: "28", rx: "8", fill: "#171717" }),
680
+ /* @__PURE__ */ i(
681
+ "path",
682
+ {
683
+ d: "M13 15.5C14.5 13.4 17.1 12 20 12C23.9 12 27.3 14.5 28.7 18C27.3 21.5 23.9 24 20 24C17.1 24 14.5 22.6 13 20.5",
684
+ stroke: "#FFFFFF",
685
+ strokeWidth: "2.2",
686
+ strokeLinecap: "round",
687
+ strokeLinejoin: "round"
688
+ }
689
+ ),
690
+ /* @__PURE__ */ i("circle", { cx: "20", cy: "18", r: "3.4", fill: "#F97316" }),
691
+ /* @__PURE__ */ i(
692
+ "path",
693
+ {
694
+ d: "M28.5 26.5L34.5 32.5",
695
+ stroke: "#2563EB",
696
+ strokeWidth: "4",
697
+ strokeLinecap: "round"
698
+ }
699
+ ),
700
+ /* @__PURE__ */ i("circle", { cx: "31.8", cy: "29.8", r: "2.1", fill: "#FACC15", stroke: "#171717", strokeWidth: "1.4" })
701
+ ]
702
+ }
703
+ );
704
+ }
705
+ const qt = [
526
706
  { label: "Desktop", value: "desktop" },
527
707
  { label: "Tablet", value: "tablet" },
528
708
  { label: "Mobile", value: "mobile" }
529
- ], He = [
709
+ ], Ge = [
530
710
  "open",
531
711
  "in_progress",
532
712
  "needs_clarification",
533
713
  "fixed",
534
714
  "wontfix",
535
715
  "resolved"
536
- ], je = ["low", "medium", "high"], Oe = ["bug", "visual", "copy", "accessibility", "responsive"], ae = {
716
+ ], Ye = ["low", "medium", "high"], Xe = ["bug", "visual", "copy", "accessibility", "responsive"], oe = {
537
717
  open: "Open",
538
718
  in_progress: "In progress",
539
719
  needs_clarification: "Needs clarification",
540
720
  fixed: "Fixed",
541
721
  wontfix: "Won't fix",
542
722
  resolved: "Resolved"
543
- }, Q = {
723
+ }, Z = {
544
724
  low: "Low",
545
725
  medium: "Medium",
546
726
  high: "High"
547
- }, Z = {
727
+ }, ee = {
548
728
  bug: "Bug",
549
729
  visual: "Visual",
550
730
  copy: "Copy",
551
731
  accessibility: "Accessibility",
552
732
  responsive: "Responsive"
553
733
  };
554
- function Zt({
734
+ function bn({
555
735
  open: e,
556
736
  onOpenChange: t,
557
737
  placement: n = "top-right",
558
738
  showResolved: r = !1,
559
739
  syncSelectionToUrl: s = !1,
560
- responsivePresets: c = Mt
740
+ responsivePresets: c = qt
561
741
  }) {
562
- var Fe;
742
+ var Te;
563
743
  const {
564
- adapter: g,
565
- config: f,
566
- currentUser: u,
567
- feedback: d,
568
- normalizedPath: v,
569
- permissions: p,
570
- createFeedback: b,
571
- updateFeedback: E,
744
+ adapter: h,
745
+ config: w,
746
+ currentUser: p,
747
+ feedback: b,
748
+ normalizedPath: g,
749
+ permissions: f,
750
+ createFeedback: m,
751
+ updateFeedback: S,
572
752
  listMessages: x,
573
- createMessage: A,
574
- uploadAttachment: h
575
- } = Nt(), [R, y] = k(), [w, C] = k(), [B, D] = k(""), [ue, Je] = k("medium"), [pe, Ve] = k("visual"), [me, ge] = k(""), [fe, qe] = k(
576
- ((Fe = c[0]) == null ? void 0 : Fe.value) ?? "desktop"
577
- ), [S, H] = k(), [M, $] = k("review"), [Ge, be] = k(!1), [j, ve] = k("all"), [O, we] = k("all"), [K, ye] = k("all"), [J, Se] = k("all"), [V, ke] = k("all"), [Ye, Xe] = k(!1), [Qe, Ce] = k({}), [se, oe] = k(""), ee = We(null), I = !!u, T = p.includes("create"), Ne = p.includes("reply"), xe = p.includes("update"), Ze = p.includes("assign"), P = R ?? w, et = !!w, tt = !!(f.captureScreenshot && (f.uploadAttachment || g.uploadAttachment)), nt = re(() => {
578
- const a = d.map((m) => m.assigneeEmail).filter((m) => !!m);
579
- return u != null && u.email && a.push(u.email), Array.from(new Set(a)).sort((m, l) => m.localeCompare(l));
580
- }, [u == null ? void 0 : u.email, d]), L = re(
581
- () => d.filter((a) => r || a.status !== "resolved").filter((a) => j === "all" || a.status === j).filter((a) => O === "all" || a.severity === O).filter((a) => K === "all" || a.category === K).filter((a) => J === "all" || a.assigneeEmail === J).filter((a) => V === "all" || a.viewportPreset === V),
753
+ createMessage: E,
754
+ uploadAttachment: l
755
+ } = Tt(), [A, v] = N(), [y, C] = N(), [F, _] = N(""), [H, Ze] = N("medium"), [we, et] = N("visual"), [be, ve] = N(""), [ye, tt] = N(
756
+ ((Te = c[0]) == null ? void 0 : Te.value) ?? "desktop"
757
+ ), [k, K] = N(), [M, P] = N("review"), [nt, Se] = N(!1), [J, ke] = N("all"), [O, Ne] = N("all"), [q, Ce] = N("all"), [V, xe] = N("all"), [G, Ee] = N("all"), [it, rt] = N(!1), [at, Le] = N({}), [le, de] = N(""), te = re(null), Fe = re(e), ce = re(
758
+ s ? new URL(window.location.href).searchParams.get("reviewLensFeedback") : null
759
+ ), $ = !!p, T = f.includes("create"), Ae = f.includes("reply"), Re = f.includes("update"), st = f.includes("assign"), j = A ?? y, ot = !!y, lt = !!(w.captureScreenshot && (w.uploadAttachment || h.uploadAttachment)), dt = se(() => {
760
+ const a = b.map((u) => u.assigneeEmail).filter((u) => !!u);
761
+ return p != null && p.email && a.push(p.email), Array.from(new Set(a)).sort((u, d) => u.localeCompare(d));
762
+ }, [p == null ? void 0 : p.email, b]), R = se(
763
+ () => b.filter((a) => r || a.status !== "resolved").filter((a) => J === "all" || a.status === J).filter((a) => O === "all" || a.severity === O).filter((a) => q === "all" || a.category === q).filter((a) => V === "all" || a.assigneeEmail === V).filter((a) => G === "all" || a.viewportPreset === G),
582
764
  [
583
- J,
584
- K,
585
- d,
765
+ V,
766
+ q,
767
+ b,
586
768
  O,
587
769
  r,
588
- j,
589
- V
770
+ J,
771
+ G
590
772
  ]
591
- ), it = [
592
- j,
593
- O,
594
- K,
773
+ ), ct = [
595
774
  J,
596
- V
775
+ O,
776
+ q,
777
+ V,
778
+ G
597
779
  ].filter((a) => a !== "all").length;
598
- _(() => {
599
- e || (y(void 0), C(void 0), D(""), oe(""), $("review"));
600
- }, [e]), _(() => {
601
- I || (y(void 0), C(void 0));
602
- }, [I]), _(() => {
603
- !w || M !== "review" || window.requestAnimationFrame(() => {
604
- var a, m, l;
605
- (m = (a = ee.current) == null ? void 0 : a.scrollIntoView) == null || m.call(a, { block: "nearest" }), (l = ee.current) == null || l.focus();
780
+ B(() => {
781
+ if (e) {
782
+ Fe.current = !0;
783
+ return;
784
+ }
785
+ if (v(void 0), C(void 0), _(""), de(""), P("review"), s && Fe.current) {
786
+ const a = new URL(window.location.href);
787
+ a.searchParams.has("reviewLensFeedback") && (a.searchParams.delete("reviewLensFeedback"), window.history.replaceState({}, "", a));
788
+ }
789
+ }, [e, s]), B(() => {
790
+ $ || (v(void 0), C(void 0));
791
+ }, [$]), B(() => {
792
+ !y || M !== "review" || window.requestAnimationFrame(() => {
793
+ var a, u, d;
794
+ (u = (a = te.current) == null ? void 0 : a.scrollIntoView) == null || u.call(a, { block: "nearest" }), (d = te.current) == null || d.focus();
606
795
  });
607
- }, [w, M]), _(() => {
608
- if (!S)
796
+ }, [y, M]), B(() => {
797
+ if (!k)
609
798
  return;
610
799
  let a = !0;
611
- return x(S.id).then((m) => {
612
- a && Ce((l) => ({ ...l, [S.id]: m }));
800
+ return x(k.id).then((u) => {
801
+ a && Le((d) => ({ ...d, [k.id]: u }));
613
802
  }), () => {
614
803
  a = !1;
615
804
  };
616
- }, [x, S]), _(() => {
617
- if (!e || !s || S || d.length === 0)
805
+ }, [x, k]), B(() => {
806
+ if (!s || !ce.current || b.length === 0)
618
807
  return;
619
- const a = new URL(window.location.href).searchParams.get("reviewLensFeedback"), m = d.find((l) => l.id === a);
620
- m && q(m, { syncUrl: !1 });
621
- }, [d, e, S, s]), _(() => {
808
+ const a = b.find((u) => u.id === ce.current);
809
+ a && (ce.current = null, t == null || t(!0), D(a, { syncUrl: !1 }));
810
+ }, [b, s]), B(() => {
811
+ if (!e || !s || k || b.length === 0)
812
+ return;
813
+ const a = new URL(window.location.href).searchParams.get("reviewLensFeedback"), u = b.find((d) => d.id === a);
814
+ u && D(u, { syncUrl: !1 });
815
+ }, [b, e, k, s]), B(() => {
622
816
  if (!e)
623
817
  return;
624
- function a(l) {
625
- var N;
626
- if (l.key === "Shift" && be(!0), l.key === "Escape") {
627
- l.preventDefault(), t == null || t(!1);
818
+ function a(d) {
819
+ var L;
820
+ if (d.key === "Shift" && Se(!0), d.key === "Escape") {
821
+ d.preventDefault(), t == null || t(!1);
628
822
  return;
629
823
  }
630
- Jt(l.target) || ((l.key === "n" || l.key === "ArrowDown") && (l.preventDefault(), Ee(1)), (l.key === "p" || l.key === "ArrowUp") && (l.preventDefault(), Ee(-1)), l.key === "c" && (l.preventDefault(), $("review"), (N = ee.current) == null || N.focus()), l.key === "f" && S && xe && (l.preventDefault(), Le(S)));
824
+ hn(d.target) || ((d.key === "n" || d.key === "ArrowDown") && (d.preventDefault(), Ie(1)), (d.key === "p" || d.key === "ArrowUp") && (d.preventDefault(), Ie(-1)), d.key === "c" && (d.preventDefault(), P("review"), (L = te.current) == null || L.focus()), d.key === "f" && k && Re && (d.preventDefault(), $e(k)));
631
825
  }
632
- function m(l) {
633
- l.key === "Shift" && be(!1);
826
+ function u(d) {
827
+ d.key === "Shift" && Se(!1);
634
828
  }
635
- return window.addEventListener("keydown", a), window.addEventListener("keyup", m), () => {
636
- window.removeEventListener("keydown", a), window.removeEventListener("keyup", m);
829
+ return window.addEventListener("keydown", a), window.addEventListener("keyup", u), () => {
830
+ window.removeEventListener("keydown", a), window.removeEventListener("keyup", u);
637
831
  };
638
832
  });
639
- const le = W((a) => {
640
- const m = a.target instanceof Element ? a.target : null;
641
- if (m)
642
- return m.closest("[data-review-lens-ui]") ? null : m;
643
- const l = document.elementFromPoint(a.clientX, a.clientY);
644
- return !l || l.closest("[data-review-lens-ui]") ? null : l;
833
+ const he = W((a) => {
834
+ const u = a.target instanceof Element ? a.target : null;
835
+ if (u)
836
+ return u.closest("[data-review-lens-ui]") ? null : u;
837
+ const d = document.elementFromPoint(a.clientX, a.clientY);
838
+ return !d || d.closest("[data-review-lens-ui]") ? null : d;
645
839
  }, []);
646
- if (_(() => {
647
- if (!e || !I)
840
+ if (B(() => {
841
+ if (!e || !$)
648
842
  return;
649
- function a(l) {
650
- const N = le(l);
651
- y(N ? X(N) : void 0);
843
+ function a(d) {
844
+ const L = he(d);
845
+ v(L ? Q(L) : void 0);
652
846
  }
653
- function m(l) {
654
- const N = le(l);
655
- N && (l.preventDefault(), l.stopPropagation(), C(X(N)), $("review"));
847
+ function u(d) {
848
+ const L = he(d);
849
+ L && (d.preventDefault(), d.stopPropagation(), C(Q(L)), P("review"));
656
850
  }
657
- return window.addEventListener("mousemove", a, !0), window.addEventListener("click", m, !0), () => {
658
- window.removeEventListener("mousemove", a, !0), window.removeEventListener("click", m, !0);
851
+ return window.addEventListener("mousemove", a, !0), window.addEventListener("click", u, !0), () => {
852
+ window.removeEventListener("mousemove", a, !0), window.removeEventListener("click", u, !0);
659
853
  };
660
- }, [I, le, e]), !e)
854
+ }, [$, he, e]), !e)
661
855
  return null;
662
- function q(a, m = { syncUrl: !0 }) {
663
- var N;
664
- if (H(a), C(void 0), $("feedback"), s && m.syncUrl !== !1) {
665
- const te = new URL(window.location.href);
666
- te.searchParams.set("reviewLensFeedback", a.id), window.history.replaceState({}, "", te);
856
+ function D(a, u = { syncUrl: !0 }) {
857
+ var L;
858
+ if (K(a), C(void 0), P("feedback"), s && u.syncUrl !== !1) {
859
+ const ne = new URL(window.location.href);
860
+ ne.searchParams.set("reviewLensFeedback", a.id), window.history.replaceState({}, "", ne);
667
861
  }
668
- const l = z(a.selector);
669
- if (!l) {
670
- y(void 0);
862
+ const d = z(a.selector);
863
+ if (!d) {
864
+ v(void 0);
671
865
  return;
672
866
  }
673
- (N = l.scrollIntoView) == null || N.call(l, { behavior: "smooth", block: "center", inline: "center" }), window.requestAnimationFrame(() => {
674
- y(X(l));
867
+ (L = d.scrollIntoView) == null || L.call(d, { behavior: "smooth", block: "center", inline: "center" }), window.requestAnimationFrame(() => {
868
+ v(Q(d));
675
869
  });
676
870
  }
677
- function Ee(a) {
678
- if (L.length === 0)
871
+ function Ie(a) {
872
+ if (R.length === 0)
679
873
  return;
680
- const m = S ? L.findIndex((N) => N.id === S.id) : -1, l = m < 0 ? a > 0 ? 0 : L.length - 1 : (m + a + L.length) % L.length;
681
- q(L[l]);
874
+ const u = k ? R.findIndex((L) => L.id === k.id) : -1, d = u < 0 ? a > 0 ? 0 : R.length - 1 : (u + a + R.length) % R.length;
875
+ D(R[d]);
682
876
  }
683
- async function Ae() {
684
- if (!w || !B.trim() || !u || !T)
877
+ async function Me() {
878
+ if (!y || !F.trim() || !p || !T)
685
879
  return;
686
- let a = await b({
687
- projectKey: f.projectKey,
688
- contentId: f.contentId,
689
- normalizedPath: v,
690
- originalUrl: f.currentUrl ?? window.location.href,
691
- selector: w.selector,
692
- selectorStrategy: w.selectorStrategy,
693
- elementFingerprint: w.fingerprint,
694
- createdCssSnapshot: w.cssSnapshot,
695
- comment: B.trim(),
880
+ let a = await m({
881
+ projectKey: w.projectKey,
882
+ contentId: w.contentId,
883
+ normalizedPath: g,
884
+ originalUrl: w.currentUrl ?? window.location.href,
885
+ selector: y.selector,
886
+ selectorStrategy: y.selectorStrategy,
887
+ elementFingerprint: y.fingerprint,
888
+ createdCssSnapshot: y.cssSnapshot,
889
+ comment: F.trim(),
696
890
  status: "open",
697
- severity: ue,
698
- category: pe,
699
- assigneeEmail: me.trim() || void 0,
891
+ severity: H,
892
+ category: we,
893
+ assigneeEmail: be.trim() || void 0,
700
894
  viewportWidth: window.innerWidth,
701
895
  viewportHeight: window.innerHeight,
702
- viewportPreset: fe,
896
+ viewportPreset: ye,
703
897
  screenshotUrl: void 0,
704
898
  screenshotThumbnailUrl: void 0,
705
- authorEmail: u.email
899
+ authorEmail: p.email
706
900
  });
707
- if (f.captureScreenshot)
901
+ if (w.captureScreenshot)
708
902
  try {
709
- const m = await f.captureScreenshot(w), l = await h(a.id, {
903
+ const u = await w.captureScreenshot(y), d = await l(a.id, {
710
904
  type: "screenshot",
711
- data: m,
712
- createdBy: u.email
905
+ data: u,
906
+ createdBy: p.email
713
907
  });
714
- a = await E(a.id, {
715
- attachments: [l],
716
- screenshotUrl: l.url,
717
- screenshotThumbnailUrl: l.thumbnailUrl
908
+ a = await S(a.id, {
909
+ attachments: [d],
910
+ screenshotUrl: d.url,
911
+ screenshotThumbnailUrl: d.thumbnailUrl
718
912
  });
719
913
  } catch {
720
914
  }
721
- D(""), ge(""), C(void 0), y(void 0), $("feedback"), H(a);
915
+ if (_(""), ve(""), C(void 0), v(void 0), P("feedback"), K(a), s) {
916
+ const u = new URL(window.location.href);
917
+ u.searchParams.set("reviewLensFeedback", a.id), window.history.replaceState({}, "", u);
918
+ }
722
919
  }
723
- async function rt(a, m) {
724
- const l = (/* @__PURE__ */ new Date()).toISOString(), N = m === "resolved" ? { status: m, resolvedAt: l, resolvedBy: u == null ? void 0 : u.email } : { status: m }, te = await E(a.id, N);
725
- H(te);
920
+ async function ht(a, u) {
921
+ const d = (/* @__PURE__ */ new Date()).toISOString(), L = u === "resolved" ? { status: u, resolvedAt: d, resolvedBy: p == null ? void 0 : p.email } : { status: u }, ne = await S(a.id, L);
922
+ K(ne);
726
923
  }
727
- async function Le(a) {
728
- const m = z(a.selector);
729
- if (!m || !u)
924
+ async function $e(a) {
925
+ const u = z(a.selector);
926
+ if (!u || !p)
730
927
  return;
731
- const l = X(m), N = await E(a.id, {
928
+ const d = Q(u), L = await S(a.id, {
732
929
  status: "fixed",
733
- fixedCssSnapshot: l.cssSnapshot,
930
+ fixedCssSnapshot: d.cssSnapshot,
734
931
  fixedAt: (/* @__PURE__ */ new Date()).toISOString(),
735
- fixedBy: u.email
932
+ fixedBy: p.email
736
933
  });
737
- H(N);
934
+ K(L);
738
935
  }
739
- async function at(a) {
740
- if (!se.trim() || !u || !Ne)
936
+ async function ut(a) {
937
+ if (!le.trim() || !p || !Ae)
741
938
  return;
742
- const m = await A({
939
+ const u = await E({
743
940
  feedbackId: a.id,
744
- body: se.trim(),
745
- authorEmail: u.email
941
+ body: le.trim(),
942
+ authorEmail: p.email
746
943
  });
747
- Ce((l) => ({
748
- ...l,
749
- [a.id]: [...l[a.id] ?? [], m]
750
- })), oe("");
944
+ Le((d) => ({
945
+ ...d,
946
+ [a.id]: [...d[a.id] ?? [], u]
947
+ })), de("");
751
948
  }
752
949
  return /* @__PURE__ */ o("div", { className: "review-lens-root", "data-review-lens-ui": !0, children: [
753
- I && P ? /* @__PURE__ */ i($t, { target: P, locked: !!w }) : null,
754
- I && w && R && Ge ? /* @__PURE__ */ i(_t, { from: w, to: R }) : null,
755
- I ? /* @__PURE__ */ o(ie, { children: [
950
+ $ && j ? /* @__PURE__ */ i(Zt, { target: j, locked: !!y }) : null,
951
+ $ && y && A && nt ? /* @__PURE__ */ i(en, { from: y, to: A }) : null,
952
+ $ ? /* @__PURE__ */ o(ae, { children: [
756
953
  /* @__PURE__ */ i(
757
- Pt,
954
+ tn,
758
955
  {
759
- feedback: L,
760
- selectedFeedback: S,
761
- onSelect: q
956
+ feedback: R,
957
+ selectedFeedback: k,
958
+ onSelect: D
762
959
  }
763
960
  ),
764
961
  /* @__PURE__ */ i(
765
- Wt,
962
+ rn,
766
963
  {
767
- feedback: L,
768
- selectedFeedback: S,
769
- onSelect: q
964
+ feedback: R,
965
+ selectedFeedback: k,
966
+ onSelect: D
770
967
  }
771
968
  )
772
969
  ] }) : null,
773
970
  /* @__PURE__ */ o("aside", { className: `review-lens-panel review-lens-panel--${n}`, "data-review-lens-ui": !0, children: [
774
971
  /* @__PURE__ */ o("header", { className: "review-lens-panel__header", children: [
775
- /* @__PURE__ */ o("div", { children: [
776
- /* @__PURE__ */ i("p", { className: "review-lens-kicker", children: "Review Lens" }),
777
- /* @__PURE__ */ i("h2", { children: M === "summary" ? "Summary" : M === "feedback" ? "Feedback" : w ? "Element locked" : "Inspecting" })
972
+ /* @__PURE__ */ o("div", { className: "review-lens-brand", children: [
973
+ /* @__PURE__ */ i(Ot, { className: "review-lens-brand__mark" }),
974
+ /* @__PURE__ */ o("div", { children: [
975
+ /* @__PURE__ */ i("p", { className: "review-lens-kicker", children: "Review Lens" }),
976
+ /* @__PURE__ */ i("h2", { children: M === "summary" ? "Summary" : M === "feedback" ? "Feedback" : y ? "Element locked" : "Inspecting" })
977
+ ] })
778
978
  ] }),
779
979
  /* @__PURE__ */ i("button", { type: "button", onClick: () => t == null ? void 0 : t(!1), children: "Close" })
780
980
  ] }),
@@ -786,7 +986,7 @@ function Zt({
786
986
  type: "button",
787
987
  role: "tab",
788
988
  "aria-selected": M === "review",
789
- onClick: () => $("review"),
989
+ onClick: () => P("review"),
790
990
  children: "Review"
791
991
  }
792
992
  ),
@@ -796,10 +996,10 @@ function Zt({
796
996
  type: "button",
797
997
  role: "tab",
798
998
  "aria-selected": M === "feedback",
799
- onClick: () => $("feedback"),
999
+ onClick: () => P("feedback"),
800
1000
  children: [
801
1001
  "Feedback ",
802
- /* @__PURE__ */ i("span", { children: L.length })
1002
+ /* @__PURE__ */ i("span", { children: R.length })
803
1003
  ]
804
1004
  }
805
1005
  ),
@@ -809,46 +1009,46 @@ function Zt({
809
1009
  type: "button",
810
1010
  role: "tab",
811
1011
  "aria-selected": M === "summary",
812
- onClick: () => $("summary"),
1012
+ onClick: () => P("summary"),
813
1013
  children: "Summary"
814
1014
  }
815
1015
  )
816
1016
  ] }),
817
1017
  M === "review" ? /* @__PURE__ */ o("div", { className: "review-lens-review-pane", role: "tabpanel", children: [
818
1018
  /* @__PURE__ */ o("div", { className: "review-lens-inspection", children: [
819
- I ? null : /* @__PURE__ */ i("p", { children: "Authenticate with Google to inspect this page." }),
820
- I && P ? /* @__PURE__ */ o(ie, { children: [
821
- /* @__PURE__ */ i(Dt, { target: P }),
822
- /* @__PURE__ */ i(_e, { title: "Accessibility", items: zt(P) }),
1019
+ $ ? null : /* @__PURE__ */ i("p", { children: "Authenticate with Google to inspect this page." }),
1020
+ $ && j ? /* @__PURE__ */ o(ae, { children: [
1021
+ /* @__PURE__ */ i(an, { target: j }),
1022
+ /* @__PURE__ */ i(De, { title: "Accessibility", items: sn(j) }),
823
1023
  /* @__PURE__ */ i(
824
- _e,
1024
+ De,
825
1025
  {
826
1026
  title: "Design tokens",
827
- items: Ht(P.cssSnapshot, f.designTokens)
1027
+ items: on(j.cssSnapshot, w.designTokens)
828
1028
  }
829
1029
  )
830
1030
  ] }) : null,
831
- I && !P ? /* @__PURE__ */ i("p", { children: "Move over the app to inspect." }) : null
1031
+ $ && !j ? /* @__PURE__ */ i("p", { children: "Move over the app to inspect." }) : null
832
1032
  ] }),
833
- et ? /* @__PURE__ */ i("div", { className: "review-lens-composer-panel", children: /* @__PURE__ */ o(
1033
+ ot ? /* @__PURE__ */ i("div", { className: "review-lens-composer-panel", children: /* @__PURE__ */ o(
834
1034
  "form",
835
1035
  {
836
1036
  className: "review-lens-feedback-form",
837
1037
  onSubmit: (a) => {
838
- a.preventDefault(), Ae();
1038
+ a.preventDefault(), Me();
839
1039
  },
840
1040
  children: [
841
1041
  /* @__PURE__ */ i("label", { htmlFor: "review-lens-comment", children: "New feedback" }),
842
1042
  /* @__PURE__ */ i(
843
1043
  "textarea",
844
1044
  {
845
- ref: ee,
1045
+ ref: te,
846
1046
  id: "review-lens-comment",
847
- value: B,
1047
+ value: F,
848
1048
  disabled: !T,
849
- onChange: (a) => D(a.target.value),
1049
+ onChange: (a) => _(a.target.value),
850
1050
  onKeyDown: (a) => {
851
- a.key === "Enter" && a.metaKey && (a.preventDefault(), Ae());
1051
+ a.key === "Enter" && a.metaKey && (a.preventDefault(), Me());
852
1052
  },
853
1053
  placeholder: T ? "Describe the UX issue..." : "You do not have permission to comment."
854
1054
  }
@@ -859,10 +1059,10 @@ function Zt({
859
1059
  /* @__PURE__ */ i(
860
1060
  "select",
861
1061
  {
862
- value: ue,
863
- onChange: (a) => Je(a.target.value),
1062
+ value: H,
1063
+ onChange: (a) => Ze(a.target.value),
864
1064
  disabled: !T,
865
- children: je.map((a) => /* @__PURE__ */ i("option", { value: a, children: Q[a] }, a))
1065
+ children: Ye.map((a) => /* @__PURE__ */ i("option", { value: a, children: Z[a] }, a))
866
1066
  }
867
1067
  )
868
1068
  ] }),
@@ -871,10 +1071,10 @@ function Zt({
871
1071
  /* @__PURE__ */ i(
872
1072
  "select",
873
1073
  {
874
- value: pe,
875
- onChange: (a) => Ve(a.target.value),
1074
+ value: we,
1075
+ onChange: (a) => et(a.target.value),
876
1076
  disabled: !T,
877
- children: Oe.map((a) => /* @__PURE__ */ i("option", { value: a, children: Z[a] }, a))
1077
+ children: Xe.map((a) => /* @__PURE__ */ i("option", { value: a, children: ee[a] }, a))
878
1078
  }
879
1079
  )
880
1080
  ] }),
@@ -883,8 +1083,8 @@ function Zt({
883
1083
  /* @__PURE__ */ i(
884
1084
  "input",
885
1085
  {
886
- value: me,
887
- onChange: (a) => ge(a.target.value),
1086
+ value: be,
1087
+ onChange: (a) => ve(a.target.value),
888
1088
  disabled: !T,
889
1089
  placeholder: "optional@email.com"
890
1090
  }
@@ -895,8 +1095,8 @@ function Zt({
895
1095
  /* @__PURE__ */ i(
896
1096
  "select",
897
1097
  {
898
- value: fe,
899
- onChange: (a) => qe(a.target.value),
1098
+ value: ye,
1099
+ onChange: (a) => tt(a.target.value),
900
1100
  disabled: !T,
901
1101
  children: c.map((a) => /* @__PURE__ */ i("option", { value: a.value, children: a.label }, a.value))
902
1102
  }
@@ -909,103 +1109,104 @@ function Zt({
909
1109
  " + ",
910
1110
  /* @__PURE__ */ i("kbd", { children: "Enter" }),
911
1111
  " to submit.",
912
- tt ? " Screenshot capture runs after save." : ""
1112
+ lt ? " Screenshot capture runs after save." : ""
913
1113
  ] }) : null,
914
- /* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "submit", disabled: !B.trim() || !T, children: "Save feedback" }) })
1114
+ /* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "submit", disabled: !F.trim() || !T, children: "Save feedback" }) })
915
1115
  ]
916
1116
  }
917
1117
  ) }) : null
918
1118
  ] }) : null,
919
1119
  M === "feedback" ? /* @__PURE__ */ o("div", { className: "review-lens-comments", children: [
920
1120
  /* @__PURE__ */ i(
921
- It,
1121
+ Vt,
922
1122
  {
923
- open: Ye,
924
- activeCount: it,
925
- statusFilter: j,
1123
+ open: it,
1124
+ activeCount: ct,
1125
+ statusFilter: J,
926
1126
  severityFilter: O,
927
- categoryFilter: K,
928
- assigneeFilter: J,
929
- viewportFilter: V,
930
- assignees: nt,
1127
+ categoryFilter: q,
1128
+ assigneeFilter: V,
1129
+ viewportFilter: G,
1130
+ assignees: dt,
931
1131
  responsivePresets: c,
932
- onStatusChange: ve,
933
- onSeverityChange: we,
934
- onCategoryChange: ye,
935
- onAssigneeChange: Se,
936
- onViewportChange: ke,
937
- onToggle: () => Xe((a) => !a),
1132
+ onStatusChange: ke,
1133
+ onSeverityChange: Ne,
1134
+ onCategoryChange: Ce,
1135
+ onAssigneeChange: xe,
1136
+ onViewportChange: Ee,
1137
+ onToggle: () => rt((a) => !a),
938
1138
  onClear: () => {
939
- ve("all"), we("all"), ye("all"), Se("all"), ke("all");
1139
+ ke("all"), Ne("all"), Ce("all"), xe("all"), Ee("all");
940
1140
  }
941
1141
  }
942
1142
  ),
943
1143
  /* @__PURE__ */ o("div", { className: "review-lens-list-panel", children: [
944
1144
  /* @__PURE__ */ o("div", { className: "review-lens-comments__header", children: [
945
1145
  /* @__PURE__ */ i("h3", { children: "All feedback" }),
946
- /* @__PURE__ */ i("span", { children: L.length })
1146
+ /* @__PURE__ */ i("span", { children: R.length })
947
1147
  ] }),
948
1148
  /* @__PURE__ */ o("div", { className: "review-lens-comments__list", children: [
949
- L.length === 0 ? /* @__PURE__ */ i("p", { children: "No feedback for this view." }) : null,
950
- L.map((a) => /* @__PURE__ */ i(
951
- Tt,
1149
+ R.length === 0 ? /* @__PURE__ */ i("p", { children: "No feedback for this view." }) : null,
1150
+ R.map((a) => /* @__PURE__ */ i(
1151
+ Gt,
952
1152
  {
953
1153
  item: a,
954
- selected: (S == null ? void 0 : S.id) === a.id,
955
- onSelect: q
1154
+ selected: (k == null ? void 0 : k.id) === a.id,
1155
+ onSelect: D
956
1156
  },
957
1157
  a.id
958
1158
  ))
959
1159
  ] })
960
1160
  ] }),
961
- S ? /* @__PURE__ */ o("div", { className: "review-lens-selected-panel", children: [
1161
+ k ? /* @__PURE__ */ o("div", { className: "review-lens-selected-panel", children: [
962
1162
  /* @__PURE__ */ i("div", { className: "review-lens-selected-panel__label", children: "Selected feedback" }),
963
1163
  /* @__PURE__ */ i(
964
- Rt,
1164
+ Yt,
965
1165
  {
966
- item: S,
967
- messages: Qe[S.id] ?? [],
968
- messageDraft: se,
969
- canReply: Ne,
970
- canUpdate: xe,
971
- canAssign: Ze,
972
- onMessageDraftChange: oe,
973
- onSubmitMessage: () => void at(S),
974
- onStatusChange: (a) => void rt(S, a),
975
- onAssigneeChange: (a) => void E(S.id, {
1166
+ item: k,
1167
+ messages: at[k.id] ?? [],
1168
+ messageDraft: le,
1169
+ canReply: Ae,
1170
+ canUpdate: Re,
1171
+ canAssign: st,
1172
+ syncSelectionToUrl: s,
1173
+ onMessageDraftChange: de,
1174
+ onSubmitMessage: () => void ut(k),
1175
+ onStatusChange: (a) => void ht(k, a),
1176
+ onAssigneeChange: (a) => void S(k.id, {
976
1177
  assigneeEmail: a.trim() || void 0
977
- }).then(H),
978
- onMarkFixed: () => void Le(S)
1178
+ }).then(K),
1179
+ onMarkFixed: () => void $e(k)
979
1180
  },
980
- S.id
1181
+ k.id
981
1182
  )
982
1183
  ] }) : /* @__PURE__ */ o("div", { className: "review-lens-selected-panel review-lens-selected-panel--empty", children: [
983
1184
  /* @__PURE__ */ i("div", { className: "review-lens-selected-panel__label", children: "Selected feedback" }),
984
1185
  /* @__PURE__ */ i("p", { children: "Select a feedback item above to review status, assignment, drift, and replies." })
985
1186
  ] })
986
1187
  ] }) : null,
987
- M === "summary" ? /* @__PURE__ */ i(Bt, { feedback: d }) : null
1188
+ M === "summary" ? /* @__PURE__ */ i(Qt, { feedback: b }) : null
988
1189
  ] })
989
1190
  ] })
990
1191
  ] });
991
1192
  }
992
- function It({
1193
+ function Vt({
993
1194
  open: e,
994
1195
  activeCount: t,
995
1196
  statusFilter: n,
996
1197
  severityFilter: r,
997
1198
  categoryFilter: s,
998
1199
  assigneeFilter: c,
999
- viewportFilter: g,
1000
- assignees: f,
1001
- responsivePresets: u,
1002
- onStatusChange: d,
1003
- onSeverityChange: v,
1004
- onCategoryChange: p,
1005
- onAssigneeChange: b,
1006
- onViewportChange: E,
1200
+ viewportFilter: h,
1201
+ assignees: w,
1202
+ responsivePresets: p,
1203
+ onStatusChange: b,
1204
+ onSeverityChange: g,
1205
+ onCategoryChange: f,
1206
+ onAssigneeChange: m,
1207
+ onViewportChange: S,
1007
1208
  onToggle: x,
1008
- onClear: A
1209
+ onClear: E
1009
1210
  }) {
1010
1211
  return /* @__PURE__ */ o("div", { className: "review-lens-filter-shell", children: [
1011
1212
  /* @__PURE__ */ o("div", { className: "review-lens-filter-bar", children: [
@@ -1013,7 +1214,7 @@ function It({
1013
1214
  "Filters",
1014
1215
  t > 0 ? /* @__PURE__ */ i("span", { children: t }) : null
1015
1216
  ] }),
1016
- t > 0 ? /* @__PURE__ */ i("button", { type: "button", onClick: A, children: "Clear" }) : null
1217
+ t > 0 ? /* @__PURE__ */ i("button", { type: "button", onClick: E, children: "Clear" }) : null
1017
1218
  ] }),
1018
1219
  e ? /* @__PURE__ */ o("div", { className: "review-lens-filters", children: [
1019
1220
  /* @__PURE__ */ o("label", { children: [
@@ -1023,10 +1224,10 @@ function It({
1023
1224
  {
1024
1225
  "aria-label": "Filter status",
1025
1226
  value: n,
1026
- onChange: (h) => d(h.target.value),
1227
+ onChange: (l) => b(l.target.value),
1027
1228
  children: [
1028
1229
  /* @__PURE__ */ i("option", { value: "all", children: "All statuses" }),
1029
- He.map((h) => /* @__PURE__ */ i("option", { value: h, children: ae[h] }, h))
1230
+ Ge.map((l) => /* @__PURE__ */ i("option", { value: l, children: oe[l] }, l))
1030
1231
  ]
1031
1232
  }
1032
1233
  )
@@ -1038,10 +1239,10 @@ function It({
1038
1239
  {
1039
1240
  "aria-label": "Filter severity",
1040
1241
  value: r,
1041
- onChange: (h) => v(h.target.value),
1242
+ onChange: (l) => g(l.target.value),
1042
1243
  children: [
1043
1244
  /* @__PURE__ */ i("option", { value: "all", children: "All priorities" }),
1044
- je.map((h) => /* @__PURE__ */ i("option", { value: h, children: Q[h] }, h))
1245
+ Ye.map((l) => /* @__PURE__ */ i("option", { value: l, children: Z[l] }, l))
1045
1246
  ]
1046
1247
  }
1047
1248
  )
@@ -1053,10 +1254,10 @@ function It({
1053
1254
  {
1054
1255
  "aria-label": "Filter type",
1055
1256
  value: s,
1056
- onChange: (h) => p(h.target.value),
1257
+ onChange: (l) => f(l.target.value),
1057
1258
  children: [
1058
1259
  /* @__PURE__ */ i("option", { value: "all", children: "All types" }),
1059
- Oe.map((h) => /* @__PURE__ */ i("option", { value: h, children: Z[h] }, h))
1260
+ Xe.map((l) => /* @__PURE__ */ i("option", { value: l, children: ee[l] }, l))
1060
1261
  ]
1061
1262
  }
1062
1263
  )
@@ -1068,10 +1269,10 @@ function It({
1068
1269
  {
1069
1270
  "aria-label": "Filter assignee",
1070
1271
  value: c,
1071
- onChange: (h) => b(h.target.value),
1272
+ onChange: (l) => m(l.target.value),
1072
1273
  children: [
1073
1274
  /* @__PURE__ */ i("option", { value: "all", children: "All assignees" }),
1074
- f.map((h) => /* @__PURE__ */ i("option", { value: h, children: h }, h))
1275
+ w.map((l) => /* @__PURE__ */ i("option", { value: l, children: l }, l))
1075
1276
  ]
1076
1277
  }
1077
1278
  )
@@ -1082,11 +1283,11 @@ function It({
1082
1283
  "select",
1083
1284
  {
1084
1285
  "aria-label": "Filter viewport",
1085
- value: g,
1086
- onChange: (h) => E(h.target.value),
1286
+ value: h,
1287
+ onChange: (l) => S(l.target.value),
1087
1288
  children: [
1088
1289
  /* @__PURE__ */ i("option", { value: "all", children: "All viewports" }),
1089
- u.map((h) => /* @__PURE__ */ i("option", { value: h.value, children: h.label }, h.value))
1290
+ p.map((l) => /* @__PURE__ */ i("option", { value: l.value, children: l.label }, l.value))
1090
1291
  ]
1091
1292
  }
1092
1293
  )
@@ -1094,12 +1295,12 @@ function It({
1094
1295
  ] }) : null
1095
1296
  ] });
1096
1297
  }
1097
- function Tt({
1298
+ function Gt({
1098
1299
  item: e,
1099
1300
  selected: t,
1100
1301
  onSelect: n
1101
1302
  }) {
1102
- const r = Ke(e);
1303
+ const r = Qe(e);
1103
1304
  return /* @__PURE__ */ o(
1104
1305
  "article",
1105
1306
  {
@@ -1115,8 +1316,8 @@ function Tt({
1115
1316
  },
1116
1317
  children: [
1117
1318
  /* @__PURE__ */ o("div", { className: "review-lens-comment__header", children: [
1118
- /* @__PURE__ */ i("span", { children: ae[e.status] }),
1119
- /* @__PURE__ */ i("strong", { children: Q[e.severity] })
1319
+ /* @__PURE__ */ i("span", { children: oe[e.status] }),
1320
+ /* @__PURE__ */ i("strong", { children: Z[e.severity] })
1120
1321
  ] }),
1121
1322
  /* @__PURE__ */ o("div", { className: "review-lens-comment__content", children: [
1122
1323
  /* @__PURE__ */ i("p", { children: e.comment }),
@@ -1126,7 +1327,7 @@ function Tt({
1126
1327
  ] })
1127
1328
  ] }),
1128
1329
  /* @__PURE__ */ o("div", { className: "review-lens-tags", children: [
1129
- /* @__PURE__ */ i("span", { children: Z[e.category] }),
1330
+ /* @__PURE__ */ i("span", { children: ee[e.category] }),
1130
1331
  /* @__PURE__ */ i("span", { children: e.viewportPreset }),
1131
1332
  /* @__PURE__ */ i("span", { children: r.label })
1132
1333
  ] })
@@ -1134,33 +1335,52 @@ function Tt({
1134
1335
  }
1135
1336
  );
1136
1337
  }
1137
- function Rt({
1338
+ function Yt({
1138
1339
  item: e,
1139
1340
  messages: t,
1140
1341
  messageDraft: n,
1141
1342
  canReply: r,
1142
1343
  canUpdate: s,
1143
1344
  canAssign: c,
1144
- onMessageDraftChange: g,
1145
- onSubmitMessage: f,
1146
- onStatusChange: u,
1147
- onAssigneeChange: d,
1148
- onMarkFixed: v
1345
+ syncSelectionToUrl: h,
1346
+ onMessageDraftChange: w,
1347
+ onSubmitMessage: p,
1348
+ onStatusChange: b,
1349
+ onAssigneeChange: g,
1350
+ onMarkFixed: f
1149
1351
  }) {
1150
- const p = Ke(e);
1352
+ const [m, S] = N(!1), x = Qe(e);
1353
+ function E() {
1354
+ const l = new URL(window.location.href);
1355
+ l.searchParams.set("reviewLensFeedback", e.id), Xt(l.toString()).then((A) => {
1356
+ A && (S(!0), setTimeout(() => S(!1), 2e3));
1357
+ });
1358
+ }
1151
1359
  return /* @__PURE__ */ o("section", { className: "review-lens-detail", "aria-label": "Selected feedback detail", children: [
1152
1360
  /* @__PURE__ */ o("div", { className: "review-lens-detail__header", children: [
1153
1361
  /* @__PURE__ */ o("h3", { children: [
1154
- Z[e.category],
1362
+ ee[e.category],
1155
1363
  " feedback"
1156
1364
  ] }),
1157
- /* @__PURE__ */ i("strong", { children: Q[e.severity] })
1365
+ /* @__PURE__ */ o("div", { className: "review-lens-detail__header-actions", children: [
1366
+ h ? /* @__PURE__ */ i(
1367
+ "button",
1368
+ {
1369
+ type: "button",
1370
+ className: "review-lens-copy-link",
1371
+ onClick: E,
1372
+ "aria-label": "Copy link to this feedback",
1373
+ children: m ? "Copied!" : "Copy link"
1374
+ }
1375
+ ) : null,
1376
+ /* @__PURE__ */ i("strong", { children: Z[e.severity] })
1377
+ ] })
1158
1378
  ] }),
1159
1379
  /* @__PURE__ */ i("blockquote", { children: e.comment }),
1160
1380
  /* @__PURE__ */ o("dl", { className: "review-lens-detail-meta", children: [
1161
1381
  /* @__PURE__ */ o("div", { children: [
1162
1382
  /* @__PURE__ */ i("dt", { children: "Target" }),
1163
- /* @__PURE__ */ i("dd", { children: p.label })
1383
+ /* @__PURE__ */ i("dd", { children: x.label })
1164
1384
  ] }),
1165
1385
  /* @__PURE__ */ o("div", { children: [
1166
1386
  /* @__PURE__ */ i("dt", { children: "Viewport" }),
@@ -1179,8 +1399,8 @@ function Rt({
1179
1399
  {
1180
1400
  value: e.status,
1181
1401
  disabled: !s,
1182
- onChange: (b) => u(b.target.value),
1183
- children: He.map((b) => /* @__PURE__ */ i("option", { value: b, children: ae[b] }, b))
1402
+ onChange: (l) => b(l.target.value),
1403
+ children: Ge.map((l) => /* @__PURE__ */ i("option", { value: l, children: oe[l] }, l))
1184
1404
  }
1185
1405
  )
1186
1406
  ] }),
@@ -1191,7 +1411,7 @@ function Rt({
1191
1411
  {
1192
1412
  defaultValue: e.assigneeEmail ?? "",
1193
1413
  disabled: !c,
1194
- onBlur: (b) => d(b.target.value),
1414
+ onBlur: (l) => g(l.target.value),
1195
1415
  placeholder: "optional@email.com"
1196
1416
  }
1197
1417
  )
@@ -1204,7 +1424,7 @@ function Rt({
1204
1424
  type: "button",
1205
1425
  className: "review-lens-button-secondary",
1206
1426
  disabled: !s,
1207
- onClick: v,
1427
+ onClick: f,
1208
1428
  children: "Mark fixed"
1209
1429
  }
1210
1430
  ),
@@ -1214,7 +1434,7 @@ function Rt({
1214
1434
  type: "button",
1215
1435
  className: "review-lens-button-primary",
1216
1436
  disabled: !s,
1217
- onClick: () => u("resolved"),
1437
+ onClick: () => b("resolved"),
1218
1438
  children: "Resolve"
1219
1439
  }
1220
1440
  )
@@ -1225,34 +1445,46 @@ function Rt({
1225
1445
  /* @__PURE__ */ i("span", { children: t.length })
1226
1446
  ] }),
1227
1447
  t.length === 0 ? /* @__PURE__ */ i("p", { children: "No replies yet." }) : null,
1228
- t.map((b) => /* @__PURE__ */ o("div", { className: "review-lens-thread__message", children: [
1229
- /* @__PURE__ */ i("p", { children: b.body }),
1230
- /* @__PURE__ */ i("span", { children: b.authorEmail })
1231
- ] }, b.id)),
1448
+ t.map((l) => /* @__PURE__ */ o("div", { className: "review-lens-thread__message", children: [
1449
+ /* @__PURE__ */ i("p", { children: l.body }),
1450
+ /* @__PURE__ */ i("span", { children: l.authorEmail })
1451
+ ] }, l.id)),
1232
1452
  /* @__PURE__ */ i(
1233
1453
  "textarea",
1234
1454
  {
1235
1455
  "aria-label": "Reply",
1236
1456
  value: n,
1237
1457
  disabled: !r,
1238
- onChange: (b) => g(b.target.value),
1458
+ onChange: (l) => w(l.target.value),
1239
1459
  placeholder: r ? "Reply..." : "You do not have permission to reply."
1240
1460
  }
1241
1461
  ),
1242
- /* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "button", disabled: !n.trim() || !r, onClick: f, children: "Reply" }) })
1462
+ /* @__PURE__ */ i("div", { className: "review-lens-actions", children: /* @__PURE__ */ i("button", { type: "button", disabled: !n.trim() || !r, onClick: p, children: "Reply" }) })
1243
1463
  ] })
1244
1464
  ] });
1245
1465
  }
1246
- function Bt({ feedback: e }) {
1466
+ async function Xt(e) {
1467
+ var n;
1468
+ if ((n = navigator.clipboard) != null && n.writeText)
1469
+ return await navigator.clipboard.writeText(e), !0;
1470
+ const t = document.createElement("textarea");
1471
+ t.value = e, t.setAttribute("readonly", ""), t.style.position = "fixed", t.style.opacity = "0", document.body.append(t), t.select();
1472
+ try {
1473
+ return document.execCommand("copy");
1474
+ } finally {
1475
+ t.remove();
1476
+ }
1477
+ }
1478
+ function Qt({ feedback: e }) {
1247
1479
  return /* @__PURE__ */ o("div", { className: "review-lens-summary", role: "tabpanel", children: [
1248
- /* @__PURE__ */ i(G, { title: "Status", values: Y(e, (t) => ae[t.status]) }),
1249
- /* @__PURE__ */ i(G, { title: "Severity", values: Y(e, (t) => Q[t.severity]) }),
1250
- /* @__PURE__ */ i(G, { title: "Type", values: Y(e, (t) => Z[t.category]) }),
1251
- /* @__PURE__ */ i(G, { title: "Assignee", values: Y(e, (t) => t.assigneeEmail ?? "Unassigned") }),
1252
- /* @__PURE__ */ i(G, { title: "Viewport", values: Y(e, (t) => t.viewportPreset) })
1480
+ /* @__PURE__ */ i(Y, { title: "Status", values: X(e, (t) => oe[t.status]) }),
1481
+ /* @__PURE__ */ i(Y, { title: "Severity", values: X(e, (t) => Z[t.severity]) }),
1482
+ /* @__PURE__ */ i(Y, { title: "Type", values: X(e, (t) => ee[t.category]) }),
1483
+ /* @__PURE__ */ i(Y, { title: "Assignee", values: X(e, (t) => t.assigneeEmail ?? "Unassigned") }),
1484
+ /* @__PURE__ */ i(Y, { title: "Viewport", values: X(e, (t) => t.viewportPreset) })
1253
1485
  ] });
1254
1486
  }
1255
- function G({ title: e, values: t }) {
1487
+ function Y({ title: e, values: t }) {
1256
1488
  return /* @__PURE__ */ o("section", { children: [
1257
1489
  /* @__PURE__ */ i("h3", { children: e }),
1258
1490
  /* @__PURE__ */ i("dl", { children: t.map(([n, r]) => /* @__PURE__ */ o("div", { children: [
@@ -1261,8 +1493,8 @@ function G({ title: e, values: t }) {
1261
1493
  ] }, n)) })
1262
1494
  ] });
1263
1495
  }
1264
- function $t({ target: e, locked: t }) {
1265
- const n = Gt(e), r = Ot(e.fingerprint);
1496
+ function Zt({ target: e, locked: t }) {
1497
+ const n = pn(e), r = dn(e.fingerprint);
1266
1498
  return /* @__PURE__ */ o(
1267
1499
  "div",
1268
1500
  {
@@ -1322,9 +1554,9 @@ function $t({ target: e, locked: t }) {
1322
1554
  }
1323
1555
  );
1324
1556
  }
1325
- function _t({ from: e, to: t }) {
1326
- const n = Kt(e.rect, t.rect);
1327
- return n.length === 0 ? null : /* @__PURE__ */ i(ie, { children: n.map((r) => /* @__PURE__ */ i(
1557
+ function en({ from: e, to: t }) {
1558
+ const n = cn(e.rect, t.rect);
1559
+ return n.length === 0 ? null : /* @__PURE__ */ i(ae, { children: n.map((r) => /* @__PURE__ */ i(
1328
1560
  "div",
1329
1561
  {
1330
1562
  className: `review-lens-distance review-lens-distance--${r.axis}`,
@@ -1339,13 +1571,13 @@ function _t({ from: e, to: t }) {
1339
1571
  r.key
1340
1572
  )) });
1341
1573
  }
1342
- function Pt({
1574
+ function tn({
1343
1575
  feedback: e,
1344
1576
  selectedFeedback: t,
1345
1577
  onSelect: n
1346
1578
  }) {
1347
- return /* @__PURE__ */ i(ie, { children: e.map((r) => /* @__PURE__ */ i(
1348
- Ut,
1579
+ return /* @__PURE__ */ i(ae, { children: e.map((r) => /* @__PURE__ */ i(
1580
+ nn,
1349
1581
  {
1350
1582
  feedback: r,
1351
1583
  selected: (t == null ? void 0 : t.id) === r.id,
@@ -1354,23 +1586,23 @@ function Pt({
1354
1586
  r.id
1355
1587
  )) });
1356
1588
  }
1357
- function Ut({
1589
+ function nn({
1358
1590
  feedback: e,
1359
1591
  selected: t,
1360
1592
  onSelect: n
1361
1593
  }) {
1362
- const r = We(null);
1363
- return lt(() => {
1594
+ const r = re(null);
1595
+ return gt(() => {
1364
1596
  let s = 0;
1365
1597
  const c = () => {
1366
1598
  s = 0;
1367
- const f = r.current, u = z(e.selector), d = u == null ? void 0 : u.getBoundingClientRect();
1368
- !f || !d || (f.style.top = `${d.top}px`, f.style.left = `${d.right}px`, f.hidden = d.bottom < 0 || d.top > window.innerHeight);
1369
- }, g = () => {
1599
+ const w = r.current, p = z(e.selector), b = p == null ? void 0 : p.getBoundingClientRect();
1600
+ !w || !b || (w.style.top = `${b.top}px`, w.style.left = `${b.right}px`, w.hidden = b.bottom < 0 || b.top > window.innerHeight);
1601
+ }, h = () => {
1370
1602
  s || (s = window.requestAnimationFrame(c));
1371
1603
  };
1372
- return c(), window.addEventListener("scroll", g, !0), window.addEventListener("resize", g), () => {
1373
- s && window.cancelAnimationFrame(s), window.removeEventListener("scroll", g, !0), window.removeEventListener("resize", g);
1604
+ return c(), window.addEventListener("scroll", h, !0), window.addEventListener("resize", h), () => {
1605
+ s && window.cancelAnimationFrame(s), window.removeEventListener("scroll", h, !0), window.removeEventListener("resize", h);
1374
1606
  };
1375
1607
  }, [e.selector]), /* @__PURE__ */ i(
1376
1608
  "button",
@@ -1383,20 +1615,20 @@ function Ut({
1383
1615
  }
1384
1616
  );
1385
1617
  }
1386
- function Wt({
1618
+ function rn({
1387
1619
  feedback: e,
1388
1620
  selectedFeedback: t,
1389
1621
  onSelect: n
1390
1622
  }) {
1391
1623
  const r = e.map((s) => {
1392
- const c = z(s.selector), g = c == null ? void 0 : c.getBoundingClientRect(), f = Math.max(
1624
+ const c = z(s.selector), h = c == null ? void 0 : c.getBoundingClientRect(), w = Math.max(
1393
1625
  document.documentElement.scrollHeight,
1394
1626
  document.body.scrollHeight,
1395
1627
  window.innerHeight
1396
1628
  );
1397
- return !g || f <= 0 ? null : {
1629
+ return !h || w <= 0 ? null : {
1398
1630
  item: s,
1399
- top: Math.min(100, Math.max(0, (g.top + window.scrollY) / f * 100))
1631
+ top: Math.min(100, Math.max(0, (h.top + window.scrollY) / w * 100))
1400
1632
  };
1401
1633
  }).filter((s) => s !== null);
1402
1634
  return r.length === 0 ? null : /* @__PURE__ */ i("div", { className: "review-lens-minimap", "data-review-lens-ui": !0, "aria-label": "Feedback map", children: r.map((s) => /* @__PURE__ */ i(
@@ -1411,7 +1643,7 @@ function Wt({
1411
1643
  s.item.id
1412
1644
  )) });
1413
1645
  }
1414
- function Dt({ target: e }) {
1646
+ function an({ target: e }) {
1415
1647
  const t = [
1416
1648
  ["Selector", e.selector],
1417
1649
  ["Size", `${e.cssSnapshot.width} x ${e.cssSnapshot.height}`],
@@ -1429,7 +1661,7 @@ function Dt({ target: e }) {
1429
1661
  /* @__PURE__ */ i("dd", { children: r })
1430
1662
  ] }, n)) });
1431
1663
  }
1432
- function _e({ title: e, items: t }) {
1664
+ function De({ title: e, items: t }) {
1433
1665
  return /* @__PURE__ */ o("section", { className: "review-lens-insights", children: [
1434
1666
  /* @__PURE__ */ i("h3", { children: e }),
1435
1667
  t.length === 0 ? /* @__PURE__ */ i("p", { children: "No issues detected." }) : null,
@@ -1443,31 +1675,31 @@ function z(e) {
1443
1675
  return null;
1444
1676
  }
1445
1677
  }
1446
- function Ke(e) {
1678
+ function Qe(e) {
1447
1679
  const t = z(e.selector);
1448
1680
  if (!t)
1449
1681
  return { label: "Target missing", level: "warning" };
1450
- const n = X(t);
1682
+ const n = Q(t);
1451
1683
  return n.fingerprint.tagName !== e.elementFingerprint.tagName ? { label: "Element changed", level: "warning" } : Math.abs(n.fingerprint.width - e.elementFingerprint.width) > 2 || Math.abs(n.fingerprint.height - e.elementFingerprint.height) > 2 ? { label: "Size changed", level: "warning" } : n.cssSnapshot.fontSize !== e.createdCssSnapshot.fontSize || n.cssSnapshot.color !== e.createdCssSnapshot.color || n.cssSnapshot.padding !== e.createdCssSnapshot.padding ? { label: "Style changed", level: "warning" } : { label: "Target unchanged", level: "ok" };
1452
1684
  }
1453
- function zt(e) {
1454
- var u;
1685
+ function sn(e) {
1686
+ var p;
1455
1687
  const t = z(e.selector);
1456
1688
  if (!t)
1457
1689
  return ["Selected element is no longer available."];
1458
- const n = [], r = t.tagName.toLowerCase(), s = t.getAttribute("role"), c = ["button", "a", "input", "select", "textarea"].includes(r) || s === "button" || s === "link", g = t.getAttribute("aria-label") || t.getAttribute("title") || ((u = t.textContent) == null ? void 0 : u.trim());
1459
- c && !g && n.push("Interactive element has no accessible name."), c && (e.rect.width < 44 || e.rect.height < 44) && n.push("Tap target is smaller than 44 x 44."), r === "img" && !t.getAttribute("alt") && n.push("Image is missing alt text.");
1460
- const f = /^h[1-6]$/.test(r) ? Number(r.slice(1)) : 0;
1461
- return f > 1 && !document.querySelector(`h${f - 1}`) && n.push("Heading may skip the previous level."), Vt(e.cssSnapshot.color, e.cssSnapshot.backgroundColor) && n.push("Text contrast may be low."), n;
1690
+ const n = [], r = t.tagName.toLowerCase(), s = t.getAttribute("role"), c = ["button", "a", "input", "select", "textarea"].includes(r) || s === "button" || s === "link", h = t.getAttribute("aria-label") || t.getAttribute("title") || ((p = t.textContent) == null ? void 0 : p.trim());
1691
+ c && !h && n.push("Interactive element has no accessible name."), c && (e.rect.width < 44 || e.rect.height < 44) && n.push("Tap target is smaller than 44 x 44."), r === "img" && !t.getAttribute("alt") && n.push("Image is missing alt text.");
1692
+ const w = /^h[1-6]$/.test(r) ? Number(r.slice(1)) : 0;
1693
+ return w > 1 && !document.querySelector(`h${w - 1}`) && n.push("Heading may skip the previous level."), un(e.cssSnapshot.color, e.cssSnapshot.backgroundColor) && n.push("Text contrast may be low."), n;
1462
1694
  }
1463
- function Ht(e, t = {}) {
1695
+ function on(e, t = {}) {
1464
1696
  const n = [];
1465
1697
  return U("Padding", e.padding, t.spacing, n, { allowComposite: !0 }), U("Margin", e.margin, t.spacing, n, { allowComposite: !0 }), U("Font size", e.fontSize, t.fontSize, n), U("Line height", e.lineHeight, t.lineHeight, n), U("Text color", e.color, t.color, n), U("Background", e.backgroundColor, t.color, n), U("Radius", e.borderRadius, t.radius, n, { allowComposite: !0 }), n;
1466
1698
  }
1467
1699
  function U(e, t, n, r, s = {}) {
1468
- !n || n.length === 0 || !t || jt(t, n, s) || r.push(`${e} ${t} is outside configured tokens.`);
1700
+ !n || n.length === 0 || !t || ln(t, n, s) || r.push(`${e} ${t} is outside configured tokens.`);
1469
1701
  }
1470
- function jt(e, t, n = {}) {
1702
+ function ln(e, t, n = {}) {
1471
1703
  if (t.includes(e))
1472
1704
  return !0;
1473
1705
  if (!n.allowComposite)
@@ -1475,42 +1707,42 @@ function jt(e, t, n = {}) {
1475
1707
  const r = e.trim().split(/\s+/);
1476
1708
  return r.length > 1 && r.every((s) => t.includes(s));
1477
1709
  }
1478
- function Ot(e) {
1710
+ function dn(e) {
1479
1711
  const t = e.id ? `#${e.id}` : "", n = e.className ? `.${e.className.split(/\s+/).filter(Boolean).slice(0, 2).join(".")}` : "", r = e.ariaLabel ? `[aria-label="${e.ariaLabel}"]` : "";
1480
1712
  return `${e.tagName}${t}${n}${r}` || e.tagName;
1481
1713
  }
1482
- function Kt(e, t) {
1714
+ function cn(e, t) {
1483
1715
  const n = [], r = (Math.max(e.left, t.left) + Math.min(e.right, t.right)) / 2, s = (Math.max(e.top, t.top) + Math.min(e.bottom, t.bottom)) / 2;
1484
1716
  if (e.right <= t.left || t.right <= e.left) {
1485
- const c = e.right <= t.left ? e.right : t.right, g = e.right <= t.left ? t.left : e.left;
1717
+ const c = e.right <= t.left ? e.right : t.right, h = e.right <= t.left ? t.left : e.left;
1486
1718
  n.push({
1487
1719
  key: "horizontal",
1488
1720
  axis: "horizontal",
1489
- top: Pe(s, 0, window.innerHeight),
1721
+ top: ze(s, 0, window.innerHeight),
1490
1722
  left: c,
1491
- width: Math.max(g - c, 1),
1723
+ width: Math.max(h - c, 1),
1492
1724
  height: 1,
1493
- label: `${Math.round(g - c)}px`
1725
+ label: `${Math.round(h - c)}px`
1494
1726
  });
1495
1727
  }
1496
1728
  if (e.bottom <= t.top || t.bottom <= e.top) {
1497
- const c = e.bottom <= t.top ? e.bottom : t.bottom, g = e.bottom <= t.top ? t.top : e.top;
1729
+ const c = e.bottom <= t.top ? e.bottom : t.bottom, h = e.bottom <= t.top ? t.top : e.top;
1498
1730
  n.push({
1499
1731
  key: "vertical",
1500
1732
  axis: "vertical",
1501
1733
  top: c,
1502
- left: Pe(r, 0, window.innerWidth),
1734
+ left: ze(r, 0, window.innerWidth),
1503
1735
  width: 1,
1504
- height: Math.max(g - c, 1),
1505
- label: `${Math.round(g - c)}px`
1736
+ height: Math.max(h - c, 1),
1737
+ label: `${Math.round(h - c)}px`
1506
1738
  });
1507
1739
  }
1508
1740
  return n;
1509
1741
  }
1510
- function Pe(e, t, n) {
1742
+ function ze(e, t, n) {
1511
1743
  return Math.min(Math.max(e, t), n);
1512
1744
  }
1513
- function Y(e, t) {
1745
+ function X(e, t) {
1514
1746
  const n = /* @__PURE__ */ new Map();
1515
1747
  for (const r of e) {
1516
1748
  const s = t(r);
@@ -1518,18 +1750,18 @@ function Y(e, t) {
1518
1750
  }
1519
1751
  return Array.from(n.entries()).sort((r, s) => s[1] - r[1] || r[0].localeCompare(s[0]));
1520
1752
  }
1521
- function Jt(e) {
1753
+ function hn(e) {
1522
1754
  return e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement || e instanceof HTMLSelectElement || e instanceof HTMLElement && e.isContentEditable;
1523
1755
  }
1524
- function Vt(e, t) {
1525
- const n = Ue(e), r = Ue(t);
1526
- return !n || !r || r.alpha === 0 ? !1 : qt(n, r) < 4.5;
1756
+ function un(e, t) {
1757
+ const n = He(e), r = He(t);
1758
+ return !n || !r || r.alpha === 0 ? !1 : mn(n, r) < 4.5;
1527
1759
  }
1528
- function Ue(e) {
1760
+ function He(e) {
1529
1761
  const t = e.match(/rgba?\(([^)]+)\)/);
1530
1762
  if (!t)
1531
1763
  return null;
1532
- const [n, r, s, c = "1"] = t[1].split(",").map((g) => g.trim());
1764
+ const [n, r, s, c = "1"] = t[1].split(",").map((h) => h.trim());
1533
1765
  return {
1534
1766
  red: Number(n),
1535
1767
  green: Number(r),
@@ -1537,33 +1769,33 @@ function Ue(e) {
1537
1769
  alpha: Number(c)
1538
1770
  };
1539
1771
  }
1540
- function qt(e, t) {
1541
- const n = Math.max(ne(e), ne(t)), r = Math.min(ne(e), ne(t));
1772
+ function mn(e, t) {
1773
+ const n = Math.max(ie(e), ie(t)), r = Math.min(ie(e), ie(t));
1542
1774
  return (n + 0.05) / (r + 0.05);
1543
1775
  }
1544
- function ne(e) {
1776
+ function ie(e) {
1545
1777
  const t = [e.red, e.green, e.blue].map((n) => {
1546
1778
  const r = n / 255;
1547
1779
  return r <= 0.03928 ? r / 12.92 : ((r + 0.055) / 1.055) ** 2.4;
1548
1780
  });
1549
1781
  return t[0] * 0.2126 + t[1] * 0.7152 + t[2] * 0.0722;
1550
1782
  }
1551
- function Gt(e) {
1783
+ function pn(e) {
1552
1784
  const t = {
1553
- top: F(e.cssSnapshot.marginTop),
1554
- right: F(e.cssSnapshot.marginRight),
1555
- bottom: F(e.cssSnapshot.marginBottom),
1556
- left: F(e.cssSnapshot.marginLeft)
1785
+ top: I(e.cssSnapshot.marginTop),
1786
+ right: I(e.cssSnapshot.marginRight),
1787
+ bottom: I(e.cssSnapshot.marginBottom),
1788
+ left: I(e.cssSnapshot.marginLeft)
1557
1789
  }, n = {
1558
- top: F(e.cssSnapshot.borderTopWidth),
1559
- right: F(e.cssSnapshot.borderRightWidth),
1560
- bottom: F(e.cssSnapshot.borderBottomWidth),
1561
- left: F(e.cssSnapshot.borderLeftWidth)
1790
+ top: I(e.cssSnapshot.borderTopWidth),
1791
+ right: I(e.cssSnapshot.borderRightWidth),
1792
+ bottom: I(e.cssSnapshot.borderBottomWidth),
1793
+ left: I(e.cssSnapshot.borderLeftWidth)
1562
1794
  }, r = {
1563
- top: F(e.cssSnapshot.paddingTop),
1564
- right: F(e.cssSnapshot.paddingRight),
1565
- bottom: F(e.cssSnapshot.paddingBottom),
1566
- left: F(e.cssSnapshot.paddingLeft)
1795
+ top: I(e.cssSnapshot.paddingTop),
1796
+ right: I(e.cssSnapshot.paddingRight),
1797
+ bottom: I(e.cssSnapshot.paddingBottom),
1798
+ left: I(e.cssSnapshot.paddingLeft)
1567
1799
  }, s = {
1568
1800
  top: e.rect.top,
1569
1801
  left: e.rect.left,
@@ -1574,33 +1806,34 @@ function Gt(e) {
1574
1806
  left: s.left - t.left,
1575
1807
  width: s.width + t.left + t.right,
1576
1808
  height: s.height + t.top + t.bottom
1577
- }, g = {
1809
+ }, h = {
1578
1810
  top: s.top + n.top,
1579
1811
  left: s.left + n.left,
1580
1812
  width: Math.max(s.width - n.left - n.right, 0),
1581
1813
  height: Math.max(s.height - n.top - n.bottom, 0)
1582
- }, f = {
1583
- top: g.top + r.top,
1584
- left: g.left + r.left,
1585
- width: Math.max(g.width - r.left - r.right, 0),
1586
- height: Math.max(g.height - r.top - r.bottom, 0)
1814
+ }, w = {
1815
+ top: h.top + r.top,
1816
+ left: h.left + r.left,
1817
+ width: Math.max(h.width - r.left - r.right, 0),
1818
+ height: Math.max(h.height - r.top - r.bottom, 0)
1587
1819
  };
1588
1820
  return {
1589
1821
  margin: c,
1590
1822
  border: s,
1591
- padding: g,
1592
- content: f
1823
+ padding: h,
1824
+ content: w
1593
1825
  };
1594
1826
  }
1595
- function F(e) {
1827
+ function I(e) {
1596
1828
  const t = Number.parseFloat(e);
1597
1829
  return Number.isFinite(t) ? t : 0;
1598
1830
  }
1599
1831
  export {
1600
- Zt as ReviewLensOverlay,
1601
- Qt as ReviewLensProvider,
1602
- X as buildElementTarget,
1603
- ht as createGoogleSheetsAdapter,
1604
- Ct as normalizeReviewUrl,
1605
- Nt as useReviewLens
1832
+ Ot as ReviewLensLogo,
1833
+ bn as ReviewLensOverlay,
1834
+ wn as ReviewLensProvider,
1835
+ Q as buildElementTarget,
1836
+ vt as createGoogleSheetsAdapter,
1837
+ $t as normalizeReviewUrl,
1838
+ Tt as useReviewLens
1606
1839
  };