hocmai-feedback-widget 0.2.1 → 0.2.3

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 (59) hide show
  1. package/README.md +78 -113
  2. package/dist/capture/device-detection.d.ts +13 -0
  3. package/dist/capture/fonts.d.ts +4 -0
  4. package/dist/capture/index.d.ts +14 -0
  5. package/dist/capture/mathjax-fonts.d.ts +5 -0
  6. package/dist/capture/types.d.ts +25 -0
  7. package/dist/ckeditor.mjs +113 -0
  8. package/dist/ckeditor.mjs.map +1 -0
  9. package/dist/components/CkEditor.d.ts +14 -0
  10. package/dist/components/FeedbackWidget.d.ts +13 -1
  11. package/dist/context/FeedbackContext.d.ts +14 -2
  12. package/dist/hocmai-feedback-widget.mjs +7550 -0
  13. package/dist/hocmai-feedback-widget.mjs.map +1 -0
  14. package/dist/index.d.ts +4 -2
  15. package/package.json +39 -29
  16. package/src/App.tsx +147 -58
  17. package/src/capture/device-detection.ts +52 -0
  18. package/src/capture/fonts.ts +34 -0
  19. package/src/capture/index.ts +361 -0
  20. package/src/capture/mathjax-fonts.ts +143 -0
  21. package/src/capture/types.ts +34 -0
  22. package/src/ckeditor.d.ts +14 -0
  23. package/src/components/CkEditor.tsx +130 -0
  24. package/src/components/CropOverlay.tsx +29 -47
  25. package/src/components/FeedbackWidget.tsx +105 -93
  26. package/src/context/FeedbackContext.tsx +49 -9
  27. package/src/index.ts +9 -3
  28. package/src/main.tsx +7 -9
  29. package/src/utils/device.ts +14 -14
  30. package/dist/support-feedback-lib.es.js +0 -3946
  31. package/dist/support-feedback-lib.umd.js +0 -84
  32. package/dist/test-mobile-screenshot.html +0 -211
  33. package/dist/test-simple-capture.html +0 -107
  34. package/dist/utils/screenshot/background-renderer.d.ts +0 -3
  35. package/dist/utils/screenshot/canvas-renderer.d.ts +0 -9
  36. package/dist/utils/screenshot/cleanup.d.ts +0 -3
  37. package/dist/utils/screenshot/device-detection.d.ts +0 -16
  38. package/dist/utils/screenshot/element-collector.d.ts +0 -10
  39. package/dist/utils/screenshot/image-renderer.d.ts +0 -21
  40. package/dist/utils/screenshot/performance.d.ts +0 -3
  41. package/dist/utils/screenshot/svg-renderer.d.ts +0 -24
  42. package/dist/utils/screenshot/text-renderer.d.ts +0 -23
  43. package/dist/utils/screenshot/types.d.ts +0 -35
  44. package/dist/utils/screenshot.d.ts +0 -9
  45. package/dist/vite.svg +0 -1
  46. package/src/App.css +0 -42
  47. package/src/assets/react.svg +0 -1
  48. package/src/index.css +0 -68
  49. package/src/utils/screenshot/background-renderer.ts +0 -54
  50. package/src/utils/screenshot/canvas-renderer.ts +0 -343
  51. package/src/utils/screenshot/cleanup.ts +0 -32
  52. package/src/utils/screenshot/device-detection.ts +0 -90
  53. package/src/utils/screenshot/element-collector.ts +0 -134
  54. package/src/utils/screenshot/image-renderer.ts +0 -148
  55. package/src/utils/screenshot/performance.ts +0 -57
  56. package/src/utils/screenshot/svg-renderer.ts +0 -149
  57. package/src/utils/screenshot/text-renderer.ts +0 -212
  58. package/src/utils/screenshot/types.ts +0 -40
  59. package/src/utils/screenshot.ts +0 -83
