@lightworkai.official/debug-capture-vue 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +52 -0
  2. package/dist/components/BugIcon.d.ts +3 -0
  3. package/dist/components/DebugCaptureInit.vue.d.ts +13 -0
  4. package/dist/components/ImageAnnotatorDialog.vue.d.ts +19 -0
  5. package/dist/components/MyTicketsPanel.vue.d.ts +17 -0
  6. package/dist/components/ReopenPanel.vue.d.ts +12 -0
  7. package/dist/components/ReportProblemButton.vue.d.ts +17 -0
  8. package/dist/components/RichReplyEditor.vue.d.ts +59 -0
  9. package/dist/components/StatusHero.vue.d.ts +10 -0
  10. package/dist/components/StatusPill.vue.d.ts +16 -0
  11. package/dist/components/TicketBody.vue.d.ts +6 -0
  12. package/dist/components/TicketConversation.vue.d.ts +22 -0
  13. package/dist/components/TicketDetail.vue.d.ts +28 -0
  14. package/dist/components/TicketScreenshots.vue.d.ts +8 -0
  15. package/dist/components/TicketTable.vue.d.ts +25 -0
  16. package/dist/components/TicketTimeline.vue.d.ts +11 -0
  17. package/dist/components/ToolbarButton.vue.d.ts +21 -0
  18. package/dist/components/icons.d.ts +38 -0
  19. package/dist/index.d.ts +24 -0
  20. package/dist/index.mjs +2996 -0
  21. package/dist/index.mjs.map +1 -0
  22. package/package.json +64 -0
  23. package/src/components/BugIcon.ts +23 -0
  24. package/src/components/DebugCaptureInit.vue +41 -0
  25. package/src/components/ImageAnnotatorDialog.vue +160 -0
  26. package/src/components/MyTicketsPanel.vue +312 -0
  27. package/src/components/README.md +12 -0
  28. package/src/components/ReopenPanel.vue +47 -0
  29. package/src/components/ReportProblemButton.vue +28 -0
  30. package/src/components/RichReplyEditor.vue +321 -0
  31. package/src/components/StatusHero.vue +85 -0
  32. package/src/components/StatusPill.vue +14 -0
  33. package/src/components/TicketBody.vue +50 -0
  34. package/src/components/TicketConversation.vue +227 -0
  35. package/src/components/TicketDetail.vue +130 -0
  36. package/src/components/TicketScreenshots.vue +47 -0
  37. package/src/components/TicketTable.vue +142 -0
  38. package/src/components/TicketTimeline.vue +86 -0
  39. package/src/components/ToolbarButton.vue +33 -0
  40. package/src/components/icons.ts +90 -0
  41. package/src/index.ts +34 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,2996 @@
