@thehammer/template-verification 0.1.3 → 0.2.2

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,8 +1,8 @@
1
- import { ref as D, watch as pe, defineComponent as M, computed as d, openBlock as l, createElementBlock as i, normalizeClass as U, createElementVNode as a, toDisplayString as p, createCommentVNode as h, Fragment as O, createVNode as I, unref as m, withCtx as j, createTextVNode as E, renderList as T, createBlock as F, withKeys as me, withModifiers as xe, renderSlot as ge, withDirectives as ye, isRef as te, vModelCheckbox as _e } from "vue";
2
- import { DanxDialog as G, DanxFile as be, DanxButton as Y, DanxInput as he, DanxFileViewer as we, DanxIcon as ke, gearIcon as Se } from "@thehammer/danx-ui";
3
- const A = "tv-chrome", le = "template-verification:enabled";
4
- let R = null;
5
- function Ve(e) {
1
+ import { ref as U, watch as ce, defineComponent as K, computed as d, openBlock as l, createElementBlock as o, normalizeClass as A, createElementVNode as r, toDisplayString as y, createCommentVNode as _, createBlock as N, unref as i, withCtx as I, createTextVNode as T, createVNode as V, Fragment as L, renderList as M, withKeys as Te, withModifiers as Ue, renderSlot as Ne, withDirectives as Ae, isRef as ge, vModelCheckbox as Re } from "vue";
2
+ import { DanxChip as J, CodeViewer as xe, useToast as _e, DanxDialog as re, DanxProgressBar as we, DanxAlert as ye, DanxTabs as Le, MarkdownEditor as je, DanxFileViewer as be, DanxButton as se, DanxInput as Ee, DanxSkeleton as ze, DanxTooltip as Pe, DanxIcon as Me, gearIcon as Be, DanxBadge as Fe, DanxToastContainer as qe } from "@thehammer/danx-ui";
3
+ const P = "tv-chrome", ke = "template-verification:enabled";
4
+ let te = null;
5
+ function Ye(e) {
6
6
  var t;
7
7
  try {
8
8
  return ((t = globalThis.localStorage) == null ? void 0 : t.getItem(e)) ?? null;
@@ -10,123 +10,128 @@ function Ve(e) {
10
10
  return null;
11
11
  }
12
12
  }
13
- function $e(e, t) {
14
- var n;
13
+ function Je(e, t) {
14
+ var a;
15
15
  try {
16
- (n = globalThis.localStorage) == null || n.setItem(e, t);
16
+ (a = globalThis.localStorage) == null || a.setItem(e, t);
17
17
  } catch {
18
18
  }
19
19
  }
20
- function Ce(e) {
21
- const t = Ve(le);
20
+ function Ke(e) {
21
+ const t = Ye(ke);
22
22
  return t === null ? e : t === "true";
23
23
  }
24
- function ae(e) {
25
- const t = D(Ce((e == null ? void 0 : e.defaultEnabled) ?? !1));
26
- return pe(t, (n) => $e(le, n ? "true" : "false")), {
24
+ function $e(e) {
25
+ const t = U(Ke((e == null ? void 0 : e.defaultEnabled) ?? !1));
26
+ return ce(
27
+ t,
28
+ (a) => Je(ke, a ? "true" : "false")
29
+ ), {
27
30
  enabled: t,
28
31
  data: (e == null ? void 0 : e.data) ?? {},
29
32
  saveOverride: e == null ? void 0 : e.saveOverride,
30
33
  workflowInputId: e == null ? void 0 : e.workflowInputId,
31
- comparisonOpen: D(!1)
34
+ auditUrl: e == null ? void 0 : e.auditUrl,
35
+ comparisonOpen: U(!1)
32
36
  };
33
37
  }
34
- function se() {
35
- return R || (R = ae()), R;
38
+ function Se() {
39
+ return te || (te = $e()), te;
36
40
  }
37
- function Bt(e) {
38
- R = ae(e);
41
+ function ha(e) {
42
+ te = $e(e);
39
43
  }
40
- function Q() {
41
- const e = se();
44
+ function le() {
45
+ const e = Se();
42
46
  return {
43
47
  enabled: e.enabled,
44
48
  data: e.data,
45
49
  saveOverride: e.saveOverride,
46
50
  workflowInputId: e.workflowInputId,
51
+ auditUrl: e.auditUrl,
47
52
  openComparison: () => {
48
53
  e.comparisonOpen.value = !0;
49
54
  }
50
55
  };
51
56
  }
52
- function Oe() {
53
- return se().comparisonOpen;
57
+ function He() {
58
+ return Se().comparisonOpen;
54
59
  }
55
- function W(e) {
60
+ function ve(e) {
56
61
  return typeof e != "number" || Number.isNaN(e) ? "unverifiable" : e <= 2 ? "low" : e === 3 ? "medium" : "high";
57
62
  }
58
- const Ie = {
63
+ const Ge = {
59
64
  high: "bg-green-50 text-green-700 ring-1 ring-inset ring-green-600/20",
60
65
  medium: "bg-yellow-50 text-yellow-700 ring-1 ring-inset ring-yellow-600/20",
61
66
  low: "bg-red-50 text-red-700 ring-1 ring-inset ring-red-600/20",
62
67
  unverifiable: "bg-gray-50 text-gray-500 ring-1 ring-inset ring-gray-400/20"
63
- }, Le = {
68
+ }, ae = {
64
69
  high: "High",
65
70
  medium: "Medium",
66
71
  low: "Low",
67
72
  unverifiable: "Unverifiable"
68
- }, ie = ["override", "extracted", "claim"];
69
- function X(e) {
70
- return e ? e.resolved && e.resolved.source && e.resolved.source !== "none" ? e.resolved : Ue(e.candidates) : { value: null, source: "none" };
73
+ }, Ce = ["override", "extracted", "claim"];
74
+ function fe(e) {
75
+ return e ? e.resolved && e.resolved.source && e.resolved.source !== "none" ? e.resolved : Qe(e.candidates) : { value: null, source: "none" };
71
76
  }
72
- function Ue(e) {
77
+ function Qe(e) {
73
78
  if (e)
74
- for (const t of ie) {
75
- const n = e[t];
76
- if (n != null)
77
- return { value: n.value, source: t };
79
+ for (const t of Ce) {
80
+ const a = e[t];
81
+ if (a != null)
82
+ return { value: a.value, source: t };
78
83
  }
79
84
  return { value: null, source: "none" };
80
85
  }
81
- function H(e) {
82
- var f, r;
83
- const t = (r = (f = e == null ? void 0 : e.candidates) == null ? void 0 : f.extracted) == null ? void 0 : r.reasoning;
86
+ function ie(e) {
87
+ var g, m;
88
+ const t = (m = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : m.reasoning;
84
89
  if (t == null) return null;
85
- const n = String(t).trim();
86
- return n === "" ? null : n;
90
+ const a = String(t).trim();
91
+ return a === "" ? null : a;
87
92
  }
88
- function q(e) {
89
- var f, r;
90
- const t = (r = (f = e == null ? void 0 : e.candidates) == null ? void 0 : f.extracted) == null ? void 0 : r.cited_text;
93
+ function oe(e) {
94
+ var g, m;
95
+ const t = (m = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : m.cited_text;
91
96
  if (t == null) return null;
92
- const n = String(t).trim();
93
- return n === "" ? null : n;
97
+ const a = String(t).trim();
98
+ return a === "" ? null : a;
94
99
  }
95
- function re(e) {
96
- return e ? typeof e.discrepancy == "boolean" ? e.discrepancy : De(e.candidates) : !1;
100
+ function Ve(e) {
101
+ return e ? typeof e.discrepancy == "boolean" ? e.discrepancy : We(e.candidates) : !1;
97
102
  }
98
- function De(e) {
103
+ function We(e) {
99
104
  if (!e) return !1;
100
- const t = ie.map((n) => e[n]).filter((n) => n != null).map((n) => Ee(n.value));
105
+ const t = Ce.map((a) => e[a]).filter((a) => a != null).map((a) => Xe(a.value));
101
106
  return t.length < 2 ? !1 : new Set(t).size > 1;
102
107
  }
103
- function Ee(e) {
108
+ function Xe(e) {
104
109
  return JSON.stringify(e ?? null);
105
110
  }
106
- function Te(e, t, n) {
107
- var o;
108
- const f = (o = t.value) == null ? void 0 : o.anchor;
109
- if (!e.saveOverride || !f) return null;
110
- const r = e.saveOverride;
111
- return async (c, g) => {
112
- const b = await r({
111
+ function Ze(e, t, a) {
112
+ var s;
113
+ const g = (s = t.value) == null ? void 0 : s.anchor;
114
+ if (!e.saveOverride || !g) return null;
115
+ const m = e.saveOverride;
116
+ return async (f, n) => {
117
+ const b = await m({
113
118
  workflow_input_id: e.workflowInputId,
114
- object_ids: f.object_ids,
115
- field: f.field,
116
- field_path: f.field_path,
117
- value: c,
118
- source_choice: g
119
+ object_ids: g.object_ids,
120
+ field: g.field,
121
+ field_path: g.field_path,
122
+ value: f,
123
+ source_choice: n
119
124
  });
120
- return n(b), b;
125
+ return a(b), b;
121
126
  };
122
127
  }
123
- const Ae = ["data-status", "title"], Ne = {
128
+ const et = ["data-status", "title"], tt = {
124
129
  class: "tv-confidence-glyph",
125
130
  "aria-hidden": "true"
126
- }, je = {
131
+ }, at = {
127
132
  key: 0,
128
133
  class: "tv-confidence-label"
129
- }, z = /* @__PURE__ */ M({
134
+ }, ue = /* @__PURE__ */ K({
130
135
  __name: "ConfidenceIcon",
131
136
  props: {
132
137
  confidence: {},
@@ -134,9 +139,9 @@ const Ae = ["data-status", "title"], Ne = {
134
139
  showLabel: { type: Boolean }
135
140
  },
136
141
  setup(e) {
137
- const t = e, n = d(
138
- () => t.status ?? W(t.confidence)
139
- ), f = {
142
+ const t = e, a = d(
143
+ () => t.status ?? ve(t.confidence)
144
+ ), g = {
140
145
  high: "✔",
141
146
  // check
142
147
  medium: "⚠",
@@ -144,68 +149,188 @@ const Ae = ["data-status", "title"], Ne = {
144
149
  low: "✕",
145
150
  // x
146
151
  unverifiable: "?"
147
- }, r = d(() => f[n.value]), o = d(() => Ie[n.value]), c = d(() => Le[n.value]);
148
- return (g, b) => (l(), i("span", {
149
- class: U(["tv-confidence-icon inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-semibold leading-none", o.value]),
150
- "data-status": n.value,
151
- title: c.value
152
+ }, m = d(() => g[a.value]), s = d(() => Ge[a.value]), f = d(() => ae[a.value]);
153
+ return (n, b) => (l(), o("span", {
154
+ class: A(["tv-confidence-icon inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-semibold leading-none", s.value]),
155
+ "data-status": a.value,
156
+ title: f.value
152
157
  }, [
153
- a("span", Ne, p(r.value), 1),
154
- e.showLabel ? (l(), i("span", je, p(c.value), 1)) : h("", !0)
155
- ], 10, Ae));
158
+ r("span", tt, y(m.value), 1),
159
+ e.showLabel ? (l(), o("span", at, y(f.value), 1)) : _("", !0)
160
+ ], 10, et));
156
161
  }
157
162
  });
158
- function oe(e) {
163
+ async function lt(e, t) {
164
+ const a = t.object_ids.at(-1), g = new URLSearchParams({
165
+ object_id: String(a),
166
+ field: t.field
167
+ }), m = e.includes("?") ? "&" : "?", s = await fetch(`${e}${m}${g}`);
168
+ if (!s.ok)
169
+ throw new Error(
170
+ `data-point-audit ${s.status}: ${await s.text()}`
171
+ );
172
+ return (await s.json()).data ?? [];
173
+ }
174
+ function De(e) {
175
+ var a, g, m;
159
176
  if (!e || e.length === 0) return [];
160
177
  const t = /* @__PURE__ */ new Map();
161
- for (const n of e) {
162
- const f = Fe(n);
163
- let r = t.get(f);
164
- r || (r = {
165
- fileLabel: Pe(n),
166
- fileUrl: n.file_url,
167
- file: n.file,
178
+ for (const s of e) {
179
+ const f = nt(s);
180
+ let n = t.get(f);
181
+ n || (n = {
182
+ fileLabel: st(s),
183
+ fileUrl: s.file_url ?? ((a = s.file) == null ? void 0 : a.url),
184
+ file: s.file,
168
185
  sources: []
169
- }, t.set(f, r)), !r.fileUrl && n.file_url && (r.fileUrl = n.file_url), !r.file && n.file && (r.file = n.file), r.sources.push(n);
186
+ }, t.set(f, n)), !n.fileUrl && (s.file_url ?? ((g = s.file) == null ? void 0 : g.url)) && (n.fileUrl = s.file_url ?? ((m = s.file) == null ? void 0 : m.url)), !n.file && s.file && (n.file = s.file), n.sources.push(s);
170
187
  }
171
188
  return [...t.values()];
172
189
  }
173
- function Fe(e) {
190
+ function nt(e) {
174
191
  const t = e.file_name ?? e.file_id ?? e.stored_file_id ?? e.source_id ?? e.id;
175
192
  return t != null ? String(t) : "__unknown__";
176
193
  }
177
- function Pe(e) {
194
+ function st(e) {
178
195
  var t;
179
196
  return (t = e.file) != null && t.name ? e.file.name : e.file_name ? e.file_name : e.file_id !== void 0 && e.file_id !== null ? `File ${e.file_id}` : e.stored_file_id !== void 0 && e.stored_file_id !== null ? `File ${e.stored_file_id}` : e.source_type ? e.source_type : "Source";
180
197
  }
181
- function ue(e) {
182
- return e.page !== void 0 && e.page !== null ? `Page ${e.page}` : e.explanation ? String(e.explanation) : e.source_type ? String(e.source_type) : "Citation";
198
+ function rt(e) {
199
+ const t = e.page ?? e.page_number;
200
+ return t != null ? `Page ${t}` : e.explanation ? String(e.explanation) : e.source_type ? String(e.source_type) : "Citation";
183
201
  }
184
- const Me = { class: "tv-modal flex flex-col gap-5 p-4 text-sm text-gray-700" }, Re = { class: "tv-modal-resolved rounded-lg border border-gray-200 bg-gray-50 p-3" }, ze = { class: "mt-1.5 flex flex-wrap items-center gap-2" }, Be = { class: "tv-resolved-value text-lg font-semibold leading-tight text-gray-900" }, Ke = { class: "mt-1 font-mono text-[11px] text-gray-400" }, Ye = { class: "tv-resolved-source" }, Ge = {
185
- key: 0,
186
- class: "tv-discrepancy mt-2 inline-flex items-center gap-1 rounded-full bg-amber-50 px-2 py-0.5 text-[11px] font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20"
187
- }, He = { class: "tv-modal-candidates" }, qe = { class: "mt-1.5 divide-y divide-gray-100 rounded-lg border border-gray-200" }, Je = { class: "w-20 shrink-0 text-xs font-medium text-gray-500" }, Qe = { class: "flex-1 truncate font-mono text-sm text-gray-800" }, We = { class: "shrink-0 text-[11px] text-gray-400" }, Xe = {
202
+ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm" }, ot = { class: "tv-audit-call-header flex flex-wrap items-center gap-2 border-b border-gray-100 bg-gray-50 px-3 py-2" }, ut = {
203
+ key: 2,
204
+ class: "font-mono text-[11px] text-gray-400"
205
+ }, dt = {
206
+ key: 3,
207
+ class: "text-[11px] font-medium text-gray-500"
208
+ }, ct = {
209
+ key: 4,
210
+ class: "text-[11px] text-gray-400"
211
+ }, vt = { class: "tv-audit-call-body flex flex-col gap-2 p-3" }, ft = /* @__PURE__ */ K({
212
+ __name: "AuditCallCard",
213
+ props: {
214
+ call: {}
215
+ },
216
+ setup(e) {
217
+ const t = e, a = d(() => {
218
+ const n = t.call.status_code;
219
+ return n == null ? "muted" : n >= 200 && n < 300 ? "success" : n >= 400 ? "danger" : "warning";
220
+ }), g = d(() => {
221
+ const n = t.call.run_time_ms;
222
+ return n == null ? null : n >= 1e3 ? `${(n / 1e3).toFixed(1)}s` : `${n}ms`;
223
+ }), m = d(() => {
224
+ if (!t.call.started_at) return null;
225
+ const n = new Date(t.call.started_at);
226
+ return Number.isNaN(n.getTime()) ? t.call.started_at : n.toLocaleString();
227
+ }), s = d(
228
+ () => JSON.stringify(t.call.request ?? null, null, 2)
229
+ ), f = d(
230
+ () => JSON.stringify(t.call.response ?? null, null, 2)
231
+ );
232
+ return (n, b) => (l(), o("div", it, [
233
+ r("div", ot, [
234
+ e.call.model ? (l(), N(i(J), {
235
+ key: 0,
236
+ variant: "info",
237
+ size: "xs",
238
+ class: "tv-audit-model"
239
+ }, {
240
+ default: I(() => [
241
+ T(y(e.call.model), 1)
242
+ ]),
243
+ _: 1
244
+ })) : _("", !0),
245
+ e.call.service ? (l(), N(i(J), {
246
+ key: 1,
247
+ variant: "muted",
248
+ size: "xxs"
249
+ }, {
250
+ default: I(() => [
251
+ T(y(e.call.service), 1)
252
+ ]),
253
+ _: 1
254
+ })) : _("", !0),
255
+ e.call.endpoint ? (l(), o("span", ut, y(e.call.endpoint), 1)) : _("", !0),
256
+ b[0] || (b[0] = r("span", { class: "flex-1" }, null, -1)),
257
+ V(i(J), {
258
+ variant: a.value,
259
+ size: "xxs",
260
+ class: "tv-audit-status"
261
+ }, {
262
+ default: I(() => [
263
+ T(y(e.call.status_code ?? "…"), 1)
264
+ ]),
265
+ _: 1
266
+ }, 8, ["variant"]),
267
+ g.value ? (l(), o("span", dt, y(g.value), 1)) : _("", !0),
268
+ m.value ? (l(), o("span", ct, y(m.value), 1)) : _("", !0)
269
+ ]),
270
+ r("div", vt, [
271
+ r("div", null, [
272
+ b[1] || (b[1] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Request ", -1)),
273
+ V(i(xe), {
274
+ "model-value": s.value,
275
+ format: "json",
276
+ collapsible: "",
277
+ "default-collapsed": "",
278
+ class: "tv-audit-request"
279
+ }, null, 8, ["model-value"])
280
+ ]),
281
+ r("div", null, [
282
+ b[2] || (b[2] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Response ", -1)),
283
+ V(i(xe), {
284
+ "model-value": f.value,
285
+ format: "json",
286
+ collapsible: "",
287
+ "default-collapsed": "",
288
+ class: "tv-audit-response"
289
+ }, null, 8, ["model-value"])
290
+ ])
291
+ ])
292
+ ]));
293
+ }
294
+ }), pt = { class: "tv-modal flex h-full flex-col gap-4 overflow-y-auto p-1" }, mt = { class: "tv-modal-resolved flex flex-col gap-3 rounded-xl border border-gray-200 bg-gradient-to-br from-gray-50 to-white p-4 shadow-sm" }, gt = { class: "flex flex-wrap items-start justify-between gap-4" }, xt = { class: "min-w-0 flex-1" }, yt = { class: "tv-resolved-value mt-1 break-words font-mono text-xl font-semibold leading-snug text-gray-900" }, bt = { class: "mt-1 text-[11px] text-gray-400" }, ht = { class: "tv-resolved-source font-medium text-gray-500" }, _t = { class: "tv-confidence-meter w-56 shrink-0" }, wt = { class: "mt-2" }, kt = {
295
+ key: 1,
296
+ class: "tv-confidence-value text-sm text-gray-400"
297
+ }, $t = {
188
298
  key: 0,
189
- class: "tv-modal-provenance flex flex-col gap-2 rounded-lg border border-gray-200 p-3"
190
- }, Ze = { class: "flex items-center justify-between" }, et = { class: "tv-confidence-value font-mono text-sm font-semibold text-gray-800" }, tt = { class: "tv-reasoning whitespace-pre-line text-sm leading-relaxed text-gray-600" }, nt = { class: "tv-cited-text rounded-md border-l-2 border-gray-300 bg-gray-50 py-1.5 pl-3 pr-2 text-sm italic leading-relaxed text-gray-600" }, lt = { class: "tv-modal-sources" }, at = {
299
+ class: "tv-tab-evidence flex min-h-0 flex-1 flex-col gap-4"
300
+ }, St = {
191
301
  key: 0,
192
- class: "tv-no-source mt-1.5 text-sm text-gray-400"
193
- }, st = {
302
+ class: "tv-reasoning-card rounded-lg border border-gray-200 p-3"
303
+ }, Ct = {
194
304
  key: 1,
195
- class: "tv-source-grid mt-2 grid grid-cols-[repeat(auto-fill,minmax(4.5rem,1fr))] items-start gap-3"
196
- }, it = { class: "relative" }, rt = ["href"], ot = {
305
+ class: "tv-cited-text rounded-lg border-l-4 border-blue-200 bg-blue-50/50 px-4 py-3 text-sm italic leading-relaxed text-gray-700"
306
+ }, Vt = {
197
307
  key: 2,
198
- class: "tv-source-name flex h-16 w-16 items-center justify-center rounded-md bg-gray-50 p-1 text-center text-[11px] leading-tight text-gray-500 ring-1 ring-gray-200"
199
- }, ut = {
308
+ class: "tv-evidence-viewer flex min-h-[24rem] flex-1 flex-col overflow-hidden rounded-lg border border-gray-200"
309
+ }, Dt = {
310
+ key: 0,
311
+ class: "tv-page-context border-t border-gray-100 bg-gray-50 px-3 py-2 text-xs text-gray-500"
312
+ }, Ot = {
200
313
  key: 3,
201
- class: "tv-source-count pointer-events-none absolute -right-1.5 -top-1.5 flex h-4 min-w-[1rem] items-center justify-center rounded-full bg-gray-700 px-1 text-[9px] font-semibold text-white"
202
- }, ct = ["title"], dt = {
314
+ class: "tv-no-source rounded-lg border border-dashed border-gray-200 p-6 text-center text-sm text-gray-400"
315
+ }, It = {
316
+ key: 4,
317
+ class: "tv-full-documents flex flex-wrap items-center gap-2"
318
+ }, Tt = {
319
+ key: 1,
320
+ class: "tv-tab-candidates flex flex-col gap-3"
321
+ }, Ut = { class: "flex flex-wrap items-center justify-between gap-3" }, Nt = { class: "min-w-0 flex-1" }, At = { class: "flex items-center gap-2" }, Rt = { class: "mt-2 break-words font-mono text-base text-gray-900" }, Lt = { class: "mt-1 text-xs text-gray-400" }, jt = {
203
322
  key: 0,
204
- class: "tv-source-citations flex flex-wrap justify-center gap-1"
205
- }, ft = {
323
+ class: "tv-custom-entry flex items-center gap-2 rounded-lg border border-dashed border-gray-300 p-4"
324
+ }, Et = {
206
325
  key: 1,
207
- class: "tv-modal-resolution flex flex-col gap-2 border-t border-gray-200 pt-4"
208
- }, vt = { class: "flex flex-wrap gap-2" }, pt = { class: "flex items-center gap-2" }, mt = /* @__PURE__ */ M({
326
+ class: "tv-read-only text-center text-xs text-gray-400"
327
+ }, zt = {
328
+ key: 2,
329
+ class: "tv-tab-audit flex flex-col gap-3"
330
+ }, Pt = {
331
+ key: 2,
332
+ class: "tv-audit-empty rounded-lg border border-dashed border-gray-200 p-6 text-center text-sm text-gray-400"
333
+ }, Mt = /* @__PURE__ */ K({
209
334
  __name: "VerificationModal",
210
335
  props: {
211
336
  modelValue: { type: Boolean },
@@ -215,255 +340,391 @@ const Me = { class: "tv-modal flex flex-col gap-5 p-4 text-sm text-gray-700" },
215
340
  },
216
341
  emits: ["update:modelValue", "saved"],
217
342
  setup(e, { emit: t }) {
218
- const n = e, f = t, r = d({
219
- get: () => n.modelValue,
220
- set: (s) => f("update:modelValue", s)
221
- }), o = d(() => X(n.meta)), c = d(() => n.meta.candidates.extracted), g = d(() => n.meta.candidates.claim), b = d(() => n.meta.candidates.override), w = d(
222
- () => {
223
- var s;
224
- return W((s = c.value) == null ? void 0 : s.confidence);
225
- }
226
- ), _ = d(() => H(n.meta)), v = d(() => q(n.meta)), V = d(() => {
227
- var s;
228
- return oe((s = c.value) == null ? void 0 : s.sources);
229
- }), L = d(
230
- () => V.value.map((s) => s.file).filter((s) => !!s)
231
- ), C = D(null), k = d({
232
- get: () => C.value !== null,
233
- set: (s) => {
234
- s || (C.value = null);
343
+ const a = e, g = t, m = le(), s = _e(), f = d({
344
+ get: () => a.modelValue,
345
+ set: (v) => g("update:modelValue", v)
346
+ }), n = d(() => fe(a.meta)), b = d(() => a.meta.candidates.extracted), $ = d(() => a.meta.candidates.claim), h = d(() => a.meta.candidates.override), x = d(() => {
347
+ var v;
348
+ return ((v = b.value) == null ? void 0 : v.confidence) ?? null;
349
+ }), k = d(() => ve(x.value)), S = d(() => ie(a.meta)), R = d(() => oe(a.meta)), O = d(() => {
350
+ var v;
351
+ return De((v = b.value) == null ? void 0 : v.sources);
352
+ }), j = d(() => (a.meta.anchor.field_path || a.label || "Data point").split(".").map(
353
+ (u) => u.replace(/\[\d+\]/g, "").replace(/_/g, " ").replace(/^\w/, (C) => C.toUpperCase())
354
+ ).join(" › ")), H = {
355
+ high: "success",
356
+ medium: "warning",
357
+ low: "danger",
358
+ unverifiable: "muted"
359
+ }, E = U("evidence"), W = d(() => !!m.auditUrl), X = d(() => {
360
+ var u;
361
+ const v = [
362
+ {
363
+ value: "evidence",
364
+ label: "Evidence",
365
+ count: O.value.reduce((C, c) => C + c.sources.length, 0)
366
+ },
367
+ {
368
+ value: "candidates",
369
+ label: "Candidates",
370
+ count: Q.value.length
371
+ }
372
+ ];
373
+ return W.value && v.push({
374
+ value: "audit",
375
+ label: "Audit trail",
376
+ count: ((u = F.value) == null ? void 0 : u.length) ?? void 0
377
+ }), v;
378
+ }), q = d(
379
+ () => O.value.map((v) => v.file).filter((v) => !!v)
380
+ ), p = U(null), w = d(() => {
381
+ const v = p.value ?? q.value[0];
382
+ if (!v) return null;
383
+ const u = O.value.find(
384
+ (c) => c.file && String(c.file.id) === String(v.id)
385
+ );
386
+ if (!u) return null;
387
+ const C = u.sources.find((c) => c.explanation);
388
+ return (C == null ? void 0 : C.explanation) ?? null;
389
+ }), D = d(() => {
390
+ const v = /* @__PURE__ */ new Map();
391
+ for (const u of O.value)
392
+ for (const C of u.sources) {
393
+ const c = C.original_file;
394
+ c && !v.has(String(c.id)) && v.set(String(c.id), c);
395
+ }
396
+ return [...v.values()];
397
+ }), z = U(null), G = d({
398
+ get: () => z.value !== null,
399
+ set: (v) => {
400
+ v || (z.value = null);
235
401
  }
236
- });
237
- function N(s) {
238
- s.file && (C.value = s);
239
- }
240
- const B = d(() => {
241
- const s = [];
242
- return b.value && s.push({
243
- source: "Override",
402
+ }), Q = d(() => {
403
+ const v = [];
404
+ return h.value && v.push({
405
+ key: "override",
406
+ title: "Human override",
407
+ variant: "success",
408
+ value: h.value.value,
409
+ detail: [
410
+ h.value.source_choice ? `basis: ${h.value.source_choice}` : null,
411
+ h.value.set_at ? new Date(h.value.set_at).toLocaleString() : null
412
+ ].filter(Boolean).join(" · "),
413
+ winner: n.value.source === "override"
414
+ }), b.value && v.push({
415
+ key: "extracted",
416
+ title: "Extracted",
417
+ variant: H[k.value],
244
418
  value: b.value.value,
245
- detail: b.value.source_choice ? `via ${b.value.source_choice}` : void 0
246
- }), c.value && s.push({
247
- source: "Extracted",
248
- value: c.value.value,
249
- detail: S(c.value.confidence)
250
- }), g.value && s.push({
251
- source: "Claim",
252
- value: g.value.value,
253
- detail: g.value.claim_set_label ?? void 0
254
- }), s;
255
- }), P = D(""), y = D(!1);
256
- function S(s) {
257
- return s == null ? "Unverifiable" : `${s}/5`;
258
- }
259
- function $(s) {
260
- return s == null ? "" : String(s);
261
- }
262
- async function K(s, u) {
263
- if (!(!n.save || y.value)) {
264
- y.value = !0;
419
+ detail: x.value != null ? `Confidence ${x.value}/5 · ${ae[k.value]}` : "No confidence recorded",
420
+ accept: a.save ? () => {
421
+ var u;
422
+ return ne(pe((u = b.value) == null ? void 0 : u.value), "extracted");
423
+ } : void 0,
424
+ winner: n.value.source === "extracted"
425
+ }), $.value && v.push({
426
+ key: "claim",
427
+ title: "Claim",
428
+ variant: "info",
429
+ value: $.value.value,
430
+ detail: $.value.claim_set_label ?? "Reference output",
431
+ accept: a.save ? () => {
432
+ var u;
433
+ return ne(pe((u = $.value) == null ? void 0 : u.value), "claim");
434
+ } : void 0,
435
+ winner: n.value.source === "claim"
436
+ }), v;
437
+ }), B = U(""), Y = U(!1);
438
+ async function ne(v, u) {
439
+ if (!(!a.save || Y.value)) {
440
+ Y.value = !0;
265
441
  try {
266
- const x = await n.save(s, u);
267
- f("saved", x);
442
+ const C = await a.save(v, u);
443
+ g("saved", C), s.success(`Verified — ${j.value} locked in`);
444
+ } catch {
445
+ s.danger(`Could not save ${j.value} — try again`);
268
446
  } finally {
269
- y.value = !1;
447
+ Y.value = !1;
270
448
  }
271
449
  }
272
450
  }
273
- const ce = () => {
274
- var s;
275
- return K(Z((s = c.value) == null ? void 0 : s.value), "extracted");
276
- }, de = () => {
277
- var s;
278
- return K(Z((s = g.value) == null ? void 0 : s.value), "claim");
279
- }, fe = () => K(P.value, "custom");
280
- function Z(s) {
281
- return s == null ? null : String(s);
451
+ const Ie = () => ne(B.value, "custom");
452
+ function pe(v) {
453
+ return v == null ? null : String(v);
454
+ }
455
+ function me(v) {
456
+ return v == null ? "—" : String(v);
282
457
  }
283
- return (s, u) => (l(), i(O, null, [
284
- I(m(G), {
285
- modelValue: r.value,
286
- "onUpdate:modelValue": u[1] || (u[1] = (x) => r.value = x),
287
- title: e.label || "Verification detail",
458
+ const F = U(null), Z = U(!1), ee = U(null);
459
+ return ce(
460
+ [E, f],
461
+ async ([v, u]) => {
462
+ if (!(v !== "audit" || !u || F.value !== null || Z.value) && m.auditUrl) {
463
+ Z.value = !0, ee.value = null;
464
+ try {
465
+ F.value = await lt(
466
+ m.auditUrl,
467
+ a.meta.anchor
468
+ );
469
+ } catch (C) {
470
+ ee.value = C instanceof Error ? C.message : String(C);
471
+ } finally {
472
+ Z.value = !1;
473
+ }
474
+ }
475
+ },
476
+ { immediate: !0 }
477
+ ), (v, u) => (l(), o(L, null, [
478
+ V(i(re), {
479
+ modelValue: f.value,
480
+ "onUpdate:modelValue": u[3] || (u[3] = (C) => f.value = C),
481
+ title: j.value,
482
+ width: 90,
483
+ height: 90,
288
484
  "close-x": "",
289
- class: U(m(A))
485
+ class: A(i(P))
290
486
  }, {
291
- default: j(() => [
292
- a("div", Me, [
293
- a("section", Re, [
294
- u[4] || (u[4] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Resolved value ", -1)),
295
- a("div", ze, [
296
- a("span", Be, p($(o.value.value) || "—"), 1),
297
- I(z, {
298
- status: w.value,
299
- "show-label": ""
300
- }, null, 8, ["status"])
301
- ]),
302
- a("div", Ke, [
303
- u[3] || (u[3] = E(" source: ", -1)),
304
- a("span", Ye, p(o.value.source), 1)
305
- ]),
306
- e.meta.discrepancy ? (l(), i("div", Ge, " ⚠ Sources disagree ")) : h("", !0)
307
- ]),
308
- a("section", He, [
309
- u[5] || (u[5] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Candidates ", -1)),
310
- a("div", qe, [
311
- (l(!0), i(O, null, T(B.value, (x) => (l(), i("div", {
312
- key: x.source,
313
- class: "tv-candidate-row flex items-center gap-3 px-3 py-2"
314
- }, [
315
- a("span", Je, p(x.source), 1),
316
- a("span", Qe, p($(x.value)), 1),
317
- a("span", We, p(x.detail), 1)
318
- ]))), 128))
319
- ])
320
- ]),
321
- c.value ? (l(), i("section", Xe, [
322
- a("div", Ze, [
323
- u[6] || (u[6] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Confidence ", -1)),
324
- a("div", et, p(S(c.value.confidence)), 1)
325
- ]),
326
- _.value ? (l(), i(O, { key: 0 }, [
327
- u[7] || (u[7] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Reasoning ", -1)),
328
- a("p", tt, p(_.value), 1)
329
- ], 64)) : h("", !0),
330
- v.value ? (l(), i(O, { key: 1 }, [
331
- u[8] || (u[8] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Cited text ", -1)),
332
- a("blockquote", nt, [
333
- E(p(v.value) + " ", 1),
334
- a("span", {
335
- class: U([
336
- "tv-cited-verified ml-1 not-italic text-[11px] font-medium",
337
- c.value.cited_text_verified ? "text-green-600" : "text-gray-400"
487
+ default: I(() => {
488
+ var C;
489
+ return [
490
+ r("div", pt, [
491
+ r("section", mt, [
492
+ r("div", gt, [
493
+ r("div", xt, [
494
+ u[6] || (u[6] = r("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Resolved value ", -1)),
495
+ r("div", yt, y(me(n.value.value)), 1),
496
+ r("div", bt, [
497
+ u[5] || (u[5] = T(" source of truth: ", -1)),
498
+ r("span", ht, y(n.value.source), 1)
338
499
  ])
339
- }, p(c.value.cited_text_verified ? "✔ verified" : "unverified"), 3)
340
- ])
341
- ], 64)) : h("", !0)
342
- ])) : h("", !0),
343
- a("section", lt, [
344
- u[9] || (u[9] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Sources ", -1)),
345
- V.value.length === 0 ? (l(), i("div", at, " No source recorded ")) : (l(), i("div", st, [
346
- (l(!0), i(O, null, T(V.value, (x) => (l(), i("div", {
347
- key: x.fileLabel,
348
- class: "tv-source-group flex flex-col items-center gap-1"
349
- }, [
350
- a("div", it, [
351
- x.file ? (l(), F(m(be), {
352
- key: 0,
353
- file: x.file,
354
- size: "sm",
355
- class: "tv-source-thumb cursor-pointer rounded-md ring-1 ring-gray-200 transition duration-150 hover:-translate-y-0.5 hover:shadow-md hover:ring-gray-300",
356
- onClick: (ee) => N(x)
357
- }, null, 8, ["file", "onClick"])) : x.fileUrl ? (l(), i("a", {
358
- key: 1,
359
- href: x.fileUrl,
360
- class: "tv-source-link flex h-16 w-16 items-center justify-center rounded-md bg-gray-50 p-1 text-center text-[11px] font-medium leading-tight text-blue-600 underline ring-1 ring-gray-200",
361
- target: "_blank",
362
- rel: "noopener"
363
- }, p(x.fileLabel), 9, rt)) : (l(), i("span", ot, p(x.fileLabel), 1)),
364
- x.sources.length > 1 ? (l(), i("span", ut, "×" + p(x.sources.length), 1)) : h("", !0)
365
500
  ]),
366
- a("span", {
367
- class: "tv-source-file-label w-full truncate text-center text-[11px] text-gray-500",
368
- title: x.fileLabel
369
- }, p(x.fileLabel), 9, ct),
370
- x.sources.length > 1 ? (l(), i("ul", dt, [
371
- (l(!0), i(O, null, T(x.sources, (ee, ve) => (l(), i("li", {
372
- key: ve,
373
- class: "tv-source-row rounded bg-gray-100 px-1 py-0.5 font-mono text-[10px] text-gray-500"
374
- }, p(m(ue)(ee)), 1))), 128))
375
- ])) : h("", !0)
376
- ]))), 128))
377
- ]))
378
- ]),
379
- e.save ? (l(), i("section", ft, [
380
- u[13] || (u[13] = a("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Resolve ", -1)),
381
- a("div", vt, [
382
- c.value ? (l(), F(m(Y), {
501
+ r("div", _t, [
502
+ u[7] || (u[7] = r("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Extraction confidence ", -1)),
503
+ r("div", wt, [
504
+ x.value != null ? (l(), N(i(we), {
505
+ key: 0,
506
+ value: x.value,
507
+ max: 5,
508
+ size: "md",
509
+ variant: H[k.value],
510
+ gradient: "",
511
+ shimmer: "",
512
+ "show-text": "",
513
+ "text-position": "beside",
514
+ label: `${x.value}/5`
515
+ }, null, 8, ["value", "variant", "label"])) : (l(), o("div", kt, " No confidence recorded "))
516
+ ]),
517
+ r("div", {
518
+ class: A(["tv-confidence-label mt-1 text-right text-xs font-medium", {
519
+ "text-green-600": k.value === "high",
520
+ "text-yellow-600": k.value === "medium",
521
+ "text-red-600": k.value === "low",
522
+ "text-gray-400": k.value === "unverifiable"
523
+ }])
524
+ }, y(i(ae)[k.value]), 3)
525
+ ])
526
+ ]),
527
+ e.meta.discrepancy ? (l(), N(i(ye), {
383
528
  key: 0,
384
- variant: "info",
385
- size: "sm",
386
- class: "tv-accept-extracted",
387
- disabled: y.value,
388
- onClick: ce
529
+ variant: "warning",
530
+ class: "tv-discrepancy"
389
531
  }, {
390
- default: j(() => [...u[10] || (u[10] = [
391
- E("Accept extracted", -1)
532
+ default: I(() => [...u[8] || (u[8] = [
533
+ T(" Sources disagree on this value — review the candidates and pick a winner. ", -1)
392
534
  ])]),
393
535
  _: 1
394
- }, 8, ["disabled"])) : h("", !0),
395
- g.value ? (l(), F(m(Y), {
396
- key: 1,
397
- variant: "muted",
398
- size: "sm",
399
- class: "tv-accept-claim",
400
- disabled: y.value,
401
- onClick: de
402
- }, {
403
- default: j(() => [...u[11] || (u[11] = [
404
- E("Accept claim", -1)
405
- ])]),
406
- _: 1
407
- }, 8, ["disabled"])) : h("", !0)
536
+ })) : _("", !0)
408
537
  ]),
409
- a("div", pt, [
410
- I(m(he), {
411
- modelValue: P.value,
412
- "onUpdate:modelValue": u[0] || (u[0] = (x) => P.value = x),
413
- size: "sm",
414
- class: "tv-custom-input flex-1",
415
- placeholder: "Type a custom value",
416
- disabled: y.value
417
- }, null, 8, ["modelValue", "disabled"]),
418
- I(m(Y), {
419
- variant: "success",
420
- size: "sm",
421
- class: "tv-accept-custom",
422
- disabled: y.value,
423
- onClick: fe
538
+ V(i(Le), {
539
+ modelValue: E.value,
540
+ "onUpdate:modelValue": u[0] || (u[0] = (c) => E.value = c),
541
+ tabs: X.value,
542
+ class: "tv-modal-tabs"
543
+ }, null, 8, ["modelValue", "tabs"]),
544
+ E.value === "evidence" ? (l(), o("section", $t, [
545
+ S.value ? (l(), o("div", St, [
546
+ u[9] || (u[9] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Reasoning ", -1)),
547
+ V(i(je), {
548
+ "model-value": S.value,
549
+ readonly: "",
550
+ class: "tv-reasoning"
551
+ }, null, 8, ["model-value"])
552
+ ])) : _("", !0),
553
+ R.value ? (l(), o("blockquote", Ct, [
554
+ T(" “" + y(R.value) + "” ", 1),
555
+ V(i(J), {
556
+ variant: (C = b.value) != null && C.cited_text_verified ? "success" : "muted",
557
+ size: "xxs",
558
+ class: "tv-cited-verified ml-2 not-italic"
559
+ }, {
560
+ default: I(() => {
561
+ var c;
562
+ return [
563
+ T(y((c = b.value) != null && c.cited_text_verified ? "✔ verified in source" : "unverified"), 1)
564
+ ];
565
+ }),
566
+ _: 1
567
+ }, 8, ["variant"])
568
+ ])) : _("", !0),
569
+ q.value.length ? (l(), o("div", Vt, [
570
+ V(i(be), {
571
+ file: q.value[0],
572
+ "file-in-preview": p.value,
573
+ "onUpdate:fileInPreview": u[1] || (u[1] = (c) => p.value = c),
574
+ "related-files": q.value,
575
+ "layout-toggles": ["sidebar", "continuous"],
576
+ "default-sidebar": "",
577
+ zoomable: "",
578
+ "storage-key": "tv-evidence-viewer",
579
+ class: "h-full min-h-0 flex-1"
580
+ }, null, 8, ["file", "file-in-preview", "related-files"]),
581
+ w.value ? (l(), o("div", Dt, y(w.value), 1)) : _("", !0)
582
+ ])) : (l(), o("div", Ot, " No source pages recorded for this data point ")),
583
+ D.value.length ? (l(), o("div", It, [
584
+ u[10] || (u[10] = r("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Full documents:", -1)),
585
+ (l(!0), o(L, null, M(D.value, (c) => (l(), N(i(se), {
586
+ key: String(c.id),
587
+ size: "sm",
588
+ variant: "info",
589
+ class: "tv-open-document",
590
+ onClick: (xa) => z.value = c
591
+ }, {
592
+ default: I(() => [
593
+ T(y(c.name), 1)
594
+ ]),
595
+ _: 2
596
+ }, 1032, ["onClick"]))), 128))
597
+ ])) : _("", !0)
598
+ ])) : _("", !0),
599
+ E.value === "candidates" ? (l(), o("section", Tt, [
600
+ (l(!0), o(L, null, M(Q.value, (c) => (l(), o("div", {
601
+ key: c.key,
602
+ class: A(["tv-candidate-row rounded-lg border p-4 transition-shadow", [
603
+ c.winner ? "border-gray-300 bg-gray-50 shadow-sm" : "border-gray-200",
604
+ e.meta.discrepancy && !c.winner ? "tv-candidate-disagrees border-amber-200" : ""
605
+ ]])
606
+ }, [
607
+ r("div", Ut, [
608
+ r("div", Nt, [
609
+ r("div", At, [
610
+ V(i(J), {
611
+ variant: c.variant,
612
+ size: "xs"
613
+ }, {
614
+ default: I(() => [
615
+ T(y(c.title), 1)
616
+ ]),
617
+ _: 2
618
+ }, 1032, ["variant"]),
619
+ c.winner ? (l(), N(i(J), {
620
+ key: 0,
621
+ variant: "success",
622
+ size: "xxs",
623
+ class: "tv-winner-chip"
624
+ }, {
625
+ default: I(() => [...u[11] || (u[11] = [
626
+ T("current value", -1)
627
+ ])]),
628
+ _: 1
629
+ })) : _("", !0)
630
+ ]),
631
+ r("div", Rt, y(me(c.value)), 1),
632
+ r("div", Lt, y(c.detail), 1)
633
+ ]),
634
+ c.accept && !c.winner ? (l(), N(i(se), {
635
+ key: 0,
636
+ size: "sm",
637
+ variant: c.variant,
638
+ loading: Y.value,
639
+ class: A(`tv-accept-${c.key}`),
640
+ onClick: c.accept
641
+ }, {
642
+ default: I(() => [...u[12] || (u[12] = [
643
+ T("Accept this value", -1)
644
+ ])]),
645
+ _: 1
646
+ }, 8, ["variant", "loading", "class", "onClick"])) : _("", !0)
647
+ ])
648
+ ], 2))), 128)),
649
+ e.save ? (l(), o("div", jt, [
650
+ V(i(Ee), {
651
+ modelValue: B.value,
652
+ "onUpdate:modelValue": u[2] || (u[2] = (c) => B.value = c),
653
+ size: "sm",
654
+ class: "tv-custom-input flex-1",
655
+ placeholder: "Type the correct value…",
656
+ disabled: Y.value
657
+ }, null, 8, ["modelValue", "disabled"]),
658
+ V(i(se), {
659
+ variant: "success",
660
+ size: "sm",
661
+ class: "tv-accept-custom",
662
+ loading: Y.value,
663
+ disabled: !B.value,
664
+ onClick: Ie
665
+ }, {
666
+ default: I(() => [...u[13] || (u[13] = [
667
+ T("Save custom value", -1)
668
+ ])]),
669
+ _: 1
670
+ }, 8, ["loading", "disabled"])
671
+ ])) : (l(), o("div", Et, " Read-only render — corrections are disabled here "))
672
+ ])) : _("", !0),
673
+ E.value === "audit" ? (l(), o("section", zt, [
674
+ Z.value ? (l(), o(L, { key: 0 }, M(2, (c) => V(i(ze), {
675
+ key: c,
676
+ shape: "rounded",
677
+ class: "tv-audit-skeleton h-24 w-full"
678
+ })), 64)) : ee.value ? (l(), N(i(ye), {
679
+ key: 1,
680
+ variant: "danger",
681
+ class: "tv-audit-error"
424
682
  }, {
425
- default: j(() => [...u[12] || (u[12] = [
426
- E("Type custom", -1)
427
- ])]),
683
+ default: I(() => [
684
+ T(" Could not load the audit trail: " + y(ee.value), 1)
685
+ ]),
428
686
  _: 1
429
- }, 8, ["disabled"])
430
- ])
431
- ])) : h("", !0)
432
- ])
433
- ]),
687
+ })) : F.value && F.value.length === 0 ? (l(), o("div", Pt, " No LLM calls recorded for this data point ")) : F.value ? (l(!0), o(L, { key: 3 }, M(F.value, (c) => (l(), N(ft, {
688
+ key: String(c.id),
689
+ call: c
690
+ }, null, 8, ["call"]))), 128)) : _("", !0)
691
+ ])) : _("", !0)
692
+ ])
693
+ ];
694
+ }),
434
695
  _: 1
435
696
  }, 8, ["modelValue", "title", "class"]),
436
- C.value ? (l(), F(m(G), {
697
+ z.value ? (l(), N(i(re), {
437
698
  key: 0,
438
- modelValue: k.value,
439
- "onUpdate:modelValue": u[2] || (u[2] = (x) => k.value = x),
699
+ modelValue: G.value,
700
+ "onUpdate:modelValue": u[4] || (u[4] = (C) => G.value = C),
701
+ title: z.value.name,
440
702
  width: 90,
441
703
  height: 90,
442
704
  "close-x": "",
443
- class: U(m(A))
705
+ class: A(i(P))
444
706
  }, {
445
- default: j(() => [
446
- C.value.file ? (l(), F(m(we), {
447
- key: 0,
448
- file: C.value.file,
449
- "related-files": L.value,
450
- "children-label": "Pages",
451
- continuous: "",
452
- sidebar: "",
707
+ default: I(() => [
708
+ V(i(be), {
709
+ file: z.value,
710
+ downloadable: "",
453
711
  zoomable: "",
454
- class: "h-full"
455
- }, null, 8, ["file", "related-files"])) : h("", !0)
712
+ class: "tv-document-viewer h-full"
713
+ }, null, 8, ["file"])
456
714
  ]),
457
715
  _: 1
458
- }, 8, ["modelValue", "class"])) : h("", !0)
716
+ }, 8, ["modelValue", "title", "class"])) : _("", !0)
459
717
  ], 64));
460
718
  }
461
- }), xt = { class: "tv-field inline-flex items-center gap-1" }, gt = ["contenteditable", "data-editable"], yt = {
462
- key: 0,
463
- class: "tv-discrepancy-indicator ml-0.5 text-amber-600",
464
- title: "Sources disagree",
719
+ }), Bt = { class: "tv-field inline-flex items-baseline gap-1" }, Ft = ["contenteditable", "data-editable"], qt = {
720
+ key: 1,
721
+ class: "tv-verified-chip inline-flex items-center gap-1 rounded-full bg-green-600 px-2 py-0.5 text-[11px] font-semibold leading-none text-white",
722
+ "data-status": "verified"
723
+ }, Yt = {
724
+ key: 2,
725
+ class: "tv-discrepancy-indicator ml-0.5 text-amber-500",
465
726
  "aria-label": "discrepancy"
466
- }, Kt = /* @__PURE__ */ M({
727
+ }, _a = /* @__PURE__ */ K({
467
728
  __name: "VerifiedField",
468
729
  props: {
469
730
  source: {},
@@ -472,278 +733,394 @@ const Me = { class: "tv-modal flex flex-col gap-5 p-4 text-sm text-gray-700" },
472
733
  format: { type: Function }
473
734
  },
474
735
  setup(e) {
475
- const t = e, n = Q(), f = d(() => n.enabled.value), r = D(null), o = d(() => {
476
- var y;
477
- return r.value ? r.value : t.source && t.field ? ((y = t.source.__meta) == null ? void 0 : y[t.field]) ?? null : null;
478
- }), c = d(() => X(o.value)), g = d(() => {
479
- if (t.original !== void 0 && t.original !== null) return t.original;
480
- if (o.value) return c.value.value;
736
+ const t = e, a = le(), g = d(() => a.enabled.value), m = U(null), s = d(() => {
737
+ var p;
738
+ return m.value ? m.value : t.source && t.field ? ((p = t.source.__meta) == null ? void 0 : p[t.field]) ?? null : null;
739
+ }), f = d(() => fe(s.value)), n = d(() => {
740
+ if (t.original !== void 0 && t.original !== null)
741
+ return t.original;
742
+ if (s.value && f.value.value !== null && f.value.value !== void 0)
743
+ return f.value.value;
481
744
  if (t.source && t.field) return t.source[t.field];
482
745
  }), b = d(() => {
483
- const y = g.value;
484
- return y == null ? "" : t.format ? t.format(y) : String(y);
485
- }), w = d(() => {
486
- var y, S, $;
487
- return W(($ = (S = (y = o.value) == null ? void 0 : y.candidates) == null ? void 0 : S.extracted) == null ? void 0 : $.confidence);
488
- }), _ = d(() => re(o.value)), v = d(() => f.value && !!o.value);
489
- function V(y) {
490
- var S;
491
- r.value = y, (S = t.source) != null && S.__meta && t.field && (t.source.__meta[t.field] = y);
746
+ const p = n.value;
747
+ return p == null ? "" : typeof t.format == "function" ? t.format(p) : String(p);
748
+ }), $ = d(
749
+ () => {
750
+ var p, w, D;
751
+ return ve((D = (w = (p = s.value) == null ? void 0 : p.candidates) == null ? void 0 : w.extracted) == null ? void 0 : D.confidence);
752
+ }
753
+ ), h = d(() => Ve(s.value)), x = d(() => {
754
+ var p, w;
755
+ return !!((w = (p = s.value) == null ? void 0 : p.candidates) != null && w.override);
756
+ }), k = d(() => {
757
+ var w;
758
+ const p = (w = s.value) == null ? void 0 : w.candidates;
759
+ return !!(p != null && p.override || p != null && p.extracted || p != null && p.claim);
760
+ }), S = d(() => g.value && !!s.value), R = d(() => {
761
+ var G, Q, B;
762
+ const p = (Q = (G = s.value) == null ? void 0 : G.candidates) == null ? void 0 : Q.extracted;
763
+ if (!p) return "No verification data";
764
+ const w = [], D = ae[$.value];
765
+ w.push(
766
+ p.confidence != null ? `${D} (${p.confidence}/5)` : D
767
+ );
768
+ const z = ((B = p.sources) == null ? void 0 : B.length) ?? 0;
769
+ return z > 0 && w.push(`${z} source ${z === 1 ? "page" : "pages"}`), h.value && w.push("sources disagree"), w.join(" · ");
770
+ });
771
+ function O(p) {
772
+ var w;
773
+ m.value = p, (w = t.source) != null && w.__meta && t.field && (t.source.__meta[t.field] = p);
492
774
  }
493
- const L = d(() => Te(n, o, V)), C = d(() => !!L.value), k = D(!1), N = D(!1);
494
- function B() {
495
- o.value && (k.value = !0);
775
+ const j = d(() => Ze(a, s, O)), H = d(() => !!j.value), E = U(!1), W = U(!1);
776
+ function X() {
777
+ s.value && (E.value = !0);
496
778
  }
497
- async function P(y) {
498
- N.value = !1;
499
- const $ = (y.target.textContent ?? "").trim();
500
- !L.value || $ === b.value || await L.value($, "custom");
779
+ async function q(p) {
780
+ W.value = !1;
781
+ const D = (p.target.textContent ?? "").trim();
782
+ !j.value || D === b.value || await j.value(D, "custom");
501
783
  }
502
- return (y, S) => (l(), i("span", xt, [
503
- a("span", {
504
- class: "tv-field-value",
505
- contenteditable: C.value,
506
- "data-editable": C.value ? "true" : "false",
507
- onFocus: S[0] || (S[0] = ($) => N.value = !0),
508
- onBlur: P,
509
- onKeydown: S[1] || (S[1] = me(xe(($) => $.target.blur(), ["prevent"]), ["enter"]))
784
+ return (p, w) => (l(), o("span", Bt, [
785
+ r("span", {
786
+ class: A([
787
+ "tv-field-value",
788
+ S.value && !k.value ? "tv-field-unverified cursor-pointer border-b border-dotted border-gray-300" : ""
789
+ ]),
790
+ contenteditable: H.value,
791
+ "data-editable": H.value ? "true" : "false",
792
+ onFocus: w[0] || (w[0] = (D) => W.value = !0),
793
+ onBlur: q,
794
+ onKeydown: w[1] || (w[1] = Te(Ue((D) => D.target.blur(), ["prevent"]), ["enter"])),
795
+ onClick: w[2] || (w[2] = (D) => S.value && !k.value ? X() : void 0)
510
796
  }, [
511
- ge(y.$slots, "default", {
512
- value: g.value,
797
+ Ne(p.$slots, "default", {
798
+ value: n.value,
513
799
  formatted: b.value
514
800
  }, () => [
515
- E(p(b.value), 1)
801
+ T(y(b.value), 1)
516
802
  ])
517
- ], 40, gt),
518
- v.value ? (l(), i("button", {
803
+ ], 42, Ft),
804
+ S.value && k.value ? (l(), N(i(Pe), {
519
805
  key: 0,
520
- type: "button",
521
- class: U(["tv-overlay ml-1 inline-flex items-center", m(A)]),
522
- title: "View verification detail",
523
- onClick: B
524
- }, [
525
- I(z, { status: w.value }, null, 8, ["status"]),
526
- _.value ? (l(), i("span", yt, "⚠")) : h("", !0)
527
- ], 2)) : h("", !0),
528
- o.value ? (l(), F(mt, {
806
+ tooltip: R.value,
807
+ placement: "top"
808
+ }, {
809
+ trigger: I(() => [
810
+ r("button", {
811
+ type: "button",
812
+ class: A(["tv-overlay inline-flex cursor-pointer items-center align-middle transition-transform duration-150 hover:scale-110", i(P)]),
813
+ onClick: X
814
+ }, [
815
+ x.value ? (l(), o("span", qt, "✔")) : (l(), N(ue, {
816
+ key: 0,
817
+ status: $.value
818
+ }, null, 8, ["status"])),
819
+ h.value && !x.value ? (l(), o("span", Yt, "⚠")) : _("", !0)
820
+ ], 2)
821
+ ]),
822
+ _: 1
823
+ }, 8, ["tooltip"])) : _("", !0),
824
+ s.value ? (l(), N(Mt, {
529
825
  key: 1,
530
- modelValue: k.value,
531
- "onUpdate:modelValue": S[2] || (S[2] = ($) => k.value = $),
532
- meta: o.value,
826
+ modelValue: E.value,
827
+ "onUpdate:modelValue": w[3] || (w[3] = (D) => E.value = D),
828
+ meta: s.value,
533
829
  label: e.field,
534
- save: L.value
535
- }, null, 8, ["modelValue", "meta", "label", "save"])) : h("", !0)
830
+ save: j.value
831
+ }, null, 8, ["modelValue", "meta", "label", "save"])) : _("", !0)
536
832
  ]));
537
833
  }
538
- }), _t = /* @__PURE__ */ new Set(["name", "type"]);
539
- function bt(e, t = "") {
540
- const n = [];
541
- return J(e, t, n), n;
834
+ }), Jt = /* @__PURE__ */ new Set(["name", "type"]);
835
+ function Oe(e, t = "") {
836
+ const a = [];
837
+ return de(e, t, a), a;
542
838
  }
543
- function J(e, t, n) {
839
+ function de(e, t, a) {
544
840
  if (Array.isArray(e)) {
545
- e.forEach((o, c) => J(o, `${t}[${c}]`, n));
841
+ e.forEach((s, f) => de(s, `${t}[${f}]`, a));
546
842
  return;
547
843
  }
548
- if (!ne(e)) return;
549
- const r = e.__meta ?? {};
550
- for (const [o, c] of Object.entries(e)) {
551
- if (o === "__meta") continue;
552
- const g = t ? `${t}.${o}` : o;
553
- if (Array.isArray(c) || ne(c)) {
554
- J(c, g, n);
844
+ if (!he(e)) return;
845
+ const m = e.__meta ?? {};
846
+ for (const [s, f] of Object.entries(e)) {
847
+ if (s === "__meta") continue;
848
+ const n = t ? `${t}.${s}` : s;
849
+ if (Array.isArray(f) || he(f)) {
850
+ de(f, n, a);
555
851
  continue;
556
852
  }
557
- const b = r[o];
558
- !b && _t.has(o) || n.push({
559
- path: g,
560
- label: o,
853
+ const b = m[s];
854
+ !b && Jt.has(s) || a.push({
855
+ path: n,
856
+ label: s,
561
857
  meta: b ?? null,
562
- value: c,
858
+ value: f,
563
859
  unanchored: !b
564
860
  });
565
861
  }
566
862
  }
567
- function ne(e) {
863
+ function he(e) {
568
864
  return typeof e == "object" && e !== null && !Array.isArray(e);
569
865
  }
570
- const ht = { class: "tv-comparison-page flex flex-col gap-4" }, wt = {
866
+ function Kt(e) {
867
+ var s;
868
+ const t = Oe(e).filter(
869
+ (f) => f.meta !== null
870
+ ), a = t.length;
871
+ let g = 0, m = 0;
872
+ for (const f of t) {
873
+ if (f.meta.candidates.override) {
874
+ g++;
875
+ continue;
876
+ }
877
+ const n = (s = f.meta.candidates.extracted) == null ? void 0 : s.confidence;
878
+ (f.meta.discrepancy || n == null || n <= 2) && m++;
879
+ }
880
+ return {
881
+ total: a,
882
+ verified: g,
883
+ needsReview: m,
884
+ percent: a === 0 ? 100 : Math.round(g / a * 100)
885
+ };
886
+ }
887
+ const Ht = { class: "tv-comparison-page flex flex-col gap-4" }, Gt = {
571
888
  key: 0,
572
889
  class: "tv-comparison-empty text-gray-400"
573
- }, kt = {
890
+ }, Qt = {
574
891
  key: 1,
575
892
  class: "tv-anchored-group flex flex-col gap-3"
576
- }, St = { class: "flex items-center gap-2" }, Vt = { class: "tv-datapoint-path font-mono text-xs text-gray-500" }, $t = { class: "tv-datapoint-resolved font-medium" }, Ct = {
893
+ }, Wt = { class: "flex items-center gap-2" }, Xt = { class: "tv-datapoint-path font-mono text-xs text-gray-500" }, Zt = { class: "tv-datapoint-resolved font-medium" }, ea = {
577
894
  key: 0,
578
895
  class: "tv-datapoint-discrepancy text-xs font-medium text-amber-600"
579
- }, Ot = { class: "tv-datapoint-candidates ml-4 text-xs text-gray-600" }, It = { class: "font-medium" }, Lt = {
896
+ }, ta = { class: "tv-datapoint-candidates ml-4 text-xs text-gray-600" }, aa = { class: "font-medium" }, la = {
580
897
  key: 0,
581
898
  class: "tv-datapoint-reasoning ml-4 text-xs italic text-gray-500"
582
- }, Ut = {
899
+ }, na = {
583
900
  key: 1,
584
901
  class: "tv-datapoint-cited ml-4 text-xs text-gray-500"
585
- }, Dt = { class: "tv-datapoint-sources ml-4 text-xs text-gray-500" }, Et = ["href"], Tt = { key: 1 }, At = { class: "ml-1" }, Nt = {
902
+ }, sa = { class: "tv-datapoint-sources ml-4 text-xs text-gray-500" }, ra = ["href"], ia = { key: 1 }, oa = { class: "ml-1" }, ua = {
586
903
  key: 2,
587
904
  class: "tv-unanchored-group flex flex-col gap-1"
588
- }, jt = { class: "tv-datapoint-path font-mono text-xs text-gray-500" }, Ft = { class: "tv-datapoint-value" }, Pt = /* @__PURE__ */ M({
905
+ }, da = { class: "tv-datapoint-path font-mono text-xs text-gray-500" }, ca = { class: "tv-datapoint-value" }, va = /* @__PURE__ */ K({
589
906
  __name: "ComparisonPage",
590
907
  setup(e) {
591
- const t = Q(), n = d(() => bt(t.data)), f = d(() => n.value.filter((w) => !w.unanchored)), r = d(() => n.value.filter((w) => w.unanchored));
592
- function o(w) {
593
- const _ = X(w).value;
594
- return _ == null ? "" : String(_);
908
+ const t = le(), a = d(() => Oe(t.data)), g = d(() => a.value.filter(($) => !$.unanchored)), m = d(() => a.value.filter(($) => $.unanchored));
909
+ function s($) {
910
+ const h = fe($).value;
911
+ return h == null ? "" : String(h);
595
912
  }
596
- function c(w) {
597
- return w == null ? "" : String(w);
913
+ function f($) {
914
+ return $ == null ? "" : String($);
598
915
  }
599
- function g(w) {
600
- var _, v, V;
601
- return (V = (v = (_ = w.meta) == null ? void 0 : _.candidates) == null ? void 0 : v.extracted) == null ? void 0 : V.confidence;
916
+ function n($) {
917
+ var h, x, k;
918
+ return (k = (x = (h = $.meta) == null ? void 0 : h.candidates) == null ? void 0 : x.extracted) == null ? void 0 : k.confidence;
602
919
  }
603
- function b(w) {
604
- var V;
605
- const _ = (V = w.meta) == null ? void 0 : V.candidates;
606
- if (!_) return [];
607
- const v = [];
608
- return _.override && v.push({ source: "override", value: _.override.value }), _.extracted && v.push({ source: "extracted", value: _.extracted.value }), _.claim && v.push({ source: "claim", value: _.claim.value }), v;
920
+ function b($) {
921
+ var k;
922
+ const h = (k = $.meta) == null ? void 0 : k.candidates;
923
+ if (!h) return [];
924
+ const x = [];
925
+ return h.override && x.push({ source: "override", value: h.override.value }), h.extracted && x.push({ source: "extracted", value: h.extracted.value }), h.claim && x.push({ source: "claim", value: h.claim.value }), x;
609
926
  }
610
- return (w, _) => (l(), i("div", ht, [
611
- _[1] || (_[1] = a("h2", { class: "tv-comparison-title text-lg font-semibold" }, "Verification comparison", -1)),
612
- n.value.length === 0 ? (l(), i("p", wt, " No data points to compare. ")) : h("", !0),
613
- f.value.length ? (l(), i("section", kt, [
614
- (l(!0), i(O, null, T(f.value, (v) => {
615
- var V, L, C;
616
- return l(), i("div", {
617
- key: v.path,
927
+ return ($, h) => (l(), o("div", Ht, [
928
+ h[1] || (h[1] = r("h2", { class: "tv-comparison-title text-lg font-semibold" }, "Verification comparison", -1)),
929
+ a.value.length === 0 ? (l(), o("p", Gt, " No data points to compare. ")) : _("", !0),
930
+ g.value.length ? (l(), o("section", Qt, [
931
+ (l(!0), o(L, null, M(g.value, (x) => {
932
+ var k, S, R;
933
+ return l(), o("div", {
934
+ key: x.path,
618
935
  class: "tv-datapoint border-t border-gray-100 pt-2"
619
936
  }, [
620
- a("div", St, [
621
- a("span", Vt, p(v.path), 1),
622
- a("span", $t, p(o(v.meta)), 1),
623
- I(z, {
624
- confidence: g(v),
937
+ r("div", Wt, [
938
+ r("span", Xt, y(x.path), 1),
939
+ r("span", Zt, y(s(x.meta)), 1),
940
+ V(ue, {
941
+ confidence: n(x),
625
942
  "show-label": ""
626
943
  }, null, 8, ["confidence"]),
627
- m(re)(v.meta) ? (l(), i("span", Ct, "⚠ discrepancy")) : h("", !0)
944
+ i(Ve)(x.meta) ? (l(), o("span", ea, "⚠ discrepancy")) : _("", !0)
628
945
  ]),
629
- a("ul", Ot, [
630
- (l(!0), i(O, null, T(b(v), (k) => (l(), i("li", {
631
- key: k.source,
946
+ r("ul", ta, [
947
+ (l(!0), o(L, null, M(b(x), (O) => (l(), o("li", {
948
+ key: O.source,
632
949
  class: "tv-candidate"
633
950
  }, [
634
- a("span", It, p(k.source) + ":", 1),
635
- E(" " + p(c(k.value)), 1)
951
+ r("span", aa, y(O.source) + ":", 1),
952
+ T(" " + y(f(O.value)), 1)
636
953
  ]))), 128))
637
954
  ]),
638
- m(H)(v.meta) ? (l(), i("p", Lt, p(m(H)(v.meta)), 1)) : h("", !0),
639
- m(q)(v.meta) ? (l(), i("p", Ut, " “" + p(m(q)(v.meta)) + "” ", 1)) : h("", !0),
640
- a("ul", Dt, [
641
- (l(!0), i(O, null, T(m(oe)((C = (L = (V = v.meta) == null ? void 0 : V.candidates) == null ? void 0 : L.extracted) == null ? void 0 : C.sources), (k, N) => (l(), i("li", {
642
- key: N,
955
+ i(ie)(x.meta) ? (l(), o("p", la, y(i(ie)(x.meta)), 1)) : _("", !0),
956
+ i(oe)(x.meta) ? (l(), o("p", na, " “" + y(i(oe)(x.meta)) + "” ", 1)) : _("", !0),
957
+ r("ul", sa, [
958
+ (l(!0), o(L, null, M(i(De)((R = (S = (k = x.meta) == null ? void 0 : k.candidates) == null ? void 0 : S.extracted) == null ? void 0 : R.sources), (O, j) => (l(), o("li", {
959
+ key: j,
643
960
  class: "tv-source-group"
644
961
  }, [
645
- k.fileUrl ? (l(), i("a", {
962
+ O.fileUrl ? (l(), o("a", {
646
963
  key: 0,
647
- href: k.fileUrl,
964
+ href: O.fileUrl,
648
965
  class: "tv-source-link text-blue-600 underline",
649
966
  target: "_blank",
650
967
  rel: "noopener"
651
- }, p(k.fileLabel), 9, Et)) : (l(), i("span", Tt, p(k.fileLabel), 1)),
652
- a("span", At, "(" + p(k.sources.map(m(ue)).join(", ")) + ")", 1)
968
+ }, y(O.fileLabel), 9, ra)) : (l(), o("span", ia, y(O.fileLabel), 1)),
969
+ r("span", oa, "(" + y(O.sources.map(i(rt)).join(", ")) + ")", 1)
653
970
  ]))), 128))
654
971
  ])
655
972
  ]);
656
973
  }), 128))
657
- ])) : h("", !0),
658
- r.value.length ? (l(), i("section", Nt, [
659
- _[0] || (_[0] = a("h3", { class: "tv-unanchored-title text-sm font-semibold text-gray-500" }, " Unanchored / not from source ", -1)),
660
- (l(!0), i(O, null, T(r.value, (v) => (l(), i("div", {
661
- key: v.path,
974
+ ])) : _("", !0),
975
+ m.value.length ? (l(), o("section", ua, [
976
+ h[0] || (h[0] = r("h3", { class: "tv-unanchored-title text-sm font-semibold text-gray-500" }, " Unanchored / not from source ", -1)),
977
+ (l(!0), o(L, null, M(m.value, (x) => (l(), o("div", {
978
+ key: x.path,
662
979
  class: "tv-unanchored-datapoint flex items-center gap-2 text-sm"
663
980
  }, [
664
- a("span", jt, p(v.path), 1),
665
- a("span", Ft, p(c(v.value)), 1),
666
- I(z, { status: "unverifiable" })
981
+ r("span", da, y(x.path), 1),
982
+ r("span", ca, y(f(x.value)), 1),
983
+ V(ue, { status: "unverifiable" })
667
984
  ]))), 128))
668
- ])) : h("", !0)
985
+ ])) : _("", !0)
669
986
  ]));
670
987
  }
671
- }), Mt = { class: "tv-enable-toggle flex items-center justify-between text-sm" }, Yt = /* @__PURE__ */ M({
988
+ }), fa = { class: "tv-enable-toggle flex items-center justify-between text-sm font-medium text-gray-700" }, pa = { class: "tv-progress-block" }, ma = { class: "mb-1 flex items-baseline justify-between" }, ga = { class: "tv-progress-count text-xs font-semibold text-gray-600" }, wa = /* @__PURE__ */ K({
672
989
  __name: "VerificationChrome",
673
990
  setup(e) {
674
- const { enabled: t, openComparison: n } = Q(), f = Oe(), r = D(!1);
675
- function o() {
676
- n(), r.value = !1;
991
+ const t = le(), { enabled: a, openComparison: g } = t, m = He(), s = _e(), f = U(!1), n = d(() => Kt(t.data)), b = U(!1);
992
+ ce(
993
+ () => n.value.percent,
994
+ (k) => {
995
+ k === 100 && n.value.total > 0 && !b.value && (b.value = !0, s.success("All data points verified 🎯"));
996
+ }
997
+ );
998
+ let $ = 0;
999
+ function h() {
1000
+ const k = document.querySelectorAll(
1001
+ ".tv-discrepancy-indicator, .tv-confidence-icon[data-status='low'], .tv-confidence-icon[data-status='unverifiable']"
1002
+ );
1003
+ if (!k.length) return;
1004
+ $ = $ % k.length;
1005
+ const S = k[$];
1006
+ $++, S.scrollIntoView({ behavior: "smooth", block: "center" }), S.animate(
1007
+ [
1008
+ { boxShadow: "0 0 0 0 rgba(245, 158, 11, 0.8)" },
1009
+ { boxShadow: "0 0 0 12px rgba(245, 158, 11, 0)" }
1010
+ ],
1011
+ { duration: 900, iterations: 2 }
1012
+ );
1013
+ }
1014
+ function x() {
1015
+ g(), f.value = !1;
677
1016
  }
678
- return (c, g) => (l(), i(O, null, [
679
- a("button", {
1017
+ return (k, S) => (l(), o(L, null, [
1018
+ r("button", {
680
1019
  type: "button",
681
- class: U(["tv-settings-button fixed bottom-4 right-4 z-50 flex h-10 w-10 items-center justify-center rounded-full bg-gray-800 text-white shadow-lg", m(A)]),
682
- title: "Verification settings",
683
- onClick: g[0] || (g[0] = (b) => r.value = !r.value)
1020
+ class: A(["tv-settings-button fixed bottom-4 right-4 z-50 flex h-11 w-11 items-center justify-center rounded-full bg-gray-900 text-white shadow-lg transition-transform hover:scale-105", i(P)]),
1021
+ title: "Verification",
1022
+ onClick: S[0] || (S[0] = (R) => f.value = !f.value)
684
1023
  }, [
685
- I(m(ke), {
686
- icon: m(Se),
1024
+ V(i(Me), {
1025
+ icon: i(Be),
687
1026
  class: "h-5 w-5"
688
- }, null, 8, ["icon"])
1027
+ }, null, 8, ["icon"]),
1028
+ i(a) && n.value.needsReview > 0 ? (l(), N(i(Fe), {
1029
+ key: 0,
1030
+ value: n.value.needsReview,
1031
+ variant: "warning",
1032
+ class: "tv-needs-review-badge absolute -right-1 -top-1"
1033
+ }, null, 8, ["value"])) : _("", !0)
689
1034
  ], 2),
690
- r.value ? (l(), i("div", {
1035
+ f.value ? (l(), o("div", {
691
1036
  key: 0,
692
- class: U(["tv-settings-panel fixed bottom-16 right-4 z-50 flex w-56 flex-col gap-3 rounded-lg bg-white p-4 shadow-xl ring-1 ring-gray-200", m(A)])
1037
+ class: A(["tv-settings-panel fixed bottom-20 right-4 z-50 flex w-72 flex-col gap-4 rounded-xl bg-white p-4 shadow-2xl ring-1 ring-gray-200", i(P)])
693
1038
  }, [
694
- a("label", Mt, [
695
- g[3] || (g[3] = a("span", null, "Verification overlay", -1)),
696
- ye(a("input", {
697
- "onUpdate:modelValue": g[1] || (g[1] = (b) => te(t) ? t.value = b : null),
1039
+ r("label", fa, [
1040
+ S[3] || (S[3] = r("span", null, "Verification overlay", -1)),
1041
+ Ae(r("input", {
1042
+ "onUpdate:modelValue": S[1] || (S[1] = (R) => ge(a) ? a.value = R : null),
698
1043
  type: "checkbox",
699
- class: "tv-enable-checkbox"
1044
+ class: "tv-enable-checkbox h-4 w-4 accent-gray-900"
700
1045
  }, null, 512), [
701
- [_e, m(t)]
1046
+ [Re, i(a)]
702
1047
  ])
703
1048
  ]),
704
- a("button", {
1049
+ i(a) && n.value.total > 0 ? (l(), o(L, { key: 0 }, [
1050
+ r("div", pa, [
1051
+ r("div", ma, [
1052
+ S[4] || (S[4] = r("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Review progress", -1)),
1053
+ r("span", ga, y(n.value.verified) + " / " + y(n.value.total), 1)
1054
+ ]),
1055
+ V(i(we), {
1056
+ value: n.value.verified,
1057
+ max: n.value.total,
1058
+ size: "md",
1059
+ variant: n.value.percent === 100 ? "success" : "info",
1060
+ striped: n.value.percent < 100,
1061
+ "animate-stripes": n.value.percent < 100,
1062
+ glow: n.value.percent === 100,
1063
+ gradient: ""
1064
+ }, null, 8, ["value", "max", "variant", "striped", "animate-stripes", "glow"])
1065
+ ]),
1066
+ n.value.needsReview > 0 ? (l(), o("button", {
1067
+ key: 0,
1068
+ type: "button",
1069
+ class: A(["tv-next-flagged flex items-center justify-between rounded-lg bg-amber-50 px-3 py-2 text-left text-xs font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20 transition hover:bg-amber-100", i(P)]),
1070
+ onClick: h
1071
+ }, [
1072
+ r("span", null, y(n.value.needsReview) + " need" + y(n.value.needsReview === 1 ? "s" : "") + " review", 1),
1073
+ S[5] || (S[5] = r("span", { "aria-hidden": "true" }, "→", -1))
1074
+ ], 2)) : _("", !0)
1075
+ ], 64)) : _("", !0),
1076
+ r("button", {
705
1077
  type: "button",
706
- class: U(["tv-open-comparison rounded border px-2 py-1 text-sm", m(A)]),
707
- onClick: o
708
- }, "Open comparison page", 2)
709
- ], 2)) : h("", !0),
710
- I(m(G), {
711
- modelValue: m(f),
712
- "onUpdate:modelValue": g[2] || (g[2] = (b) => te(f) ? f.value = b : null),
1078
+ class: A(["tv-open-comparison rounded-lg border border-gray-200 px-3 py-2 text-sm font-medium text-gray-600 transition hover:bg-gray-50", i(P)]),
1079
+ onClick: x
1080
+ }, " Open comparison page ", 2)
1081
+ ], 2)) : _("", !0),
1082
+ V(i(re), {
1083
+ modelValue: i(m),
1084
+ "onUpdate:modelValue": S[2] || (S[2] = (R) => ge(m) ? m.value = R : null),
713
1085
  title: "Verification comparison",
714
1086
  width: 80,
715
1087
  "close-x": "",
716
- class: U(m(A))
1088
+ class: A(i(P))
717
1089
  }, {
718
- default: j(() => [
719
- I(Pt)
1090
+ default: I(() => [
1091
+ V(va)
720
1092
  ]),
721
1093
  _: 1
722
- }, 8, ["modelValue", "class"])
1094
+ }, 8, ["modelValue", "class"]),
1095
+ V(i(qe), {
1096
+ class: A(i(P))
1097
+ }, null, 8, ["class"])
723
1098
  ], 64));
724
1099
  }
725
1100
  });
726
1101
  export {
727
- A as CHROME_CLASS,
728
- Pt as ComparisonPage,
729
- z as ConfidenceIcon,
730
- le as ENABLED_STORAGE_KEY,
731
- ie as RESOLUTION_PRIORITY,
732
- Ie as STATUS_COLORS,
733
- Le as STATUS_LABELS,
734
- Yt as VerificationChrome,
735
- mt as VerificationModal,
736
- Kt as VerifiedField,
737
- W as bucketConfidence,
738
- De as candidatesDisagree,
739
- q as citedTextOf,
740
- oe as groupSources,
741
- re as hasDiscrepancy,
742
- Bt as initVerification,
743
- H as reasoningOf,
744
- Ue as resolveCandidates,
745
- X as resolveDataPoint,
746
- ue as sourceRowLabel,
747
- Q as useVerification,
748
- bt as walkDataPoints
1102
+ P as CHROME_CLASS,
1103
+ va as ComparisonPage,
1104
+ ue as ConfidenceIcon,
1105
+ ke as ENABLED_STORAGE_KEY,
1106
+ Ce as RESOLUTION_PRIORITY,
1107
+ Ge as STATUS_COLORS,
1108
+ ae as STATUS_LABELS,
1109
+ wa as VerificationChrome,
1110
+ Mt as VerificationModal,
1111
+ _a as VerifiedField,
1112
+ ve as bucketConfidence,
1113
+ We as candidatesDisagree,
1114
+ oe as citedTextOf,
1115
+ Kt as computeProgress,
1116
+ lt as fetchDataPointAudit,
1117
+ De as groupSources,
1118
+ Ve as hasDiscrepancy,
1119
+ ha as initVerification,
1120
+ ie as reasoningOf,
1121
+ Qe as resolveCandidates,
1122
+ fe as resolveDataPoint,
1123
+ rt as sourceRowLabel,
1124
+ le as useVerification,
1125
+ Oe as walkDataPoints
749
1126
  };