@@ -1,3946 +0,0 @@
1
- import { jsxs as R, jsx as k, Fragment as Ne } from "react/jsx-runtime";
2
- import Mt, { forwardRef as an, createElement as ht, useState as L, useEffect as Ot, createContext as Pn, useContext as Hn } from "react";
3
- var Vn = "2.0.7", $n = 500, Dt = "user-agent", ye = "", Ft = "?", O = {
4
- FUNCTION: "function",
5
- OBJECT: "object",
6
- STRING: "string",
7
- UNDEFINED: "undefined"
8
- }, $ = "browser", ee = "cpu", J = "device", X = "engine", W = "os", ve = "result", f = "name", c = "type", h = "vendor", p = "version", P = "architecture", Oe = "major", u = "model", qe = "console", I = "mobile", A = "tablet", _ = "smarttv", Y = "wearable", He = "xr", Me = "embedded", pe = "inapp", vt = "brands", de = "formFactors", xt = "fullVersionList", xe = "platform", Ct = "platformVersion", Je = "bitness", se = "sec-ch-ua", Wn = se + "-full-version-list", qn = se + "-arch", jn = se + "-" + Je, Gn = se + "-form-factors", Xn = se + "-" + I, Yn = se + "-" + u, ln = se + "-" + xe, Jn = ln + "-version", cn = [vt, xt, I, u, xe, Ct, P, de, Je], Ve = "Amazon", me = "Apple", _t = "ASUS", Lt = "BlackBerry", le = "Google", Ut = "Huawei", ot = "Lenovo", zt = "Honor", $e = "LG", st = "Microsoft", at = "Motorola", Bt = "Nvidia", Pt = "OnePlus", lt = "OPPO", ke = "Samsung", Ht = "Sharp", Ee = "Sony", ct = "Xiaomi", dt = "Zebra", Vt = "Chrome", $t = "Chromium", ne = "Chromecast", je = "Edge", Te = "Firefox", Ie = "Opera", ut = "Facebook", Wt = "Sogou", we = "Mobile ", Re = " Browser", pt = "Windows", Qn = typeof window !== O.UNDEFINED, V = Qn && window.navigator ? window.navigator : void 0, ue = V && V.userAgentData ? V.userAgentData : void 0, Kn = function(e, n) {
9
- var t = {}, i = n;
10
- if (!Ge(n)) {
11
- i = {};
12
- for (var s in n)
13
- for (var o in n[s])
14
- i[o] = n[s][o].concat(i[o] ? i[o] : []);
15
- }
16
- for (var r in e)
17
- t[r] = i[r] && i[r].length % 2 === 0 ? i[r].concat(e[r]) : e[r];
18
- return t;
19
- }, Qe = function(e) {
20
- for (var n = {}, t = 0; t < e.length; t++)
21
- n[e[t].toUpperCase()] = e[t];
22
- return n;
23
- }, mt = function(e, n) {
24
- if (typeof e === O.OBJECT && e.length > 0) {
25
- for (var t in e)
26
- if (ie(n) == ie(e[t])) return !0;
27
- return !1;
28
- }
29
- return Le(e) ? ie(n) == ie(e) : !1;
30
- }, Ge = function(e, n) {
31
- for (var t in e)
32
- return /^(browser|cpu|device|engine|os)$/.test(t) || (n ? Ge(e[t]) : !1);
33
- }, Le = function(e) {
34
- return typeof e === O.STRING;
35
- }, ft = function(e) {
36
- if (e) {
37
- for (var n = [], t = Ce(/\\?\"/g, e).split(","), i = 0; i < t.length; i++)
38
- if (t[i].indexOf(";") > -1) {
39
- var s = Xe(t[i]).split(";v=");
40
- n[i] = { brand: s[0], version: s[1] };
41
- } else
42
- n[i] = Xe(t[i]);
43
- return n;
44
- }
45
- }, ie = function(e) {
46
- return Le(e) ? e.toLowerCase() : e;
47
- }, wt = function(e) {
48
- return Le(e) ? Ce(/[^\d\.]/g, e).split(".")[0] : void 0;
49
- }, Z = function(e) {
50
- for (var n in e)
51
- if (e.hasOwnProperty(n)) {
52
- var t = e[n];
53
- typeof t == O.OBJECT && t.length == 2 ? this[t[0]] = t[1] : this[t] = void 0;
54
- }
55
- return this;
56
- }, Ce = function(e, n) {
57
- return Le(n) ? n.replace(e, ye) : n;
58
- }, Ae = function(e) {
59
- return Ce(/\\?\"/g, e);
60
- }, Xe = function(e, n) {
61
- return e = Ce(/^\s\s*/, String(e)), typeof n === O.UNDEFINED ? e : e.substring(0, n);
62
- }, bt = function(e, n) {
63
- if (!(!e || !n))
64
- for (var t = 0, i, s, o, r, a, d; t < n.length && !a; ) {
65
- var g = n[t], l = n[t + 1];
66
- for (i = s = 0; i < g.length && !a && g[i]; )
67
- if (a = g[i++].exec(e), a)
68
- for (o = 0; o < l.length; o++)
69
- d = a[++s], r = l[o], typeof r === O.OBJECT && r.length > 0 ? r.length === 2 ? typeof r[1] == O.FUNCTION ? this[r[0]] = r[1].call(this, d) : this[r[0]] = r[1] : r.length >= 3 && (typeof r[1] === O.FUNCTION && !(r[1].exec && r[1].test) ? r.length > 3 ? this[r[0]] = d ? r[1].apply(this, r.slice(2)) : void 0 : this[r[0]] = d ? r[1].call(this, d, r[2]) : void 0 : r.length == 3 ? this[r[0]] = d ? d.replace(r[1], r[2]) : void 0 : r.length == 4 ? this[r[0]] = d ? r[3].call(this, d.replace(r[1], r[2])) : void 0 : r.length > 4 && (this[r[0]] = d ? r[3].apply(this, [d.replace(r[1], r[2])].concat(r.slice(4))) : void 0)) : this[r] = d || void 0;
70
- t += 2;
71
- }
72
- }, G = function(e, n) {
73
- for (var t in n)
74
- if (typeof n[t] === O.OBJECT && n[t].length > 0) {
75
- for (var i = 0; i < n[t].length; i++)
76
- if (mt(n[t][i], e))
77
- return t === Ft ? void 0 : t;
78
- } else if (mt(n[t], e))
79
- return t === Ft ? void 0 : t;
80
- return n.hasOwnProperty("*") ? n["*"] : e;
81
- }, qt = {
82
- ME: "4.90",
83
- "NT 3.51": "3.51",
84
- "NT 4.0": "4.0",
85
- 2e3: ["5.0", "5.01"],
86
- XP: ["5.1", "5.2"],
87
- Vista: "6.0",
88
- 7: "6.1",
89
- 8: "6.2",
90
- "8.1": "6.3",
91
- 10: ["6.4", "10.0"],
92
- NT: ""
93
- }, jt = {
94
- embedded: "Automotive",
95
- mobile: "Mobile",
96
- tablet: ["Tablet", "EInk"],
97
- smarttv: "TV",
98
- wearable: "Watch",
99
- xr: ["VR", "XR"],
100
- "?": ["Desktop", "Unknown"],
101
- "*": void 0
102
- }, Zn = {
103
- Chrome: "Google Chrome",
104
- Edge: "Microsoft Edge",
105
- "Edge WebView2": "Microsoft Edge WebView2",
106
- "Chrome WebView": "Android WebView",
107
- "Chrome Headless": "HeadlessChrome",
108
- "Huawei Browser": "HuaweiBrowser",
109
- "MIUI Browser": "Miui Browser",
110
- "Opera Mobi": "OperaMobile",
111
- Yandex: "YaBrowser"
112
- }, Gt = {
113
- browser: [
114
- [
115
- // Most common regardless engine
116
- /\b(?:crmo|crios)\/([\w\.]+)/i
117
- // Chrome for Android/iOS
118
- ],
119
- [p, [f, we + "Chrome"]],
120
- [
121
- /webview.+edge\/([\w\.]+)/i
122
- // Microsoft Edge
123
- ],
124
- [p, [f, je + " WebView"]],
125
- [
126
- /edg(?:e|ios|a)?\/([\w\.]+)/i
127
- ],
128
- [p, [f, "Edge"]],
129
- [
130
- // Presto based
131
- /(opera mini)\/([-\w\.]+)/i,
132
- // Opera Mini
133
- /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,
134
- // Opera Mobi/Tablet
135
- /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i
136
- // Opera
137
- ],
138
- [f, p],
139
- [
140
- /opios[\/ ]+([\w\.]+)/i
141
- // Opera mini on iphone >= 8.0
142
- ],
143
- [p, [f, Ie + " Mini"]],
144
- [
145
- /\bop(?:rg)?x\/([\w\.]+)/i
146
- // Opera GX
147
- ],
148
- [p, [f, Ie + " GX"]],
149
- [
150
- /\bopr\/([\w\.]+)/i
151
- // Opera Webkit
152
- ],
153
- [p, [f, Ie]],
154
- [
155
- // Mixed
156
- /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i
157
- // Baidu
158
- ],
159
- [p, [f, "Baidu"]],
160
- [
161
- /\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i
162
- // Maxthon
163
- ],
164
- [p, [f, "Maxthon"]],
165
- [
166
- /(kindle)\/([\w\.]+)/i,
167
- // Kindle
168
- /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
169
- // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
170
- // Trident based
171
- /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,
172
- // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
173
- /(?:ms|\()(ie) ([\w\.]+)/i,
174
- // Internet Explorer
175
- // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble/Palemoon
176
- /(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser|palemoon)\/([-\w\.]+)/i,
177
- // Atlas/Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
178
- /(heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,
179
- // HeyTap/Ovi/115/Surf
180
- /(qwant)(?:ios|mobile)\/([\d\.]+)/i,
181
- // Qwant
182
- /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i
183
- // Ecosia/Weibo
184
- ],
185
- [f, p],
186
- [
187
- /quark(?:pc)?\/([-\w\.]+)/i
188
- // Quark
189
- ],
190
- [p, [f, "Quark"]],
191
- [
192
- /\bddg\/([\w\.]+)/i
193
- // DuckDuckGo
194
- ],
195
- [p, [f, "DuckDuckGo"]],
196
- [
197
- /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
198
- // UCBrowser
199
- ],
200
- [p, [f, "UCBrowser"]],
201
- [
202
- /microm.+\bqbcore\/([\w\.]+)/i,
203
- // WeChat Desktop for Windows Built-in Browser
204
- /\bqbcore\/([\w\.]+).+microm/i,
205
- /micromessenger\/([\w\.]+)/i
206
- // WeChat
207
- ],
208
- [p, [f, "WeChat"]],
209
- [
210
- /konqueror\/([\w\.]+)/i
211
- // Konqueror
212
- ],
213
- [p, [f, "Konqueror"]],
214
- [
215
- /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i
216
- // IE11
217
- ],
218
- [p, [f, "IE"]],
219
- [
220
- /ya(?:search)?browser\/([\w\.]+)/i
221
- // Yandex
222
- ],
223
- [p, [f, "Yandex"]],
224
- [
225
- /slbrowser\/([\w\.]+)/i
226
- // Smart Lenovo Browser
227
- ],
228
- [p, [f, "Smart " + ot + Re]],
229
- [
230
- /(avast|avg)\/([\w\.]+)/i
231
- // Avast/AVG Secure Browser
232
- ],
233
- [[f, /(.+)/, "$1 Secure" + Re], p],
234
- [
235
- /\bfocus\/([\w\.]+)/i
236
- // Firefox Focus
237
- ],
238
- [p, [f, Te + " Focus"]],
239
- [
240
- /\bopt\/([\w\.]+)/i
241
- // Opera Touch
242
- ],
243
- [p, [f, Ie + " Touch"]],
244
- [
245
- /coc_coc\w+\/([\w\.]+)/i
246
- // Coc Coc Browser
247
- ],
248
- [p, [f, "Coc Coc"]],
249
- [
250
- /dolfin\/([\w\.]+)/i
251
- // Dolphin
252
- ],
253
- [p, [f, "Dolphin"]],
254
- [
255
- /coast\/([\w\.]+)/i
256
- // Opera Coast
257
- ],
258
- [p, [f, Ie + " Coast"]],
259
- [
260
- /miuibrowser\/([\w\.]+)/i
261
- // MIUI Browser
262
- ],
263
- [p, [f, "MIUI" + Re]],
264
- [
265
- /fxios\/([\w\.-]+)/i
266
- // Firefox for iOS
267
- ],
268
- [p, [f, we + Te]],
269
- [
270
- /\bqihoobrowser\/?([\w\.]*)/i
271
- // 360
272
- ],
273
- [p, [f, "360"]],
274
- [
275
- /\b(qq)\/([\w\.]+)/i
276
- // QQ
277
- ],
278
- [[f, /(.+)/, "$1Browser"], p],
279
- [
280
- /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
281
- ],
282
- [[f, /(.+)/, "$1" + Re], p],
283
- [
284
- // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
285
- /samsungbrowser\/([\w\.]+)/i
286
- // Samsung Internet
287
- ],
288
- [p, [f, ke + " Internet"]],
289
- [
290
- /metasr[\/ ]?([\d\.]+)/i
291
- // Sogou Explorer
292
- ],
293
- [p, [f, Wt + " Explorer"]],
294
- [
295
- /(sogou)mo\w+\/([\d\.]+)/i
296
- // Sogou Mobile
297
- ],
298
- [[f, Wt + " Mobile"], p],
299
- [
300
- /(electron)\/([\w\.]+) safari/i,
301
- // Electron-based App
302
- /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,
303
- // Tesla
304
- /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i
305
- // QQ/2345
306
- ],
307
- [f, p],
308
- [
309
- /(lbbrowser|rekonq|steam(?= (clie|tenf|gameo)))/i
310
- // LieBao Browser/Rekonq/Steam
311
- ],
312
- [f],
313
- [
314
- /ome\/([\w\.]+) \w* ?(iron) saf/i,
315
- // Iron
316
- /ome\/([\w\.]+).+qihu (360)[es]e/i
317
- // 360
318
- ],
319
- [p, f],
320
- [
321
- // WebView
322
- /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i
323
- // Facebook App for iOS & Android
324
- ],
325
- [[f, ut], p, [c, pe]],
326
- [
327
- /(kakao(?:talk|story))[\/ ]([\w\.]+)/i,
328
- // Kakao App
329
- /(naver)\(.*?(\d+\.[\w\.]+).*\)/i,
330
- // Naver InApp
331
- /(daum)apps[\/ ]([\w\.]+)/i,
332
- // Daum App
333
- /safari (line)\/([\w\.]+)/i,
334
- // Line App for iOS
335
- /\b(line)\/([\w\.]+)\/iab/i,
336
- // Line App for Android
337
- /(alipay)client\/([\w\.]+)/i,
338
- // Alipay
339
- /(twitter)(?:and| f.+e\/([\w\.]+))/i,
340
- // Twitter
341
- /(bing)(?:web|sapphire)\/([\w\.]+)/i,
342
- // Bing
343
- /(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i
344
- // Instagram/Snapchat/Klarna
345
- ],
346
- [f, p, [c, pe]],
347
- [
348
- /\bgsa\/([\w\.]+) .*safari\//i
349
- // Google Search Appliance on iOS
350
- ],
351
- [p, [f, "GSA"], [c, pe]],
352
- [
353
- /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i
354
- // TikTok
355
- ],
356
- [p, [f, "TikTok"], [c, pe]],
357
- [
358
- /\[(linkedin)app\]/i
359
- // LinkedIn App for iOS & Android
360
- ],
361
- [f, [c, pe]],
362
- [
363
- /(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i
364
- // Zalo
365
- ],
366
- [[f, /(.+)/, "Zalo"], p, [c, pe]],
367
- [
368
- /(chromium)[\/ ]([-\w\.]+)/i
369
- // Chromium
370
- ],
371
- [f, p],
372
- [
373
- /headlesschrome(?:\/([\w\.]+)| )/i
374
- // Chrome Headless
375
- ],
376
- [p, [f, Vt + " Headless"]],
377
- [
378
- /wv\).+chrome\/([\w\.]+).+edgw\//i
379
- // Edge WebView2
380
- ],
381
- [p, [f, je + " WebView2"]],
382
- [
383
- / wv\).+(chrome)\/([\w\.]+)/i
384
- // Chrome WebView
385
- ],
386
- [[f, Vt + " WebView"], p],
387
- [
388
- /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i
389
- // Android Browser
390
- ],
391
- [p, [f, "Android" + Re]],
392
- [
393
- /chrome\/([\w\.]+) mobile/i
394
- // Chrome Mobile
395
- ],
396
- [p, [f, we + "Chrome"]],
397
- [
398
- /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i
399
- // Chrome/OmniWeb/Arora/Tizen/Nokia
400
- ],
401
- [f, p],
402
- [
403
- /version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i
404
- // Safari Mobile
405
- ],
406
- [p, [f, we + "Safari"]],
407
- [
408
- /iphone .*mobile(?:\/\w+ | ?)safari/i
409
- ],
410
- [[f, we + "Safari"]],
411
- [
412
- /version\/([\w\.\,]+) .*(safari)/i
413
- // Safari
414
- ],
415
- [p, f],
416
- [
417
- /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i
418
- // Safari < 3.0
419
- ],
420
- [f, [p, "1"]],
421
- [
422
- /(webkit|khtml)\/([\w\.]+)/i
423
- ],
424
- [f, p],
425
- [
426
- // Gecko based
427
- /(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i
428
- // Firefox Mobile
429
- ],
430
- [[f, we + Te], p],
431
- [
432
- /(navigator|netscape\d?)\/([-\w\.]+)/i
433
- // Netscape
434
- ],
435
- [[f, "Netscape"], p],
436
- [
437
- /(wolvic|librewolf)\/([\w\.]+)/i
438
- // Wolvic/LibreWolf
439
- ],
440
- [f, p],
441
- [
442
- /mobile vr; rv:([\w\.]+)\).+firefox/i
443
- // Firefox Reality
444
- ],
445
- [p, [f, Te + " Reality"]],
446
- [
447
- /ekiohf.+(flow)\/([\w\.]+)/i,
448
- // Flow
449
- /(swiftfox)/i,
450
- // Swiftfox
451
- /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
452
- // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
453
- /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,
454
- // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
455
- /(firefox)\/([\w\.]+)/i,
456
- // Other Firefox-based
457
- /(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,
458
- // Mozilla
459
- // Other
460
- /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
461
- // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird
462
- /\b(links) \(([\w\.]+)/i
463
- // Links
464
- ],
465
- [f, [p, /_/g, "."]],
466
- [
467
- /(cobalt)\/([\w\.]+)/i
468
- // Cobalt
469
- ],
470
- [f, [p, /[^\d\.]+./, ye]]
471
- ],
472
- cpu: [
473
- [
474
- /\b((amd|x|x86[-_]?|wow|win)64)\b/i
475
- // AMD64 (x64)
476
- ],
477
- [[P, "amd64"]],
478
- [
479
- /(ia32(?=;))/i,
480
- // IA32 (quicktime)
481
- /\b((i[346]|x)86)(pc)?\b/i
482
- // IA32 (x86)
483
- ],
484
- [[P, "ia32"]],
485
- [
486
- /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i
487
- // ARM64
488
- ],
489
- [[P, "arm64"]],
490
- [
491
- /\b(arm(v[67])?ht?n?[fl]p?)\b/i
492
- // ARMHF
493
- ],
494
- [[P, "armhf"]],
495
- [
496
- // PocketPC mistakenly identified as PowerPC
497
- /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
498
- ],
499
- [[P, "arm"]],
500
- [
501
- / sun4\w[;\)]/i
502
- // SPARC
503
- ],
504
- [[P, "sparc"]],
505
- [
506
- // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
507
- /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
508
- /((ppc|powerpc)(64)?)( mac|;|\))/i,
509
- // PowerPC
510
- /(?:osf1|[freopnt]{3,4}bsd) (alpha)/i
511
- // Alpha
512
- ],
513
- [[P, /ower/, ye, ie]],
514
- [
515
- /mc680.0/i
516
- ],
517
- [[P, "68k"]],
518
- [
519
- /winnt.+\[axp/i
520
- ],
521
- [[P, "alpha"]]
522
- ],
523
- device: [
524
- [
525
- //////////////////////////
526
- // MOBILES & TABLETS
527
- /////////////////////////
528
- // Samsung
529
- /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
530
- ],
531
- [u, [h, ke], [c, A]],
532
- [
533
- /\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
534
- /samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,
535
- /sec-(sgh\w+)/i
536
- ],
537
- [u, [h, ke], [c, I]],
538
- [
539
- // Apple
540
- /(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i
541
- // iPod/iPhone
542
- ],
543
- [u, [h, me], [c, I]],
544
- [
545
- /\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,
546
- // iPad
547
- /\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i
548
- ],
549
- [u, [h, me], [c, A]],
550
- [
551
- /(macintosh);/i
552
- ],
553
- [u, [h, me]],
554
- [
555
- // Sharp
556
- /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
557
- ],
558
- [u, [h, Ht], [c, I]],
559
- [
560
- // Honor
561
- /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i
562
- ],
563
- [u, [h, zt], [c, A]],
564
- [
565
- /honor([-\w ]+)[;\)]/i
566
- ],
567
- [u, [h, zt], [c, I]],
568
- [
569
- // Huawei
570
- /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i
571
- ],
572
- [u, [h, Ut], [c, A]],
573
- [
574
- /(?:huawei) ?([-\w ]+)[;\)]/i,
575
- /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i
576
- ],
577
- [u, [h, Ut], [c, I]],
578
- [
579
- // Xiaomi
580
- /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,
581
- /\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i
582
- // Mi Pad tablets
583
- ],
584
- [[u, /_/g, " "], [h, ct], [c, A]],
585
- [
586
- /\b; (\w+) build\/hm\1/i,
587
- // Xiaomi Hongmi 'numeric' models
588
- /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
589
- // Xiaomi Hongmi
590
- // Xiaomi Redmi / POCO / Black Shark / Qin
591
- /oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,
592
- // Xiaomi Mi
593
- /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
594
- / ([\w ]+) miui\/v?\d/i
595
- ],
596
- [[u, /_/g, " "], [h, ct], [c, I]],
597
- [
598
- // OnePlus
599
- /droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,
600
- /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
601
- ],
602
- [u, [h, Pt], [c, I]],
603
- [
604
- // OPPO
605
- /; (\w+) bui.+ oppo/i,
606
- /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
607
- ],
608
- [u, [h, lt], [c, I]],
609
- [
610
- /\b(opd2(\d{3}a?))(?: bui|\))/i
611
- ],
612
- [u, [h, G, { OnePlus: ["203", "304", "403", "404", "413", "415"], "*": lt }], [c, A]],
613
- [
614
- // BLU
615
- /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i
616
- // Vivo series
617
- ],
618
- [u, [h, "BLU"], [c, I]],
619
- [
620
- // Vivo
621
- /; vivo (\w+)(?: bui|\))/i,
622
- /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
623
- ],
624
- [u, [h, "Vivo"], [c, I]],
625
- [
626
- // Realme
627
- /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
628
- ],
629
- [u, [h, "Realme"], [c, I]],
630
- [
631
- // Lenovo
632
- /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,
633
- /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
634
- ],
635
- [u, [h, ot], [c, A]],
636
- [
637
- /lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i
638
- ],
639
- [u, [h, ot], [c, I]],
640
- [
641
- // Motorola
642
- /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
643
- /\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,
644
- /((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i
645
- ],
646
- [u, [h, at], [c, I]],
647
- [
648
- /\b(mz60\d|xoom[2 ]{0,2}) build\//i
649
- ],
650
- [u, [h, at], [c, A]],
651
- [
652
- // LG
653
- /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
654
- ],
655
- [u, [h, $e], [c, A]],
656
- [
657
- /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
658
- /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,
659
- /\blg-?([\d\w]+) bui/i
660
- ],
661
- [u, [h, $e], [c, I]],
662
- [
663
- // Nokia
664
- /(nokia) (t[12][01])/i
665
- ],
666
- [h, u, [c, A]],
667
- [
668
- /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,
669
- /nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i
670
- ],
671
- [[u, /_/g, " "], [c, I], [h, "Nokia"]],
672
- [
673
- // Google
674
- /(pixel (c|tablet))\b/i
675
- // Google Pixel C/Tablet
676
- ],
677
- [u, [h, le], [c, A]],
678
- [
679
- // Google Pixel
680
- /droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i
681
- ],
682
- [u, [h, le], [c, I]],
683
- [
684
- /(google) (pixelbook( go)?)/i
685
- ],
686
- [h, u],
687
- [
688
- // Sony
689
- /droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
690
- ],
691
- [u, [h, Ee], [c, I]],
692
- [
693
- /sony tablet [ps]/i,
694
- /\b(?:sony)?sgp\w+(?: bui|\))/i
695
- ],
696
- [[u, "Xperia Tablet"], [h, Ee], [c, A]],
697
- [
698
- // Amazon
699
- /(alexa)webm/i,
700
- /(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,
701
- // Kindle Fire without Silk / Echo Show
702
- /(kf[a-z]+)( bui|\)).+silk\//i
703
- // Kindle Fire HD
704
- ],
705
- [u, [h, Ve], [c, A]],
706
- [
707
- /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i
708
- // Fire Phone
709
- ],
710
- [[u, /(.+)/g, "Fire Phone $1"], [h, Ve], [c, I]],
711
- [
712
- // BlackBerry
713
- /(playbook);[-\w\),; ]+(rim)/i
714
- // BlackBerry PlayBook
715
- ],
716
- [u, h, [c, A]],
717
- [
718
- /\b((?:bb[a-f]|st[hv])100-\d)/i,
719
- /(?:blackberry|\(bb10;) (\w+)/i
720
- ],
721
- [u, [h, Lt], [c, I]],
722
- [
723
- // Asus
724
- /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
725
- ],
726
- [u, [h, _t], [c, A]],
727
- [
728
- / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
729
- ],
730
- [u, [h, _t], [c, I]],
731
- [
732
- // HTC
733
- /(nexus 9)/i
734
- // HTC Nexus 9
735
- ],
736
- [u, [h, "HTC"], [c, A]],
737
- [
738
- /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,
739
- // HTC
740
- // ZTE
741
- /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
742
- /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i
743
- // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
744
- ],
745
- [h, [u, /_/g, " "], [c, I]],
746
- [
747
- // TCL
748
- /tcl (xess p17aa)/i,
749
- /droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
750
- ],
751
- [u, [h, "TCL"], [c, A]],
752
- [
753
- /droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
754
- ],
755
- [u, [h, "TCL"], [c, I]],
756
- [
757
- // itel
758
- /(itel) ((\w+))/i
759
- ],
760
- [[h, ie], u, [c, G, { tablet: ["p10001l", "w7001"], "*": "mobile" }]],
761
- [
762
- // Acer
763
- /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
764
- ],
765
- [u, [h, "Acer"], [c, A]],
766
- [
767
- // Meizu
768
- /droid.+; (m[1-5] note) bui/i,
769
- /\bmz-([-\w]{2,})/i
770
- ],
771
- [u, [h, "Meizu"], [c, I]],
772
- [
773
- // Ulefone
774
- /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
775
- ],
776
- [u, [h, "Ulefone"], [c, I]],
777
- [
778
- // Energizer
779
- /; (energy ?\w+)(?: bui|\))/i,
780
- /; energizer ([\w ]+)(?: bui|\))/i
781
- ],
782
- [u, [h, "Energizer"], [c, I]],
783
- [
784
- // Cat
785
- /; cat (b35);/i,
786
- /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
787
- ],
788
- [u, [h, "Cat"], [c, I]],
789
- [
790
- // Smartfren
791
- /((?:new )?andromax[\w- ]+)(?: bui|\))/i
792
- ],
793
- [u, [h, "Smartfren"], [c, I]],
794
- [
795
- // Nothing
796
- /droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i
797
- ],
798
- [u, [h, "Nothing"], [c, I]],
799
- [
800
- // Archos
801
- /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,
802
- /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i
803
- ],
804
- [u, [h, "Archos"], [c, A]],
805
- [
806
- /archos ([\w ]+)( b|\))/i,
807
- /; (ac[3-6]\d\w{2,8})( b|\))/i
808
- ],
809
- [u, [h, "Archos"], [c, I]],
810
- [
811
- // HMD
812
- /; (n159v)/i
813
- ],
814
- [u, [h, "HMD"], [c, I]],
815
- [
816
- // MIXED
817
- /(imo) (tab \w+)/i,
818
- // IMO
819
- /(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i
820
- // Infinix XPad / Tecno
821
- ],
822
- [h, u, [c, A]],
823
- [
824
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
825
- // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
826
- // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
827
- /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,
828
- /(hp) ([\w ]+\w)/i,
829
- // HP iPAQ
830
- /(microsoft); (lumia[\w ]+)/i,
831
- // Microsoft Lumia
832
- /(oppo) ?([\w ]+) bui/i,
833
- // OPPO
834
- /(hisense) ([ehv][\w ]+)\)/i,
835
- // Hisense
836
- /droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i
837
- // Philips
838
- ],
839
- [h, u, [c, I]],
840
- [
841
- /(kobo)\s(ereader|touch)/i,
842
- // Kobo
843
- /(hp).+(touchpad(?!.+tablet)|tablet)/i,
844
- // HP TouchPad
845
- /(kindle)\/([\w\.]+)/i
846
- // Kindle
847
- ],
848
- [h, u, [c, A]],
849
- [
850
- /(surface duo)/i
851
- // Surface Duo
852
- ],
853
- [u, [h, st], [c, A]],
854
- [
855
- /droid [\d\.]+; (fp\du?)(?: b|\))/i
856
- // Fairphone
857
- ],
858
- [u, [h, "Fairphone"], [c, I]],
859
- [
860
- /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i
861
- // Nvidia Tablets
862
- ],
863
- [u, [h, Bt], [c, A]],
864
- [
865
- /(sprint) (\w+)/i
866
- // Sprint Phones
867
- ],
868
- [h, u, [c, I]],
869
- [
870
- /(kin\.[onetw]{3})/i
871
- // Microsoft Kin
872
- ],
873
- [[u, /\./g, " "], [h, st], [c, I]],
874
- [
875
- /droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i
876
- // Zebra
877
- ],
878
- [u, [h, dt], [c, A]],
879
- [
880
- /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
881
- ],
882
- [u, [h, dt], [c, I]],
883
- [
884
- ///////////////////
885
- // SMARTTVS
886
- ///////////////////
887
- /(philips)[\w ]+tv/i,
888
- // Philips
889
- /smart-tv.+(samsung)/i
890
- // Samsung
891
- ],
892
- [h, [c, _]],
893
- [
894
- /hbbtv.+maple;(\d+)/i
895
- ],
896
- [[u, /^/, "SmartTV"], [h, ke], [c, _]],
897
- [
898
- /(vizio)(?: |.+model\/)(\w+-\w+)/i,
899
- // Vizio
900
- /tcast.+(lg)e?. ([-\w]+)/i
901
- // LG SmartTV
902
- ],
903
- [h, u, [c, _]],
904
- [
905
- /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
906
- ],
907
- [[h, $e], [c, _]],
908
- [
909
- /(apple) ?tv/i
910
- // Apple TV
911
- ],
912
- [h, [u, me + " TV"], [c, _]],
913
- [
914
- /crkey.*devicetype\/chromecast/i
915
- // Google Chromecast Third Generation
916
- ],
917
- [[u, ne + " Third Generation"], [h, le], [c, _]],
918
- [
919
- /crkey.*devicetype\/([^/]*)/i
920
- // Google Chromecast with specific device type
921
- ],
922
- [[u, /^/, "Chromecast "], [h, le], [c, _]],
923
- [
924
- /fuchsia.*crkey/i
925
- // Google Chromecast Nest Hub
926
- ],
927
- [[u, ne + " Nest Hub"], [h, le], [c, _]],
928
- [
929
- /crkey/i
930
- // Google Chromecast, Linux-based or unknown
931
- ],
932
- [[u, ne], [h, le], [c, _]],
933
- [
934
- /(portaltv)/i
935
- // Facebook Portal TV
936
- ],
937
- [u, [h, ut], [c, _]],
938
- [
939
- /droid.+aft(\w+)( bui|\))/i
940
- // Fire TV
941
- ],
942
- [u, [h, Ve], [c, _]],
943
- [
944
- /(shield \w+ tv)/i
945
- // Nvidia Shield TV
946
- ],
947
- [u, [h, Bt], [c, _]],
948
- [
949
- /\(dtv[\);].+(aquos)/i,
950
- /(aquos-tv[\w ]+)\)/i
951
- // Sharp
952
- ],
953
- [u, [h, Ht], [c, _]],
954
- [
955
- /(bravia[\w ]+)( bui|\))/i
956
- // Sony
957
- ],
958
- [u, [h, Ee], [c, _]],
959
- [
960
- /(mi(tv|box)-?\w+) bui/i
961
- // Xiaomi
962
- ],
963
- [u, [h, ct], [c, _]],
964
- [
965
- /Hbbtv.*(technisat) (.*);/i
966
- // TechniSAT
967
- ],
968
- [h, u, [c, _]],
969
- [
970
- /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,
971
- // Roku
972
- /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i
973
- // HbbTV devices
974
- ],
975
- [[h, /.+\/(\w+)/, "$1", G, { LG: "lge" }], [u, Xe], [c, _]],
976
- [
977
- ///////////////////
978
- // CONSOLES
979
- ///////////////////
980
- /(playstation \w+)/i
981
- // Playstation
982
- ],
983
- [u, [h, Ee], [c, qe]],
984
- [
985
- /\b(xbox(?: one)?(?!; xbox))[\); ]/i
986
- // Microsoft Xbox
987
- ],
988
- [u, [h, st], [c, qe]],
989
- [
990
- /(ouya)/i,
991
- // Ouya
992
- /(nintendo) (\w+)/i,
993
- // Nintendo
994
- /(retroid) (pocket ([^\)]+))/i,
995
- // Retroid Pocket
996
- /(valve).+(steam deck)/i,
997
- /droid.+; ((shield|rgcube|gr0006))( bui|\))/i
998
- // Nvidia Portable/Anbernic/Logitech
999
- ],
1000
- [[h, G, { Nvidia: "Shield", Anbernic: "RGCUBE", Logitech: "GR0006" }], u, [c, qe]],
1001
- [
1002
- ///////////////////
1003
- // WEARABLES
1004
- ///////////////////
1005
- /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i
1006
- // Samsung Galaxy Watch
1007
- ],
1008
- [u, [h, ke], [c, Y]],
1009
- [
1010
- /((pebble))app/i,
1011
- // Pebble
1012
- /(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i
1013
- // Asus ZenWatch / LG Watch / Pixel Watch / Xiaomi Watch
1014
- ],
1015
- [h, u, [c, Y]],
1016
- [
1017
- /(ow(?:19|20)?we?[1-3]{1,3})/i
1018
- // Oppo Watch
1019
- ],
1020
- [u, [h, lt], [c, Y]],
1021
- [
1022
- /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i
1023
- // Apple Watch
1024
- ],
1025
- [u, [h, me], [c, Y]],
1026
- [
1027
- /(opwwe\d{3})/i
1028
- // OnePlus Watch
1029
- ],
1030
- [u, [h, Pt], [c, Y]],
1031
- [
1032
- /(moto 360)/i
1033
- // Motorola 360
1034
- ],
1035
- [u, [h, at], [c, Y]],
1036
- [
1037
- /(smartwatch 3)/i
1038
- // Sony SmartWatch
1039
- ],
1040
- [u, [h, Ee], [c, Y]],
1041
- [
1042
- /(g watch r)/i
1043
- // LG G Watch R
1044
- ],
1045
- [u, [h, $e], [c, Y]],
1046
- [
1047
- /droid.+; (wt63?0{2,3})\)/i
1048
- ],
1049
- [u, [h, dt], [c, Y]],
1050
- [
1051
- ///////////////////
1052
- // XR
1053
- ///////////////////
1054
- /droid.+; (glass) \d/i
1055
- // Google Glass
1056
- ],
1057
- [u, [h, le], [c, He]],
1058
- [
1059
- /(pico) ([\w ]+) os\d/i
1060
- // Pico
1061
- ],
1062
- [h, u, [c, He]],
1063
- [
1064
- /(quest( \d| pro)?s?).+vr/i
1065
- // Meta Quest
1066
- ],
1067
- [u, [h, ut], [c, He]],
1068
- [
1069
- /mobile vr; rv.+firefox/i
1070
- // Unidentifiable VR device using Firefox Reality / Wolvic
1071
- ],
1072
- [[c, He]],
1073
- [
1074
- ///////////////////
1075
- // EMBEDDED
1076
- ///////////////////
1077
- /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i
1078
- // Tesla
1079
- ],
1080
- [h, [c, Me]],
1081
- [
1082
- /(aeobc)\b/i
1083
- // Echo Dot
1084
- ],
1085
- [u, [h, Ve], [c, Me]],
1086
- [
1087
- /(homepod).+mac os/i
1088
- // Apple HomePod
1089
- ],
1090
- [u, [h, me], [c, Me]],
1091
- [
1092
- /windows iot/i
1093
- // Unidentifiable embedded device using Windows IoT
1094
- ],
1095
- [[c, Me]],
1096
- [
1097
- ////////////////////
1098
- // MIXED (GENERIC)
1099
- ///////////////////
1100
- /droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i
1101
- // Unidentifiable SmartTV
1102
- ],
1103
- [u, [c, _]],
1104
- [
1105
- /\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
1106
- ],
1107
- [[c, _]],
1108
- [
1109
- /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i
1110
- ],
1111
- [u, [c, G, { mobile: "Mobile", xr: "VR", "*": A }]],
1112
- [
1113
- /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i
1114
- // Unidentifiable Tablet
1115
- ],
1116
- [[c, A]],
1117
- [
1118
- /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i
1119
- // Unidentifiable Mobile
1120
- ],
1121
- [[c, I]],
1122
- [
1123
- /droid .+?; ([\w\. -]+)( bui|\))/i
1124
- // Generic Android Device
1125
- ],
1126
- [u, [h, "Generic"]]
1127
- ],
1128
- engine: [
1129
- [
1130
- /windows.+ edge\/([\w\.]+)/i
1131
- // EdgeHTML
1132
- ],
1133
- [p, [f, je + "HTML"]],
1134
- [
1135
- /(arkweb)\/([\w\.]+)/i
1136
- // ArkWeb
1137
- ],
1138
- [f, p],
1139
- [
1140
- /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i
1141
- // Blink
1142
- ],
1143
- [p, [f, "Blink"]],
1144
- [
1145
- /(presto)\/([\w\.]+)/i,
1146
- // Presto
1147
- /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,
1148
- // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
1149
- /ekioh(flow)\/([\w\.]+)/i,
1150
- // Flow
1151
- /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
1152
- // KHTML/Tasman/Links
1153
- /(icab)[\/ ]([23]\.[\d\.]+)/i,
1154
- // iCab
1155
- /\b(libweb)/i
1156
- // LibWeb
1157
- ],
1158
- [f, p],
1159
- [
1160
- /ladybird\//i
1161
- ],
1162
- [[f, "LibWeb"]],
1163
- [
1164
- /rv\:([\w\.]{1,9})\b.+(gecko)/i
1165
- // Gecko
1166
- ],
1167
- [p, f]
1168
- ],
1169
- os: [
1170
- [
1171
- // Windows
1172
- /(windows nt) (6\.[23]); arm/i
1173
- // Windows RT
1174
- ],
1175
- [[f, /N/, "R"], [p, G, qt]],
1176
- [
1177
- /(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,
1178
- // Windows IoT/Mobile/Phone
1179
- // Windows NT/3.1/95/98/ME/2000/XP/Vista/7/8/8.1/10/11
1180
- /(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i
1181
- ],
1182
- [f, p],
1183
- [
1184
- /windows nt ?([\d\.\)]*)(?!.+xbox)/i,
1185
- /\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i
1186
- ],
1187
- [[p, /(;|\))/g, "", G, qt], [f, pt]],
1188
- [
1189
- /(windows ce)\/?([\d\.]*)/i
1190
- // Windows CE
1191
- ],
1192
- [f, p],
1193
- [
1194
- // iOS/macOS
1195
- /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,
1196
- // iOS
1197
- /(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,
1198
- /\btvos ?([\w\.]+)/i,
1199
- /cfnetwork\/.+darwin/i
1200
- ],
1201
- [[p, /_/g, "."], [f, "iOS"]],
1202
- [
1203
- /(mac os x) ?([\w\. ]*)/i,
1204
- /(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i
1205
- // Mac OS
1206
- ],
1207
- [[f, "macOS"], [p, /_/g, "."]],
1208
- [
1209
- // Google Chromecast
1210
- /android ([\d\.]+).*crkey/i
1211
- // Google Chromecast, Android-based
1212
- ],
1213
- [p, [f, ne + " Android"]],
1214
- [
1215
- /fuchsia.*crkey\/([\d\.]+)/i
1216
- // Google Chromecast, Fuchsia-based
1217
- ],
1218
- [p, [f, ne + " Fuchsia"]],
1219
- [
1220
- /crkey\/([\d\.]+).*devicetype\/smartspeaker/i
1221
- // Google Chromecast, Linux-based Smart Speaker
1222
- ],
1223
- [p, [f, ne + " SmartSpeaker"]],
1224
- [
1225
- /linux.*crkey\/([\d\.]+)/i
1226
- // Google Chromecast, Legacy Linux-based
1227
- ],
1228
- [p, [f, ne + " Linux"]],
1229
- [
1230
- /crkey\/([\d\.]+)/i
1231
- // Google Chromecast, unknown
1232
- ],
1233
- [p, [f, ne]],
1234
- [
1235
- // Mobile OSes
1236
- /droid ([\w\.]+)\b.+(android[- ]x86)/i
1237
- // Android-x86
1238
- ],
1239
- [p, f],
1240
- [
1241
- /(ubuntu) ([\w\.]+) like android/i
1242
- // Ubuntu Touch
1243
- ],
1244
- [[f, /(.+)/, "$1 Touch"], p],
1245
- [
1246
- /(harmonyos)[\/ ]?([\d\.]*)/i,
1247
- // HarmonyOS
1248
- // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen
1249
- /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i
1250
- ],
1251
- [f, p],
1252
- [
1253
- /\(bb(10);/i
1254
- // BlackBerry 10
1255
- ],
1256
- [p, [f, Lt]],
1257
- [
1258
- /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i
1259
- // Symbian
1260
- ],
1261
- [p, [f, "Symbian"]],
1262
- [
1263
- /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i
1264
- // Firefox OS
1265
- ],
1266
- [p, [f, Te + " OS"]],
1267
- [
1268
- /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,
1269
- // WebOS
1270
- /webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i
1271
- ],
1272
- [p, [f, "webOS"]],
1273
- [
1274
- /web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
1275
- // https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
1276
- ],
1277
- [[p, G, { 25: "120", 24: "108", 23: "94", 22: "87", 6: "79", 5: "68", 4: "53", 3: "38", 2: "538", 1: "537", "*": "TV" }], [f, "webOS"]],
1278
- [
1279
- /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i
1280
- // watchOS
1281
- ],
1282
- [p, [f, "watchOS"]],
1283
- [
1284
- // Google ChromeOS
1285
- /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i
1286
- // Chromium OS
1287
- ],
1288
- [[f, "Chrome OS"], p],
1289
- [
1290
- // Smart TVs
1291
- /panasonic;(viera)/i,
1292
- // Panasonic Viera
1293
- /(netrange)mmh/i,
1294
- // Netrange
1295
- /(nettv)\/(\d+\.[\w\.]+)/i,
1296
- // NetTV
1297
- // Console
1298
- /(nintendo|playstation) (\w+)/i,
1299
- // Nintendo/Playstation
1300
- /(xbox); +xbox ([^\);]+)/i,
1301
- // Microsoft Xbox (360, One, X, S, Series X, Series S)
1302
- /(pico) .+os([\w\.]+)/i,
1303
- // Pico
1304
- // Other
1305
- /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
1306
- // Joli/Palm
1307
- /linux.+(mint)[\/\(\) ]?([\w\.]*)/i,
1308
- // Mint
1309
- /(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,
1310
- // Mageia/VectorLinux/Fuchsia/ArcaOS/Arch
1311
- /([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
1312
- // Ubuntu/Debian/SUSE/Gentoo/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire/Knoppix
1313
- /((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
1314
- // Solaris
1315
- /\b(aix)[; ]([1-9\.]{0,4})/i,
1316
- // AIX
1317
- /(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,
1318
- // Hurd/Linux/MorphOS
1319
- /(gnu) ?([\w\.]*)/i,
1320
- // GNU
1321
- /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
1322
- // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
1323
- /(haiku) ?(r\d)?/i
1324
- // Haiku
1325
- ],
1326
- [f, p],
1327
- [
1328
- /(sunos) ?([\d\.]*)/i
1329
- // Solaris
1330
- ],
1331
- [[f, "Solaris"], p],
1332
- [
1333
- /\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,
1334
- // BeOS/OS2/AmigaOS/OpenVMS/HP-UX/SerenityOS
1335
- /(unix) ?([\w\.]*)/i
1336
- // UNIX
1337
- ],
1338
- [f, p]
1339
- ]
1340
- }, We = (function() {
1341
- var e = { init: {}, isIgnore: {}, isIgnoreRgx: {}, toString: {} };
1342
- return Z.call(e.init, [
1343
- [$, [f, p, Oe, c]],
1344
- [ee, [P]],
1345
- [J, [c, u, h]],
1346
- [X, [f, p]],
1347
- [W, [f, p]]
1348
- ]), Z.call(e.isIgnore, [
1349
- [$, [p, Oe]],
1350
- [X, [p]],
1351
- [W, [p]]
1352
- ]), Z.call(e.isIgnoreRgx, [
1353
- [$, / ?browser$/i],
1354
- [W, / ?os$/i]
1355
- ]), Z.call(e.toString, [
1356
- [$, [f, p]],
1357
- [ee, [P]],
1358
- [J, [h, u]],
1359
- [X, [f, p]],
1360
- [W, [f, p]]
1361
- ]), e;
1362
- })(), ei = function(e, n) {
1363
- var t = We.init[n], i = We.isIgnore[n] || 0, s = We.isIgnoreRgx[n] || 0, o = We.toString[n] || 0;
1364
- function r() {
1365
- Z.call(this, t);
1366
- }
1367
- return r.prototype.getItem = function() {
1368
- return e;
1369
- }, r.prototype.withClientHints = function() {
1370
- return ue ? ue.getHighEntropyValues(cn).then(function(a) {
1371
- return e.setCH(new dn(a, !1)).parseCH().get();
1372
- }) : e.parseCH().get();
1373
- }, r.prototype.withFeatureCheck = function() {
1374
- return e.detectFeature().get();
1375
- }, n != ve && (r.prototype.is = function(a) {
1376
- var d = !1;
1377
- for (var g in this)
1378
- if (this.hasOwnProperty(g) && !mt(i, g) && ie(s ? Ce(s, this[g]) : this[g]) == ie(s ? Ce(s, a) : a)) {
1379
- if (d = !0, a != O.UNDEFINED) break;
1380
- } else if (a == O.UNDEFINED && d) {
1381
- d = !d;
1382
- break;
1383
- }
1384
- return d;
1385
- }, r.prototype.toString = function() {
1386
- var a = ye;
1387
- for (var d in o)
1388
- typeof this[o[d]] !== O.UNDEFINED && (a += (a ? " " : ye) + this[o[d]]);
1389
- return a || O.UNDEFINED;
1390
- }), r.prototype.then = function(a) {
1391
- var d = this, g = function() {
1392
- for (var m in d)
1393
- d.hasOwnProperty(m) && (this[m] = d[m]);
1394
- };
1395
- g.prototype = {
1396
- is: r.prototype.is,
1397
- toString: r.prototype.toString,
1398
- withClientHints: r.prototype.withClientHints,
1399
- withFeatureCheck: r.prototype.withFeatureCheck
1400
- };
1401
- var l = new g();
1402
- return a(l), l;
1403
- }, new r();
1404
- };
1405
- function dn(e, n) {
1406
- if (e = e || {}, Z.call(this, cn), n)
1407
- Z.call(this, [
1408
- [vt, ft(e[se])],
1409
- [xt, ft(e[Wn])],
1410
- [I, /\?1/.test(e[Xn])],
1411
- [u, Ae(e[Yn])],
1412
- [xe, Ae(e[ln])],
1413
- [Ct, Ae(e[Jn])],
1414
- [P, Ae(e[qn])],
1415
- [de, ft(e[Gn])],
1416
- [Je, Ae(e[jn])]
1417
- ]);
1418
- else
1419
- for (var t in e)
1420
- this.hasOwnProperty(t) && typeof e[t] !== O.UNDEFINED && (this[t] = e[t]);
1421
- }
1422
- function re(e, n, t, i) {
1423
- return Z.call(this, [
1424
- ["itemType", e],
1425
- ["ua", n],
1426
- ["uaCH", i],
1427
- ["rgxMap", t],
1428
- ["data", ei(this, e)]
1429
- ]), this;
1430
- }
1431
- re.prototype.get = function(e) {
1432
- return e ? this.data.hasOwnProperty(e) ? this.data[e] : void 0 : this.data;
1433
- };
1434
- re.prototype.set = function(e, n) {
1435
- return this.data[e] = n, this;
1436
- };
1437
- re.prototype.setCH = function(e) {
1438
- return this.uaCH = e, this;
1439
- };
1440
- re.prototype.detectFeature = function() {
1441
- if (V && V.userAgent == this.ua)
1442
- switch (this.itemType) {
1443
- case $:
1444
- V.brave && typeof V.brave.isBrave == O.FUNCTION && this.set(f, "Brave");
1445
- break;
1446
- case J:
1447
- !this.get(c) && ue && ue[I] && this.set(c, I), this.get(u) == "Macintosh" && V && typeof V.standalone !== O.UNDEFINED && V.maxTouchPoints && V.maxTouchPoints > 2 && this.set(u, "iPad").set(c, A);
1448
- break;
1449
- case W:
1450
- !this.get(f) && ue && ue[xe] && this.set(f, ue[xe]);
1451
- break;
1452
- case ve:
1453
- var e = this.data, n = function(t) {
1454
- return e[t].getItem().detectFeature().get();
1455
- };
1456
- this.set($, n($)).set(ee, n(ee)).set(J, n(J)).set(X, n(X)).set(W, n(W));
1457
- }
1458
- return this;
1459
- };
1460
- re.prototype.parseUA = function() {
1461
- switch (this.itemType != ve && bt.call(this.data, this.ua, this.rgxMap), this.itemType) {
1462
- case $:
1463
- this.set(Oe, wt(this.get(p)));
1464
- break;
1465
- case W:
1466
- if (this.get(f) == "iOS" && this.get(p) == "18.6") {
1467
- var e = /\) Version\/([\d\.]+)/.exec(this.ua);
1468
- e && parseInt(e[1].substring(0, 2), 10) >= 26 && this.set(p, e[1]);
1469
- }
1470
- break;
1471
- }
1472
- return this;
1473
- };
1474
- re.prototype.parseCH = function() {
1475
- var e = this.uaCH, n = this.rgxMap;
1476
- switch (this.itemType) {
1477
- case $:
1478
- case X:
1479
- var t = e[xt] || e[vt], i;
1480
- if (t)
1481
- for (var s = 0; s < t.length; s++) {
1482
- var o = t[s].brand || t[s], r = t[s].version;
1483
- this.itemType == $ && !/not.a.brand/i.test(o) && (!i || /Chrom/.test(i) && o != $t || i == je && /WebView2/.test(o)) && (o = G(o, Zn), i = this.get(f), i && !/Chrom/.test(i) && /Chrom/.test(o) || this.set(f, o).set(p, r).set(Oe, wt(r)), i = o), this.itemType == X && o == $t && this.set(p, r);
1484
- }
1485
- break;
1486
- case ee:
1487
- var a = e[P];
1488
- a && (a && e[Je] == "64" && (a += "64"), bt.call(this.data, a + ";", n));
1489
- break;
1490
- case J:
1491
- if (e[I] && this.set(c, I), e[u] && (this.set(u, e[u]), !this.get(c) || !this.get(h))) {
1492
- var d = {};
1493
- bt.call(d, "droid 9; " + e[u] + ")", n), !this.get(c) && d.type && this.set(c, d.type), !this.get(h) && d.vendor && this.set(h, d.vendor);
1494
- }
1495
- if (e[de]) {
1496
- var g;
1497
- if (typeof e[de] != "string")
1498
- for (var l = 0; !g && l < e[de].length; )
1499
- g = G(e[de][l++], jt);
1500
- else
1501
- g = G(e[de], jt);
1502
- this.set(c, g);
1503
- }
1504
- break;
1505
- case W:
1506
- var m = e[xe];
1507
- if (m) {
1508
- var b = e[Ct];
1509
- m == pt && (b = parseInt(wt(b), 10) >= 13 ? "11" : "10"), this.set(f, m).set(p, b);
1510
- }
1511
- this.get(f) == pt && e[u] == "Xbox" && this.set(f, "Xbox").set(p, void 0);
1512
- break;
1513
- case ve:
1514
- var x = this.data, C = function(w) {
1515
- return x[w].getItem().setCH(e).parseCH().get();
1516
- };
1517
- this.set($, C($)).set(ee, C(ee)).set(J, C(J)).set(X, C(X)).set(W, C(W));
1518
- }
1519
- return this;
1520
- };
1521
- function te(e, n, t) {
1522
- if (typeof e === O.OBJECT ? (Ge(e, !0) ? (typeof n === O.OBJECT && (t = n), n = e) : (t = e, n = void 0), e = void 0) : typeof e === O.STRING && !Ge(n, !0) && (t = n, n = void 0), t)
1523
- if (typeof t.append === O.FUNCTION) {
1524
- var i = {};
1525
- t.forEach(function(l, m) {
1526
- i[String(m).toLowerCase()] = l;
1527
- }), t = i;
1528
- } else {
1529
- var s = {};
1530
- for (var o in t)
1531
- t.hasOwnProperty(o) && (s[String(o).toLowerCase()] = t[o]);
1532
- t = s;
1533
- }
1534
- if (!(this instanceof te))
1535
- return new te(e, n, t).getResult();
1536
- var r = typeof e === O.STRING ? e : (
1537
- // Passed user-agent string
1538
- t && t[Dt] ? t[Dt] : (
1539
- // User-Agent from passed headers
1540
- V && V.userAgent ? V.userAgent : (
1541
- // navigator.userAgent
1542
- ye
1543
- )
1544
- )
1545
- ), a = new dn(t, !0), d = n ? Kn(Gt, n) : Gt, g = function(l) {
1546
- return l == ve ? function() {
1547
- return new re(l, r, d, a).set("ua", r).set($, this.getBrowser()).set(ee, this.getCPU()).set(J, this.getDevice()).set(X, this.getEngine()).set(W, this.getOS()).get();
1548
- } : function() {
1549
- return new re(l, r, d[l], a).parseUA().get();
1550
- };
1551
- };
1552
- return Z.call(this, [
1553
- ["getBrowser", g($)],
1554
- ["getCPU", g(ee)],
1555
- ["getDevice", g(J)],
1556
- ["getEngine", g(X)],
1557
- ["getOS", g(W)],
1558
- ["getResult", g(ve)],
1559
- ["getUA", function() {
1560
- return r;
1561
- }],
1562
- ["setUA", function(l) {
1563
- return Le(l) && (r = Xe(l, $n)), this;
1564
- }]
1565
- ]).setUA(r), this;
1566
- }
1567
- te.VERSION = Vn;
1568
- te.BROWSER = Qe([f, p, Oe, c]);
1569
- te.CPU = Qe([P]);
1570
- te.DEVICE = Qe([u, h, c, qe, I, _, A, Y, Me]);
1571
- te.ENGINE = te.OS = Qe([f, p]);
1572
- const ti = () => {
1573
- const n = new te().getResult();
1574
- return {
1575
- os: n.os.name || "unknown",
1576
- osVersion: n.os.version || "unknown",
1577
- browser: n.browser.name || "unknown",
1578
- browserVersion: n.browser.version || "unknown",
1579
- deviceType: n.device.type || "desktop"
1580
- // Default to desktop if empty (common for desktop browsers)
1581
- };
1582
- };
1583
- function ni() {
1584
- const e = navigator.userAgent.toLowerCase(), n = /iphone|ipod|android.*mobile/.test(e), t = /ipad|android(?!.*mobile)/.test(e), s = (navigator.deviceMemory || 4) < 4;
1585
- return n ? {
1586
- maxCanvasSize: 4096,
1587
- recommendedScale: s ? 0.8 : 1,
1588
- recommendedQuality: s ? 0.7 : 0.8,
1589
- chunkSize: 30,
1590
- yieldInterval: 16,
1591
- // ~60fps
1592
- maxTimeout: 5e3
1593
- } : t ? {
1594
- maxCanvasSize: 8192,
1595
- recommendedScale: 1,
1596
- recommendedQuality: 0.85,
1597
- chunkSize: 50,
1598
- yieldInterval: 16,
1599
- maxTimeout: 4e3
1600
- } : {
1601
- maxCanvasSize: 16384,
1602
- recommendedScale: 1,
1603
- recommendedQuality: 0.9,
1604
- chunkSize: 100,
1605
- yieldInterval: 8,
1606
- maxTimeout: 3e3
1607
- };
1608
- }
1609
- function ii() {
1610
- return {
1611
- objectUrls: [],
1612
- tempCanvases: []
1613
- };
1614
- }
1615
- function ri(e) {
1616
- e.objectUrls.forEach((n) => {
1617
- try {
1618
- URL.revokeObjectURL(n);
1619
- } catch {
1620
- console.warn("[Screenshot] Failed to revoke URL:", n);
1621
- }
1622
- }), e.tempCanvases.forEach((n) => {
1623
- const t = n.getContext("2d");
1624
- t && t.clearRect(0, 0, n.width, n.height), n.width = 0, n.height = 0;
1625
- }), e.objectUrls.length = 0, e.tempCanvases.length = 0;
1626
- }
1627
- function oi(e, n, t, i) {
1628
- const s = () => t !== void 0 ? t : window.visualViewport ? window.visualViewport.width : document.documentElement.clientWidth || window.innerWidth, o = () => i !== void 0 ? i : window.visualViewport ? window.visualViewport.height : document.documentElement.clientHeight || window.innerHeight, r = e ? e.x : 0, a = e ? e.y : 0, d = e ? e.width : s(), g = e ? e.height : o(), l = {
1629
- left: r - n,
1630
- top: a - n,
1631
- right: r + d + n,
1632
- bottom: a + g + n
1633
- };
1634
- return console.log("[ElementCollector] calculateCaptureBounds:", {
1635
- viewportWidth: t || "auto",
1636
- viewportHeight: i || "auto",
1637
- targetWidth: d,
1638
- targetHeight: g,
1639
- bounds: l,
1640
- scroll: { x: window.scrollX, y: window.scrollY }
1641
- }), l;
1642
- }
1643
- function si(e, n) {
1644
- const t = e.getBoundingClientRect(), i = window.scrollX || window.pageXOffset, s = window.scrollY || window.pageYOffset, o = {
1645
- left: n.left - i,
1646
- top: n.top - s,
1647
- right: n.right - i,
1648
- bottom: n.bottom - s
1649
- };
1650
- return !(t.bottom < o.top || t.top > o.bottom || t.right < o.left || t.left > o.right || t.width === 0 || t.height === 0);
1651
- }
1652
- function ai(e) {
1653
- const n = Array.from(document.body.getElementsByTagName("*")), t = n.filter((i) => {
1654
- if (!(i instanceof HTMLElement)) return !1;
1655
- const s = i.tagName;
1656
- return ["SCRIPT", "STYLE", "LINK", "IFRAME", "NOSCRIPT"].includes(s) ? !1 : s === "HTML" || s === "BODY" ? !0 : si(i, e);
1657
- });
1658
- return console.log("[ElementCollector] collectVisibleElements:", {
1659
- total: n.length,
1660
- filtered: t.length,
1661
- bounds: e,
1662
- sampleElements: t.slice(0, 5).map((i) => ({
1663
- tag: i.tagName,
1664
- rect: i.getBoundingClientRect()
1665
- }))
1666
- }), t;
1667
- }
1668
- function li(e) {
1669
- const n = e.getElementsByTagName("*"), t = e.getElementsByTagName("img"), i = e.getElementsByTagName("svg"), s = n.length, o = t.length, r = i.length, a = s > 1e3 || o > 50 || r > 10;
1670
- return { nodeCount: s, imageCount: o, svgCount: r, isComplex: a };
1671
- }
1672
- function ce() {
1673
- return new Promise((e) => {
1674
- "scheduler" in window && "yield" in window.scheduler ? window.scheduler.yield().then(e) : setTimeout(e, 0);
1675
- });
1676
- }
1677
- function ci(e, n, t) {
1678
- return new Promise((i, s) => {
1679
- const o = setTimeout(() => {
1680
- s(new Error("Image load timeout"));
1681
- }, t);
1682
- e.onload = () => {
1683
- clearTimeout(o), i();
1684
- }, e.onerror = () => {
1685
- clearTimeout(o), s(new Error("Image load error"));
1686
- }, e.src = n;
1687
- });
1688
- }
1689
- async function di(e, n) {
1690
- const t = e.getBoundingClientRect(), i = window.getComputedStyle(e), s = t.left, o = t.top, r = t.width, a = t.height, d = i.backgroundColor;
1691
- d && d !== "transparent" && d !== "rgba(0, 0, 0, 0)" && (n.fillStyle = d, n.fillRect(s, o, r, a));
1692
- const g = parseFloat(i.borderWidth) || 0;
1693
- if (g > 0) {
1694
- const l = i.borderColor;
1695
- l && l !== "transparent" && (n.strokeStyle = l, n.lineWidth = g, n.strokeRect(s, o, r, a));
1696
- }
1697
- }
1698
- async function Xt(e, n) {
1699
- for (const t of e)
1700
- t instanceof HTMLElement && await di(t, n);
1701
- }
1702
- async function ui(e, n, t, i, s, o) {
1703
- try {
1704
- const r = new Image();
1705
- return r.crossOrigin = "anonymous", await ci(r, e.src, 3e3), n.drawImage(r, t, i, s, o), { success: !0, method: "canvas" };
1706
- } catch (r) {
1707
- return {
1708
- success: !1,
1709
- error: r instanceof Error ? r.message : "Canvas render failed"
1710
- };
1711
- }
1712
- }
1713
- function fi(e, n, t, i, s) {
1714
- return e.fillStyle = "#f0f0f0", e.fillRect(n, t, i, s), e.strokeStyle = "#ccc", e.lineWidth = 1, e.strokeRect(n, t, i, s), e.fillStyle = "#999", e.font = "12px sans-serif", e.textAlign = "center", e.textBaseline = "middle", e.fillText("Image", n + i / 2, t + s / 2), { success: !0, method: "placeholder" };
1715
- }
1716
- function gi(e, n) {
1717
- return e < 5 || n < 5;
1718
- }
1719
- async function hi(e, n) {
1720
- const t = e.getBoundingClientRect(), i = t.left, s = t.top, o = t.width, r = t.height;
1721
- if (gi(o, r))
1722
- return { success: !0, method: "skip" };
1723
- const a = await ui(e, n, i, s, o, r);
1724
- return a.success ? a : fi(n, i, s, o, r);
1725
- }
1726
- async function Yt(e, n, t) {
1727
- for (let i = 0; i < e.length; i++)
1728
- await hi(e[i], n), t && t(i + 1, e.length);
1729
- }
1730
- function pi(e) {
1731
- const n = [];
1732
- for (const t of e)
1733
- t instanceof HTMLImageElement && t.src && n.push(t);
1734
- return n;
1735
- }
1736
- function mi(e) {
1737
- let t = new XMLSerializer().serializeToString(e);
1738
- return t.includes("xmlns=") || (t = t.replace(
1739
- "<svg",
1740
- '<svg xmlns="http://www.w3.org/2000/svg"'
1741
- )), t;
1742
- }
1743
- function wi(e) {
1744
- return !!(e.includes('xlink:href="http') || e.includes('href="http') || e.includes("@font-face") && e.includes("url(http"));
1745
- }
1746
- async function bi(e, n) {
1747
- try {
1748
- const t = e.getBoundingClientRect(), i = t.left, s = t.top, o = t.width, r = t.height;
1749
- if (o < 1 || r < 1)
1750
- return { success: !0 };
1751
- const a = mi(e);
1752
- if (wi(a))
1753
- return console.warn("[SVG] Skipping SVG with external resources to prevent canvas tainting"), { success: !0 };
1754
- const d = new Blob([a], { type: "image/svg+xml;charset=utf-8" }), g = URL.createObjectURL(d);
1755
- try {
1756
- const l = new Image();
1757
- return await new Promise((m, b) => {
1758
- l.onload = () => m(), l.onerror = () => b(new Error("SVG image load failed")), l.src = g;
1759
- }), n.drawImage(l, i, s, o, r), { success: !0 };
1760
- } finally {
1761
- URL.revokeObjectURL(g);
1762
- }
1763
- } catch (t) {
1764
- return {
1765
- success: !1,
1766
- error: t instanceof Error ? t.message : "SVG render failed"
1767
- };
1768
- }
1769
- }
1770
- async function Jt(e, n, t) {
1771
- for (let i = 0; i < e.length; i++)
1772
- await bi(e[i], n), t && t(i + 1, e.length);
1773
- }
1774
- function yi(e) {
1775
- return e.classList.contains("MathJax") || e.classList.contains("MathJax_Display") || e.classList.contains("MJX-TeXAtom-ORD") || e.hasAttribute("data-mathml");
1776
- }
1777
- function vi(e) {
1778
- const n = [];
1779
- for (const t of e)
1780
- t instanceof SVGElement && n.push(t);
1781
- return n;
1782
- }
1783
- function xi(e) {
1784
- return e.filter((n) => yi(n));
1785
- }
1786
- async function Ci(e, n) {
1787
- try {
1788
- const t = e.getBoundingClientRect(), i = t.left, s = t.top, o = t.width, r = t.height;
1789
- if (o < 1 || r < 1)
1790
- return { success: !0 };
1791
- const a = window.getComputedStyle(e), d = e.cloneNode(!0), g = [
1792
- "color",
1793
- "font-family",
1794
- "font-size",
1795
- "font-weight",
1796
- "font-style",
1797
- "line-height",
1798
- "text-align",
1799
- "text-decoration",
1800
- "text-transform",
1801
- "letter-spacing",
1802
- "word-spacing",
1803
- "white-space",
1804
- "padding",
1805
- "margin",
1806
- "display",
1807
- "flex-direction",
1808
- "align-items",
1809
- "justify-content"
1810
- ];
1811
- let l = "";
1812
- g.forEach((C) => {
1813
- const w = a.getPropertyValue(C);
1814
- w && (l += `${C}: ${w}; `);
1815
- }), d.setAttribute("style", l);
1816
- const m = `
1817
- <svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${r}">
1818
- <foreignObject width="100%" height="100%">
1819
- <div xmlns="http://www.w3.org/1999/xhtml" style="width: ${o}px; height: ${r}px; overflow: hidden;">
1820
- ${d.outerHTML}
1821
- </div>
1822
- </foreignObject>
1823
- </svg>
1824
- `, b = new Blob([m], { type: "image/svg+xml;charset=utf-8" }), x = URL.createObjectURL(b);
1825
- try {
1826
- const C = new Image();
1827
- return await new Promise((w, E) => {
1828
- const y = setTimeout(() => {
1829
- E(new Error("Text element render timeout"));
1830
- }, 1e3);
1831
- C.onload = () => {
1832
- clearTimeout(y), w();
1833
- }, C.onerror = () => {
1834
- clearTimeout(y), E(new Error("Text element image load failed"));
1835
- }, C.src = x;
1836
- }), n.drawImage(C, i, s, o, r), { success: !0 };
1837
- } finally {
1838
- URL.revokeObjectURL(x);
1839
- }
1840
- } catch (t) {
1841
- return console.warn("[TextRenderer] Failed to render text element:", t), {
1842
- success: !1,
1843
- error: t instanceof Error ? t.message : "Text render failed"
1844
- };
1845
- }
1846
- }
1847
- function Si(e) {
1848
- const n = window.getComputedStyle(e);
1849
- if (n.display === "none" || n.visibility === "hidden")
1850
- return !1;
1851
- const t = e.textContent?.trim();
1852
- return !(!t || t.length === 0);
1853
- }
1854
- function ki(e) {
1855
- const n = [];
1856
- for (const t of e) {
1857
- if (!(t instanceof HTMLElement)) continue;
1858
- const i = t.tagName;
1859
- if (["IMG", "SVG", "CANVAS", "VIDEO", "IFRAME", "SCRIPT", "STYLE", "NOSCRIPT"].includes(i))
1860
- continue;
1861
- [
1862
- "P",
1863
- "SPAN",
1864
- "DIV",
1865
- "A",
1866
- "BUTTON",
1867
- "LABEL",
1868
- "LI",
1869
- "H1",
1870
- "H2",
1871
- "H3",
1872
- "H4",
1873
- "H5",
1874
- "H6",
1875
- "TD",
1876
- "TH",
1877
- "STRONG",
1878
- "EM",
1879
- "B",
1880
- "I",
1881
- "U",
1882
- "CODE",
1883
- "PRE",
1884
- "BLOCKQUOTE"
1885
- ].includes(i) && Si(t) && (Array.from(t.children).some((r) => {
1886
- const a = r.tagName;
1887
- return ["DIV", "P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "TABLE"].includes(a);
1888
- }) || n.push(t));
1889
- }
1890
- return n;
1891
- }
1892
- async function Ei(e, n, t) {
1893
- const i = ki(e);
1894
- console.log("[TextRenderer] Rendering", i.length, "text elements");
1895
- for (let s = 0; s < i.length; s++) {
1896
- const o = await Ci(i[s], n);
1897
- o.success || console.warn("[TextRenderer] Failed to render element:", i[s], o.error), t && t(s + 1, i.length);
1898
- }
1899
- }
1900
- async function Ti(e, n, t) {
1901
- const i = ii();
1902
- try {
1903
- const s = ni(), o = n.quality ?? s.recommendedQuality, r = n.scale ?? s.recommendedScale, a = n.includeMathJax ?? !0;
1904
- t?.({
1905
- phase: "analyzing",
1906
- progress: 10,
1907
- message: "Analyzing DOM structure..."
1908
- });
1909
- const d = document.documentElement, g = li(d);
1910
- console.log("[Canvas] DOM complexity:", g);
1911
- let l = o;
1912
- g.isComplex && (l = Math.max(0.6, o - 0.1), console.log("[Canvas] Complex DOM detected, reducing quality to", l));
1913
- const m = () => window.visualViewport ? window.visualViewport.width : document.documentElement.clientWidth || window.innerWidth, b = () => window.visualViewport ? window.visualViewport.height : document.documentElement.clientHeight || window.innerHeight, x = e ? e.x : 0, C = e ? e.y : 0, w = e ? e.width : m(), E = e ? e.height : b();
1914
- let y = r;
1915
- (w * y > s.maxCanvasSize || E * y > s.maxCanvasSize) && (console.warn("[Canvas] Size exceeds device limits, reducing scale"), y = Math.min(
1916
- s.maxCanvasSize / w,
1917
- s.maxCanvasSize / E,
1918
- y
1919
- ));
1920
- const T = document.createElement("canvas");
1921
- T.width = w * y, T.height = E * y, i.tempCanvases.push(T);
1922
- const S = T.getContext("2d", {
1923
- alpha: !1,
1924
- willReadFrequently: !1
1925
- });
1926
- if (!S)
1927
- throw new Error("Failed to get canvas context");
1928
- S.scale(y, y), S.fillStyle = "#ffffff", S.fillRect(0, 0, w, E), t?.({
1929
- phase: "analyzing",
1930
- progress: 20,
1931
- message: "Collecting visible elements..."
1932
- });
1933
- const D = oi(
1934
- e,
1935
- s.maxCanvasSize > 8192 ? 500 : 300,
1936
- // Buffer based on device
1937
- w,
1938
- E
1939
- ), F = ai(D);
1940
- console.log("[Canvas] Visible elements:", F.length);
1941
- const z = pi(F), q = vi(F), j = a ? xi(F) : [];
1942
- console.log("[Canvas] Images:", z.length, "SVGs:", q.length, "MathJax:", j.length), t?.({
1943
- phase: "rendering",
1944
- progress: 30,
1945
- message: "Rendering backgrounds..."
1946
- }), S.translate(-x, -C);
1947
- const fe = () => {
1948
- try {
1949
- return S.getImageData(0, 0, 1, 1), !1;
1950
- } catch {
1951
- return !0;
1952
- }
1953
- };
1954
- if (await Xt(F, S), await ce(), fe())
1955
- return console.warn("[Canvas] Canvas tainted after background rendering"), null;
1956
- if (t?.({
1957
- phase: "rendering",
1958
- progress: 50,
1959
- message: `Rendering ${z.length} images...`
1960
- }), await Yt(z, S, (N, U) => {
1961
- const B = 50 + Math.round(N / U * 30);
1962
- t?.({
1963
- phase: "rendering",
1964
- progress: B,
1965
- message: `Rendering images (${N}/${U})...`
1966
- });
1967
- }), await ce(), fe()) {
1968
- console.warn("[Canvas] Canvas tainted after image rendering, skipping SVG and text layers"), t?.({
1969
- phase: "exporting",
1970
- progress: 95,
1971
- message: "Exporting canvas (images tainted, skipping remaining layers)..."
1972
- });
1973
- try {
1974
- const N = T.toDataURL("image/png", l);
1975
- return N.length < 5e3 ? (console.warn("[Canvas] Canvas appears blank"), null) : (console.log("[Canvas] Capture successful (backgrounds + images only, skipped SVG/text due to taint)"), N);
1976
- } catch (N) {
1977
- return console.error("[Canvas] Export failed after image layer:", N), null;
1978
- }
1979
- }
1980
- if (t?.({
1981
- phase: "rendering",
1982
- progress: 80,
1983
- message: `Rendering ${q.length} SVG elements...`
1984
- }), await Jt(q, S, (N, U) => {
1985
- const B = 80 + Math.round(N / U * 10);
1986
- t?.({
1987
- phase: "rendering",
1988
- progress: B,
1989
- message: `Rendering SVG (${N}/${U})...`
1990
- });
1991
- }), await ce(), fe()) {
1992
- console.warn("[Canvas] Canvas tainted after SVG rendering, skipping text layer"), t?.({
1993
- phase: "exporting",
1994
- progress: 95,
1995
- message: "Exporting canvas (SVG tainted, skipping text)..."
1996
- });
1997
- try {
1998
- const N = T.toDataURL("image/png", l);
1999
- return N.length < 5e3 ? (console.warn("[Canvas] Canvas appears blank"), null) : (console.log("[Canvas] Capture successful (backgrounds + images + SVG, skipped text due to taint)"), N);
2000
- } catch (N) {
2001
- return console.error("[Canvas] Export failed after SVG layer:", N), null;
2002
- }
2003
- }
2004
- t?.({
2005
- phase: "rendering",
2006
- progress: 90,
2007
- message: "Rendering text content..."
2008
- }), await Ei(F, S, (N, U) => {
2009
- const B = 90 + Math.round(N / U * 5);
2010
- t?.({
2011
- phase: "rendering",
2012
- progress: B,
2013
- message: `Rendering text (${N}/${U})...`
2014
- });
2015
- }), await ce(), t?.({
2016
- phase: "exporting",
2017
- progress: 95,
2018
- message: "Exporting canvas to image..."
2019
- });
2020
- try {
2021
- S.getImageData(0, 0, 1, 1);
2022
- const N = T.toDataURL("image/png", l);
2023
- return N.length < 5e3 ? (console.warn("[Canvas] Canvas export appears to be blank or too small"), null) : (t?.({
2024
- phase: "exporting",
2025
- progress: 100,
2026
- message: "Capture complete"
2027
- }), console.log("[Canvas] Capture successful (all layers)"), N);
2028
- } catch {
2029
- console.warn("[Canvas] Canvas tainted after text rendering, retrying without text layer"), S.clearRect(0, 0, T.width, T.height), S.fillStyle = "#ffffff", S.fillRect(0, 0, w, E), S.translate(-x, -C), await Xt(F, S), await ce(), await Yt(z, S, () => {
2030
- }), await ce(), await Jt(q, S, () => {
2031
- }), await ce();
2032
- try {
2033
- const U = T.toDataURL("image/png", l);
2034
- return U.length < 5e3 ? (console.warn("[Canvas] Canvas still appears blank after retry"), null) : (console.log("[Canvas] Capture successful (without text layer)"), U);
2035
- } catch (U) {
2036
- return console.error("[Canvas] Export failed even without text layer:", U), null;
2037
- }
2038
- }
2039
- } catch (s) {
2040
- return console.error("[Canvas] Capture failed:", s), null;
2041
- } finally {
2042
- ri(i);
2043
- }
2044
- }
2045
- function Ii(e, n) {
2046
- return e[13] = 1, e[14] = n >> 8, e[15] = n & 255, e[16] = n >> 8, e[17] = n & 255, e;
2047
- }
2048
- const un = 112, fn = 72, gn = 89, hn = 115;
2049
- let gt;
2050
- function Ri() {
2051
- const e = new Int32Array(256);
2052
- for (let n = 0; n < 256; n++) {
2053
- let t = n;
2054
- for (let i = 0; i < 8; i++)
2055
- t = t & 1 ? 3988292384 ^ t >>> 1 : t >>> 1;
2056
- e[n] = t;
2057
- }
2058
- return e;
2059
- }
2060
- function Ai(e) {
2061
- let n = -1;
2062
- gt || (gt = Ri());
2063
- for (let t = 0; t < e.length; t++)
2064
- n = gt[(n ^ e[t]) & 255] ^ n >>> 8;
2065
- return n ^ -1;
2066
- }
2067
- function Ni(e) {
2068
- const n = e.length - 1;
2069
- for (let t = n; t >= 4; t--)
2070
- if (e[t - 4] === 9 && e[t - 3] === un && e[t - 2] === fn && e[t - 1] === gn && e[t] === hn)
2071
- return t - 3;
2072
- return 0;
2073
- }
2074
- function Mi(e, n, t = !1) {
2075
- const i = new Uint8Array(13);
2076
- n *= 39.3701, i[0] = un, i[1] = fn, i[2] = gn, i[3] = hn, i[4] = n >>> 24, i[5] = n >>> 16, i[6] = n >>> 8, i[7] = n & 255, i[8] = i[4], i[9] = i[5], i[10] = i[6], i[11] = i[7], i[12] = 1;
2077
- const s = Ai(i), o = new Uint8Array(4);
2078
- if (o[0] = s >>> 24, o[1] = s >>> 16, o[2] = s >>> 8, o[3] = s & 255, t) {
2079
- const r = Ni(e);
2080
- return e.set(i, r), e.set(o, r + 13), e;
2081
- } else {
2082
- const r = new Uint8Array(4);
2083
- r[0] = 0, r[1] = 0, r[2] = 0, r[3] = 9;
2084
- const a = new Uint8Array(54);
2085
- return a.set(e, 0), a.set(r, 33), a.set(i, 37), a.set(o, 50), a;
2086
- }
2087
- }
2088
- const Oi = "AAlwSFlz", Di = "AAAJcEhZ", Fi = "AAAACXBI";
2089
- function _i(e) {
2090
- let n = e.indexOf(Oi);
2091
- return n === -1 && (n = e.indexOf(Di)), n === -1 && (n = e.indexOf(Fi)), n;
2092
- }
2093
- const pn = "[modern-screenshot]", oe = typeof window < "u", Li = oe && "Worker" in window, Ui = oe && "atob" in window, zi = oe && "btoa" in window, St = oe ? window.navigator?.userAgent : "", mn = St.includes("Chrome"), Ye = St.includes("AppleWebKit") && !mn, kt = St.includes("Firefox"), Bi = (e) => e && "__CONTEXT__" in e, Pi = (e) => e.constructor.name === "CSSFontFaceRule", Hi = (e) => e.constructor.name === "CSSImportRule", Q = (e) => e.nodeType === 1, Ue = (e) => typeof e.className == "object", wn = (e) => e.tagName === "image", Vi = (e) => e.tagName === "use", De = (e) => Q(e) && typeof e.style < "u" && !Ue(e), $i = (e) => e.nodeType === 8, Wi = (e) => e.nodeType === 3, Se = (e) => e.tagName === "IMG", Ke = (e) => e.tagName === "VIDEO", qi = (e) => e.tagName === "CANVAS", ji = (e) => e.tagName === "TEXTAREA", Gi = (e) => e.tagName === "INPUT", Xi = (e) => e.tagName === "STYLE", Yi = (e) => e.tagName === "SCRIPT", Ji = (e) => e.tagName === "SELECT", Qi = (e) => e.tagName === "SLOT", Ki = (e) => e.tagName === "IFRAME", Zi = (...e) => console.warn(pn, ...e);
2094
- function er(e) {
2095
- const n = e?.createElement?.("canvas");
2096
- return n && (n.height = n.width = 1), !!n && "toDataURL" in n && !!n.toDataURL("image/webp").includes("image/webp");
2097
- }
2098
- const yt = (e) => e.startsWith("data:");
2099
- function bn(e, n) {
2100
- if (e.match(/^[a-z]+:\/\//i))
2101
- return e;
2102
- if (oe && e.match(/^\/\//))
2103
- return window.location.protocol + e;
2104
- if (e.match(/^[a-z]+:/i) || !oe)
2105
- return e;
2106
- const t = Ze().implementation.createHTMLDocument(), i = t.createElement("base"), s = t.createElement("a");
2107
- return t.head.appendChild(i), t.body.appendChild(s), n && (i.href = n), s.href = e, s.href;
2108
- }
2109
- function Ze(e) {
2110
- return (e && Q(e) ? e?.ownerDocument : e) ?? window.document;
2111
- }
2112
- const et = "http://www.w3.org/2000/svg";
2113
- function tr(e, n, t) {
2114
- const i = Ze(t).createElementNS(et, "svg");
2115
- return i.setAttributeNS(null, "width", e.toString()), i.setAttributeNS(null, "height", n.toString()), i.setAttributeNS(null, "viewBox", `0 0 ${e} ${n}`), i;
2116
- }
2117
- function nr(e, n) {
2118
- let t = new XMLSerializer().serializeToString(e);
2119
- return n && (t = t.replace(/[\u0000-\u0008\v\f\u000E-\u001F\uD800-\uDFFF\uFFFE\uFFFF]/gu, "")), `data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`;
2120
- }
2121
- function ir(e, n) {
2122
- return new Promise((t, i) => {
2123
- const s = new FileReader();
2124
- s.onload = () => t(s.result), s.onerror = () => i(s.error), s.onabort = () => i(new Error(`Failed read blob to ${n}`)), s.readAsDataURL(e);
2125
- });
2126
- }
2127
- const rr = (e) => ir(e, "dataUrl");
2128
- function be(e, n) {
2129
- const t = Ze(n).createElement("img");
2130
- return t.decoding = "sync", t.loading = "eager", t.src = e, t;
2131
- }
2132
- function Fe(e, n) {
2133
- return new Promise((t) => {
2134
- const { timeout: i, ownerDocument: s, onError: o, onWarn: r } = n ?? {}, a = typeof e == "string" ? be(e, Ze(s)) : e;
2135
- let d = null, g = null;
2136
- function l() {
2137
- t(a), d && clearTimeout(d), g?.();
2138
- }
2139
- if (i && (d = setTimeout(l, i)), Ke(a)) {
2140
- const m = a.currentSrc || a.src;
2141
- if (!m)
2142
- return a.poster ? Fe(a.poster, n).then(t) : l();
2143
- if (a.readyState >= 2)
2144
- return l();
2145
- const b = l, x = (C) => {
2146
- r?.(
2147
- "Failed video load",
2148
- m,
2149
- C
2150
- ), o?.(C), l();
2151
- };
2152
- g = () => {
2153
- a.removeEventListener("loadeddata", b), a.removeEventListener("error", x);
2154
- }, a.addEventListener("loadeddata", b, { once: !0 }), a.addEventListener("error", x, { once: !0 });
2155
- } else {
2156
- const m = wn(a) ? a.href.baseVal : a.currentSrc || a.src;
2157
- if (!m)
2158
- return l();
2159
- const b = async () => {
2160
- if (Se(a) && "decode" in a)
2161
- try {
2162
- await a.decode();
2163
- } catch (C) {
2164
- r?.(
2165
- "Failed to decode image, trying to render anyway",
2166
- a.dataset.originalSrc || m,
2167
- C
2168
- );
2169
- }
2170
- l();
2171
- }, x = (C) => {
2172
- r?.(
2173
- "Failed image load",
2174
- a.dataset.originalSrc || m,
2175
- C
2176
- ), l();
2177
- };
2178
- if (Se(a) && a.complete)
2179
- return b();
2180
- g = () => {
2181
- a.removeEventListener("load", b), a.removeEventListener("error", x);
2182
- }, a.addEventListener("load", b, { once: !0 }), a.addEventListener("error", x, { once: !0 });
2183
- }
2184
- });
2185
- }
2186
- async function or(e, n) {
2187
- De(e) && (Se(e) || Ke(e) ? await Fe(e, n) : await Promise.all(
2188
- ["img", "video"].flatMap((t) => Array.from(e.querySelectorAll(t)).map((i) => Fe(i, n)))
2189
- ));
2190
- }
2191
- const yn = /* @__PURE__ */ (function() {
2192
- let n = 0;
2193
- const t = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);
2194
- return () => (n += 1, `u${t()}${n}`);
2195
- })();
2196
- function vn(e) {
2197
- return e?.split(",").map((n) => n.trim().replace(/"|'/g, "").toLowerCase()).filter(Boolean);
2198
- }
2199
- let Qt = 0;
2200
- function sr(e) {
2201
- const n = `${pn}[#${Qt}]`;
2202
- return Qt++, {
2203
- // eslint-disable-next-line no-console
2204
- time: (t) => e && console.time(`${n} ${t}`),
2205
- // eslint-disable-next-line no-console
2206
- timeEnd: (t) => e && console.timeEnd(`${n} ${t}`),
2207
- warn: (...t) => e && Zi(...t)
2208
- };
2209
- }
2210
- function ar(e) {
2211
- return {
2212
- cache: e ? "no-cache" : "force-cache"
2213
- };
2214
- }
2215
- async function tt(e, n) {
2216
- return Bi(e) ? e : lr(e, { ...n, autoDestruct: !0 });
2217
- }
2218
- async function lr(e, n) {
2219
- const { scale: t = 1, workerUrl: i, workerNumber: s = 1 } = n || {}, o = !!n?.debug, r = n?.features ?? !0, a = e.ownerDocument ?? (oe ? window.document : void 0), d = e.ownerDocument?.defaultView ?? (oe ? window : void 0), g = /* @__PURE__ */ new Map(), l = {
2220
- // Options
2221
- width: 0,
2222
- height: 0,
2223
- quality: 1,
2224
- type: "image/png",
2225
- scale: t,
2226
- backgroundColor: null,
2227
- style: null,
2228
- filter: null,
2229
- maximumCanvasSize: 0,
2230
- timeout: 3e4,
2231
- progress: null,
2232
- debug: o,
2233
- fetch: {
2234
- requestInit: ar(n?.fetch?.bypassingCache),
2235
- placeholderImage: "data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
2236
- bypassingCache: !1,
2237
- ...n?.fetch
2238
- },
2239
- fetchFn: null,
2240
- font: {},
2241
- drawImageInterval: 100,
2242
- workerUrl: null,
2243
- workerNumber: s,
2244
- onCloneEachNode: null,
2245
- onCloneNode: null,
2246
- onEmbedNode: null,
2247
- onCreateForeignObjectSvg: null,
2248
- includeStyleProperties: null,
2249
- autoDestruct: !1,
2250
- ...n,
2251
- // InternalContext
2252
- __CONTEXT__: !0,
2253
- log: sr(o),
2254
- node: e,
2255
- ownerDocument: a,
2256
- ownerWindow: d,
2257
- dpi: t === 1 ? null : 96 * t,
2258
- svgStyleElement: xn(a),
2259
- svgDefsElement: a?.createElementNS(et, "defs"),
2260
- svgStyles: /* @__PURE__ */ new Map(),
2261
- defaultComputedStyles: /* @__PURE__ */ new Map(),
2262
- workers: [
2263
- ...Array.from({
2264
- length: Li && i && s ? s : 0
2265
- })
2266
- ].map(() => {
2267
- try {
2268
- const x = new Worker(i);
2269
- return x.onmessage = async (C) => {
2270
- const { url: w, result: E } = C.data;
2271
- E ? g.get(w)?.resolve?.(E) : g.get(w)?.reject?.(new Error(`Error receiving message from worker: ${w}`));
2272
- }, x.onmessageerror = (C) => {
2273
- const { url: w } = C.data;
2274
- g.get(w)?.reject?.(new Error(`Error receiving message from worker: ${w}`));
2275
- }, x;
2276
- } catch (x) {
2277
- return l.log.warn("Failed to new Worker", x), null;
2278
- }
2279
- }).filter(Boolean),
2280
- fontFamilies: /* @__PURE__ */ new Map(),
2281
- fontCssTexts: /* @__PURE__ */ new Map(),
2282
- acceptOfImage: `${[
2283
- er(a) && "image/webp",
2284
- "image/svg+xml",
2285
- "image/*",
2286
- "*/*"
2287
- ].filter(Boolean).join(",")};q=0.8`,
2288
- requests: g,
2289
- drawImageCount: 0,
2290
- tasks: [],
2291
- features: r,
2292
- isEnable: (x) => x === "restoreScrollPosition" ? typeof r == "boolean" ? !1 : r[x] ?? !1 : typeof r == "boolean" ? r : r[x] ?? !0,
2293
- shadowRoots: []
2294
- };
2295
- l.log.time("wait until load"), await or(e, { timeout: l.timeout, onWarn: l.log.warn }), l.log.timeEnd("wait until load");
2296
- const { width: m, height: b } = cr(e, l);
2297
- return l.width = m, l.height = b, l;
2298
- }
2299
- function xn(e) {
2300
- if (!e)
2301
- return;
2302
- const n = e.createElement("style"), t = n.ownerDocument.createTextNode(`
2303
- .______background-clip--text {
2304
- background-clip: text;
2305
- -webkit-background-clip: text;
2306
- }
2307
- `);
2308
- return n.appendChild(t), n;
2309
- }
2310
- function cr(e, n) {
2311
- let { width: t, height: i } = n;
2312
- if (Q(e) && (!t || !i)) {
2313
- const s = e.getBoundingClientRect();
2314
- t = t || s.width || Number(e.getAttribute("width")) || 0, i = i || s.height || Number(e.getAttribute("height")) || 0;
2315
- }
2316
- return { width: t, height: i };
2317
- }
2318
- async function dr(e, n) {
2319
- const {
2320
- log: t,
2321
- timeout: i,
2322
- drawImageCount: s,
2323
- drawImageInterval: o
2324
- } = n;
2325
- t.time("image to canvas");
2326
- const r = await Fe(e, { timeout: i, onWarn: n.log.warn }), { canvas: a, context2d: d } = ur(e.ownerDocument, n), g = () => {
2327
- try {
2328
- d?.drawImage(r, 0, 0, a.width, a.height);
2329
- } catch (l) {
2330
- n.log.warn("Failed to drawImage", l);
2331
- }
2332
- };
2333
- if (g(), n.isEnable("fixSvgXmlDecode"))
2334
- for (let l = 0; l < s; l++)
2335
- await new Promise((m) => {
2336
- setTimeout(() => {
2337
- d?.clearRect(0, 0, a.width, a.height), g(), m();
2338
- }, l + o);
2339
- });
2340
- return n.drawImageCount = 0, t.timeEnd("image to canvas"), a;
2341
- }
2342
- function ur(e, n) {
2343
- const { width: t, height: i, scale: s, backgroundColor: o, maximumCanvasSize: r } = n, a = e.createElement("canvas");
2344
- a.width = Math.floor(t * s), a.height = Math.floor(i * s), a.style.width = `${t}px`, a.style.height = `${i}px`, r && (a.width > r || a.height > r) && (a.width > r && a.height > r ? a.width > a.height ? (a.height *= r / a.width, a.width = r) : (a.width *= r / a.height, a.height = r) : a.width > r ? (a.height *= r / a.width, a.width = r) : (a.width *= r / a.height, a.height = r));
2345
- const d = a.getContext("2d");
2346
- return d && o && (d.fillStyle = o, d.fillRect(0, 0, a.width, a.height)), { canvas: a, context2d: d };
2347
- }
2348
- function Cn(e, n) {
2349
- if (e.ownerDocument)
2350
- try {
2351
- const o = e.toDataURL();
2352
- if (o !== "data:,")
2353
- return be(o, e.ownerDocument);
2354
- } catch (o) {
2355
- n.log.warn("Failed to clone canvas", o);
2356
- }
2357
- const t = e.cloneNode(!1), i = e.getContext("2d"), s = t.getContext("2d");
2358
- try {
2359
- return i && s && s.putImageData(
2360
- i.getImageData(0, 0, e.width, e.height),
2361
- 0,
2362
- 0
2363
- ), t;
2364
- } catch (o) {
2365
- n.log.warn("Failed to clone canvas", o);
2366
- }
2367
- return t;
2368
- }
2369
- function fr(e, n) {
2370
- try {
2371
- if (e?.contentDocument?.body)
2372
- return Et(e.contentDocument.body, n);
2373
- } catch (t) {
2374
- n.log.warn("Failed to clone iframe", t);
2375
- }
2376
- return e.cloneNode(!1);
2377
- }
2378
- function gr(e) {
2379
- const n = e.cloneNode(!1);
2380
- return e.currentSrc && e.currentSrc !== e.src && (n.src = e.currentSrc, n.srcset = ""), n.loading === "lazy" && (n.loading = "eager"), n;
2381
- }
2382
- async function hr(e, n) {
2383
- if (e.ownerDocument && !e.currentSrc && e.poster)
2384
- return be(e.poster, e.ownerDocument);
2385
- const t = e.cloneNode(!1);
2386
- t.crossOrigin = "anonymous", e.currentSrc && e.currentSrc !== e.src && (t.src = e.currentSrc);
2387
- const i = t.ownerDocument;
2388
- if (i) {
2389
- let s = !0;
2390
- if (await Fe(t, { onError: () => s = !1, onWarn: n.log.warn }), !s)
2391
- return e.poster ? be(e.poster, e.ownerDocument) : t;
2392
- t.currentTime = e.currentTime, await new Promise((r) => {
2393
- t.addEventListener("seeked", r, { once: !0 });
2394
- });
2395
- const o = i.createElement("canvas");
2396
- o.width = e.offsetWidth, o.height = e.offsetHeight;
2397
- try {
2398
- const r = o.getContext("2d");
2399
- r && r.drawImage(t, 0, 0, o.width, o.height);
2400
- } catch (r) {
2401
- return n.log.warn("Failed to clone video", r), e.poster ? be(e.poster, e.ownerDocument) : t;
2402
- }
2403
- return Cn(o, n);
2404
- }
2405
- return t;
2406
- }
2407
- function pr(e, n) {
2408
- return qi(e) ? Cn(e, n) : Ki(e) ? fr(e, n) : Se(e) ? gr(e) : Ke(e) ? hr(e, n) : e.cloneNode(!1);
2409
- }
2410
- function mr(e) {
2411
- let n = e.sandbox;
2412
- if (!n) {
2413
- const { ownerDocument: t } = e;
2414
- try {
2415
- t && (n = t.createElement("iframe"), n.id = `__SANDBOX__${yn()}`, n.width = "0", n.height = "0", n.style.visibility = "hidden", n.style.position = "fixed", t.body.appendChild(n), n.srcdoc = '<!DOCTYPE html><meta charset="UTF-8"><title></title><body>', e.sandbox = n);
2416
- } catch (i) {
2417
- e.log.warn("Failed to getSandBox", i);
2418
- }
2419
- }
2420
- return n;
2421
- }
2422
- const wr = [
2423
- "width",
2424
- "height",
2425
- "-webkit-text-fill-color"
2426
- ], br = [
2427
- "stroke",
2428
- "fill"
2429
- ];
2430
- function Sn(e, n, t) {
2431
- const { defaultComputedStyles: i } = t, s = e.nodeName.toLowerCase(), o = Ue(e) && s !== "svg", r = o ? br.map((w) => [w, e.getAttribute(w)]).filter(([, w]) => w !== null) : [], a = [
2432
- o && "svg",
2433
- s,
2434
- r.map((w, E) => `${w}=${E}`).join(","),
2435
- n
2436
- ].filter(Boolean).join(":");
2437
- if (i.has(a))
2438
- return i.get(a);
2439
- const g = mr(t)?.contentWindow;
2440
- if (!g)
2441
- return /* @__PURE__ */ new Map();
2442
- const l = g?.document;
2443
- let m, b;
2444
- o ? (m = l.createElementNS(et, "svg"), b = m.ownerDocument.createElementNS(m.namespaceURI, s), r.forEach(([w, E]) => {
2445
- b.setAttributeNS(null, w, E);
2446
- }), m.appendChild(b)) : m = b = l.createElement(s), b.textContent = " ", l.body.appendChild(m);
2447
- const x = g.getComputedStyle(b, n), C = /* @__PURE__ */ new Map();
2448
- for (let w = x.length, E = 0; E < w; E++) {
2449
- const y = x.item(E);
2450
- wr.includes(y) || C.set(y, x.getPropertyValue(y));
2451
- }
2452
- return l.body.removeChild(m), i.set(a, C), C;
2453
- }
2454
- function kn(e, n, t) {
2455
- const i = /* @__PURE__ */ new Map(), s = [], o = /* @__PURE__ */ new Map();
2456
- if (t)
2457
- for (const a of t)
2458
- r(a);
2459
- else
2460
- for (let a = e.length, d = 0; d < a; d++) {
2461
- const g = e.item(d);
2462
- r(g);
2463
- }
2464
- for (let a = s.length, d = 0; d < a; d++)
2465
- o.get(s[d])?.forEach((g, l) => i.set(l, g));
2466
- function r(a) {
2467
- const d = e.getPropertyValue(a), g = e.getPropertyPriority(a), l = a.lastIndexOf("-"), m = l > -1 ? a.substring(0, l) : void 0;
2468
- if (m) {
2469
- let b = o.get(m);
2470
- b || (b = /* @__PURE__ */ new Map(), o.set(m, b)), b.set(a, [d, g]);
2471
- }
2472
- n.get(a) === d && !g || (m ? s.push(m) : i.set(a, [d, g]));
2473
- }
2474
- return i;
2475
- }
2476
- function yr(e, n, t, i) {
2477
- const { ownerWindow: s, includeStyleProperties: o, currentParentNodeStyle: r } = i, a = n.style, d = s.getComputedStyle(e), g = Sn(e, null, i);
2478
- r?.forEach((m, b) => {
2479
- g.delete(b);
2480
- });
2481
- const l = kn(d, g, o);
2482
- l.delete("transition-property"), l.delete("all"), l.delete("d"), l.delete("content"), t && (l.delete("margin-top"), l.delete("margin-right"), l.delete("margin-bottom"), l.delete("margin-left"), l.delete("margin-block-start"), l.delete("margin-block-end"), l.delete("margin-inline-start"), l.delete("margin-inline-end"), l.set("box-sizing", ["border-box", ""])), l.get("background-clip")?.[0] === "text" && n.classList.add("______background-clip--text"), mn && (l.has("font-kerning") || l.set("font-kerning", ["normal", ""]), (l.get("overflow-x")?.[0] === "hidden" || l.get("overflow-y")?.[0] === "hidden") && l.get("text-overflow")?.[0] === "ellipsis" && e.scrollWidth === e.clientWidth && l.set("text-overflow", ["clip", ""]));
2483
- for (let m = a.length, b = 0; b < m; b++)
2484
- a.removeProperty(a.item(b));
2485
- return l.forEach(([m, b], x) => {
2486
- a.setProperty(x, m, b);
2487
- }), l;
2488
- }
2489
- function vr(e, n) {
2490
- (ji(e) || Gi(e) || Ji(e)) && n.setAttribute("value", e.value);
2491
- }
2492
- const xr = [
2493
- "::before",
2494
- "::after"
2495
- // '::placeholder', TODO
2496
- ], Cr = [
2497
- "::-webkit-scrollbar",
2498
- "::-webkit-scrollbar-button",
2499
- // '::-webkit-scrollbar:horizontal', TODO
2500
- "::-webkit-scrollbar-thumb",
2501
- "::-webkit-scrollbar-track",
2502
- "::-webkit-scrollbar-track-piece",
2503
- // '::-webkit-scrollbar:vertical', TODO
2504
- "::-webkit-scrollbar-corner",
2505
- "::-webkit-resizer"
2506
- ];
2507
- function Sr(e, n, t, i, s) {
2508
- const { ownerWindow: o, svgStyleElement: r, svgStyles: a, currentNodeStyle: d } = i;
2509
- if (!r || !o)
2510
- return;
2511
- function g(l) {
2512
- const m = o.getComputedStyle(e, l);
2513
- let b = m.getPropertyValue("content");
2514
- if (!b || b === "none")
2515
- return;
2516
- s?.(b), b = b.replace(/(')|(")|(counter\(.+\))/g, "");
2517
- const x = [yn()], C = Sn(e, l, i);
2518
- d?.forEach((S, D) => {
2519
- C.delete(D);
2520
- });
2521
- const w = kn(m, C, i.includeStyleProperties);
2522
- w.delete("content"), w.delete("-webkit-locale"), w.get("background-clip")?.[0] === "text" && n.classList.add("______background-clip--text");
2523
- const E = [
2524
- `content: '${b}';`
2525
- ];
2526
- if (w.forEach(([S, D], F) => {
2527
- E.push(`${F}: ${S}${D ? " !important" : ""};`);
2528
- }), E.length === 1)
2529
- return;
2530
- try {
2531
- n.className = [n.className, ...x].join(" ");
2532
- } catch (S) {
2533
- i.log.warn("Failed to copyPseudoClass", S);
2534
- return;
2535
- }
2536
- const y = E.join(`
2537
- `);
2538
- let T = a.get(y);
2539
- T || (T = [], a.set(y, T)), T.push(`.${x[0]}${l}`);
2540
- }
2541
- xr.forEach(g), t && Cr.forEach(g);
2542
- }
2543
- const Kt = /* @__PURE__ */ new Set([
2544
- "symbol"
2545
- // test/fixtures/svg.symbol.html
2546
- ]);
2547
- async function Zt(e, n, t, i, s) {
2548
- if (Q(t) && (Xi(t) || Yi(t)) || i.filter && !i.filter(t))
2549
- return;
2550
- Kt.has(n.nodeName) || Kt.has(t.nodeName) ? i.currentParentNodeStyle = void 0 : i.currentParentNodeStyle = i.currentNodeStyle;
2551
- const o = await Et(t, i, !1, s);
2552
- i.isEnable("restoreScrollPosition") && kr(e, o), n.appendChild(o);
2553
- }
2554
- async function en(e, n, t, i) {
2555
- let s = e.firstChild;
2556
- Q(e) && e.shadowRoot && (s = e.shadowRoot?.firstChild, t.shadowRoots.push(e.shadowRoot));
2557
- for (let o = s; o; o = o.nextSibling)
2558
- if (!$i(o))
2559
- if (Q(o) && Qi(o) && typeof o.assignedNodes == "function") {
2560
- const r = o.assignedNodes();
2561
- for (let a = 0; a < r.length; a++)
2562
- await Zt(e, n, r[a], t, i);
2563
- } else
2564
- await Zt(e, n, o, t, i);
2565
- }
2566
- function kr(e, n) {
2567
- if (!De(e) || !De(n))
2568
- return;
2569
- const { scrollTop: t, scrollLeft: i } = e;
2570
- if (!t && !i)
2571
- return;
2572
- const { transform: s } = n.style, o = new DOMMatrix(s), { a: r, b: a, c: d, d: g } = o;
2573
- o.a = 1, o.b = 0, o.c = 0, o.d = 1, o.translateSelf(-i, -t), o.a = r, o.b = a, o.c = d, o.d = g, n.style.transform = o.toString();
2574
- }
2575
- function Er(e, n) {
2576
- const { backgroundColor: t, width: i, height: s, style: o } = n, r = e.style;
2577
- if (t && r.setProperty("background-color", t, "important"), i && r.setProperty("width", `${i}px`, "important"), s && r.setProperty("height", `${s}px`, "important"), o)
2578
- for (const a in o) r[a] = o[a];
2579
- }
2580
- const Tr = /^[\w-:]+$/;
2581
- async function Et(e, n, t = !1, i) {
2582
- const { ownerDocument: s, ownerWindow: o, fontFamilies: r, onCloneEachNode: a } = n;
2583
- if (s && Wi(e))
2584
- return i && /\S/.test(e.data) && i(e.data), s.createTextNode(e.data);
2585
- if (s && o && Q(e) && (De(e) || Ue(e))) {
2586
- const g = await pr(e, n);
2587
- if (n.isEnable("removeAbnormalAttributes")) {
2588
- const w = g.getAttributeNames();
2589
- for (let E = w.length, y = 0; y < E; y++) {
2590
- const T = w[y];
2591
- Tr.test(T) || g.removeAttribute(T);
2592
- }
2593
- }
2594
- const l = n.currentNodeStyle = yr(e, g, t, n);
2595
- t && Er(g, n);
2596
- let m = !1;
2597
- if (n.isEnable("copyScrollbar")) {
2598
- const w = [
2599
- l.get("overflow-x")?.[0],
2600
- l.get("overflow-y")?.[0]
2601
- ];
2602
- m = w.includes("scroll") || (w.includes("auto") || w.includes("overlay")) && (e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth);
2603
- }
2604
- const b = l.get("text-transform")?.[0], x = vn(l.get("font-family")?.[0]), C = x ? (w) => {
2605
- b === "uppercase" ? w = w.toUpperCase() : b === "lowercase" ? w = w.toLowerCase() : b === "capitalize" && (w = w[0].toUpperCase() + w.substring(1)), x.forEach((E) => {
2606
- let y = r.get(E);
2607
- y || r.set(E, y = /* @__PURE__ */ new Set()), w.split("").forEach((T) => y.add(T));
2608
- });
2609
- } : void 0;
2610
- return Sr(
2611
- e,
2612
- g,
2613
- m,
2614
- n,
2615
- C
2616
- ), vr(e, g), Ke(e) || await en(
2617
- e,
2618
- g,
2619
- n,
2620
- C
2621
- ), await a?.(g), g;
2622
- }
2623
- const d = e.cloneNode(!1);
2624
- return await en(e, d, n), await a?.(d), d;
2625
- }
2626
- function Ir(e) {
2627
- if (e.ownerDocument = void 0, e.ownerWindow = void 0, e.svgStyleElement = void 0, e.svgDefsElement = void 0, e.svgStyles.clear(), e.defaultComputedStyles.clear(), e.sandbox) {
2628
- try {
2629
- e.sandbox.remove();
2630
- } catch (n) {
2631
- e.log.warn("Failed to destroyContext", n);
2632
- }
2633
- e.sandbox = void 0;
2634
- }
2635
- e.workers = [], e.fontFamilies.clear(), e.fontCssTexts.clear(), e.requests.clear(), e.tasks = [], e.shadowRoots = [];
2636
- }
2637
- function Rr(e) {
2638
- const { url: n, timeout: t, responseType: i, ...s } = e, o = new AbortController(), r = t ? setTimeout(() => o.abort(), t) : void 0;
2639
- return fetch(n, { signal: o.signal, ...s }).then((a) => {
2640
- if (!a.ok)
2641
- throw new Error("Failed fetch, not 2xx response", { cause: a });
2642
- switch (i) {
2643
- case "arrayBuffer":
2644
- return a.arrayBuffer();
2645
- case "dataUrl":
2646
- return a.blob().then(rr);
2647
- default:
2648
- return a.text();
2649
- }
2650
- }).finally(() => clearTimeout(r));
2651
- }
2652
- function _e(e, n) {
2653
- const { url: t, requestType: i = "text", responseType: s = "text", imageDom: o } = n;
2654
- let r = t;
2655
- const {
2656
- timeout: a,
2657
- acceptOfImage: d,
2658
- requests: g,
2659
- fetchFn: l,
2660
- fetch: {
2661
- requestInit: m,
2662
- bypassingCache: b,
2663
- placeholderImage: x
2664
- },
2665
- font: C,
2666
- workers: w,
2667
- fontFamilies: E
2668
- } = e;
2669
- i === "image" && (Ye || kt) && e.drawImageCount++;
2670
- let y = g.get(t);
2671
- if (!y) {
2672
- b && b instanceof RegExp && b.test(r) && (r += (/\?/.test(r) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
2673
- const T = i.startsWith("font") && C && C.minify, S = /* @__PURE__ */ new Set();
2674
- T && i.split(";")[1].split(",").forEach((q) => {
2675
- E.has(q) && E.get(q).forEach((j) => S.add(j));
2676
- });
2677
- const D = T && S.size, F = {
2678
- url: r,
2679
- timeout: a,
2680
- responseType: D ? "arrayBuffer" : s,
2681
- headers: i === "image" ? { accept: d } : void 0,
2682
- ...m
2683
- };
2684
- y = {
2685
- type: i,
2686
- resolve: void 0,
2687
- reject: void 0,
2688
- response: null
2689
- }, y.response = (async () => {
2690
- if (l && i === "image") {
2691
- const z = await l(t);
2692
- if (z)
2693
- return z;
2694
- }
2695
- return !Ye && t.startsWith("http") && w.length ? new Promise((z, q) => {
2696
- w[g.size & w.length - 1].postMessage({ rawUrl: t, ...F }), y.resolve = z, y.reject = q;
2697
- }) : Rr(F);
2698
- })().catch((z) => {
2699
- if (g.delete(t), i === "image" && x)
2700
- return e.log.warn("Failed to fetch image base64, trying to use placeholder image", r), typeof x == "string" ? x : x(o);
2701
- throw z;
2702
- }), g.set(t, y);
2703
- }
2704
- return y.response;
2705
- }
2706
- async function En(e, n, t, i) {
2707
- if (!Tn(e))
2708
- return e;
2709
- for (const [s, o] of Ar(e, n))
2710
- try {
2711
- const r = await _e(
2712
- t,
2713
- {
2714
- url: o,
2715
- requestType: i ? "image" : "text",
2716
- responseType: "dataUrl"
2717
- }
2718
- );
2719
- e = e.replace(Nr(s), `$1${r}$3`);
2720
- } catch (r) {
2721
- t.log.warn("Failed to fetch css data url", s, r);
2722
- }
2723
- return e;
2724
- }
2725
- function Tn(e) {
2726
- return /url\((['"]?)([^'"]+?)\1\)/.test(e);
2727
- }
2728
- const In = /url\((['"]?)([^'"]+?)\1\)/g;
2729
- function Ar(e, n) {
2730
- const t = [];
2731
- return e.replace(In, (i, s, o) => (t.push([o, bn(o, n)]), i)), t.filter(([i]) => !yt(i));
2732
- }
2733
- function Nr(e) {
2734
- const n = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
2735
- return new RegExp(`(url\\(['"]?)(${n})(['"]?\\))`, "g");
2736
- }
2737
- const Mr = [
2738
- "background-image",
2739
- "border-image-source",
2740
- "-webkit-border-image",
2741
- "-webkit-mask-image",
2742
- "list-style-image"
2743
- ];
2744
- function Or(e, n) {
2745
- return Mr.map((t) => {
2746
- const i = e.getPropertyValue(t);
2747
- return !i || i === "none" ? null : ((Ye || kt) && n.drawImageCount++, En(i, null, n, !0).then((s) => {
2748
- !s || i === s || e.setProperty(
2749
- t,
2750
- s,
2751
- e.getPropertyPriority(t)
2752
- );
2753
- }));
2754
- }).filter(Boolean);
2755
- }
2756
- function Dr(e, n) {
2757
- if (Se(e)) {
2758
- const t = e.currentSrc || e.src;
2759
- if (!yt(t))
2760
- return [
2761
- _e(n, {
2762
- url: t,
2763
- imageDom: e,
2764
- requestType: "image",
2765
- responseType: "dataUrl"
2766
- }).then((i) => {
2767
- i && (e.srcset = "", e.dataset.originalSrc = t, e.src = i || "");
2768
- })
2769
- ];
2770
- (Ye || kt) && n.drawImageCount++;
2771
- } else if (Ue(e) && !yt(e.href.baseVal)) {
2772
- const t = e.href.baseVal;
2773
- return [
2774
- _e(n, {
2775
- url: t,
2776
- imageDom: e,
2777
- requestType: "image",
2778
- responseType: "dataUrl"
2779
- }).then((i) => {
2780
- i && (e.dataset.originalSrc = t, e.href.baseVal = i || "");
2781
- })
2782
- ];
2783
- }
2784
- return [];
2785
- }
2786
- function Fr(e, n) {
2787
- const { ownerDocument: t, svgDefsElement: i } = n, s = e.getAttribute("href") ?? e.getAttribute("xlink:href");
2788
- if (!s)
2789
- return [];
2790
- const [o, r] = s.split("#");
2791
- if (r) {
2792
- const a = `#${r}`, d = n.shadowRoots.reduce(
2793
- (g, l) => g ?? l.querySelector(`svg ${a}`),
2794
- t?.querySelector(`svg ${a}`)
2795
- );
2796
- if (o && e.setAttribute("href", a), i?.querySelector(a))
2797
- return [];
2798
- if (d)
2799
- return i?.appendChild(d.cloneNode(!0)), [];
2800
- if (o)
2801
- return [
2802
- _e(n, {
2803
- url: o,
2804
- responseType: "text"
2805
- }).then((g) => {
2806
- i?.insertAdjacentHTML("beforeend", g);
2807
- })
2808
- ];
2809
- }
2810
- return [];
2811
- }
2812
- function Rn(e, n) {
2813
- const { tasks: t } = n;
2814
- Q(e) && ((Se(e) || wn(e)) && t.push(...Dr(e, n)), Vi(e) && t.push(...Fr(e, n))), De(e) && t.push(...Or(e.style, n)), e.childNodes.forEach((i) => {
2815
- Rn(i, n);
2816
- });
2817
- }
2818
- async function _r(e, n) {
2819
- const {
2820
- ownerDocument: t,
2821
- svgStyleElement: i,
2822
- fontFamilies: s,
2823
- fontCssTexts: o,
2824
- tasks: r,
2825
- font: a
2826
- } = n;
2827
- if (!(!t || !i || !s.size))
2828
- if (a && a.cssText) {
2829
- const d = nn(a.cssText, n);
2830
- i.appendChild(t.createTextNode(`${d}
2831
- `));
2832
- } else {
2833
- const d = Array.from(t.styleSheets).filter((l) => {
2834
- try {
2835
- return "cssRules" in l && !!l.cssRules.length;
2836
- } catch (m) {
2837
- return n.log.warn(`Error while reading CSS rules from ${l.href}`, m), !1;
2838
- }
2839
- });
2840
- await Promise.all(
2841
- d.flatMap((l) => Array.from(l.cssRules).map(async (m, b) => {
2842
- if (Hi(m)) {
2843
- let x = b + 1;
2844
- const C = m.href;
2845
- let w = "";
2846
- try {
2847
- w = await _e(n, {
2848
- url: C,
2849
- requestType: "text",
2850
- responseType: "text"
2851
- });
2852
- } catch (y) {
2853
- n.log.warn(`Error fetch remote css import from ${C}`, y);
2854
- }
2855
- const E = w.replace(
2856
- In,
2857
- (y, T, S) => y.replace(S, bn(S, C))
2858
- );
2859
- for (const y of Ur(E))
2860
- try {
2861
- l.insertRule(
2862
- y,
2863
- y.startsWith("@import") ? x += 1 : l.cssRules.length
2864
- );
2865
- } catch (T) {
2866
- n.log.warn("Error inserting rule from remote css import", { rule: y, error: T });
2867
- }
2868
- }
2869
- }))
2870
- ), d.flatMap((l) => Array.from(l.cssRules)).filter((l) => Pi(l) && Tn(l.style.getPropertyValue("src")) && vn(l.style.getPropertyValue("font-family"))?.some((m) => s.has(m))).forEach((l) => {
2871
- const m = l, b = o.get(m.cssText);
2872
- b ? i.appendChild(t.createTextNode(`${b}
2873
- `)) : r.push(
2874
- En(
2875
- m.cssText,
2876
- m.parentStyleSheet ? m.parentStyleSheet.href : null,
2877
- n
2878
- ).then((x) => {
2879
- x = nn(x, n), o.set(m.cssText, x), i.appendChild(t.createTextNode(`${x}
2880
- `));
2881
- })
2882
- );
2883
- });
2884
- }
2885
- }
2886
- const Lr = /(\/\*[\s\S]*?\*\/)/g, tn = /((@.*?keyframes [\s\S]*?){([\s\S]*?}\s*?)})/gi;
2887
- function Ur(e) {
2888
- if (e == null)
2889
- return [];
2890
- const n = [];
2891
- let t = e.replace(Lr, "");
2892
- for (; ; ) {
2893
- const o = tn.exec(t);
2894
- if (!o)
2895
- break;
2896
- n.push(o[0]);
2897
- }
2898
- t = t.replace(tn, "");
2899
- const i = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, s = new RegExp(
2900
- // eslint-disable-next-line
2901
- "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})",
2902
- "gi"
2903
- );
2904
- for (; ; ) {
2905
- let o = i.exec(t);
2906
- if (o)
2907
- s.lastIndex = i.lastIndex;
2908
- else if (o = s.exec(t), o)
2909
- i.lastIndex = s.lastIndex;
2910
- else
2911
- break;
2912
- n.push(o[0]);
2913
- }
2914
- return n;
2915
- }
2916
- const zr = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, Br = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
2917
- function nn(e, n) {
2918
- const { font: t } = n, i = t ? t?.preferredFormat : void 0;
2919
- return i ? e.replace(Br, (s) => {
2920
- for (; ; ) {
2921
- const [o, , r] = zr.exec(s) || [];
2922
- if (!r)
2923
- return "";
2924
- if (r === i)
2925
- return `src: ${o};`;
2926
- }
2927
- }) : e;
2928
- }
2929
- async function Pr(e, n) {
2930
- const t = await tt(e, n);
2931
- if (Q(t.node) && Ue(t.node))
2932
- return t.node;
2933
- const {
2934
- ownerDocument: i,
2935
- log: s,
2936
- tasks: o,
2937
- svgStyleElement: r,
2938
- svgDefsElement: a,
2939
- svgStyles: d,
2940
- font: g,
2941
- progress: l,
2942
- autoDestruct: m,
2943
- onCloneNode: b,
2944
- onEmbedNode: x,
2945
- onCreateForeignObjectSvg: C
2946
- } = t;
2947
- s.time("clone node");
2948
- const w = await Et(t.node, t, !0);
2949
- if (r && i) {
2950
- let D = "";
2951
- d.forEach((F, z) => {
2952
- D += `${F.join(`,
2953
- `)} {
2954
- ${z}
2955
- }
2956
- `;
2957
- }), r.appendChild(i.createTextNode(D));
2958
- }
2959
- s.timeEnd("clone node"), await b?.(w), g !== !1 && Q(w) && (s.time("embed web font"), await _r(w, t), s.timeEnd("embed web font")), s.time("embed node"), Rn(w, t);
2960
- const E = o.length;
2961
- let y = 0;
2962
- const T = async () => {
2963
- for (; ; ) {
2964
- const D = o.pop();
2965
- if (!D)
2966
- break;
2967
- try {
2968
- await D;
2969
- } catch (F) {
2970
- t.log.warn("Failed to run task", F);
2971
- }
2972
- l?.(++y, E);
2973
- }
2974
- };
2975
- l?.(y, E), await Promise.all([...Array.from({ length: 4 })].map(T)), s.timeEnd("embed node"), await x?.(w);
2976
- const S = Hr(w, t);
2977
- return a && S.insertBefore(a, S.children[0]), r && S.insertBefore(r, S.children[0]), m && Ir(t), await C?.(S), S;
2978
- }
2979
- function Hr(e, n) {
2980
- const { width: t, height: i } = n, s = tr(t, i, e.ownerDocument), o = s.ownerDocument.createElementNS(s.namespaceURI, "foreignObject");
2981
- return o.setAttributeNS(null, "x", "0%"), o.setAttributeNS(null, "y", "0%"), o.setAttributeNS(null, "width", "100%"), o.setAttributeNS(null, "height", "100%"), o.append(e), s.appendChild(o), s;
2982
- }
2983
- async function Vr(e, n) {
2984
- const t = await tt(e, n), i = await Pr(t), s = nr(i, t.isEnable("removeControlCharacter"));
2985
- t.autoDestruct || (t.svgStyleElement = xn(t.ownerDocument), t.svgDefsElement = t.ownerDocument?.createElementNS(et, "defs"), t.svgStyles.clear());
2986
- const o = be(s, i.ownerDocument);
2987
- return await dr(o, t);
2988
- }
2989
- async function $r(e, n) {
2990
- const t = await tt(e, n), { log: i, quality: s, type: o, dpi: r } = t, a = await Vr(t);
2991
- i.time("canvas to data url");
2992
- let d = a.toDataURL(o, s);
2993
- if (["image/png", "image/jpeg"].includes(o) && r && Ui && zi) {
2994
- const [g, l] = d.split(",");
2995
- let m = 0, b = !1;
2996
- if (o === "image/png") {
2997
- const S = _i(l);
2998
- S >= 0 ? (m = Math.ceil((S + 28) / 3) * 4, b = !0) : m = 33 / 3 * 4;
2999
- } else o === "image/jpeg" && (m = 18 / 3 * 4);
3000
- const x = l.substring(0, m), C = l.substring(m), w = window.atob(x), E = new Uint8Array(w.length);
3001
- for (let S = 0; S < E.length; S++)
3002
- E[S] = w.charCodeAt(S);
3003
- const y = o === "image/png" ? Mi(E, r, b) : Ii(E, r), T = window.btoa(String.fromCharCode(...y));
3004
- d = [g, ",", T, C].join("");
3005
- }
3006
- return i.timeEnd("canvas to data url"), d;
3007
- }
3008
- async function Wr(e, n) {
3009
- return $r(
3010
- await tt(e, { ...n, type: "image/png" })
3011
- );
3012
- }
3013
- const qr = async (e, n) => {
3014
- console.log("[Screenshot] Starting capture with 3-tier fallback strategy");
3015
- try {
3016
- console.log("[Screenshot] Tier 1: Attempting canvas-based capture...");
3017
- const t = await Ti(e, {}, n);
3018
- if (t)
3019
- return console.log("[Screenshot] Tier 1 successful - canvas-based capture"), t;
3020
- console.warn("[Screenshot] Tier 1 failed, falling back to Tier 2");
3021
- } catch (t) {
3022
- console.warn("[Screenshot] Tier 1 error:", t);
3023
- }
3024
- try {
3025
- console.log("[Screenshot] Tier 2: Attempting modern-screenshot...");
3026
- const t = () => window.visualViewport ? window.visualViewport.width : document.documentElement.clientWidth || window.innerWidth, i = () => window.visualViewport ? window.visualViewport.height : document.documentElement.clientHeight || window.innerHeight, s = document.documentElement, o = e ? e.x : 0, r = e ? e.y : 0, a = e ? e.width : t(), d = e ? e.height : i(), g = window.scrollX, l = window.scrollY, m = g + o, b = l + r, x = await Wr(s, {
3027
- quality: 0.9,
3028
- width: a,
3029
- height: d,
3030
- style: {
3031
- transform: `translate(${-m}px, ${-b}px)`
3032
- }
3033
- });
3034
- return console.log("[Screenshot] Tier 2 successful - modern-screenshot"), x;
3035
- } catch (t) {
3036
- console.error("[Screenshot] Tier 2 failed:", t);
3037
- }
3038
- return console.error("[Screenshot] All capture methods failed"), null;
3039
- };
3040
- const jr = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), Gr = (e) => e.replace(
3041
- /^([A-Z])|[\s-_]+(\w)/g,
3042
- (n, t, i) => i ? i.toUpperCase() : t.toLowerCase()
3043
- ), rn = (e) => {
3044
- const n = Gr(e);
3045
- return n.charAt(0).toUpperCase() + n.slice(1);
3046
- }, An = (...e) => e.filter((n, t, i) => !!n && n.trim() !== "" && i.indexOf(n) === t).join(" ").trim(), Xr = (e) => {
3047
- for (const n in e)
3048
- if (n.startsWith("aria-") || n === "role" || n === "title")
3049
- return !0;
3050
- };
3051
- var Yr = {
3052
- xmlns: "http://www.w3.org/2000/svg",
3053
- width: 24,
3054
- height: 24,
3055
- viewBox: "0 0 24 24",
3056
- fill: "none",
3057
- stroke: "currentColor",
3058
- strokeWidth: 2,
3059
- strokeLinecap: "round",
3060
- strokeLinejoin: "round"
3061
- };
3062
- const Jr = an(
3063
- ({
3064
- color: e = "currentColor",
3065
- size: n = 24,
3066
- strokeWidth: t = 2,
3067
- absoluteStrokeWidth: i,
3068
- className: s = "",
3069
- children: o,
3070
- iconNode: r,
3071
- ...a
3072
- }, d) => ht(
3073
- "svg",
3074
- {
3075
- ref: d,
3076
- ...Yr,
3077
- width: n,
3078
- height: n,
3079
- stroke: e,
3080
- strokeWidth: i ? Number(t) * 24 / Number(n) : t,
3081
- className: An("lucide", s),
3082
- ...!o && !Xr(a) && { "aria-hidden": "true" },
3083
- ...a
3084
- },
3085
- [
3086
- ...r.map(([g, l]) => ht(g, l)),
3087
- ...Array.isArray(o) ? o : [o]
3088
- ]
3089
- )
3090
- );
3091
- const ae = (e, n) => {
3092
- const t = an(
3093
- ({ className: i, ...s }, o) => ht(Jr, {
3094
- ref: o,
3095
- iconNode: n,
3096
- className: An(
3097
- `lucide-${jr(rn(e))}`,
3098
- `lucide-${e}`,
3099
- i
3100
- ),
3101
- ...s
3102
- })
3103
- );
3104
- return t.displayName = rn(e), t;
3105
- };
3106
- const Qr = [
3107
- ["path", { d: "M6 2v14a2 2 0 0 0 2 2h14", key: "ron5a4" }],
3108
- ["path", { d: "M18 22V8a2 2 0 0 0-2-2H2", key: "7s9ehn" }]
3109
- ], Kr = ae("crop", Qr);
3110
- const Zr = [
3111
- ["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
3112
- ["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
3113
- ["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
3114
- ["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
3115
- ], on = ae("hash", Zr);
3116
- const eo = [
3117
- ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
3118
- ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
3119
- ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
3120
- ], to = ae("image", eo);
3121
- const no = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]], io = ae("loader-circle", no);
3122
- const ro = [
3123
- [
3124
- "path",
3125
- {
3126
- d: "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
3127
- key: "18887p"
3128
- }
3129
- ],
3130
- ["path", { d: "M12 8v6", key: "1ib9pf" }],
3131
- ["path", { d: "M9 11h6", key: "1fldmi" }]
3132
- ], oo = ae("message-square-plus", ro);
3133
- const so = [
3134
- ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
3135
- ["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
3136
- ["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
3137
- ], ao = ae("monitor", so);
3138
- const lo = [
3139
- ["path", { d: "M21 5H3", key: "1fi0y6" }],
3140
- ["path", { d: "M15 12H3", key: "6jk70r" }],
3141
- ["path", { d: "M17 19H3", key: "z6ezky" }]
3142
- ], co = ae("text-align-start", lo);
3143
- const uo = [
3144
- ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
3145
- ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
3146
- ], sn = ae("x", uo), fo = ({ onConfirm: e, onCancel: n }) => {
3147
- const [t, i] = L(!1), [s, o] = L({ x: 0, y: 0 }), [r, a] = L({ x: 0, y: 0 }), [d, g] = L(!1);
3148
- Ot(() => (d ? document.body.style.overflow = "hidden" : document.body.style.overflow = "", () => {
3149
- document.body.style.overflow = "";
3150
- }), [d]);
3151
- const l = (y) => {
3152
- i(!0), o({ x: y.clientX, y: y.clientY }), a({ x: y.clientX, y: y.clientY });
3153
- }, m = (y) => {
3154
- t && a({ x: y.clientX, y: y.clientY });
3155
- }, b = () => {
3156
- E();
3157
- }, x = (y) => {
3158
- if (y.touches.length === 1) {
3159
- i(!0);
3160
- const T = y.touches[0];
3161
- o({ x: T.clientX, y: T.clientY }), a({ x: T.clientX, y: T.clientY }), g(!0);
3162
- }
3163
- }, C = (y) => {
3164
- if (t && y.touches.length === 1) {
3165
- const T = y.touches[0];
3166
- a({ x: T.clientX, y: T.clientY });
3167
- }
3168
- }, w = () => {
3169
- E(), g(!1);
3170
- }, E = () => {
3171
- if (t) {
3172
- i(!1);
3173
- const y = Math.min(s.x, r.x), T = Math.min(s.y, r.y), S = Math.abs(r.x - s.x), D = Math.abs(r.y - s.y);
3174
- S > 10 && D > 10 && e({
3175
- x: y,
3176
- y: T,
3177
- width: S,
3178
- height: D
3179
- });
3180
- }
3181
- };
3182
- return Ot(() => {
3183
- const y = (T) => {
3184
- T.key === "Escape" && n();
3185
- };
3186
- return window.addEventListener("keydown", y), () => window.removeEventListener("keydown", y);
3187
- }, [n]), /* @__PURE__ */ R(
3188
- "div",
3189
- {
3190
- style: {
3191
- position: "fixed",
3192
- inset: 0,
3193
- zIndex: 99999,
3194
- // Extremely high z-index
3195
- cursor: "crosshair",
3196
- userSelect: "none"
3197
- },
3198
- onMouseDown: l,
3199
- onMouseMove: m,
3200
- onMouseUp: b,
3201
- onTouchStart: x,
3202
- onTouchMove: C,
3203
- onTouchEnd: w,
3204
- children: [
3205
- /* @__PURE__ */ k("div", { style: {
3206
- position: "absolute",
3207
- inset: 0,
3208
- backgroundColor: "rgba(0, 0, 0, 0.4)"
3209
- } }),
3210
- !t && /* @__PURE__ */ k("div", { style: {
3211
- position: "absolute",
3212
- top: "20px",
3213
- left: "50%",
3214
- transform: "translateX(-50%)",
3215
- background: "rgba(0,0,0,0.8)",
3216
- color: "white",
3217
- padding: "8px 16px",
3218
- borderRadius: "20px",
3219
- pointerEvents: "none",
3220
- fontSize: "14px"
3221
- }, children: "Kéo chuột hoặc chạm để chọn vùng chụp ảnh (ESC để hủy)" }),
3222
- t && /* @__PURE__ */ k(
3223
- "div",
3224
- {
3225
- style: {
3226
- position: "absolute",
3227
- left: Math.min(s.x, r.x),
3228
- top: Math.min(s.y, r.y),
3229
- width: Math.abs(r.x - s.x),
3230
- height: Math.abs(r.y - s.y),
3231
- border: "2px solid #fff",
3232
- backgroundColor: "rgba(255, 255, 255, 0.1)",
3233
- boxShadow: "0 0 0 9999px rgba(0, 0, 0, 0.5)"
3234
- // Clever trick to dim outside
3235
- }
3236
- }
3237
- )
3238
- ]
3239
- }
3240
- );
3241
- }, go = ({
3242
- questionId: e,
3243
- contextData: n,
3244
- onSubmit: t,
3245
- themeColor: i = "#3b82f6",
3246
- triggerComponent: s,
3247
- isOpen: o,
3248
- onOpen: r,
3249
- onClose: a,
3250
- isEnableCaptureFull: d = !0,
3251
- isEnableCaptureElement: g = !0
3252
- }) => {
3253
- const [l, m] = L(!1), [b, x] = L(""), [C, w] = L(e), [E, y] = L(n?.questionIdChild || ""), [T, S] = L([]), [D, F] = L(null), [z, q] = L(!1), [j, fe] = L(!1), [N, U] = L(!1), [B, ge] = L(null), [H, he] = L({}), [Tt, ze] = L("incorrect_content"), [Mn, nt] = L(!1), It = Mt.useRef(null), it = o !== void 0 ? o : l, On = it && !Mn;
3254
- Mt.useEffect(() => {
3255
- it && (he({}), w(e), y(n?.questionIdChild || ""), S([]), x(""), ze("incorrect_content"));
3256
- }, [it, e, n]);
3257
- const Dn = () => {
3258
- if (T.length >= 3) {
3259
- alert("Bạn chỉ có thể chụp tối đa 3 ảnh.");
3260
- return;
3261
- }
3262
- It.current?.click();
3263
- }, Fn = (v) => {
3264
- const M = v.target.files?.[0];
3265
- if (!M) return;
3266
- if (!M.type.startsWith("image/")) {
3267
- alert("Vui lòng chọn file ảnh.");
3268
- return;
3269
- }
3270
- if (M.size > 5 * 1024 * 1024) {
3271
- alert("Ảnh quá lớn. Vui lòng chọn ảnh dưới 5MB.");
3272
- return;
3273
- }
3274
- const K = new FileReader();
3275
- K.onload = (Be) => {
3276
- const Pe = Be.target?.result;
3277
- Pe && S((Nt) => [...Nt, Pe]);
3278
- }, K.readAsDataURL(M), v.target.value = "";
3279
- }, _n = () => {
3280
- S([]), x(""), w(e), y(n?.questionIdChild || ""), ze("incorrect_content"), he({}), o === void 0 && m(!0);
3281
- }, Rt = async (v) => {
3282
- if (console.log("click capture", performance.now()), T.length >= 3) {
3283
- alert("Bạn chỉ có thể chụp tối đa 3 ảnh.");
3284
- return;
3285
- }
3286
- if (nt(!0), v === "crop") {
3287
- setTimeout(() => U(!0), 150);
3288
- return;
3289
- }
3290
- setTimeout(async () => {
3291
- await At();
3292
- }, 150);
3293
- }, At = async (v) => {
3294
- console.log("performCapture start", performance.now()), q(!0);
3295
- try {
3296
- const M = await qr(v);
3297
- console.log("performCapture end", performance.now()), M ? S((K) => [...K, M]) : alert("Không thể chụp ảnh màn hình. Vui lòng thử lại.");
3298
- } catch (M) {
3299
- console.error(M);
3300
- } finally {
3301
- q(!1), nt(!1);
3302
- }
3303
- }, Ln = (v) => {
3304
- U(!1), At(v);
3305
- }, Un = () => {
3306
- U(!1), nt(!1);
3307
- }, zn = (v) => {
3308
- S((M) => M.filter((K, Be) => Be !== v));
3309
- }, rt = () => {
3310
- a && a(), m(!1), S([]), U(!1), F(null), x(""), he({}), ze("incorrect_content");
3311
- }, Bn = async () => {
3312
- const v = {};
3313
- if (C ? isNaN(Number(C)) && (v.questionId = "ID câu hỏi phải là số") : v.questionId = "Vui lòng nhập ID câu hỏi", E && isNaN(Number(E)) && (v.questionIdChild = "ID câu hỏi con phải là số"), b.trim() || (v.description = "Vui lòng nhập mô tả lỗi"), Object.keys(v).length > 0) {
3314
- he(v);
3315
- return;
3316
- }
3317
- fe(!0);
3318
- try {
3319
- const M = ti(), K = await Promise.all(
3320
- T.map(async (Pe) => (await (await fetch("https://lcms.icanwork.vn/api/upload-to-s3/upload-image-error-to-s3", {
3321
- method: "POST",
3322
- headers: {
3323
- "Content-Type": "application/json"
3324
- },
3325
- body: JSON.stringify({
3326
- base64: Pe
3327
- })
3328
- })).json()).file_url)
3329
- );
3330
- await t({
3331
- idQuestion: C,
3332
- idChildQuestion: E,
3333
- errorType: Tt,
3334
- errorDescription: b,
3335
- listImage: K,
3336
- deviceInfo: M,
3337
- contextData: n
3338
- }), rt();
3339
- } catch (M) {
3340
- console.error("Submit feedback failed", M);
3341
- } finally {
3342
- fe(!1);
3343
- }
3344
- };
3345
- return /* @__PURE__ */ R(Ne, { children: [
3346
- /* @__PURE__ */ k("style", { id: "feedback-widget-styles", children: `
3347
- @keyframes fb-fade-in {
3348
- from { opacity: 0; transform: translateY(10px); }
3349
- to { opacity: 1; transform: translateY(0); }
3350
- }
3351
- @keyframes fb-spin {
3352
- from { transform: rotate(0deg); }
3353
- to { transform: rotate(360deg); }
3354
- }
3355
- .fb-widget-modal {
3356
- animation: fb-fade-in 0.3s cubic-bezier(0.16, 1, 0.3, 1);
3357
- position: fixed;
3358
- bottom: 80px;
3359
- right: 24px;
3360
- z-index: 9999;
3361
- background: white;
3362
- padding: 16px;
3363
- border-radius: 12px;
3364
- width: 280px;
3365
- max-width: 90vw;
3366
- max-height: 80vh;
3367
- overflow-y: auto;
3368
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06), 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
3369
- border: 1px solid #f3f4f6;
3370
- display: flex;
3371
- flex-direction: column;
3372
- gap: 12px;
3373
- text-align: left;
3374
- box-sizing: border-box;
3375
- }
3376
- @media (max-width: 640px) {
3377
- .fb-widget-modal {
3378
- bottom: 70px !important;
3379
- right: 5% !important;
3380
- width: 90% !important;
3381
- max-height: 70vh !important;
3382
- }
3383
- .fb-widget-trigger {
3384
- bottom: 20px !important;
3385
- right: 20px !important;
3386
- }
3387
- /* Prevent iOS zoom on inputs */
3388
- input, select, textarea {
3389
- font-size: 16px !important;
3390
- }
3391
- }
3392
- @media (max-width: 820px) {
3393
- .fb-btn-crop {
3394
- display: none !important;
3395
- }
3396
- /* Enforce 16px font on all mobile/tablet inputs to prevent zoom */
3397
- .fb-widget-modal input,
3398
- .fb-widget-modal select,
3399
- .fb-widget-modal textarea {
3400
- font-size: 16px !important;
3401
- }
3402
- }
3403
- @media (min-width: 768px) {
3404
- .fb-btn-upload {
3405
-
3406
- }
3407
- }
3408
- ` }),
3409
- N && /* @__PURE__ */ k(fo, { onConfirm: Ln, onCancel: Un }),
3410
- D && /* @__PURE__ */ k(
3411
- "div",
3412
- {
3413
- style: {
3414
- position: "fixed",
3415
- inset: 0,
3416
- backgroundColor: "rgba(0,0,0,0.8)",
3417
- zIndex: 1e4,
3418
- display: "flex",
3419
- alignItems: "center",
3420
- justifyContent: "center",
3421
- cursor: "zoom-out",
3422
- animation: "fb-fade-in 0.2s ease-out",
3423
- backdropFilter: "blur(4px)"
3424
- },
3425
- onClick: () => F(null),
3426
- children: /* @__PURE__ */ k(
3427
- "img",
3428
- {
3429
- src: D,
3430
- alt: "Zoomed",
3431
- draggable: !1,
3432
- onContextMenu: (v) => v.preventDefault(),
3433
- style: {
3434
- maxWidth: "90vw",
3435
- maxHeight: "90vh",
3436
- objectFit: "contain",
3437
- borderRadius: "8px",
3438
- boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1)",
3439
- backgroundColor: "white",
3440
- userSelect: "none",
3441
- WebkitUserSelect: "none"
3442
- }
3443
- }
3444
- )
3445
- }
3446
- ),
3447
- /* @__PURE__ */ k("div", { onClick: () => {
3448
- o === void 0 ? _n() : r && r();
3449
- }, style: { cursor: "pointer", display: "inline-block" }, children: s || /* @__PURE__ */ k(
3450
- "button",
3451
- {
3452
- className: "fb-widget-trigger",
3453
- style: {
3454
- position: "fixed",
3455
- bottom: "24px",
3456
- right: "24px",
3457
- backgroundColor: i,
3458
- color: "white",
3459
- border: "none",
3460
- borderRadius: "50%",
3461
- width: "48px",
3462
- height: "48px",
3463
- display: "flex",
3464
- alignItems: "center",
3465
- justifyContent: "center",
3466
- boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
3467
- cursor: "pointer",
3468
- zIndex: 9990,
3469
- transition: "transform 0.2s"
3470
- },
3471
- title: "Báo lỗi",
3472
- onMouseEnter: (v) => v.currentTarget.style.transform = "scale(1.1)",
3473
- onMouseLeave: (v) => v.currentTarget.style.transform = "scale(1)",
3474
- children: /* @__PURE__ */ k(oo, { size: 24 })
3475
- }
3476
- ) }),
3477
- z && /* @__PURE__ */ k("div", { style: { position: "fixed", top: 20, right: 20, background: "rgba(0,0,0,0.8)", color: "white", padding: "8px 12px", borderRadius: "8px", zIndex: 1e4, fontWeight: 500, backdropFilter: "blur(4px)", fontSize: "0.8rem" }, children: "Đang chụp..." }),
3478
- On && !N && !D && /* @__PURE__ */ R("div", { className: "fb-widget-modal", children: [
3479
- /* @__PURE__ */ R("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
3480
- /* @__PURE__ */ k("h2", { style: { margin: 0, fontSize: "1rem", fontWeight: 700, color: "#111827" }, children: "Báo lỗi" }),
3481
- /* @__PURE__ */ k(
3482
- "button",
3483
- {
3484
- onClick: rt,
3485
- style: {
3486
- background: "transparent",
3487
- border: "none",
3488
- cursor: "pointer",
3489
- color: "#6b7280",
3490
- padding: "4px",
3491
- display: "flex",
3492
- alignItems: "center",
3493
- justifyContent: "center",
3494
- borderRadius: "50%",
3495
- transition: "background-color 0.2s"
3496
- },
3497
- onMouseEnter: (v) => v.currentTarget.style.backgroundColor = "#f3f4f6",
3498
- onMouseLeave: (v) => v.currentTarget.style.backgroundColor = "transparent",
3499
- children: /* @__PURE__ */ k(sn, { size: 18 })
3500
- }
3501
- )
3502
- ] }),
3503
- /* @__PURE__ */ R("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
3504
- /* @__PURE__ */ R("div", { children: [
3505
- /* @__PURE__ */ R("label", { style: { display: "block", marginBottom: "2px", fontSize: "0.8rem", fontWeight: 600, color: "#374151" }, children: [
3506
- "ID Câu hỏi ",
3507
- n?.questionIdChild ? "bài đọc" : "",
3508
- " ",
3509
- /* @__PURE__ */ k("span", { style: { color: "#ef4444" }, children: "*" })
3510
- ] }),
3511
- /* @__PURE__ */ R("div", { style: {
3512
- position: "relative",
3513
- display: "flex",
3514
- alignItems: "center",
3515
- transition: "all 0.2s"
3516
- }, children: [
3517
- /* @__PURE__ */ k(on, { size: 12, style: {
3518
- position: "absolute",
3519
- left: "10px",
3520
- color: B === "id" ? i : H.questionId ? "#ef4444" : "#9ca3af",
3521
- transition: "color 0.2s",
3522
- pointerEvents: "none"
3523
- } }),
3524
- /* @__PURE__ */ k(
3525
- "input",
3526
- {
3527
- type: "text",
3528
- value: C,
3529
- onFocus: () => ge("id"),
3530
- onBlur: () => ge(null),
3531
- onChange: (v) => {
3532
- w(v.target.value), H.questionId && he((M) => ({ ...M, questionId: void 0 }));
3533
- },
3534
- disabled: !!e,
3535
- placeholder: "Nhập ID (ví dụ: 101)",
3536
- style: {
3537
- width: "100%",
3538
- padding: "6px 10px 6px 28px",
3539
- borderRadius: "6px",
3540
- border: `1px solid ${H.questionId ? "#ef4444" : B === "id" ? i : "#e5e7eb"}`,
3541
- boxShadow: B === "id" ? `0 0 0 2px ${i}20` : "none",
3542
- outline: "none",
3543
- fontSize: "0.85rem",
3544
- color: "#1f2937",
3545
- transition: "all 0.2s",
3546
- backgroundColor: "#f9fafb"
3547
- }
3548
- }
3549
- )
3550
- ] }),
3551
- H.questionId && /* @__PURE__ */ k("span", { style: { display: "block", marginTop: "2px", fontSize: "0.7rem", color: "#ef4444" }, children: H.questionId })
3552
- ] }),
3553
- n?.questionIdChild ? /* @__PURE__ */ R("div", { children: [
3554
- /* @__PURE__ */ k("label", { style: { display: "block", marginBottom: "2px", fontSize: "0.8rem", fontWeight: 600, color: "#374151" }, children: "ID Câu hỏi" }),
3555
- /* @__PURE__ */ R("div", { style: {
3556
- position: "relative",
3557
- display: "flex",
3558
- alignItems: "center",
3559
- transition: "all 0.2s"
3560
- }, children: [
3561
- /* @__PURE__ */ k(on, { size: 12, style: {
3562
- position: "absolute",
3563
- left: "10px",
3564
- color: B === "idChild" ? i : H.questionIdChild ? "#ef4444" : "#9ca3af",
3565
- transition: "color 0.2s",
3566
- pointerEvents: "none"
3567
- } }),
3568
- /* @__PURE__ */ k(
3569
- "input",
3570
- {
3571
- type: "text",
3572
- value: E,
3573
- onFocus: () => ge("idChild"),
3574
- onBlur: () => ge(null),
3575
- onChange: (v) => {
3576
- y(v.target.value);
3577
- },
3578
- placeholder: "Nhập ID (ví dụ: 101)",
3579
- disabled: !!n?.questionIdChild,
3580
- style: {
3581
- width: "100%",
3582
- padding: "6px 10px 6px 28px",
3583
- borderRadius: "6px",
3584
- border: `1px solid ${H.questionIdChild ? "#ef4444" : B === "idChild" ? i : "#e5e7eb"}`,
3585
- boxShadow: B === "idChild" ? `0 0 0 2px ${i}20` : "none",
3586
- outline: "none",
3587
- fontSize: "0.85rem",
3588
- color: "#1f2937",
3589
- transition: "all 0.2s",
3590
- backgroundColor: "#f9fafb"
3591
- }
3592
- }
3593
- )
3594
- ] }),
3595
- H.questionIdChild && /* @__PURE__ */ k("span", { style: { display: "block", marginTop: "2px", fontSize: "0.7rem", color: "#ef4444" }, children: H.questionIdChild })
3596
- ] }) : /* @__PURE__ */ k(Ne, {}),
3597
- /* @__PURE__ */ R("div", { children: [
3598
- /* @__PURE__ */ R("label", { style: { display: "block", marginBottom: "2px", fontSize: "0.8rem", fontWeight: 600, color: "#374151" }, children: [
3599
- "Loại lỗi ",
3600
- /* @__PURE__ */ k("span", { style: { color: "#ef4444" }, children: "*" })
3601
- ] }),
3602
- /* @__PURE__ */ R(
3603
- "select",
3604
- {
3605
- value: Tt,
3606
- onChange: (v) => ze(v.target.value),
3607
- style: {
3608
- width: "100%",
3609
- padding: "6px 10px",
3610
- borderRadius: "6px",
3611
- border: "1px solid #e5e7eb",
3612
- backgroundColor: "#f9fafb",
3613
- fontSize: "0.85rem",
3614
- color: "#1f2937",
3615
- outline: "none",
3616
- cursor: "pointer",
3617
- appearance: "none",
3618
- backgroundImage: `url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'/%3e%3c/svg%3e")`,
3619
- backgroundRepeat: "no-repeat",
3620
- backgroundPosition: "right 10px center",
3621
- backgroundSize: "14px"
3622
- },
3623
- children: [
3624
- /* @__PURE__ */ k("option", { value: "incorrect_content", children: "Lỗi nội dung" }),
3625
- /* @__PURE__ */ k("option", { value: "display_error", children: "Lỗi hiển thị" }),
3626
- /* @__PURE__ */ k("option", { value: "missing_data", children: "Thiếu thông tin" }),
3627
- /* @__PURE__ */ k("option", { value: "technical_issue", children: "Lỗi kỹ thuật" }),
3628
- /* @__PURE__ */ k("option", { value: "other", children: "Khác" })
3629
- ]
3630
- }
3631
- )
3632
- ] }),
3633
- /* @__PURE__ */ R("div", { children: [
3634
- /* @__PURE__ */ R("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "2px" }, children: [
3635
- /* @__PURE__ */ R("label", { style: { fontSize: "0.8rem", fontWeight: 600, color: "#374151" }, children: [
3636
- "Mô tả lỗi ",
3637
- /* @__PURE__ */ k("span", { style: { color: "#ef4444" }, children: "*" })
3638
- ] }),
3639
- /* @__PURE__ */ R("span", { style: { fontSize: "0.7rem", color: "#9ca3af" }, children: [
3640
- b.length,
3641
- "/1000"
3642
- ] })
3643
- ] }),
3644
- /* @__PURE__ */ R("div", { style: { position: "relative" }, children: [
3645
- /* @__PURE__ */ k("div", { style: {
3646
- position: "absolute",
3647
- left: "10px",
3648
- top: "8px",
3649
- pointerEvents: "none"
3650
- }, children: /* @__PURE__ */ k(co, { size: 12, style: {
3651
- color: B === "desc" ? i : H.description ? "#ef4444" : "#9ca3af",
3652
- transition: "color 0.2s"
3653
- } }) }),
3654
- /* @__PURE__ */ k(
3655
- "textarea",
3656
- {
3657
- value: b,
3658
- onFocus: () => ge("desc"),
3659
- onBlur: () => ge(null),
3660
- onChange: (v) => {
3661
- x(v.target.value), H.description && he((M) => ({ ...M, description: void 0 }));
3662
- },
3663
- maxLength: 1e3,
3664
- placeholder: "Mô tả chi tiết...",
3665
- style: {
3666
- width: "100%",
3667
- minHeight: "80px",
3668
- padding: "6px 10px 6px 28px",
3669
- borderRadius: "6px",
3670
- border: `1px solid ${H.description ? "#ef4444" : B === "desc" ? i : "#e5e7eb"}`,
3671
- boxShadow: B === "desc" ? `0 0 0 2px ${i}20` : "none",
3672
- outline: "none",
3673
- fontSize: "0.85rem",
3674
- color: "#1f2937",
3675
- resize: "vertical",
3676
- boxSizing: "border-box",
3677
- transition: "all 0.2s",
3678
- backgroundColor: "#f9fafb",
3679
- lineHeight: "1.4",
3680
- fontFamily: "inherit"
3681
- }
3682
- }
3683
- )
3684
- ] }),
3685
- H.description && /* @__PURE__ */ k("span", { style: { display: "block", marginTop: "2px", fontSize: "0.7rem", color: "#ef4444" }, children: H.description })
3686
- ] })
3687
- ] }),
3688
- /* @__PURE__ */ R("div", { style: { marginBottom: "2px" }, children: [
3689
- /* @__PURE__ */ k("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "6px" }, children: /* @__PURE__ */ R("label", { style: { fontWeight: 600, fontSize: "0.8rem", color: "#374151" }, children: [
3690
- "Ảnh chụp (",
3691
- T.length,
3692
- "/3)"
3693
- ] }) }),
3694
- T.length > 0 && /* @__PURE__ */ k("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "6px", marginBottom: "8px" }, children: T.map((v, M) => /* @__PURE__ */ R("div", { style: {
3695
- position: "relative",
3696
- aspectRatio: "16/9",
3697
- border: "1px solid #e5e7eb",
3698
- borderRadius: "6px",
3699
- overflow: "hidden",
3700
- boxShadow: "0 1px 2px rgba(0,0,0,0.05)"
3701
- }, children: [
3702
- /* @__PURE__ */ k(
3703
- "img",
3704
- {
3705
- src: v,
3706
- alt: `Screenshot ${M + 1}`,
3707
- draggable: !1,
3708
- onContextMenu: (K) => K.preventDefault(),
3709
- style: {
3710
- width: "100%",
3711
- height: "100%",
3712
- objectFit: "cover",
3713
- cursor: "zoom-in",
3714
- transition: "transform 0.2s",
3715
- userSelect: "none",
3716
- WebkitUserSelect: "none"
3717
- },
3718
- onClick: () => F(v)
3719
- }
3720
- ),
3721
- /* @__PURE__ */ k(
3722
- "button",
3723
- {
3724
- onClick: () => zn(M),
3725
- title: "Xóa ảnh",
3726
- style: {
3727
- position: "absolute",
3728
- top: "2px",
3729
- right: "2px",
3730
- background: "rgba(239, 68, 68, 0.9)",
3731
- color: "white",
3732
- border: "none",
3733
- borderRadius: "50%",
3734
- width: "16px",
3735
- height: "16px",
3736
- display: "flex",
3737
- alignItems: "center",
3738
- justifyContent: "center",
3739
- cursor: "pointer",
3740
- padding: 0,
3741
- boxShadow: "0 1px 2px rgba(0,0,0,0.2)"
3742
- },
3743
- children: /* @__PURE__ */ k(sn, { size: 10 })
3744
- }
3745
- )
3746
- ] }, M)) }),
3747
- /* @__PURE__ */ R("div", { style: { display: "flex", gap: "8px" }, children: [
3748
- /* @__PURE__ */ k(
3749
- "input",
3750
- {
3751
- type: "file",
3752
- ref: It,
3753
- style: { display: "none" },
3754
- accept: "image/*",
3755
- onChange: Fn
3756
- }
3757
- ),
3758
- d ? /* @__PURE__ */ R(
3759
- "button",
3760
- {
3761
- onClick: () => Rt("full"),
3762
- style: {
3763
- flex: 1,
3764
- padding: "12px",
3765
- textAlign: "center",
3766
- background: "white",
3767
- border: "1px dashed #d1d5db",
3768
- borderRadius: "8px",
3769
- color: "#4b5563",
3770
- cursor: "pointer",
3771
- display: "flex",
3772
- flexDirection: "column",
3773
- alignItems: "center",
3774
- gap: "4px",
3775
- transition: "all 0.2s",
3776
- minWidth: "60px"
3777
- // Prevent squishing
3778
- },
3779
- onMouseOver: (v) => {
3780
- v.currentTarget.style.borderColor = i, v.currentTarget.style.color = i, v.currentTarget.style.backgroundColor = "#f9fafb";
3781
- },
3782
- onMouseOut: (v) => {
3783
- v.currentTarget.style.borderColor = "#d1d5db", v.currentTarget.style.color = "#4b5563", v.currentTarget.style.backgroundColor = "white";
3784
- },
3785
- children: [
3786
- /* @__PURE__ */ k(ao, { size: 18 }),
3787
- /* @__PURE__ */ k("span", { style: { fontSize: "0.8rem", fontWeight: 500 }, children: "Toàn màn hình" })
3788
- ]
3789
- }
3790
- ) : /* @__PURE__ */ k(Ne, {}),
3791
- g ? /* @__PURE__ */ R(
3792
- "button",
3793
- {
3794
- onClick: () => Rt("crop"),
3795
- className: "fb-btn-crop",
3796
- style: {
3797
- flex: 1,
3798
- padding: "12px",
3799
- textAlign: "center",
3800
- background: "white",
3801
- border: "1px dashed #d1d5db",
3802
- borderRadius: "8px",
3803
- color: "#4b5563",
3804
- cursor: "pointer",
3805
- display: "flex",
3806
- flexDirection: "column",
3807
- alignItems: "center",
3808
- gap: "4px",
3809
- transition: "all 0.2s",
3810
- minWidth: "60px"
3811
- },
3812
- onMouseOver: (v) => {
3813
- v.currentTarget.style.borderColor = i, v.currentTarget.style.color = i, v.currentTarget.style.backgroundColor = "#f9fafb";
3814
- },
3815
- onMouseOut: (v) => {
3816
- v.currentTarget.style.borderColor = "#d1d5db", v.currentTarget.style.color = "#4b5563", v.currentTarget.style.backgroundColor = "white";
3817
- },
3818
- children: [
3819
- /* @__PURE__ */ k(Kr, { size: 18 }),
3820
- /* @__PURE__ */ k("span", { style: { fontSize: "0.8rem", fontWeight: 500 }, children: "Chọn vùng" })
3821
- ]
3822
- }
3823
- ) : /* @__PURE__ */ k(Ne, {}),
3824
- /* @__PURE__ */ R(
3825
- "button",
3826
- {
3827
- onClick: Dn,
3828
- className: "fb-btn-upload",
3829
- style: {
3830
- flex: 1,
3831
- padding: "12px",
3832
- textAlign: "center",
3833
- background: "white",
3834
- border: "1px dashed #d1d5db",
3835
- borderRadius: "8px",
3836
- color: "#4b5563",
3837
- cursor: "pointer",
3838
- display: "flex",
3839
- flexDirection: "column",
3840
- alignItems: "center",
3841
- gap: "4px",
3842
- transition: "all 0.2s",
3843
- minWidth: "60px"
3844
- },
3845
- onMouseOver: (v) => {
3846
- v.currentTarget.style.borderColor = i, v.currentTarget.style.color = i, v.currentTarget.style.backgroundColor = "#f9fafb";
3847
- },
3848
- onMouseOut: (v) => {
3849
- v.currentTarget.style.borderColor = "#d1d5db", v.currentTarget.style.color = "#4b5563", v.currentTarget.style.backgroundColor = "white";
3850
- },
3851
- children: [
3852
- /* @__PURE__ */ k(to, { size: 18 }),
3853
- /* @__PURE__ */ k("span", { style: { fontSize: "0.8rem", fontWeight: 500 }, children: "Chọn ảnh" })
3854
- ]
3855
- }
3856
- )
3857
- ] })
3858
- ] }),
3859
- /* @__PURE__ */ R("div", { style: { display: "flex", justifyContent: "flex-end", gap: "8px", marginTop: "auto", paddingTop: "8px", borderTop: "1px solid #f3f4f6" }, children: [
3860
- /* @__PURE__ */ k(
3861
- "button",
3862
- {
3863
- onClick: rt,
3864
- disabled: j,
3865
- style: {
3866
- padding: "8px 16px",
3867
- borderRadius: "8px",
3868
- border: "1px solid #d1d5db",
3869
- background: "white",
3870
- cursor: "pointer",
3871
- color: "#374151",
3872
- fontWeight: 500,
3873
- fontSize: "0.85rem",
3874
- transition: "background-color 0.2s"
3875
- },
3876
- onMouseEnter: (v) => v.currentTarget.style.background = "#f9fafb",
3877
- onMouseLeave: (v) => v.currentTarget.style.background = "white",
3878
- children: "Hủy bỏ"
3879
- }
3880
- ),
3881
- /* @__PURE__ */ k(
3882
- "button",
3883
- {
3884
- onClick: Bn,
3885
- disabled: j,
3886
- style: {
3887
- padding: "8px 16px",
3888
- borderRadius: "8px",
3889
- border: "none",
3890
- background: i,
3891
- color: "white",
3892
- cursor: j ? "not-allowed" : "pointer",
3893
- fontWeight: 600,
3894
- fontSize: "0.85rem",
3895
- opacity: j ? 0.7 : 1,
3896
- boxShadow: "0 2px 4px -1px rgba(0, 0, 0, 0.1)",
3897
- transition: "transform 0.1s, opacity 0.2s"
3898
- },
3899
- onMouseDown: (v) => !j && (v.currentTarget.style.transform = "scale(0.98)"),
3900
- onMouseUp: (v) => !j && (v.currentTarget.style.transform = "scale(1)"),
3901
- children: j ? /* @__PURE__ */ R("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
3902
- /* @__PURE__ */ k(io, { size: 16, style: { animation: "fb-spin 1s linear infinite" } }),
3903
- /* @__PURE__ */ k("span", { children: "Đang gửi..." })
3904
- ] }) : "Gửi báo lỗi"
3905
- }
3906
- )
3907
- ] })
3908
- ] })
3909
- ] });
3910
- }, Nn = Pn(void 0), bo = () => {
3911
- const e = Hn(Nn);
3912
- if (!e)
3913
- throw new Error("useFeedback must be used within a FeedbackProvider");
3914
- return e;
3915
- }, yo = ({
3916
- children: e,
3917
- onSubmit: n,
3918
- themeColor: t
3919
- }) => {
3920
- const [i, s] = L(!1), [o, r] = L(null), [a, d] = L(void 0), g = (m, b) => {
3921
- r(m), d(b), s(!0);
3922
- }, l = () => {
3923
- s(!1);
3924
- };
3925
- return /* @__PURE__ */ R(Nn.Provider, { value: { openFeedback: g, closeFeedback: l, isOpen: i, activeQuestionId: o }, children: [
3926
- e,
3927
- o && /* @__PURE__ */ k(
3928
- go,
3929
- {
3930
- questionId: o,
3931
- contextData: a,
3932
- onSubmit: n,
3933
- themeColor: t,
3934
- isOpen: i,
3935
- onClose: l,
3936
- triggerComponent: /* @__PURE__ */ k(Ne, {})
3937
- }
3938
- )
3939
- ] });
3940
- };
3941
- export {
3942
- yo as FeedbackProvider,
3943
- go as FeedbackWidget,
3944
- qr as captureScreenshot,
3945
- bo as useFeedback
3946
- };