bariweb-widget 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/AdminUI-CGKuDZdZ.js +66 -0
- package/dist/Watcher-CrSaF4Ov.js +226 -0
- package/dist/bariweb.iife.js +1346 -0
- package/dist/bariweb.js +3195 -0
- package/dist/favicon.svg +1 -0
- package/dist/icons.svg +24 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# BariWeb Accessibility Widget
|
|
2
|
+
|
|
3
|
+
Modern AI-powered accessibility widget for websites.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- **AI-powered Chat**: Assistance in finding elements and filling forms.
|
|
7
|
+
- **Accessibility Tools**: Text scaling, monochrome mode, dark contrast, and more.
|
|
8
|
+
- **Natural Language Support**: Kazakh, Russian, and English.
|
|
9
|
+
- **Mobile Friendly**: Fully responsive design.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
### Via Script Tag
|
|
14
|
+
Add the following script to your HTML file:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<script
|
|
18
|
+
src="https://unpkg.com/bariweb-widget@latest/dist/bariweb.iife.js"
|
|
19
|
+
data-client-id="YOUR_CLIENT_ID"
|
|
20
|
+
></script>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Via NPM
|
|
24
|
+
Install the package:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install bariweb-widget
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then import it in your application:
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
import 'bariweb-widget';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Configuration
|
|
37
|
+
|
|
38
|
+
The widget uses `data-client-id` attribute on the script tag or `client-id` attribute on the `<bw-widget>` element to identify the client.
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
Proprietary
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { n as e, r as t, t as n } from "./Watcher-CrSaF4Ov.js";
|
|
2
|
+
//#region src/lib/AdminUI.ts
|
|
3
|
+
var r = "\n #bw-admin-panel {\n position: fixed;\n bottom: 160px;\n right: 20px;\n z-index: 2147483647;\n width: 320px;\n background: #0f172a;\n border: 1px solid #334155;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 12px 50px rgba(0,0,0,0.6);\n font-family: Inter, system-ui, sans-serif;\n color: #f1f5f9;\n transition: border-color 0.3s;\n }\n #bw-admin-panel.trained {\n border-color: #10b981;\n }\n #bw-admin-panel.discovering {\n border-color: #a78bfa;\n }\n\n .bw-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n }\n .bw-panel-title {\n font-size: 13px;\n font-weight: 700;\n color: #a78bfa;\n }\n .bw-panel-close {\n background: none;\n border: none;\n color: #64748b;\n cursor: pointer;\n font-size: 16px;\n padding: 0;\n line-height: 1;\n }\n .bw-panel-close:hover { color: #f87171; }\n\n .bw-status-box {\n background: #1e293b;\n border-radius: 10px;\n padding: 12px;\n margin-bottom: 12px;\n border: 1px solid #334155;\n transition: all 0.3s;\n }\n .bw-status-box.trained {\n border-color: #10b981;\n background: rgba(16, 185, 129, 0.08);\n }\n .bw-status-box.draft {\n border-color: #f59e0b;\n background: rgba(245, 158, 11, 0.05);\n }\n\n .bw-status-indicator {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n .bw-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n .bw-status-dot.active { background: #4ade80; box-shadow: 0 0 8px #4ade80; animation: bw-pulse 2s infinite; }\n .bw-status-dot.draft { background: #f59e0b; }\n .bw-status-dot.idle { background: #475569; }\n\n @keyframes bw-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n }\n\n .bw-status-text {\n font-size: 11px;\n font-weight: 600;\n }\n .bw-status-text.trained { color: #4ade80; }\n .bw-status-text.draft { color: #f59e0b; }\n .bw-status-text.idle { color: #94a3b8; }\n\n .bw-label-display {\n font-size: 14px;\n font-weight: 700;\n color: #e2e8f0;\n margin: 4px 0;\n word-break: break-word;\n }\n .bw-desc-display {\n font-size: 11px;\n color: #94a3b8;\n line-height: 1.4;\n margin-top: 4px;\n }\n\n .bw-fp-mini {\n font-family: monospace;\n font-size: 9px;\n color: #475569;\n margin-bottom: 10px;\n word-break: break-all;\n }\n\n .bw-tokens-list {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .bw-token-tag {\n background: #334155;\n color: #e2e8f0;\n font-size: 9px;\n padding: 2px 6px;\n border-radius: 4px;\n cursor: help;\n transition: all 0.15s;\n }\n .bw-token-tag:hover {\n background: #7c3aed;\n color: white;\n transform: translateY(-1px);\n }\n\n .bw-discovery-bar {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px;\n background: rgba(167, 139, 250, 0.08);\n border: 1px solid rgba(167, 139, 250, 0.2);\n border-radius: 8px;\n font-size: 10px;\n color: #a78bfa;\n margin-top: 8px;\n }\n .bw-discovery-bar .spinner {\n width: 12px;\n height: 12px;\n border: 2px solid rgba(167, 139, 250, 0.3);\n border-top-color: #a78bfa;\n border-radius: 50%;\n animation: bw-spin 0.8s linear infinite;\n }\n @keyframes bw-spin {\n to { transform: rotate(360deg); }\n }\n\n .bw-highlight-rect {\n position: absolute;\n pointer-events: none;\n border: 2px solid #7c3aed;\n background: rgba(124, 58, 237, 0.1);\n box-shadow: 0 0 10px #7c3aed;\n z-index: 100000;\n border-radius: 4px;\n transition: all 0.15s ease-out;\n }\n", i = null, a = null;
|
|
4
|
+
function o() {
|
|
5
|
+
if (!i) return;
|
|
6
|
+
let n = e(), r = t(), o = a?.is_trained === !0, c = a && !a.is_trained, l = a?.label || null, u = a?.description || null, d = o ? "active" : c ? "draft" : "idle", f = o ? "trained" : c ? "draft" : "idle", p = o ? "✅ Обучено" : c ? "📝 Черновик (не подтверждено)" : "🔍 Сканирование...", m = i.querySelector("#bw-admin-panel");
|
|
7
|
+
m && (m.className = o ? "trained" : "discovering", m.id = "bw-admin-panel", o && m.classList.add("trained"));
|
|
8
|
+
let h = i.querySelector("#bw-panel-content");
|
|
9
|
+
h && (h.innerHTML = `
|
|
10
|
+
<div class="bw-status-box ${o ? "trained" : c ? "draft" : ""}">
|
|
11
|
+
<div class="bw-status-indicator">
|
|
12
|
+
<span class="bw-status-dot ${d}"></span>
|
|
13
|
+
<span class="bw-status-text ${f}">${p}</span>
|
|
14
|
+
</div>
|
|
15
|
+
${l ? `<div class="bw-label-display">${l}</div>` : ""}
|
|
16
|
+
${u ? `<div class="bw-desc-display">${u}</div>` : ""}
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div class="bw-fp-mini">🔑 ${r}</div>
|
|
20
|
+
|
|
21
|
+
<div class="bw-tokens-list">
|
|
22
|
+
${n.map((e) => `<span class="bw-token-tag" data-token="${e}">${e}</span>`).join("")}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="bw-discovery-bar">
|
|
26
|
+
<div class="spinner"></div>
|
|
27
|
+
🤖 Система обучается в фоновом режиме...
|
|
28
|
+
</div>
|
|
29
|
+
`, h.querySelectorAll(".bw-token-tag").forEach((e) => {
|
|
30
|
+
let t = e;
|
|
31
|
+
t.onmouseenter = () => s(t.dataset.token || ""), t.onmouseleave = () => document.querySelectorAll(".bw-highlight-rect").forEach((e) => e.remove());
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
function s(e) {
|
|
35
|
+
document.querySelectorAll(".bw-highlight-rect").forEach((e) => e.remove());
|
|
36
|
+
let t = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT), n;
|
|
37
|
+
for (; n = t.nextNode();) if ((n.innerText || "").toLowerCase() === e.toLowerCase() && n.offsetWidth > 0) {
|
|
38
|
+
let e = n.getBoundingClientRect(), t = document.createElement("div");
|
|
39
|
+
t.className = "bw-highlight-rect", t.style.top = `${e.top + window.scrollY}px`, t.style.left = `${e.left + window.scrollX}px`, t.style.width = `${e.width}px`, t.style.height = `${e.height}px`, document.body.appendChild(t);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function c() {
|
|
43
|
+
if (i) return;
|
|
44
|
+
let e = document.createElement("div");
|
|
45
|
+
e.id = "bw-admin-wrapper", e.innerHTML = `
|
|
46
|
+
<style>${r}</style>
|
|
47
|
+
<div id="bw-admin-panel">
|
|
48
|
+
<div class="bw-panel-header">
|
|
49
|
+
<span class="bw-panel-title">🧠 Discovery Mode</span>
|
|
50
|
+
<button class="bw-panel-close" id="bw-admin-close">✕</button>
|
|
51
|
+
</div>
|
|
52
|
+
<div id="bw-panel-content"></div>
|
|
53
|
+
</div>
|
|
54
|
+
`, document.body.appendChild(e), i = e;
|
|
55
|
+
let t = e.querySelector("#bw-admin-close");
|
|
56
|
+
t.onclick = () => {
|
|
57
|
+
i?.remove(), i = null;
|
|
58
|
+
}, n.onDiscovery((e) => {
|
|
59
|
+
a = e, o();
|
|
60
|
+
}), o(), await n.forceDiscovery();
|
|
61
|
+
}
|
|
62
|
+
function l() {
|
|
63
|
+
c();
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { l as initAdminMode };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
//#region src/lib/Fingerprint.ts
|
|
2
|
+
var e = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, t = /\/\d{1,20}(?=\/|$)/g, n = /\/[a-z0-9]+(?:-[a-z0-9]+)*-\d+(?=\/|$)/g, r = /\/[0-9a-f]{8,}(?=\/|$)/gi, i = new Set([
|
|
3
|
+
"id",
|
|
4
|
+
"userId",
|
|
5
|
+
"user_id",
|
|
6
|
+
"orderId",
|
|
7
|
+
"order_id",
|
|
8
|
+
"itemId",
|
|
9
|
+
"item_id",
|
|
10
|
+
"productId",
|
|
11
|
+
"product_id",
|
|
12
|
+
"token",
|
|
13
|
+
"key",
|
|
14
|
+
"ref",
|
|
15
|
+
"code",
|
|
16
|
+
"session"
|
|
17
|
+
]);
|
|
18
|
+
function a(a) {
|
|
19
|
+
try {
|
|
20
|
+
let o = new URL(a), s = o.pathname;
|
|
21
|
+
s = s.replace(e, ":id"), s = s.replace(t, "/:id"), s = s.replace(n, "/:slug"), s = s.replace(r, "/:id");
|
|
22
|
+
let c = new URLSearchParams();
|
|
23
|
+
o.searchParams.forEach((e, t) => {
|
|
24
|
+
i.has(t) ? c.set(`:${t}`, "") : e.length < 30 && !/^\d+$/.test(e) && c.set(t, e);
|
|
25
|
+
});
|
|
26
|
+
let l = c.toString();
|
|
27
|
+
return s.replace(/\/$/, "") + (l ? `?${l}` : "");
|
|
28
|
+
} catch {
|
|
29
|
+
return a.replace(e, ":id").replace(/\/\d{1,20}(?=\/|$)/g, "/:id").split("?")[0];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
var o = new Set(/* @__PURE__ */ "ok,ок,okay,close,закрыть,cancel,отмена,yes,da,no,нет,да,submit,отправить,back,назад,next,далее,more,ещё,еще,menu,меню,...,•,·,loading,загрузка,open,открыть,expand,collapse,toggle,sort".split(","));
|
|
33
|
+
function s(e) {
|
|
34
|
+
let t = [
|
|
35
|
+
"dialog",
|
|
36
|
+
"tooltip",
|
|
37
|
+
"menu",
|
|
38
|
+
"listbox",
|
|
39
|
+
"alertdialog"
|
|
40
|
+
], n = e;
|
|
41
|
+
for (; n && n !== document.body;) {
|
|
42
|
+
let e = n.getAttribute("role") || "";
|
|
43
|
+
if (t.includes(e) || n.hasAttribute("data-radix-popper-content-wrapper") || n.hasAttribute("data-floating-ui-portal")) return !0;
|
|
44
|
+
let r = typeof n.className == "string" ? n.className : "";
|
|
45
|
+
if (/popover|tooltip|dropdown-menu|floating|overlay/i.test(r)) return !0;
|
|
46
|
+
n = n.parentElement;
|
|
47
|
+
}
|
|
48
|
+
return !1;
|
|
49
|
+
}
|
|
50
|
+
function c(e) {
|
|
51
|
+
let t = [
|
|
52
|
+
"li",
|
|
53
|
+
"article",
|
|
54
|
+
"tr",
|
|
55
|
+
"dd"
|
|
56
|
+
], n = e.parentElement, r = 0;
|
|
57
|
+
for (; n && n !== document.body && r < 8;) {
|
|
58
|
+
let e = n.tagName.toLowerCase();
|
|
59
|
+
if (t.includes(e)) return !0;
|
|
60
|
+
let i = typeof n.className == "string" ? n.className : "";
|
|
61
|
+
if (/\b(card|item|tile|post|entry|product|row-item|list-item|feed-item|cell)\b/i.test(i)) {
|
|
62
|
+
let e = n.parentElement?.children;
|
|
63
|
+
if (e && e.length > 2) return !0;
|
|
64
|
+
}
|
|
65
|
+
let a = n.getAttribute("role") || "";
|
|
66
|
+
if (a === "listitem" || a === "row" || a === "gridcell") return !0;
|
|
67
|
+
n = n.parentElement, r++;
|
|
68
|
+
}
|
|
69
|
+
return !1;
|
|
70
|
+
}
|
|
71
|
+
function l(e) {
|
|
72
|
+
let t = e, n = (t.getAttribute("aria-label") || t.getAttribute("title") || t.innerText || t.getAttribute("placeholder") || "").trim().toLowerCase();
|
|
73
|
+
return !n || n.length < 2 || n.length > 40 || /^[\d\s₸$€%.,\-+:()]+$/.test(n) || /^\d{1,2}[./]\d{1,2}/.test(n) || o.has(n) ? "" : n.replace(/^[\p{Emoji}\s]+/u, "").trim().slice(0, 30);
|
|
74
|
+
}
|
|
75
|
+
function u(e) {
|
|
76
|
+
let t = 5381;
|
|
77
|
+
for (let n = 0; n < e.length; n++) t = (t << 5) + t ^ e.charCodeAt(n);
|
|
78
|
+
return (t >>> 0).toString(16);
|
|
79
|
+
}
|
|
80
|
+
function d() {
|
|
81
|
+
let e = [], t = a(window.location.href);
|
|
82
|
+
e.push(`route:${t}`);
|
|
83
|
+
let n = document.querySelector("h1");
|
|
84
|
+
if (n) {
|
|
85
|
+
let t = n.innerText?.trim().toLowerCase();
|
|
86
|
+
t && t.length > 1 && t.length < 50 && !/\d{3,}/.test(t) && e.push(`h1:${t.slice(0, 30)}`);
|
|
87
|
+
}
|
|
88
|
+
let r = Array.from(document.querySelectorAll("input:not([type=\"hidden\"]):not([type=\"submit\"]):not([type=\"radio\"]):not([type=\"checkbox\"]), textarea, select")).slice(0, 8);
|
|
89
|
+
for (let t of r) {
|
|
90
|
+
if (s(t)) continue;
|
|
91
|
+
let n = t, r = (n.getAttribute("name") || n.getAttribute("placeholder") || n.getAttribute("aria-label") || "").toLowerCase().trim().slice(0, 25);
|
|
92
|
+
r && r.length > 1 && !o.has(r) && e.push(`field:${r}`);
|
|
93
|
+
}
|
|
94
|
+
let i = Array.from(document.querySelectorAll("nav a, [role=\"navigation\"] a")).slice(0, 6);
|
|
95
|
+
for (let t of i) {
|
|
96
|
+
if (s(t)) continue;
|
|
97
|
+
let n = l(t);
|
|
98
|
+
n && e.push(`nav:${n}`);
|
|
99
|
+
}
|
|
100
|
+
let u = document.querySelector("main") || document.querySelector("[role=\"main\"]") || document.getElementById("root");
|
|
101
|
+
return u && Array.from(u.querySelectorAll("button:not([aria-hidden=\"true\"]), [role=\"button\"]:not([aria-hidden=\"true\"])")).filter((e) => !s(e) && !c(e)).map(l).filter((e) => e.length > 1).reduce((e, t) => e.includes(t) ? e : [...e, t], []).slice(0, 3).forEach((t) => e.push(`btn:${t}`)), [...new Set(e)].sort().slice(0, 15);
|
|
102
|
+
}
|
|
103
|
+
function f() {
|
|
104
|
+
return `bw-${u(d().join("|"))}`;
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region src/lib/Watcher.ts
|
|
108
|
+
function p(e, t) {
|
|
109
|
+
let n = new Set([...e].filter((e) => t.has(e))), r = new Set([...e, ...t]);
|
|
110
|
+
return r.size === 0 ? 1 : n.size / r.size;
|
|
111
|
+
}
|
|
112
|
+
var m = new class {
|
|
113
|
+
constructor(e = 1500) {
|
|
114
|
+
this._observer = null, this._debounceTimer = null, this._lastTokens = /* @__PURE__ */ new Set(), this._lastUrl = "", this._callbacks = [], this._discoveryCallbacks = [], this._isDiscovering = !1, this.isAutoDiscoveryEnabled = !1, this._debounceMs = e;
|
|
115
|
+
}
|
|
116
|
+
start() {
|
|
117
|
+
this._observer || (this._lastTokens = new Set(d()), this._lastUrl = a(window.location.href), this._observer = new MutationObserver(() => {
|
|
118
|
+
this._debounceTimer && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._onMutation(), this._debounceMs);
|
|
119
|
+
}), this._observer.observe(document.body, {
|
|
120
|
+
childList: !0,
|
|
121
|
+
subtree: !0,
|
|
122
|
+
attributes: !1,
|
|
123
|
+
characterData: !1
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
stop() {
|
|
127
|
+
this._observer?.disconnect(), this._observer = null, this._debounceTimer && clearTimeout(this._debounceTimer);
|
|
128
|
+
}
|
|
129
|
+
onStateChange(e) {
|
|
130
|
+
this._callbacks.push(e);
|
|
131
|
+
}
|
|
132
|
+
onDiscovery(e) {
|
|
133
|
+
this._discoveryCallbacks.push(e);
|
|
134
|
+
}
|
|
135
|
+
get isDiscovering() {
|
|
136
|
+
return this._isDiscovering;
|
|
137
|
+
}
|
|
138
|
+
getLiveSnapshot() {
|
|
139
|
+
let e = (e, t) => {
|
|
140
|
+
if (e.hasAttribute("bw-private") || e.hasAttribute("data-bw-private")) return "[MASKED]";
|
|
141
|
+
if (!t) return t;
|
|
142
|
+
let n = t.replace(/(?:\d[ \-]*?){13,16}/g, "****");
|
|
143
|
+
return n = n.replace(/\b\d{12}\b/g, "****"), n;
|
|
144
|
+
}, t = Array.from(document.querySelectorAll("h1, h2")).map((t) => e(t, t.innerText?.trim() || "")).filter(Boolean).slice(0, 3), n = Array.from(document.querySelectorAll("button, a[href], [role=\"button\"]")).map((t) => {
|
|
145
|
+
let n = t, r = e(n, (n.getAttribute("aria-label") || n.innerText || "").trim().slice(0, 60));
|
|
146
|
+
return {
|
|
147
|
+
id: n.id || "",
|
|
148
|
+
text: r
|
|
149
|
+
};
|
|
150
|
+
}).filter((e) => e.text.length > 0).slice(0, 30);
|
|
151
|
+
return {
|
|
152
|
+
url: window.location.href,
|
|
153
|
+
headings: t,
|
|
154
|
+
fingerprint: f(),
|
|
155
|
+
elements: n
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async _onMutation() {
|
|
159
|
+
if (document.readyState !== "complete") return;
|
|
160
|
+
let e = a(window.location.href), t = new Set(d());
|
|
161
|
+
if (t.size < 2) return;
|
|
162
|
+
let n = f(), r = e !== this._lastUrl, i = p(this._lastTokens, t);
|
|
163
|
+
if (r || i < .55) {
|
|
164
|
+
let a = r ? `URL: ${this._lastUrl} → ${e}` : `Sim: ${i.toFixed(2)}`;
|
|
165
|
+
console.log(`[Watcher] Screen change (${a})`), this._lastUrl = e, this._lastTokens = t;
|
|
166
|
+
let o = this.getLiveSnapshot();
|
|
167
|
+
if (this.isAutoDiscoveryEnabled) {
|
|
168
|
+
let e = this._buildTypedTokens();
|
|
169
|
+
this._discover(n, e).catch(() => {});
|
|
170
|
+
}
|
|
171
|
+
this._callbacks.forEach((e) => e(o));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
_buildTypedTokens() {
|
|
175
|
+
let e = /* @__PURE__ */ new Set(), t = [], n = (n, r) => {
|
|
176
|
+
let i = r.trim().slice(0, 40);
|
|
177
|
+
if (!i || i.length < 2) return;
|
|
178
|
+
let a = `${n}:${i}`;
|
|
179
|
+
e.has(a) || (e.add(a), t.push(a));
|
|
180
|
+
};
|
|
181
|
+
return document.querySelectorAll("button, [role=\"button\"]").forEach((e) => {
|
|
182
|
+
let t = e.innerText?.trim();
|
|
183
|
+
t && n("btn", t);
|
|
184
|
+
}), document.querySelectorAll("a[href]").forEach((e) => {
|
|
185
|
+
let t = (e.getAttribute("aria-label") || e.innerText)?.trim();
|
|
186
|
+
t && n("a", t);
|
|
187
|
+
}), document.querySelectorAll("input:not([type=hidden]), textarea, select").forEach((e) => {
|
|
188
|
+
let t = e.placeholder || e.name;
|
|
189
|
+
t && n("input", t);
|
|
190
|
+
}), t.slice(0, 8);
|
|
191
|
+
}
|
|
192
|
+
async _discover(e, t) {
|
|
193
|
+
let n = localStorage.getItem("bw_admin_token");
|
|
194
|
+
if (n) {
|
|
195
|
+
this._isDiscovering = !0;
|
|
196
|
+
try {
|
|
197
|
+
let r = await fetch("http://localhost:8000/v1/training/discover", {
|
|
198
|
+
method: "POST",
|
|
199
|
+
headers: {
|
|
200
|
+
"Content-Type": "application/json",
|
|
201
|
+
Authorization: `Bearer ${n}`
|
|
202
|
+
},
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
fingerprint: e,
|
|
205
|
+
tokens: t,
|
|
206
|
+
page_url: window.location.href
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
if (r.ok) {
|
|
210
|
+
let e = await r.json();
|
|
211
|
+
console.log(`[Discovery] ${e.status} — ${e.label}`), this._discoveryCallbacks.forEach((t) => t(e));
|
|
212
|
+
} else r.status === 401 ? (console.warn("[Discovery] Token expired — disabling auto-discovery"), localStorage.removeItem("bw_admin_token"), this.isAutoDiscoveryEnabled = !1) : console.warn(`[Discovery] Server error ${r.status}`);
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.warn("[Discovery] Network error", e);
|
|
215
|
+
} finally {
|
|
216
|
+
this._isDiscovering = !1;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async forceDiscovery() {
|
|
221
|
+
let e = [...new Set(d())], t = f();
|
|
222
|
+
await this._discover(t, e);
|
|
223
|
+
}
|
|
224
|
+
}(1500);
|
|
225
|
+
//#endregion
|
|
226
|
+
export { d as n, f as r, m as t };
|