bariweb-widget 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bariweb.iife.js +34 -28
- package/dist/bariweb.js +99 -49
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/bariweb.iife.js
CHANGED
|
@@ -31,6 +31,12 @@
|
|
|
31
31
|
--bw-border: #e2e8f0;
|
|
32
32
|
--bw-bg-hover: #f8fafc;
|
|
33
33
|
--bw-bg-subtle: #f1f5f9;
|
|
34
|
+
--bw-danger: #ef4444;
|
|
35
|
+
--bw-danger-bg: #fee2e2;
|
|
36
|
+
--bw-danger-border: #fecaca;
|
|
37
|
+
--bw-success: #10b981;
|
|
38
|
+
--bw-success-bg: rgba(16, 185, 129, 0.08);
|
|
39
|
+
--bw-success-border: rgba(16, 185, 129, 0.2);
|
|
34
40
|
--bw-radius: 14px;
|
|
35
41
|
--bw-radius-sm: 8px;
|
|
36
42
|
--bw-shadow-panel: 0 20px 60px -10px rgba(0,0,0,0.18), 0 8px 24px -4px rgba(0,0,0,0.1);
|
|
@@ -143,7 +149,7 @@
|
|
|
143
149
|
transition: all 0.2s;
|
|
144
150
|
color: var(--bw-fg-muted);
|
|
145
151
|
}
|
|
146
|
-
.close-btn:hover { background:
|
|
152
|
+
.close-btn:hover { background: var(--bw-danger-bg); color: var(--bw-danger); transform: rotate(90deg); }
|
|
147
153
|
.close-btn svg { width: 18px; height: 18px; }
|
|
148
154
|
|
|
149
155
|
/* ─── Segmented Tab Control ─── */
|
|
@@ -177,8 +183,8 @@
|
|
|
177
183
|
.bw-tab:hover { background: var(--bw-bg-hover); color: var(--bw-fg); }
|
|
178
184
|
.bw-tab[active] {
|
|
179
185
|
background: var(--bw-primary);
|
|
180
|
-
color:
|
|
181
|
-
box-shadow: 0 2px 8px rgba(
|
|
186
|
+
color: var(--bw-primary-fg);
|
|
187
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
/* ─── Content area ─── */
|
|
@@ -273,7 +279,7 @@
|
|
|
273
279
|
.chat-bubble.user {
|
|
274
280
|
align-self: flex-end;
|
|
275
281
|
background: var(--bw-primary);
|
|
276
|
-
color:
|
|
282
|
+
color: var(--bw-primary-fg);
|
|
277
283
|
border-bottom-right-radius: 4px;
|
|
278
284
|
}
|
|
279
285
|
.chat-bubble.assistant {
|
|
@@ -285,12 +291,12 @@
|
|
|
285
291
|
}
|
|
286
292
|
|
|
287
293
|
.screen-label-badge {
|
|
288
|
-
background:
|
|
289
|
-
border: 1px solid
|
|
294
|
+
background: var(--bw-success-bg);
|
|
295
|
+
border: 1px solid var(--bw-success-border);
|
|
290
296
|
border-radius: var(--bw-radius-sm);
|
|
291
297
|
padding: 6px 12px;
|
|
292
298
|
font-size: 12px;
|
|
293
|
-
color:
|
|
299
|
+
color: var(--bw-success);
|
|
294
300
|
display: flex;
|
|
295
301
|
align-items: center;
|
|
296
302
|
gap: 6px;
|
|
@@ -354,17 +360,17 @@
|
|
|
354
360
|
}
|
|
355
361
|
.btn-confirm {
|
|
356
362
|
width: 100%; min-height: 46px; border-radius: var(--bw-radius-sm);
|
|
357
|
-
background: var(--bw-primary); color:
|
|
363
|
+
background: var(--bw-primary); color: var(--bw-primary-fg); border: none;
|
|
358
364
|
font-weight: 700; font-size: 14px; cursor: pointer;
|
|
359
|
-
transition: all 0.2s; box-shadow: 0 4px 12px rgba(
|
|
365
|
+
transition: all 0.2s; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
360
366
|
}
|
|
361
367
|
.btn-confirm:hover { filter: brightness(1.1); transform: translateY(-1px); }
|
|
362
368
|
.btn-cancel {
|
|
363
369
|
width: 100%; min-height: 44px; border-radius: var(--bw-radius-sm);
|
|
364
|
-
background: transparent; color:
|
|
370
|
+
background: transparent; color: var(--bw-danger); border: 1px solid var(--bw-danger-border);
|
|
365
371
|
font-weight: 600; font-size: 13px; cursor: pointer; transition: all 0.2s;
|
|
366
372
|
}
|
|
367
|
-
.btn-cancel:hover { background:
|
|
373
|
+
.btn-cancel:hover { background: var(--bw-danger-bg); }
|
|
368
374
|
|
|
369
375
|
/* Chat input area */
|
|
370
376
|
.chat-input-area {
|
|
@@ -443,14 +449,14 @@
|
|
|
443
449
|
}
|
|
444
450
|
#bw-voice-btn:hover { background: rgba(109, 40, 217, 0.08); transform: scale(1.05); }
|
|
445
451
|
#bw-voice-btn.recording {
|
|
446
|
-
background:
|
|
447
|
-
border-color:
|
|
448
|
-
color:
|
|
452
|
+
background: var(--bw-danger-bg);
|
|
453
|
+
border-color: var(--bw-danger);
|
|
454
|
+
color: var(--bw-danger);
|
|
449
455
|
animation: micPulse 1.5s infinite;
|
|
450
456
|
}
|
|
451
457
|
@keyframes micPulse {
|
|
452
|
-
0% { box-shadow: 0 0 0 0 rgba(
|
|
453
|
-
100% { box-shadow: 0 0 0 10px rgba(
|
|
458
|
+
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); transform: scale(1.05); }
|
|
459
|
+
100% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); transform: scale(1.05); }
|
|
454
460
|
}
|
|
455
461
|
|
|
456
462
|
.chat-icon-btn.tts-on { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.4); color: #059669; }
|
|
@@ -462,13 +468,13 @@
|
|
|
462
468
|
border-radius: 50%;
|
|
463
469
|
border: none;
|
|
464
470
|
background: var(--bw-primary);
|
|
465
|
-
color:
|
|
471
|
+
color: var(--bw-primary-fg);
|
|
466
472
|
cursor: pointer;
|
|
467
473
|
display: flex;
|
|
468
474
|
align-items: center;
|
|
469
475
|
justify-content: center;
|
|
470
476
|
transition: all 0.2s;
|
|
471
|
-
box-shadow: 0 2px 8px rgba(
|
|
477
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
472
478
|
margin-left: 6px;
|
|
473
479
|
}
|
|
474
480
|
.chat-send-btn:hover:not(:disabled) { transform: scale(1.08); filter: brightness(1.1); }
|
|
@@ -824,15 +830,7 @@
|
|
|
824
830
|
html[data-bw-has-custom-content] div:not(bw-widget *) {
|
|
825
831
|
color: var(--bw-custom-content) !important;
|
|
826
832
|
}
|
|
827
|
-
`}_applySettings(){let e=document.documentElement;this._ensureGlobalStyles(),e.style.setProperty(`--bw-grayscale`,this.settings.monochrome?`100%`:`0%`);let t=1;this.settings.lowSaturation&&(t=.3),this.settings.highSaturation&&(t=2.5),e.style.setProperty(`--bw-saturation`,t.toString()),this.settings.customBgHue===null?e.removeAttribute(`data-bw-has-custom-bg`):(e.style.setProperty(`--bw-custom-bg`,`hsl(${this.settings.customBgHue}, 50%, 95%)`),e.setAttribute(`data-bw-has-custom-bg`,``)),this.settings.customHeaderHue===null?e.removeAttribute(`data-bw-has-custom-header`):(e.style.setProperty(`--bw-custom-header`,`hsl(${this.settings.customHeaderHue}, 70%, 30%)`),e.setAttribute(`data-bw-has-custom-header`,``)),this.settings.customContentHue===null?e.removeAttribute(`data-bw-has-custom-content`):(e.style.setProperty(`--bw-custom-content`,`hsl(${this.settings.customContentHue}, 60%, 40%)`),e.setAttribute(`data-bw-has-custom-content`,``)),this.settings.textScale>1?e.style.fontSize=`${this.settings.textScale*100}%`:e.style.fontSize=``;let n={"data-bw-monochrome":this.settings.monochrome,"data-bw-dark-high-contrast":this.settings.darkHighContrast,"data-bw-bright-high-contrast":this.settings.brightHighContrast,"data-bw-contrast-mode":this.settings.contrastMode,"data-bw-text-spacing":this.settings.textSpacing,"data-bw-dyslexic":this.settings.dyslexicFont,"data-bw-focus-visualizer":this.settings.focusVisualizer,"data-bw-cursor-magnifier":this.settings.cursorMagnifier,"data-bw-no-animations":this.settings.animationsDisabled,"data-bw-link-highlight":this.settings.linkHighlight,"data-bw-highlight-headers":this.settings.highlightHeaders,"data-bw-enlarge-buttons":this.settings.enlargeButtons};Object.entries(n).forEach(([t,n])=>{n?e.setAttribute(t,``):e.removeAttribute(t)});let r=this.host;r&&r.style.setProperty(`--bw-font-scale`,this.settings.textScale.toString())}toggleMonochrome(){this.settings.monochrome=!this.settings.monochrome,this._saveSettings()}toggleDarkHighContrast(){this.settings.darkHighContrast=!this.settings.darkHighContrast,this.settings.darkHighContrast&&(this.settings.brightHighContrast=!1,this.settings.contrastMode=!1),this._saveSettings()}toggleBrightHighContrast(){this.settings.brightHighContrast=!this.settings.brightHighContrast,this.settings.brightHighContrast&&(this.settings.darkHighContrast=!1,this.settings.contrastMode=!1),this._saveSettings()}toggleLowSaturation(){this.settings.lowSaturation=!this.settings.lowSaturation,this.settings.lowSaturation&&(this.settings.highSaturation=!1),this._saveSettings()}toggleHighSaturation(){this.settings.highSaturation=!this.settings.highSaturation,this.settings.highSaturation&&(this.settings.lowSaturation=!1),this._saveSettings()}toggleContrastMode(){this.settings.contrastMode=!this.settings.contrastMode,this.settings.contrastMode&&(this.settings.darkHighContrast=!1,this.settings.brightHighContrast=!1),this._saveSettings()}setCustomHue(e){this.settings.activeColorTab===`background`?this.settings.customBgHue=e:this.settings.activeColorTab===`header`?this.settings.customHeaderHue=e:this.settings.customContentHue=e,this._saveSettings()}resetCustomColors(){this.settings.customBgHue=null,this.settings.customHeaderHue=null,this.settings.customContentHue=null,this._saveSettings()}toggleHighlightHeaders(){this.settings.highlightHeaders=!this.settings.highlightHeaders,this._saveSettings()}toggleEnlargeButtons(){this.settings.enlargeButtons=!this.settings.enlargeButtons,this._saveSettings()}incrementTextScale(){this.settings.textScale>=1.5?this.settings.textScale=1:this.settings.textScale=parseFloat((this.settings.textScale+.1).toFixed(1)),this._saveSettings()}toggleTextSpacing(){this.settings.textSpacing=!this.settings.textSpacing,this._saveSettings()}toggleDyslexicFont(){this.settings.dyslexicFont=!this.settings.dyslexicFont,this._saveSettings()}toggleFocusVisualizer(){this.settings.focusVisualizer=!this.settings.focusVisualizer,this._saveSettings()}toggleCursorMagnifier(){this.settings.cursorMagnifier=!this.settings.cursorMagnifier,this._saveSettings()}toggleAnimations(){this.settings.animationsDisabled=!this.settings.animationsDisabled,this._saveSettings()}toggleLinkHighlight(){this.settings.linkHighlight=!this.settings.linkHighlight,this._saveSettings()}reset(){this.settings={...U},this._saveSettings()}};function W(e){try{let t=new URL(e),n=t.pathname;n=n.replace(yt,`:id`),n=n.replace(bt,`/:id`),n=n.replace(xt,`/:slug`),n=n.replace(St,`/:id`);let r=new URLSearchParams;t.searchParams.forEach((e,t)=>{Ct.has(t)?r.set(`:${t}`,``):e.length<30&&!/^\d+$/.test(e)&&r.set(t,e)});let i=r.toString();return n.replace(/\/$/,``)+(i?`?${i}`:``)}catch{return e.replace(yt,`:id`).replace(/\/\d{1,20}(?=\/|$)/g,`/:id`).split(`?`)[0]}}function G(e){let t=[`dialog`,`tooltip`,`menu`,`listbox`,`alertdialog`],n=e;for(;n&&n!==document.body;){let e=n.getAttribute(`role`)||``;if(t.includes(e)||n.hasAttribute(`data-radix-popper-content-wrapper`)||n.hasAttribute(`data-floating-ui-portal`))return!0;let r=typeof n.className==`string`?n.className:``;if(/popover|tooltip|dropdown-menu|floating|overlay/i.test(r))return!0;n=n.parentElement}return!1}function gt(e){let t=[`li`,`article`,`tr`,`dd`],n=e.parentElement,r=0;for(;n&&n!==document.body&&r<8;){let e=n.tagName.toLowerCase();if(t.includes(e))return!0;let i=typeof n.className==`string`?n.className:``;if(/\b(card|item|tile|post|entry|product|row-item|list-item|feed-item|cell)\b/i.test(i)){let e=n.parentElement?.children;if(e&&e.length>2)return!0}let a=n.getAttribute(`role`)||``;if(a===`listitem`||a===`row`||a===`gridcell`)return!0;n=n.parentElement,r++}return!1}function _t(e){let t=e,n=(t.getAttribute(`aria-label`)||t.getAttribute(`title`)||t.innerText||t.getAttribute(`placeholder`)||``).trim().toLowerCase();return!n||n.length<2||n.length>40||/^[\d\s₸$€%.,\-+:()]+$/.test(n)||/^\d{1,2}[./]\d{1,2}/.test(n)||wt.has(n)?``:n.replace(/^[\p{Emoji}\s]+/u,``).trim().slice(0,30)}function vt(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t^e.charCodeAt(n);return(t>>>0).toString(16)}function K(){let e=[],t=W(window.location.href);e.push(`route:${t}`);let n=document.querySelector(`h1`);if(n){let t=n.innerText?.trim().toLowerCase();t&&t.length>1&&t.length<50&&!/\d{3,}/.test(t)&&e.push(`h1:${t.slice(0,30)}`)}let r=Array.from(document.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="radio"]):not([type="checkbox"]), textarea, select`)).slice(0,8);for(let t of r){if(G(t))continue;let n=t,r=(n.getAttribute(`name`)||n.getAttribute(`placeholder`)||n.getAttribute(`aria-label`)||``).toLowerCase().trim().slice(0,25);r&&r.length>1&&!wt.has(r)&&e.push(`field:${r}`)}let i=Array.from(document.querySelectorAll(`nav a, [role="navigation"] a`)).slice(0,6);for(let t of i){if(G(t))continue;let n=_t(t);n&&e.push(`nav:${n}`)}let a=document.querySelector(`main`)||document.querySelector(`[role="main"]`)||document.getElementById(`root`);return a&&Array.from(a.querySelectorAll(`button:not([aria-hidden="true"]), [role="button"]:not([aria-hidden="true"])`)).filter(e=>!G(e)&&!gt(e)).map(_t).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)}function q(){return`bw-${vt(K().join(`|`))}`}var yt,bt,xt,St,Ct,wt,Tt=t((()=>{yt=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,bt=/\/\d{1,20}(?=\/|$)/g,xt=/\/[a-z0-9]+(?:-[a-z0-9]+)*-\d+(?=\/|$)/g,St=/\/[0-9a-f]{8,}(?=\/|$)/gi,Ct=new Set([`id`,`userId`,`user_id`,`orderId`,`order_id`,`itemId`,`item_id`,`productId`,`product_id`,`token`,`key`,`ref`,`code`,`session`]),wt=new Set(`ok,ок,okay,close,закрыть,cancel,отмена,yes,da,no,нет,да,submit,отправить,back,назад,next,далее,more,ещё,еще,menu,меню,...,•,·,loading,загрузка,open,открыть,expand,collapse,toggle,sort`.split(`,`))}));function Et(e,t){let n=new Set([...e].filter(e=>t.has(e))),r=new Set([...e,...t]);return r.size===0?1:n.size/r.size}var Dt,J,Ot=t((()=>{Tt(),Dt=class{constructor(e=1500){this._observer=null,this._debounceTimer=null,this._lastTokens=new Set,this._lastUrl=``,this._callbacks=[],this._discoveryCallbacks=[],this._isDiscovering=!1,this.isAutoDiscoveryEnabled=!1,this._debounceMs=e}start(){this._observer||(this._lastTokens=new Set(K()),this._lastUrl=W(window.location.href),this._observer=new MutationObserver(()=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(()=>this._onMutation(),this._debounceMs)}),this._observer.observe(document.body,{childList:!0,subtree:!0,attributes:!1,characterData:!1}))}stop(){this._observer?.disconnect(),this._observer=null,this._debounceTimer&&clearTimeout(this._debounceTimer)}onStateChange(e){this._callbacks.push(e)}onDiscovery(e){this._discoveryCallbacks.push(e)}get isDiscovering(){return this._isDiscovering}getLiveSnapshot(){let e=(e,t)=>{if(e.hasAttribute(`bw-private`)||e.hasAttribute(`data-bw-private`))return`[MASKED]`;if(!t)return t;let n=t.replace(/(?:\d[ \-]*?){13,16}/g,`****`);return n=n.replace(/\b\d{12}\b/g,`****`),n},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=>{let n=t,r=e(n,(n.getAttribute(`aria-label`)||n.innerText||``).trim().slice(0,60));return{id:n.id||``,text:r}}).filter(e=>e.text.length>0).slice(0,30);return{url:window.location.href,headings:t,fingerprint:q(),elements:n}}async _onMutation(){if(document.readyState!==`complete`)return;let e=W(window.location.href),t=new Set(K());if(t.size<2)return;let n=q(),r=e!==this._lastUrl,i=Et(this._lastTokens,t);if(r||i<.55){let a=r?`URL: ${this._lastUrl} → ${e}`:`Sim: ${i.toFixed(2)}`;console.log(`[Watcher] Screen change (${a})`),this._lastUrl=e,this._lastTokens=t;let o=this.getLiveSnapshot();if(this.isAutoDiscoveryEnabled){let e=this._buildTypedTokens();this._discover(n,e).catch(()=>{})}this._callbacks.forEach(e=>e(o))}}_buildTypedTokens(){let e=new Set,t=[],n=(n,r)=>{let i=r.trim().slice(0,40);if(!i||i.length<2)return;let a=`${n}:${i}`;e.has(a)||(e.add(a),t.push(a))};return document.querySelectorAll(`button, [role="button"]`).forEach(e=>{let t=e.innerText?.trim();t&&n(`btn`,t)}),document.querySelectorAll(`a[href]`).forEach(e=>{let t=(e.getAttribute(`aria-label`)||e.innerText)?.trim();t&&n(`a`,t)}),document.querySelectorAll(`input:not([type=hidden]), textarea, select`).forEach(e=>{let t=e.placeholder||e.name;t&&n(`input`,t)}),t.slice(0,8)}async _discover(e,t){let n=localStorage.getItem(`bw_admin_token`);if(n){this._isDiscovering=!0;try{let r=await fetch(`http://localhost:8000/v1/training/discover`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify({fingerprint:e,tokens:t,page_url:window.location.href})});if(r.ok){let e=await r.json();console.log(`[Discovery] ${e.status} — ${e.label}`),this._discoveryCallbacks.forEach(t=>t(e))}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}`)}catch(e){console.warn(`[Discovery] Network error`,e)}finally{this._isDiscovering=!1}}}async forceDiscovery(){let e=[...new Set(K())],t=q();await this._discover(t,e)}},J=new Dt(1500)}));Ot();var kt=`http://localhost:8000`,At=class{constructor(e){this.isFixing=!1,this.simplifyEnabled=!1,this.autoA11yEnabled=!1,this._onParagraphClick=async e=>{if(!this.simplifyEnabled)return;let t=e.target;if(t.closest(`bw-widget`)||t.closest(`.bw-ai-tooltip`))return;let n=t.tagName.toLowerCase();if([`p`,`span`,`div`,`li`,`article`,`h1`,`h2`,`h3`,`h4`,`h5`,`h6`].includes(n)){let n=t.innerText?.trim();if(n&&n.length>20){e.preventDefault(),e.stopPropagation(),document.querySelectorAll(`.bw-ai-tooltip`).forEach(e=>e.remove());let r=window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches,i=document.createElement(`div`);i.className=`bw-ai-tooltip bw-ai-tooltip-loading`,r&&i.setAttribute(`data-theme`,`dark`),i.innerHTML=`
|
|
828
|
-
<div class="bw-ai-tooltip-header">
|
|
829
|
-
<span>✨ AI Упрощение</span>
|
|
830
|
-
<button class="bw-ai-tooltip-close">✕</button>
|
|
831
|
-
</div>
|
|
832
|
-
<div class="bw-ai-tooltip-content">
|
|
833
|
-
Ожидаем ответ от ИИ...
|
|
834
|
-
</div>
|
|
835
|
-
`,document.body.appendChild(i),i.style.left=`${Math.max(10,e.pageX-160)}px`,i.style.top=`${e.pageY+20}px`;let a=t.style.outline,o=t.style.backgroundColor;t.style.outline=`2px dashed #a855f7`,t.style.backgroundColor=`rgba(168, 85, 247, 0.05)`,i.querySelector(`.bw-ai-tooltip-close`)?.addEventListener(`click`,()=>{i.remove(),t.style.outline=a,t.style.backgroundColor=o});try{let e=window.BariwebConfig?.clientId||``,t=await fetch(`${kt}/v1/widget/a11y/simplify`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":e},body:JSON.stringify({text:n})});if(t.ok){let e=await t.json();if(e.text)i.classList.remove(`bw-ai-tooltip-loading`),i.querySelector(`.bw-ai-tooltip-content`).innerHTML=e.text;else throw Error(`Empty response`)}else throw Error(`Server error`)}catch(e){console.error(`BariWeb AI: Simplify failed`,e),i.classList.remove(`bw-ai-tooltip-loading`),i.querySelector(`.bw-ai-tooltip-content`).innerHTML=`<span style="color:#ef4444; font-size:13px;">Ошибка создания упрощенного текста. Попробуйте еще раз.</span>`}}}},(this.host=e).addController(this),this.simplifyEnabled=localStorage.getItem(`bw-ai-simplify`)===`true`,this.autoA11yEnabled=localStorage.getItem(`bw-ai-autofix`)===`true`,J.onStateChange(()=>{this.autoA11yEnabled&&!this.isFixing&&this.fixMarkup()}),this.autoA11yEnabled&&setTimeout(()=>this.fixMarkup(),1e3)}toggleAutoA11y(){this.autoA11yEnabled=!this.autoA11yEnabled,localStorage.setItem(`bw-ai-autofix`,this.autoA11yEnabled?`true`:`false`),this.autoA11yEnabled&&!this.isFixing&&this.fixMarkup(),this.host.requestUpdate()}hostConnected(){}hostDisconnected(){this.simplifyEnabled&&(document.body.removeEventListener(`click`,this._onParagraphClick,{capture:!0}),document.body.classList.remove(`bw-simplify-mode`))}async fixMarkup(){this.isFixing=!0,this.host.requestUpdate();try{let e=[];if(document.querySelectorAll(`img:not([alt]), img[alt=""]`).forEach(t=>{t.hasAttribute(`data-bw-ai-id`)||t.setAttribute(`data-bw-ai-id`,`ai-img-`+Math.random().toString(36).substring(2,9)),e.push({id:t.getAttribute(`data-bw-ai-id`),html:t.outerHTML.substring(0,300)+(t.outerHTML.length>300?`...>`:``)})}),document.querySelectorAll(`button:not([aria-label]), a:not([aria-label]), [role="button"]:not([aria-label])`).forEach(t=>{if(t.tagName===`INPUT`)return;let n=t;n.innerText?.trim()||n.textContent?.trim()||(t.hasAttribute(`data-bw-ai-id`)||t.setAttribute(`data-bw-ai-id`,`ai-btn-`+Math.random().toString(36).substring(2,9)),e.push({id:t.getAttribute(`data-bw-ai-id`),html:t.outerHTML.substring(0,300)+(t.outerHTML.length>300?`...>`:``)}))}),e.length===0){console.log(`BariWeb AI: No broken elements found.`);return}console.log(`BariWeb AI: Found ${e.length} broken elements. Processing...`);let t=window.BariwebConfig?.clientId||``;for(let n=0;n<e.length;n+=10){let r=e.slice(n,n+10),i=await fetch(`${kt}/v1/widget/a11y/fix`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":t},body:JSON.stringify({elements:r})});i.ok&&(await i.json()).forEach(e=>{let t=document.querySelector(`[data-bw-ai-id="${e.id}"]`);if(t&&e.value&&(e.attribute===`alt`||e.attribute===`aria-label`)){t.setAttribute(e.attribute,e.value);let n=t,r=n.style.outline;n.style.outline=`3px solid #10b981`,setTimeout(()=>{n.style.outline=r},2e3)}})}}catch(e){console.error(`BariWeb AI: A11y Fix failed`,e)}finally{this.isFixing=!1,this.host.requestUpdate()}}toggleSimplify(){if(this.simplifyEnabled=!this.simplifyEnabled,this.simplifyEnabled){if(document.body.addEventListener(`click`,this._onParagraphClick,{capture:!0}),document.documentElement.style.setProperty(`--bw-simplify-cursor`,`help`),!document.getElementById(`bw-simplify-mode-style`)){let e=document.createElement(`style`);e.id=`bw-simplify-mode-style`,e.textContent=`
|
|
833
|
+
`}_applySettings(){let e=document.documentElement;this._ensureGlobalStyles(),e.style.setProperty(`--bw-grayscale`,this.settings.monochrome?`100%`:`0%`);let t=1;this.settings.lowSaturation&&(t=.3),this.settings.highSaturation&&(t=2.5),e.style.setProperty(`--bw-saturation`,t.toString()),this.settings.customBgHue===null?e.removeAttribute(`data-bw-has-custom-bg`):(e.style.setProperty(`--bw-custom-bg`,`hsl(${this.settings.customBgHue}, 50%, 95%)`),e.setAttribute(`data-bw-has-custom-bg`,``)),this.settings.customHeaderHue===null?e.removeAttribute(`data-bw-has-custom-header`):(e.style.setProperty(`--bw-custom-header`,`hsl(${this.settings.customHeaderHue}, 70%, 30%)`),e.setAttribute(`data-bw-has-custom-header`,``)),this.settings.customContentHue===null?e.removeAttribute(`data-bw-has-custom-content`):(e.style.setProperty(`--bw-custom-content`,`hsl(${this.settings.customContentHue}, 60%, 40%)`),e.setAttribute(`data-bw-has-custom-content`,``)),this.settings.textScale>1?e.style.fontSize=`${this.settings.textScale*100}%`:e.style.fontSize=``;let n={"data-bw-monochrome":this.settings.monochrome,"data-bw-dark-high-contrast":this.settings.darkHighContrast,"data-bw-bright-high-contrast":this.settings.brightHighContrast,"data-bw-contrast-mode":this.settings.contrastMode,"data-bw-text-spacing":this.settings.textSpacing,"data-bw-dyslexic":this.settings.dyslexicFont,"data-bw-focus-visualizer":this.settings.focusVisualizer,"data-bw-cursor-magnifier":this.settings.cursorMagnifier,"data-bw-no-animations":this.settings.animationsDisabled,"data-bw-link-highlight":this.settings.linkHighlight,"data-bw-highlight-headers":this.settings.highlightHeaders,"data-bw-enlarge-buttons":this.settings.enlargeButtons};Object.entries(n).forEach(([t,n])=>{n?e.setAttribute(t,``):e.removeAttribute(t)});let r=this.host;r&&r.style.setProperty(`--bw-font-scale`,this.settings.textScale.toString())}toggleMonochrome(){this.settings.monochrome=!this.settings.monochrome,this._saveSettings()}toggleDarkHighContrast(){this.settings.darkHighContrast=!this.settings.darkHighContrast,this.settings.darkHighContrast&&(this.settings.brightHighContrast=!1,this.settings.contrastMode=!1),this._saveSettings()}toggleBrightHighContrast(){this.settings.brightHighContrast=!this.settings.brightHighContrast,this.settings.brightHighContrast&&(this.settings.darkHighContrast=!1,this.settings.contrastMode=!1),this._saveSettings()}toggleLowSaturation(){this.settings.lowSaturation=!this.settings.lowSaturation,this.settings.lowSaturation&&(this.settings.highSaturation=!1),this._saveSettings()}toggleHighSaturation(){this.settings.highSaturation=!this.settings.highSaturation,this.settings.highSaturation&&(this.settings.lowSaturation=!1),this._saveSettings()}toggleContrastMode(){this.settings.contrastMode=!this.settings.contrastMode,this.settings.contrastMode&&(this.settings.darkHighContrast=!1,this.settings.brightHighContrast=!1),this._saveSettings()}setCustomHue(e){this.settings.activeColorTab===`background`?this.settings.customBgHue=e:this.settings.activeColorTab===`header`?this.settings.customHeaderHue=e:this.settings.customContentHue=e,this._saveSettings()}resetCustomColors(){this.settings.customBgHue=null,this.settings.customHeaderHue=null,this.settings.customContentHue=null,this._saveSettings()}toggleHighlightHeaders(){this.settings.highlightHeaders=!this.settings.highlightHeaders,this._saveSettings()}toggleEnlargeButtons(){this.settings.enlargeButtons=!this.settings.enlargeButtons,this._saveSettings()}incrementTextScale(){this.settings.textScale>=1.5?this.settings.textScale=1:this.settings.textScale=parseFloat((this.settings.textScale+.1).toFixed(1)),this._saveSettings()}toggleTextSpacing(){this.settings.textSpacing=!this.settings.textSpacing,this._saveSettings()}toggleDyslexicFont(){this.settings.dyslexicFont=!this.settings.dyslexicFont,this._saveSettings()}toggleFocusVisualizer(){this.settings.focusVisualizer=!this.settings.focusVisualizer,this._saveSettings()}toggleCursorMagnifier(){this.settings.cursorMagnifier=!this.settings.cursorMagnifier,this._saveSettings()}toggleAnimations(){this.settings.animationsDisabled=!this.settings.animationsDisabled,this._saveSettings()}toggleLinkHighlight(){this.settings.linkHighlight=!this.settings.linkHighlight,this._saveSettings()}reset(){this.settings={...U},this._saveSettings()}};function W(e){try{let t=new URL(e),n=t.pathname;n=n.replace(yt,`:id`),n=n.replace(bt,`/:id`),n=n.replace(xt,`/:slug`),n=n.replace(St,`/:id`);let r=new URLSearchParams;t.searchParams.forEach((e,t)=>{Ct.has(t)?r.set(`:${t}`,``):e.length<30&&!/^\d+$/.test(e)&&r.set(t,e)});let i=r.toString();return n.replace(/\/$/,``)+(i?`?${i}`:``)}catch{return e.replace(yt,`:id`).replace(/\/\d{1,20}(?=\/|$)/g,`/:id`).split(`?`)[0]}}function G(e){let t=[`dialog`,`tooltip`,`menu`,`listbox`,`alertdialog`],n=e;for(;n&&n!==document.body;){let e=n.getAttribute(`role`)||``;if(t.includes(e)||n.hasAttribute(`data-radix-popper-content-wrapper`)||n.hasAttribute(`data-floating-ui-portal`))return!0;let r=typeof n.className==`string`?n.className:``;if(/popover|tooltip|dropdown-menu|floating|overlay/i.test(r))return!0;n=n.parentElement}return!1}function gt(e){let t=[`li`,`article`,`tr`,`dd`],n=e.parentElement,r=0;for(;n&&n!==document.body&&r<8;){let e=n.tagName.toLowerCase();if(t.includes(e))return!0;let i=typeof n.className==`string`?n.className:``;if(/\b(card|item|tile|post|entry|product|row-item|list-item|feed-item|cell)\b/i.test(i)){let e=n.parentElement?.children;if(e&&e.length>2)return!0}let a=n.getAttribute(`role`)||``;if(a===`listitem`||a===`row`||a===`gridcell`)return!0;n=n.parentElement,r++}return!1}function _t(e){let t=e,n=(t.getAttribute(`aria-label`)||t.getAttribute(`title`)||t.innerText||t.getAttribute(`placeholder`)||``).trim().toLowerCase();return!n||n.length<2||n.length>40||/^[\d\s₸$€%.,\-+:()]+$/.test(n)||/^\d{1,2}[./]\d{1,2}/.test(n)||wt.has(n)?``:n.replace(/^[\p{Emoji}\s]+/u,``).trim().slice(0,30)}function vt(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t^e.charCodeAt(n);return(t>>>0).toString(16)}function K(){let e=[],t=W(window.location.href);e.push(`route:${t}`);let n=document.querySelector(`h1`);if(n){let t=n.innerText?.trim().toLowerCase();t&&t.length>1&&t.length<50&&!/\d{3,}/.test(t)&&e.push(`h1:${t.slice(0,30)}`)}let r=Array.from(document.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="radio"]):not([type="checkbox"]), textarea, select`)).slice(0,8);for(let t of r){if(G(t))continue;let n=t,r=(n.getAttribute(`name`)||n.getAttribute(`placeholder`)||n.getAttribute(`aria-label`)||``).toLowerCase().trim().slice(0,25);r&&r.length>1&&!wt.has(r)&&e.push(`field:${r}`)}let i=Array.from(document.querySelectorAll(`nav a, [role="navigation"] a`)).slice(0,6);for(let t of i){if(G(t))continue;let n=_t(t);n&&e.push(`nav:${n}`)}let a=document.querySelector(`main`)||document.querySelector(`[role="main"]`)||document.getElementById(`root`);return a&&Array.from(a.querySelectorAll(`button:not([aria-hidden="true"]), [role="button"]:not([aria-hidden="true"])`)).filter(e=>!G(e)&&!gt(e)).map(_t).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)}function q(){return`bw-${vt(K().join(`|`))}`}var yt,bt,xt,St,Ct,wt,Tt=t((()=>{yt=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,bt=/\/\d{1,20}(?=\/|$)/g,xt=/\/[a-z0-9]+(?:-[a-z0-9]+)*-\d+(?=\/|$)/g,St=/\/[0-9a-f]{8,}(?=\/|$)/gi,Ct=new Set([`id`,`userId`,`user_id`,`orderId`,`order_id`,`itemId`,`item_id`,`productId`,`product_id`,`token`,`key`,`ref`,`code`,`session`]),wt=new Set(`ok,ок,okay,close,закрыть,cancel,отмена,yes,da,no,нет,да,submit,отправить,back,назад,next,далее,more,ещё,еще,menu,меню,...,•,·,loading,загрузка,open,открыть,expand,collapse,toggle,sort`.split(`,`))}));function Et(e,t){let n=new Set([...e].filter(e=>t.has(e))),r=new Set([...e,...t]);return r.size===0?1:n.size/r.size}var Dt,J,Ot=t((()=>{Tt(),Dt=class{constructor(e=1500){this._observer=null,this._debounceTimer=null,this._lastTokens=new Set,this._lastUrl=``,this._callbacks=[],this._discoveryCallbacks=[],this._isDiscovering=!1,this.isAutoDiscoveryEnabled=!1,this._debounceMs=e}start(){this._observer||(this._lastTokens=new Set(K()),this._lastUrl=W(window.location.href),this._observer=new MutationObserver(()=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(()=>this._onMutation(),this._debounceMs)}),this._observer.observe(document.body,{childList:!0,subtree:!0,attributes:!1,characterData:!1}))}stop(){this._observer?.disconnect(),this._observer=null,this._debounceTimer&&clearTimeout(this._debounceTimer)}onStateChange(e){this._callbacks.push(e)}onDiscovery(e){this._discoveryCallbacks.push(e)}get isDiscovering(){return this._isDiscovering}getLiveSnapshot(){let e=(e,t)=>{if(e.hasAttribute(`bw-private`)||e.hasAttribute(`data-bw-private`))return`[MASKED]`;if(!t)return t;let n=t.replace(/(?:\d[ \-]*?){13,16}/g,`****`);return n=n.replace(/\b\d{12}\b/g,`****`),n},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=>{let n=t,r=e(n,(n.getAttribute(`aria-label`)||n.innerText||``).trim().slice(0,60));return{id:n.id||``,text:r}}).filter(e=>e.text.length>0).slice(0,30);return{url:window.location.href,headings:t,fingerprint:q(),elements:n}}async _onMutation(){if(document.readyState!==`complete`)return;let e=W(window.location.href),t=new Set(K());if(t.size<2)return;let n=q(),r=e!==this._lastUrl,i=Et(this._lastTokens,t);if(r||i<.55){let a=r?`URL: ${this._lastUrl} → ${e}`:`Sim: ${i.toFixed(2)}`;console.log(`[Watcher] Screen change (${a})`),this._lastUrl=e,this._lastTokens=t;let o=this.getLiveSnapshot();if(this.isAutoDiscoveryEnabled){let e=this._buildTypedTokens();this._discover(n,e).catch(()=>{})}this._callbacks.forEach(e=>e(o))}}_buildTypedTokens(){let e=new Set,t=[],n=(n,r)=>{let i=r.trim().slice(0,40);if(!i||i.length<2)return;let a=`${n}:${i}`;e.has(a)||(e.add(a),t.push(a))};return document.querySelectorAll(`button, [role="button"]`).forEach(e=>{let t=e.innerText?.trim();t&&n(`btn`,t)}),document.querySelectorAll(`a[href]`).forEach(e=>{let t=(e.getAttribute(`aria-label`)||e.innerText)?.trim();t&&n(`a`,t)}),document.querySelectorAll(`input:not([type=hidden]), textarea, select`).forEach(e=>{let t=e.placeholder||e.name;t&&n(`input`,t)}),t.slice(0,8)}async _discover(e,t){let n=localStorage.getItem(`bw_admin_token`);if(n){this._isDiscovering=!0;try{let r=await fetch(`http://localhost:8000/v1/training/discover`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify({fingerprint:e,tokens:t,page_url:window.location.href})});if(r.ok){let e=await r.json();console.log(`[Discovery] ${e.status} — ${e.label}`),this._discoveryCallbacks.forEach(t=>t(e))}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}`)}catch(e){console.warn(`[Discovery] Network error`,e)}finally{this._isDiscovering=!1}}}async forceDiscovery(){let e=[...new Set(K())],t=q();await this._discover(t,e)}},J=new Dt(1500)}));Ot();var kt=`http://localhost:8000`,At=class{constructor(e){this.isFixing=!1,this.simplifyEnabled=!1,this.autoA11yEnabled=!1,this._onParagraphKeydown=e=>{if(this.simplifyEnabled&&(e.key===`Enter`||e.key===` `)&&e.target instanceof HTMLElement){if(e.target.closest(`bw-widget`)||e.target.closest(`.bw-ai-tooltip`))return;let t=e.target.tagName.toLowerCase();if([`p`,`span`,`div`,`li`,`article`,`h1`,`h2`,`h3`,`h4`,`h5`,`h6`].includes(t)){e.preventDefault(),e.stopPropagation();let t=e.target.getBoundingClientRect();this._triggerSimplify(e.target,t.left+window.scrollX,t.bottom+window.scrollY)}}},this._onParagraphClick=async e=>{if(!this.simplifyEnabled)return;let t=e.target;if(t.closest(`bw-widget`)||t.closest(`.bw-ai-tooltip`))return;let n=t.tagName.toLowerCase();if([`p`,`span`,`div`,`li`,`article`,`h1`,`h2`,`h3`,`h4`,`h5`,`h6`].includes(n)){let n=t.innerText?.trim();n&&n.length>20&&(e.preventDefault(),e.stopPropagation(),this._triggerSimplify(t,e.pageX,e.pageY))}},(this.host=e).addController(this),this.simplifyEnabled=localStorage.getItem(`bw-ai-simplify`)===`true`,this.autoA11yEnabled=localStorage.getItem(`bw-ai-autofix`)===`true`,J.onStateChange(()=>{this.autoA11yEnabled&&!this.isFixing&&this.fixMarkup()}),this.autoA11yEnabled&&setTimeout(()=>this.fixMarkup(),1e3)}toggleAutoA11y(){this.autoA11yEnabled=!this.autoA11yEnabled,localStorage.setItem(`bw-ai-autofix`,this.autoA11yEnabled?`true`:`false`),this.autoA11yEnabled&&!this.isFixing&&this.fixMarkup(),this.host.requestUpdate()}hostConnected(){}hostDisconnected(){this.simplifyEnabled&&(document.body.removeEventListener(`click`,this._onParagraphClick,{capture:!0}),document.body.classList.remove(`bw-simplify-mode`))}_announce(e){let t=document.getElementById(`bw-ai-announcer`);t||(t=document.createElement(`div`),t.id=`bw-ai-announcer`,t.setAttribute(`aria-live`,`polite`),t.setAttribute(`aria-atomic`,`true`),Object.assign(t.style,{position:`absolute`,width:`1px`,height:`1px`,padding:`0`,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,border:`0`}),document.body.appendChild(t)),t.textContent=e}async fixMarkup(){this.isFixing=!0,this.host.requestUpdate();try{let e=[];if(document.querySelectorAll(`img:not([alt]), img[alt=""]`).forEach(t=>{t.hasAttribute(`data-bw-ai-id`)||t.setAttribute(`data-bw-ai-id`,`ai-img-`+Math.random().toString(36).substring(2,9)),e.push({id:t.getAttribute(`data-bw-ai-id`),html:t.outerHTML.substring(0,300)+(t.outerHTML.length>300?`...>`:``)})}),document.querySelectorAll(`button:not([aria-label]), a:not([aria-label]), [role="button"]:not([aria-label])`).forEach(t=>{if(t.tagName===`INPUT`)return;let n=t;n.innerText?.trim()||n.textContent?.trim()||(t.hasAttribute(`data-bw-ai-id`)||t.setAttribute(`data-bw-ai-id`,`ai-btn-`+Math.random().toString(36).substring(2,9)),e.push({id:t.getAttribute(`data-bw-ai-id`),html:t.outerHTML.substring(0,300)+(t.outerHTML.length>300?`...>`:``)}))}),e.length===0){console.log(`BariWeb AI: No broken elements found.`);return}console.log(`BariWeb AI: Found ${e.length} broken elements. Processing...`);let t=window.BariwebConfig?.clientId||``;for(let n=0;n<e.length;n+=10){let r=e.slice(n,n+10),i=await fetch(`${kt}/v1/widget/a11y/fix`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":t},body:JSON.stringify({elements:r})});i.ok&&(await i.json()).forEach(e=>{let t=document.querySelector(`[data-bw-ai-id="${e.id}"]`);if(t&&e.value&&(e.attribute===`alt`||e.attribute===`aria-label`)){t.setAttribute(e.attribute,e.value);let n=t,r=n.style.outline;n.style.outline=`3px solid #10b981`,setTimeout(()=>{n.style.outline=r},2e3)}})}this._announce(`Режим для незрячих отработал. AI исправил ${e.length} элементов.`)}catch(e){console.error(`BariWeb AI: A11y Fix failed`,e),this._announce(`Произошла ошибка при исправлении элементов.`)}finally{this.isFixing=!1,this.host.requestUpdate()}}toggleSimplify(){if(this.simplifyEnabled=!this.simplifyEnabled,this.simplifyEnabled){if(document.body.addEventListener(`click`,this._onParagraphClick,{capture:!0}),document.body.addEventListener(`keydown`,this._onParagraphKeydown,{capture:!0}),document.querySelectorAll(`p, h1, h2, h3, h4, h5, h6, li, article`).forEach(e=>{!e.hasAttribute(`tabindex`)&&e.textContent?.trim().length>20&&(e.setAttribute(`tabindex`,`0`),e.classList.add(`bw-simplify-focusable`))}),document.documentElement.style.setProperty(`--bw-simplify-cursor`,`help`),!document.getElementById(`bw-simplify-mode-style`)){let e=document.createElement(`style`);e.id=`bw-simplify-mode-style`,e.textContent=`
|
|
836
834
|
body.bw-simplify-mode *:hover {
|
|
837
835
|
cursor: help !important;
|
|
838
836
|
background-color: rgba(168, 85, 247, 0.1) !important;
|
|
@@ -909,7 +907,15 @@
|
|
|
909
907
|
from { opacity: 0; transform: translateY(4px); }
|
|
910
908
|
to { opacity: 1; transform: translateY(0); }
|
|
911
909
|
}
|
|
912
|
-
`,document.head.appendChild(e)}document.body.classList.add(`bw-simplify-mode`)}else document.body.removeEventListener(`click`,this._onParagraphClick,{capture:!0}),document.body.classList.remove(`bw-simplify-mode`),document.documentElement.style.removeProperty(`--bw-simplify-cursor`);this.host.requestUpdate()}},jt=`bw-tts-enabled-v1`,Mt=class{constructor(){this.enabled=!0,this.enabled=this.loadEnabled()}isEnabled(){return this.enabled}setEnabled(e){this.enabled=e;try{localStorage.setItem(jt,e?`1`:`0`)}catch{}e||this.stop()}stop(){`speechSynthesis`in window&&window.speechSynthesis.cancel()}speak(e){if(!this.enabled||!(`speechSynthesis`in window))return;let t=(e||``).trim();if(t)try{window.speechSynthesis.cancel();let e=new SpeechSynthesisUtterance(t),n=this.detectLanguage(t);e.lang=n;let r=this.pickVoice(n);r&&(e.voice=r),e.rate=1,e.pitch=1,window.speechSynthesis.speak(e)}catch(e){console.warn(`TTS speak failed`,e)}}loadEnabled(){try{let e=localStorage.getItem(jt);return e===null?!0:e!==`0`}catch{return!0}}detectLanguage(e){let t=e.toLowerCase();return/[әіңғүұқөһ]/i.test(t)?`kk-KZ`:/[а-яё]/i.test(t)?`ru-RU`:/[a-z]/i.test(t)?`en-US`:`ru-RU`}pickVoice(e){if(!(`speechSynthesis`in window))return null;let t=window.speechSynthesis.getVoices();if(!t||t.length===0)return null;let n=e.split(`-`)[0].toLowerCase();return t.find(t=>t.lang.toLowerCase()===e.toLowerCase())||t.find(e=>e.lang.toLowerCase().startsWith(n))||t[0]||null}};Tt();var Nt=`http://localhost:8000`,Pt=5,Ft=[/(submit|отправить|оплатить|сгенерировать|сохранить|перевести|подтвердит|купить|удалить|delete|pay|purchase|buy|send|transfer|confirm|place.?order|checkout|remove|drop|unsubscribe|sign.?out|выйти|уволить)/i];function It(e){if(e.type!==`click_element`||!e.element_id)return!1;let t=document.getElementById(e.element_id);if(!t)return!1;if(t.getAttribute(`type`)===`submit`||t.tagName.toLowerCase()===`button`&&t.closest(`form`)!==null&&t.getAttribute(`type`)!==`button`)return!0;let n=[t.textContent?.trim()||``,t.getAttribute(`aria-label`)||``,t.getAttribute(`title`)||``,t.getAttribute(`name`)||``,t.getAttribute(`value`)||``].join(` `);return Ft.some(e=>e.test(n))}var Lt=class{constructor(e){this.messages=[],this.isLoading=!1,this.error=null,this._tts=new Mt,this._voiceMode=!1,this.pendingConfirmation=null,(this.host=e).addController(this),this._loadMessages()}hostConnected(){}hostDisconnected(){this._tts.stop()}_loadMessages(){try{let e=sessionStorage.getItem(`bw-chat-history`);e&&(this.messages=JSON.parse(e),this.messages.length>0&&typeof this.host.setOpen==`function`&&setTimeout(()=>this.host.setOpen(!0),100));let t=sessionStorage.getItem(`bw-auto-resume`);if(t===`true`||t===`verify-only`){sessionStorage.removeItem(`bw-auto-resume`);let e=t===`verify-only`?`Страница загрузилась после отправки формы. Проверь новый DOM: если авторизация прошла успешно (нет формы входа, есть контент приложения) — сообщи об успехе. НЕ нажимай ничего снова.`:`Страница загрузилась. Продолжай выполнение задачи с учетом нового контекста и DOM.`;setTimeout(()=>{this._agentStep(e)},1e3)}}catch(e){console.error(`Failed to load chat history`,e)}}_saveMessages(){try{sessionStorage.setItem(`bw-chat-history`,JSON.stringify(this.messages))}catch(e){console.error(`Failed to save chat history`,e)}}gatherContext(){let e=window.location.href,t=document.body?.innerText?.slice(0,3e3)??``,n=Array.from(document.querySelectorAll(`a[href], button, [role="button"], input:not([type="hidden"]), textarea, select`)).filter(e=>!e.hasAttribute(`bw-private`)).map(e=>{let t=e,n=t.tagName.toLowerCase(),r=n===`input`||n===`textarea`||n===`select`,i=t.getAttribute(`type`)||(n===`input`?`text`:n===`button`?`button`:n),a=t.getAttribute(`name`)||``,o=t.getAttribute(`placeholder`)||``,s=r?(t.value||``).slice(0,80):``;s&&=(s=s.replace(/\b\d{13,19}\b/g,e=>e.slice(0,4)+` **** **** `+e.slice(-4)),s.replace(/\b\d{12}\b/g,`**** **** ****`));let c=t.id&&!t.getAttribute(`data-bw-auto`)?t.id:t.getAttribute(`data-id`)||t.getAttribute(`data-testid`)||``;if(!c){let e=`${n}|${i}|${a}|${o}|${(t.className||``).toString().replace(/\s+/g,`-`).slice(0,40)}|${t.href||``}|${(t.textContent||``).trim().slice(0,30)}|${t.parentElement?.tagName?.toLowerCase()||`root`}`,r=5381;for(let t=0;t<e.length;t++)r=(r<<5)+r^e.charCodeAt(t);c=`bw-${(r>>>0).toString(16)}`,t.id=c,t.setAttribute(`data-bw-auto`,`true`)}let l=t.getAttribute(`aria-label`)||``;if(!l&&c){let e=document.querySelector(`label[for="${c}"]`);e&&(l=e.textContent?.trim()||``)}if(!l){let e=t.parentElement;for(;e&&e.tagName.toLowerCase()!==`form`&&e.tagName.toLowerCase()!==`body`;){if(e.tagName.toLowerCase()===`label`){l=(e.textContent||``).replace(t.textContent||``,``).trim();break}e=e.parentElement}}if(l||=(t.textContent||``).trim().slice(0,80),l||=t.getAttribute(`title`)||``,!l&&o&&(l=o),!l&&n===`button`){let e=t.querySelector(`svg`);if(e&&typeof e.className?.baseVal==`string`){let t=e.className.baseVal.match(/lucide-([a-z0-9\-]+)/);l=t?`[icon:${t[1]}]`:`[icon]`}else l=`[btn:${(t.className||``).toString().slice(0,30)}]`}return{id:c,label:l.trim(),tag:n,type:i,name:a,placeholder:o,value:s}}).filter(e=>e.label.length>0||(e.placeholder??``).length>0||(e.name??``).length>0).slice(0,100).map(e=>`[`+[e.tag,e.type||``,e.id,e.name||``,e.placeholder||``,e.value||``,e.label].join(`|`)+`]`).join(``),r=t;return r=r.replace(/\b\d{13,19}\b/g,`**** **** **** ****`),r=r.replace(/\b\d{12}\b/g,`**** **** ****`),{page_text:r,elements:n,page_url:e}}executeAction(e){if(e.type===`click_element`&&e.element_id){let t=document.getElementById(e.element_id);if(t){if(t.tagName.toLowerCase()===`a`&&t.href){let n=t.href;return new URL(n,window.location.origin).origin===window.location.origin&&sessionStorage.setItem(`bw-auto-resume`,`true`),t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!0}}return t.getAttribute(`type`)===`submit`||t.tagName.toLowerCase()===`button`&&t.closest(`form`)!==null&&t.getAttribute(`type`)!==`button`?(sessionStorage.setItem(`bw-auto-resume`,`verify-only`),t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!0}):(t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!1})}return{result:`⚠️ Элемент "${e.element_id}" не найден.`,causesNavigation:!1}}if(e.type===`navigate`&&e.url)return sessionStorage.setItem(`bw-auto-resume`,`true`),window.location.href=e.url,{result:`🔀 Перехожу на ${e.url}...`,causesNavigation:!0};if(e.type===`input_text`&&e.element_id&&e.value!==void 0){let t=document.getElementById(e.element_id);if(t){let n=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,`value`)?.set,r=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,`value`)?.set;return t.tagName.toLowerCase()===`textarea`&&r?r.call(t,e.value):n?n.call(t,e.value):t.value=e.value,t.dispatchEvent(new Event(`input`,{bubbles:!0})),t.dispatchEvent(new Event(`change`,{bubbles:!0})),{result:`⌨️ Ввел текст "${e.value}" в поле.`,causesNavigation:!1}}return{result:`⚠️ Поле ввода "${e.element_id}" не найдено.`,causesNavigation:!1}}return e.type===`continue`?{result:`🔄 Анализирую страницу...`,causesNavigation:!1}:{result:`⚠️ Неизвестное действие.`,causesNavigation:!1}}async _callAPI(e){let{page_text:t,elements:n,page_url:r}=this.gatherContext(),i=q(),a=this.host.clientId||window.__BARIWEB_CLIENT_ID__||``,o=null;try{let e=await fetch(`${Nt}/v1/training/match-screen`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":a},body:JSON.stringify({fingerprint:i})});if(e.ok){let t=await e.json();t.matched&&(o=t.label)}}catch(e){console.warn(`Failed to match screen fingerprint`,e)}let s=await fetch(`${Nt}/v1/chat`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":a},body:JSON.stringify({query:e,history:this._compressedHistory(),page_text:t,elements:n,page_url:r,screen_label:o,screen_fingerprint:i})});if(!s.ok)throw Error(`HTTP ${s.status}: ${s.statusText}`);let c=await s.json();if(c.text&&c.text.trimStart().startsWith(`{`))try{let e=JSON.parse(c.text);e.text&&(c.text=e.text,e.action&&!c.action&&(c.action=e.action))}catch{c.text=c.text.replace(/^\{"text"\s*:\s*"/,``).replace(/",?\s*"action".*$/,``)}return c}_compressedHistory(){let e=this.messages.map(e=>({role:e.role,text:e.text}));if(e.length<=3)return e;let t=-1;for(let n=e.length-1;n>=0;n--)if(e[n].role===`user`){t=n;break}return t===-1?e.slice(-3):[e[t],...e.slice(t+1).filter(e=>e.role===`assistant`).slice(-2)]}async _agentLoop(e,t,n=!1){if(this.isLoading)return;this.isLoading=!0,this.error=null,this._voiceMode=n,t&&(this.messages=[...this.messages,{role:`user`,text:e,timestamp:Date.now()}],this._saveMessages()),this.host.requestUpdate();let r=e,i=0;try{for(;i<Pt;){i++;let e=await this._callAPI(r),t=e.text;if(e.action){if(It(e.action)){let t=document.getElementById(e.action.element_id||``)?.textContent?.trim()||e.action.element_id||`кнопку`;this.pendingConfirmation={text:`${e.text}\n\n⚠️ Нажать «${t}»?`,action:e.action,currentQuery:r,step:i},this.messages=[...this.messages,{role:`assistant`,text:`${e.text}\n\n🛑 **Подтвердите действие:** нажать «${t}»?`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(e.text),this.isLoading=!1,this.host.requestUpdate();return}let n=this.gatherContext().page_text,{result:a,causesNavigation:o}=this.executeAction(e.action);if(e.action.type===`continue`){this.messages=[...this.messages,{role:`assistant`,text:`🔄 Анализирую...`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Анализирую...`),this.host.requestUpdate(),await this._waitForDom(800),r=`Страница обновилась. Продолжай задачу, прочитай DOM.`;continue}if(t=`${e.text}\n${a}`,o){this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),await this._waitForDom(1500);let e=sessionStorage.getItem(`bw-auto-resume`);if(e===`true`||e===`verify-only`){sessionStorage.removeItem(`bw-auto-resume`),r=e===`verify-only`?`Страница загрузилась после отправки формы (SPA навигация). Проверь новый DOM: если задача выполнена — сообщи об успехе. НЕ нажимай ничего снова.`:`Страница загрузилась (SPA навигация). Продолжай задачу, прочитай новый DOM.`;continue}break}this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),e.action.type===`input_text`&&e.action.element_id?(await this._waitForDom(800),r=(document.getElementById(e.action.element_id)?.value??``).length>0?`✅ Поле заполнено. Переходи к СЛЕДУЮЩЕМУ незаполненному полю или нажми кнопку отправки. НЕ повторяй ввод.`:`⚠️ Поле не получило значение. Попробуй ввести снова в id="${e.action.element_id}".`):(await this._waitForDom(800),r=n===this.gatherContext().page_text?`⚠️ Страница не изменилась. Возможно кнопка не сработала. Проверь DOM.`:`Действие выполнено. Если задача готова — сообщи. Иначе продолжай.`);continue}this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t);break}}catch(e){this.error=e.message??`Ошибка соединения`,this.messages=[...this.messages,{role:`assistant`,text:`❌ Ошибка: ${this.error}`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Ошибка: ${this.error}`)}finally{this.isLoading=!1,this.host.requestUpdate()}}async confirmAction(){if(!this.pendingConfirmation)return;let{action:e}=this.pendingConfirmation;this.pendingConfirmation=null,this.messages=[...this.messages,{role:`user`,text:`✅ Подтверждаю`,timestamp:Date.now()}],this._saveMessages(),this.host.requestUpdate();let{result:t,causesNavigation:n}=this.executeAction(e);this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),!n&&(await this._waitForDom(1200),await this._agentStep(`Действие подтверждено и выполнено. Проверь результат в DOM.`))}cancelAction(){this.pendingConfirmation&&(this.pendingConfirmation=null,this.messages=[...this.messages,{role:`user`,text:`❌ Отмена`,timestamp:Date.now()},{role:`assistant`,text:`🚫 Действие отменено. Чем ещё могу помочь?`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Действие отменено. Чем ещё могу помочь?`),this.host.requestUpdate())}_waitForDom(e){return new Promise(t=>setTimeout(t,e))}async sendMessage(e,t=!1){!e.trim()||this.isLoading||(await this._agentLoop(e,!0,t),this.host.updateComplete?.then(()=>{let e=this.host.renderRoot?.querySelector(`.chat-messages`);e&&(e.scrollTop=e.scrollHeight)}))}async _agentStep(e){await this._agentLoop(e,!1,this._voiceMode),this.host.updateComplete?.then(()=>{let e=this.host.renderRoot?.querySelector(`.chat-messages`);e&&(e.scrollTop=e.scrollHeight)})}clearMessages(){this.messages=[],this.error=null,this.pendingConfirmation=null,this._saveMessages(),this.host.requestUpdate()}isTtsEnabled(){return this._tts.isEnabled()}setTtsEnabled(e){this._tts.setEnabled(e),this.host.requestUpdate()}async transcribeAudio(e,t){let n=this.host.clientId||window.__BARIWEB_CLIENT_ID__||``,r=new FormData;r.append(`language_mode`,t),r.append(`audio`,e,`speech.wav`);let i=await fetch(`${Nt}/v1/stt/transcribe`,{method:`POST`,headers:{"X-Client-ID":n},body:r});if(!i.ok){let e=`HTTP ${i.status}`;try{e=(await i.json())?.detail||e}catch{}throw Error(e)}return await i.json()}};function Y(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var Rt=n({initAdminMode:()=>Ht,mountAdminPanel:()=>Vt});function zt(){if(!X)return;let e=K(),t=q(),n=Z?.is_trained===!0,r=Z&&!Z.is_trained,i=Z?.label||null,a=Z?.description||null,o=n?`active`:r?`draft`:`idle`,s=n?`trained`:r?`draft`:`idle`,c=n?`✅ Обучено`:r?`📝 Черновик (не подтверждено)`:`🔍 Сканирование...`,l=X.querySelector(`#bw-admin-panel`);l&&(l.className=n?`trained`:`discovering`,l.id=`bw-admin-panel`,n&&l.classList.add(`trained`));let u=X.querySelector(`#bw-panel-content`);u&&(u.innerHTML=`
|
|
910
|
+
`,document.head.appendChild(e)}document.body.classList.add(`bw-simplify-mode`),this._announce(`Режим AI Упрощение текста включен. Используйте Tab для навигации по тексту и Enter для упрощения.`)}else document.body.removeEventListener(`click`,this._onParagraphClick,{capture:!0}),document.body.removeEventListener(`keydown`,this._onParagraphKeydown,{capture:!0}),document.querySelectorAll(`.bw-simplify-focusable`).forEach(e=>{e.removeAttribute(`tabindex`),e.classList.remove(`bw-simplify-focusable`)}),document.body.classList.remove(`bw-simplify-mode`),document.documentElement.style.removeProperty(`--bw-simplify-cursor`),this._announce(`Режим AI Упрощение текста выключен.`);this.host.requestUpdate()}async _triggerSimplify(e,t,n){let r=e.innerText?.trim();if(!r)return;document.querySelectorAll(`.bw-ai-tooltip`).forEach(e=>e.remove());let i=document.createElement(`div`);i.className=`bw-ai-tooltip bw-ai-tooltip-loading`,i.tabIndex=-1,i.innerHTML=`
|
|
911
|
+
<div class="bw-ai-tooltip-header">
|
|
912
|
+
<span>✨ AI Упрощение</span>
|
|
913
|
+
<button class="bw-ai-tooltip-close" aria-label="Закрыть">✕</button>
|
|
914
|
+
</div>
|
|
915
|
+
<div class="bw-ai-tooltip-content" role="status" aria-live="polite">
|
|
916
|
+
Ожидаем ответ от ИИ...
|
|
917
|
+
</div>
|
|
918
|
+
`,document.body.appendChild(i),i.style.left=`${Math.max(10,t-160)}px`,i.style.top=`${n+20}px`;let a=e.style.outline,o=e.style.backgroundColor;e.style.outline=`2px dashed #a855f7`,e.style.backgroundColor=`rgba(168, 85, 247, 0.05)`,i.querySelector(`.bw-ai-tooltip-close`)?.addEventListener(`click`,()=>{i.remove(),e.style.outline=a,e.style.backgroundColor=o});try{let e=window.BariwebConfig?.clientId||``,t=await fetch(`${kt}/v1/widget/a11y/simplify`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":e},body:JSON.stringify({text:r})});if(t.ok){let e=await t.json();if(e.text)i.classList.remove(`bw-ai-tooltip-loading`),i.querySelector(`.bw-ai-tooltip-content`).innerHTML=e.text,i.focus();else throw Error(`Empty response`)}else throw Error(`Server error`)}catch(e){console.error(`BariWeb AI: Simplify failed`,e),i.classList.remove(`bw-ai-tooltip-loading`),i.querySelector(`.bw-ai-tooltip-content`).innerHTML=`<span style="color:#ef4444; font-size:13px;">Ошибка создания упрощенного текста. Попробуйте еще раз.</span>`,i.focus()}}},jt=`bw-tts-enabled-v1`,Mt=class{constructor(){this.enabled=!0,this.enabled=this.loadEnabled()}isEnabled(){return this.enabled}setEnabled(e){this.enabled=e;try{localStorage.setItem(jt,e?`1`:`0`)}catch{}e||this.stop()}stop(){`speechSynthesis`in window&&window.speechSynthesis.cancel()}speak(e){if(!this.enabled||!(`speechSynthesis`in window))return;let t=(e||``).trim();if(t)try{window.speechSynthesis.cancel();let e=new SpeechSynthesisUtterance(t),n=this.detectLanguage(t);e.lang=n;let r=this.pickVoice(n);r&&(e.voice=r),e.rate=1,e.pitch=1,window.speechSynthesis.speak(e)}catch(e){console.warn(`TTS speak failed`,e)}}loadEnabled(){try{let e=localStorage.getItem(jt);return e===null?!0:e!==`0`}catch{return!0}}detectLanguage(e){let t=e.toLowerCase();return/[әіңғүұқөһ]/i.test(t)?`kk-KZ`:/[а-яё]/i.test(t)?`ru-RU`:/[a-z]/i.test(t)?`en-US`:`ru-RU`}pickVoice(e){if(!(`speechSynthesis`in window))return null;let t=window.speechSynthesis.getVoices();if(!t||t.length===0)return null;let n=e.split(`-`)[0].toLowerCase();return t.find(t=>t.lang.toLowerCase()===e.toLowerCase())||t.find(e=>e.lang.toLowerCase().startsWith(n))||t[0]||null}};Tt();var Nt=`http://localhost:8000`,Pt=5,Ft=[/(submit|отправить|оплатить|сгенерировать|сохранить|перевести|подтвердит|купить|удалить|delete|pay|purchase|buy|send|transfer|confirm|place.?order|checkout|remove|drop|unsubscribe|sign.?out|выйти|уволить)/i];function It(e){if(e.type!==`click_element`||!e.element_id)return!1;let t=document.getElementById(e.element_id);if(!t)return!1;if(t.getAttribute(`type`)===`submit`||t.tagName.toLowerCase()===`button`&&t.closest(`form`)!==null&&t.getAttribute(`type`)!==`button`)return!0;let n=[t.textContent?.trim()||``,t.getAttribute(`aria-label`)||``,t.getAttribute(`title`)||``,t.getAttribute(`name`)||``,t.getAttribute(`value`)||``].join(` `);return Ft.some(e=>e.test(n))}var Lt=class{constructor(e){this.messages=[],this.isLoading=!1,this.error=null,this._tts=new Mt,this._voiceMode=!1,this.pendingConfirmation=null,(this.host=e).addController(this),this._loadMessages()}hostConnected(){}hostDisconnected(){this._tts.stop()}_loadMessages(){try{let e=sessionStorage.getItem(`bw-chat-history`);e&&(this.messages=JSON.parse(e),this.messages.length>0&&typeof this.host.setOpen==`function`&&setTimeout(()=>this.host.setOpen(!0),100));let t=sessionStorage.getItem(`bw-auto-resume`);if(t===`true`||t===`verify-only`){sessionStorage.removeItem(`bw-auto-resume`);let e=t===`verify-only`?`Страница загрузилась после отправки формы. Проверь новый DOM: если авторизация прошла успешно (нет формы входа, есть контент приложения) — сообщи об успехе. НЕ нажимай ничего снова.`:`Страница загрузилась. Продолжай выполнение задачи с учетом нового контекста и DOM.`;setTimeout(()=>{this._agentStep(e)},1e3)}}catch(e){console.error(`Failed to load chat history`,e)}}_saveMessages(){try{sessionStorage.setItem(`bw-chat-history`,JSON.stringify(this.messages))}catch(e){console.error(`Failed to save chat history`,e)}}gatherContext(){let e=window.location.href,t=document.body?.innerText?.slice(0,3e3)??``,n=Array.from(document.querySelectorAll(`a[href], button, [role="button"], input:not([type="hidden"]), textarea, select`)).filter(e=>!e.hasAttribute(`bw-private`)).map(e=>{let t=e,n=t.tagName.toLowerCase(),r=n===`input`||n===`textarea`||n===`select`,i=t.getAttribute(`type`)||(n===`input`?`text`:n===`button`?`button`:n),a=t.getAttribute(`name`)||``,o=t.getAttribute(`placeholder`)||``,s=r?(t.value||``).slice(0,80):``;s&&=(s=s.replace(/\b\d{13,19}\b/g,e=>e.slice(0,4)+` **** **** `+e.slice(-4)),s.replace(/\b\d{12}\b/g,`**** **** ****`));let c=t.id&&!t.getAttribute(`data-bw-auto`)?t.id:t.getAttribute(`data-id`)||t.getAttribute(`data-testid`)||``;if(!c){let e=`${n}|${i}|${a}|${o}|${(t.className||``).toString().replace(/\s+/g,`-`).slice(0,40)}|${t.href||``}|${(t.textContent||``).trim().slice(0,30)}|${t.parentElement?.tagName?.toLowerCase()||`root`}`,r=5381;for(let t=0;t<e.length;t++)r=(r<<5)+r^e.charCodeAt(t);c=`bw-${(r>>>0).toString(16)}`,t.id=c,t.setAttribute(`data-bw-auto`,`true`)}let l=t.getAttribute(`aria-label`)||``;if(!l&&c){let e=document.querySelector(`label[for="${c}"]`);e&&(l=e.textContent?.trim()||``)}if(!l){let e=t.parentElement;for(;e&&e.tagName.toLowerCase()!==`form`&&e.tagName.toLowerCase()!==`body`;){if(e.tagName.toLowerCase()===`label`){l=(e.textContent||``).replace(t.textContent||``,``).trim();break}e=e.parentElement}}if(l||=(t.textContent||``).trim().slice(0,80),l||=t.getAttribute(`title`)||``,!l&&o&&(l=o),!l&&n===`button`){let e=t.querySelector(`svg`);if(e&&typeof e.className?.baseVal==`string`){let t=e.className.baseVal.match(/lucide-([a-z0-9\-]+)/);l=t?`[icon:${t[1]}]`:`[icon]`}else l=`[btn:${(t.className||``).toString().slice(0,30)}]`}return{id:c,label:l.trim(),tag:n,type:i,name:a,placeholder:o,value:s}}).filter(e=>e.label.length>0||(e.placeholder??``).length>0||(e.name??``).length>0).slice(0,100).map(e=>`[`+[e.tag,e.type||``,e.id,e.name||``,e.placeholder||``,e.value||``,e.label].join(`|`)+`]`).join(``),r=t;return r=r.replace(/\b\d{13,19}\b/g,`**** **** **** ****`),r=r.replace(/\b\d{12}\b/g,`**** **** ****`),{page_text:r,elements:n,page_url:e}}executeAction(e){if(e.type===`click_element`&&e.element_id){let t=document.getElementById(e.element_id);if(t){if(t.tagName.toLowerCase()===`a`&&t.href){let n=t.href;return new URL(n,window.location.origin).origin===window.location.origin&&sessionStorage.setItem(`bw-auto-resume`,`true`),t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!0}}return t.getAttribute(`type`)===`submit`||t.tagName.toLowerCase()===`button`&&t.closest(`form`)!==null&&t.getAttribute(`type`)!==`button`?(sessionStorage.setItem(`bw-auto-resume`,`verify-only`),t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!0}):(t.click(),{result:`✅ Нажал на "${t.textContent?.trim()||e.element_id}"`,causesNavigation:!1})}return{result:`⚠️ Элемент "${e.element_id}" не найден.`,causesNavigation:!1}}if(e.type===`navigate`&&e.url)return sessionStorage.setItem(`bw-auto-resume`,`true`),window.location.href=e.url,{result:`🔀 Перехожу на ${e.url}...`,causesNavigation:!0};if(e.type===`input_text`&&e.element_id&&e.value!==void 0){let t=document.getElementById(e.element_id);if(t){let n=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,`value`)?.set,r=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,`value`)?.set;return t.tagName.toLowerCase()===`textarea`&&r?r.call(t,e.value):n?n.call(t,e.value):t.value=e.value,t.dispatchEvent(new Event(`input`,{bubbles:!0})),t.dispatchEvent(new Event(`change`,{bubbles:!0})),{result:`⌨️ Ввел текст "${e.value}" в поле.`,causesNavigation:!1}}return{result:`⚠️ Поле ввода "${e.element_id}" не найдено.`,causesNavigation:!1}}return e.type===`continue`?{result:`🔄 Анализирую страницу...`,causesNavigation:!1}:{result:`⚠️ Неизвестное действие.`,causesNavigation:!1}}async _callAPI(e){let{page_text:t,elements:n,page_url:r}=this.gatherContext(),i=q(),a=this.host.clientId||window.__BARIWEB_CLIENT_ID__||``,o=null;try{let e=await fetch(`${Nt}/v1/training/match-screen`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":a},body:JSON.stringify({fingerprint:i})});if(e.ok){let t=await e.json();t.matched&&(o=t.label)}}catch(e){console.warn(`Failed to match screen fingerprint`,e)}let s=await fetch(`${Nt}/v1/chat`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Client-ID":a},body:JSON.stringify({query:e,history:this._compressedHistory(),page_text:t,elements:n,page_url:r,screen_label:o,screen_fingerprint:i})});if(!s.ok)throw Error(`HTTP ${s.status}: ${s.statusText}`);let c=await s.json();if(c.text&&c.text.trimStart().startsWith(`{`))try{let e=JSON.parse(c.text);e.text&&(c.text=e.text,e.action&&!c.action&&(c.action=e.action))}catch{c.text=c.text.replace(/^\{"text"\s*:\s*"/,``).replace(/",?\s*"action".*$/,``)}return c}_compressedHistory(){let e=this.messages.map(e=>({role:e.role,text:e.text}));if(e.length<=3)return e;let t=-1;for(let n=e.length-1;n>=0;n--)if(e[n].role===`user`){t=n;break}return t===-1?e.slice(-3):[e[t],...e.slice(t+1).filter(e=>e.role===`assistant`).slice(-2)]}async _agentLoop(e,t,n=!1){if(this.isLoading)return;this.isLoading=!0,this.error=null,this._voiceMode=n,t&&(this.messages=[...this.messages,{role:`user`,text:e,timestamp:Date.now()}],this._saveMessages()),this.host.requestUpdate();let r=e,i=0;try{for(;i<Pt;){i++;let e=await this._callAPI(r),t=e.text;if(e.action){if(It(e.action)){let t=document.getElementById(e.action.element_id||``)?.textContent?.trim()||e.action.element_id||`кнопку`;this.pendingConfirmation={text:`${e.text}\n\n⚠️ Нажать «${t}»?`,action:e.action,currentQuery:r,step:i},this.messages=[...this.messages,{role:`assistant`,text:`${e.text}\n\n🛑 **Подтвердите действие:** нажать «${t}»?`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(e.text),this.isLoading=!1,this.host.requestUpdate();return}let n=this.gatherContext().page_text,{result:a,causesNavigation:o}=this.executeAction(e.action);if(e.action.type===`continue`){this.messages=[...this.messages,{role:`assistant`,text:`🔄 Анализирую...`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Анализирую...`),this.host.requestUpdate(),await this._waitForDom(800),r=`Страница обновилась. Продолжай задачу, прочитай DOM.`;continue}if(t=`${e.text}\n${a}`,o){this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),await this._waitForDom(1500);let e=sessionStorage.getItem(`bw-auto-resume`);if(e===`true`||e===`verify-only`){sessionStorage.removeItem(`bw-auto-resume`),r=e===`verify-only`?`Страница загрузилась после отправки формы (SPA навигация). Проверь новый DOM: если задача выполнена — сообщи об успехе. НЕ нажимай ничего снова.`:`Страница загрузилась (SPA навигация). Продолжай задачу, прочитай новый DOM.`;continue}break}this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),e.action.type===`input_text`&&e.action.element_id?(await this._waitForDom(800),r=(document.getElementById(e.action.element_id)?.value??``).length>0?`✅ Поле заполнено. Переходи к СЛЕДУЮЩЕМУ незаполненному полю или нажми кнопку отправки. НЕ повторяй ввод.`:`⚠️ Поле не получило значение. Попробуй ввести снова в id="${e.action.element_id}".`):(await this._waitForDom(800),r=n===this.gatherContext().page_text?`⚠️ Страница не изменилась. Возможно кнопка не сработала. Проверь DOM.`:`Действие выполнено. Если задача готова — сообщи. Иначе продолжай.`);continue}this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t);break}}catch(e){this.error=e.message??`Ошибка соединения`,this.messages=[...this.messages,{role:`assistant`,text:`❌ Ошибка: ${this.error}`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Ошибка: ${this.error}`)}finally{this.isLoading=!1,this.host.requestUpdate()}}async confirmAction(){if(!this.pendingConfirmation)return;let{action:e}=this.pendingConfirmation;this.pendingConfirmation=null,this.messages=[...this.messages,{role:`user`,text:`✅ Подтверждаю`,timestamp:Date.now()}],this._saveMessages(),this.host.requestUpdate();let{result:t,causesNavigation:n}=this.executeAction(e);this.messages=[...this.messages,{role:`assistant`,text:t,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(t),this.host.requestUpdate(),!n&&(await this._waitForDom(1200),await this._agentStep(`Действие подтверждено и выполнено. Проверь результат в DOM.`))}cancelAction(){this.pendingConfirmation&&(this.pendingConfirmation=null,this.messages=[...this.messages,{role:`user`,text:`❌ Отмена`,timestamp:Date.now()},{role:`assistant`,text:`🚫 Действие отменено. Чем ещё могу помочь?`,timestamp:Date.now()}],this._saveMessages(),this._voiceMode&&this._tts.speak(`Действие отменено. Чем ещё могу помочь?`),this.host.requestUpdate())}_waitForDom(e){return new Promise(t=>setTimeout(t,e))}async sendMessage(e,t=!1){!e.trim()||this.isLoading||(await this._agentLoop(e,!0,t),this.host.updateComplete?.then(()=>{let e=this.host.renderRoot?.querySelector(`.chat-messages`);e&&(e.scrollTop=e.scrollHeight)}))}async _agentStep(e){await this._agentLoop(e,!1,this._voiceMode),this.host.updateComplete?.then(()=>{let e=this.host.renderRoot?.querySelector(`.chat-messages`);e&&(e.scrollTop=e.scrollHeight)})}clearMessages(){this.messages=[],this.error=null,this.pendingConfirmation=null,this._saveMessages(),this.host.requestUpdate()}isTtsEnabled(){return this._tts.isEnabled()}setTtsEnabled(e){this._tts.setEnabled(e),this.host.requestUpdate()}async transcribeAudio(e,t){let n=this.host.clientId||window.__BARIWEB_CLIENT_ID__||``,r=new FormData;r.append(`language_mode`,t),r.append(`audio`,e,`speech.wav`);let i=await fetch(`${Nt}/v1/stt/transcribe`,{method:`POST`,headers:{"X-Client-ID":n},body:r});if(!i.ok){let e=`HTTP ${i.status}`;try{e=(await i.json())?.detail||e}catch{}throw Error(e)}return await i.json()}};function Y(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var Rt=n({initAdminMode:()=>Ht,mountAdminPanel:()=>Vt});function zt(){if(!X)return;let e=K(),t=q(),n=Z?.is_trained===!0,r=Z&&!Z.is_trained,i=Z?.label||null,a=Z?.description||null,o=n?`active`:r?`draft`:`idle`,s=n?`trained`:r?`draft`:`idle`,c=n?`✅ Обучено`:r?`📝 Черновик (не подтверждено)`:`🔍 Сканирование...`,l=X.querySelector(`#bw-admin-panel`);l&&(l.className=n?`trained`:`discovering`,l.id=`bw-admin-panel`,n&&l.classList.add(`trained`));let u=X.querySelector(`#bw-panel-content`);u&&(u.innerHTML=`
|
|
913
919
|
<div class="bw-status-box ${n?`trained`:r?`draft`:``}">
|
|
914
920
|
<div class="bw-status-indicator">
|
|
915
921
|
<span class="bw-status-dot ${o}"></span>
|
package/dist/bariweb.js
CHANGED
|
@@ -1169,6 +1169,12 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1169
1169
|
--bw-border: #e2e8f0;
|
|
1170
1170
|
--bw-bg-hover: #f8fafc;
|
|
1171
1171
|
--bw-bg-subtle: #f1f5f9;
|
|
1172
|
+
--bw-danger: #ef4444;
|
|
1173
|
+
--bw-danger-bg: #fee2e2;
|
|
1174
|
+
--bw-danger-border: #fecaca;
|
|
1175
|
+
--bw-success: #10b981;
|
|
1176
|
+
--bw-success-bg: rgba(16, 185, 129, 0.08);
|
|
1177
|
+
--bw-success-border: rgba(16, 185, 129, 0.2);
|
|
1172
1178
|
--bw-radius: 14px;
|
|
1173
1179
|
--bw-radius-sm: 8px;
|
|
1174
1180
|
--bw-shadow-panel: 0 20px 60px -10px rgba(0,0,0,0.18), 0 8px 24px -4px rgba(0,0,0,0.1);
|
|
@@ -1281,7 +1287,7 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1281
1287
|
transition: all 0.2s;
|
|
1282
1288
|
color: var(--bw-fg-muted);
|
|
1283
1289
|
}
|
|
1284
|
-
.close-btn:hover { background:
|
|
1290
|
+
.close-btn:hover { background: var(--bw-danger-bg); color: var(--bw-danger); transform: rotate(90deg); }
|
|
1285
1291
|
.close-btn svg { width: 18px; height: 18px; }
|
|
1286
1292
|
|
|
1287
1293
|
/* ─── Segmented Tab Control ─── */
|
|
@@ -1315,8 +1321,8 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1315
1321
|
.bw-tab:hover { background: var(--bw-bg-hover); color: var(--bw-fg); }
|
|
1316
1322
|
.bw-tab[active] {
|
|
1317
1323
|
background: var(--bw-primary);
|
|
1318
|
-
color:
|
|
1319
|
-
box-shadow: 0 2px 8px rgba(
|
|
1324
|
+
color: var(--bw-primary-fg);
|
|
1325
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
1320
1326
|
}
|
|
1321
1327
|
|
|
1322
1328
|
/* ─── Content area ─── */
|
|
@@ -1411,7 +1417,7 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1411
1417
|
.chat-bubble.user {
|
|
1412
1418
|
align-self: flex-end;
|
|
1413
1419
|
background: var(--bw-primary);
|
|
1414
|
-
color:
|
|
1420
|
+
color: var(--bw-primary-fg);
|
|
1415
1421
|
border-bottom-right-radius: 4px;
|
|
1416
1422
|
}
|
|
1417
1423
|
.chat-bubble.assistant {
|
|
@@ -1423,12 +1429,12 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1423
1429
|
}
|
|
1424
1430
|
|
|
1425
1431
|
.screen-label-badge {
|
|
1426
|
-
background:
|
|
1427
|
-
border: 1px solid
|
|
1432
|
+
background: var(--bw-success-bg);
|
|
1433
|
+
border: 1px solid var(--bw-success-border);
|
|
1428
1434
|
border-radius: var(--bw-radius-sm);
|
|
1429
1435
|
padding: 6px 12px;
|
|
1430
1436
|
font-size: 12px;
|
|
1431
|
-
color:
|
|
1437
|
+
color: var(--bw-success);
|
|
1432
1438
|
display: flex;
|
|
1433
1439
|
align-items: center;
|
|
1434
1440
|
gap: 6px;
|
|
@@ -1492,17 +1498,17 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1492
1498
|
}
|
|
1493
1499
|
.btn-confirm {
|
|
1494
1500
|
width: 100%; min-height: 46px; border-radius: var(--bw-radius-sm);
|
|
1495
|
-
background: var(--bw-primary); color:
|
|
1501
|
+
background: var(--bw-primary); color: var(--bw-primary-fg); border: none;
|
|
1496
1502
|
font-weight: 700; font-size: 14px; cursor: pointer;
|
|
1497
|
-
transition: all 0.2s; box-shadow: 0 4px 12px rgba(
|
|
1503
|
+
transition: all 0.2s; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
1498
1504
|
}
|
|
1499
1505
|
.btn-confirm:hover { filter: brightness(1.1); transform: translateY(-1px); }
|
|
1500
1506
|
.btn-cancel {
|
|
1501
1507
|
width: 100%; min-height: 44px; border-radius: var(--bw-radius-sm);
|
|
1502
|
-
background: transparent; color:
|
|
1508
|
+
background: transparent; color: var(--bw-danger); border: 1px solid var(--bw-danger-border);
|
|
1503
1509
|
font-weight: 600; font-size: 13px; cursor: pointer; transition: all 0.2s;
|
|
1504
1510
|
}
|
|
1505
|
-
.btn-cancel:hover { background:
|
|
1511
|
+
.btn-cancel:hover { background: var(--bw-danger-bg); }
|
|
1506
1512
|
|
|
1507
1513
|
/* Chat input area */
|
|
1508
1514
|
.chat-input-area {
|
|
@@ -1581,14 +1587,14 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1581
1587
|
}
|
|
1582
1588
|
#bw-voice-btn:hover { background: rgba(109, 40, 217, 0.08); transform: scale(1.05); }
|
|
1583
1589
|
#bw-voice-btn.recording {
|
|
1584
|
-
background:
|
|
1585
|
-
border-color:
|
|
1586
|
-
color:
|
|
1590
|
+
background: var(--bw-danger-bg);
|
|
1591
|
+
border-color: var(--bw-danger);
|
|
1592
|
+
color: var(--bw-danger);
|
|
1587
1593
|
animation: micPulse 1.5s infinite;
|
|
1588
1594
|
}
|
|
1589
1595
|
@keyframes micPulse {
|
|
1590
|
-
0% { box-shadow: 0 0 0 0 rgba(
|
|
1591
|
-
100% { box-shadow: 0 0 0 10px rgba(
|
|
1596
|
+
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); transform: scale(1.05); }
|
|
1597
|
+
100% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); transform: scale(1.05); }
|
|
1592
1598
|
}
|
|
1593
1599
|
|
|
1594
1600
|
.chat-icon-btn.tts-on { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.4); color: #059669; }
|
|
@@ -1600,13 +1606,13 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1600
1606
|
border-radius: 50%;
|
|
1601
1607
|
border: none;
|
|
1602
1608
|
background: var(--bw-primary);
|
|
1603
|
-
color:
|
|
1609
|
+
color: var(--bw-primary-fg);
|
|
1604
1610
|
cursor: pointer;
|
|
1605
1611
|
display: flex;
|
|
1606
1612
|
align-items: center;
|
|
1607
1613
|
justify-content: center;
|
|
1608
1614
|
transition: all 0.2s;
|
|
1609
|
-
box-shadow: 0 2px 8px rgba(
|
|
1615
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
1610
1616
|
margin-left: 6px;
|
|
1611
1617
|
}
|
|
1612
1618
|
.chat-send-btn:hover:not(:disabled) { transform: scale(1.08); filter: brightness(1.1); }
|
|
@@ -1959,7 +1965,29 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1959
1965
|
}
|
|
1960
1966
|
}, lt = "http://localhost:8000", ut = class {
|
|
1961
1967
|
constructor(e) {
|
|
1962
|
-
this.isFixing = !1, this.simplifyEnabled = !1, this.autoA11yEnabled = !1, this.
|
|
1968
|
+
this.isFixing = !1, this.simplifyEnabled = !1, this.autoA11yEnabled = !1, this._onParagraphKeydown = (e) => {
|
|
1969
|
+
if (this.simplifyEnabled && (e.key === "Enter" || e.key === " ") && e.target instanceof HTMLElement) {
|
|
1970
|
+
if (e.target.closest("bw-widget") || e.target.closest(".bw-ai-tooltip")) return;
|
|
1971
|
+
let t = e.target.tagName.toLowerCase();
|
|
1972
|
+
if ([
|
|
1973
|
+
"p",
|
|
1974
|
+
"span",
|
|
1975
|
+
"div",
|
|
1976
|
+
"li",
|
|
1977
|
+
"article",
|
|
1978
|
+
"h1",
|
|
1979
|
+
"h2",
|
|
1980
|
+
"h3",
|
|
1981
|
+
"h4",
|
|
1982
|
+
"h5",
|
|
1983
|
+
"h6"
|
|
1984
|
+
].includes(t)) {
|
|
1985
|
+
e.preventDefault(), e.stopPropagation();
|
|
1986
|
+
let t = e.target.getBoundingClientRect();
|
|
1987
|
+
this._triggerSimplify(e.target, t.left + window.scrollX, t.bottom + window.scrollY);
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
}, this._onParagraphClick = async (e) => {
|
|
1963
1991
|
if (!this.simplifyEnabled) return;
|
|
1964
1992
|
let t = e.target;
|
|
1965
1993
|
if (t.closest("bw-widget") || t.closest(".bw-ai-tooltip")) return;
|
|
@@ -1978,32 +2006,7 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
1978
2006
|
"h6"
|
|
1979
2007
|
].includes(n)) {
|
|
1980
2008
|
let n = t.innerText?.trim();
|
|
1981
|
-
|
|
1982
|
-
e.preventDefault(), e.stopPropagation(), document.querySelectorAll(".bw-ai-tooltip").forEach((e) => e.remove());
|
|
1983
|
-
let r = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches, i = document.createElement("div");
|
|
1984
|
-
i.className = "bw-ai-tooltip bw-ai-tooltip-loading", r && i.setAttribute("data-theme", "dark"), i.innerHTML = "\n <div class=\"bw-ai-tooltip-header\">\n <span>✨ AI Упрощение</span>\n <button class=\"bw-ai-tooltip-close\">✕</button>\n </div>\n <div class=\"bw-ai-tooltip-content\">\n Ожидаем ответ от ИИ...\n </div>\n ", document.body.appendChild(i), i.style.left = `${Math.max(10, e.pageX - 160)}px`, i.style.top = `${e.pageY + 20}px`;
|
|
1985
|
-
let a = t.style.outline, o = t.style.backgroundColor;
|
|
1986
|
-
t.style.outline = "2px dashed #a855f7", t.style.backgroundColor = "rgba(168, 85, 247, 0.05)", i.querySelector(".bw-ai-tooltip-close")?.addEventListener("click", () => {
|
|
1987
|
-
i.remove(), t.style.outline = a, t.style.backgroundColor = o;
|
|
1988
|
-
});
|
|
1989
|
-
try {
|
|
1990
|
-
let e = window.BariwebConfig?.clientId || "", t = await fetch(`${lt}/v1/widget/a11y/simplify`, {
|
|
1991
|
-
method: "POST",
|
|
1992
|
-
headers: {
|
|
1993
|
-
"Content-Type": "application/json",
|
|
1994
|
-
"X-Client-ID": e
|
|
1995
|
-
},
|
|
1996
|
-
body: JSON.stringify({ text: n })
|
|
1997
|
-
});
|
|
1998
|
-
if (t.ok) {
|
|
1999
|
-
let e = await t.json();
|
|
2000
|
-
if (e.text) i.classList.remove("bw-ai-tooltip-loading"), i.querySelector(".bw-ai-tooltip-content").innerHTML = e.text;
|
|
2001
|
-
else throw Error("Empty response");
|
|
2002
|
-
} else throw Error("Server error");
|
|
2003
|
-
} catch (e) {
|
|
2004
|
-
console.error("BariWeb AI: Simplify failed", e), i.classList.remove("bw-ai-tooltip-loading"), i.querySelector(".bw-ai-tooltip-content").innerHTML = "<span style=\"color:#ef4444; font-size:13px;\">Ошибка создания упрощенного текста. Попробуйте еще раз.</span>";
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2009
|
+
n && n.length > 20 && (e.preventDefault(), e.stopPropagation(), this._triggerSimplify(t, e.pageX, e.pageY));
|
|
2007
2010
|
}
|
|
2008
2011
|
}, (this.host = e).addController(this), this.simplifyEnabled = localStorage.getItem("bw-ai-simplify") === "true", this.autoA11yEnabled = localStorage.getItem("bw-ai-autofix") === "true", t.onStateChange(() => {
|
|
2009
2012
|
this.autoA11yEnabled && !this.isFixing && this.fixMarkup();
|
|
@@ -2016,6 +2019,20 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
2016
2019
|
hostDisconnected() {
|
|
2017
2020
|
this.simplifyEnabled && (document.body.removeEventListener("click", this._onParagraphClick, { capture: !0 }), document.body.classList.remove("bw-simplify-mode"));
|
|
2018
2021
|
}
|
|
2022
|
+
_announce(e) {
|
|
2023
|
+
let t = document.getElementById("bw-ai-announcer");
|
|
2024
|
+
t || (t = document.createElement("div"), t.id = "bw-ai-announcer", t.setAttribute("aria-live", "polite"), t.setAttribute("aria-atomic", "true"), Object.assign(t.style, {
|
|
2025
|
+
position: "absolute",
|
|
2026
|
+
width: "1px",
|
|
2027
|
+
height: "1px",
|
|
2028
|
+
padding: "0",
|
|
2029
|
+
margin: "-1px",
|
|
2030
|
+
overflow: "hidden",
|
|
2031
|
+
clip: "rect(0, 0, 0, 0)",
|
|
2032
|
+
whiteSpace: "nowrap",
|
|
2033
|
+
border: "0"
|
|
2034
|
+
}), document.body.appendChild(t)), t.textContent = e;
|
|
2035
|
+
}
|
|
2019
2036
|
async fixMarkup() {
|
|
2020
2037
|
this.isFixing = !0, this.host.requestUpdate();
|
|
2021
2038
|
try {
|
|
@@ -2058,22 +2075,55 @@ var at = rt(K), q = (e) => F`${at(`
|
|
|
2058
2075
|
}
|
|
2059
2076
|
});
|
|
2060
2077
|
}
|
|
2078
|
+
this._announce(`Режим для незрячих отработал. AI исправил ${e.length} элементов.`);
|
|
2061
2079
|
} catch (e) {
|
|
2062
|
-
console.error("BariWeb AI: A11y Fix failed", e);
|
|
2080
|
+
console.error("BariWeb AI: A11y Fix failed", e), this._announce("Произошла ошибка при исправлении элементов.");
|
|
2063
2081
|
} finally {
|
|
2064
2082
|
this.isFixing = !1, this.host.requestUpdate();
|
|
2065
2083
|
}
|
|
2066
2084
|
}
|
|
2067
2085
|
toggleSimplify() {
|
|
2068
2086
|
if (this.simplifyEnabled = !this.simplifyEnabled, this.simplifyEnabled) {
|
|
2069
|
-
if (document.body.addEventListener("click", this._onParagraphClick, { capture: !0 }), document.
|
|
2087
|
+
if (document.body.addEventListener("click", this._onParagraphClick, { capture: !0 }), document.body.addEventListener("keydown", this._onParagraphKeydown, { capture: !0 }), document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, article").forEach((e) => {
|
|
2088
|
+
!e.hasAttribute("tabindex") && e.textContent?.trim().length > 20 && (e.setAttribute("tabindex", "0"), e.classList.add("bw-simplify-focusable"));
|
|
2089
|
+
}), document.documentElement.style.setProperty("--bw-simplify-cursor", "help"), !document.getElementById("bw-simplify-mode-style")) {
|
|
2070
2090
|
let e = document.createElement("style");
|
|
2071
2091
|
e.id = "bw-simplify-mode-style", e.textContent = "\n body.bw-simplify-mode *:hover {\n cursor: help !important;\n background-color: rgba(168, 85, 247, 0.1) !important;\n outline: 1px dashed rgba(168, 85, 247, 0.4) !important;\n }\n bw-widget.bw-simplify-mode *:hover, .bw-ai-tooltip *:hover {\n cursor: inherit !important;\n background-color: transparent !important;\n outline: none !important;\n }\n .bw-ai-tooltip {\n position: absolute;\n width: 320px;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);\n color: #0f172a;\n font-family: system-ui, -apple-system, sans-serif;\n z-index: 999999;\n overflow: hidden;\n animation: bwAiFadeIn 0.2s ease-out;\n }\n .bw-ai-tooltip[data-theme=\"dark\"] {\n background: #1e293b;\n border-color: #334155;\n color: #f8fafc;\n }\n .bw-ai-tooltip-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: #f8fafc;\n border-bottom: 1px solid #e2e8f0;\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n }\n .bw-ai-tooltip[data-theme=\"dark\"] .bw-ai-tooltip-header {\n background: #0f172a;\n border-bottom-color: #334155;\n color: #94a3b8;\n }\n .bw-ai-tooltip-close {\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n font-size: 14px;\n padding: 2px 6px;\n border-radius: 4px;\n }\n .bw-ai-tooltip-close:hover {\n background: rgba(0,0,0,0.05);\n }\n .bw-ai-tooltip[data-theme=\"dark\"] .bw-ai-tooltip-close:hover {\n background: rgba(255,255,255,0.1);\n }\n .bw-ai-tooltip-content {\n padding: 14px;\n font-size: 14px;\n line-height: 1.6;\n }\n .bw-ai-tooltip-loading .bw-ai-tooltip-content {\n display: flex;\n align-items: center;\n gap: 10px;\n color: #64748b;\n font-style: italic;\n font-size: 13px;\n }\n @keyframes bwAiFadeIn {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n ", document.head.appendChild(e);
|
|
2072
2092
|
}
|
|
2073
|
-
document.body.classList.add("bw-simplify-mode");
|
|
2074
|
-
} else document.body.removeEventListener("click", this._onParagraphClick, { capture: !0 }), document.body.
|
|
2093
|
+
document.body.classList.add("bw-simplify-mode"), this._announce("Режим AI Упрощение текста включен. Используйте Tab для навигации по тексту и Enter для упрощения.");
|
|
2094
|
+
} else document.body.removeEventListener("click", this._onParagraphClick, { capture: !0 }), document.body.removeEventListener("keydown", this._onParagraphKeydown, { capture: !0 }), document.querySelectorAll(".bw-simplify-focusable").forEach((e) => {
|
|
2095
|
+
e.removeAttribute("tabindex"), e.classList.remove("bw-simplify-focusable");
|
|
2096
|
+
}), document.body.classList.remove("bw-simplify-mode"), document.documentElement.style.removeProperty("--bw-simplify-cursor"), this._announce("Режим AI Упрощение текста выключен.");
|
|
2075
2097
|
this.host.requestUpdate();
|
|
2076
2098
|
}
|
|
2099
|
+
async _triggerSimplify(e, t, n) {
|
|
2100
|
+
let r = e.innerText?.trim();
|
|
2101
|
+
if (!r) return;
|
|
2102
|
+
document.querySelectorAll(".bw-ai-tooltip").forEach((e) => e.remove());
|
|
2103
|
+
let i = document.createElement("div");
|
|
2104
|
+
i.className = "bw-ai-tooltip bw-ai-tooltip-loading", i.tabIndex = -1, i.innerHTML = "\n <div class=\"bw-ai-tooltip-header\">\n <span>✨ AI Упрощение</span>\n <button class=\"bw-ai-tooltip-close\" aria-label=\"Закрыть\">✕</button>\n </div>\n <div class=\"bw-ai-tooltip-content\" role=\"status\" aria-live=\"polite\">\n Ожидаем ответ от ИИ...\n </div>\n ", document.body.appendChild(i), i.style.left = `${Math.max(10, t - 160)}px`, i.style.top = `${n + 20}px`;
|
|
2105
|
+
let a = e.style.outline, o = e.style.backgroundColor;
|
|
2106
|
+
e.style.outline = "2px dashed #a855f7", e.style.backgroundColor = "rgba(168, 85, 247, 0.05)", i.querySelector(".bw-ai-tooltip-close")?.addEventListener("click", () => {
|
|
2107
|
+
i.remove(), e.style.outline = a, e.style.backgroundColor = o;
|
|
2108
|
+
});
|
|
2109
|
+
try {
|
|
2110
|
+
let e = window.BariwebConfig?.clientId || "", t = await fetch(`${lt}/v1/widget/a11y/simplify`, {
|
|
2111
|
+
method: "POST",
|
|
2112
|
+
headers: {
|
|
2113
|
+
"Content-Type": "application/json",
|
|
2114
|
+
"X-Client-ID": e
|
|
2115
|
+
},
|
|
2116
|
+
body: JSON.stringify({ text: r })
|
|
2117
|
+
});
|
|
2118
|
+
if (t.ok) {
|
|
2119
|
+
let e = await t.json();
|
|
2120
|
+
if (e.text) i.classList.remove("bw-ai-tooltip-loading"), i.querySelector(".bw-ai-tooltip-content").innerHTML = e.text, i.focus();
|
|
2121
|
+
else throw Error("Empty response");
|
|
2122
|
+
} else throw Error("Server error");
|
|
2123
|
+
} catch (e) {
|
|
2124
|
+
console.error("BariWeb AI: Simplify failed", e), i.classList.remove("bw-ai-tooltip-loading"), i.querySelector(".bw-ai-tooltip-content").innerHTML = "<span style=\"color:#ef4444; font-size:13px;\">Ошибка создания упрощенного текста. Попробуйте еще раз.</span>", i.focus();
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2077
2127
|
}, dt = "bw-tts-enabled-v1", ft = class {
|
|
2078
2128
|
constructor() {
|
|
2079
2129
|
this.enabled = !0, this.enabled = this.loadEnabled();
|