1
+ var bn = Object.defineProperty;
2
+ var yn = (e, t, o) => t in e ? bn(e, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : e[t] = o;
3
+ var de = (e, t, o) => yn(e, typeof t != "symbol" ? t + "" : t, o);
4
+ import { defineComponent as J, onMounted as Oe, openBlock as m, createElementBlock as v, h as be, renderSlot as Ft, createVNode as O, unref as P, normalizeStyle as xe, toDisplayString as y, computed as F, Fragment as q, createElementVNode as f, renderList as ae, createTextVNode as V, createCommentVNode as B, withKeys as vn, withModifiers as $t, createBlock as G, ref as N, watch as re, resolveDynamicComponent as et, withDirectives as Je, vModelText as Qt, normalizeClass as fe, shallowRef as Vt, onBeforeUnmount as qt, useModel as wn, withCtx as ut, mergeModels as ct, nextTick as kn, vModelSelect as xn } from "vue";
5
+ import { useEditor as Mn, EditorContent as Sn } from "@tiptap/vue-3";
6
+ import En from "@tiptap/starter-kit";
7
+ import Cn from "@tiptap/extension-image";
8
+ import An from "@tiptap/extension-placeholder";
9
+ var Ln = { maxRequests: 60, maxConsoleEntries: 120, maxActions: 80, maxBodyChars: 2e4 }, $ = null;
10
+ function Tn(e) {
11
+ $ = e;
12
+ }
13
+ function X() {
14
+ if (!$) throw Error("[debug-capture] configureDebugCapture() has not been called");
15
+ return $;
16
+ }
17
+ function Jt() {
18
+ return $ !== null;
19
+ }
20
+ function Me() {
21
+ let e = X().app;
22
+ return { name: e.name, version: e.version ?? "0.0.0", environment: e.environment ?? _n() };
23
+ }
24
+ function _n() {
25
+ if (typeof window > "u") return "unknown";
26
+ let e = window.location.hostname;
27
+ return e === "localhost" || e === "127.0.0.1" || e.endsWith(".local") ? "development" : "production";
28
+ }
29
+ function Ce(e) {
30
+ var o;
31
+ let t = (o = $ == null ? void 0 : $.capture) == null ? void 0 : o[e];
32
+ return typeof t == "number" ? t : Ln[e];
33
+ }
34
+ function Rn(e) {
35
+ let t = $ == null ? void 0 : $.module;
36
+ if (!t) return null;
37
+ try {
38
+ return t(e) ?? null;
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+ function tt() {
44
+ let e = $ == null ? void 0 : $.redact;
45
+ return { headers: (e == null ? void 0 : e.headers) ?? [], queryKeys: ((e == null ? void 0 : e.queryKeys) ?? []).map((t) => t.toLowerCase()), bodyKeys: ((e == null ? void 0 : e.bodyKeys) ?? []).map((t) => t.toLowerCase()) };
46
+ }
47
+ function In() {
48
+ var e;
49
+ return ((e = $ == null ? void 0 : $.capture) == null ? void 0 : e.overlaySelectors) ?? [];
50
+ }
51
+ function zn(e) {
52
+ var o;
53
+ if (typeof window > "u") return !1;
54
+ let t;
55
+ try {
56
+ t = new URL(e, window.location.href);
57
+ } catch {
58
+ return !1;
59
+ }
60
+ return Nn(t) ? !1 : t.origin === window.location.origin ? !0 : (((o = $ == null ? void 0 : $.capture) == null ? void 0 : o.bodyOrigins) ?? []).some((n) => {
61
+ try {
62
+ return new URL(n).origin === t.origin;
63
+ } catch {
64
+ return !1;
65
+ }
66
+ });
67
+ }
68
+ function Nn(e) {
69
+ if (!($ != null && $.host)) return !1;
70
+ try {
71
+ if (new URL($.host).origin !== e.origin) return !1;
72
+ } catch {
73
+ return !1;
74
+ }
75
+ return e.pathname.startsWith("/ingest/");
76
+ }
77
+ var Ee = "‹redacted›", Pn = /^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i, Un = /* @__PURE__ */ new Set(["access_token", "token", "id_token", "refresh_token", "code", "secret", "client_secret", "password", "apikey", "api_key", "signature", "x-amz-signature", "x-amz-credential"]), Dn = /(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i, On = /[\w.+-]+@[\w-]+\.[\w.-]+/g, Bn = /\d(?:[\d\s-]{7,})\d/g;
78
+ function Be(e) {
79
+ return e.replace(On, Ee).replace(Bn, Ee);
80
+ }
81
+ function Hn(e) {
82
+ return Pn.test(e) ? !0 : tt().headers.some((t) => t.toLowerCase() === e.toLowerCase());
83
+ }
84
+ function Ze(e) {
85
+ let t = {};
86
+ for (let [o, n] of Object.entries(e)) t[o] = Hn(o) ? Ee : n;
87
+ return t;
88
+ }
89
+ function nt(e) {
90
+ try {
91
+ let t = /^https?:\/\//i.test(e), o = new URL(e, t ? void 0 : "http://local.invalid"), n = !1;
92
+ return o.searchParams.forEach((r, a) => {
93
+ (Un.has(a.toLowerCase()) || tt().queryKeys.includes(a.toLowerCase())) && (o.searchParams.set(a, Ee), n = !0);
94
+ }), n ? t ? o.toString() : `${o.pathname}${o.search}` : e;
95
+ } catch {
96
+ return e;
97
+ }
98
+ }
99
+ function Ye(e, t) {
100
+ if (t > 6 || e === null || typeof e != "object") return e;
101
+ if (Array.isArray(e)) return e.map((n) => Ye(n, t + 1));
102
+ let o = {};
103
+ for (let [n, r] of Object.entries(e)) {
104
+ let a = Dn.test(n) || tt().bodyKeys.some((l) => n.toLowerCase().includes(l));
105
+ o[n] = a ? Ee : Ye(r, t + 1);
106
+ }
107
+ return o;
108
+ }
109
+ function Pe(e, t) {
110
+ if (e == null) return null;
111
+ let o = e, n = e.trim();
112
+ if (n.startsWith("{") || n.startsWith("[")) try {
113
+ let r = JSON.parse(n);
114
+ o = JSON.stringify(Ye(r, 0));
115
+ } catch {
116
+ }
117
+ return o.length > t ? `${o.slice(0, t)}… [truncated ${o.length - t} chars]` : o;
118
+ }
119
+ var Xe = 120, ot = 40, ye = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, rt = (e) => {
120
+ try {
121
+ return decodeURIComponent(e);
122
+ } catch {
123
+ return e;
124
+ }
125
+ }, ge = [], dt = 0, ft = !1;
126
+ function ke(e, t, o, n) {
127
+ let r = ye(t, Xe), a = ge[ge.length - 1];
128
+ if (e === "navigate" && (a == null ? void 0 : a.kind) === "click") {
129
+ let s = r.replace(/^ไปที่\s*/, "");
130
+ if (a.detail.includes(`→ ${s}`)) return a.at = (/* @__PURE__ */ new Date()).toISOString(), a;
131
+ let c = s.split(/[?#]/)[0] ?? s, g = a.source ? rt(a.source.replace(/^→\s*/, "")).split(/[?#]/)[0] : null;
132
+ if (g && (c === g || c.startsWith(g))) return a.detail = ye(`${a.detail} → ${s}`, Xe), a.source = void 0, a.at = (/* @__PURE__ */ new Date()).toISOString(), a;
133
+ }
134
+ if (a && a.kind === e && a.detail === r)
135
+ return a.at = (/* @__PURE__ */ new Date()).toISOString(), e !== "navigate" && (a.count = (a.count ?? 1) + 1), a;
136
+ dt += 1;
137
+ let l = { id: `act_${dt}`, at: (/* @__PURE__ */ new Date()).toISOString(), kind: e, detail: r, count: 1, source: o, html: Ue(n) };
138
+ for (ge.push(l); ge.length > Ce("maxActions"); ) $n(ge.shift());
139
+ return l;
140
+ }
141
+ var Fn = 2e5, Se = 0;
142
+ function Ue(e) {
143
+ if (e && !(Se + e.length > Fn))
144
+ return Se += e.length, e;
145
+ }
146
+ function $n(e) {
147
+ var t, o;
148
+ e && (Se -= (((t = e.html) == null ? void 0 : t.length) ?? 0) + (((o = e.afterHtml) == null ? void 0 : o.length) ?? 0), Se < 0 && (Se = 0));
149
+ }
150
+ function Ie(e) {
151
+ return e instanceof Element && !!e.closest("[data-debug-reporter]");
152
+ }
153
+ var Qn = 'button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea', Vn = { button: "ปุ่ม", a: "ลิงก์", input: "ช่อง", textarea: "ช่อง", select: "ตัวเลือก", summary: "ส่วนขยาย" }, ht = { button: "ปุ่ม", tab: "แท็บ", menuitem: "เมนู", option: "ตัวเลือก", switch: "สวิตช์", checkbox: "ช่องเลือก", radio: "ตัวเลือก", link: "ลิงก์" };
154
+ function qn(e) {
155
+ let t = e.getAttribute("role");
156
+ return t && ht[t] ? ht[t] : Vn[e.tagName.toLowerCase()] ?? "ปุ่ม";
157
+ }
158
+ function Jn(e, t) {
159
+ var o;
160
+ try {
161
+ let n = e, r = 0;
162
+ for (; n && r <= t; ) {
163
+ let a = Yt(n);
164
+ if (a && typeof ((o = a.memoizedProps) == null ? void 0 : o.onClick) == "function") return n;
165
+ n = n.parentElement, r += 1;
166
+ }
167
+ } catch {
168
+ }
169
+ return null;
170
+ }
171
+ function Zn(e) {
172
+ var r, a;
173
+ let t = (r = e.getAttribute("aria-label")) == null ? void 0 : r.trim();
174
+ if (t) return t;
175
+ let o = (a = e.getAttribute("title")) == null ? void 0 : a.trim();
176
+ if (o) return o;
177
+ if (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement || e instanceof HTMLSelectElement) return (e.getAttribute("placeholder") || e.getAttribute("name") || "").trim();
178
+ if (e instanceof HTMLImageElement) return (e.getAttribute("alt") || "").trim();
179
+ let n = (e.textContent ?? "").replace(/\s+/g, " ").trim();
180
+ if (n) return n;
181
+ if (e instanceof HTMLAnchorElement) {
182
+ let l = e.getAttribute("href");
183
+ if (l != null && l.startsWith("/")) return rt(l);
184
+ }
185
+ return "";
186
+ }
187
+ function Yn(e) {
188
+ if (!(e instanceof Element)) return null;
189
+ let t = e.closest(Qn) ?? Jn(e, 4);
190
+ if (!t) return null;
191
+ let o = t.tagName.toLowerCase();
192
+ return o === "html" || o === "body" ? null : t;
193
+ }
194
+ function Xn(e) {
195
+ let t = Be(Zn(e));
196
+ return t ? `${qn(e)} “${ye(t, ot)}”` : null;
197
+ }
198
+ var Zt = 6e3, Gn = 4e3, Kn = /(?:^|\s)!?(?:fixed|absolute|sticky|inset-\S+|z-\S+|top-\S+|bottom-\S+|left-\S+|right-\S+|w-screen|h-screen|min-h-screen|max-h-screen|translate-\S+|scale-\S+)(?=\s|$)/g;
199
+ function jn(e) {
200
+ e.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((r) => r.remove());
201
+ let t = [e, ...Array.from(e.querySelectorAll("*"))];
202
+ for (let r of t) {
203
+ for (let l of Array.from(r.attributes)) {
204
+ let s = l.name.toLowerCase();
205
+ (s.startsWith("on") || s === "srcdoc" || s === "value" || s.startsWith("data-")) && r.removeAttribute(l.name);
206
+ }
207
+ r instanceof HTMLAnchorElement && r.setAttribute("href", "#"), r instanceof HTMLImageElement && r.removeAttribute("src");
208
+ let a = r.getAttribute("class");
209
+ if (a) {
210
+ let l = a.replace(Kn, " ").replace(/\s+/g, " ").trim();
211
+ l ? r.setAttribute("class", l) : r.removeAttribute("class");
212
+ }
213
+ }
214
+ let o = document.createTreeWalker(e, NodeFilter.SHOW_TEXT), n = o.nextNode();
215
+ for (; n; )
216
+ n.nodeValue && (n.nodeValue = Be(n.nodeValue)), n = o.nextNode();
217
+ }
218
+ function at(e, t, o) {
219
+ try {
220
+ let n = e.outerHTML;
221
+ if (!n || n.length > t) return;
222
+ let r = e.cloneNode(!0);
223
+ jn(r);
224
+ let a = r.outerHTML;
225
+ return a && a.length <= o ? a : void 0;
226
+ } catch {
227
+ return;
228
+ }
229
+ }
230
+ var Wn = (e) => at(e, Zt, Gn), eo = 15e4, to = 4e4, pt = (e) => at(e, eo, to);
231
+ function no(e) {
232
+ if (!(e instanceof HTMLInputElement) && !(e instanceof HTMLTextAreaElement) && !(e instanceof HTMLSelectElement)) return null;
233
+ let t = e.name || e.id || e.getAttribute("aria-label") || e.getAttribute("placeholder") || e.tagName.toLowerCase();
234
+ return `ช่อง “${Be(t)}”`;
235
+ }
236
+ var mt = 80;
237
+ function Yt(e) {
238
+ let t = Object.keys(e).find((o) => o.startsWith("__reactFiber$") || o.startsWith("__reactInternalInstance$"));
239
+ return t ? e[t] : null;
240
+ }
241
+ function oo(e) {
242
+ var t;
243
+ if (typeof e != "function") return null;
244
+ try {
245
+ let o = Function.prototype.toString.call(e);
246
+ return ((t = o.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/) ?? o.match(/redirect\(\s*['"`]([^'"`]+)['"`]/)) == null ? void 0 : t[1]) ?? null;
247
+ } catch {
248
+ return null;
249
+ }
250
+ }
251
+ function gt(e) {
252
+ if (e)
253
+ return `→ ${e.length > mt ? `${e.slice(0, mt)}…` : e}`;
254
+ }
255
+ function ro(e) {
256
+ var t, o;
257
+ try {
258
+ let n = (t = e.closest("a[href]")) == null ? void 0 : t.getAttribute("href");
259
+ if (n && n.startsWith("/")) return gt(n);
260
+ let r = Yt(e), a = 0;
261
+ for (; r && a < 30; ) {
262
+ if (typeof ((o = r.memoizedProps) == null ? void 0 : o.onClick) == "function") return gt(oo(r.memoizedProps.onClick));
263
+ r = r.return, a += 1;
264
+ }
265
+ return;
266
+ } catch {
267
+ return;
268
+ }
269
+ }
270
+ var ao = '[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';
271
+ function lo() {
272
+ let e = In();
273
+ return e.length ? e.join(", ") : ao;
274
+ }
275
+ function io(e) {
276
+ let t = e.getAttribute("role");
277
+ return t === "status" || t === "alert" ? "ข้อความแจ้งเตือน" : t === "menu" ? "เมนู" : t === "listbox" ? "รายการตัวเลือก" : t === "alertdialog" ? "กล่องยืนยัน" : "กล่องโต้ตอบ";
278
+ }
279
+ function so(e) {
280
+ var r, a, l;
281
+ let t = (r = e.getAttribute("aria-label")) == null ? void 0 : r.trim();
282
+ if (t) return t;
283
+ let o = e.getAttribute("aria-labelledby");
284
+ if (o) {
285
+ let s = o.split(/\s+/).map((c) => {
286
+ var g, k;
287
+ return ((k = (g = document.getElementById(c)) == null ? void 0 : g.textContent) == null ? void 0 : k.trim()) ?? "";
288
+ }).filter(Boolean).join(" ");
289
+ if (s) return s;
290
+ }
291
+ let n = (l = (a = e.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')) == null ? void 0 : a.textContent) == null ? void 0 : l.replace(/\s+/g, " ").trim();
292
+ return n || (e.textContent ?? "").replace(/\s+/g, " ").trim();
293
+ }
294
+ function Xt(e) {
295
+ let t = Be(so(e)), o = io(e);
296
+ return t ? `เปิด ${o} “${ye(t, ot)}”` : `เปิด ${o}`;
297
+ }
298
+ var uo = '[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin', co = /กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;
299
+ function fo(e) {
300
+ return e.querySelector(uo) ? !0 : co.test(e.textContent ?? "");
301
+ }
302
+ var ho = 400, po = 250, mo = 8e3;
303
+ function go(e, t) {
304
+ if (typeof MutationObserver > "u") {
305
+ t.html = Ue(pt(e));
306
+ return;
307
+ }
308
+ let o = Date.now(), n = !1, r = () => {
309
+ n = !0, l.disconnect(), window.clearInterval(s), window.clearTimeout(c);
310
+ }, a = () => {
311
+ n || (r(), e.isConnected && (t.detail = ye(Xt(e), Xe), t.html = Ue(pt(e))));
312
+ }, l = new MutationObserver(() => {
313
+ o = Date.now();
314
+ });
315
+ l.observe(e, { childList: !0, subtree: !0, attributes: !0, characterData: !0 });
316
+ let s = window.setInterval(() => {
317
+ if (!n) {
318
+ if (!e.isConnected) {
319
+ r();
320
+ return;
321
+ }
322
+ Date.now() - o >= ho && !fo(e) && a();
323
+ }
324
+ }, po), c = window.setTimeout(a, mo);
325
+ }
326
+ function bo(e) {
327
+ if (Ie(e)) return;
328
+ let t = ke("ui", Xt(e));
329
+ t && go(e, t);
330
+ }
331
+ function yo() {
332
+ if (typeof MutationObserver > "u") return;
333
+ let e = /* @__PURE__ */ new WeakSet();
334
+ new MutationObserver((t) => {
335
+ for (let o of t) for (let n of Array.from(o.addedNodes)) {
336
+ if (!(n instanceof Element)) continue;
337
+ let r = lo(), a = n.matches(r) ? [n] : Array.from(n.querySelectorAll(r));
338
+ for (let l of a)
339
+ e.has(l) || (e.add(l), bo(l));
340
+ }
341
+ }).observe(document.body, { childList: !0, subtree: !0 });
342
+ }
343
+ var vo = 1600, wo = 2500;
344
+ function bt(e) {
345
+ return { disabled: e.hasAttribute("disabled") || e.getAttribute("aria-disabled") === "true", busy: e.getAttribute("aria-busy") === "true", text: ye((e.textContent ?? "").replace(/\s+/g, " ").trim(), ot) };
346
+ }
347
+ function ko(e, t) {
348
+ return !e.disabled && t.disabled ? "ปุ่มถูกปิดใช้งานหลังคลิก" : !e.busy && t.busy ? "ปุ่มเข้าสู่สถานะกำลังโหลด" : e.text !== t.text && t.text ? `ข้อความเปลี่ยนเป็น “${t.text}”` : null;
349
+ }
350
+ function xo(e, t) {
351
+ if (typeof MutationObserver > "u") return;
352
+ let o = bt(e), n = !1, r = (s, c) => {
353
+ n || (n = !0, a.disconnect(), window.clearTimeout(l), t.afterNote = s, c && (t.afterHtml = Ue(at(e, Zt, wo))));
354
+ }, a = new MutationObserver(() => {
355
+ if (!e.isConnected) {
356
+ r("องค์ประกอบหายไปจากหน้าจอ", !1);
357
+ return;
358
+ }
359
+ let s = ko(o, bt(e));
360
+ s && r(s, !0);
361
+ });
362
+ a.observe(e, { attributes: !0, attributeFilter: ["disabled", "aria-disabled", "aria-busy", "class"], childList: !0, subtree: !0, characterData: !0 });
363
+ let l = window.setTimeout(() => {
364
+ if (!n && !e.isConnected) {
365
+ r("องค์ประกอบหายไปจากหน้าจอ", !1);
366
+ return;
367
+ }
368
+ n = !0, a.disconnect();
369
+ }, vo);
370
+ }
371
+ function Mo() {
372
+ if (ft || typeof window > "u") return;
373
+ ft = !0, document.addEventListener("click", (n) => {
374
+ if (Ie(n.target)) return;
375
+ let r = Yn(n.target);
376
+ if (!r) return;
377
+ let a = Xn(r);
378
+ if (!a) return;
379
+ let l = ke("click", `คลิก ${a}`, ro(r), Wn(r));
380
+ l && xo(r, l);
381
+ }, { capture: !0, passive: !0 }), document.addEventListener("change", (n) => {
382
+ if (Ie(n.target)) return;
383
+ let r = no(n.target);
384
+ r && ke("input", `แก้ไข ${r}`);
385
+ }, { capture: !0, passive: !0 }), document.addEventListener("submit", (n) => {
386
+ Ie(n.target) || ke("submit", "ส่งฟอร์ม");
387
+ }, { capture: !0, passive: !0 });
388
+ let e = () => ke("navigate", `ไปที่ ${rt(nt(location.pathname + location.search))}`), t = history.pushState.bind(history), o = history.replaceState.bind(history);
389
+ history.pushState = (...n) => {
390
+ let r = t(...n);
391
+ return e(), r;
392
+ }, history.replaceState = (...n) => {
393
+ let r = o(...n);
394
+ return e(), r;
395
+ }, window.addEventListener("popstate", e), yo();
396
+ }
397
+ function So() {
398
+ return ge.map((e) => ({ ...e }));
399
+ }
400
+ var yt = 2e3, ze = [], vt = 0, wt = !1;
401
+ function Fe(e, t) {
402
+ for (vt += 1, ze.push({ id: `log_${vt}`, at: (/* @__PURE__ */ new Date()).toISOString(), level: e, message: t.length > yt ? `${t.slice(0, yt)}…` : t }); ze.length > Ce("maxConsoleEntries"); ) ze.shift();
403
+ }
404
+ function Eo() {
405
+ let e = /* @__PURE__ */ new WeakSet();
406
+ return (t, o) => {
407
+ if (typeof o == "object" && o !== null) {
408
+ if (e.has(o)) return "[Circular]";
409
+ e.add(o);
410
+ }
411
+ return typeof o == "bigint" ? o.toString() : o;
412
+ };
413
+ }
414
+ function kt(e) {
415
+ if (typeof e == "string") return e;
416
+ if (e instanceof Error) return `${e.name}: ${e.message}`;
417
+ try {
418
+ return JSON.stringify(e, Eo()) ?? String(e);
419
+ } catch {
420
+ return String(e);
421
+ }
422
+ }
423
+ function Co() {
424
+ if (wt || typeof window > "u") return;
425
+ wt = !0;
426
+ let e = ["log", "info", "warn", "error", "debug"];
427
+ for (let t of e) {
428
+ let o = console[t].bind(console);
429
+ console[t] = (...n) => {
430
+ Fe(t, n.map(kt).join(" ")), o(...n);
431
+ };
432
+ }
433
+ window.addEventListener("error", (t) => {
434
+ let o = t.filename ? ` (${t.filename}:${t.lineno}:${t.colno})` : "";
435
+ Fe("exception", `${t.message}${o}`);
436
+ }), window.addEventListener("unhandledrejection", (t) => {
437
+ let o = t.reason instanceof Error ? `${t.reason.name}: ${t.reason.message}` : kt(t.reason);
438
+ Fe("unhandledrejection", o);
439
+ });
440
+ }
441
+ function Ao() {
442
+ return ze.map((e) => ({ ...e }));
443
+ }
444
+ var Gt = /* @__PURE__ */ new Set(), Kt = /* @__PURE__ */ new Set();
445
+ function jt(e, t) {
446
+ return e.add(t), () => e.delete(t);
447
+ }
448
+ function Wt(e, t) {
449
+ for (let o of [...e]) o(t);
450
+ }
451
+ function Lo(e) {
452
+ return jt(Gt, e);
453
+ }
454
+ function en(e = { type: "manual" }) {
455
+ Wt(Gt, e);
456
+ }
457
+ function To(e) {
458
+ return jt(Kt, e);
459
+ }
460
+ function _o(e) {
461
+ Wt(Kt, e);
462
+ }
463
+ var Ro = 15e3, Io = ["ResizeObserver loop", "Script error.", "Non-Error promise rejection captured"], xt = !1, Mt = 0;
464
+ function zo(e) {
465
+ return Io.some((t) => e.includes(t));
466
+ }
467
+ function St(e) {
468
+ let t = e.message ?? "";
469
+ if (!t || zo(t)) return;
470
+ let o = Date.now();
471
+ o - Mt < Ro || (Mt = o, _o({ ...e, message: t }));
472
+ }
473
+ function No() {
474
+ xt || typeof window > "u" || (xt = !0, window.addEventListener("error", (e) => {
475
+ if (!e.message && !e.error) return;
476
+ let t = e.error instanceof Error ? e.error : null;
477
+ St({ type: "runtime-error", message: e.message || (t ? t.message : "Unknown error"), stack: t == null ? void 0 : t.stack });
478
+ }), window.addEventListener("unhandledrejection", (e) => {
479
+ let t = e.reason;
480
+ St({ type: "unhandledrejection", message: t instanceof Error ? t.message : String(t), stack: t instanceof Error ? t.stack : void 0 });
481
+ }));
482
+ }
483
+ var tn = 4e3, Po = 1e6, Uo = 1e7, Ne = [], Et = 0, Ct = !1;
484
+ function nn(e) {
485
+ for (Ne.push(e); Ne.length > Ce("maxRequests"); ) Ne.shift();
486
+ }
487
+ function on() {
488
+ return Et += 1, `req_${Et}`;
489
+ }
490
+ function At(e) {
491
+ let t = {};
492
+ if (!e) return t;
493
+ if (e instanceof Headers) e.forEach((o, n) => {
494
+ t[n] = o;
495
+ });
496
+ else if (Array.isArray(e)) for (let [o, n] of e) t[o] = n;
497
+ else Object.assign(t, e);
498
+ return t;
499
+ }
500
+ function Do(e) {
501
+ let t = {};
502
+ return e.forEach((o, n) => {
503
+ t[n] = o;
504
+ }), t;
505
+ }
506
+ function Oo(e) {
507
+ return e == null ? null : typeof e == "string" ? e : e instanceof URLSearchParams ? e.toString() : typeof FormData < "u" && e instanceof FormData ? `[FormData: ${Array.from(e.keys()).join(", ")}]` : typeof Blob < "u" && e instanceof Blob ? `[Blob ${e.size} bytes]` : e instanceof ArrayBuffer ? `[ArrayBuffer ${e.byteLength} bytes]` : "[binary]";
508
+ }
509
+ function Bo(e, t) {
510
+ let o = "", n = "GET", r = {}, a = null;
511
+ return typeof e == "string" ? o = e : e instanceof URL ? o = e.toString() : (o = e.url, n = e.method || n, r = At(e.headers)), t && (t.method && (n = t.method), t.headers && (r = { ...r, ...At(t.headers) }), t.body !== void 0 && (a = Oo(t.body))), { method: n.toUpperCase(), url: o, headers: r, body: a };
512
+ }
513
+ function rn(e) {
514
+ return !zn(e);
515
+ }
516
+ function Ho(e, t) {
517
+ if (rn(t.url)) {
518
+ t.responseSnippet = "[body not captured for this origin]";
519
+ return;
520
+ }
521
+ let o = e.headers.get("content-type") ?? "", n = Number(e.headers.get("content-length") ?? "0"), r = n ? `, ~${n} bytes` : "";
522
+ if (!/json|text|xml|html|javascript|urlencoded/i.test(o)) {
523
+ t.responseSnippet = `[binary ${o || "unknown"}${r}]`;
524
+ return;
525
+ }
526
+ if (n > Po) {
527
+ t.responseSnippet = `[response ${o || "text"}${r} — omitted]`;
528
+ return;
529
+ }
530
+ try {
531
+ e.clone().text().then((a) => {
532
+ t.responseSnippet = Pe(a, Ce("maxBodyChars"));
533
+ }).catch(() => {
534
+ });
535
+ } catch {
536
+ }
537
+ }
538
+ function an(e, t) {
539
+ if (/[?&]_rsc=/.test(e)) return !0;
540
+ for (let o of Object.keys(t)) {
541
+ let n = o.toLowerCase();
542
+ if (n === "rsc" || n === "next-router-prefetch" || n === "next-router-state-tree") return !0;
543
+ }
544
+ return !1;
545
+ }
546
+ function Fo() {
547
+ if (typeof window > "u" || typeof window.fetch != "function") return;
548
+ let e = window.fetch.bind(window);
549
+ window.fetch = Object.assign(async (t, o) => {
550
+ let n = Bo(t, o);
551
+ if (an(n.url, n.headers)) return e(t, o);
552
+ let r = { id: on(), startedAt: (/* @__PURE__ */ new Date()).toISOString(), method: n.method, url: nt(n.url), requestHeaders: Ze(n.headers), requestBody: Pe(n.body, tn), status: null, statusText: null, durationMs: null, via: "fetch" };
553
+ nn(r);
554
+ let a = performance.now();
555
+ try {
556
+ let l = await e(t, o);
557
+ return r.status = l.status, r.statusText = l.statusText, r.durationMs = Math.round(performance.now() - a), r.responseHeaders = Ze(Do(l.headers)), Ho(l, r), l;
558
+ } catch (l) {
559
+ throw r.durationMs = Math.round(performance.now() - a), r.error = l instanceof Error ? `${l.name}: ${l.message}` : String(l), l;
560
+ }
561
+ }, e);
562
+ }
563
+ function $o() {
564
+ if (typeof window > "u" || typeof window.XMLHttpRequest != "function") return;
565
+ let e = XMLHttpRequest.prototype, t = e.open, o = e.send, n = function(a, l) {
566
+ let s = typeof l == "string" ? l : l.toString();
567
+ return this.__cibEntry = an(s, {}) ? void 0 : { id: on(), startedAt: "", method: (a || "GET").toUpperCase(), url: nt(s), requestHeaders: {}, requestBody: null, status: null, statusText: null, durationMs: null, via: "xhr" }, t.apply(this, arguments);
568
+ }, r = function(a) {
569
+ let l = this.__cibEntry;
570
+ if (l) {
571
+ l.startedAt = (/* @__PURE__ */ new Date()).toISOString(), l.requestBody = typeof a == "string" ? Pe(a, tn) : a == null ? null : "[non-string body]";
572
+ let s = performance.now();
573
+ nn(l), this.addEventListener("loadend", () => {
574
+ if (l.status = this.status || null, l.statusText = this.statusText || null, l.durationMs = Math.round(performance.now() - s), rn(l.url)) l.responseSnippet = "[body not captured for this origin]";
575
+ else if (this.responseType === "" || this.responseType === "text") try {
576
+ l.responseSnippet = Pe(this.responseText || "", Ce("maxBodyChars"));
577
+ } catch {
578
+ }
579
+ else {
580
+ let c = this.getResponseHeader("content-type") ?? this.responseType;
581
+ l.responseSnippet = `[binary ${c}]`;
582
+ }
583
+ });
584
+ }
585
+ return o.apply(this, arguments);
586
+ };
587
+ e.open = n, e.send = r;
588
+ }
589
+ function Qo() {
590
+ Ct || (Ct = !0, Fo(), $o());
591
+ }
592
+ function Vo() {
593
+ let e = Ne.map((o) => ({ ...o })), t = 0;
594
+ for (let o = e.length - 1; o >= 0; o -= 1) {
595
+ let n = e[o], r = n == null ? void 0 : n.responseSnippet;
596
+ !n || typeof r != "string" || r.length === 0 || (t + r.length > Uo ? n.responseSnippet = `[response omitted — report size budget reached (${r.length.toLocaleString()} chars)]` : t += r.length);
597
+ }
598
+ return e;
599
+ }
600
+ var qo = { title: "รายงานปัญหา", summaryLabel: "หัวข้อปัญหา", summaryRequired: "(ต้องกรอกก่อนแจ้งปัญหา)", summaryPlaceholder: "สรุปปัญหาสั้น ๆ เช่น กดบันทึกร่างแล้ว error", detailLabel: "อธิบายปัญหา (ไม่บังคับ)", detailPlaceholder: "เกิดอะไรขึ้น? กำลังทำอะไรอยู่ตอนที่พบปัญหา?", annotateTitle: "วาดบนรูป", annotateHint: "ทำเครื่องหมายจุดที่มีปัญหาก่อนแนบ — วงกรอบ ชี้ลูกศร ไฮไลต์ หรือพิมพ์ข้อความ", annotateApply: "ใช้รูปนี้", cancel: "ยกเลิก", toolRect: "กรอบ", toolArrow: "ลูกศร", toolHighlight: "ไฮไลต์", toolText: "ข้อความ", deleteSelected: "ลบที่เลือก", clearAll: "ล้างทั้งหมด", annotateHelp: "เลือกเครื่องมือแล้วลากบนรูป · ไม่ได้เลือกเครื่องมือ = ย้าย/ปรับขนาดสิ่งที่วาดไว้ · กดกากบาทมุมขวาบนของรูปทรงเพื่อลบ", capturing: "กำลังเก็บภาพหน้าจอ…", noScreenshot: "ไม่มีภาพหน้าจอ — ยังส่งรายงานได้", cancelled: "ยกเลิกการเก็บภาพหน้าจอแล้ว", close: "ปิด", submit: "แจ้งปัญหา", submitting: "กำลังส่ง…", submitted: "แจ้งปัญหาสำเร็จ", crashed: "เกิดข้อผิดพลาดในระบบ", crashAction: "แจ้งปัญหา", failed: "ส่งรายงานไม่สำเร็จ", captured: "เก็บข้อมูลแล้ว", reporter: "ผู้แจ้ง", page: "หน้า" }, Jo = { title: "Report a problem", summaryLabel: "Summary", summaryRequired: "(required)", summaryPlaceholder: "One line, e.g. saving a draft returns an error", detailLabel: "Details (optional)", detailPlaceholder: "What happened? What were you doing at the time?", annotateTitle: "Draw on the image", annotateHint: "Mark what went wrong before attaching — box it, point at it, highlight it, or type on it", annotateApply: "Use this image", cancel: "Cancel", toolRect: "Box", toolArrow: "Arrow", toolHighlight: "Highlight", toolText: "Text", deleteSelected: "Delete selected", clearAll: "Clear all", annotateHelp: "Pick a tool and drag on the image · no tool selected = move/resize what you drew · press the ✕ on a shape to delete it", capturing: "Capturing the screen…", noScreenshot: "No screenshot — you can still send the report", cancelled: "Screen capture cancelled", close: "Close", submit: "Send report", submitting: "Sending…", submitted: "Report sent", crashed: "Something went wrong", crashAction: "Report it", failed: "Could not send the report", captured: "Captured", reporter: "Reporter", page: "Page" };
601
+ function lt(e) {
602
+ return e === "en" ? Jo : qo;
603
+ }
604
+ var ve = null;
605
+ function Zo() {
606
+ if (typeof document > "u") return null;
607
+ if (ve != null && ve.isConnected) return ve;
608
+ let e = document.createElement("lw-debug-toasts");
609
+ e.dataset.debugReporter = "true";
610
+ let t = e.attachShadow({ mode: "open" }), o = document.createElement("style");
611
+ o.textContent = `
612
+ :host { all: initial; }
613
+ .stack {
614
+ position: fixed; top: 16px; right: 16px; z-index: 2147483001;
615
+ display: flex; flex-direction: column; gap: 8px; pointer-events: none;
616
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans Thai", sans-serif;
617
+ }
618
+ .toast {
619
+ pointer-events: auto; display: flex; align-items: center; gap: 8px;
620
+ max-width: 380px; padding: 12px 14px; border-radius: 10px;
621
+ font-size: 14px; line-height: 1.5; color: #0f172a;
622
+ background: #fff; border: 1px solid #e2e8f0;
623
+ box-shadow: 0 10px 30px rgba(15, 23, 42, 0.16);
624
+ animation: in 160ms ease-out;
625
+ }
626
+ .toast[data-tone="success"] { border-left: 3px solid #10b981; }
627
+ .toast[data-tone="error"] { border-left: 3px solid #e11d48; }
628
+ .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
629
+ .toast[data-tone="success"] .dot { background: #10b981; }
630
+ .toast[data-tone="error"] .dot { background: #e11d48; }
631
+ .action {
632
+ flex: none; cursor: pointer; padding: 5px 10px; margin-left: auto;
633
+ font: inherit; font-size: 13px; font-weight: 600;
634
+ color: #fff; background: #0f172a; border: none; border-radius: 7px;
635
+ }
636
+ .action + .close { margin-left: 4px; }
637
+ .close {
638
+ margin-left: auto; flex: none; cursor: pointer; border: none; background: none;
639
+ padding: 0 2px; font: inherit; font-size: 16px; line-height: 1; color: #94a3b8;
640
+ }
641
+ @keyframes in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
642
+ @media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
643
+ `;
644
+ let n = document.createElement("div");
645
+ return n.className = "stack", n.setAttribute("role", "status"), n.setAttribute("aria-live", "polite"), t.append(o, n), document.body.append(e), ve = n, n;
646
+ }
647
+ function Ge(e, t = "success", o) {
648
+ let n = Zo();
649
+ if (!n) return;
650
+ let r = document.createElement("div");
651
+ r.className = "toast", r.dataset.tone = t;
652
+ let a = document.createElement("span");
653
+ a.className = "dot";
654
+ let l = document.createElement("span");
655
+ l.textContent = e;
656
+ let s = document.createElement("button");
657
+ s.type = "button", s.className = "close", s.textContent = "✕", s.setAttribute("aria-label", "ปิด");
658
+ let c = () => {
659
+ window.clearTimeout(g), r.remove();
660
+ };
661
+ s.addEventListener("click", c);
662
+ let g = t === "error" || o ? 0 : window.setTimeout(c, 6e3);
663
+ if (r.append(a, l), o) {
664
+ let k = document.createElement("button");
665
+ k.type = "button", k.className = "action", k.textContent = o.label, k.addEventListener("click", () => {
666
+ c(), o.onClick();
667
+ }), r.append(k);
668
+ }
669
+ r.append(s), n.append(r);
670
+ }
671
+ function Yo(e, t, o) {
672
+ let n = e.filter((a) => !!a.error || a.status != null && a.status >= 400).slice(-20).map((a) => ({ method: a.method, url: a.url, status: a.status, error: a.error, at: a.startedAt })), r = t.filter((a) => a.level === "error" || a.level === "exception" || a.level === "unhandledrejection").slice(-20).map((a) => a.message);
673
+ return { failedRequests: n, errors: r, erroredQueries: o.slice(0, 20) };
674
+ }
675
+ function Xo() {
676
+ let e = { memoryUsedMb: null, memoryLimitMb: null, domContentLoadedMs: null, loadEventMs: null };
677
+ if (typeof performance > "u") return e;
678
+ let t = performance.memory;
679
+ t && (e.memoryUsedMb = Math.round(t.usedJSHeapSize / 1024 / 1024), e.memoryLimitMb = Math.round(t.jsHeapSizeLimit / 1024 / 1024));
680
+ let [o] = performance.getEntriesByType("navigation");
681
+ return o && (e.domContentLoadedMs = Math.round(o.domContentLoadedEventEnd), e.loadEventMs = Math.round(o.loadEventEnd)), e;
682
+ }
683
+ function $e(e, t) {
684
+ if (!e) return t;
685
+ try {
686
+ return e();
687
+ } catch {
688
+ return t;
689
+ }
690
+ }
691
+ function Go() {
692
+ let e = X(), { pathname: t, search: o, href: n } = window.location;
693
+ return { capturedAt: (/* @__PURE__ */ new Date()).toISOString(), route: { href: n, pathname: t, search: o }, module: Rn(t), user: $e(e.user, {}), apiHeaders: Ze($e(e.headers, {})), app: { name: Me().name, version: Me().version, environment: Me().environment }, client: { userAgent: navigator.userAgent, language: navigator.language, platform: navigator.platform, online: navigator.onLine, viewport: { width: window.innerWidth, height: window.innerHeight, dpr: window.devicePixelRatio }, screen: { width: window.screen.width, height: window.screen.height } }, performance: Xo(), extra: $e(e.extra, {}) };
694
+ }
695
+ var Ko = 2;
696
+ function jo(e) {
697
+ let t = Vo(), o = Ao();
698
+ return { context: Go(), reason: e.reason, note: e.note, cause: Yo(t, o, e.erroredQueries), actionTrail: So(), network: t, console: o, screenshotDataUrl: e.screenshotDataUrl, screenshotMethod: e.screenshotMethod, meta: { generatedBy: "lightwork-debug-capture", schemaVersion: Ko } };
699
+ }
700
+ async function Wo() {
701
+ var t;
702
+ if (typeof navigator < "u" && ((t = navigator.mediaDevices) != null && t.getDisplayMedia)) {
703
+ let o = await er();
704
+ if (o.status === "ok") return { dataUrl: o.dataUrl, method: "display-media" };
705
+ if (o.status === "cancelled") return { dataUrl: null, method: "cancelled" };
706
+ }
707
+ let e = await or();
708
+ return e ? { dataUrl: e, method: "html-to-image" } : { dataUrl: null, method: "none" };
709
+ }
710
+ async function er() {
711
+ let e = null;
712
+ try {
713
+ let t = { video: { frameRate: 30 }, audio: !1, preferCurrentTab: !0, selfBrowserSurface: "include", surfaceSwitching: "exclude" };
714
+ e = await navigator.mediaDevices.getDisplayMedia(t);
715
+ let o = await tr(e);
716
+ return o ? { status: "ok", dataUrl: o } : { status: "error" };
717
+ } catch (t) {
718
+ return t instanceof DOMException && (t.name === "NotAllowedError" || t.name === "AbortError") ? { status: "cancelled" } : { status: "error" };
719
+ } finally {
720
+ e == null || e.getTracks().forEach((t) => t.stop());
721
+ }
722
+ }
723
+ async function tr(e) {
724
+ let t = document.createElement("video");
725
+ t.srcObject = e, t.muted = !0, t.playsInline = !0, await new Promise((l) => {
726
+ let s = !1, c = () => {
727
+ s || (s = !0, l());
728
+ };
729
+ t.onloadedmetadata = () => {
730
+ t.play().then(c).catch(c);
731
+ }, window.setTimeout(c, 1500);
732
+ }), await nr(t);
733
+ let { videoWidth: o, videoHeight: n } = t;
734
+ if (!o || !n) return null;
735
+ let r = document.createElement("canvas");
736
+ r.width = o, r.height = n;
737
+ let a = r.getContext("2d");
738
+ if (!a) return null;
739
+ a.drawImage(t, 0, 0, o, n), t.pause(), t.srcObject = null;
740
+ try {
741
+ return r.toDataURL("image/png");
742
+ } catch {
743
+ return null;
744
+ }
745
+ }
746
+ function nr(e) {
747
+ return new Promise((t) => {
748
+ let o = !1, n = () => {
749
+ o || (o = !0, t());
750
+ }, r = e;
751
+ typeof r.requestVideoFrameCallback == "function" ? (r.requestVideoFrameCallback(() => n()), window.setTimeout(n, 1e3)) : window.setTimeout(n, 250);
752
+ });
753
+ }
754
+ async function or() {
755
+ let e = X().screenshotFallback;
756
+ if (!e) return null;
757
+ let t = await e().catch(() => null);
758
+ if (!t) return null;
759
+ try {
760
+ return await t(document.body, { cacheBust: !0, pixelRatio: Math.min(window.devicePixelRatio || 1, 2), filter: (o) => {
761
+ var n;
762
+ return !(o instanceof HTMLElement && ((n = o.dataset) == null ? void 0 : n.debugReporter) === "true");
763
+ } });
764
+ } catch {
765
+ return null;
766
+ }
767
+ }
768
+ var rr = 2e3, ar = 0.82, lr = 3e6;
769
+ function ir(e) {
770
+ return new Promise((t, o) => {
771
+ let n = new Image();
772
+ n.onload = () => t(n), n.onerror = () => o(Error("could not read the screenshot")), n.src = e;
773
+ });
774
+ }
775
+ async function sr(e) {
776
+ try {
777
+ let t = await ir(e), o = Math.max(t.naturalWidth, t.naturalHeight), n = Math.min(1, rr / o), r = document.createElement("canvas");
778
+ r.width = Math.max(1, Math.round(t.naturalWidth * n)), r.height = Math.max(1, Math.round(t.naturalHeight * n));
779
+ let a = r.getContext("2d");
780
+ if (!a) return e;
781
+ a.fillStyle = "#fff", a.fillRect(0, 0, r.width, r.height), a.drawImage(t, 0, 0, r.width, r.height);
782
+ let l = ar, s = r.toDataURL("image/jpeg", l);
783
+ for (; s.length > lr && l > 0.4; ) l -= 0.15, s = r.toDataURL("image/jpeg", l);
784
+ return s;
785
+ } catch {
786
+ return e;
787
+ }
788
+ }
789
+ var ur = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, cr = /^\d+$/, dr = /^[0-9a-f]{16,}$/i;
790
+ function fr(e) {
791
+ var a, l;
792
+ if (e.reason.type === "manual") return null;
793
+ let t = (l = (a = e.cause) == null ? void 0 : a.failedRequests) == null ? void 0 : l[0];
794
+ if (!(t != null && t.url)) return null;
795
+ let o;
796
+ try {
797
+ o = new URL(t.url, "http://x").pathname;
798
+ } catch {
799
+ o = t.url;
800
+ }
801
+ let n = o.split("/").map((s) => ur.test(s) || cr.test(s) || dr.test(s) ? ":id" : s).join("/"), r = t.status ?? (t.error ? "ERR" : "?");
802
+ return `${t.method ?? "REQ"} ${n} ${r}`;
803
+ }
804
+ var hr = 2e6;
805
+ function Te(e) {
806
+ let { screenshotDataUrl: t, ...o } = e;
807
+ return JSON.stringify(o).length;
808
+ }
809
+ function pr(e, t = 2e6) {
810
+ if (Te(e) <= t) return e;
811
+ let o = e.network.map((r) => ({ ...r })), n = { ...e, network: o };
812
+ for (let r of o) {
813
+ if (Te(n) <= t) return n;
814
+ typeof r.responseSnippet == "string" && r.responseSnippet.length > 35 && (r.responseSnippet = "[body dropped — report size budget]"), typeof r.requestBody == "string" && r.requestBody.length > 35 && (r.requestBody = "[body dropped — report size budget]");
815
+ }
816
+ for (; n.network.length > 1 && Te(n) > t; ) n.network = n.network.slice(1);
817
+ for (; n.console.length > 1 && Te(n) > t; ) n.console = n.console.slice(1);
818
+ return n;
819
+ }
820
+ var Lt = 32768;
821
+ function mr(e) {
822
+ let t = "";
823
+ for (let o = 0; o < e.length; o += Lt) t += String.fromCharCode(...e.subarray(o, o + Lt));
824
+ return btoa(t);
825
+ }
826
+ function gr(e) {
827
+ return { dataUri: `data:application/json;base64,${mr(new TextEncoder().encode(JSON.stringify(e)))}`, filename: "debug-bundle.json" };
828
+ }
829
+ async function br(e, t) {
830
+ var k, w;
831
+ let o = X(), n = pr(t, hr), { context: r, note: a } = n, l = [];
832
+ if (n.screenshotDataUrl) {
833
+ let S = await sr(n.screenshotDataUrl);
834
+ l.push({ dataUri: S, filename: "screenshot.jpg" });
835
+ }
836
+ l.push(gr(n));
837
+ let s = fr(n), c = { title: e, description: a.trim() || void 0, category: ((k = r.module) == null ? void 0 : k.label) || Me().name, routeUrl: r.route.href, priority: "MEDIUM", requesterEmail: r.user.email ?? void 0, requesterName: r.user.fullName ?? void 0, customFields: { unit: r.user.unit ?? "", appVersion: r.app.version, environment: r.app.environment, reasonType: n.reason.type, appName: Me().name, module: ((w = r.module) == null ? void 0 : w.label) ?? "" }, context: { ...s ? { signature: s } : {}, capturedAt: r.capturedAt, reason: n.reason, cause: n.cause, actionTrail: n.actionTrail, client: r.client, performance: r.performance, apiHeaders: r.apiHeaders, extra: r.extra, counts: { network: n.network.length, console: n.console.length, actions: n.actionTrail.length }, screenshotMethod: n.screenshotMethod }, attachments: l }, g = await fetch(`${o.host.replace(/\/$/, "")}/ingest/tickets`, { method: "POST", headers: { "content-type": "application/json", "x-realm-key": o.realmKey }, body: JSON.stringify(c) });
838
+ if (!g.ok) {
839
+ let S = g.headers.get("retry-after"), E = await g.json().then((T) => T.error).catch(() => null);
840
+ throw Error(g.status === 429 ? `Too many reports — try again in ${S ?? "a moment"}s` : E ?? `Report failed (${g.status})`);
841
+ }
842
+ return await g.json();
843
+ }
844
+ var we = Math.PI / 6;
845
+ function yr(e, t, o) {
846
+ let n = t.x - e.x, r = t.y - e.y, a = Math.hypot(n, r), l = Math.atan2(r, n), s = [{ x: t.x, y: t.y }, { x: t.x - o * Math.cos(l - we), y: t.y - o * Math.sin(l - we) }, { x: t.x - o * Math.cos(l + we), y: t.y - o * Math.sin(l + we) }], c = o * Math.cos(we) * 0.92;
847
+ return a <= c ? { shaft: null, head: s } : { shaft: { from: e, to: { x: t.x - c * Math.cos(l), y: t.y - c * Math.sin(l) } }, head: s };
848
+ }
849
+ var Qe = "#f44336", vr = "rgba(250, 204, 21, 0.4)", Ve = 22, Tt = "#2563eb", _t = 9, Rt = 11, It = 18, zt = 4, _e = 8, wr = [{ id: "nw", fx: 0, fy: 0, cursor: "nwse-resize" }, { id: "n", fx: 0.5, fy: 0, cursor: "ns-resize" }, { id: "ne", fx: 1, fy: 0, cursor: "nesw-resize" }, { id: "e", fx: 1, fy: 0.5, cursor: "ew-resize" }, { id: "se", fx: 1, fy: 1, cursor: "nwse-resize" }, { id: "s", fx: 0.5, fy: 1, cursor: "ns-resize" }, { id: "sw", fx: 0, fy: 1, cursor: "nesw-resize" }, { id: "w", fx: 0, fy: 0.5, cursor: "ew-resize" }];
850
+ function ln(e, t, o) {
851
+ let n = [], r = null, a = -1, l = null, s = null, c = e.getContext("2d");
852
+ function g() {
853
+ let i = e.getBoundingClientRect().width;
854
+ return i > 0 ? e.width / i : 1;
855
+ }
856
+ function k(i) {
857
+ let u = e.getBoundingClientRect();
858
+ return { x: (i.clientX - u.left) / u.width * e.width, y: (i.clientY - u.top) / u.height * e.height };
859
+ }
860
+ function w(i) {
861
+ var p;
862
+ let u = i.size ?? Ve;
863
+ if (!c) return (((p = i.text) == null ? void 0 : p.length) ?? 0) * u * 0.6;
864
+ c.save(), c.font = `600 ${u}px system-ui, sans-serif`;
865
+ let d = c.measureText(i.text ?? "").width;
866
+ return c.restore(), d;
867
+ }
868
+ function S(i) {
869
+ if (i.tool === "text") {
870
+ let u = i.size ?? Ve;
871
+ return { left: i.x1, top: i.y1, right: i.x1 + w(i), bottom: i.y1 + u * 1.25 };
872
+ }
873
+ return { left: Math.min(i.x1, i.x2), top: Math.min(i.y1, i.y2), right: Math.max(i.x1, i.x2), bottom: Math.max(i.y1, i.y2) };
874
+ }
875
+ function E(i) {
876
+ if (i.tool === "arrow") return [{ id: "tail", x: i.x1, y: i.y1, cursor: "move" }, { id: "head", x: i.x2, y: i.y2, cursor: "move" }];
877
+ let u = S(i);
878
+ return i.tool === "text" ? [{ id: "size", x: u.right, y: u.bottom, cursor: "nwse-resize" }] : wr.map((d) => ({ id: d.id, x: u.left + (u.right - u.left) * d.fx, y: u.top + (u.bottom - u.top) * d.fy, cursor: d.cursor }));
879
+ }
880
+ function T(i) {
881
+ let u = S(i);
882
+ return { x: u.right + It * g(), y: u.top - It * g() };
883
+ }
884
+ function R(i, u, d) {
885
+ let { shaft: p, head: b } = yr({ x: u.x1, y: u.y1 }, { x: u.x2, y: u.y2 }, Math.max(10, 16 * d));
886
+ p && (i.lineCap = "butt", i.beginPath(), i.moveTo(p.from.x, p.from.y), i.lineTo(p.to.x, p.to.y), i.stroke()), i.beginPath(), i.moveTo(b[0].x, b[0].y), i.lineTo(b[1].x, b[1].y), i.lineTo(b[2].x, b[2].y), i.closePath(), i.fill();
887
+ }
888
+ function x(i, u, d) {
889
+ i.save(), i.lineWidth = Math.max(2, 3 * d), i.strokeStyle = Qe, i.fillStyle = Qe;
890
+ let p = S(u);
891
+ if (u.tool === "rect") i.strokeRect(p.left, p.top, p.right - p.left, p.bottom - p.top);
892
+ else if (u.tool === "arrow") R(i, u, d);
893
+ else if (u.tool === "highlight") i.fillStyle = vr, i.fillRect(p.left, p.top, p.right - p.left, p.bottom - p.top);
894
+ else if (u.tool === "text" && u.text) {
895
+ let b = u.size ?? Ve;
896
+ i.font = `600 ${b}px system-ui, sans-serif`, i.textBaseline = "top";
897
+ let C = b * 0.22;
898
+ i.fillStyle = "rgba(255,255,255,0.92)", i.fillRect(p.left - C, p.top - C, p.right - p.left + C * 2, p.bottom - p.top + C * 2), i.fillStyle = Qe, i.fillText(u.text, p.left, p.top);
899
+ }
900
+ i.restore();
901
+ }
902
+ function M(i, u, d) {
903
+ let p = S(u);
904
+ i.save(), i.strokeStyle = Tt, i.lineWidth = Math.max(1, 1.5 * d), i.setLineDash([6 * d, 4 * d]), i.strokeRect(p.left, p.top, p.right - p.left, p.bottom - p.top), i.setLineDash([]);
905
+ let b = _t * d;
906
+ for (let K of E(u)) i.fillStyle = "#fff", i.strokeStyle = Tt, i.lineWidth = Math.max(1, 1.5 * d), i.beginPath(), i.rect(K.x - b / 2, K.y - b / 2, b, b), i.fill(), i.stroke();
907
+ let C = T(u), D = Rt * d;
908
+ i.beginPath(), i.arc(C.x, C.y, D, 0, Math.PI * 2), i.fillStyle = "#dc2626", i.fill(), i.strokeStyle = "#fff", i.lineWidth = Math.max(1.5, 2 * d), i.beginPath(), i.moveTo(C.x - D * 0.4, C.y - D * 0.4), i.lineTo(C.x + D * 0.4, C.y + D * 0.4), i.moveTo(C.x + D * 0.4, C.y - D * 0.4), i.lineTo(C.x - D * 0.4, C.y + D * 0.4), i.stroke(), i.restore();
909
+ }
910
+ function A() {
911
+ if (!c) return;
912
+ let i = g();
913
+ c.clearRect(0, 0, e.width, e.height), c.drawImage(t, 0, 0, e.width, e.height), n.forEach((d, p) => {
914
+ p !== _ && x(c, d, i);
915
+ }), l && x(c, l, i);
916
+ let u = n[a];
917
+ u && !l && M(c, u, i);
918
+ }
919
+ function Q(i, u, d, p, b) {
920
+ return Math.abs(i - d) <= b && Math.abs(u - p) <= b;
921
+ }
922
+ function j(i, u) {
923
+ let d = n[a];
924
+ if (!d) return null;
925
+ let p = _t * g() / 2 + 3 * g();
926
+ for (let b of E(d)) if (Q(i, u, b.x, b.y, p)) return b.id;
927
+ return null;
928
+ }
929
+ function ne(i, u) {
930
+ let d = n[a];
931
+ if (!d) return !1;
932
+ let p = T(d);
933
+ return Q(i, u, p.x, p.y, Rt * g());
934
+ }
935
+ function W(i, u) {
936
+ let d = 6 * g();
937
+ for (let p = n.length - 1; p >= 0; p -= 1) {
938
+ let b = n[p];
939
+ if (b.tool === "arrow") {
940
+ let D = b.x2 - b.x1, K = b.y2 - b.y1, ue = Math.hypot(D, K) || 1, ce = Math.max(0, Math.min(1, ((i - b.x1) * D + (u - b.y1) * K) / (ue * ue)));
941
+ if (Math.hypot(i - (b.x1 + ce * D), u - (b.y1 + ce * K)) <= d + 4 * g()) return p;
942
+ continue;
943
+ }
944
+ let C = S(b);
945
+ if (i >= C.left - d && i <= C.right + d && u >= C.top - d && u <= C.bottom + d) return p;
946
+ }
947
+ return -1;
948
+ }
949
+ function ie(i, u, d, p, b) {
950
+ if (u === "tail") {
951
+ i.x1 = d.x1 + p, i.y1 = d.y1 + b;
952
+ return;
953
+ }
954
+ if (u === "head") {
955
+ i.x2 = d.x2 + p, i.y2 = d.y2 + b;
956
+ return;
957
+ }
958
+ if (u === "size") {
959
+ let gn = (d.size ?? 24) + b;
960
+ i.size = Math.max(10, gn);
961
+ return;
962
+ }
963
+ let C = S(d), { left: D, top: K, right: ue, bottom: ce } = C;
964
+ u.includes("w") && (D = Math.min(ue - _e, D + p)), u.includes("e") && (ue = Math.max(D + _e, ue + p)), u.includes("n") && (K = Math.min(ce - _e, K + b)), u.includes("s") && (ce = Math.max(K + _e, ce + b)), i.x1 = D, i.y1 = K, i.x2 = ue, i.y2 = ce;
965
+ }
966
+ function he(i, u, d, p) {
967
+ i.x1 = u.x1 + d, i.y1 = u.y1 + p, i.x2 = u.x2 + d, i.y2 = u.y2 + p;
968
+ }
969
+ let h = null, _ = -1, L = { x: 0, y: 0, size: 24 };
970
+ function H() {
971
+ let i = e.getBoundingClientRect().width;
972
+ return i > 0 ? i / e.width : 1;
973
+ }
974
+ function Z(i, u) {
975
+ if (!c) return i.length * u * 0.6;
976
+ c.save(), c.font = `600 ${u}px system-ui, sans-serif`;
977
+ let d = c.measureText(i || " ").width;
978
+ return c.restore(), d;
979
+ }
980
+ function ee() {
981
+ if (!h) return;
982
+ let i = e.parentElement;
983
+ if (!i) return;
984
+ let u = e.getBoundingClientRect(), d = i.getBoundingClientRect(), p = H(), b = L.size * p;
985
+ h.style.left = `${u.left - d.left + L.x * p}px`, h.style.top = `${u.top - d.top + L.y * p}px`, h.style.fontSize = `${b}px`, h.style.width = `${Math.max(40, Z(h.value, b) + b)}px`;
986
+ }
987
+ function te(i) {
988
+ let u = h;
989
+ if (!u) return;
990
+ h = null;
991
+ let d = u.value.trim(), p = _;
992
+ _ = -1, u.remove(), i && d ? (p >= 0 && n[p] ? (n[p].text = d, a = p) : (n.push({ tool: "text", x1: L.x, y1: L.y, x2: L.x, y2: L.y, text: d, size: L.size }), a = n.length - 1), o()) : p >= 0 && (a = p), e.focus(), A();
993
+ }
994
+ function se(i, u, d = -1) {
995
+ te(!0);
996
+ let p = e.parentElement;
997
+ if (!p) return;
998
+ getComputedStyle(p).position === "static" && (p.style.position = "relative");
999
+ let b = d >= 0 ? n[d] : void 0;
1000
+ _ = d, L = { x: (b == null ? void 0 : b.x1) ?? i, y: (b == null ? void 0 : b.y1) ?? u, size: (b == null ? void 0 : b.size) ?? Math.round(24 * g()) };
1001
+ let C = document.createElement("input");
1002
+ C.type = "text", C.className = "text-edit", C.value = (b == null ? void 0 : b.text) ?? "", C.setAttribute("aria-label", "ข้อความบนภาพ"), C.placeholder = "ข้อความ", h = C, p.append(C), ee(), C.addEventListener("input", ee), C.addEventListener("keydown", (D) => {
1003
+ D.stopPropagation(), D.key === "Enter" ? te(!0) : D.key === "Escape" && te(!1);
1004
+ }), requestAnimationFrame(() => {
1005
+ h === C && (C.focus(), C.select(), C.addEventListener("blur", () => te(!0)));
1006
+ }), A();
1007
+ }
1008
+ function oe(i) {
1009
+ let { x: u, y: d } = k(i);
1010
+ if (e.setPointerCapture(i.pointerId), ne(u, d)) {
1011
+ z();
1012
+ return;
1013
+ }
1014
+ let p = j(u, d);
1015
+ if (p && n[a]) {
1016
+ s = { grip: p, x: u, y: d, start: { ...n[a] } };
1017
+ return;
1018
+ }
1019
+ if (r === "text") {
1020
+ i.preventDefault(), e.hasPointerCapture(i.pointerId) && e.releasePointerCapture(i.pointerId), r = null, o(), se(u, d);
1021
+ return;
1022
+ }
1023
+ if (r) {
1024
+ l = { tool: r, x1: u, y1: d, x2: u, y2: d }, a = -1;
1025
+ return;
1026
+ }
1027
+ let b = W(u, d);
1028
+ a = b, s = b >= 0 ? { grip: "body", x: u, y: d, start: { ...n[b] } } : null, A();
1029
+ }
1030
+ function Ae(i) {
1031
+ let { x: u, y: d } = k(i);
1032
+ if (l) {
1033
+ l.x2 = u, l.y2 = d, A();
1034
+ return;
1035
+ }
1036
+ if (s) {
1037
+ let b = n[a];
1038
+ if (!b) return;
1039
+ let C = u - s.x, D = d - s.y;
1040
+ s.grip === "body" ? he(b, s.start, C, D) : ie(b, s.grip, s.start, C, D), A();
1041
+ return;
1042
+ }
1043
+ if (r) {
1044
+ e.style.cursor = "crosshair";
1045
+ return;
1046
+ }
1047
+ if (ne(u, d)) {
1048
+ e.style.cursor = "pointer";
1049
+ return;
1050
+ }
1051
+ let p = j(u, d);
1052
+ if (p) {
1053
+ let b = n[a] ? E(n[a]).find((C) => C.id === p) : null;
1054
+ e.style.cursor = (b == null ? void 0 : b.cursor) ?? "pointer";
1055
+ return;
1056
+ }
1057
+ e.style.cursor = W(u, d) >= 0 ? "move" : "default";
1058
+ }
1059
+ function pe() {
1060
+ l && (Math.abs(l.x2 - l.x1) < zt && Math.abs(l.y2 - l.y1) < zt || (n.push(l), a = n.length - 1, r = null, o()), l = null), s && (s = null, o()), A();
1061
+ }
1062
+ function Le(i) {
1063
+ let u = e.getBoundingClientRect(), d = (i.clientX - u.left) / u.width * e.width, p = (i.clientY - u.top) / u.height * e.height, b = W(d, p), C = n[b];
1064
+ !C || C.tool !== "text" || (i.preventDefault(), se(C.x1, C.y1, b));
1065
+ }
1066
+ function I(i) {
1067
+ a < 0 || (i.key === "Delete" || i.key === "Backspace" ? (i.preventDefault(), z()) : i.key === "Escape" && (a = -1, A()));
1068
+ }
1069
+ function z() {
1070
+ a < 0 || (n.splice(a, 1), a = -1, o(), A());
1071
+ }
1072
+ return e.addEventListener("pointerdown", oe), e.addEventListener("pointermove", Ae), e.addEventListener("pointerup", pe), e.addEventListener("pointercancel", pe), e.addEventListener("dblclick", Le), e.tabIndex = 0, e.addEventListener("keydown", I), A(), { setTool(i) {
1073
+ r = i, a = -1, e.style.cursor = i ? "crosshair" : "default", A();
1074
+ }, deleteSelected: z, clear() {
1075
+ n.length = 0, a = -1, o(), A();
1076
+ }, hasShapes: () => n.length > 0, hasSelection: () => a >= 0, toDataUrl() {
1077
+ let i = document.createElement("canvas");
1078
+ i.width = t.naturalWidth, i.height = t.naturalHeight;
1079
+ let u = i.getContext("2d");
1080
+ if (!u) return e.toDataURL("image/png");
1081
+ u.drawImage(t, 0, 0);
1082
+ let d = g();
1083
+ for (let p of n) x(u, p, d);
1084
+ return i.toDataURL("image/png");
1085
+ }, destroy() {
1086
+ te(!1), e.removeEventListener("pointerdown", oe), e.removeEventListener("pointermove", Ae), e.removeEventListener("pointerup", pe), e.removeEventListener("pointercancel", pe), e.removeEventListener("dblclick", Le), e.removeEventListener("keydown", I);
1087
+ } };
1088
+ }
1089
+ var kr = `
1090
+ :host { all: initial; }
1091
+ * { box-sizing: border-box; }
1092
+
1093
+ .backdrop {
1094
+ position: fixed; inset: 0; z-index: 2147483000;
1095
+ display: flex; align-items: center; justify-content: center;
1096
+ padding: 24px; background: rgba(15, 23, 42, 0.55);
1097
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans Thai", sans-serif;
1098
+ color: #0f172a;
1099
+ }
1100
+ .panel {
1101
+ display: flex; flex-direction: column; gap: 16px;
1102
+ width: min(820px, 100%); max-height: 90vh; overflow-y: auto;
1103
+ /* No bottom padding: the footer supplies its own and sits flush, so it can
1104
+ stick to the panel's edge without a gap under it. */
1105
+ padding: 24px 24px 0; border-radius: 16px; background: #fff;
1106
+ box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
1107
+ }
1108
+ .head { display: flex; align-items: flex-start; gap: 12px; }
1109
+ h2 { margin: 0; font-size: 20px; font-weight: 700; flex: 1; }
1110
+ label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
1111
+ .req { color: #dc2626; }
1112
+ .hint { font-weight: 400; color: #64748b; }
1113
+ input[type="text"], textarea {
1114
+ width: 100%; padding: 10px 12px; font: inherit; font-size: 14px;
1115
+ border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; color: inherit;
1116
+ }
1117
+ input[type="text"]:focus, textarea:focus {
1118
+ outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);
1119
+ }
1120
+ textarea { min-height: 88px; resize: vertical; }
1121
+
1122
+ .meta {
1123
+ padding: 12px 14px; border-radius: 10px; background: #f8fafc;
1124
+ font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;
1125
+ }
1126
+ .meta b { color: #0f172a; font-weight: 600; }
1127
+
1128
+ .tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
1129
+ .sep { width: 1px; align-self: stretch; background: #e2e8f0; margin: 0 4px; }
1130
+ button {
1131
+ display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
1132
+ padding: 8px 14px; font: inherit; font-size: 14px; font-weight: 500;
1133
+ border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; color: inherit;
1134
+ }
1135
+ button:hover:not(:disabled) { background: #f1f5f9; }
1136
+ button:disabled { opacity: 0.5; cursor: not-allowed; }
1137
+ button[aria-pressed="true"] { border-color: #2563eb; background: #eff6ff; color: #1d4ed8; }
1138
+ button.primary { background: #2563eb; border-color: #2563eb; color: #fff; }
1139
+ button.primary:hover:not(:disabled) { background: #1d4ed8; }
1140
+ button.icon { padding: 6px 10px; border-color: transparent; font-size: 18px; line-height: 1; }
1141
+
1142
+ /* The on-image text editor. Absolutely placed over the canvas and matched to
1143
+ the shape it becomes — same weight, same red, same white plate — so what you
1144
+ type is what gets drawn, at the position you clicked. Sized in JS, because
1145
+ the font size tracks the image's own scale. */
1146
+ .text-edit {
1147
+ position: absolute; z-index: 2; margin: 0; padding: 2px 4px;
1148
+ font-family: system-ui, sans-serif; font-weight: 600; line-height: 1.25;
1149
+ color: #e11d48; background: rgba(255, 255, 255, 0.92);
1150
+ border: 1px dashed #e11d48; border-radius: 4px; outline: none;
1151
+ box-shadow: 0 2px 10px rgba(15, 23, 42, 0.18);
1152
+ }
1153
+ .text-edit::placeholder { color: rgba(225, 29, 72, 0.45); }
1154
+
1155
+ canvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; border-radius: 10px; touch-action: none; }
1156
+ .shot { position: relative; }
1157
+ .status { font-size: 13px; color: #64748b; }
1158
+ .status[data-tone="error"] { color: #dc2626; }
1159
+ /* Pinned to the bottom of the scrolling panel.
1160
+ A screenshot is tall — often taller than the viewport — so แจ้งปัญหา sat
1161
+ below the fold and the last step of filing a report was "scroll to the end
1162
+ and find the button". Sticky, with its own ground and a rule above it so the
1163
+ annotated image scrolls underneath rather than bleeding into it. */
1164
+ .foot {
1165
+ position: sticky; bottom: 0; z-index: 3;
1166
+ display: flex; align-items: center; gap: 12px;
1167
+ margin: 4px -24px 0; padding: 12px 24px;
1168
+ background: #fff; border-top: 1px solid #e2e8f0;
1169
+ border-radius: 0 0 16px 16px;
1170
+ }
1171
+ .foot .grow { flex: 1; }
1172
+ `, De = "lw-debug-reporter", sn = () => [];
1173
+ function xr(e) {
1174
+ sn = e;
1175
+ }
1176
+ var Mr = [{ tool: "rect", key: "toolRect" }, { tool: "arrow", key: "toolArrow" }, { tool: "highlight", key: "toolHighlight" }, { tool: "text", key: "toolText" }];
1177
+ function Sr() {
1178
+ return class extends HTMLElement {
1179
+ constructor() {
1180
+ super();
1181
+ de(this, "root");
1182
+ de(this, "stop", null);
1183
+ de(this, "annotator", null);
1184
+ de(this, "bundle", null);
1185
+ de(this, "busy", !1);
1186
+ this.root = this.attachShadow({ mode: "open" });
1187
+ }
1188
+ connectedCallback() {
1189
+ this.dataset.debugReporter = "true", this.stop = Lo((t) => void this.open(t));
1190
+ }
1191
+ disconnectedCallback() {
1192
+ var t;
1193
+ (t = this.stop) == null || t.call(this), this.stop = null, this.close();
1194
+ }
1195
+ async open(t) {
1196
+ if (this.busy) return;
1197
+ this.busy = !0;
1198
+ let o = lt(X().locale), n = await Wo();
1199
+ if (n.method === "cancelled") {
1200
+ this.close();
1201
+ return;
1202
+ }
1203
+ this.bundle = jo({ reason: t, note: "", screenshotDataUrl: n.dataUrl, screenshotMethod: n.method, erroredQueries: Er() }), this.renderForm(o);
1204
+ }
1205
+ close() {
1206
+ var t;
1207
+ (t = this.annotator) == null || t.destroy(), this.annotator = null, this.bundle = null, this.busy = !1, this.root.replaceChildren();
1208
+ }
1209
+ shell(t) {
1210
+ let o = document.createElement("style");
1211
+ o.textContent = kr;
1212
+ let n = document.createElement("div");
1213
+ n.className = "backdrop";
1214
+ let r = document.createElement("div");
1215
+ return r.className = "panel", r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "true"), r.setAttribute("aria-label", t.title), n.append(r), this.root.replaceChildren(o, n), r;
1216
+ }
1217
+ renderShell(t, o) {
1218
+ let n = this.shell(t), r = Y("div", "head");
1219
+ r.append(Y("h2", "", t.title)), n.append(r, Y("p", "status", o));
1220
+ }
1221
+ renderForm(t) {
1222
+ let o = this.bundle;
1223
+ if (!o) return;
1224
+ let n = this.shell(t), r = Y("div", "head"), a = me("✕", "icon");
1225
+ a.setAttribute("aria-label", t.close), a.addEventListener("click", () => this.close()), r.append(Y("h2", "", t.title), a);
1226
+ let l = document.createElement("input");
1227
+ l.type = "text", l.placeholder = t.summaryPlaceholder;
1228
+ let s = qe(t.summaryLabel, t.summaryRequired, !0), c = document.createElement("textarea");
1229
+ c.placeholder = t.detailPlaceholder;
1230
+ let g = Y("div", "meta");
1231
+ g.innerHTML = "";
1232
+ let { context: k } = o;
1233
+ for (let [R, x] of [[t.reporter, `${k.user.fullName ?? "—"} (${k.user.email ?? "—"})`], [t.page, k.route.href], [t.captured, `${o.network.length} network · ${o.console.length} console · ${o.actionTrail.length} actions`]]) {
1234
+ let M = document.createElement("div"), A = document.createElement("b");
1235
+ A.textContent = `${R}: `, M.append(A, document.createTextNode(x)), g.append(M);
1236
+ }
1237
+ let w = Y("p", "status", ""), S = me(t.submit, "primary");
1238
+ S.disabled = !0, l.addEventListener("input", () => {
1239
+ S.disabled = l.value.trim().length === 0;
1240
+ }), n.append(r, s, l, qe(t.detailLabel), c, g), o.screenshotDataUrl ? n.append(...this.screenshotSection(t, o.screenshotDataUrl)) : n.append(Y("p", "status", t.noScreenshot));
1241
+ let E = Y("div", "foot"), T = me(t.close);
1242
+ T.addEventListener("click", () => this.close()), E.append(T, w, Y("span", "grow"), S), n.append(E), S.addEventListener("click", async () => {
1243
+ var R;
1244
+ S.disabled = !0, w.dataset.tone = "", w.textContent = t.submitting;
1245
+ try {
1246
+ let x = await br(l.value.trim(), { ...o, note: c.value, screenshotDataUrl: (R = this.annotator) != null && R.hasShapes() ? this.annotator.toDataUrl() : o.screenshotDataUrl }), M = this.dispatchEvent(new CustomEvent("lw-report-submitted", { detail: x, bubbles: !0, composed: !0, cancelable: !0 }));
1247
+ this.close(), M && Ge(`${t.submitted} — #${x.number}`, "success");
1248
+ } catch (x) {
1249
+ let M = x instanceof Error ? x.message : t.failed;
1250
+ w.dataset.tone = "error", w.textContent = M, Ge(`${t.failed} — ${M}`, "error"), S.disabled = !1;
1251
+ }
1252
+ }), l.focus();
1253
+ }
1254
+ screenshotSection(t, o) {
1255
+ let n = qe(t.annotateHint), r = Y("div", "tools"), a = document.createElement("canvas"), l = Y("div", "shot");
1256
+ l.append(a);
1257
+ let s = [], c = (S) => {
1258
+ for (let E of s) E.setAttribute("aria-pressed", String(E === S));
1259
+ };
1260
+ for (let { tool: S, key: E } of Mr) {
1261
+ let T = me(t[E]);
1262
+ T.setAttribute("aria-pressed", "false"), T.addEventListener("click", () => {
1263
+ var x;
1264
+ let R = T.getAttribute("aria-pressed") === "true";
1265
+ c(R ? null : T), (x = this.annotator) == null || x.setTool(R ? null : S);
1266
+ }), s.push(T), r.append(T);
1267
+ }
1268
+ r.append(Y("span", "sep"));
1269
+ let g = me(t.deleteSelected);
1270
+ g.addEventListener("click", () => {
1271
+ var S;
1272
+ return (S = this.annotator) == null ? void 0 : S.deleteSelected();
1273
+ });
1274
+ let k = me(t.clearAll);
1275
+ k.addEventListener("click", () => {
1276
+ var S;
1277
+ (S = this.annotator) == null || S.clear(), c(null);
1278
+ }), r.append(g, k);
1279
+ let w = new Image();
1280
+ return w.onload = () => {
1281
+ a.width = w.naturalWidth, a.height = w.naturalHeight, this.annotator = ln(a, w, () => {
1282
+ var S;
1283
+ c(null), g.disabled = !((S = this.annotator) != null && S.hasSelection());
1284
+ });
1285
+ }, w.src = o, [n, r, Y("p", "status", t.annotateHelp), l];
1286
+ }
1287
+ };
1288
+ }
1289
+ function Er() {
1290
+ try {
1291
+ return sn();
1292
+ } catch {
1293
+ return [];
1294
+ }
1295
+ }
1296
+ function Y(e, t = "", o = "") {
1297
+ let n = document.createElement(e);
1298
+ return t && (n.className = t), o && (n.textContent = o), n;
1299
+ }
1300
+ function me(e, t = "") {
1301
+ let o = document.createElement("button");
1302
+ return o.type = "button", o.textContent = e, t && (o.className = t), o;
1303
+ }
1304
+ function qe(e, t = "", o = !1) {
1305
+ let n = document.createElement("label");
1306
+ if (n.append(document.createTextNode(e)), o) {
1307
+ let r = document.createElement("span");
1308
+ r.className = "req", r.textContent = " *", n.append(r);
1309
+ }
1310
+ if (t) {
1311
+ let r = document.createElement("span");
1312
+ r.className = "hint", r.textContent = ` ${t}`, n.append(r);
1313
+ }
1314
+ return n;
1315
+ }
1316
+ function Cr() {
1317
+ typeof window > "u" || customElements.get(De) || customElements.define(De, Sr());
1318
+ }
1319
+ var Nt = !1;
1320
+ function Ar(e = {}) {
1321
+ if (Nt || typeof window > "u") return;
1322
+ if (!Jt()) {
1323
+ console.error("[debug-capture] configureDebugCapture() must be called before install");
1324
+ return;
1325
+ }
1326
+ if (Nt = !0, Qo(), Co(), Mo(), No(), e.ui === !1) return;
1327
+ let t = lt(X().locale);
1328
+ To((o) => {
1329
+ Ge(o.message ?? t.crashed, "error", { label: t.crashAction, onClick: () => en(o) });
1330
+ }), Cr(), !document.querySelector(De) && document.body.append(document.createElement(De));
1331
+ }
1332
+ class un extends Error {
1333
+ constructor(o, n) {
1334
+ super(o);
1335
+ de(this, "status");
1336
+ this.status = n;
1337
+ }
1338
+ }
1339
+ class Ke extends Error {
1340
+ constructor() {
1341
+ super("[debug-capture] no reporter identity — configure `identity` to use the tickets panel");
1342
+ }
1343
+ }
1344
+ function cn() {
1345
+ return X().host.replace(/\/$/, "");
1346
+ }
1347
+ async function Lr() {
1348
+ let e = X().identity;
1349
+ if (!e) throw new Ke();
1350
+ let t = await e();
1351
+ if (!t) throw new Ke();
1352
+ return t;
1353
+ }
1354
+ async function le(e, t = {}) {
1355
+ let o = await Lr(), n = await fetch(`${cn()}/ingest/me${e}`, { ...t, headers: { "x-realm-key": X().realmKey, authorization: `Bearer ${o}`, ...t.body ? { "content-type": "application/json" } : {}, ...t.headers } });
1356
+ if (!n.ok) {
1357
+ let r = await n.json().then((a) => a.error).catch(() => null);
1358
+ throw new un(r ?? `Request failed (${n.status})`, n.status);
1359
+ }
1360
+ return await n.json();
1361
+ }
1362
+ async function Tr() {
1363
+ let { items: e } = await le("/tickets");
1364
+ return e;
1365
+ }
1366
+ function _r(e) {
1367
+ return le(`/tickets/${encodeURIComponent(e)}`);
1368
+ }
1369
+ function Rr(e) {
1370
+ return le(`/attachments/${encodeURIComponent(e)}`);
1371
+ }
1372
+ function Ir(e) {
1373
+ return le(`/tickets/${encodeURIComponent(e)}/history`);
1374
+ }
1375
+ function zr(e, t) {
1376
+ return le(`/tickets/${encodeURIComponent(e)}/messages`, { method: "POST", body: JSON.stringify({ body: t }) });
1377
+ }
1378
+ function Nr(e, t, o) {
1379
+ return le(`/tickets/${encodeURIComponent(e)}/messages/${encodeURIComponent(t)}`, { method: "PUT", body: JSON.stringify({ body: o }) });
1380
+ }
1381
+ function Pr(e, t) {
1382
+ return le(`/tickets/${encodeURIComponent(e)}/reopen`, { method: "POST", body: JSON.stringify({ note: (t == null ? void 0 : t.trim()) || void 0 }) });
1383
+ }
1384
+ function Ur(e, t, o) {
1385
+ return le(`/tickets/${encodeURIComponent(e)}/inline-image`, { method: "POST", body: JSON.stringify({ dataUri: t, filename: o }) });
1386
+ }
1387
+ var Re = null;
1388
+ function Dr() {
1389
+ if (!Re) {
1390
+ let e = encodeURIComponent(X().realmKey);
1391
+ Re = fetch(`${cn()}/ingest/config?key=${e}`).then((t) => {
1392
+ if (!t.ok) throw new un(`Config failed (${t.status})`, t.status);
1393
+ return t.json();
1394
+ }).catch((t) => {
1395
+ throw Re = null, t;
1396
+ });
1397
+ }
1398
+ return Re;
1399
+ }
1400
+ function it(e, t) {
1401
+ let o = (e ?? "").trim().toUpperCase().replace(/[^A-Z0-9]+/g, "");
1402
+ return o ? `${o}-${t}` : `#${t}`;
1403
+ }
1404
+ function He(e, t, o) {
1405
+ if (!e) return "—";
1406
+ let n = new Date(e);
1407
+ if (Number.isNaN(n.getTime())) return "—";
1408
+ try {
1409
+ return new Intl.DateTimeFormat(o === "en" ? "en-GB" : "th-TH-u-ca-buddhist", { dateStyle: "medium", timeStyle: "short", timeZone: t }).format(n);
1410
+ } catch {
1411
+ return n.toISOString().slice(0, 16).replace("T", " ");
1412
+ }
1413
+ }
1414
+ function Or(e, t) {
1415
+ let o = new Map(e.map((r) => [r.key, r])), n = e.map((r) => r.key);
1416
+ return { labelOf: (r) => {
1417
+ var a;
1418
+ return ((a = o.get(r)) == null ? void 0 : a.label) ?? r;
1419
+ }, columnOf: (r) => o.get(r), isAwaitingReply: (r) => {
1420
+ var a;
1421
+ return ((a = o.get(r)) == null ? void 0 : a.awaitingReply) === !0;
1422
+ }, isClosed: (r) => {
1423
+ var a;
1424
+ return ((a = o.get(r)) == null ? void 0 : a.bucket) === "closed";
1425
+ }, rankOf: (r) => {
1426
+ let a = n.indexOf(r);
1427
+ return a === -1 ? n.length : a;
1428
+ }, options: [{ value: "", label: t }, ...e.map((r) => ({ value: r.key, label: r.label }))] };
1429
+ }
1430
+ function dn(e) {
1431
+ return !!(e.resolutionNote && e.resolutionNote.trim());
1432
+ }
1433
+ function fn(e) {
1434
+ return e.agentReplyCount > 0;
1435
+ }
1436
+ function Pt(e) {
1437
+ return dn(e) ? 2 : fn(e) ? 1 : 0;
1438
+ }
1439
+ function Br(e, t, o, n) {
1440
+ let r = t.trim().toLowerCase();
1441
+ return r ? [it(o, e.number), String(e.number), e.title, e.category ?? "", n(e.status)].join(" ").toLowerCase().includes(r) : !0;
1442
+ }
1443
+ function Hr(e, t, o) {
1444
+ let n = e.direction === "asc" ? 1 : -1;
1445
+ return (r, a) => {
1446
+ let l = 0;
1447
+ switch (e.key) {
1448
+ case "number":
1449
+ l = r.number - a.number;
1450
+ break;
1451
+ case "title":
1452
+ l = (r.title ?? "").localeCompare(a.title ?? "", "th");
1453
+ break;
1454
+ case "module":
1455
+ l = (r.category ?? "").localeCompare(a.category ?? "", "th");
1456
+ break;
1457
+ case "status":
1458
+ l = t.rankOf(r.status) - t.rankOf(a.status);
1459
+ break;
1460
+ case "response":
1461
+ l = Pt(r) - Pt(a);
1462
+ break;
1463
+ case "createdAt":
1464
+ l = Date.parse(r.createdAt) - Date.parse(a.createdAt);
1465
+ break;
1466
+ case "updatedAt":
1467
+ l = Date.parse(r.updatedAt) - Date.parse(a.updatedAt);
1468
+ break;
1469
+ }
1470
+ return l !== 0 ? l * n : (r.number - a.number) * n;
1471
+ };
1472
+ }
1473
+ var hn = 10;
1474
+ function Fr(e, t, o = hn) {
1475
+ return e.slice((t - 1) * o, t * o);
1476
+ }
1477
+ function $r(e, t = hn) {
1478
+ return Math.max(1, Math.ceil(e / t));
1479
+ }
1480
+ var Ut = { blue: { fg: "#1c5cab", bg: "#e8f1fd" }, amber: { fg: "#92400e", bg: "#fef3c7" }, violet: { fg: "#4a3aa7", bg: "#ece9fb" }, emerald: { fg: "#0f766e", bg: "#d9f2ec" }, gray: { fg: "#4b5563", bg: "#f1f2f4" }, red: { fg: "#b91c1c", bg: "#fde8e8" }, sky: { fg: "#0369a1", bg: "#e0f2fe" }, rose: { fg: "#be123c", bg: "#ffe4e9" }, teal: { fg: "#0f766e", bg: "#d7f2ef" }, orange: { fg: "#c2410c", bg: "#ffedd5" } };
1481
+ function Qr(e) {
1482
+ return Ut[e ?? ""] ?? Ut.gray;
1483
+ }
1484
+ var Vr = /* @__PURE__ */ new Set(["p", "br", "strong", "b", "em", "i", "u", "s", "code", "pre", "ul", "ol", "li", "blockquote", "h1", "h2", "h3", "a", "img", "span"]), qr = /* @__PURE__ */ new Set(["href", "target", "rel", "src", "alt", "title"]), Jr = /^\/api\/inline\/[a-f0-9]{64}$/i;
1485
+ function Zr(e) {
1486
+ return /^(?:https?:\/\/|mailto:|#|\/)/i.test(e.trim());
1487
+ }
1488
+ function Yr(e, t) {
1489
+ try {
1490
+ let o = new URL(e.trim(), t);
1491
+ return o.origin === new URL(t).origin && Jr.test(o.pathname);
1492
+ } catch {
1493
+ return !1;
1494
+ }
1495
+ }
1496
+ function Xr(e) {
1497
+ return /<[a-z/][^>]*>/i.test(e);
1498
+ }
1499
+ function pn(e, t, o) {
1500
+ if (e.textContent = "", !Xr(t)) {
1501
+ for (let [r, a] of t.split(`
1502
+ `).entries())
1503
+ r && e.append(document.createElement("br")), e.append(document.createTextNode(a));
1504
+ return;
1505
+ }
1506
+ let n = new DOMParser().parseFromString(t, "text/html");
1507
+ for (let r of Array.from(n.body.childNodes)) {
1508
+ let a = mn(r, o);
1509
+ a && e.append(a);
1510
+ }
1511
+ }
1512
+ var Gr = /* @__PURE__ */ new Set(["script", "style", "iframe", "object", "embed", "noscript", "template", "svg", "math"]);
1513
+ function mn(e, t) {
1514
+ if (e.nodeType === 3) return document.createTextNode(e.nodeValue ?? "");
1515
+ if (e.nodeType !== 1) return null;
1516
+ let o = e, n = o.tagName.toLowerCase();
1517
+ if (Gr.has(n)) return null;
1518
+ let r = Vr.has(n), a = r ? document.createElement(n) : document.createDocumentFragment();
1519
+ if (r) {
1520
+ let l = a;
1521
+ for (let s of Array.from(o.attributes)) {
1522
+ let c = s.name.toLowerCase();
1523
+ if (qr.has(c) && !(c === "href" && !Zr(s.value))) {
1524
+ if (c === "src") {
1525
+ if (n !== "img" || !Yr(s.value, t)) continue;
1526
+ l.setAttribute("src", ea(s.value, t));
1527
+ continue;
1528
+ }
1529
+ l.setAttribute(c, s.value);
1530
+ }
1531
+ }
1532
+ if (n === "a" && (l.setAttribute("target", "_blank"), l.setAttribute("rel", "noopener noreferrer nofollow")), n === "img" && !l.getAttribute("src")) return null;
1533
+ }
1534
+ for (let l of Array.from(o.childNodes)) {
1535
+ let s = mn(l, t);
1536
+ s && a.append(s);
1537
+ }
1538
+ return a;
1539
+ }
1540
+ function Kr(e, t) {
1541
+ let o = document.createElement("div");
1542
+ pn(o, e, t);
1543
+ let n = jr(t);
1544
+ if (n) for (let r of Array.from(o.querySelectorAll("img"))) {
1545
+ let a = r.getAttribute("src") ?? "";
1546
+ a.startsWith(`${n}/`) && r.setAttribute("src", a.slice(n.length));
1547
+ }
1548
+ return o.innerHTML;
1549
+ }
1550
+ function jr(e) {
1551
+ try {
1552
+ return new URL(e).origin;
1553
+ } catch {
1554
+ return null;
1555
+ }
1556
+ }
1557
+ function Wr(e) {
1558
+ return e ? /<img\b/i.test(e) ? !1 : e.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").trim() === "" : !0;
1559
+ }
1560
+ function ea(e, t) {
1561
+ let o = e.trim();
1562
+ return o.startsWith("/") ? `${t.replace(/\/$/, "")}${o}` : o;
1563
+ }
1564
+ var ta = ["bold", "italic", "underline", "bulletList", "orderedList", "link", "image"], na = { title: "ปัญหาที่แจ้ง", intro: "ปัญหาที่คุณแจ้งไว้ พร้อมสถานะล่าสุด", searchPlaceholder: "ค้นหาเลขที่/หัวข้อ/โมดูล", searchLabel: "ค้นหาปัญหาที่แจ้ง", allStatuses: "ทุกสถานะ", count: (e) => `${e} รายการ`, colNumber: "เลขที่", colTitle: "หัวข้อ", colModule: "โมดูล", colStatus: "สถานะ", colResponse: "คำตอบจากทีม", colCreated: "แจ้งเมื่อ", colUpdated: "อัปเดตล่าสุด", awaitingReply: "รอคุณตอบกลับ", hasSolution: "มีวิธีแก้ไข", hasReply: "ตอบกลับแล้ว", noReply: "ยังไม่มีการตอบกลับ", empty: "คุณยังไม่ได้แจ้งปัญหา", emptyFiltered: "ไม่พบรายการที่ตรงกับการค้นหา", loading: "กำลังโหลด…", listFailed: "โหลดรายการไม่สำเร็จ", detailFailed: "โหลดรายงานไม่สำเร็จ", signedOut: "กรุณาเข้าสู่ระบบเพื่อดูปัญหาที่แจ้งไว้", back: "กลับไปรายการ", reportedBy: "แจ้งเมื่อ", conversation: "การสนทนา", resolution: "วิธีแก้ไข", noMessages: "ยังไม่มีข้อความ", you: "คุณ", team: "ทีมงาน", reporterRole: "ผู้แจ้ง", edited: "แก้ไขแล้ว", edit: "แก้ไข", saveEdit: "บันทึกการแก้ไข", cancel: "ยกเลิก", replyPlaceholder: "พิมพ์ข้อความถึงทีมงาน", bold: "ตัวหนา", italic: "ตัวเอียง", underline: "ขีดเส้นใต้", strike: "ขีดฆ่า", code: "โค้ด", blockquote: "ยกคำพูด", bulletList: "รายการหัวข้อ", orderedList: "รายการตัวเลข", link: "ลิงก์", linkPrompt: "ใส่ลิงก์", linkNeedsSelection: "เลือกข้อความที่ต้องการทำลิงก์ก่อน", linkInvalid: "ลิงก์ต้องขึ้นต้นด้วย http:// หรือ https://", attachImage: "แนบรูป", uploading: "กำลังอัปโหลดรูป…", send: "ส่งข้อความ", sending: "กำลังส่ง…", sent: "ส่งข้อความแล้ว", sendFailed: "ส่งไม่สำเร็จ ลองใหม่อีกครั้ง", reopen: "ยังมีปัญหา", reopenHint: "ถ้าปัญหายังไม่หาย แจ้งทีมงานอีกครั้งได้", reopening: "กำลังแจ้ง…", reopened: "แจ้งทีมงานอีกครั้งแล้ว — เรากำลังดูให้ครับ", reopenFailed: "เปิดเรื่องไม่สำเร็จ ลองใหม่อีกครั้ง", close: "ปิด", retry: "ลองใหม่", page: "หน้า", of: (e, t) => `หน้า ${e} จาก ${t}`, prev: "ก่อนหน้า", next: "ถัดไป" }, oa = { title: "My reports", intro: "The problems you have reported, with their latest status", searchPlaceholder: "Search number / title / module", searchLabel: "Search my reports", allStatuses: "All statuses", count: (e) => `${e} item${e === 1 ? "" : "s"}`, colNumber: "No.", colTitle: "Title", colModule: "Module", colStatus: "Status", colResponse: "Team response", colCreated: "Reported", colUpdated: "Last update", awaitingReply: "Awaiting your reply", hasSolution: "Solution provided", hasReply: "Replied", noReply: "No reply yet", empty: "You have not reported anything yet", emptyFiltered: "Nothing matches that search", loading: "Loading…", listFailed: "Could not load your reports", detailFailed: "Could not load this report", signedOut: "Sign in to see the problems you have reported", back: "Back to the list", reportedBy: "Reported", conversation: "Conversation", resolution: "Solution", noMessages: "No messages yet", you: "You", team: "Support", reporterRole: "Reporter", edited: "edited", edit: "Edit", saveEdit: "Save changes", cancel: "Cancel", replyPlaceholder: "Write a message to the team", bold: "Bold", italic: "Italic", underline: "Underline", strike: "Strikethrough", code: "Code", blockquote: "Quote", bulletList: "Bulleted list", orderedList: "Numbered list", link: "Link", linkPrompt: "Enter a link", linkNeedsSelection: "Select the text you want to link first", linkInvalid: "A link must start with http:// or https://", attachImage: "Add an image", uploading: "Uploading the image…", send: "Send", sending: "Sending…", sent: "Message sent", sendFailed: "Could not send — try again", reopen: "Still a problem", reopenHint: "If the problem is not fixed, tell the team again", reopening: "Sending…", reopened: "The team has been notified — we are looking at it", reopenFailed: "Could not reopen — try again", close: "Close", retry: "Try again", page: "Page", of: (e, t) => `Page ${e} of ${t}`, prev: "Previous", next: "Next" };
1565
+ function ra(e) {
1566
+ return e === "en" ? oa : na;
1567
+ }
1568
+ const aa = { style: { display: "none" } }, Bi = /* @__PURE__ */ J({
1569
+ __name: "DebugCaptureInit",
1570
+ props: {
1571
+ ui: { type: Boolean, default: !0 },
1572
+ errorQueries: {},
1573
+ config: {}
1574
+ },
1575
+ setup(e) {
1576
+ const t = e;
1577
+ return t.config && !Jt() && Tn(t.config), Oe(() => {
1578
+ t.errorQueries && xr(t.errorQueries), Ar({ ui: t.ui });
1579
+ }), (o, n) => (m(), v("span", aa));
1580
+ }
1581
+ }), la = () => be(
1582
+ "svg",
1583
+ {
1584
+ width: 20,
1585
+ height: 20,
1586
+ viewBox: "0 0 24 24",
1587
+ fill: "none",
1588
+ stroke: "currentColor",
1589
+ "stroke-width": 1.8,
1590
+ "stroke-linecap": "round",
1591
+ "stroke-linejoin": "round",
1592
+ "aria-hidden": "true"
1593
+ },
1594
+ [
1595
+ be("path", { d: "M8 2l1.9 1.9M16 2l-1.9 1.9" }),
1596
+ be("rect", { x: 8, y: 6, width: 8, height: 14, rx: 4 }),
1597
+ be("path", { d: "M3 13h5M16 13h5M4 8l3 2M20 8l-3 2M4 18l3-2M20 18l-3-2" })
1598
+ ]
1599
+ ), ia = ["aria-label", "title"], Hi = /* @__PURE__ */ J({
1600
+ __name: "ReportProblemButton",
1601
+ props: {
1602
+ label: { default: "รายงานปัญหา" }
1603
+ },
1604
+ setup(e) {
1605
+ function t(o) {
1606
+ o.defaultPrevented || en({ type: "manual" });
1607
+ }
1608
+ return (o, n) => (m(), v("button", {
1609
+ type: "button",
1610
+ "aria-label": e.label,
1611
+ title: e.label,
1612
+ onClick: t
1613
+ }, [
1614
+ Ft(o.$slots, "default", {}, () => [
1615
+ O(P(la))
1616
+ ])
1617
+ ], 8, ia));
1618
+ }
1619
+ }), sa = /* @__PURE__ */ J({
1620
+ __name: "StatusPill",
1621
+ props: {
1622
+ label: {},
1623
+ tone: {}
1624
+ },
1625
+ setup(e) {
1626
+ return (t, o) => (m(), v("span", {
1627
+ class: "lw-status",
1628
+ style: xe({ background: e.tone.bg, color: e.tone.fg })
1629
+ }, y(e.label), 5));
1630
+ }
1631
+ });
1632
+ function U(e, t = {}) {
1633
+ return () => be(
1634
+ "svg",
1635
+ {
1636
+ width: 15,
1637
+ height: 15,
1638
+ viewBox: "0 0 24 24",
1639
+ fill: "none",
1640
+ stroke: "currentColor",
1641
+ "stroke-width": 2,
1642
+ "stroke-linecap": "round",
1643
+ "stroke-linejoin": "round",
1644
+ "aria-hidden": "true",
1645
+ ...t
1646
+ },
1647
+ e.map((n) => be("path", { d: n }))
1648
+ );
1649
+ }
1650
+ const ua = U(["M6 4h8a4 4 0 0 1 0 8H6z", "M6 12h9a4 4 0 0 1 0 8H6z"]), ca = U(["M19 4h-9", "M14 20H5", "M15 4L9 20"]), da = U(["M6 4v6a6 6 0 0 0 12 0V4", "M4 20h16"]), fa = U([
1651
+ "M8 6h13",
1652
+ "M8 12h13",
1653
+ "M8 18h13",
1654
+ "M3 6h.01",
1655
+ "M3 12h.01",
1656
+ "M3 18h.01"
1657
+ ]), ha = U([
1658
+ "M10 6h11",
1659
+ "M10 12h11",
1660
+ "M10 18h11",
1661
+ "M4 6h1v4",
1662
+ "M4 10h2",
1663
+ "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"
1664
+ ]), pa = U([
1665
+ "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",
1666
+ "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"
1667
+ ]), Dt = U([
1668
+ "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z",
1669
+ "M8.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z",
1670
+ "M21 15l-5-5L5 21"
1671
+ ]), ma = U(["M22 2L11 13", "M22 2l-7 20-4-9-9-4 20-7z"]), ga = U(["M21 21l-4.34-4.34", "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"]), ba = U(["M19 12H5", "M12 19l-7-7 7-7"]), ya = U(["M20 6L9 17l-5-5"]), je = U(["M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"]), We = U(["M3 12a9 9 0 1 0 3-6.7L3 8", "M3 3v5h5"]), va = U(["M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z", "M12 8v4", "M12 16h.01"]), wa = U([
1672
+ "M22 12h-6l-2 3h-4l-2-3H2",
1673
+ "M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"
1674
+ ]), ka = U(["M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z", "M12 6v6l4 2"]), Ot = U(["M22 11.08V12a10 10 0 1 1-5.93-9.14", "M22 4L12 14.01l-3-3"]), xa = U(["M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z", "M4.93 4.93l14.14 14.14"]), Ma = U([
1675
+ "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
1676
+ ]), Sa = U(["M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z"], { width: 14, height: 14 }), Ea = U(["M7 17L17 7", "M7 7h10v10"], { width: 14, height: 14 }), Ca = U([
1677
+ "M9 11l-6 6v3h9l3-3",
1678
+ "M22 12l-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4"
1679
+ ], { width: 14, height: 14 }), Aa = U(["M4 7V4h16v3", "M9 20h6", "M12 4v16"], { width: 14, height: 14 }), La = U([
1680
+ "M3 6h18",
1681
+ "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
1682
+ ], { width: 14, height: 14 }), Ta = U(["M16 4H9a3 3 0 0 0-2.83 4", "M14 12a4 4 0 0 1 0 8H6", "M4 12h16"]), _a = U(["M16 18l6-6-6-6", "M8 6l-6 6 6 6"]), Ra = U([
1683
+ "M3 21c3 0 7-1 7-8V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h3",
1684
+ "M14 21c3 0 7-1 7-8V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h3"
1685
+ ]), Ia = U([
1686
+ "M12 20h9",
1687
+ "M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"
1688
+ ], { width: 11, height: 11 }), za = U(["M20 6L9 17l-5-5"], { width: 12, height: 12 }), Na = U(["M18 6L6 18", "M6 6l12 12"], { width: 12, height: 12 }), Pa = { class: "lw-tablewrap" }, Ua = { class: "lw-table" }, Da = ["aria-sort", "onClick"], Oa = { class: "lw-arrow" }, Ba = { key: 0 }, Ha = ["colspan"], Fa = ["onClick", "onKeydown"], $a = { class: "lw-num" }, Qa = { class: "lw-title" }, Va = {
1689
+ key: 0,
1690
+ class: "lw-chip"
1691
+ }, qa = {
1692
+ key: 1,
1693
+ class: "lw-dash"
1694
+ }, Ja = {
1695
+ key: 0,
1696
+ class: "lw-pill lw-pill--awaiting"
1697
+ }, Za = {
1698
+ key: 0,
1699
+ class: "lw-pill lw-pill--solution"
1700
+ }, Ya = {
1701
+ key: 1,
1702
+ class: "lw-pill lw-pill--replied"
1703
+ }, Xa = {
1704
+ key: 2,
1705
+ class: "lw-muted"
1706
+ }, Ga = { class: "lw-dim" }, Ka = { class: "lw-dim" }, ja = {
1707
+ key: 0,
1708
+ class: "lw-pager"
1709
+ }, Wa = ["disabled"], el = ["disabled"], tl = /* @__PURE__ */ J({
1710
+ __name: "TicketTable",
1711
+ props: {
1712
+ items: {},
1713
+ maps: {},
1714
+ t: {},
1715
+ slug: {},
1716
+ timezone: {},
1717
+ locale: {},
1718
+ keyword: {},
1719
+ statusFilter: {},
1720
+ sort: {},
1721
+ page: {}
1722
+ },
1723
+ emits: ["open", "sort", "page"],
1724
+ setup(e, { expose: t, emit: o }) {
1725
+ const n = e, r = o, a = [
1726
+ { key: "number", label: "colNumber", width: "120px" },
1727
+ { key: "title", label: "colTitle" },
1728
+ { key: "module", label: "colModule", width: "160px" },
1729
+ { key: "status", label: "colStatus", width: "130px" },
1730
+ { key: "response", label: "colResponse", width: "150px" },
1731
+ { key: "createdAt", label: "colCreated", width: "170px" },
1732
+ { key: "updatedAt", label: "colUpdated", width: "170px" }
1733
+ ], l = F(
1734
+ () => n.items.filter((w) => n.statusFilter ? w.status === n.statusFilter : !0).filter((w) => Br(w, n.keyword, n.slug, n.maps.labelOf)).sort(Hr(n.sort, n.maps, n.slug))
1735
+ ), s = F(() => $r(l.value.length)), c = F(() => Math.min(n.page, s.value)), g = F(() => Fr(l.value, c.value));
1736
+ t({ count: F(() => l.value.length) });
1737
+ function k(w) {
1738
+ return He(w, n.timezone, n.locale);
1739
+ }
1740
+ return (w, S) => (m(), v(q, null, [
1741
+ f("div", Pa, [
1742
+ f("table", Ua, [
1743
+ f("thead", null, [
1744
+ f("tr", null, [
1745
+ (m(), v(q, null, ae(a, (E) => f("th", {
1746
+ key: E.key,
1747
+ scope: "col",
1748
+ class: "lw-th",
1749
+ style: xe(E.width ? { width: E.width } : void 0),
1750
+ "aria-sort": e.sort.key === E.key ? e.sort.direction === "asc" ? "ascending" : "descending" : void 0,
1751
+ onClick: (T) => r("sort", E.key)
1752
+ }, [
1753
+ V(y(e.t[E.label]) + " ", 1),
1754
+ f("span", Oa, y(e.sort.key === E.key ? e.sort.direction === "asc" ? "▲" : "▼" : "⇅"), 1)
1755
+ ], 12, Da)), 64))
1756
+ ])
1757
+ ]),
1758
+ f("tbody", null, [
1759
+ g.value.length ? B("", !0) : (m(), v("tr", Ba, [
1760
+ f("td", {
1761
+ colspan: a.length,
1762
+ class: "lw-empty"
1763
+ }, y(e.items.length === 0 ? e.t.empty : e.t.emptyFiltered), 9, Ha)
1764
+ ])),
1765
+ (m(!0), v(q, null, ae(g.value, (E) => {
1766
+ var T;
1767
+ return m(), v("tr", {
1768
+ key: E.id,
1769
+ class: "lw-row",
1770
+ tabindex: "0",
1771
+ onClick: (R) => r("open", E.id),
1772
+ onKeydown: vn($t((R) => r("open", E.id), ["prevent"]), ["enter", "space"])
1773
+ }, [
1774
+ f("td", $a, y(P(it)(e.slug, E.number)), 1),
1775
+ f("td", Qa, y(E.title), 1),
1776
+ f("td", null, [
1777
+ E.category ? (m(), v("span", Va, y(E.category), 1)) : (m(), v("span", qa, "—"))
1778
+ ]),
1779
+ f("td", null, [
1780
+ e.maps.isAwaitingReply(E.status) ? (m(), v("span", Ja, [
1781
+ O(P(je)),
1782
+ V(" " + y(e.t.awaitingReply), 1)
1783
+ ])) : (m(), G(sa, {
1784
+ key: 1,
1785
+ label: e.maps.labelOf(E.status),
1786
+ tone: P(Qr)((T = e.maps.columnOf(E.status)) == null ? void 0 : T.color)
1787
+ }, null, 8, ["label", "tone"]))
1788
+ ]),
1789
+ f("td", null, [
1790
+ P(dn)(E) ? (m(), v("span", Za, [
1791
+ O(P(ya)),
1792
+ V(" " + y(e.t.hasSolution), 1)
1793
+ ])) : P(fn)(E) ? (m(), v("span", Ya, [
1794
+ O(P(je)),
1795
+ V(" " + y(e.t.hasReply), 1)
1796
+ ])) : (m(), v("span", Xa, y(e.t.noReply), 1))
1797
+ ]),
1798
+ f("td", Ga, y(k(E.createdAt)), 1),
1799
+ f("td", Ka, y(k(E.updatedAt)), 1)
1800
+ ], 40, Fa);
1801
+ }), 128))
1802
+ ])
1803
+ ])
1804
+ ]),
1805
+ l.value.length > g.value.length || c.value > 1 ? (m(), v("div", ja, [
1806
+ f("span", null, y(e.t.of(c.value, s.value)), 1),
1807
+ f("button", {
1808
+ type: "button",
1809
+ class: "lw-btn",
1810
+ disabled: c.value <= 1,
1811
+ onClick: S[0] || (S[0] = (E) => r("page", c.value - 1))
1812
+ }, y(e.t.prev), 9, Wa),
1813
+ f("button", {
1814
+ type: "button",
1815
+ class: "lw-btn",
1816
+ disabled: c.value >= s.value,
1817
+ onClick: S[1] || (S[1] = (E) => r("page", c.value + 1))
1818
+ }, y(e.t.next), 9, el)
1819
+ ])) : B("", !0)
1820
+ ], 64));
1821
+ }
1822
+ }), nl = ["src"], st = /* @__PURE__ */ J({
1823
+ __name: "TicketBody",
1824
+ props: {
1825
+ html: {},
1826
+ host: {}
1827
+ },
1828
+ setup(e) {
1829
+ const t = e, o = N(null), n = N(null);
1830
+ function r(l) {
1831
+ const s = l.target;
1832
+ if (!s || s.tagName !== "IMG") return;
1833
+ const c = s.getAttribute("src");
1834
+ c && (n.value = c);
1835
+ }
1836
+ function a() {
1837
+ o.value && pn(o.value, t.html, t.host);
1838
+ }
1839
+ return Oe(a), re(() => [t.html, t.host], a), (l, s) => (m(), v(q, null, [
1840
+ f("div", {
1841
+ ref_key: "target",
1842
+ ref: o,
1843
+ class: "lw-body",
1844
+ onClick: r
1845
+ }, null, 512),
1846
+ n.value ? (m(), v("div", {
1847
+ key: 0,
1848
+ class: "lw-zoom",
1849
+ role: "dialog",
1850
+ "aria-modal": "true",
1851
+ onClick: s[0] || (s[0] = (c) => n.value = null)
1852
+ }, [
1853
+ s[1] || (s[1] = f("button", {
1854
+ type: "button",
1855
+ class: "lw-zoom__close",
1856
+ "aria-label": "close"
1857
+ }, "✕", -1)),
1858
+ f("img", {
1859
+ src: n.value,
1860
+ alt: ""
1861
+ }, null, 8, nl)
1862
+ ])) : B("", !0)
1863
+ ], 64));
1864
+ }
1865
+ }), ol = { class: "lw-hero__body" }, rl = { class: "lw-hero__kicker" }, al = {
1866
+ key: 0,
1867
+ class: "lw-hero__nudge"
1868
+ }, ll = {
1869
+ key: 1,
1870
+ class: "lw-hero__note"
1871
+ }, il = /* @__PURE__ */ J({
1872
+ __name: "StatusHero",
1873
+ props: {
1874
+ ticket: {},
1875
+ maps: {},
1876
+ t: {},
1877
+ locale: {},
1878
+ host: {}
1879
+ },
1880
+ setup(e) {
1881
+ const t = e, o = {
1882
+ OPEN: { icon: wa, border: "#bfdbfe", bg: "#eff6ff", fg: "#1e3a8a", accent: "#3b82f6" },
1883
+ IN_PROGRESS: { icon: ka, border: "#fde68a", bg: "#fffbeb", fg: "#78350f", accent: "#f59e0b" },
1884
+ RESOLVED: { icon: Ot, border: "#a7f3d0", bg: "#ecfdf5", fg: "#064e3b", accent: "#10b981" },
1885
+ CLOSED: { icon: Ot, border: "#e5e7eb", bg: "#f9fafb", fg: "#1f2937", accent: "#9ca3af" },
1886
+ WONT_FIX: { icon: xa, border: "#e5e7eb", bg: "#f9fafb", fg: "#374151", accent: "#9ca3af" }
1887
+ }, n = { icon: je, border: "#fcd34d", bg: "#fffbeb", fg: "#78350f", accent: "#f59e0b" }, r = {
1888
+ OPEN: { th: "รับเรื่องแล้ว — รอทีมงานตรวจสอบ", en: "Received — waiting for the team to look" },
1889
+ IN_PROGRESS: { th: "ทีมงานกำลังดำเนินการแก้ไข", en: "The team is working on it" },
1890
+ RESOLVED: { th: "แก้ไขเรียบร้อยแล้ว", en: "Fixed" },
1891
+ CLOSED: { th: "ปิดเรื่องแล้ว", en: "Closed" },
1892
+ WONT_FIX: { th: "พิจารณาแล้ว — ยังไม่ได้ดำเนินการในขณะนี้", en: "Reviewed — not being worked on for now" }
1893
+ }, a = F(() => t.maps.isAwaitingReply(t.ticket.status)), l = F(() => a.value ? n : o[t.ticket.status] ?? o.OPEN), s = F(() => {
1894
+ var k, w, S;
1895
+ return a.value ? t.locale === "en" ? "The team needs more information from you" : "ทีมงานขอข้อมูลเพิ่มเติม — รอการตอบกลับจากคุณ" : ((w = (k = t.maps.columnOf(t.ticket.status)) == null ? void 0 : k.description) == null ? void 0 : w.trim()) || ((S = r[t.ticket.status]) == null ? void 0 : S[t.locale]) || t.maps.labelOf(t.ticket.status);
1896
+ }), c = F(
1897
+ () => {
1898
+ var g;
1899
+ return !a.value && !t.ticket.messages.some((k) => k.authorRole === "AGENT") && t.maps.isClosed(t.ticket.status) && !!((g = t.ticket.resolutionNote) != null && g.trim());
1900
+ }
1901
+ );
1902
+ return (g, k) => (m(), v("section", {
1903
+ class: "lw-hero",
1904
+ style: xe({ borderColor: l.value.border, background: l.value.bg })
1905
+ }, [
1906
+ (m(), G(et(l.value.icon), {
1907
+ class: "lw-hero__icon",
1908
+ style: xe({ color: l.value.accent })
1909
+ }, null, 8, ["style"])),
1910
+ f("div", ol, [
1911
+ f("p", rl, y(a.value ? e.locale === "en" ? "AWAITING YOUR REPLY" : "รอการตอบกลับจากคุณ" : e.locale === "en" ? "LATEST STATUS" : "สถานะล่าสุด"), 1),
1912
+ f("p", {
1913
+ class: "lw-hero__headline",
1914
+ style: xe({ color: l.value.fg })
1915
+ }, y(s.value), 5),
1916
+ a.value ? (m(), v("p", al, y(e.locale === "en" ? "Please reply to the team in the conversation below" : "กรุณาตอบกลับให้ทีมงานในช่องแชทด้านล่าง"), 1)) : B("", !0),
1917
+ c.value ? (m(), v("div", ll, [
1918
+ O(P(Ma), { class: "lw-hero__wrench" }),
1919
+ O(st, {
1920
+ html: e.ticket.resolutionNote ?? "",
1921
+ host: e.host
1922
+ }, null, 8, ["html", "host"])
1923
+ ])) : B("", !0)
1924
+ ])
1925
+ ], 4));
1926
+ }
1927
+ }), sl = { class: "lw-reopen" }, ul = {
1928
+ key: 0,
1929
+ class: "lw-reopen__row"
1930
+ }, cl = { class: "lw-reopen__hint" }, dl = { key: 1 }, fl = { class: "lw-reopen__title" }, hl = ["placeholder"], pl = { class: "lw-reopen__actions" }, ml = ["disabled"], gl = /* @__PURE__ */ J({
1931
+ __name: "ReopenPanel",
1932
+ props: {
1933
+ t: {},
1934
+ locale: {},
1935
+ busy: { type: Boolean }
1936
+ },
1937
+ emits: ["reopen"],
1938
+ setup(e, { emit: t }) {
1939
+ const o = t, n = N(!1), r = N("");
1940
+ function a() {
1941
+ o("reopen", r.value.trim());
1942
+ }
1943
+ return (l, s) => (m(), v("section", sl, [
1944
+ n.value ? (m(), v("div", dl, [
1945
+ f("p", fl, y(e.t.reopen), 1),
1946
+ Je(f("textarea", {
1947
+ "onUpdate:modelValue": s[1] || (s[1] = (c) => r.value = c),
1948
+ rows: "2",
1949
+ class: "lw-reopen__note",
1950
+ placeholder: e.locale === "en" ? "Tell us what is still happening (optional)…" : "บอกเราหน่อยว่ายังพบปัญหาอะไร (ไม่ระบุก็ได้)…"
1951
+ }, null, 8, hl), [
1952
+ [Qt, r.value]
1953
+ ]),
1954
+ f("div", pl, [
1955
+ f("button", {
1956
+ type: "button",
1957
+ class: "lw-reopen__cancel",
1958
+ onClick: s[2] || (s[2] = (c) => {
1959
+ n.value = !1, r.value = "";
1960
+ })
1961
+ }, y(e.locale === "en" ? "Cancel" : "ยกเลิก"), 1),
1962
+ f("button", {
1963
+ type: "button",
1964
+ class: "lw-reopen__confirm",
1965
+ disabled: e.busy,
1966
+ onClick: a
1967
+ }, [
1968
+ O(P(We)),
1969
+ V(" " + y(e.busy ? e.t.reopening : e.t.reopen), 1)
1970
+ ], 8, ml)
1971
+ ])
1972
+ ])) : (m(), v("div", ul, [
1973
+ f("span", cl, y(e.locale === "en" ? "Problem not fixed?" : "ปัญหายังไม่หาย?"), 1),
1974
+ f("button", {
1975
+ type: "button",
1976
+ class: "lw-reopen__open",
1977
+ onClick: s[0] || (s[0] = (c) => n.value = !0)
1978
+ }, [
1979
+ O(P(We)),
1980
+ V(" " + y(e.t.reopen), 1)
1981
+ ])
1982
+ ]))
1983
+ ]));
1984
+ }
1985
+ }), bl = { class: "lw-timeline" }, yl = { class: "lw-rail" }, vl = {
1986
+ key: 0,
1987
+ class: "lw-pip"
1988
+ }, wl = { class: "lw-node__time" }, kl = /* @__PURE__ */ J({
1989
+ __name: "TicketTimeline",
1990
+ props: {
1991
+ history: {},
1992
+ status: {},
1993
+ createdAt: {},
1994
+ maps: {},
1995
+ timezone: {},
1996
+ locale: {}
1997
+ },
1998
+ setup(e) {
1999
+ const t = e, o = ["OPEN", "IN_PROGRESS", "RESOLVED", "CLOSED"], n = F(() => {
2000
+ const r = t.history.length ? t.history.map((c) => ({ status: c.toStatus, at: c.createdAt })) : (
2001
+ // A row from before history was recorded still gets one node rather than
2002
+ // an empty section.
2003
+ [{ status: "OPEN", at: t.createdAt }]
2004
+ ), a = r.map((c, g) => {
2005
+ const k = r[g - 1];
2006
+ return {
2007
+ label: g === 0 ? t.locale === "en" ? "Reported" : "รายงานปัญหา" : t.maps.labelOf(c.status),
2008
+ time: He(c.at, t.timezone, t.locale),
2009
+ state: g === r.length - 1 ? "current" : "done",
2010
+ reopened: !!(k && t.maps.isClosed(k.status) && !t.maps.isClosed(c.status))
2011
+ };
2012
+ }), l = o.indexOf(t.status), s = t.maps.isClosed(t.status) || l < 0 ? [] : o.slice(l + 1);
2013
+ for (const c of s)
2014
+ a.push({
2015
+ label: t.maps.labelOf(c),
2016
+ time: t.locale === "en" ? "Pending" : "รอดำเนินการ",
2017
+ state: "pending",
2018
+ reopened: !1
2019
+ });
2020
+ return a;
2021
+ });
2022
+ return (r, a) => (m(), v("ol", bl, [
2023
+ (m(!0), v(q, null, ae(n.value, (l, s) => (m(), v("li", {
2024
+ key: `${l.label}-${s}`,
2025
+ class: "lw-node"
2026
+ }, [
2027
+ f("div", yl, [
2028
+ s < n.value.length - 1 ? (m(), v("span", {
2029
+ key: 0,
2030
+ class: fe(["lw-line", { "lw-line--pending": l.state === "pending" }])
2031
+ }, null, 2)) : B("", !0),
2032
+ f("span", {
2033
+ class: fe(["lw-dot", [`lw-dot--${l.state}`, { "lw-dot--reopened": l.reopened }]])
2034
+ }, [
2035
+ l.state === "current" && !l.reopened ? (m(), v("span", vl)) : B("", !0)
2036
+ ], 2)
2037
+ ]),
2038
+ f("div", {
2039
+ class: fe(["lw-node__text", { "lw-node__text--last": s === n.value.length - 1 }])
2040
+ }, [
2041
+ f("div", {
2042
+ class: fe(["lw-node__label", [`lw-node__label--${l.state}`, { "lw-node__label--reopened": l.reopened }]])
2043
+ }, [
2044
+ l.reopened ? (m(), G(P(We), {
2045
+ key: 0,
2046
+ class: "lw-node__icon"
2047
+ })) : B("", !0),
2048
+ V(" " + y(l.reopened ? `${e.locale === "en" ? "Reopened" : "เปิดใหม่"} · ${l.label}` : l.label), 1)
2049
+ ], 2),
2050
+ f("div", wl, y(l.time), 1)
2051
+ ], 2)
2052
+ ]))), 128))
2053
+ ]));
2054
+ }
2055
+ }), xl = ["title", "aria-label", "aria-pressed", "disabled"], Bt = /* @__PURE__ */ J({
2056
+ __name: "ToolbarButton",
2057
+ props: {
2058
+ label: {},
2059
+ active: { type: Boolean },
2060
+ disabled: { type: Boolean }
2061
+ },
2062
+ emits: ["activate"],
2063
+ setup(e, { emit: t }) {
2064
+ const o = t;
2065
+ function n(r) {
2066
+ r.preventDefault(), o("activate");
2067
+ }
2068
+ return (r, a) => (m(), v("button", {
2069
+ type: "button",
2070
+ class: fe(["lw-tool", { "lw-tool--on": e.active }]),
2071
+ title: e.label,
2072
+ "aria-label": e.label,
2073
+ "aria-pressed": e.active ? "true" : "false",
2074
+ disabled: e.disabled,
2075
+ onMousedown: n
2076
+ }, [
2077
+ Ft(r.$slots, "default")
2078
+ ], 42, xl));
2079
+ }
2080
+ }), Ml = { class: "lw-annotator__panel" }, Sl = { class: "lw-annotator__head" }, El = { class: "lw-grow" }, Cl = { class: "lw-annotator__title" }, Al = { class: "lw-annotator__desc" }, Ll = ["aria-label"], Tl = { class: "lw-annotator__tools" }, _l = ["aria-pressed", "disabled", "onClick"], Rl = ["disabled"], Il = { class: "lw-annotator__canvas" }, zl = { class: "lw-annotator__canvasbox" }, Nl = { class: "lw-annotator__hint" }, Pl = { class: "lw-annotator__actions" }, Ul = ["disabled"], Dl = /* @__PURE__ */ J({
2081
+ __name: "ImageAnnotatorDialog",
2082
+ props: {
2083
+ src: {},
2084
+ filename: {},
2085
+ locale: {}
2086
+ },
2087
+ emits: ["confirm", "cancel"],
2088
+ setup(e, { emit: t }) {
2089
+ const o = e, n = t, r = lt(o.locale ?? a());
2090
+ function a() {
2091
+ try {
2092
+ return X().locale;
2093
+ } catch {
2094
+ return;
2095
+ }
2096
+ }
2097
+ const l = [
2098
+ { tool: "rect", key: "toolRect", icon: Sa },
2099
+ { tool: "arrow", key: "toolArrow", icon: Ea },
2100
+ { tool: "highlight", key: "toolHighlight", icon: Ca },
2101
+ { tool: "text", key: "toolText", icon: Aa }
2102
+ ], s = N(null), c = Vt(null), g = N(null), k = N(!0);
2103
+ re(
2104
+ () => [o.src, s.value],
2105
+ ([T, R]) => {
2106
+ var M;
2107
+ if (!T || !R) return;
2108
+ (M = c.value) == null || M.destroy();
2109
+ const x = new Image();
2110
+ x.addEventListener("load", () => {
2111
+ R.width = x.naturalWidth, R.height = x.naturalHeight, c.value = ln(R, x, () => {
2112
+ g.value = null;
2113
+ }), k.value = !1;
2114
+ }), x.src = T;
2115
+ },
2116
+ { immediate: !0 }
2117
+ ), qt(() => {
2118
+ var T;
2119
+ return (T = c.value) == null ? void 0 : T.destroy();
2120
+ });
2121
+ function w(T) {
2122
+ var R;
2123
+ g.value = g.value === T ? null : T, (R = c.value) == null || R.setTool(g.value);
2124
+ }
2125
+ function S() {
2126
+ var T;
2127
+ (T = c.value) == null || T.clear(), g.value = null;
2128
+ }
2129
+ function E() {
2130
+ var T;
2131
+ n("confirm", ((T = c.value) == null ? void 0 : T.toDataUrl()) ?? o.src ?? "");
2132
+ }
2133
+ return (T, R) => e.src ? (m(), v("div", {
2134
+ key: 0,
2135
+ class: "lw-annotator",
2136
+ role: "dialog",
2137
+ "aria-modal": "true",
2138
+ onClick: R[2] || (R[2] = $t((x) => n("cancel"), ["self"]))
2139
+ }, [
2140
+ f("div", Ml, [
2141
+ f("div", Sl, [
2142
+ f("div", El, [
2143
+ f("h2", Cl, y(P(r).annotateTitle), 1),
2144
+ f("p", Al, [
2145
+ V(y(P(r).annotateHint), 1),
2146
+ e.filename ? (m(), v(q, { key: 0 }, [
2147
+ V(" · " + y(e.filename), 1)
2148
+ ], 64)) : B("", !0)
2149
+ ])
2150
+ ]),
2151
+ f("button", {
2152
+ type: "button",
2153
+ class: "lw-annotator__close",
2154
+ "aria-label": P(r).cancel,
2155
+ onClick: R[0] || (R[0] = (x) => n("cancel"))
2156
+ }, "✕", 8, Ll)
2157
+ ]),
2158
+ f("div", Tl, [
2159
+ (m(), v(q, null, ae(l, (x) => f("button", {
2160
+ key: x.tool,
2161
+ type: "button",
2162
+ class: "lw-atool",
2163
+ "aria-pressed": g.value === x.tool,
2164
+ disabled: k.value,
2165
+ onClick: (M) => w(x.tool)
2166
+ }, [
2167
+ (m(), G(et(x.icon))),
2168
+ V(" " + y(P(r)[x.key]), 1)
2169
+ ], 8, _l)), 64)),
2170
+ R[3] || (R[3] = f("span", { class: "lw-grow" }, null, -1)),
2171
+ f("button", {
2172
+ type: "button",
2173
+ class: "lw-atool lw-atool--plain",
2174
+ disabled: k.value,
2175
+ onClick: S
2176
+ }, [
2177
+ O(P(La)),
2178
+ V(" " + y(P(r).clearAll), 1)
2179
+ ], 8, Rl)
2180
+ ]),
2181
+ f("div", Il, [
2182
+ f("div", zl, [
2183
+ f("canvas", {
2184
+ ref_key: "canvas",
2185
+ ref: s
2186
+ }, null, 512)
2187
+ ])
2188
+ ]),
2189
+ f("p", Nl, y(P(r).annotateHelp), 1),
2190
+ f("div", Pl, [
2191
+ R[4] || (R[4] = f("span", { class: "lw-grow" }, null, -1)),
2192
+ f("button", {
2193
+ type: "button",
2194
+ class: "lw-btn",
2195
+ onClick: R[1] || (R[1] = (x) => n("cancel"))
2196
+ }, y(P(r).cancel), 1),
2197
+ f("button", {
2198
+ type: "button",
2199
+ class: "lw-send",
2200
+ disabled: k.value,
2201
+ onClick: E
2202
+ }, y(P(r).annotateApply), 9, Ul)
2203
+ ])
2204
+ ])
2205
+ ])) : B("", !0);
2206
+ }
2207
+ }), Ol = {
2208
+ key: 0,
2209
+ class: "lw-editor__tools"
2210
+ }, Bl = {
2211
+ key: 1,
2212
+ class: "lw-editor__uploading"
2213
+ }, Ht = /* @__PURE__ */ J({
2214
+ __name: "RichReplyEditor",
2215
+ props: /* @__PURE__ */ ct({
2216
+ placeholder: {},
2217
+ host: {},
2218
+ disabled: { type: Boolean },
2219
+ tools: { default: () => ta },
2220
+ compact: { type: Boolean, default: !1 },
2221
+ labels: {},
2222
+ uploadImage: {},
2223
+ locale: {},
2224
+ initial: {}
2225
+ }, {
2226
+ modelValue: { required: !1 },
2227
+ modelModifiers: {}
2228
+ }),
2229
+ emits: /* @__PURE__ */ ct(["error"], ["update:modelValue"]),
2230
+ setup(e, { expose: t, emit: o }) {
2231
+ const n = e, r = wn(e, "modelValue"), a = o, l = N(!1), s = N(!1), c = N(null), g = N(null), k = N("screenshot.png"), w = Mn({
2232
+ // StarterKit v3 already carries Underline and Link, so the toolbar the
2233
+ // original defines needs only two extensions beyond it.
2234
+ extensions: [
2235
+ En,
2236
+ Cn.configure({ inline: !1, allowBase64: !1 }),
2237
+ An.configure({ placeholder: () => n.placeholder })
2238
+ ],
2239
+ content: n.initial ?? r.value ?? "",
2240
+ onUpdate: ({ editor: h }) => {
2241
+ (r.value !== void 0 || n.compact) && (r.value = h.isEmpty ? "" : h.getHTML());
2242
+ },
2243
+ onFocus: () => l.value = !0,
2244
+ onBlur: () => l.value = !1,
2245
+ editorProps: {
2246
+ attributes: { class: "lw-editor-body" },
2247
+ /**
2248
+ * A pasted screenshot is the normal case — Cmd+Shift+4, Cmd+V — and
2249
+ * without this the only route is save-to-disk, find-the-file, pick-it.
2250
+ */
2251
+ handlePaste: (h, _) => {
2252
+ var H;
2253
+ const L = Array.from(((H = _.clipboardData) == null ? void 0 : H.files) ?? []).find((Z) => Z.type.startsWith("image/"));
2254
+ return L ? (_.preventDefault(), x(L), !0) : !1;
2255
+ },
2256
+ handleDrop: (h, _) => {
2257
+ var Z;
2258
+ const L = _, H = Array.from(((Z = L.dataTransfer) == null ? void 0 : Z.files) ?? []).find((ee) => ee.type.startsWith("image/"));
2259
+ return H ? (L.preventDefault(), x(H), !0) : !1;
2260
+ }
2261
+ }
2262
+ });
2263
+ re(
2264
+ () => n.disabled,
2265
+ (h) => {
2266
+ var _;
2267
+ return (_ = w.value) == null ? void 0 : _.setEditable(!h);
2268
+ }
2269
+ ), re(r, (h) => {
2270
+ const _ = w.value;
2271
+ !_ || _.isDestroyed || h === "" && !_.isEmpty && _.commands.clearContent();
2272
+ });
2273
+ const S = F(() => {
2274
+ var h;
2275
+ return !n.compact || l.value || !((h = w.value) != null && h.isEmpty);
2276
+ }), E = {
2277
+ bold: () => ({ name: "bold", icon: ua, label: n.labels.bold, run: () => {
2278
+ var h;
2279
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleBold().run();
2280
+ } }),
2281
+ italic: () => ({ name: "italic", icon: ca, label: n.labels.italic, run: () => {
2282
+ var h;
2283
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleItalic().run();
2284
+ } }),
2285
+ underline: () => ({ name: "underline", icon: da, label: n.labels.underline, run: () => {
2286
+ var h;
2287
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleUnderline().run();
2288
+ } }),
2289
+ strike: () => ({ name: "strike", icon: Ta, label: n.labels.strike, run: () => {
2290
+ var h;
2291
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleStrike().run();
2292
+ } }),
2293
+ code: () => ({ name: "code", icon: _a, label: n.labels.code, run: () => {
2294
+ var h;
2295
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleCode().run();
2296
+ } }),
2297
+ bulletList: () => ({ name: "bulletList", icon: fa, label: n.labels.bulletList, run: () => {
2298
+ var h;
2299
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleBulletList().run();
2300
+ } }),
2301
+ orderedList: () => ({ name: "orderedList", icon: ha, label: n.labels.orderedList, run: () => {
2302
+ var h;
2303
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleOrderedList().run();
2304
+ } }),
2305
+ blockquote: () => ({ name: "blockquote", icon: Ra, label: n.labels.blockquote, run: () => {
2306
+ var h;
2307
+ return (h = w.value) == null ? void 0 : h.chain().focus().toggleBlockquote().run();
2308
+ } }),
2309
+ link: () => ({ name: "link", icon: pa, label: n.labels.link, run: W }),
2310
+ image: () => ({ name: "image", icon: Dt, label: n.labels.attachImage, run: j })
2311
+ }, T = F(() => n.tools.filter((h) => h !== "image").map((h) => E[h]())), R = F(() => n.tools.includes("image"));
2312
+ qt(() => {
2313
+ var h;
2314
+ return (h = w.value) == null ? void 0 : h.destroy();
2315
+ });
2316
+ async function x(h) {
2317
+ if (!(s.value || g.value))
2318
+ try {
2319
+ k.value = h.name || "screenshot.png", g.value = await A(h);
2320
+ } catch (_) {
2321
+ a("error", _ instanceof Error ? _.message : "unreadable file");
2322
+ }
2323
+ }
2324
+ async function M(h) {
2325
+ var _;
2326
+ g.value = null, s.value = !0;
2327
+ try {
2328
+ const L = n.uploadImage ? await n.uploadImage(Q(h, k.value)) : h;
2329
+ (_ = w.value) == null || _.chain().focus().setImage({ src: L, alt: k.value }).run();
2330
+ } catch (L) {
2331
+ a("error", L instanceof Error ? L.message : "upload failed");
2332
+ } finally {
2333
+ s.value = !1;
2334
+ }
2335
+ }
2336
+ function A(h) {
2337
+ return new Promise((_, L) => {
2338
+ const H = new FileReader();
2339
+ H.addEventListener(
2340
+ "load",
2341
+ () => typeof H.result == "string" ? _(H.result) : L(new Error("unreadable file"))
2342
+ ), H.addEventListener("error", () => L(new Error("unreadable file"))), H.readAsDataURL(h);
2343
+ });
2344
+ }
2345
+ function Q(h, _) {
2346
+ var se;
2347
+ const [L, H] = h.split(","), Z = ((se = /data:([^;]+)/.exec(L ?? "")) == null ? void 0 : se[1]) ?? "image/png", ee = atob(H ?? ""), te = new Uint8Array(ee.length);
2348
+ for (let oe = 0; oe < ee.length; oe += 1) te[oe] = ee.charCodeAt(oe);
2349
+ return new File([te], _, { type: Z });
2350
+ }
2351
+ function j() {
2352
+ var h;
2353
+ (h = c.value) == null || h.click();
2354
+ }
2355
+ function ne(h) {
2356
+ var H;
2357
+ const _ = h.target, L = (H = _.files) == null ? void 0 : H[0];
2358
+ _.value = "", L && x(L);
2359
+ }
2360
+ function W() {
2361
+ const h = w.value;
2362
+ if (!h) return;
2363
+ if (h.getAttributes("link").href) {
2364
+ h.chain().focus().unsetLink().run();
2365
+ return;
2366
+ }
2367
+ const L = window.prompt(n.labels.linkPrompt, "https://");
2368
+ if (L) {
2369
+ if (!/^https?:\/\//i.test(L)) {
2370
+ a("error", `${n.labels.link}: http(s) only`);
2371
+ return;
2372
+ }
2373
+ h.chain().focus().extendMarkRange("link").setLink({ href: L }).run();
2374
+ }
2375
+ }
2376
+ function ie() {
2377
+ var _;
2378
+ const h = Kr(((_ = w.value) == null ? void 0 : _.getHTML()) ?? "", n.host);
2379
+ return Wr(h) ? "" : h;
2380
+ }
2381
+ function he() {
2382
+ var h;
2383
+ (h = w.value) == null || h.commands.clearContent(!0);
2384
+ }
2385
+ return t({ value: ie, clear: he, focus: () => {
2386
+ var h;
2387
+ return (h = w.value) == null ? void 0 : h.commands.focus();
2388
+ } }), (h, _) => (m(), v("div", {
2389
+ class: fe(["lw-editor", { "lw-editor--disabled": e.disabled }])
2390
+ }, [
2391
+ S.value ? (m(), v("div", Ol, [
2392
+ (m(!0), v(q, null, ae(T.value, (L) => {
2393
+ var H;
2394
+ return m(), G(Bt, {
2395
+ key: L.name,
2396
+ label: L.label,
2397
+ active: (H = P(w)) == null ? void 0 : H.isActive(L.name),
2398
+ disabled: e.disabled,
2399
+ onActivate: (Z) => L.run()
2400
+ }, {
2401
+ default: ut(() => [
2402
+ (m(), G(et(L.icon)))
2403
+ ]),
2404
+ _: 2
2405
+ }, 1032, ["label", "active", "disabled", "onActivate"]);
2406
+ }), 128)),
2407
+ R.value ? (m(), v(q, { key: 0 }, [
2408
+ _[1] || (_[1] = f("span", { class: "lw-editor__sep" }, null, -1)),
2409
+ O(Bt, {
2410
+ label: e.labels.attachImage ?? "",
2411
+ disabled: e.disabled || s.value,
2412
+ onActivate: j
2413
+ }, {
2414
+ default: ut(() => [
2415
+ O(P(Dt))
2416
+ ]),
2417
+ _: 1
2418
+ }, 8, ["label", "disabled"])
2419
+ ], 64)) : B("", !0),
2420
+ s.value ? (m(), v("span", Bl, y(e.labels.uploading ?? ""), 1)) : B("", !0)
2421
+ ])) : B("", !0),
2422
+ O(P(Sn), {
2423
+ editor: P(w),
2424
+ class: "lw-editor__content"
2425
+ }, null, 8, ["editor"]),
2426
+ f("input", {
2427
+ ref_key: "fileInput",
2428
+ ref: c,
2429
+ type: "file",
2430
+ accept: "image/*",
2431
+ hidden: "",
2432
+ onChange: ne
2433
+ }, null, 544),
2434
+ O(Dl, {
2435
+ src: g.value,
2436
+ filename: k.value,
2437
+ locale: e.locale,
2438
+ onConfirm: M,
2439
+ onCancel: _[0] || (_[0] = (L) => g.value = null)
2440
+ }, null, 8, ["src", "filename", "locale"])
2441
+ ], 2));
2442
+ }
2443
+ }), Hl = { class: "lw-card" }, Fl = { class: "lw-card__title" }, $l = {
2444
+ key: 0,
2445
+ class: "lw-thread__empty"
2446
+ }, Ql = { class: "lw-msg__bubble" }, Vl = { class: "lw-msg__meta" }, ql = {
2447
+ key: 0,
2448
+ class: "lw-msg__who"
2449
+ }, Jl = { class: "lw-msg__who" }, Zl = { class: "lw-msg__role" }, Yl = {
2450
+ key: 2,
2451
+ class: "lw-msg__edited"
2452
+ }, Xl = ["onClick"], Gl = {
2453
+ key: 0,
2454
+ class: "lw-msg__editing"
2455
+ }, Kl = { class: "lw-msg__editActions" }, jl = ["disabled"], Wl = ["disabled", "onClick"], ei = { class: "lw-composer" }, ti = { class: "lw-composer__actions" }, ni = ["disabled"], oi = /* @__PURE__ */ J({
2456
+ __name: "TicketConversation",
2457
+ props: {
2458
+ ticket: {},
2459
+ t: {},
2460
+ host: {},
2461
+ timezone: {},
2462
+ locale: {},
2463
+ sending: { type: Boolean },
2464
+ uploadImage: { type: Function }
2465
+ },
2466
+ emits: ["send", "edited", "error"],
2467
+ setup(e, { expose: t, emit: o }) {
2468
+ const n = e, r = o, a = N(null), l = N(null), s = N(null), c = N(!1), g = Vt(null);
2469
+ function k(x) {
2470
+ g.value = x ?? null;
2471
+ }
2472
+ const w = F(() => ({
2473
+ bold: n.t.bold,
2474
+ italic: n.t.italic,
2475
+ underline: n.t.underline,
2476
+ bulletList: n.t.bulletList,
2477
+ orderedList: n.t.orderedList,
2478
+ link: n.t.link,
2479
+ linkPrompt: n.t.linkPrompt,
2480
+ attachImage: n.t.attachImage,
2481
+ uploading: n.t.uploading
2482
+ }));
2483
+ function S(x) {
2484
+ return x.authorRole === "REPORTER";
2485
+ }
2486
+ async function E(x) {
2487
+ var A;
2488
+ const M = ((A = g.value) == null ? void 0 : A.value()) ?? "";
2489
+ if (!(!M || c.value)) {
2490
+ c.value = !0;
2491
+ try {
2492
+ await Nr(n.ticket.id, x.id, M), s.value = null, r("edited");
2493
+ } catch (Q) {
2494
+ r("error", Q instanceof Error ? Q.message : n.t.sendFailed);
2495
+ } finally {
2496
+ c.value = !1;
2497
+ }
2498
+ }
2499
+ }
2500
+ function T() {
2501
+ var M, A;
2502
+ const x = ((M = a.value) == null ? void 0 : M.value()) ?? "";
2503
+ !x || n.sending || (r("send", x), (A = a.value) == null || A.clear());
2504
+ }
2505
+ async function R(x) {
2506
+ var A, Q;
2507
+ await kn();
2508
+ const M = l.value;
2509
+ M && (M.scrollTop = M.scrollHeight), x === "smooth" && ((Q = (A = l.value) == null ? void 0 : A.lastElementChild) == null || Q.scrollIntoView({ block: "nearest", behavior: x }));
2510
+ }
2511
+ return re(() => n.ticket.id, () => void R("auto"), { immediate: !0 }), re(
2512
+ () => n.ticket.messages.length,
2513
+ (x, M) => {
2514
+ x <= (M ?? 0) || R("smooth");
2515
+ }
2516
+ ), t({ clear: () => {
2517
+ var x;
2518
+ return (x = a.value) == null ? void 0 : x.clear();
2519
+ } }), (x, M) => (m(), v("section", Hl, [
2520
+ f("h3", Fl, y(e.t.conversation), 1),
2521
+ f("div", {
2522
+ ref_key: "thread",
2523
+ ref: l,
2524
+ class: "lw-thread"
2525
+ }, [
2526
+ e.ticket.messages.length ? B("", !0) : (m(), v("p", $l, y(e.t.noMessages), 1)),
2527
+ (m(!0), v(q, null, ae(e.ticket.messages, (A) => (m(), v("article", {
2528
+ key: A.id,
2529
+ class: fe(["lw-msg", { "lw-msg--mine": A.authorRole === "REPORTER" }])
2530
+ }, [
2531
+ f("div", Ql, [
2532
+ f("p", Vl, [
2533
+ A.authorRole === "AGENT" ? (m(), v("span", ql, y(e.t.team), 1)) : (m(), v(q, { key: 1 }, [
2534
+ f("span", Jl, y(A.authorName || e.t.you), 1),
2535
+ f("span", Zl, y(e.t.reporterRole), 1)
2536
+ ], 64)),
2537
+ f("span", null, "· " + y(P(He)(A.createdAt, e.timezone, e.locale)), 1),
2538
+ A.editedAt ? (m(), v("span", Yl, "· " + y(e.t.edited), 1)) : B("", !0),
2539
+ S(A) && s.value !== A.id ? (m(), v("button", {
2540
+ key: 3,
2541
+ type: "button",
2542
+ class: "lw-msg__edit",
2543
+ onClick: (Q) => s.value = A.id
2544
+ }, [
2545
+ O(P(Ia)),
2546
+ V(" " + y(e.t.edit), 1)
2547
+ ], 8, Xl)) : B("", !0)
2548
+ ]),
2549
+ s.value === A.id ? (m(), v("div", Gl, [
2550
+ O(Ht, {
2551
+ ref_for: !0,
2552
+ ref: k,
2553
+ placeholder: e.t.replyPlaceholder,
2554
+ host: e.host,
2555
+ locale: e.locale,
2556
+ disabled: c.value,
2557
+ "upload-image": e.uploadImage,
2558
+ labels: w.value,
2559
+ initial: A.body,
2560
+ onError: M[0] || (M[0] = (Q) => r("error", Q))
2561
+ }, null, 8, ["placeholder", "host", "locale", "disabled", "upload-image", "labels", "initial"]),
2562
+ f("div", Kl, [
2563
+ f("button", {
2564
+ type: "button",
2565
+ class: "lw-btn",
2566
+ disabled: c.value,
2567
+ onClick: M[1] || (M[1] = (Q) => s.value = null)
2568
+ }, [
2569
+ O(P(Na)),
2570
+ V(" " + y(e.t.cancel), 1)
2571
+ ], 8, jl),
2572
+ f("button", {
2573
+ type: "button",
2574
+ class: "lw-send",
2575
+ disabled: c.value,
2576
+ onClick: (Q) => E(A)
2577
+ }, [
2578
+ O(P(za)),
2579
+ V(" " + y(e.t.saveEdit), 1)
2580
+ ], 8, Wl)
2581
+ ])
2582
+ ])) : (m(), G(st, {
2583
+ key: 1,
2584
+ html: A.body,
2585
+ host: e.host
2586
+ }, null, 8, ["html", "host"]))
2587
+ ])
2588
+ ], 2))), 128))
2589
+ ], 512),
2590
+ f("div", ei, [
2591
+ O(Ht, {
2592
+ ref_key: "editor",
2593
+ ref: a,
2594
+ placeholder: e.t.replyPlaceholder,
2595
+ host: e.host,
2596
+ locale: e.locale,
2597
+ disabled: e.sending,
2598
+ "upload-image": e.uploadImage,
2599
+ labels: w.value,
2600
+ onError: M[2] || (M[2] = (A) => r("error", A))
2601
+ }, null, 8, ["placeholder", "host", "locale", "disabled", "upload-image", "labels"]),
2602
+ f("div", ti, [
2603
+ f("button", {
2604
+ type: "button",
2605
+ class: "lw-send",
2606
+ disabled: e.sending,
2607
+ onClick: T
2608
+ }, [
2609
+ O(P(ma)),
2610
+ V(" " + y(e.sending ? e.t.sending : e.t.send), 1)
2611
+ ], 8, ni)
2612
+ ])
2613
+ ])
2614
+ ]));
2615
+ }
2616
+ }), ri = { class: "lw-card" }, ai = { class: "lw-card__title" }, li = ["src", "alt", "onError"], ii = /* @__PURE__ */ J({
2617
+ __name: "TicketScreenshots",
2618
+ props: {
2619
+ images: {},
2620
+ title: {},
2621
+ attachmentUrl: { type: Function }
2622
+ },
2623
+ setup(e) {
2624
+ const t = e, o = N({}), n = N({});
2625
+ return Oe(() => {
2626
+ for (const r of t.images)
2627
+ t.attachmentUrl(r.id).then(
2628
+ (a) => o.value = { ...o.value, [r.id]: a },
2629
+ // Drop the frame rather than leave a broken-image icon where a screenshot
2630
+ // should be.
2631
+ () => n.value = { ...n.value, [r.id]: !0 }
2632
+ );
2633
+ }), (r, a) => (m(), v("section", ri, [
2634
+ f("h3", ai, y(e.title), 1),
2635
+ (m(!0), v(q, null, ae(e.images, (l) => (m(), v(q, {
2636
+ key: l.id
2637
+ }, [
2638
+ o.value[l.id] && !n.value[l.id] ? (m(), v("img", {
2639
+ key: 0,
2640
+ class: "lw-shot",
2641
+ src: o.value[l.id],
2642
+ alt: l.filename ?? "",
2643
+ onError: (s) => n.value = { ...n.value, [l.id]: !0 }
2644
+ }, null, 40, li)) : B("", !0)
2645
+ ], 64))), 128))
2646
+ ]));
2647
+ }
2648
+ }), si = { class: "lw-detail" }, ui = { class: "lw-card" }, ci = { class: "lw-card__heading" }, di = { class: "lw-facts" }, fi = { class: "lw-key" }, hi = {
2649
+ key: 0,
2650
+ class: "lw-chip"
2651
+ }, pi = { key: 1 }, mi = {
2652
+ key: 1,
2653
+ class: "lw-route"
2654
+ }, gi = ["href"], bi = { class: "lw-card" }, yi = { class: "lw-card__title" }, vi = /* @__PURE__ */ J({
2655
+ __name: "TicketDetail",
2656
+ props: {
2657
+ ticket: {},
2658
+ history: {},
2659
+ config: {},
2660
+ maps: {},
2661
+ t: {},
2662
+ host: {},
2663
+ locale: {},
2664
+ sending: { type: Boolean },
2665
+ reopening: { type: Boolean },
2666
+ uploadImage: { type: Function },
2667
+ attachmentUrl: { type: Function }
2668
+ },
2669
+ emits: ["back", "edited", "send", "reopen", "error"],
2670
+ setup(e, { emit: t }) {
2671
+ const o = e, n = t, r = F(() => o.locale === "en" ? "en" : "th"), a = F(
2672
+ () => o.maps.isClosed(o.ticket.status) && o.config.featureFlags.selfServiceReopen === !0
2673
+ ), l = F(() => o.ticket.updatedAt && o.ticket.updatedAt !== o.ticket.createdAt), s = F(
2674
+ () => o.ticket.attachments.filter((g) => (g.contentType ?? "").startsWith("image/"))
2675
+ );
2676
+ function c(g) {
2677
+ return He(g, o.config.timezone, o.locale);
2678
+ }
2679
+ return (g, k) => (m(), v("div", si, [
2680
+ f("button", {
2681
+ type: "button",
2682
+ class: "lw-back",
2683
+ onClick: k[0] || (k[0] = (w) => n("back"))
2684
+ }, [
2685
+ O(P(ba)),
2686
+ V(" " + y(e.t.back), 1)
2687
+ ]),
2688
+ f("section", ui, [
2689
+ f("h3", ci, y(e.ticket.title), 1),
2690
+ f("div", di, [
2691
+ f("span", fi, y(P(it)(e.config.realm.slug, e.ticket.number)), 1),
2692
+ e.ticket.category ? (m(), v("span", hi, y(e.ticket.category), 1)) : B("", !0),
2693
+ f("span", null, y(e.t.colCreated) + " " + y(c(e.ticket.createdAt)), 1),
2694
+ l.value ? (m(), v("span", pi, y(e.t.colUpdated) + " " + y(c(e.ticket.updatedAt)), 1)) : B("", !0)
2695
+ ]),
2696
+ e.ticket.description ? (m(), G(st, {
2697
+ key: 0,
2698
+ class: "lw-intro",
2699
+ html: e.ticket.description,
2700
+ host: e.host
2701
+ }, null, 8, ["html", "host"])) : B("", !0),
2702
+ e.ticket.routeUrl ? (m(), v("p", mi, [
2703
+ V(y(e.t.page) + ": ", 1),
2704
+ f("a", {
2705
+ href: e.ticket.routeUrl,
2706
+ target: "_blank",
2707
+ rel: "noopener noreferrer"
2708
+ }, y(e.ticket.routeUrl), 9, gi)
2709
+ ])) : B("", !0)
2710
+ ]),
2711
+ O(il, {
2712
+ ticket: e.ticket,
2713
+ maps: e.maps,
2714
+ t: e.t,
2715
+ locale: r.value,
2716
+ host: e.host
2717
+ }, null, 8, ["ticket", "maps", "t", "locale", "host"]),
2718
+ a.value ? (m(), G(gl, {
2719
+ key: 0,
2720
+ t: e.t,
2721
+ locale: r.value,
2722
+ busy: e.reopening,
2723
+ onReopen: k[1] || (k[1] = (w) => n("reopen", w))
2724
+ }, null, 8, ["t", "locale", "busy"])) : B("", !0),
2725
+ f("section", bi, [
2726
+ f("h3", yi, y(r.value === "en" ? "Progress" : "ความคืบหน้า"), 1),
2727
+ O(kl, {
2728
+ history: e.history,
2729
+ status: e.ticket.status,
2730
+ "created-at": e.ticket.createdAt,
2731
+ maps: e.maps,
2732
+ timezone: e.config.timezone,
2733
+ locale: r.value
2734
+ }, null, 8, ["history", "status", "created-at", "maps", "timezone", "locale"])
2735
+ ]),
2736
+ O(oi, {
2737
+ ticket: e.ticket,
2738
+ t: e.t,
2739
+ host: e.host,
2740
+ timezone: e.config.timezone,
2741
+ locale: e.locale,
2742
+ sending: e.sending,
2743
+ "upload-image": e.uploadImage,
2744
+ onSend: k[2] || (k[2] = (w) => n("send", w)),
2745
+ onEdited: k[3] || (k[3] = (w) => n("edited")),
2746
+ onError: k[4] || (k[4] = (w) => n("error", w))
2747
+ }, null, 8, ["ticket", "t", "host", "timezone", "locale", "sending", "upload-image"]),
2748
+ s.value.length ? (m(), G(ii, {
2749
+ key: 1,
2750
+ images: s.value,
2751
+ title: r.value === "en" ? "Screenshots you sent" : "ภาพหน้าจอที่คุณแจ้ง",
2752
+ "attachment-url": e.attachmentUrl
2753
+ }, null, 8, ["images", "title", "attachment-url"])) : B("", !0)
2754
+ ]));
2755
+ }
2756
+ }), wi = { class: "lw-panel" }, ki = {
2757
+ key: 0,
2758
+ class: "lw-panel__title"
2759
+ }, xi = { class: "lw-panel__intro" }, Mi = { class: "lw-controls" }, Si = { class: "lw-search" }, Ei = ["placeholder", "aria-label"], Ci = ["value"], Ai = { class: "lw-count" }, Li = {
2760
+ key: 1,
2761
+ class: "lw-state"
2762
+ }, Ti = {
2763
+ key: 2,
2764
+ class: "lw-skeletons"
2765
+ }, _i = {
2766
+ key: 3,
2767
+ class: "lw-state lw-state--error"
2768
+ }, Ri = {
2769
+ key: 1,
2770
+ class: "lw-skeletons"
2771
+ }, Ii = {
2772
+ key: 2,
2773
+ class: "lw-state lw-state--error"
2774
+ }, Fi = /* @__PURE__ */ J({
2775
+ __name: "MyTicketsPanel",
2776
+ props: {
2777
+ refreshKey: {},
2778
+ hideTitle: { type: Boolean }
2779
+ },
2780
+ emits: ["replied", "reopened", "error"],
2781
+ setup(e, { emit: t }) {
2782
+ const o = e, n = t, r = F(() => {
2783
+ try {
2784
+ return X().locale;
2785
+ } catch {
2786
+ return;
2787
+ }
2788
+ }), a = F(() => {
2789
+ try {
2790
+ return X().host;
2791
+ } catch {
2792
+ return "";
2793
+ }
2794
+ }), l = F(() => ra(r.value)), s = N([]), c = N(null), g = N(!0), k = N(null), w = N(!1), S = N(""), E = N(""), T = N(""), R = N({ key: "createdAt", direction: "desc" }), x = N(1), M = N(null), A = N([]), Q = N(null), j = N(!1), ne = N(!1), W = N(!1), ie = F(() => {
2795
+ var I;
2796
+ return Or(((I = c.value) == null ? void 0 : I.statusColumns) ?? [], l.value.allStatuses);
2797
+ }), he = N(null), h = F(() => {
2798
+ var I;
2799
+ return ((I = he.value) == null ? void 0 : I.count) ?? 0;
2800
+ });
2801
+ let _ = null;
2802
+ re(S, (I) => {
2803
+ _ && clearTimeout(_), _ = setTimeout(() => {
2804
+ E.value = I, x.value = 1;
2805
+ }, 300);
2806
+ }), re(T, () => x.value = 1), re(() => o.refreshKey, () => void L()), Oe(L);
2807
+ async function L() {
2808
+ g.value = !0, k.value = null, w.value = !1;
2809
+ try {
2810
+ const [I, z] = await Promise.all([Dr(), Tr()]);
2811
+ c.value = I, s.value = z;
2812
+ } catch (I) {
2813
+ I instanceof Ke ? w.value = !0 : k.value = I instanceof Error ? I.message : l.value.listFailed;
2814
+ } finally {
2815
+ g.value = !1;
2816
+ }
2817
+ }
2818
+ async function H(I) {
2819
+ M.value = null, A.value = [], Q.value = null, j.value = !0;
2820
+ try {
2821
+ await Z(I);
2822
+ } finally {
2823
+ j.value = !1;
2824
+ }
2825
+ }
2826
+ async function Z(I) {
2827
+ try {
2828
+ const [z, i] = await Promise.all([
2829
+ _r(I),
2830
+ // The timeline is a nicety, not the page: a ticket whose history fails to
2831
+ // load should still show its conversation.
2832
+ Ir(I).catch(() => [])
2833
+ ]);
2834
+ M.value = z, A.value = i;
2835
+ } catch (z) {
2836
+ Q.value = z instanceof Error ? z.message : l.value.detailFailed;
2837
+ }
2838
+ }
2839
+ function ee() {
2840
+ M.value = null, L();
2841
+ }
2842
+ function te(I) {
2843
+ R.value = R.value.key === I ? { key: I, direction: R.value.direction === "asc" ? "desc" : "asc" } : (
2844
+ // Dates open newest-first, text A→Z: the useful first click differs by
2845
+ // what the column holds.
2846
+ { key: I, direction: I === "createdAt" || I === "updatedAt" ? "desc" : "asc" }
2847
+ );
2848
+ }
2849
+ async function se(I) {
2850
+ const z = M.value;
2851
+ if (!(!z || ne.value)) {
2852
+ ne.value = !0;
2853
+ try {
2854
+ await zr(z.id, I), await Z(z.id), M.value && n("replied", M.value);
2855
+ } catch (i) {
2856
+ n("error", i instanceof Error ? i.message : l.value.sendFailed);
2857
+ } finally {
2858
+ ne.value = !1;
2859
+ }
2860
+ }
2861
+ }
2862
+ async function oe(I) {
2863
+ const z = M.value;
2864
+ if (!(!z || W.value)) {
2865
+ W.value = !0;
2866
+ try {
2867
+ await Pr(z.id, I), await Z(z.id), M.value && n("reopened", M.value);
2868
+ } catch (i) {
2869
+ n("error", i instanceof Error ? i.message : l.value.reopenFailed);
2870
+ } finally {
2871
+ W.value = !1;
2872
+ }
2873
+ }
2874
+ }
2875
+ function Ae(I) {
2876
+ const z = M.value;
2877
+ return z ? Le(I).then(
2878
+ (i) => Ur(z.id, i, I.name).then((u) => u.url)
2879
+ ) : Promise.reject(new Error("no ticket"));
2880
+ }
2881
+ function pe(I) {
2882
+ return Rr(I).then((z) => z.url);
2883
+ }
2884
+ function Le(I) {
2885
+ return new Promise((z, i) => {
2886
+ const u = new FileReader();
2887
+ u.addEventListener(
2888
+ "load",
2889
+ () => typeof u.result == "string" ? z(u.result) : i(new Error("unreadable file"))
2890
+ ), u.addEventListener("error", () => i(new Error("unreadable file"))), u.readAsDataURL(I);
2891
+ });
2892
+ }
2893
+ return (I, z) => {
2894
+ var i, u;
2895
+ return m(), v("div", wi, [
2896
+ !M.value && !j.value ? (m(), v(q, { key: 0 }, [
2897
+ e.hideTitle ? B("", !0) : (m(), v("h2", ki, y(l.value.title), 1)),
2898
+ f("p", xi, y(l.value.intro), 1),
2899
+ f("div", Mi, [
2900
+ f("div", Si, [
2901
+ O(P(ga), { class: "lw-search__icon" }),
2902
+ Je(f("input", {
2903
+ "onUpdate:modelValue": z[0] || (z[0] = (d) => S.value = d),
2904
+ type: "search",
2905
+ class: "lw-input lw-search__field",
2906
+ placeholder: l.value.searchPlaceholder,
2907
+ "aria-label": l.value.searchLabel
2908
+ }, null, 8, Ei), [
2909
+ [Qt, S.value]
2910
+ ])
2911
+ ]),
2912
+ Je(f("select", {
2913
+ "onUpdate:modelValue": z[1] || (z[1] = (d) => T.value = d),
2914
+ class: "lw-input"
2915
+ }, [
2916
+ (m(!0), v(q, null, ae(ie.value.options, (d) => (m(), v("option", {
2917
+ key: d.value,
2918
+ value: d.value
2919
+ }, y(d.label), 9, Ci))), 128))
2920
+ ], 512), [
2921
+ [xn, T.value]
2922
+ ]),
2923
+ f("span", Ai, y(l.value.count(h.value)), 1)
2924
+ ]),
2925
+ w.value ? (m(), v("p", Li, y(l.value.signedOut), 1)) : g.value ? (m(), v("div", Ti, [
2926
+ (m(), v(q, null, ae(4, (d) => f("div", {
2927
+ key: d,
2928
+ class: "lw-skeleton"
2929
+ })), 64))
2930
+ ])) : k.value ? (m(), v("p", _i, [
2931
+ O(P(va)),
2932
+ V(" " + y(k.value) + " ", 1),
2933
+ f("button", {
2934
+ type: "button",
2935
+ class: "lw-retry",
2936
+ onClick: L
2937
+ }, y(l.value.retry), 1)
2938
+ ])) : (m(), G(tl, {
2939
+ key: 4,
2940
+ ref_key: "table",
2941
+ ref: he,
2942
+ items: s.value,
2943
+ maps: ie.value,
2944
+ t: l.value,
2945
+ slug: (i = c.value) == null ? void 0 : i.realm.slug,
2946
+ timezone: ((u = c.value) == null ? void 0 : u.timezone) ?? "Asia/Bangkok",
2947
+ locale: r.value,
2948
+ keyword: E.value,
2949
+ "status-filter": T.value,
2950
+ sort: R.value,
2951
+ page: x.value,
2952
+ onOpen: H,
2953
+ onSort: te,
2954
+ onPage: z[2] || (z[2] = (d) => x.value = d)
2955
+ }, null, 8, ["items", "maps", "t", "slug", "timezone", "locale", "keyword", "status-filter", "sort", "page"]))
2956
+ ], 64)) : j.value ? (m(), v("div", Ri, [...z[5] || (z[5] = [
2957
+ f("div", { class: "lw-skeleton" }, null, -1),
2958
+ f("div", { class: "lw-skeleton" }, null, -1)
2959
+ ])])) : Q.value ? (m(), v("p", Ii, y(Q.value), 1)) : M.value && c.value ? (m(), G(vi, {
2960
+ key: 3,
2961
+ ticket: M.value,
2962
+ history: A.value,
2963
+ config: c.value,
2964
+ maps: ie.value,
2965
+ t: l.value,
2966
+ host: a.value,
2967
+ locale: r.value,
2968
+ sending: ne.value,
2969
+ reopening: W.value,
2970
+ "upload-image": Ae,
2971
+ "attachment-url": pe,
2972
+ onBack: ee,
2973
+ onEdited: z[3] || (z[3] = (d) => M.value && Z(M.value.id)),
2974
+ onSend: se,
2975
+ onReopen: oe,
2976
+ onError: z[4] || (z[4] = (d) => n("error", d))
2977
+ }, null, 8, ["ticket", "history", "config", "maps", "t", "host", "locale", "sending", "reopening"])) : B("", !0)
2978
+ ]);
2979
+ };
2980
+ }
2981
+ });
2982
+ export {
2983
+ Bi as DebugCaptureInit,
2984
+ Dl as ImageAnnotatorDialog,
2985
+ Fi as MyTicketsPanel,
2986
+ Hi as ReportProblemButton,
2987
+ Ht as RichReplyEditor,
2988
+ st as TicketBody,
2989
+ oi as TicketConversation,
2990
+ vi as TicketDetail,
2991
+ tl as TicketTable,
2992
+ Tn as configureDebugCapture,
2993
+ en as launch,
2994
+ To as onCrash
2995
+ };
2996
+ //# sourceMappingURL=index.mjs.map