iobroker.agent-dvr 0.0.4 → 0.0.6

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/build/main.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport * as http from 'node:http';\nimport { getWidgetLabels, type WidgetLabels } from './lib/widget-i18n';\n\n// =====================================================================\n// Agent DVR -> ioBroker Adapter\n// API reference: https://ispysoftware.github.io/Agent_API/ (v7.5)\n// =====================================================================\n\n// ---- Types ----\n\ninterface ApiResult {\n\tok: boolean;\n\tdata?: string;\n\terror?: string;\n}\n\ninterface AgentDvrEvent {\n\tfn?: string;\n\ttg?: string;\n\tc?: number;\n\td?: number | string;\n\tsb?: number;\n\t[key: string]: unknown;\n}\n\ninterface Device {\n\toid: number | string;\n\tot: number;\n\tname: string;\n\traw: Record<string, unknown>;\n}\n\ntype RegistryKind = 'cam' | 'sys' | 'ptz' | 'ptzHold' | 'push' | 'setProfile' | 'snapshotB64';\n\ninterface RegistryEntry {\n\tkind: RegistryKind;\n\tpath?: string | null;\n\tparams?: string[];\n\toid?: number | string;\n\tot?: number;\n\tdir?: number;\n\tfid?: string;\n}\n\n// ---- Commands ----\n\nconst CAM_COMMANDS = [\n\t{ id: 'record', path: '/command/record', params: ['oid', 'ot'], name: 'Start recording' },\n\t{ id: 'recordStop', path: '/command/recordStop', params: ['oid', 'ot'], name: 'Stop recording' },\n\t{ id: 'recordRestart', path: '/command/recordRestart', params: ['oid', 'ot'], name: 'Restart recording' },\n\t{ id: 'triggerRecord', path: '/command/triggerRecord', params: ['oid', 'ot'], name: 'Trigger recording (timeout)' },\n\t{ id: 'snapshot', path: '/command/snapshot', params: ['oid'], name: 'Take snapshot' },\n\t{ id: 'detect', path: '/command/detect', params: ['oid', 'ot'], name: 'Trigger motion detection' },\n\t{ id: 'alertOn', path: '/command/alertOn', params: ['oid', 'ot'], name: 'Arm alerts' },\n\t{ id: 'alertOff', path: '/command/alertOff', params: ['oid', 'ot'], name: 'Disarm alerts' },\n\t{ id: 'switchOn', path: '/command/switchOn', params: ['oid', 'ot'], name: 'Switch device on' },\n\t{ id: 'switchOff', path: '/command/switchOff', params: ['oid', 'ot'], name: 'Switch device off' },\n\t{ id: 'objectDetectOn', path: '/command/objectdetecton', params: ['oid', 'ot'], name: 'Enable object detection' },\n\t{\n\t\tid: 'objectDetectOff',\n\t\tpath: '/command/objectdetectoff',\n\t\tparams: ['oid', 'ot'],\n\t\tname: 'Disable object detection',\n\t},\n\t{ id: 'recOnAlert', path: '/command/recordOnAlertOn', params: ['oid', 'ot'], name: 'Record on alert: on' },\n\t{ id: 'recOnDetect', path: '/command/recordOnDetectOn', params: ['oid', 'ot'], name: 'Record on detect: on' },\n\t{ id: 'purge', path: '/command/purge', params: ['oid', 'ot'], name: 'Purge folder (caution!)' },\n] as const;\n\nconst SYS_COMMANDS = [\n\t{ id: 'arm', path: '/command/arm', name: 'Arm system' },\n\t{ id: 'disarm', path: '/command/disarm', name: 'Disarm system' },\n\t{ id: 'allOn', path: '/command/allOn', name: 'All devices on' },\n\t{ id: 'allOff', path: '/command/allOff', name: 'All devices off' },\n\t{ id: 'reloadConfig', path: '/command/reloadConfig', name: 'Reload config' },\n\t{ id: 'reloadObjects', path: '/command/reloadObjects', name: 'Reload objects' },\n\t{ id: 'runStorageMgmt', path: '/command/runStorageMgmt', name: 'Run storage management' },\n\t{ id: 'blockExternal', path: '/command/blockExternal', name: 'Block external access' },\n\t{ id: 'unblockExternal', path: '/command/unblockExternal', name: 'Unblock external access' },\n\t{ id: 'restart', path: '/command/restart', name: 'Restart Agent DVR' },\n\t{ id: 'refresh', path: null, name: 'Refresh data now' },\n] as const;\n\nconst PTZ_DIRS = [\n\t{ id: 'left', dir: 1, hold: true },\n\t{ id: 'upLeft', dir: 2, hold: true },\n\t{ id: 'up', dir: 3, hold: true },\n\t{ id: 'upRight', dir: 4, hold: true },\n\t{ id: 'right', dir: 5, hold: true },\n\t{ id: 'downRight', dir: 6, hold: true },\n\t{ id: 'down', dir: 7, hold: true },\n\t{ id: 'downLeft', dir: 8, hold: true },\n\t{ id: 'zoomIn', dir: 9, hold: true },\n\t{ id: 'zoomOut', dir: 10, hold: true },\n\t{ id: 'stop', dir: 11, hold: false },\n\t{ id: 'center', dir: 0, hold: false },\n] as const;\n\nconst SKIP_KEYS = ['icons', 'image', 'thumbnail', 'base64'];\n\n// ---- Module-level helpers ----\n\nfunction sanitize(s: unknown): string {\n\treturn (\n\t\tString(s)\n\t\t\t.replace(/[\\s.[\\]*?\"'`,;:/\\\\]+/g, '_')\n\t\t\t.replace(/[^A-Za-z0-9_-]/g, '_')\n\t\t\t.replace(/_+/g, '_')\n\t\t\t.replace(/^_+|_+$/g, '') || 'x'\n\t);\n}\n\nfunction asJson(data: unknown): Record<string, unknown> | null {\n\tif (data == null) {\n\t\treturn null;\n\t}\n\tif (typeof data === 'object') {\n\t\treturn data as Record<string, unknown>;\n\t}\n\tif (typeof data === 'string') {\n\t\ttry {\n\t\t\treturn JSON.parse(data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction toStr(v: unknown): string {\n\tif (v == null) {\n\t\treturn '';\n\t}\n\tif (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n\t\treturn String(v);\n\t}\n\treturn Object.prototype.toString.call(v);\n}\n\nfunction escHtml(s: unknown): string {\n\treturn toStr(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\nfunction parseSizeGb(s: unknown): number | null {\n\tif (s == null) {\n\t\treturn null;\n\t}\n\tconst m = toStr(s)\n\t\t.trim()\n\t\t.match(/([\\d.,]+)\\s*([KMGT]?B)?/i);\n\tif (!m) {\n\t\treturn null;\n\t}\n\tlet v = parseFloat(m[1].replace(',', '.'));\n\tif (isNaN(v)) {\n\t\treturn null;\n\t}\n\tconst u = (m[2] || 'GB').toUpperCase();\n\tif (u === 'TB') {\n\t\tv *= 1024;\n\t} else if (u === 'MB') {\n\t\tv /= 1024;\n\t} else if (u === 'KB') {\n\t\tv /= 1048576;\n\t} else if (u === 'B') {\n\t\tv /= 1073741824;\n\t}\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction findWH(obj: unknown, depth: number): [number, number] | null {\n\tif (!obj || typeof obj !== 'object' || depth > 5) {\n\t\treturn null;\n\t}\n\tconst o = obj as Record<string, unknown>;\n\tfor (const [kw, kh] of [\n\t\t['width', 'height'],\n\t\t['w', 'h'],\n\t\t['sourceWidth', 'sourceHeight'],\n\t\t['videoWidth', 'videoHeight'],\n\t\t['imageWidth', 'imageHeight'],\n\t]) {\n\t\tconst w = o[kw],\n\t\t\th = o[kh];\n\t\tif (typeof w === 'number' && typeof h === 'number' && w >= 100 && h >= 100 && w <= 12000 && h <= 12000) {\n\t\t\tconst r = w / h;\n\t\t\tif (r >= 0.3 && r <= 4) {\n\t\t\t\treturn [w, h];\n\t\t\t}\n\t\t}\n\t}\n\tfor (const k of Object.keys(o)) {\n\t\tconst g = findWH(o[k], depth + 1);\n\t\tif (g) {\n\t\t\treturn g;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction detectOt(elem: Record<string, unknown>): number {\n\tconst v = elem.typeID ?? elem.ot ?? elem.objectTypeID ?? elem.type;\n\treturn v === 1 || v === 2 ? v : 2;\n}\n\nfunction findDevices(json: Record<string, unknown>): Device[] {\n\tconst list = Array.isArray(json.objectList) ? json.objectList : [];\n\tconst out: Device[] = [];\n\tfor (const e of list) {\n\t\tif (!e || typeof e !== 'object') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst el = e as Record<string, unknown>;\n\t\tconst rawId = el.id ?? el.oid;\n\t\tif (rawId === undefined || rawId === null) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = rawId as number | string;\n\t\tconst name = typeof el.name === 'string' ? el.name : `obj_${id}`;\n\t\tout.push({ oid: id, ot: detectOt(el), name, raw: el });\n\t}\n\treturn out;\n}\n\n// ---- HTML/CSS gallery helpers ----\n\nfunction galleryCss(minCol: number, maxW: number): string {\n\treturn (\n\t\t`.advgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:12px;max-width:100%}` +\n\t\t`.advgrid .advlb{display:none}` +\n\t\t`.advcell{display:flex;flex-direction:column;cursor:pointer;text-decoration:none;color:inherit;font-family:inherit}` +\n\t\t`.advimg{position:relative;display:block;border-radius:8px;overflow:hidden;background:rgba(127,127,127,.15)}` +\n\t\t`.advimg img{width:100%;height:auto;display:block}` +\n\t\t`.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtag{position:absolute;background:rgba(0,0,0,.55);color:#fff;font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplay::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcell:hover .advplay{opacity:1}` +\n\t\t`.advcap{font-size:.72rem;margin-top:4px;line-height:1.25;opacity:.85}` +\n\t\t`.advmodal{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}` +\n\t\t`.advgrid .advlb:checked + .advthumb + .advmodal{display:flex}` +\n\t\t`.advbackdrop{position:absolute;inset:0;background:transparent;cursor:pointer}` +\n\t\t`.advbox{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,${maxW}px);background:#1c1c1e;padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}` +\n\t\t`.advvideo{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}` +\n\t\t`.advclose{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}` +\n\t\t`.advinfo{color:#fff;font-size:.8rem;text-align:center}` +\n\t\t`.advinfo a{color:#8ab4f8}` +\n\t\t`.advempty{padding:24px;text-align:center;opacity:.7;font-family:inherit}`\n\t);\n}\n\nfunction galleryCssJs(minCol: number): string {\n\treturn (\n\t\t`.advroot{font-family:inherit;color:inherit}` +\n\t\t`.advbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}` +\n\t\t`.advsearchjs{flex:1 1 160px;min-width:120px;padding:6px 10px;border-radius:8px;border:1px solid rgba(127,127,127,.4);background:rgba(127,127,127,.08);color:inherit;font:inherit}` +\n\t\t`.advtagsjs{display:flex;flex-wrap:wrap;gap:6px}` +\n\t\t`.advtagbtn{padding:4px 10px;border-radius:999px;border:1px solid rgba(127,127,127,.4);background:transparent;color:inherit;cursor:pointer;font:inherit;font-size:.8rem}` +\n\t\t`.advtagbtn.on{background:#2d6cdf;color:#fff;border-color:#2d6cdf}` +\n\t\t`.advgridjs{display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:12px}` +\n\t\t`.advcelljs{display:flex;flex-direction:column;cursor:pointer}` +\n\t\t`.advimgjs{position:relative;display:block;border-radius:8px;overflow:hidden;background:rgba(127,127,127,.15)}` +\n\t\t`.advimgjs img{width:100%;height:auto;display:block}` +\n\t\t`.advimgjs.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtagjs{position:absolute;background:rgba(0,0,0,.55);color:#fff;font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplayjs{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplayjs::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcelljs:hover .advplayjs{opacity:1}` +\n\t\t`.advcapjs{font-size:.72rem;margin-top:4px;line-height:1.25;opacity:.85}` +\n\t\t`.advemptyjs{padding:24px;text-align:center;opacity:.7}`\n\t);\n}\n\n// Client-side browser code for the JS widget variant.\n// Stored as a string: TypeScript never type-checks browser code running in DOM context.\nconst ADV_CLIENT_CODE = `\n(function(){\nfunction esc(s){return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');}\nvar MODAL_CSS='.advmodaljs{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}.advbackdropjs{position:absolute;inset:0;background:transparent;cursor:pointer}.advboxjs{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,900px);background:#1c1c1e;padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}.advvideojs{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}.advclosejs{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}.advinfojs{color:#fff;font-size:.8rem;text-align:center}';\nvar modalEl=null,modalVideo=null,modalInfo=null,modalBox=null;\nfunction getModal(){\n if(modalEl&&document.body.contains(modalEl))return modalEl;\n if(!document.getElementById('advmodalcss')){var st=document.createElement('style');st.id='advmodalcss';st.textContent=MODAL_CSS;document.head.appendChild(st);}\n modalEl=document.createElement('div');modalEl.className='advmodaljs';\n var bd=document.createElement('div');bd.className='advbackdropjs';\n modalBox=document.createElement('div');modalBox.className='advboxjs';\n var cl=document.createElement('span');cl.className='advclosejs';cl.textContent='\u2715';\n modalVideo=document.createElement('video');modalVideo.className='advvideojs';\n modalVideo.setAttribute('controls','');modalVideo.setAttribute('preload','none');modalVideo.setAttribute('playsinline','');\n modalInfo=document.createElement('div');modalInfo.className='advinfojs';\n modalBox.appendChild(cl);modalBox.appendChild(modalVideo);modalBox.appendChild(modalInfo);\n modalEl.appendChild(bd);modalEl.appendChild(modalBox);\n document.body.appendChild(modalEl);\n bd.addEventListener('click',closeModal);cl.addEventListener('click',closeModal);\n return modalEl;\n}\nfunction openSrc(src,label,maxW){\n var m=getModal();\n if(maxW)modalBox.style.maxWidth='min(92vw,'+maxW+'px)';\n modalVideo.setAttribute('src',src);modalInfo.textContent=label;m.style.display='flex';\n}\nfunction closeModal(){\n if(!modalEl)return;\n try{modalVideo.pause();}catch(e){}\n modalVideo.removeAttribute('src');try{modalVideo.load();}catch(e){}\n modalEl.style.display='none';\n}\ndocument.addEventListener('keydown',function(e){if(e.key==='Escape'||e.keyCode===27)closeModal();});\nfunction initRoot(root){\n var dataEl=root.querySelector('script.advdata');\n if(!dataEl)return;\n var D;try{D=JSON.parse(dataEl.textContent);}catch(e){return;}\n var cfg=D.cfg||{},items=D.items||[],live=D.live||null;\n var grid=root.querySelector('.advgridjs'),search=root.querySelector('.advsearchjs'),tagsBox=root.querySelector('.advtagsjs');\n var state={q:'',tag:''};\n var tagset={};\n items.forEach(function(it){String(it.tag||'').split(/[,\\\\s]+/).forEach(function(t){if(t)tagset[t]=1;});});\n var tags=Object.keys(tagset);\n if(cfg.show_tags&&tags.length){\n var mk=function(label,val){\n var b=document.createElement('button');b.className='advtagbtn';b.textContent=label;b.setAttribute('data-tag',val);\n b.addEventListener('click',function(){state.tag=state.tag===val?'':val;updateTagBtns();render();});\n tagsBox.appendChild(b);\n };\n mk(cfg.labels&&cfg.labels.all||'All','');tags.forEach(function(t){mk(t,t);});\n }\n function updateTagBtns(){var bs=tagsBox.querySelectorAll('.advtagbtn');for(var i=0;i<bs.length;i++)bs[i].classList.toggle('on',bs[i].getAttribute('data-tag')===state.tag);}\n updateTagBtns();\n if(search)search.addEventListener('input',function(){state.q=this.value.toLowerCase();render();});\n function badge(it){if(!(cfg.show_tags&&it.tag))return '';var pos=String(cfg.tag_position||'bottom-left').split('-');return '<span class=\"advtagjs\" style=\"'+pos[0]+':5px;'+pos[1]+':5px\">'+esc(it.tag)+'</span>';}\n function render(){\n var html='';\n if(live){var ar=cfg.live_aspect||'',arStyle=ar?' style=\"aspect-ratio:'+ar.replace('/',' / ')+'\"':'',arCls=ar?' advimgfix':'';\n html+='<div class=\"advcelljs\" data-live=\"1\"><span class=\"advimgjs'+arCls+'\"'+arStyle+'><img loading=\"lazy\" src=\"'+esc(live.thumb)+'\"><span class=\"advtagjs\" style=\"top:5px;left:5px\">&#9679; '+(cfg.labels&&cfg.labels.live||'LIVE')+'</span><span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(live.name)+'</span></div>';}\n items.forEach(function(it,i){\n if(state.tag&&String(it.tag||'').toLowerCase().indexOf(state.tag.toLowerCase())<0)return;\n if(state.q){var hay=((it.date||'')+' '+(it.time||'')+' '+(it.tag||'')).toLowerCase();if(hay.indexOf(state.q)<0)return;}\n html+='<div class=\"advcelljs\" data-i=\"'+i+'\"><span class=\"advimgjs\"><img loading=\"lazy\" src=\"'+esc(it.thumb)+'\">'+badge(it)+'<span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(it.date)+' '+esc(it.time)+'<br>'+esc(it.dur)+'s &middot; '+esc(it.size)+' MB</span></div>';\n });\n grid.innerHTML=html||'<div class=\"advemptyjs\">'+(cfg.labels&&cfg.labels.noRecordings||'No recordings')+'</div>';\n var cells=grid.querySelectorAll('.advcelljs');\n for(var k=0;k<cells.length;k++)(function(cell){\n cell.addEventListener('click',function(){\n if(cell.getAttribute('data-live')==='1'){openSrc(live.video,(live.name||'')+' \u00B7 Live',cfg.max_modal_width);return;}\n var it=items[parseInt(cell.getAttribute('data-i'),10)],maxW=Number(cfg.max_modal_width)||900;\n if(cfg.player_url){var u=cfg.player_url.replace(/{video}/g,encodeURIComponent(it.video)).replace(/{videoRaw}/g,it.video).replace(/{fn}/g,encodeURIComponent(it.fn||'')).replace(/{date}/g,encodeURIComponent(it.date)).replace(/{time}/g,encodeURIComponent(it.time)).replace(/{duration}/g,encodeURIComponent(it.dur)).replace(/{size}/g,encodeURIComponent(it.size)).replace(/{tags}/g,encodeURIComponent(it.tag));window.open(u,'_blank');}\n else{openSrc(it.video,esc(it.date)+' '+esc(it.time)+(it.dur!=null?' \u00B7 '+it.dur+'s':'')+(it.size!=null?' \u00B7 '+it.size+' MB':'')+(it.tag?' \u00B7 '+it.tag:''),maxW);}\n });\n })(cells[k]);\n }\n render();\n}\nfunction scan(){var roots=document.querySelectorAll('.advroot');for(var i=0;i<roots.length;i++)if(!roots[i].__adv){roots[i].__adv=1;initRoot(roots[i]);}}\nwindow.ADVscan=scan;scan();\n})();\n`.trim();\n\n// ---- Adapter class ----\n\nclass AgentDvr extends utils.Adapter {\n\tprivate pollTimer: ioBroker.Interval | undefined = undefined;\n\tprivate refreshTimer: ioBroker.Timeout | undefined = undefined;\n\tprivate authHeader: string | null = null;\n\tprivate baseUrl = '';\n\tprivate wt: WidgetLabels = getWidgetLabels('en');\n\n\tprivate readonly ensuredFolders = new Set<string>();\n\tprivate readonly registry = new Map<string, RegistryEntry>();\n\tprivate readonly ptzActive = new Map<string | number, string>();\n\tprivate readonly widgetSig: Record<string, string> = {};\n\tprivate profileSig = '';\n\tprivate readonly lastEventFn: Record<string | number, string> = {};\n\tprivate readonly camAspect: Record<string | number, string> = {};\n\tprivate readonly devById = new Map<string | number, Device>();\n\tprivate readonly eventBusy: Record<string | number, boolean> = {};\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({ ...options, name: 'agent-dvr' });\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t// ---- lifecycle ----\n\n\tprivate async onReady(): Promise<void> {\n\t\tvoid this.setState('info.connection', false, true);\n\n\t\tconst sysConfig = await this.getForeignObjectAsync('system.config');\n\t\tconst rawLang = (sysConfig?.common as unknown as { language?: string } | undefined)?.language;\n\t\tthis.wt = getWidgetLabels(rawLang ?? 'en');\n\n\t\tconst pollSeconds = Math.max(5, Math.min(3600, this.config.pollSeconds || 30));\n\t\tthis.baseUrl = `http://${this.config.ip}:${this.config.port || 8090}`;\n\n\t\tif (this.config.user || this.config.pass) {\n\t\t\tthis.authHeader = `Basic ${Buffer.from(`${this.config.user}:${this.config.pass}`).toString('base64')}`;\n\t\t}\n\n\t\tawait this.buildSystem();\n\t\ttry {\n\t\t\tawait this.poll();\n\t\t} catch (e) {\n\t\t\tthis.log.warn(`First poll error: ${(e as Error).message}`);\n\t\t}\n\n\t\tthis.pollTimer = this.setInterval(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Poll error: ${(e as Error).message}`)),\n\t\t\tpollSeconds * 1000,\n\t\t);\n\n\t\tthis.subscribeStates('*');\n\t\tthis.log.info(`Agent DVR adapter ready. Polling ${this.baseUrl} every ${pollSeconds}s.`);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.pollTimer !== undefined) {\n\t\t\t\tthis.clearInterval(this.pollTimer);\n\t\t\t\tthis.pollTimer = undefined;\n\t\t\t}\n\t\t\tif (this.refreshTimer !== undefined) {\n\t\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\t\tthis.refreshTimer = undefined;\n\t\t\t}\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t\tcallback();\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (!state || state.ack !== false) {\n\t\t\treturn;\n\t\t}\n\t\tconst relId = this.getRelId(id);\n\t\tconst entry = this.registry.get(relId);\n\t\tif (entry) {\n\t\t\tthis.runCommand(relId, entry, state.val).catch(e =>\n\t\t\t\tthis.log.warn(`Command error: ${(e as Error).message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- helpers ----\n\n\tprivate getRelId(fullId: string): string {\n\t\treturn fullId.startsWith(`${this.namespace}.`) ? fullId.slice(this.namespace.length + 1) : fullId;\n\t}\n\n\tprivate apiGet(path: string): Promise<ApiResult> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tlet data = '';\n\t\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\t\tdata += c.toString();\n\t\t\t\t\t});\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate apiGetBuffer(path: string): Promise<{ ok: boolean; data?: Buffer; error?: string }> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\tres.on('data', (c: Buffer) => chunks.push(c));\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data: Buffer.concat(chunks) });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async ensureFolder(id: string, name: string, type: 'device' | 'channel' = 'channel'): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setObjectNotExistsAsync(id, { type, common: { name }, native: {} });\n\t\tthis.ensuredFolders.add(id);\n\t}\n\n\tprivate async ensurePath(fullId: string): Promise<void> {\n\t\tconst parts = fullId.split('.');\n\t\tlet acc = parts[0];\n\t\tfor (let i = 1; i < parts.length - 1; i++) {\n\t\t\tacc += `.${parts[i]}`;\n\t\t\tif (!this.ensuredFolders.has(acc)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(acc, { type: 'channel', common: { name: parts[i] }, native: {} });\n\t\t\t\tthis.ensuredFolders.add(acc);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate guessRole(id: string, val: unknown): ioBroker.CommonType {\n\t\tif (typeof val === 'string' && /^https?:\\/\\//i.test(val)) {\n\t\t\treturn 'string';\n\t\t}\n\t\treturn 'string';\n\t}\n\n\tprivate async writeLeaf(id: string, val: unknown): Promise<void> {\n\t\tconst t = typeof val;\n\t\tlet common: ioBroker.StateCommon;\n\t\tif (t === 'boolean') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'boolean', role: 'indicator', read: true, write: false };\n\t\t} else if (t === 'number') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'number', role: 'value', read: true, write: false };\n\t\t} else {\n\t\t\tconst role = typeof val === 'string' && /^https?:\\/\\//i.test(val) ? 'text.url' : 'text';\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'string', role, read: true, write: false };\n\t\t}\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, { type: 'state', common, native: {} });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tawait this.setStateAsync(id, { val: (val === undefined ? null : val) as ioBroker.StateValue, ack: true });\n\t}\n\n\tprivate async flattenWrite(obj: unknown, prefix: string, depth: number): Promise<void> {\n\t\tconst maxDepth = Math.max(1, Math.min(10, this.config.maxDepth || 6));\n\t\tconst maxArray = Math.max(1, Math.min(500, this.config.maxArray || 30));\n\t\tif (depth > maxDepth) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj === null || obj === undefined) {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof obj === 'object') {\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tif (obj.length > maxArray) {\n\t\t\t\t\tawait this.writeLeaf(`${prefix}.count`, obj.length);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\t\t\tawait this.flattenWrite(obj[i], `${prefix}.${i}`, depth + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const k of Object.keys(obj)) {\n\t\t\t\t\tif (SKIP_KEYS.includes(k)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.flattenWrite((obj as Record<string, unknown>)[k], `${prefix}.${sanitize(k)}`, depth + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t}\n\t}\n\n\tprivate async ensureControl(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\trole: 'button' | 'switch',\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'boolean', role, read: role === 'switch', write: true, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate ensureButton(id: string, name: string, entry: RegistryEntry): Promise<void> {\n\t\treturn this.ensureControl(id, name, entry, 'button');\n\t}\n\n\tprivate async ensureSelector(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\tstates: Record<number, string>,\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'number', role: 'level', read: true, write: true, states },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: 0, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate async fetchSnapshotB64(oid: number | string, snapId: string): Promise<void> {\n\t\tconst imgRes = await this.apiGetBuffer(`/photo.jpg?oid=${oid}`);\n\t\tif (imgRes.ok && imgRes.data) {\n\t\t\tawait this.setStateAsync(snapId, {\n\t\t\t\tval: `data:image/jpeg;base64,${imgRes.data.toString('base64')}`,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async ensureFlag(id: string, name: string): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.ensurePath(id);\n\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name, type: 'boolean', role: 'indicator', read: true, write: false, def: false },\n\t\t\tnative: {},\n\t\t});\n\t\tthis.ensuredFolders.add(id);\n\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t}\n\n\tprivate async pulse(id: string): Promise<void> {\n\t\tawait this.setStateAsync(id, { val: true, ack: true });\n\t\tthis.setTimeout(() => this.setStateAsync(id, { val: false, ack: true }).catch(() => {}), 1500);\n\t}\n\n\t// ---- system structure ----\n\n\tprivate async buildSystem(): Promise<void> {\n\t\tawait this.ensureFolder('system', 'System', 'channel');\n\t\tawait this.writeLeaf('system.online', false);\n\t\tawait this.writeLeaf('system.lastUpdate', '');\n\t\tawait this.writeLeaf('system.lastPoll', 0);\n\t\tawait this.writeLeaf('system.cameraCount', 0);\n\n\t\tif (this.config.enableSystemControls) {\n\t\t\tawait this.ensureFolder('system.control', 'Control', 'channel');\n\t\t\tfor (const c of SYS_COMMANDS) {\n\t\t\t\tawait this.ensureButton(`system.control.${c.id}`, c.name, { kind: 'sys', path: c.path });\n\t\t\t}\n\t\t\tawait this.ensureFolder('system.profile', 'Profile', 'channel');\n\t\t\tawait this.ensureSelector(\n\t\t\t\t'system.profile.selector',\n\t\t\t\t'Active profile',\n\t\t\t\t{ kind: 'setProfile' },\n\t\t\t\t{ 0: 'Home', 1: 'Away', 2: 'Night' },\n\t\t\t);\n\t\t\tif (!this.ensuredFolders.has('system.profile.list')) {\n\t\t\t\tawait this.setObjectNotExistsAsync('system.profile.list', {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Available profiles (JSON)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'json',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add('system.profile.list');\n\t\t\t\tawait this.setStateAsync('system.profile.list', { val: '[]', ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---- camera aspect detection ----\n\n\tprivate async detectAspect(d: Device): Promise<void> {\n\t\tif (this.camAspect[d.oid] !== undefined) {\n\t\t\treturn;\n\t\t}\n\t\tlet wh = findWH(d.raw, 0);\n\t\tif (!wh) {\n\t\t\tconst res = await this.apiGet(`/command/getObject?oid=${d.oid}&ot=2`);\n\t\t\tconst j = asJson(res.data);\n\t\t\tif (j) {\n\t\t\t\twh = findWH(j, 0);\n\t\t\t}\n\t\t}\n\t\tthis.camAspect[d.oid] = wh ? `${wh[0]}/${wh[1]}` : '';\n\t\tif (wh) {\n\t\t\tthis.log.debug(`cam ${d.oid} resolution ${wh[0]}x${wh[1]} -> AR ${this.camAspect[d.oid]}`);\n\t\t}\n\t}\n\n\t// ---- device folder name ----\n\n\tprivate deviceFolder(d: Device): string {\n\t\treturn `${d.ot === 1 ? 'mic' : 'cam'}_${sanitize(d.oid)}_${sanitize(d.name)}`;\n\t}\n\n\t// ---- build device data points ----\n\n\tprivate async buildDevice(d: Device): Promise<void> {\n\t\tconst fid = this.deviceFolder(d);\n\t\tthis.devById.set(d.oid, d);\n\n\t\tawait this.ensureFolder(fid, d.name, 'device');\n\t\tif (d.ot === 2) {\n\t\t\tawait this.detectAspect(d);\n\t\t}\n\t\tawait this.flattenWrite(d.raw, fid, 0);\n\n\t\tawait this.ensureFolder(`${fid}.control`, 'Control', 'channel');\n\t\tfor (const c of CAM_COMMANDS) {\n\t\t\tif (c.id === 'snapshot' && d.ot !== 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.${c.id}`, c.name, {\n\t\t\t\tkind: 'cam',\n\t\t\t\tpath: c.path,\n\t\t\t\tparams: [...c.params],\n\t\t\t\toid: d.oid,\n\t\t\t\tot: d.ot,\n\t\t\t});\n\t\t}\n\n\t\tif (this.config.enablePtz && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.control.ptz`, 'PTZ', 'channel');\n\t\t\tfor (const p of PTZ_DIRS) {\n\t\t\t\tconst cid = `${fid}.control.ptz.${p.id}`;\n\t\t\t\tif (p.hold) {\n\t\t\t\t\tawait this.ensureControl(\n\t\t\t\t\t\tcid,\n\t\t\t\t\t\t`PTZ ${p.id} (hold)`,\n\t\t\t\t\t\t{ kind: 'ptzHold', oid: d.oid, dir: p.dir },\n\t\t\t\t\t\t'switch',\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.ensureButton(cid, `PTZ ${p.id}`, { kind: 'ptz', oid: d.oid, dir: p.dir });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.config.enableUrls && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.urls`, 'URLs', 'channel');\n\t\t\tawait this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);\n\t\t}\n\n\t\tif (d.ot === 2) {\n\t\t\tconst snapId = `${fid}.snapshot_b64`;\n\t\t\tif (!this.ensuredFolders.has(snapId)) {\n\t\t\t\tawait this.ensurePath(snapId);\n\t\t\t\tawait this.setObjectNotExistsAsync(snapId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Snapshot (Base64)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(snapId, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(snapId);\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.refreshSnapshotB64`, 'Refresh snapshot (Base64)', {\n\t\t\t\tkind: 'snapshotB64',\n\t\t\t\toid: d.oid,\n\t\t\t\tfid,\n\t\t\t});\n\t\t\tif (this.config.enableSnapshotB64) {\n\t\t\t\tawait this.fetchSnapshotB64(d.oid, snapId);\n\t\t\t}\n\t\t}\n\n\t\tawait this.updateCameraEvents(d, fid);\n\t}\n\n\t// ---- event formatting ----\n\n\tprivate fmtEvent(\n\t\tev: Record<string, unknown>,\n\t\toid: number | string,\n\t): {\n\t\tfn: string;\n\t\tsizeMB: number;\n\t\tdur: string;\n\t\ttag: string;\n\t\tdate: string;\n\t\ttime: string;\n\t\tthumb: string;\n\t\tvideo: string;\n\t} {\n\t\tconst e = ev as AgentDvrEvent;\n\t\tconst fn = e.fn ?? '';\n\t\tconst dot = fn.lastIndexOf('.');\n\t\tconst jpg = `${dot > 0 ? fn.slice(0, dot) : fn}_large.jpg`;\n\t\tconst sizeMB = e.sb ? Math.round((Number(e.sb) / 1048576) * 100) / 100 : 0;\n\t\tconst dur = e.d != null ? String(e.d) : '';\n\t\tconst tag = e.tg ?? '';\n\t\tconst ms = (parseFloat(String(e.c ?? 0)) - 621355968000000000) / 10000;\n\t\tconst dt = new Date(ms);\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst date = `${two(dt.getDate())}.${two(dt.getMonth() + 1)}.`;\n\t\tconst time = `${two(dt.getHours())}:${two(dt.getMinutes())}`;\n\t\tconst thumb = `${this.baseUrl}/fileThumb.jpg?oid=${oid}&fn=${encodeURIComponent(jpg)}`;\n\t\tconst video = `${this.baseUrl}/streamFile.cgi?oid=${oid}&ot=2&fn=${encodeURIComponent(fn)}`;\n\t\treturn { fn, sizeMB, dur, tag, date, time, thumb, video };\n\t}\n\n\t// ---- gallery HTML builders ----\n\n\tprivate buildGalleryHtml(d: Device, events: Record<string, unknown>[]): string {\n\t\treturn (this.config.widgetMode || 'nojs') === 'js'\n\t\t\t? this.buildGalleryHtmlJs(d, events)\n\t\t\t: this.buildGalleryHtmlNojs(d, events);\n\t}\n\n\tprivate buildGalleryHtmlNojs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showTags = this.config.widgetShowTags;\n\t\tconst pos = (this.config.widgetTagPosition || 'bottom-left').split('-');\n\t\tconst tagStyle = `${pos[0]}:5px;${pos[1]}:5px`;\n\t\tconst playerUrl = (this.config.widgetPlayerUrl || '').trim();\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\n\t\tconst items = events\n\t\t\t.map((ev, i) => {\n\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\tconst id = `adv${sanitize(oid)}_${i}`;\n\t\t\t\tconst badge =\n\t\t\t\t\tshowTags && p.tag ? `<span class=\"advtag\" style=\"${tagStyle}\">${escHtml(p.tag)}</span>` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg\"><img src=\"${p.thumb}\" loading=\"lazy\" alt=\"\">${badge}<span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${escHtml(p.date)} ${escHtml(p.time)}<br>${escHtml(p.dur)}s &middot; ${escHtml(p.sizeMB)} MB</span>`;\n\t\t\t\tif (playerUrl) {\n\t\t\t\t\tconst href = playerUrl\n\t\t\t\t\t\t.replace(/{video}/g, encodeURIComponent(p.video))\n\t\t\t\t\t\t.replace(/{videoRaw}/g, p.video)\n\t\t\t\t\t\t.replace(/{fn}/g, encodeURIComponent(p.fn))\n\t\t\t\t\t\t.replace(/{date}/g, encodeURIComponent(p.date))\n\t\t\t\t\t\t.replace(/{time}/g, encodeURIComponent(p.time))\n\t\t\t\t\t\t.replace(/{duration}/g, encodeURIComponent(p.dur))\n\t\t\t\t\t\t.replace(/{size}/g, encodeURIComponent(String(p.sizeMB)))\n\t\t\t\t\t\t.replace(/{tags}/g, encodeURIComponent(p.tag));\n\t\t\t\t\treturn `<a class=\"advcell\" href=\"${escHtml(href)}\" target=\"_blank\" rel=\"noopener\">${inner}</a>`;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">&#10005;</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${p.video}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${escHtml(p.date)} ${escHtml(p.time)} &middot; ${escHtml(p.dur)}s &middot; ${escHtml(p.sizeMB)} MB${\n\t\t\t\t\t\tp.tag ? ` &middot; ${escHtml(p.tag)}` : ''\n\t\t\t\t\t} &middot; <a href=\"${p.video}\" download target=\"_blank\">${this.wt.download}</a></div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\n\t\tconst grid = items\n\t\t\t? `<div class=\"advgrid\">${items}</div>`\n\t\t\t: `<div class=\"advempty\">${this.wt.noRecordings}</div>`;\n\t\treturn `<style>${galleryCss(minCol, maxW)}</style>${grid}`;\n\t}\n\n\tprivate buildGalleryHtmlJs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst items = events.map(ev => {\n\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\treturn {\n\t\t\t\tfn: p.fn,\n\t\t\t\tdate: p.date,\n\t\t\t\ttime: p.time,\n\t\t\t\tdur: p.dur,\n\t\t\t\tsize: p.sizeMB,\n\t\t\t\ttag: p.tag,\n\t\t\t\tthumb: p.thumb,\n\t\t\t\tvideo: p.video,\n\t\t\t};\n\t\t});\n\t\tconst cfg = {\n\t\t\tmin_col: minCol,\n\t\t\tshow_tags: !!this.config.widgetShowTags,\n\t\t\tmax_modal_width: maxW,\n\t\t\tlive_aspect: this.camAspect[oid] || this.config.widgetLiveAspect || '',\n\t\t\tplayer_url: (this.config.widgetPlayerUrl || '').trim(),\n\t\t\ttag_position: this.config.widgetTagPosition || 'bottom-left',\n\t\t\tlabels: { noRecordings: this.wt.noRecordings, all: this.wt.all, live: this.wt.live },\n\t\t};\n\t\tconst data = JSON.stringify({ items, live: null, cfg }).replace(/</g, '\\\\u003c');\n\t\tconst boot = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\t\treturn (\n\t\t\t`<style>${galleryCssJs(minCol)}</style>` +\n\t\t\t`<div class=\"advroot\"><script type=\"application/json\" class=\"advdata\">${data}</script>` +\n\t\t\t`<div class=\"advbar\"><input class=\"advsearchjs\" type=\"text\" placeholder=\"${escHtml(this.wt.search)}\"><div class=\"advtagsjs\"></div></div>` +\n\t\t\t`<div class=\"advgridjs\"></div></div>` +\n\t\t\t`<script type=\"text/plain\" class=\"advcode\">${ADV_CLIENT_CODE}</script>` +\n\t\t\t`<img alt=\"\" src=\"${boot}\" style=\"display:none\" onload=\"(function(){if(window.ADVscan){window.ADVscan();return;}var c=document.querySelector('script.advcode');if(!c)return;var s=document.createElement('script');s.textContent=c.textContent;document.body.appendChild(s);})()\">`\n\t\t);\n\t}\n\n\tprivate buildOverviewHtml(cams: Device[]): string {\n\t\tconst ts = Date.now();\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\t\tconst tiles = cams\n\t\t\t.map(d => {\n\t\t\t\tconst oid = d.oid;\n\t\t\t\tconst id = `advlive${sanitize(oid)}`;\n\t\t\t\tconst grab = `${this.baseUrl}/grab.jpg?oid=${oid}&ot=2&maintainAR=1&ts=${ts}`;\n\t\t\t\tconst webm = `${this.baseUrl}/video.webm?oid=${oid}&ot=2`;\n\t\t\t\tconst name = escHtml(d.name || `Camera ${oid}`);\n\t\t\t\tconst arRaw = this.camAspect[oid] || this.config.widgetLiveAspect || '';\n\t\t\t\tconst ar = arRaw ? String(arRaw).replace('/', ' / ') : '';\n\t\t\t\tconst fix = ar ? ' advimgfix' : '';\n\t\t\t\tconst arStyle = ar ? ` style=\"aspect-ratio:${ar}\"` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg${fix}\"${arStyle}><img src=\"${grab}\" loading=\"lazy\" alt=\"\">` +\n\t\t\t\t\t`<span class=\"advtag\" style=\"top:5px;left:5px\">&#9679; ${escHtml(this.wt.live)}</span><span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${name}</span>`;\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">&#10005;</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${webm}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${name} &middot; Live</div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\t\tconst grid = tiles ? `<div class=\"advgrid\">${tiles}</div>` : `<div class=\"advempty\">No cameras</div>`;\n\t\treturn `<style>${galleryCss(minCol, maxW)}</style>${grid}`;\n\t}\n\n\t// ---- event data points ----\n\n\tprivate async writeEventDps(d: Device, fid: string, events: Record<string, unknown>[]): Promise<void> {\n\t\tconst oid = d.oid;\n\t\tawait this.ensureFolder(`${fid}.events`, 'Events', 'channel');\n\t\tawait this.ensureFolder(`${fid}.events.last`, 'Last event', 'channel');\n\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst now = new Date();\n\t\tconst td = `${two(now.getDate())}.${two(now.getMonth() + 1)}.`;\n\t\tconst todayCount = events.filter(ev => this.fmtEvent(ev, oid).date === td).length;\n\n\t\tawait this.writeLeaf(`${fid}.events.count`, events.length);\n\t\tawait this.writeLeaf(`${fid}.events.today`, todayCount);\n\n\t\tif (events.length) {\n\t\t\tconst p = this.fmtEvent(events[0], oid);\n\t\t\tconst tsMs = (parseFloat(String((events[0] as AgentDvrEvent).c ?? 0)) - 621355968000000000) / 10000;\n\t\t\tawait this.writeLeaf(`${fid}.events.last.time`, `${p.date} ${p.time}`);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.timestamp`, Math.round(tsMs));\n\t\t\tawait this.writeLeaf(`${fid}.events.last.tag`, p.tag);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.duration`, p.dur ? parseFloat(p.dur) : 0);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.size_mb`, p.sizeMB);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.thumb`, p.thumb);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.video`, p.video);\n\t\t}\n\n\t\tawait this.ensureFlag(`${fid}.events.new`, 'New event');\n\n\t\tif (this.config.enablePush) {\n\t\t\tconst pid = `${fid}.events.pushTrigger`;\n\t\t\tif (!this.ensuredFolders.has(pid)) {\n\t\t\t\tawait this.ensurePath(pid);\n\t\t\t\tawait this.setObjectNotExistsAsync(pid, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Push trigger (AgentDVR action)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'text',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(pid, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(pid);\n\t\t\t}\n\t\t\tthis.registry.set(pid, { kind: 'push', oid, fid });\n\t\t}\n\n\t\tconst ignore = (this.config.eventTagsIgnore || 'detected')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim().toLowerCase())\n\t\t\t.filter(Boolean);\n\t\tconst tokensOf = (s: string): string[] =>\n\t\t\ts\n\t\t\t\t.toLowerCase()\n\t\t\t\t.split(/[,\\s]+/)\n\t\t\t\t.filter(Boolean);\n\n\t\tfor (const kw of (this.config.eventTags || '')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(Boolean)) {\n\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(kw)}`, `Detected: ${kw}`);\n\t\t}\n\n\t\tif (this.config.eventTagsDynamic) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const ev of events) {\n\t\t\t\ttokensOf((ev as AgentDvrEvent).tg ?? '').forEach(t => seen.add(t));\n\t\t\t}\n\t\t\tfor (const t of seen) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(t)}`, `Detected: ${t}`);\n\t\t\t}\n\t\t}\n\n\t\tlet newCount = 0;\n\t\tif (events.length) {\n\t\t\tconst prev = this.lastEventFn[oid];\n\t\t\tif (prev !== undefined) {\n\t\t\t\tconst i = events.findIndex(e => (e as AgentDvrEvent).fn === prev);\n\t\t\t\tnewCount = i === -1 ? events.length : i;\n\t\t\t}\n\t\t\tthis.lastEventFn[oid] = (events[0] as AgentDvrEvent).fn ?? '';\n\t\t}\n\n\t\tif (newCount > 0) {\n\t\t\tawait this.pulse(`${fid}.events.new`);\n\t\t\tconst tags = new Set<string>();\n\t\t\tfor (let i = 0; i < newCount && i < events.length; i++) {\n\t\t\t\ttokensOf((events[i] as AgentDvrEvent).tg ?? '').forEach(t => tags.add(t));\n\t\t\t}\n\t\t\tfor (const t of tags) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst tid = `${fid}.events.detected_${sanitize(t)}`;\n\t\t\t\tawait this.ensureFlag(tid, `Detected: ${t}`);\n\t\t\t\tawait this.pulse(tid);\n\t\t\t}\n\t\t\tthis.log.debug(`${newCount} new event(s) cam ${oid} [${[...tags].join(',')}]`);\n\t\t}\n\t}\n\n\t// ---- camera events + widget ----\n\n\tprivate async updateCameraEvents(d: Device, fid: string): Promise<void> {\n\t\tif (d.ot !== 2) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.config.enableWidget && !this.config.enableEventDps) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.eventBusy[d.oid]) {\n\t\t\treturn;\n\t\t}\n\t\tthis.eventBusy[d.oid] = true;\n\t\ttry {\n\t\t\tconst evRes = await this.apiGet(`/q/getEvents?oid=${d.oid}&ot=2`);\n\t\t\tconst evJson = asJson(evRes.data);\n\t\t\tif (!evJson) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst events = (\n\t\t\t\tArray.isArray(evJson.events) ? evJson.events : Array.isArray(evJson) ? evJson : []\n\t\t\t) as Record<string, unknown>[];\n\n\t\t\tif (this.config.enableEventDps) {\n\t\t\t\tawait this.writeEventDps(d, fid, events);\n\t\t\t}\n\n\t\t\tif (this.config.enableWidget) {\n\t\t\t\tconst wId = `${fid}.widget`;\n\t\t\t\tif (!this.ensuredFolders.has(wId)) {\n\t\t\t\t\tawait this.ensurePath(wId);\n\t\t\t\t\tawait this.setObjectNotExistsAsync(wId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'HTML gallery widget',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(wId);\n\t\t\t\t}\n\t\t\t\tconst ev = events.slice(0, Math.max(1, this.config.widgetAnzahl || 50));\n\t\t\t\tconst f = (ev[0] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst l = (ev[ev.length - 1] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst sig = `${ev.length}|${f.fn ?? ''}|${l.fn ?? ''}`;\n\t\t\t\tif (this.widgetSig[wId] !== sig) {\n\t\t\t\t\tawait this.setStateAsync(wId, { val: this.buildGalleryHtml(d, ev), ack: true });\n\t\t\t\t\tthis.widgetSig[wId] = sig;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.eventBusy[d.oid] = false;\n\t\t}\n\t}\n\n\tprivate pushRefresh(oid: number | string): void {\n\t\tconst d = this.devById.get(oid);\n\t\tif (!d) {\n\t\t\tthis.log.warn(`Push: camera ${oid} unknown (available after first poll)`);\n\t\t\treturn;\n\t\t}\n\t\tconst fid = this.deviceFolder(d);\n\t\tfor (const ms of [0, 1500, 3500, 6000]) {\n\t\t\tthis.setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tthis.updateCameraEvents(d, fid).catch(e =>\n\t\t\t\t\t\tthis.log.warn(`Push refresh error: ${(e as Error).message}`),\n\t\t\t\t\t),\n\t\t\t\tms,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- main poll ----\n\n\tprivate async poll(): Promise<void> {\n\t\tconst res = await this.apiGet('/command/getObjects');\n\t\tconst json = asJson(res.data);\n\n\t\tif (!res.ok || !json) {\n\t\t\tawait this.setStateAsync('info.connection', false, true);\n\t\t\tawait this.setStateAsync('system.online', { val: false, ack: true });\n\t\t\tthis.log.warn(`AgentDVR unreachable: ${res.error || 'invalid response'}`);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.setStateAsync('info.connection', true, true);\n\t\tawait this.setStateAsync('system.online', { val: true, ack: true });\n\n\t\tif (json.settings) {\n\t\t\tawait this.flattenWrite(json.settings, 'system.settings', 0);\n\t\t}\n\n\t\tif (this.config.storeRawJson) {\n\t\t\tconst clean: Record<string, unknown> = { ...json };\n\t\t\tdelete clean.icons;\n\t\t\tawait this.writeLeaf('system.raw_getObjects', JSON.stringify(clean).slice(0, 60000));\n\t\t}\n\n\t\tconst devices = findDevices(json);\n\t\tawait this.setStateAsync('system.cameraCount', { val: devices.filter(d => d.ot === 2).length, ack: true });\n\n\t\tfor (const d of devices) {\n\t\t\tawait this.buildDevice(d);\n\t\t}\n\n\t\tconst stats = asJson((await this.apiGet('/command/getSystemStats')).data);\n\t\tif (stats) {\n\t\t\tawait this.flattenWrite(stats, 'system.stats', 0);\n\t\t\tconst gb = parseSizeGb(stats.disk_free);\n\t\t\tif (gb !== null) {\n\t\t\t\tawait this.writeLeaf('system.disk_free_gb', gb);\n\t\t\t}\n\t\t}\n\n\t\tconst status = asJson((await this.apiGet('/command/getStatus')).data);\n\t\tif (status) {\n\t\t\tawait this.flattenWrite(status, 'system.status', 0);\n\t\t}\n\n\t\tif (this.config.enableSystemControls && Array.isArray(json.profiles)) {\n\t\t\tconst states: Record<number, string> = {};\n\t\t\tlet activeInd: number | null = null;\n\t\t\tfor (const p of json.profiles) {\n\t\t\t\tif (p && typeof p === 'object') {\n\t\t\t\t\tconst po = p as Record<string, unknown>;\n\t\t\t\t\tconst ind = po.id ?? po.ind ?? po.index;\n\t\t\t\t\tconst pname = po.name;\n\t\t\t\t\tif (typeof ind === 'number' && (typeof pname === 'string' || typeof pname === 'number')) {\n\t\t\t\t\t\tstates[ind] = String(pname);\n\t\t\t\t\t\tif (po.active === true) {\n\t\t\t\t\t\t\tactiveInd = ind;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Object.keys(states).length > 0) {\n\t\t\t\tconst sig = JSON.stringify(states);\n\t\t\t\tif (sig !== this.profileSig) {\n\t\t\t\t\tthis.profileSig = sig;\n\t\t\t\t\tawait this.extendObjectAsync('system.profile.selector', { common: { states } });\n\t\t\t\t\tawait this.setStateAsync('system.profile.list', { val: sig, ack: true });\n\t\t\t\t}\n\t\t\t\tif (activeInd !== null) {\n\t\t\t\t\tawait this.setStateAsync('system.profile.selector', { val: activeInd, ack: true });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.config.enableOverview) {\n\t\t\tconst cams = devices.filter(d => d.ot === 2);\n\t\t\tconst ovId = 'overview';\n\t\t\tif (!this.ensuredFolders.has(ovId)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(ovId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Overview (all cameras)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add(ovId);\n\t\t\t}\n\t\t\tawait this.setStateAsync(ovId, { val: this.buildOverviewHtml(cams), ack: true });\n\t\t}\n\n\t\tawait this.setStateAsync('system.lastUpdate', { val: new Date().toISOString(), ack: true });\n\t\tawait this.setStateAsync('system.lastPoll', { val: Date.now(), ack: true });\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.refreshTimer !== undefined) {\n\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = undefined;\n\t\t}\n\t\tthis.refreshTimer = this.setTimeout(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Refresh error: ${(e as Error).message}`)),\n\t\t\t1500,\n\t\t);\n\t}\n\n\t// ---- command execution ----\n\n\tprivate ptzUrl(oid: number | string, dir: number): string {\n\t\treturn `/ptz.cgi?oid=${encodeURIComponent(String(oid))}&dir=${dir}`;\n\t}\n\n\tprivate buildCommandUrl(entry: RegistryEntry): string {\n\t\tif (entry.kind === 'ptz') {\n\t\t\treturn this.ptzUrl(entry.oid!, entry.dir!);\n\t\t}\n\t\tif (entry.kind === 'sys') {\n\t\t\treturn entry.path as string;\n\t\t}\n\t\tconst qs: string[] = [];\n\t\tfor (const p of entry.params || []) {\n\t\t\tif (p === 'oid') {\n\t\t\t\tqs.push(`oid=${encodeURIComponent(String(entry.oid))}`);\n\t\t\t} else if (p === 'ot') {\n\t\t\t\tqs.push(`ot=${encodeURIComponent(String(entry.ot))}`);\n\t\t\t}\n\t\t}\n\t\treturn (entry.path || '') + (qs.length ? `?${qs.join('&')}` : '');\n\t}\n\n\tprivate async clearPtzSiblings(stateId: string): Promise<void> {\n\t\tconst prefix = stateId.slice(0, stateId.lastIndexOf('.') + 1);\n\t\tfor (const p of PTZ_DIRS) {\n\t\t\tif (!p.hold) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst sid = prefix + p.id;\n\t\t\tif (sid !== stateId) {\n\t\t\t\tawait this.setStateAsync(sid, { val: false, ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async runCommand(relId: string, entry: RegistryEntry, val: ioBroker.StateValue): Promise<void> {\n\t\tif (entry.kind === 'setProfile') {\n\t\t\tconst ind = typeof val === 'number' ? val : parseInt(String(val ?? ''), 10);\n\t\t\tif (!isNaN(ind)) {\n\t\t\t\tconst url = `/command/setProfile?ind=${ind}`;\n\t\t\t\tconst cmdRes = await this.apiGet(url);\n\t\t\t\tif (cmdRes.ok) {\n\t\t\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t\t\t\tawait this.setStateAsync(relId, { val: ind, ack: true });\n\t\t\t\t} else {\n\t\t\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t\t\t}\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'snapshotB64') {\n\t\t\tconst snapId = `${entry.fid}.snapshot_b64`;\n\t\t\tawait this.fetchSnapshotB64(entry.oid!, snapId);\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'push') {\n\t\t\tthis.log.info(`Push trigger cam ${entry.oid}`);\n\t\t\tawait this.setStateAsync(relId, { val: '', ack: true });\n\t\t\tthis.pushRefresh(entry.oid!);\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'ptzHold') {\n\t\t\tconst oid = entry.oid!;\n\t\t\tconst startMove = async (): Promise<void> => {\n\t\t\t\tawait this.clearPtzSiblings(relId);\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, entry.dir!));\n\t\t\t\tthis.ptzActive.set(oid, relId);\n\t\t\t\tawait this.setStateAsync(relId, { val: true, ack: true });\n\t\t\t};\n\t\t\tconst stopMove = async (): Promise<void> => {\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, 11));\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tthis.ptzActive.delete(oid);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\t};\n\t\t\tif (val) {\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tawait stopMove();\n\t\t\t\t} else {\n\t\t\t\t\tawait startMove();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait stopMove();\n\t\t\t}\n\t\t\tthis.scheduleRefresh();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!val) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'sys' && entry.path === null) {\n\t\t\tawait this.poll().catch(e => this.log.warn(`Manual refresh error: ${(e as Error).message}`));\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = this.buildCommandUrl(entry);\n\t\tconst cmdRes = await this.apiGet(url);\n\t\tif (cmdRes.ok) {\n\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t} else {\n\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t}\n\n\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\tthis.scheduleRefresh();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AgentDvr(options);\n} else {\n\t(() => new AgentDvr())();\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;AACvB,WAAsB;AACtB,yBAAmD;AA6CnD,MAAM,eAAe;AAAA,EACpB,EAAE,IAAI,UAAU,MAAM,mBAAmB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,kBAAkB;AAAA,EACxF,EAAE,IAAI,cAAc,MAAM,uBAAuB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,iBAAiB;AAAA,EAC/F,EAAE,IAAI,iBAAiB,MAAM,0BAA0B,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,oBAAoB;AAAA,EACxG,EAAE,IAAI,iBAAiB,MAAM,0BAA0B,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,8BAA8B;AAAA,EAClH,EAAE,IAAI,YAAY,MAAM,qBAAqB,QAAQ,CAAC,KAAK,GAAG,MAAM,gBAAgB;AAAA,EACpF,EAAE,IAAI,UAAU,MAAM,mBAAmB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,2BAA2B;AAAA,EACjG,EAAE,IAAI,WAAW,MAAM,oBAAoB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,aAAa;AAAA,EACrF,EAAE,IAAI,YAAY,MAAM,qBAAqB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,gBAAgB;AAAA,EAC1F,EAAE,IAAI,YAAY,MAAM,qBAAqB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,mBAAmB;AAAA,EAC7F,EAAE,IAAI,aAAa,MAAM,sBAAsB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,oBAAoB;AAAA,EAChG,EAAE,IAAI,kBAAkB,MAAM,2BAA2B,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,0BAA0B;AAAA,EAChH;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,CAAC,OAAO,IAAI;AAAA,IACpB,MAAM;AAAA,EACP;AAAA,EACA,EAAE,IAAI,cAAc,MAAM,4BAA4B,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,sBAAsB;AAAA,EACzG,EAAE,IAAI,eAAe,MAAM,6BAA6B,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,uBAAuB;AAAA,EAC5G,EAAE,IAAI,SAAS,MAAM,kBAAkB,QAAQ,CAAC,OAAO,IAAI,GAAG,MAAM,0BAA0B;AAC/F;AAEA,MAAM,eAAe;AAAA,EACpB,EAAE,IAAI,OAAO,MAAM,gBAAgB,MAAM,aAAa;AAAA,EACtD,EAAE,IAAI,UAAU,MAAM,mBAAmB,MAAM,gBAAgB;AAAA,EAC/D,EAAE,IAAI,SAAS,MAAM,kBAAkB,MAAM,iBAAiB;AAAA,EAC9D,EAAE,IAAI,UAAU,MAAM,mBAAmB,MAAM,kBAAkB;AAAA,EACjE,EAAE,IAAI,gBAAgB,MAAM,yBAAyB,MAAM,gBAAgB;AAAA,EAC3E,EAAE,IAAI,iBAAiB,MAAM,0BAA0B,MAAM,iBAAiB;AAAA,EAC9E,EAAE,IAAI,kBAAkB,MAAM,2BAA2B,MAAM,yBAAyB;AAAA,EACxF,EAAE,IAAI,iBAAiB,MAAM,0BAA0B,MAAM,wBAAwB;AAAA,EACrF,EAAE,IAAI,mBAAmB,MAAM,4BAA4B,MAAM,0BAA0B;AAAA,EAC3F,EAAE,IAAI,WAAW,MAAM,oBAAoB,MAAM,oBAAoB;AAAA,EACrE,EAAE,IAAI,WAAW,MAAM,MAAM,MAAM,mBAAmB;AACvD;AAEA,MAAM,WAAW;AAAA,EAChB,EAAE,IAAI,QAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,EACjC,EAAE,IAAI,UAAU,KAAK,GAAG,MAAM,KAAK;AAAA,EACnC,EAAE,IAAI,MAAM,KAAK,GAAG,MAAM,KAAK;AAAA,EAC/B,EAAE,IAAI,WAAW,KAAK,GAAG,MAAM,KAAK;AAAA,EACpC,EAAE,IAAI,SAAS,KAAK,GAAG,MAAM,KAAK;AAAA,EAClC,EAAE,IAAI,aAAa,KAAK,GAAG,MAAM,KAAK;AAAA,EACtC,EAAE,IAAI,QAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,EACjC,EAAE,IAAI,YAAY,KAAK,GAAG,MAAM,KAAK;AAAA,EACrC,EAAE,IAAI,UAAU,KAAK,GAAG,MAAM,KAAK;AAAA,EACnC,EAAE,IAAI,WAAW,KAAK,IAAI,MAAM,KAAK;AAAA,EACrC,EAAE,IAAI,QAAQ,KAAK,IAAI,MAAM,MAAM;AAAA,EACnC,EAAE,IAAI,UAAU,KAAK,GAAG,MAAM,MAAM;AACrC;AAEA,MAAM,YAAY,CAAC,SAAS,SAAS,aAAa,QAAQ;AAI1D,SAAS,SAAS,GAAoB;AACrC,SACC,OAAO,CAAC,EACN,QAAQ,yBAAyB,GAAG,EACpC,QAAQ,mBAAmB,GAAG,EAC9B,QAAQ,OAAO,GAAG,EAClB,QAAQ,YAAY,EAAE,KAAK;AAE/B;AAEA,SAAS,OAAO,MAA+C;AAC9D,MAAI,QAAQ,MAAM;AACjB,WAAO;AAAA,EACR;AACA,MAAI,OAAO,SAAS,UAAU;AAC7B,WAAO;AAAA,EACR;AACA,MAAI,OAAO,SAAS,UAAU;AAC7B,QAAI;AACH,aAAO,KAAK,MAAM,IAAI;AAAA,IACvB,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,MAAM,GAAoB;AAClC,MAAI,KAAK,MAAM;AACd,WAAO;AAAA,EACR;AACA,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,WAAW;AAC7E,WAAO,OAAO,CAAC;AAAA,EAChB;AACA,SAAO,OAAO,UAAU,SAAS,KAAK,CAAC;AACxC;AAEA,SAAS,QAAQ,GAAoB;AACpC,SAAO,MAAM,CAAC,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ;AAC1G;AAEA,SAAS,YAAY,GAA2B;AAC/C,MAAI,KAAK,MAAM;AACd,WAAO;AAAA,EACR;AACA,QAAM,IAAI,MAAM,CAAC,EACf,KAAK,EACL,MAAM,0BAA0B;AAClC,MAAI,CAAC,GAAG;AACP,WAAO;AAAA,EACR;AACA,MAAI,IAAI,WAAW,EAAE,CAAC,EAAE,QAAQ,KAAK,GAAG,CAAC;AACzC,MAAI,MAAM,CAAC,GAAG;AACb,WAAO;AAAA,EACR;AACA,QAAM,KAAK,EAAE,CAAC,KAAK,MAAM,YAAY;AACrC,MAAI,MAAM,MAAM;AACf,SAAK;AAAA,EACN,WAAW,MAAM,MAAM;AACtB,SAAK;AAAA,EACN,WAAW,MAAM,MAAM;AACtB,SAAK;AAAA,EACN,WAAW,MAAM,KAAK;AACrB,SAAK;AAAA,EACN;AACA,SAAO,KAAK,MAAM,IAAI,GAAG,IAAI;AAC9B;AAEA,SAAS,OAAO,KAAc,OAAwC;AACrE,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,QAAQ,GAAG;AACjD,WAAO;AAAA,EACR;AACA,QAAM,IAAI;AACV,aAAW,CAAC,IAAI,EAAE,KAAK;AAAA,IACtB,CAAC,SAAS,QAAQ;AAAA,IAClB,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,eAAe,cAAc;AAAA,IAC9B,CAAC,cAAc,aAAa;AAAA,IAC5B,CAAC,cAAc,aAAa;AAAA,EAC7B,GAAG;AACF,UAAM,IAAI,EAAE,EAAE,GACb,IAAI,EAAE,EAAE;AACT,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,KAAK,OAAO,KAAK,OAAO,KAAK,QAAS,KAAK,MAAO;AACvG,YAAM,IAAI,IAAI;AACd,UAAI,KAAK,OAAO,KAAK,GAAG;AACvB,eAAO,CAAC,GAAG,CAAC;AAAA,MACb;AAAA,IACD;AAAA,EACD;AACA,aAAW,KAAK,OAAO,KAAK,CAAC,GAAG;AAC/B,UAAM,IAAI,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC;AAChC,QAAI,GAAG;AACN,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,SAAS,MAAuC;AAzMzD;AA0MC,QAAM,KAAI,sBAAK,WAAL,YAAe,KAAK,OAApB,YAA0B,KAAK,iBAA/B,YAA+C,KAAK;AAC9D,SAAO,MAAM,KAAK,MAAM,IAAI,IAAI;AACjC;AAEA,SAAS,YAAY,MAAyC;AA9M9D;AA+MC,QAAM,OAAO,MAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,aAAa,CAAC;AACjE,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,MAAM;AACrB,QAAI,CAAC,KAAK,OAAO,MAAM,UAAU;AAChC;AAAA,IACD;AACA,UAAM,KAAK;AACX,UAAM,SAAQ,QAAG,OAAH,YAAS,GAAG;AAC1B,QAAI,UAAU,UAAa,UAAU,MAAM;AAC1C;AAAA,IACD;AACA,UAAM,KAAK;AACX,UAAM,OAAO,OAAO,GAAG,SAAS,WAAW,GAAG,OAAO,OAAO,EAAE;AAC9D,QAAI,KAAK,EAAE,KAAK,IAAI,IAAI,SAAS,EAAE,GAAG,MAAM,KAAK,GAAG,CAAC;AAAA,EACtD;AACA,SAAO;AACR;AAIA,SAAS,WAAW,QAAgB,MAAsB;AACzD,SACC,uEAAuE,MAAM,k0CAcwB,IAAI;AAO3G;AAEA,SAAS,aAAa,QAAwB;AAC7C,SACC,8oBAMyE,MAAM;AAYjF;AAIA,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgFtB,KAAK;AAIP,MAAM,iBAAiB,MAAM,QAAQ;AAAA,EAC5B,YAA2C;AAAA,EAC3C,eAA6C;AAAA,EAC7C,aAA4B;AAAA,EAC5B,UAAU;AAAA,EACV,SAAmB,oCAAgB,IAAI;AAAA,EAE9B,iBAAiB,oBAAI,IAAY;AAAA,EACjC,WAAW,oBAAI,IAA2B;AAAA,EAC1C,YAAY,oBAAI,IAA6B;AAAA,EAC7C,YAAoC,CAAC;AAAA,EAC9C,aAAa;AAAA,EACJ,cAA+C,CAAC;AAAA,EAChD,YAA6C,CAAC;AAAA,EAC9C,UAAU,oBAAI,IAA6B;AAAA,EAC3C,YAA8C,CAAC;AAAA,EAEzD,YAAY,UAAyC,CAAC,GAAG;AAC/D,UAAM,EAAE,GAAG,SAAS,MAAM,YAAY,CAAC;AACvC,SAAK,GAAG,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxC,SAAK,GAAG,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AACpD,SAAK,GAAG,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA;AAAA,EAIA,MAAc,UAAyB;AAlYxC;AAmYE,SAAK,KAAK,SAAS,mBAAmB,OAAO,IAAI;AAEjD,UAAM,YAAY,MAAM,KAAK,sBAAsB,eAAe;AAClE,UAAM,WAAW,4CAAW,WAAX,mBAAoE;AACrF,SAAK,SAAK,oCAAgB,4BAAW,IAAI;AAEzC,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,KAAK,OAAO,eAAe,EAAE,CAAC;AAC7E,SAAK,UAAU,UAAU,KAAK,OAAO,EAAE,IAAI,KAAK,OAAO,QAAQ,IAAI;AAEnE,QAAI,KAAK,OAAO,QAAQ,KAAK,OAAO,MAAM;AACzC,WAAK,aAAa,SAAS,OAAO,KAAK,GAAG,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,IACrG;AAEA,UAAM,KAAK,YAAY;AACvB,QAAI;AACH,YAAM,KAAK,KAAK;AAAA,IACjB,SAAS,GAAG;AACX,WAAK,IAAI,KAAK,qBAAsB,EAAY,OAAO,EAAE;AAAA,IAC1D;AAEA,SAAK,YAAY,KAAK;AAAA,MACrB,MAAM,KAAK,KAAK,EAAE,MAAM,OAAK,KAAK,IAAI,KAAK,eAAgB,EAAY,OAAO,EAAE,CAAC;AAAA,MACjF,cAAc;AAAA,IACf;AAEA,SAAK,gBAAgB,GAAG;AACxB,SAAK,IAAI,KAAK,oCAAoC,KAAK,OAAO,UAAU,WAAW,IAAI;AAAA,EACxF;AAAA,EAEQ,SAAS,UAA4B;AAC5C,QAAI;AACH,UAAI,KAAK,cAAc,QAAW;AACjC,aAAK,cAAc,KAAK,SAAS;AACjC,aAAK,YAAY;AAAA,MAClB;AACA,UAAI,KAAK,iBAAiB,QAAW;AACpC,aAAK,aAAa,KAAK,YAAY;AACnC,aAAK,eAAe;AAAA,MACrB;AAAA,IACD,QAAQ;AAAA,IAER;AACA,aAAS;AAAA,EACV;AAAA,EAEQ,cAAc,IAAY,OAAgD;AACjF,QAAI,CAAC,SAAS,MAAM,QAAQ,OAAO;AAClC;AAAA,IACD;AACA,UAAM,QAAQ,KAAK,SAAS,EAAE;AAC9B,UAAM,QAAQ,KAAK,SAAS,IAAI,KAAK;AACrC,QAAI,OAAO;AACV,WAAK,WAAW,OAAO,OAAO,MAAM,GAAG,EAAE;AAAA,QAAM,OAC9C,KAAK,IAAI,KAAK,kBAAmB,EAAY,OAAO,EAAE;AAAA,MACvD;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAIQ,SAAS,QAAwB;AACxC,WAAO,OAAO,WAAW,GAAG,KAAK,SAAS,GAAG,IAAI,OAAO,MAAM,KAAK,UAAU,SAAS,CAAC,IAAI;AAAA,EAC5F;AAAA,EAEQ,OAAO,MAAkC;AAChD,WAAO,IAAI,QAAQ,aAAW;AAC7B,YAAM,UAAU,KAAK,IAAI,KAAM,KAAK,IAAI,KAAO,KAAK,OAAO,iBAAiB,GAAI,CAAC;AACjF,YAAM,OAA4B;AAAA,QACjC,UAAU,KAAK,OAAO;AAAA,QACtB,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACD;AACA,UAAI,KAAK,YAAY;AACpB,aAAK,UAAU,EAAE,eAAe,KAAK,WAAW;AAAA,MACjD;AACA,UAAI;AACH,cAAM,MAAM,KAAK,QAAQ,MAAM,SAAO;AACrC,cAAI,OAAO;AACX,cAAI,GAAG,QAAQ,CAAC,MAAc;AAC7B,oBAAQ,EAAE,SAAS;AAAA,UACpB,CAAC;AACD,cAAI,GAAG,OAAO,MAAM;AACnB,gBAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC5C,sBAAQ,EAAE,IAAI,OAAO,OAAO,QAAQ,IAAI,UAAU,GAAG,CAAC;AAAA,YACvD,OAAO;AACN,sBAAQ,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,YAC3B;AAAA,UACD,CAAC;AACD,cAAI,GAAG,SAAS,CAAC,MAAa,QAAQ,EAAE,IAAI,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC;AAAA,QACvE,CAAC;AACD,YAAI,GAAG,SAAS,CAAC,MAAa,QAAQ,EAAE,IAAI,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtE,YAAI,GAAG,WAAW,MAAM;AACvB,cAAI,QAAQ;AACZ,kBAAQ,EAAE,IAAI,OAAO,OAAO,UAAU,CAAC;AAAA,QACxC,CAAC;AACD,YAAI,IAAI;AAAA,MACT,SAAS,GAAG;AACX,gBAAQ,EAAE,IAAI,OAAO,OAAO,OAAQ,EAAY,WAAW,CAAC,EAAE,CAAC;AAAA,MAChE;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEQ,aAAa,MAAuE;AAC3F,WAAO,IAAI,QAAQ,aAAW;AAC7B,YAAM,UAAU,KAAK,IAAI,KAAM,KAAK,IAAI,KAAO,KAAK,OAAO,iBAAiB,GAAI,CAAC;AACjF,YAAM,OAA4B;AAAA,QACjC,UAAU,KAAK,OAAO;AAAA,QACtB,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACD;AACA,UAAI,KAAK,YAAY;AACpB,aAAK,UAAU,EAAE,eAAe,KAAK,WAAW;AAAA,MACjD;AACA,UAAI;AACH,cAAM,MAAM,KAAK,QAAQ,MAAM,SAAO;AACrC,gBAAM,SAAmB,CAAC;AAC1B,cAAI,GAAG,QAAQ,CAAC,MAAc,OAAO,KAAK,CAAC,CAAC;AAC5C,cAAI,GAAG,OAAO,MAAM;AACnB,gBAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC5C,sBAAQ,EAAE,IAAI,OAAO,OAAO,QAAQ,IAAI,UAAU,GAAG,CAAC;AAAA,YACvD,OAAO;AACN,sBAAQ,EAAE,IAAI,MAAM,MAAM,OAAO,OAAO,MAAM,EAAE,CAAC;AAAA,YAClD;AAAA,UACD,CAAC;AACD,cAAI,GAAG,SAAS,CAAC,MAAa,QAAQ,EAAE,IAAI,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC;AAAA,QACvE,CAAC;AACD,YAAI,GAAG,SAAS,CAAC,MAAa,QAAQ,EAAE,IAAI,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC;AACtE,YAAI,GAAG,WAAW,MAAM;AACvB,cAAI,QAAQ;AACZ,kBAAQ,EAAE,IAAI,OAAO,OAAO,UAAU,CAAC;AAAA,QACxC,CAAC;AACD,YAAI,IAAI;AAAA,MACT,SAAS,GAAG;AACX,gBAAQ,EAAE,IAAI,OAAO,OAAO,OAAQ,EAAY,WAAW,CAAC,EAAE,CAAC;AAAA,MAChE;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,IAAY,MAAc,OAA6B,WAA0B;AAC3G,QAAI,KAAK,eAAe,IAAI,EAAE,GAAG;AAChC;AAAA,IACD;AACA,UAAM,KAAK,wBAAwB,IAAI,EAAE,MAAM,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC7E,SAAK,eAAe,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,MAAc,WAAW,QAA+B;AACvD,UAAM,QAAQ,OAAO,MAAM,GAAG;AAC9B,QAAI,MAAM,MAAM,CAAC;AACjB,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AAC1C,aAAO,IAAI,MAAM,CAAC,CAAC;AACnB,UAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;AAClC,cAAM,KAAK,wBAAwB,KAAK,EAAE,MAAM,WAAW,QAAQ,EAAE,MAAM,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACnG,aAAK,eAAe,IAAI,GAAG;AAAA,MAC5B;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,UAAU,IAAY,KAAmC;AAChE,QAAI,OAAO,QAAQ,YAAY,gBAAgB,KAAK,GAAG,GAAG;AACzD,aAAO;AAAA,IACR;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAc,UAAU,IAAY,KAA6B;AAChE,UAAM,IAAI,OAAO;AACjB,QAAI;AACJ,QAAI,MAAM,WAAW;AACpB,eAAS,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,MAAM,WAAW,MAAM,aAAa,MAAM,MAAM,OAAO,MAAM;AAAA,IAC1G,WAAW,MAAM,UAAU;AAC1B,eAAS,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,MAAM,UAAU,MAAM,SAAS,MAAM,MAAM,OAAO,MAAM;AAAA,IACrG,OAAO;AACN,YAAM,OAAO,OAAO,QAAQ,YAAY,gBAAgB,KAAK,GAAG,IAAI,aAAa;AACjF,eAAS,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,OAAO,MAAM;AAAA,IAC5F;AACA,QAAI,CAAC,KAAK,eAAe,IAAI,EAAE,GAAG;AACjC,YAAM,KAAK,WAAW,EAAE;AACxB,YAAM,KAAK,wBAAwB,IAAI,EAAE,MAAM,SAAS,QAAQ,QAAQ,CAAC,EAAE,CAAC;AAC5E,WAAK,eAAe,IAAI,EAAE;AAAA,IAC3B;AACA,UAAM,KAAK,cAAc,IAAI,EAAE,KAAM,QAAQ,SAAY,OAAO,KAA6B,KAAK,KAAK,CAAC;AAAA,EACzG;AAAA,EAEA,MAAc,aAAa,KAAc,QAAgB,OAA8B;AACtF,UAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,OAAO,YAAY,CAAC,CAAC;AACpE,UAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,OAAO,YAAY,EAAE,CAAC;AACtE,QAAI,QAAQ,UAAU;AACrB;AAAA,IACD;AACA,QAAI,QAAQ,QAAQ,QAAQ,QAAW;AACtC,YAAM,KAAK,UAAU,QAAQ,GAAG;AAChC;AAAA,IACD;AACA,QAAI,OAAO,QAAQ,UAAU;AAC5B,UAAI,MAAM,QAAQ,GAAG,GAAG;AACvB,YAAI,IAAI,SAAS,UAAU;AAC1B,gBAAM,KAAK,UAAU,GAAG,MAAM,UAAU,IAAI,MAAM;AAClD;AAAA,QACD;AACA,iBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,gBAAM,KAAK,aAAa,IAAI,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,QAAQ,CAAC;AAAA,QAC5D;AAAA,MACD,OAAO;AACN,mBAAW,KAAK,OAAO,KAAK,GAAG,GAAG;AACjC,cAAI,UAAU,SAAS,CAAC,GAAG;AAC1B;AAAA,UACD;AACA,gBAAM,KAAK,aAAc,IAAgC,CAAC,GAAG,GAAG,MAAM,IAAI,SAAS,CAAC,CAAC,IAAI,QAAQ,CAAC;AAAA,QACnG;AAAA,MACD;AAAA,IACD,OAAO;AACN,YAAM,KAAK,UAAU,QAAQ,GAAG;AAAA,IACjC;AAAA,EACD;AAAA,EAEA,MAAc,cACb,IACA,MACA,OACA,MACgB;AAChB,QAAI,CAAC,KAAK,eAAe,IAAI,EAAE,GAAG;AACjC,YAAM,KAAK,WAAW,EAAE;AACxB,YAAM,KAAK,wBAAwB,IAAI;AAAA,QACtC,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,MAAM,WAAW,MAAM,MAAM,SAAS,UAAU,OAAO,MAAM,KAAK,MAAM;AAAA,QACxF,QAAQ,CAAC;AAAA,MACV,CAAC;AACD,YAAM,KAAK,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACtD,WAAK,eAAe,IAAI,EAAE;AAAA,IAC3B;AACA,SAAK,SAAS,IAAI,IAAI,KAAK;AAAA,EAC5B;AAAA,EAEQ,aAAa,IAAY,MAAc,OAAqC;AACnF,WAAO,KAAK,cAAc,IAAI,MAAM,OAAO,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAc,eACb,IACA,MACA,OACA,QACgB;AAChB,QAAI,CAAC,KAAK,eAAe,IAAI,EAAE,GAAG;AACjC,YAAM,KAAK,WAAW,EAAE;AACxB,YAAM,KAAK,wBAAwB,IAAI;AAAA,QACtC,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,MAAM,UAAU,MAAM,SAAS,MAAM,MAAM,OAAO,MAAM,OAAO;AAAA,QAC/E,QAAQ,CAAC;AAAA,MACV,CAAC;AACD,YAAM,KAAK,cAAc,IAAI,EAAE,KAAK,GAAG,KAAK,KAAK,CAAC;AAClD,WAAK,eAAe,IAAI,EAAE;AAAA,IAC3B;AACA,SAAK,SAAS,IAAI,IAAI,KAAK;AAAA,EAC5B;AAAA,EAEA,MAAc,iBAAiB,KAAsB,QAA+B;AACnF,UAAM,SAAS,MAAM,KAAK,aAAa,kBAAkB,GAAG,EAAE;AAC9D,QAAI,OAAO,MAAM,OAAO,MAAM;AAC7B,YAAM,KAAK,cAAc,QAAQ;AAAA,QAChC,KAAK,0BAA0B,OAAO,KAAK,SAAS,QAAQ,CAAC;AAAA,QAC7D,KAAK;AAAA,MACN,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,MAAc,WAAW,IAAY,MAA6B;AACjE,QAAI,KAAK,eAAe,IAAI,EAAE,GAAG;AAChC;AAAA,IACD;AACA,UAAM,KAAK,WAAW,EAAE;AACxB,UAAM,KAAK,wBAAwB,IAAI;AAAA,MACtC,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,MAAM,WAAW,MAAM,aAAa,MAAM,MAAM,OAAO,OAAO,KAAK,MAAM;AAAA,MACzF,QAAQ,CAAC;AAAA,IACV,CAAC;AACD,SAAK,eAAe,IAAI,EAAE;AAC1B,UAAM,KAAK,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,EACvD;AAAA,EAEA,MAAc,MAAM,IAA2B;AAC9C,UAAM,KAAK,cAAc,IAAI,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AACrD,SAAK,WAAW,MAAM,KAAK,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC,GAAG,IAAI;AAAA,EAC9F;AAAA;AAAA,EAIA,MAAc,cAA6B;AAC1C,UAAM,KAAK,aAAa,UAAU,UAAU,SAAS;AACrD,UAAM,KAAK,UAAU,iBAAiB,KAAK;AAC3C,UAAM,KAAK,UAAU,qBAAqB,EAAE;AAC5C,UAAM,KAAK,UAAU,mBAAmB,CAAC;AACzC,UAAM,KAAK,UAAU,sBAAsB,CAAC;AAE5C,QAAI,KAAK,OAAO,sBAAsB;AACrC,YAAM,KAAK,aAAa,kBAAkB,WAAW,SAAS;AAC9D,iBAAW,KAAK,cAAc;AAC7B,cAAM,KAAK,aAAa,kBAAkB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,OAAO,MAAM,EAAE,KAAK,CAAC;AAAA,MACxF;AACA,YAAM,KAAK,aAAa,kBAAkB,WAAW,SAAS;AAC9D,YAAM,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,EAAE,MAAM,aAAa;AAAA,QACrB,EAAE,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ;AAAA,MACpC;AACA,UAAI,CAAC,KAAK,eAAe,IAAI,qBAAqB,GAAG;AACpD,cAAM,KAAK,wBAAwB,uBAAuB;AAAA,UACzD,MAAM;AAAA,UACN,QAAQ;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,UACR;AAAA,UACA,QAAQ,CAAC;AAAA,QACV,CAAC;AACD,aAAK,eAAe,IAAI,qBAAqB;AAC7C,cAAM,KAAK,cAAc,uBAAuB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,MACzE;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAIA,MAAc,aAAa,GAA0B;AACpD,QAAI,KAAK,UAAU,EAAE,GAAG,MAAM,QAAW;AACxC;AAAA,IACD;AACA,QAAI,KAAK,OAAO,EAAE,KAAK,CAAC;AACxB,QAAI,CAAC,IAAI;AACR,YAAM,MAAM,MAAM,KAAK,OAAO,0BAA0B,EAAE,GAAG,OAAO;AACpE,YAAM,IAAI,OAAO,IAAI,IAAI;AACzB,UAAI,GAAG;AACN,aAAK,OAAO,GAAG,CAAC;AAAA,MACjB;AAAA,IACD;AACA,SAAK,UAAU,EAAE,GAAG,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK;AACnD,QAAI,IAAI;AACP,WAAK,IAAI,MAAM,OAAO,EAAE,GAAG,eAAe,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,KAAK,UAAU,EAAE,GAAG,CAAC,EAAE;AAAA,IAC1F;AAAA,EACD;AAAA;AAAA,EAIQ,aAAa,GAAmB;AACvC,WAAO,GAAG,EAAE,OAAO,IAAI,QAAQ,KAAK,IAAI,SAAS,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,IAAI,CAAC;AAAA,EAC5E;AAAA;AAAA,EAIA,MAAc,YAAY,GAA0B;AACnD,UAAM,MAAM,KAAK,aAAa,CAAC;AAC/B,SAAK,QAAQ,IAAI,EAAE,KAAK,CAAC;AAEzB,UAAM,KAAK,aAAa,KAAK,EAAE,MAAM,QAAQ;AAC7C,QAAI,EAAE,OAAO,GAAG;AACf,YAAM,KAAK,aAAa,CAAC;AAAA,IAC1B;AACA,UAAM,KAAK,aAAa,EAAE,KAAK,KAAK,CAAC;AAErC,UAAM,KAAK,aAAa,GAAG,GAAG,YAAY,WAAW,SAAS;AAC9D,eAAW,KAAK,cAAc;AAC7B,UAAI,EAAE,OAAO,cAAc,EAAE,OAAO,GAAG;AACtC;AAAA,MACD;AACA,YAAM,KAAK,aAAa,GAAG,GAAG,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM;AAAA,QACzD,MAAM;AAAA,QACN,MAAM,EAAE;AAAA,QACR,QAAQ,CAAC,GAAG,EAAE,MAAM;AAAA,QACpB,KAAK,EAAE;AAAA,QACP,IAAI,EAAE;AAAA,MACP,CAAC;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,aAAa,EAAE,OAAO,GAAG;AACxC,YAAM,KAAK,aAAa,GAAG,GAAG,gBAAgB,OAAO,SAAS;AAC9D,iBAAW,KAAK,UAAU;AACzB,cAAM,MAAM,GAAG,GAAG,gBAAgB,EAAE,EAAE;AACtC,YAAI,EAAE,MAAM;AACX,gBAAM,KAAK;AAAA,YACV;AAAA,YACA,OAAO,EAAE,EAAE;AAAA,YACX,EAAE,MAAM,WAAW,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI;AAAA,YAC1C;AAAA,UACD;AAAA,QACD,OAAO;AACN,gBAAM,KAAK,aAAa,KAAK,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,OAAO,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI,CAAC;AAAA,QACpF;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,OAAO,cAAc,EAAE,OAAO,GAAG;AACzC,YAAM,KAAK,aAAa,GAAG,GAAG,SAAS,QAAQ,SAAS;AACxD,YAAM,KAAK,UAAU,GAAG,GAAG,kBAAkB,GAAG,KAAK,OAAO,iBAAiB,EAAE,GAAG,EAAE;AACpF,YAAM,KAAK,UAAU,GAAG,GAAG,eAAe,GAAG,KAAK,OAAO,kBAAkB,EAAE,GAAG,EAAE;AAClF,YAAM,KAAK,UAAU,GAAG,GAAG,eAAe,GAAG,KAAK,OAAO,oBAAoB,EAAE,GAAG,EAAE;AACpF,YAAM,KAAK,UAAU,GAAG,GAAG,aAAa,GAAG,KAAK,OAAO,mBAAmB,EAAE,GAAG,EAAE;AAAA,IAClF;AAEA,QAAI,EAAE,OAAO,GAAG;AACf,YAAM,SAAS,GAAG,GAAG;AACrB,UAAI,CAAC,KAAK,eAAe,IAAI,MAAM,GAAG;AACrC,cAAM,KAAK,WAAW,MAAM;AAC5B,cAAM,KAAK,wBAAwB,QAAQ;AAAA,UAC1C,MAAM;AAAA,UACN,QAAQ;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,UACR;AAAA,UACA,QAAQ,CAAC;AAAA,QACV,CAAC;AACD,cAAM,KAAK,cAAc,QAAQ,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC;AACvD,aAAK,eAAe,IAAI,MAAM;AAAA,MAC/B;AACA,YAAM,KAAK,aAAa,GAAG,GAAG,+BAA+B,6BAA6B;AAAA,QACzF,MAAM;AAAA,QACN,KAAK,EAAE;AAAA,QACP;AAAA,MACD,CAAC;AACD,UAAI,KAAK,OAAO,mBAAmB;AAClC,cAAM,KAAK,iBAAiB,EAAE,KAAK,MAAM;AAAA,MAC1C;AAAA,IACD;AAEA,UAAM,KAAK,mBAAmB,GAAG,GAAG;AAAA,EACrC;AAAA;AAAA,EAIQ,SACP,IACA,KAUC;AAv0BH;AAw0BE,UAAM,IAAI;AACV,UAAM,MAAK,OAAE,OAAF,YAAQ;AACnB,UAAM,MAAM,GAAG,YAAY,GAAG;AAC9B,UAAM,MAAM,GAAG,MAAM,IAAI,GAAG,MAAM,GAAG,GAAG,IAAI,EAAE;AAC9C,UAAM,SAAS,EAAE,KAAK,KAAK,MAAO,OAAO,EAAE,EAAE,IAAI,UAAW,GAAG,IAAI,MAAM;AACzE,UAAM,MAAM,EAAE,KAAK,OAAO,OAAO,EAAE,CAAC,IAAI;AACxC,UAAM,OAAM,OAAE,OAAF,YAAQ;AACpB,UAAM,MAAM,WAAW,QAAO,OAAE,MAAF,YAAO,CAAC,CAAC,IAAI,eAAsB;AACjE,UAAM,KAAK,IAAI,KAAK,EAAE;AACtB,UAAM,MAAM,CAAC,MAAsB,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AAC5D,UAAM,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC,IAAI,IAAI,GAAG,SAAS,IAAI,CAAC,CAAC;AAC3D,UAAM,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,IAAI,IAAI,GAAG,WAAW,CAAC,CAAC;AAC1D,UAAM,QAAQ,GAAG,KAAK,OAAO,sBAAsB,GAAG,OAAO,mBAAmB,GAAG,CAAC;AACpF,UAAM,QAAQ,GAAG,KAAK,OAAO,uBAAuB,GAAG,YAAY,mBAAmB,EAAE,CAAC;AACzF,WAAO,EAAE,IAAI,QAAQ,KAAK,KAAK,MAAM,MAAM,OAAO,MAAM;AAAA,EACzD;AAAA;AAAA,EAIQ,iBAAiB,GAAW,QAA2C;AAC9E,YAAQ,KAAK,OAAO,cAAc,YAAY,OAC3C,KAAK,mBAAmB,GAAG,MAAM,IACjC,KAAK,qBAAqB,GAAG,MAAM;AAAA,EACvC;AAAA,EAEQ,qBAAqB,GAAW,QAA2C;AAClF,UAAM,MAAM,EAAE;AACd,UAAM,SAAS,KAAK,OAAO,gBAAgB;AAC3C,UAAM,OAAO,KAAK,OAAO,uBAAuB;AAChD,UAAM,WAAW,KAAK,OAAO;AAC7B,UAAM,OAAO,KAAK,OAAO,qBAAqB,eAAe,MAAM,GAAG;AACtE,UAAM,WAAW,GAAG,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;AACxC,UAAM,aAAa,KAAK,OAAO,mBAAmB,IAAI,KAAK;AAC3D,UAAM,aAAa;AAEnB,UAAM,QAAQ,OACZ,IAAI,CAAC,IAAI,MAAM;AACf,YAAM,IAAI,KAAK,SAAS,IAAI,GAAG;AAC/B,YAAM,KAAK,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC;AACnC,YAAM,QACL,YAAY,EAAE,MAAM,+BAA+B,QAAQ,KAAK,QAAQ,EAAE,GAAG,CAAC,YAAY;AAC3F,YAAM,QACL,kCAAkC,EAAE,KAAK,2BAA2B,KAAK,4DACjD,QAAQ,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,IAAI,CAAC,OAAO,QAAQ,EAAE,GAAG,CAAC,cAAc,QAAQ,EAAE,MAAM,CAAC;AAC/G,UAAI,WAAW;AACd,cAAM,OAAO,UACX,QAAQ,YAAY,mBAAmB,EAAE,KAAK,CAAC,EAC/C,QAAQ,eAAe,EAAE,KAAK,EAC9B,QAAQ,SAAS,mBAAmB,EAAE,EAAE,CAAC,EACzC,QAAQ,WAAW,mBAAmB,EAAE,IAAI,CAAC,EAC7C,QAAQ,WAAW,mBAAmB,EAAE,IAAI,CAAC,EAC7C,QAAQ,eAAe,mBAAmB,EAAE,GAAG,CAAC,EAChD,QAAQ,WAAW,mBAAmB,OAAO,EAAE,MAAM,CAAC,CAAC,EACvD,QAAQ,WAAW,mBAAmB,EAAE,GAAG,CAAC;AAC9C,eAAO,4BAA4B,QAAQ,IAAI,CAAC,oCAAoC,KAAK;AAAA,MAC1F;AACA,aACC,4CAA4C,EAAE,IAAI,UAAU,yCACpB,EAAE,KAAK,KAAK,iEACK,EAAE,8DACP,EAAE,sFACc,EAAE,KAAK,kCACnD,QAAQ,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,IAAI,CAAC,aAAa,QAAQ,EAAE,GAAG,CAAC,cAAc,QAAQ,EAAE,MAAM,CAAC,MACnH,EAAE,MAAM,aAAa,QAAQ,EAAE,GAAG,CAAC,KAAK,EACzC,sBAAsB,EAAE,KAAK,8BAA8B,KAAK,GAAG,QAAQ;AAAA,IAE7E,CAAC,EACA,KAAK,EAAE;AAET,UAAM,OAAO,QACV,wBAAwB,KAAK,WAC7B,yBAAyB,KAAK,GAAG,YAAY;AAChD,WAAO,UAAU,WAAW,QAAQ,IAAI,CAAC,WAAW,IAAI;AAAA,EACzD;AAAA,EAEQ,mBAAmB,GAAW,QAA2C;AAChF,UAAM,MAAM,EAAE;AACd,UAAM,SAAS,KAAK,OAAO,gBAAgB;AAC3C,UAAM,OAAO,KAAK,OAAO,uBAAuB;AAChD,UAAM,QAAQ,OAAO,IAAI,QAAM;AAC9B,YAAM,IAAI,KAAK,SAAS,IAAI,GAAG;AAC/B,aAAO;AAAA,QACN,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,KAAK,EAAE;AAAA,QACP,MAAM,EAAE;AAAA,QACR,KAAK,EAAE;AAAA,QACP,OAAO,EAAE;AAAA,QACT,OAAO,EAAE;AAAA,MACV;AAAA,IACD,CAAC;AACD,UAAM,MAAM;AAAA,MACX,SAAS;AAAA,MACT,WAAW,CAAC,CAAC,KAAK,OAAO;AAAA,MACzB,iBAAiB;AAAA,MACjB,aAAa,KAAK,UAAU,GAAG,KAAK,KAAK,OAAO,oBAAoB;AAAA,MACpE,aAAa,KAAK,OAAO,mBAAmB,IAAI,KAAK;AAAA,MACrD,cAAc,KAAK,OAAO,qBAAqB;AAAA,MAC/C,QAAQ,EAAE,cAAc,KAAK,GAAG,cAAc,KAAK,KAAK,GAAG,KAAK,MAAM,KAAK,GAAG,KAAK;AAAA,IACpF;AACA,UAAM,OAAO,KAAK,UAAU,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC,EAAE,QAAQ,MAAM,SAAS;AAC/E,UAAM,OAAO;AACb,WACC,UAAU,aAAa,MAAM,CAAC,gFAC0C,IAAI,oFACD,QAAQ,KAAK,GAAG,MAAM,CAAC,qHAErD,eAAe,6BACxC,IAAI;AAAA,EAE1B;AAAA,EAEQ,kBAAkB,MAAwB;AACjD,UAAM,KAAK,KAAK,IAAI;AACpB,UAAM,SAAS,KAAK,OAAO,gBAAgB;AAC3C,UAAM,OAAO,KAAK,OAAO,uBAAuB;AAChD,UAAM,aAAa;AACnB,UAAM,QAAQ,KACZ,IAAI,OAAK;AACT,YAAM,MAAM,EAAE;AACd,YAAM,KAAK,UAAU,SAAS,GAAG,CAAC;AAClC,YAAM,OAAO,GAAG,KAAK,OAAO,iBAAiB,GAAG,yBAAyB,EAAE;AAC3E,YAAM,OAAO,GAAG,KAAK,OAAO,mBAAmB,GAAG;AAClD,YAAM,OAAO,QAAQ,EAAE,QAAQ,UAAU,GAAG,EAAE;AAC9C,YAAM,QAAQ,KAAK,UAAU,GAAG,KAAK,KAAK,OAAO,oBAAoB;AACrE,YAAM,KAAK,QAAQ,OAAO,KAAK,EAAE,QAAQ,KAAK,KAAK,IAAI;AACvD,YAAM,MAAM,KAAK,eAAe;AAChC,YAAM,UAAU,KAAK,wBAAwB,EAAE,MAAM;AACrD,YAAM,QACL,sBAAsB,GAAG,IAAI,OAAO,cAAc,IAAI,iFACG,QAAQ,KAAK,GAAG,IAAI,CAAC,mEACtD,IAAI;AAC7B,aACC,4CAA4C,EAAE,IAAI,UAAU,yCACpB,EAAE,KAAK,KAAK,iEACK,EAAE,8DACP,EAAE,sFACc,IAAI,kCAChD,IAAI;AAAA,IAE9B,CAAC,EACA,KAAK,EAAE;AACT,UAAM,OAAO,QAAQ,wBAAwB,KAAK,WAAW;AAC7D,WAAO,UAAU,WAAW,QAAQ,IAAI,CAAC,WAAW,IAAI;AAAA,EACzD;AAAA;AAAA,EAIA,MAAc,cAAc,GAAW,KAAa,QAAkD;AA79BvG;AA89BE,UAAM,MAAM,EAAE;AACd,UAAM,KAAK,aAAa,GAAG,GAAG,WAAW,UAAU,SAAS;AAC5D,UAAM,KAAK,aAAa,GAAG,GAAG,gBAAgB,cAAc,SAAS;AAErE,UAAM,MAAM,CAAC,MAAsB,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AAC5D,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,KAAK,GAAG,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,IAAI,IAAI,SAAS,IAAI,CAAC,CAAC;AAC3D,UAAM,aAAa,OAAO,OAAO,QAAM,KAAK,SAAS,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE;AAE3E,UAAM,KAAK,UAAU,GAAG,GAAG,iBAAiB,OAAO,MAAM;AACzD,UAAM,KAAK,UAAU,GAAG,GAAG,iBAAiB,UAAU;AAEtD,QAAI,OAAO,QAAQ;AAClB,YAAM,IAAI,KAAK,SAAS,OAAO,CAAC,GAAG,GAAG;AACtC,YAAM,QAAQ,WAAW,QAAQ,YAAO,CAAC,EAAoB,MAA5B,YAAiC,CAAC,CAAC,IAAI,eAAsB;AAC9F,YAAM,KAAK,UAAU,GAAG,GAAG,qBAAqB,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE;AACrE,YAAM,KAAK,UAAU,GAAG,GAAG,0BAA0B,KAAK,MAAM,IAAI,CAAC;AACrE,YAAM,KAAK,UAAU,GAAG,GAAG,oBAAoB,EAAE,GAAG;AACpD,YAAM,KAAK,UAAU,GAAG,GAAG,yBAAyB,EAAE,MAAM,WAAW,EAAE,GAAG,IAAI,CAAC;AACjF,YAAM,KAAK,UAAU,GAAG,GAAG,wBAAwB,EAAE,MAAM;AAC3D,YAAM,KAAK,UAAU,GAAG,GAAG,sBAAsB,EAAE,KAAK;AACxD,YAAM,KAAK,UAAU,GAAG,GAAG,sBAAsB,EAAE,KAAK;AAAA,IACzD;AAEA,UAAM,KAAK,WAAW,GAAG,GAAG,eAAe,WAAW;AAEtD,QAAI,KAAK,OAAO,YAAY;AAC3B,YAAM,MAAM,GAAG,GAAG;AAClB,UAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;AAClC,cAAM,KAAK,WAAW,GAAG;AACzB,cAAM,KAAK,wBAAwB,KAAK;AAAA,UACvC,MAAM;AAAA,UACN,QAAQ;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK;AAAA,UACN;AAAA,UACA,QAAQ,CAAC;AAAA,QACV,CAAC;AACD,cAAM,KAAK,cAAc,KAAK,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC;AACpD,aAAK,eAAe,IAAI,GAAG;AAAA,MAC5B;AACA,WAAK,SAAS,IAAI,KAAK,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,IAClD;AAEA,UAAM,UAAU,KAAK,OAAO,mBAAmB,YAC7C,MAAM,GAAG,EACT,IAAI,OAAK,EAAE,KAAK,EAAE,YAAY,CAAC,EAC/B,OAAO,OAAO;AAChB,UAAM,WAAW,CAAC,MACjB,EACE,YAAY,EACZ,MAAM,QAAQ,EACd,OAAO,OAAO;AAEjB,eAAW,OAAO,KAAK,OAAO,aAAa,IACzC,MAAM,GAAG,EACT,IAAI,OAAK,EAAE,KAAK,CAAC,EACjB,OAAO,OAAO,GAAG;AAClB,YAAM,KAAK,WAAW,GAAG,GAAG,oBAAoB,SAAS,EAAE,CAAC,IAAI,aAAa,EAAE,EAAE;AAAA,IAClF;AAEA,QAAI,KAAK,OAAO,kBAAkB;AACjC,YAAM,OAAO,oBAAI,IAAY;AAC7B,iBAAW,MAAM,QAAQ;AACxB,kBAAU,QAAqB,OAArB,YAA2B,EAAE,EAAE,QAAQ,OAAK,KAAK,IAAI,CAAC,CAAC;AAAA,MAClE;AACA,iBAAW,KAAK,MAAM;AACrB,YAAI,OAAO,SAAS,CAAC,GAAG;AACvB;AAAA,QACD;AACA,cAAM,KAAK,WAAW,GAAG,GAAG,oBAAoB,SAAS,CAAC,CAAC,IAAI,aAAa,CAAC,EAAE;AAAA,MAChF;AAAA,IACD;AAEA,QAAI,WAAW;AACf,QAAI,OAAO,QAAQ;AAClB,YAAM,OAAO,KAAK,YAAY,GAAG;AACjC,UAAI,SAAS,QAAW;AACvB,cAAM,IAAI,OAAO,UAAU,OAAM,EAAoB,OAAO,IAAI;AAChE,mBAAW,MAAM,KAAK,OAAO,SAAS;AAAA,MACvC;AACA,WAAK,YAAY,GAAG,KAAK,YAAO,CAAC,EAAoB,OAA5B,YAAkC;AAAA,IAC5D;AAEA,QAAI,WAAW,GAAG;AACjB,YAAM,KAAK,MAAM,GAAG,GAAG,aAAa;AACpC,YAAM,OAAO,oBAAI,IAAY;AAC7B,eAAS,IAAI,GAAG,IAAI,YAAY,IAAI,OAAO,QAAQ,KAAK;AACvD,kBAAU,YAAO,CAAC,EAAoB,OAA5B,YAAkC,EAAE,EAAE,QAAQ,OAAK,KAAK,IAAI,CAAC,CAAC;AAAA,MACzE;AACA,iBAAW,KAAK,MAAM;AACrB,YAAI,OAAO,SAAS,CAAC,GAAG;AACvB;AAAA,QACD;AACA,cAAM,MAAM,GAAG,GAAG,oBAAoB,SAAS,CAAC,CAAC;AACjD,cAAM,KAAK,WAAW,KAAK,aAAa,CAAC,EAAE;AAC3C,cAAM,KAAK,MAAM,GAAG;AAAA,MACrB;AACA,WAAK,IAAI,MAAM,GAAG,QAAQ,qBAAqB,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG,CAAC,GAAG;AAAA,IAC9E;AAAA,EACD;AAAA;AAAA,EAIA,MAAc,mBAAmB,GAAW,KAA4B;AA1kCzE;AA2kCE,QAAI,EAAE,OAAO,GAAG;AACf;AAAA,IACD;AACA,QAAI,CAAC,KAAK,OAAO,gBAAgB,CAAC,KAAK,OAAO,gBAAgB;AAC7D;AAAA,IACD;AACA,QAAI,KAAK,UAAU,EAAE,GAAG,GAAG;AAC1B;AAAA,IACD;AACA,SAAK,UAAU,EAAE,GAAG,IAAI;AACxB,QAAI;AACH,YAAM,QAAQ,MAAM,KAAK,OAAO,oBAAoB,EAAE,GAAG,OAAO;AAChE,YAAM,SAAS,OAAO,MAAM,IAAI;AAChC,UAAI,CAAC,QAAQ;AACZ;AAAA,MACD;AACA,YAAM,SACL,MAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,SAAS,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AAGlF,UAAI,KAAK,OAAO,gBAAgB;AAC/B,cAAM,KAAK,cAAc,GAAG,KAAK,MAAM;AAAA,MACxC;AAEA,UAAI,KAAK,OAAO,cAAc;AAC7B,cAAM,MAAM,GAAG,GAAG;AAClB,YAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;AAClC,gBAAM,KAAK,WAAW,GAAG;AACzB,gBAAM,KAAK,wBAAwB,KAAK;AAAA,YACvC,MAAM;AAAA,YACN,QAAQ;AAAA,cACP,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,cACP,KAAK;AAAA,YACN;AAAA,YACA,QAAQ,CAAC;AAAA,UACV,CAAC;AACD,eAAK,eAAe,IAAI,GAAG;AAAA,QAC5B;AACA,cAAM,KAAK,OAAO,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,OAAO,gBAAgB,EAAE,CAAC;AACtE,cAAM,KAAK,QAAG,CAAC,MAAJ,YAAS,CAAC;AACrB,cAAM,KAAK,QAAG,GAAG,SAAS,CAAC,MAAhB,YAAqB,CAAC;AACjC,cAAM,MAAM,GAAG,GAAG,MAAM,KAAI,OAAE,OAAF,YAAQ,EAAE,KAAI,OAAE,OAAF,YAAQ,EAAE;AACpD,YAAI,KAAK,UAAU,GAAG,MAAM,KAAK;AAChC,gBAAM,KAAK,cAAc,KAAK,EAAE,KAAK,KAAK,iBAAiB,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC;AAC9E,eAAK,UAAU,GAAG,IAAI;AAAA,QACvB;AAAA,MACD;AAAA,IACD,UAAE;AACD,WAAK,UAAU,EAAE,GAAG,IAAI;AAAA,IACzB;AAAA,EACD;AAAA,EAEQ,YAAY,KAA4B;AAC/C,UAAM,IAAI,KAAK,QAAQ,IAAI,GAAG;AAC9B,QAAI,CAAC,GAAG;AACP,WAAK,IAAI,KAAK,gBAAgB,GAAG,uCAAuC;AACxE;AAAA,IACD;AACA,UAAM,MAAM,KAAK,aAAa,CAAC;AAC/B,eAAW,MAAM,CAAC,GAAG,MAAM,MAAM,GAAI,GAAG;AACvC,WAAK;AAAA,QACJ,MACC,KAAK,mBAAmB,GAAG,GAAG,EAAE;AAAA,UAAM,OACrC,KAAK,IAAI,KAAK,uBAAwB,EAAY,OAAO,EAAE;AAAA,QAC5D;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAIA,MAAc,OAAsB;AAvpCrC;AAwpCE,UAAM,MAAM,MAAM,KAAK,OAAO,qBAAqB;AACnD,UAAM,OAAO,OAAO,IAAI,IAAI;AAE5B,QAAI,CAAC,IAAI,MAAM,CAAC,MAAM;AACrB,YAAM,KAAK,cAAc,mBAAmB,OAAO,IAAI;AACvD,YAAM,KAAK,cAAc,iBAAiB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACnE,WAAK,IAAI,KAAK,yBAAyB,IAAI,SAAS,kBAAkB,EAAE;AACxE;AAAA,IACD;AAEA,UAAM,KAAK,cAAc,mBAAmB,MAAM,IAAI;AACtD,UAAM,KAAK,cAAc,iBAAiB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAElE,QAAI,KAAK,UAAU;AAClB,YAAM,KAAK,aAAa,KAAK,UAAU,mBAAmB,CAAC;AAAA,IAC5D;AAEA,QAAI,KAAK,OAAO,cAAc;AAC7B,YAAM,QAAiC,EAAE,GAAG,KAAK;AACjD,aAAO,MAAM;AACb,YAAM,KAAK,UAAU,yBAAyB,KAAK,UAAU,KAAK,EAAE,MAAM,GAAG,GAAK,CAAC;AAAA,IACpF;AAEA,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,KAAK,cAAc,sBAAsB,EAAE,KAAK,QAAQ,OAAO,OAAK,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,KAAK,CAAC;AAEzG,eAAW,KAAK,SAAS;AACxB,YAAM,KAAK,YAAY,CAAC;AAAA,IACzB;AAEA,UAAM,QAAQ,QAAQ,MAAM,KAAK,OAAO,yBAAyB,GAAG,IAAI;AACxE,QAAI,OAAO;AACV,YAAM,KAAK,aAAa,OAAO,gBAAgB,CAAC;AAChD,YAAM,KAAK,YAAY,MAAM,SAAS;AACtC,UAAI,OAAO,MAAM;AAChB,cAAM,KAAK,UAAU,uBAAuB,EAAE;AAAA,MAC/C;AAAA,IACD;AAEA,UAAM,SAAS,QAAQ,MAAM,KAAK,OAAO,oBAAoB,GAAG,IAAI;AACpE,QAAI,QAAQ;AACX,YAAM,KAAK,aAAa,QAAQ,iBAAiB,CAAC;AAAA,IACnD;AAEA,QAAI,KAAK,OAAO,wBAAwB,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACrE,YAAM,SAAiC,CAAC;AACxC,UAAI,YAA2B;AAC/B,iBAAW,KAAK,KAAK,UAAU;AAC9B,YAAI,KAAK,OAAO,MAAM,UAAU;AAC/B,gBAAM,KAAK;AACX,gBAAM,OAAM,cAAG,OAAH,YAAS,GAAG,QAAZ,YAAmB,GAAG;AAClC,gBAAM,QAAQ,GAAG;AACjB,cAAI,OAAO,QAAQ,aAAa,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AACxF,mBAAO,GAAG,IAAI,OAAO,KAAK;AAC1B,gBAAI,GAAG,WAAW,MAAM;AACvB,0BAAY;AAAA,YACb;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,UAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AACnC,cAAM,MAAM,KAAK,UAAU,MAAM;AACjC,YAAI,QAAQ,KAAK,YAAY;AAC5B,eAAK,aAAa;AAClB,gBAAM,KAAK,kBAAkB,2BAA2B,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC9E,gBAAM,KAAK,cAAc,uBAAuB,EAAE,KAAK,KAAK,KAAK,KAAK,CAAC;AAAA,QACxE;AACA,YAAI,cAAc,MAAM;AACvB,gBAAM,KAAK,cAAc,2BAA2B,EAAE,KAAK,WAAW,KAAK,KAAK,CAAC;AAAA,QAClF;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,OAAO,gBAAgB;AAC/B,YAAM,OAAO,QAAQ,OAAO,OAAK,EAAE,OAAO,CAAC;AAC3C,YAAM,OAAO;AACb,UAAI,CAAC,KAAK,eAAe,IAAI,IAAI,GAAG;AACnC,cAAM,KAAK,wBAAwB,MAAM;AAAA,UACxC,MAAM;AAAA,UACN,QAAQ;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK;AAAA,UACN;AAAA,UACA,QAAQ,CAAC;AAAA,QACV,CAAC;AACD,aAAK,eAAe,IAAI,IAAI;AAAA,MAC7B;AACA,YAAM,KAAK,cAAc,MAAM,EAAE,KAAK,KAAK,kBAAkB,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,IAChF;AAEA,UAAM,KAAK,cAAc,qBAAqB,EAAE,MAAK,oBAAI,KAAK,GAAE,YAAY,GAAG,KAAK,KAAK,CAAC;AAC1F,UAAM,KAAK,cAAc,mBAAmB,EAAE,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,EAC3E;AAAA,EAEQ,kBAAwB;AAC/B,QAAI,KAAK,iBAAiB,QAAW;AACpC,WAAK,aAAa,KAAK,YAAY;AACnC,WAAK,eAAe;AAAA,IACrB;AACA,SAAK,eAAe,KAAK;AAAA,MACxB,MAAM,KAAK,KAAK,EAAE,MAAM,OAAK,KAAK,IAAI,KAAK,kBAAmB,EAAY,OAAO,EAAE,CAAC;AAAA,MACpF;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAIQ,OAAO,KAAsB,KAAqB;AACzD,WAAO,gBAAgB,mBAAmB,OAAO,GAAG,CAAC,CAAC,QAAQ,GAAG;AAAA,EAClE;AAAA,EAEQ,gBAAgB,OAA8B;AACrD,QAAI,MAAM,SAAS,OAAO;AACzB,aAAO,KAAK,OAAO,MAAM,KAAM,MAAM,GAAI;AAAA,IAC1C;AACA,QAAI,MAAM,SAAS,OAAO;AACzB,aAAO,MAAM;AAAA,IACd;AACA,UAAM,KAAe,CAAC;AACtB,eAAW,KAAK,MAAM,UAAU,CAAC,GAAG;AACnC,UAAI,MAAM,OAAO;AAChB,WAAG,KAAK,OAAO,mBAAmB,OAAO,MAAM,GAAG,CAAC,CAAC,EAAE;AAAA,MACvD,WAAW,MAAM,MAAM;AACtB,WAAG,KAAK,MAAM,mBAAmB,OAAO,MAAM,EAAE,CAAC,CAAC,EAAE;AAAA,MACrD;AAAA,IACD;AACA,YAAQ,MAAM,QAAQ,OAAO,GAAG,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,KAAK;AAAA,EAC/D;AAAA,EAEA,MAAc,iBAAiB,SAAgC;AAC9D,UAAM,SAAS,QAAQ,MAAM,GAAG,QAAQ,YAAY,GAAG,IAAI,CAAC;AAC5D,eAAW,KAAK,UAAU;AACzB,UAAI,CAAC,EAAE,MAAM;AACZ;AAAA,MACD;AACA,YAAM,MAAM,SAAS,EAAE;AACvB,UAAI,QAAQ,SAAS;AACpB,cAAM,KAAK,cAAc,KAAK,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,MACxD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,WAAW,OAAe,OAAsB,KAAyC;AACtG,QAAI,MAAM,SAAS,cAAc;AAChC,YAAM,MAAM,OAAO,QAAQ,WAAW,MAAM,SAAS,OAAO,oBAAO,EAAE,GAAG,EAAE;AAC1E,UAAI,CAAC,MAAM,GAAG,GAAG;AAChB,cAAMA,OAAM,2BAA2B,GAAG;AAC1C,cAAMC,UAAS,MAAM,KAAK,OAAOD,IAAG;AACpC,YAAIC,QAAO,IAAI;AACd,eAAK,IAAI,MAAM,OAAOD,IAAG,EAAE;AAC3B,gBAAM,KAAK,cAAc,OAAO,EAAE,KAAK,KAAK,KAAK,KAAK,CAAC;AAAA,QACxD,OAAO;AACN,eAAK,IAAI,KAAK,mBAAmBA,IAAG,MAAMC,QAAO,KAAK,EAAE;AAAA,QACzD;AACA,aAAK,gBAAgB;AAAA,MACtB;AACA;AAAA,IACD;AAEA,QAAI,MAAM,SAAS,eAAe;AACjC,YAAM,SAAS,GAAG,MAAM,GAAG;AAC3B,YAAM,KAAK,iBAAiB,MAAM,KAAM,MAAM;AAC9C,YAAM,KAAK,cAAc,OAAO,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACzD;AAAA,IACD;AAEA,QAAI,MAAM,SAAS,QAAQ;AAC1B,WAAK,IAAI,KAAK,oBAAoB,MAAM,GAAG,EAAE;AAC7C,YAAM,KAAK,cAAc,OAAO,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC;AACtD,WAAK,YAAY,MAAM,GAAI;AAC3B;AAAA,IACD;AAEA,QAAI,MAAM,SAAS,WAAW;AAC7B,YAAM,MAAM,MAAM;AAClB,YAAM,YAAY,YAA2B;AAC5C,cAAM,KAAK,iBAAiB,KAAK;AACjC,cAAM,KAAK,OAAO,KAAK,OAAO,KAAK,MAAM,GAAI,CAAC;AAC9C,aAAK,UAAU,IAAI,KAAK,KAAK;AAC7B,cAAM,KAAK,cAAc,OAAO,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,MACzD;AACA,YAAM,WAAW,YAA2B;AAC3C,cAAM,KAAK,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC;AACtC,YAAI,KAAK,UAAU,IAAI,GAAG,MAAM,OAAO;AACtC,eAAK,UAAU,OAAO,GAAG;AAAA,QAC1B;AACA,cAAM,KAAK,cAAc,OAAO,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,MAC1D;AACA,UAAI,KAAK;AACR,YAAI,KAAK,UAAU,IAAI,GAAG,MAAM,OAAO;AACtC,gBAAM,SAAS;AAAA,QAChB,OAAO;AACN,gBAAM,UAAU;AAAA,QACjB;AAAA,MACD,OAAO;AACN,cAAM,SAAS;AAAA,MAChB;AACA,WAAK,gBAAgB;AACrB;AAAA,IACD;AAEA,QAAI,CAAC,KAAK;AACT;AAAA,IACD;AAEA,QAAI,MAAM,SAAS,SAAS,MAAM,SAAS,MAAM;AAChD,YAAM,KAAK,KAAK,EAAE,MAAM,OAAK,KAAK,IAAI,KAAK,yBAA0B,EAAY,OAAO,EAAE,CAAC;AAC3F,YAAM,KAAK,cAAc,OAAO,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACzD;AAAA,IACD;AAEA,UAAM,MAAM,KAAK,gBAAgB,KAAK;AACtC,UAAM,SAAS,MAAM,KAAK,OAAO,GAAG;AACpC,QAAI,OAAO,IAAI;AACd,WAAK,IAAI,MAAM,OAAO,GAAG,EAAE;AAAA,IAC5B,OAAO;AACN,WAAK,IAAI,KAAK,mBAAmB,GAAG,MAAM,OAAO,KAAK,EAAE;AAAA,IACzD;AAEA,UAAM,KAAK,cAAc,OAAO,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACzD,SAAK,gBAAgB;AAAA,EACtB;AACD;AAEA,IAAI,QAAQ,SAAS,QAAQ;AAC5B,SAAO,UAAU,CAAC,YAAuD,IAAI,SAAS,OAAO;AAC9F,OAAO;AACN,GAAC,MAAM,IAAI,SAAS,GAAG;AACxB;",
4
+ "sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport { getWidgetLabels, type WidgetLabels } from './lib/widget-i18n';\n\n// =====================================================================\n// Agent DVR -> ioBroker Adapter\n// API reference: https://ispysoftware.github.io/Agent_API/ (v7.5)\n// =====================================================================\n\n// ---- Types ----\n\ninterface ApiResult {\n\tok: boolean;\n\tdata?: string;\n\terror?: string;\n}\n\ninterface AgentDvrEvent {\n\tfn?: string;\n\ttg?: string;\n\tc?: number;\n\td?: number | string;\n\tsb?: number;\n\t[key: string]: unknown;\n}\n\ninterface Device {\n\toid: number | string;\n\tot: number;\n\tname: string;\n\traw: Record<string, unknown>;\n}\n\ntype RegistryKind = 'cam' | 'sys' | 'ptz' | 'ptzHold' | 'push' | 'setProfile' | 'snapshotB64';\n\ninterface RegistryEntry {\n\tkind: RegistryKind;\n\tpath?: string | null;\n\tparams?: string[];\n\toid?: number | string;\n\tot?: number;\n\tdir?: number;\n\tfid?: string;\n}\n\n// ---- Commands ----\n\nconst CAM_COMMANDS = [\n\t{ id: 'record', path: '/command/record', params: ['oid', 'ot'], name: 'Start recording' },\n\t{ id: 'recordStop', path: '/command/recordStop', params: ['oid', 'ot'], name: 'Stop recording' },\n\t{ id: 'recordRestart', path: '/command/recordRestart', params: ['oid', 'ot'], name: 'Restart recording' },\n\t{ id: 'triggerRecord', path: '/command/triggerRecord', params: ['oid', 'ot'], name: 'Trigger recording (timeout)' },\n\t{ id: 'snapshot', path: '/command/snapshot', params: ['oid'], name: 'Take snapshot' },\n\t{ id: 'detect', path: '/command/detect', params: ['oid', 'ot'], name: 'Trigger motion detection' },\n\t{ id: 'alertOn', path: '/command/alertOn', params: ['oid', 'ot'], name: 'Arm alerts' },\n\t{ id: 'alertOff', path: '/command/alertOff', params: ['oid', 'ot'], name: 'Disarm alerts' },\n\t{ id: 'switchOn', path: '/command/switchOn', params: ['oid', 'ot'], name: 'Switch device on' },\n\t{ id: 'switchOff', path: '/command/switchOff', params: ['oid', 'ot'], name: 'Switch device off' },\n\t{ id: 'objectDetectOn', path: '/command/objectdetecton', params: ['oid', 'ot'], name: 'Enable object detection' },\n\t{\n\t\tid: 'objectDetectOff',\n\t\tpath: '/command/objectdetectoff',\n\t\tparams: ['oid', 'ot'],\n\t\tname: 'Disable object detection',\n\t},\n\t{ id: 'recOnAlert', path: '/command/recordOnAlertOn', params: ['oid', 'ot'], name: 'Record on alert: on' },\n\t{ id: 'recOnDetect', path: '/command/recordOnDetectOn', params: ['oid', 'ot'], name: 'Record on detect: on' },\n\t{ id: 'purge', path: '/command/purge', params: ['oid', 'ot'], name: 'Purge folder (caution!)' },\n] as const;\n\nconst SYS_COMMANDS = [\n\t{ id: 'arm', path: '/command/arm', name: 'Arm system' },\n\t{ id: 'disarm', path: '/command/disarm', name: 'Disarm system' },\n\t{ id: 'allOn', path: '/command/allOn', name: 'All devices on' },\n\t{ id: 'allOff', path: '/command/allOff', name: 'All devices off' },\n\t{ id: 'reloadConfig', path: '/command/reloadConfig', name: 'Reload config' },\n\t{ id: 'reloadObjects', path: '/command/reloadObjects', name: 'Reload objects' },\n\t{ id: 'runStorageMgmt', path: '/command/runStorageMgmt', name: 'Run storage management' },\n\t{ id: 'blockExternal', path: '/command/blockExternal', name: 'Block external access' },\n\t{ id: 'unblockExternal', path: '/command/unblockExternal', name: 'Unblock external access' },\n\t{ id: 'restart', path: '/command/restart', name: 'Restart Agent DVR' },\n\t{ id: 'refresh', path: null, name: 'Refresh data now' },\n] as const;\n\nconst PTZ_DIRS = [\n\t{ id: 'left', dir: 1, hold: true },\n\t{ id: 'upLeft', dir: 2, hold: true },\n\t{ id: 'up', dir: 3, hold: true },\n\t{ id: 'upRight', dir: 4, hold: true },\n\t{ id: 'right', dir: 5, hold: true },\n\t{ id: 'downRight', dir: 6, hold: true },\n\t{ id: 'down', dir: 7, hold: true },\n\t{ id: 'downLeft', dir: 8, hold: true },\n\t{ id: 'zoomIn', dir: 9, hold: true },\n\t{ id: 'zoomOut', dir: 10, hold: true },\n\t{ id: 'stop', dir: 11, hold: false },\n\t{ id: 'center', dir: 0, hold: false },\n] as const;\n\nconst SKIP_KEYS = ['icons', 'image', 'thumbnail', 'base64'];\n\n// ---- Module-level helpers ----\n\nfunction sanitize(s: unknown): string {\n\treturn (\n\t\tString(s)\n\t\t\t.replace(/[\\s.[\\]*?\"'`,;:/\\\\]+/g, '_')\n\t\t\t.replace(/[^A-Za-z0-9_-]/g, '_')\n\t\t\t.replace(/_+/g, '_')\n\t\t\t.replace(/^_+|_+$/g, '') || 'x'\n\t);\n}\n\nfunction asJson(data: unknown): Record<string, unknown> | null {\n\tif (data == null) {\n\t\treturn null;\n\t}\n\tif (typeof data === 'object') {\n\t\treturn data as Record<string, unknown>;\n\t}\n\tif (typeof data === 'string') {\n\t\ttry {\n\t\t\treturn JSON.parse(data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction toStr(v: unknown): string {\n\tif (v == null) {\n\t\treturn '';\n\t}\n\tif (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n\t\treturn String(v);\n\t}\n\treturn Object.prototype.toString.call(v);\n}\n\nfunction escHtml(s: unknown): string {\n\treturn toStr(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\nfunction parseSizeGb(s: unknown): number | null {\n\tif (s == null) {\n\t\treturn null;\n\t}\n\tconst m = toStr(s)\n\t\t.trim()\n\t\t.match(/([\\d.,]+)\\s*([KMGT]?B)?/i);\n\tif (!m) {\n\t\treturn null;\n\t}\n\tlet v = parseFloat(m[1].replace(',', '.'));\n\tif (isNaN(v)) {\n\t\treturn null;\n\t}\n\tconst u = (m[2] || 'GB').toUpperCase();\n\tif (u === 'TB') {\n\t\tv *= 1024;\n\t} else if (u === 'MB') {\n\t\tv /= 1024;\n\t} else if (u === 'KB') {\n\t\tv /= 1048576;\n\t} else if (u === 'B') {\n\t\tv /= 1073741824;\n\t}\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction findWH(obj: unknown, depth: number): [number, number] | null {\n\tif (!obj || typeof obj !== 'object' || depth > 5) {\n\t\treturn null;\n\t}\n\tconst o = obj as Record<string, unknown>;\n\tfor (const [kw, kh] of [\n\t\t['width', 'height'],\n\t\t['w', 'h'],\n\t\t['sourceWidth', 'sourceHeight'],\n\t\t['videoWidth', 'videoHeight'],\n\t\t['imageWidth', 'imageHeight'],\n\t]) {\n\t\tconst w = o[kw],\n\t\t\th = o[kh];\n\t\tif (typeof w === 'number' && typeof h === 'number' && w >= 100 && h >= 100 && w <= 12000 && h <= 12000) {\n\t\t\tconst r = w / h;\n\t\t\tif (r >= 0.3 && r <= 4) {\n\t\t\t\treturn [w, h];\n\t\t\t}\n\t\t}\n\t}\n\tfor (const k of Object.keys(o)) {\n\t\tconst g = findWH(o[k], depth + 1);\n\t\tif (g) {\n\t\t\treturn g;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction detectOt(elem: Record<string, unknown>): number {\n\tconst v = elem.typeID ?? elem.ot ?? elem.objectTypeID ?? elem.type;\n\treturn v === 1 || v === 2 ? v : 2;\n}\n\nfunction findDevices(json: Record<string, unknown>): Device[] {\n\tconst list = Array.isArray(json.objectList) ? json.objectList : [];\n\tconst out: Device[] = [];\n\tfor (const e of list) {\n\t\tif (!e || typeof e !== 'object') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst el = e as Record<string, unknown>;\n\t\tconst rawId = el.id ?? el.oid;\n\t\tif (rawId === undefined || rawId === null) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = rawId as number | string;\n\t\tconst name = typeof el.name === 'string' ? el.name : `obj_${id}`;\n\t\tout.push({ oid: id, ot: detectOt(el), name, raw: el });\n\t}\n\treturn out;\n}\n\n// ---- HTML/CSS gallery helpers ----\n\ninterface WidgetColors {\n\tcardBg?: string;\n\ttagBg?: string;\n\ttagText?: string;\n\taccent?: string;\n\tmodalBg?: string;\n\tradius?: number;\n}\n\nfunction advCssVars(c?: WidgetColors): string {\n\tconst cardBg = c?.cardBg || 'rgba(127,127,127,.15)';\n\tconst tagBg = c?.tagBg || 'rgba(0,0,0,.55)';\n\tconst tagText = c?.tagText || '#fff';\n\tconst accent = c?.accent || '#8ab4f8';\n\tconst modalBg = c?.modalBg || '#1c1c1e';\n\tconst radius = c?.radius != null ? `${c.radius}px` : '8px';\n\treturn `--adv-card-bg:${cardBg};--adv-tag-bg:${tagBg};--adv-tag-color:${tagText};--adv-accent:${accent};--adv-modal-bg:${modalBg};--adv-radius:${radius};`;\n}\n\nfunction galleryCss(minCol: number, maxW: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advgrid{${advCssVars(colors)}display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px;max-width:100%}` +\n\t\t`.advgrid .advlb{display:none}` +\n\t\t`.advcell{display:flex;flex-direction:column;cursor:pointer;text-decoration:none;color:inherit;font-family:inherit}` +\n\t\t`.advimg{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimg img{width:100%;height:auto;display:block}` +\n\t\t`.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtag{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplay::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcell:hover .advplay{opacity:1}` +\n\t\t`.advcap{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advmodal{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}` +\n\t\t`.advgrid .advlb:checked + .advthumb + .advmodal{display:flex}` +\n\t\t`.advbackdrop{position:absolute;inset:0;background:transparent;cursor:pointer}` +\n\t\t`.advbox{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,${maxW}px);background:var(--adv-modal-bg);padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}` +\n\t\t`.advvideo{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}` +\n\t\t`.advclose{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}` +\n\t\t`.advinfo{color:#fff;font-size:.8rem;text-align:center}` +\n\t\t`.advinfo a{color:var(--adv-accent)}` +\n\t\t`.advempty{padding:24px;text-align:center;opacity:.7;font-family:inherit}`\n\t);\n}\n\nfunction galleryCssJs(minCol: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advroot{${advCssVars(colors)}font-family:inherit;color:inherit}` +\n\t\t`.advbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}` +\n\t\t`.advsearchjs{flex:1 1 160px;min-width:120px;padding:6px 10px;border-radius:8px;border:1px solid rgba(127,127,127,.4);background:rgba(127,127,127,.08);color:inherit;font:inherit}` +\n\t\t`.advtagsjs{display:flex;flex-wrap:wrap;gap:6px}` +\n\t\t`.advtagbtn{padding:4px 10px;border-radius:999px;border:1px solid rgba(127,127,127,.4);background:transparent;color:inherit;cursor:pointer;font:inherit;font-size:.8rem}` +\n\t\t`.advtagbtn.on{background:var(--adv-accent);color:#fff;border-color:var(--adv-accent)}` +\n\t\t`.advgridjs{display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px}` +\n\t\t`.advcelljs{display:flex;flex-direction:column;cursor:pointer}` +\n\t\t`.advimgjs{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimgjs img{width:100%;height:auto;display:block}` +\n\t\t`.advimgjs.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtagjs{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplayjs{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplayjs::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcelljs:hover .advplayjs{opacity:1}` +\n\t\t`.advcapjs{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advemptyjs{padding:24px;text-align:center;opacity:.7}`\n\t);\n}\n\n// Client-side browser code for the JS widget variant.\n// Stored as a string: TypeScript never type-checks browser code running in DOM context.\nconst ADV_CLIENT_CODE = `\n(function(){\nfunction esc(s){return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');}\nvar MODAL_CSS='.advmodaljs{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}.advbackdropjs{position:absolute;inset:0;background:transparent;cursor:pointer}.advboxjs{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,900px);background:#1c1c1e;padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}.advvideojs{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}.advclosejs{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}.advinfojs{color:#fff;font-size:.8rem;text-align:center}';\nvar modalEl=null,modalVideo=null,modalInfo=null,modalBox=null;\nfunction getModal(){\n if(modalEl&&document.body.contains(modalEl))return modalEl;\n if(!document.getElementById('advmodalcss')){var st=document.createElement('style');st.id='advmodalcss';st.textContent=MODAL_CSS;document.head.appendChild(st);}\n modalEl=document.createElement('div');modalEl.className='advmodaljs';\n var bd=document.createElement('div');bd.className='advbackdropjs';\n modalBox=document.createElement('div');modalBox.className='advboxjs';\n var cl=document.createElement('span');cl.className='advclosejs';cl.textContent='\u2715';\n modalVideo=document.createElement('video');modalVideo.className='advvideojs';\n modalVideo.setAttribute('controls','');modalVideo.setAttribute('preload','none');modalVideo.setAttribute('playsinline','');\n modalInfo=document.createElement('div');modalInfo.className='advinfojs';\n modalBox.appendChild(cl);modalBox.appendChild(modalVideo);modalBox.appendChild(modalInfo);\n modalEl.appendChild(bd);modalEl.appendChild(modalBox);\n document.body.appendChild(modalEl);\n bd.addEventListener('click',closeModal);cl.addEventListener('click',closeModal);\n return modalEl;\n}\nfunction openSrc(src,label,maxW){\n var m=getModal();\n if(maxW)modalBox.style.maxWidth='min(92vw,'+maxW+'px)';\n modalVideo.setAttribute('src',src);modalInfo.textContent=label;m.style.display='flex';\n}\nfunction closeModal(){\n if(!modalEl)return;\n try{modalVideo.pause();}catch(e){}\n modalVideo.removeAttribute('src');try{modalVideo.load();}catch(e){}\n modalEl.style.display='none';\n}\ndocument.addEventListener('keydown',function(e){if(e.key==='Escape'||e.keyCode===27)closeModal();});\nfunction initRoot(root){\n var dataEl=root.querySelector('script.advdata');\n if(!dataEl)return;\n var D;try{D=JSON.parse(dataEl.textContent);}catch(e){return;}\n var cfg=D.cfg||{},items=D.items||[],live=D.live||null;\n var grid=root.querySelector('.advgridjs'),search=root.querySelector('.advsearchjs'),tagsBox=root.querySelector('.advtagsjs');\n var state={q:'',tag:cfg.default_tag||''};\n var tagset={};\n items.forEach(function(it){String(it.tag||'').split(/[,\\\\s]+/).forEach(function(t){if(t)tagset[t]=1;});});\n var tags=Object.keys(tagset);\n if(cfg.show_tags&&tags.length){\n var mk=function(label,val){\n var b=document.createElement('button');b.className='advtagbtn';b.textContent=label;b.setAttribute('data-tag',val);\n b.addEventListener('click',function(){state.tag=state.tag===val?'':val;updateTagBtns();render();});\n tagsBox.appendChild(b);\n };\n mk(cfg.labels&&cfg.labels.all||'All','');tags.forEach(function(t){mk(t,t);});\n }\n function updateTagBtns(){var bs=tagsBox.querySelectorAll('.advtagbtn');for(var i=0;i<bs.length;i++)bs[i].classList.toggle('on',bs[i].getAttribute('data-tag')===state.tag);}\n updateTagBtns();\n if(search)search.addEventListener('input',function(){state.q=this.value.toLowerCase();render();});\n function badge(it){if(!(cfg.show_tags&&it.tag))return '';var pos=String(cfg.tag_position||'bottom-left').split('-');return '<span class=\"advtagjs\" style=\"'+pos[0]+':5px;'+pos[1]+':5px\">'+esc(it.tag)+'</span>';}\n function render(){\n var html='';\n if(live){var ar=cfg.live_aspect||'',arStyle=ar?' style=\"aspect-ratio:'+ar.replace('/',' / ')+'\"':'',arCls=ar?' advimgfix':'';\n html+='<div class=\"advcelljs\" data-live=\"1\"><span class=\"advimgjs'+arCls+'\"'+arStyle+'><img loading=\"lazy\" src=\"'+esc(live.thumb)+'\"><span class=\"advtagjs\" style=\"top:5px;left:5px\">&#9679; '+(cfg.labels&&cfg.labels.live||'LIVE')+'</span><span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(live.name)+'</span></div>';}\n items.forEach(function(it,i){\n if(state.tag&&String(it.tag||'').toLowerCase().indexOf(state.tag.toLowerCase())<0)return;\n if(state.q){var hay=((it.date||'')+' '+(it.time||'')+' '+(it.tag||'')).toLowerCase();if(hay.indexOf(state.q)<0)return;}\n html+='<div class=\"advcelljs\" data-i=\"'+i+'\"><span class=\"advimgjs\"><img loading=\"lazy\" src=\"'+esc(it.thumb)+'\">'+badge(it)+'<span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(it.date)+' '+esc(it.time)+'<br>'+esc(it.dur)+'s &middot; '+esc(it.size)+' MB</span></div>';\n });\n grid.innerHTML=html||'<div class=\"advemptyjs\">'+(cfg.labels&&cfg.labels.noRecordings||'No recordings')+'</div>';\n var cells=grid.querySelectorAll('.advcelljs');\n for(var k=0;k<cells.length;k++)(function(cell){\n cell.addEventListener('click',function(){\n if(cell.getAttribute('data-live')==='1'){openSrc(live.video,(live.name||'')+' \u00B7 Live',cfg.max_modal_width);return;}\n var it=items[parseInt(cell.getAttribute('data-i'),10)],maxW=Number(cfg.max_modal_width)||900;\n if(cfg.player_url){var u=cfg.player_url.replace(/{video}/g,encodeURIComponent(it.video)).replace(/{videoRaw}/g,it.video).replace(/{fn}/g,encodeURIComponent(it.fn||'')).replace(/{date}/g,encodeURIComponent(it.date)).replace(/{time}/g,encodeURIComponent(it.time)).replace(/{duration}/g,encodeURIComponent(it.dur)).replace(/{size}/g,encodeURIComponent(it.size)).replace(/{tags}/g,encodeURIComponent(it.tag));window.open(u,'_blank');}\n else{openSrc(it.video,esc(it.date)+' '+esc(it.time)+(it.dur!=null?' \u00B7 '+it.dur+'s':'')+(it.size!=null?' \u00B7 '+it.size+' MB':'')+(it.tag?' \u00B7 '+it.tag:''),maxW);}\n });\n })(cells[k]);\n }\n render();\n}\nfunction scan(){var roots=document.querySelectorAll('.advroot');for(var i=0;i<roots.length;i++)if(!roots[i].__adv){roots[i].__adv=1;initRoot(roots[i]);}}\nwindow.ADVscan=scan;scan();\n})();\n`.trim();\n\n// ---- Adapter class ----\n\nclass AgentDvr extends utils.Adapter {\n\tprivate pollTimer: ioBroker.Interval | undefined = undefined;\n\tprivate refreshTimer: ioBroker.Timeout | undefined = undefined;\n\tprivate authHeader: string | null = null;\n\tprivate baseUrl = '';\n\tprivate wt: WidgetLabels = getWidgetLabels('en');\n\n\tprivate readonly ensuredFolders = new Set<string>();\n\tprivate readonly registry = new Map<string, RegistryEntry>();\n\tprivate readonly ptzActive = new Map<string | number, string>();\n\tprivate readonly widgetSig: Record<string, string> = {};\n\tprivate profileSig = '';\n\tprivate readonly lastEventFn: Record<string | number, string> = {};\n\tprivate readonly camAspect: Record<string | number, string> = {};\n\tprivate readonly devById = new Map<string | number, Device>();\n\tprivate readonly eventBusy: Record<string | number, boolean> = {};\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({ ...options, name: 'agent-dvr' });\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('message', this.onMessage.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t// ---- lifecycle ----\n\n\tprivate async ensureWebInstance(): Promise<void> {\n\t\tconst instanceId = `system.adapter.${this.namespace}`;\n\t\tconst obj = await this.getForeignObjectAsync(instanceId);\n\t\tif (obj && !obj.native?.webInstance) {\n\t\t\tawait this.extendForeignObjectAsync(instanceId, { native: { webInstance: '*' } });\n\t\t\tthis.log.info('webInstance set \u2014 web adapter will reload the extension');\n\t\t}\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tvoid this.setState('info.connection', false, true);\n\t\tawait this.ensureWebInstance();\n\n\t\tconst sysConfig = await this.getForeignObjectAsync('system.config');\n\t\tconst rawLang = (sysConfig?.common as unknown as { language?: string } | undefined)?.language;\n\t\tthis.wt = getWidgetLabels(rawLang ?? 'en');\n\n\t\tconst pollSeconds = Math.max(5, Math.min(3600, this.config.pollSeconds || 30));\n\t\tthis.baseUrl = `http://${this.config.ip}:${this.config.port || 8090}`;\n\n\t\tif (this.config.user || this.config.pass) {\n\t\t\tthis.authHeader = `Basic ${Buffer.from(`${this.config.user}:${this.config.pass}`).toString('base64')}`;\n\t\t}\n\n\t\tawait this.buildSystem();\n\t\ttry {\n\t\t\tawait this.poll();\n\t\t} catch (e) {\n\t\t\tthis.log.warn(`First poll error: ${(e as Error).message}`);\n\t\t}\n\n\t\tthis.pollTimer = this.setInterval(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Poll error: ${(e as Error).message}`)),\n\t\t\tpollSeconds * 1000,\n\t\t);\n\n\t\tthis.subscribeStates('*');\n\t\tthis.log.info(`Agent DVR adapter ready. Polling ${this.baseUrl} every ${pollSeconds}s.`);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.pollTimer !== undefined) {\n\t\t\t\tthis.clearInterval(this.pollTimer);\n\t\t\t\tthis.pollTimer = undefined;\n\t\t\t}\n\t\t\tif (this.refreshTimer !== undefined) {\n\t\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\t\tthis.refreshTimer = undefined;\n\t\t\t}\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t\tcallback();\n\t}\n\n\tprivate onMessage(obj: ioBroker.Message): void {\n\t\tif (!obj || obj.command !== 'getGo2rtcStreams') {\n\t\t\treturn;\n\t\t}\n\t\tvoid this.fetchGo2rtcStreams().then(streams => {\n\t\t\tthis.sendTo(obj.from, obj.command, { streams }, obj.callback);\n\t\t});\n\t}\n\n\tprivate fetchGo2rtcStreams(): Promise<string[]> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst url = this.config.go2rtcUrl;\n\t\t\tif (!url) {\n\t\t\t\tresolve([]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet target: URL;\n\t\t\ttry {\n\t\t\t\ttarget = new URL('/api/streams', url);\n\t\t\t} catch {\n\t\t\t\tresolve([]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst mod = target.protocol === 'https:' ? https : http;\n\t\t\tconst req = mod.get(target.toString(), res => {\n\t\t\t\tlet body = '';\n\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\tbody += c.toString();\n\t\t\t\t});\n\t\t\t\tres.on('end', () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresolve(Object.keys(JSON.parse(body) || {}));\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tresolve([]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tres.on('error', () => resolve([]));\n\t\t\t});\n\t\t\treq.setTimeout(4000, () => {\n\t\t\t\treq.destroy();\n\t\t\t});\n\t\t\treq.on('error', () => resolve([]));\n\t\t});\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (!state || state.ack !== false) {\n\t\t\treturn;\n\t\t}\n\t\tconst relId = this.getRelId(id);\n\t\tconst entry = this.registry.get(relId);\n\t\tif (entry) {\n\t\t\tthis.runCommand(relId, entry, state.val).catch(e =>\n\t\t\t\tthis.log.warn(`Command error: ${(e as Error).message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- helpers ----\n\n\tprivate getRelId(fullId: string): string {\n\t\treturn fullId.startsWith(`${this.namespace}.`) ? fullId.slice(this.namespace.length + 1) : fullId;\n\t}\n\n\tprivate apiGet(path: string): Promise<ApiResult> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tlet data = '';\n\t\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\t\tdata += c.toString();\n\t\t\t\t\t});\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate apiGetBuffer(path: string): Promise<{ ok: boolean; data?: Buffer; error?: string }> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\tres.on('data', (c: Buffer) => chunks.push(c));\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data: Buffer.concat(chunks) });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async ensureFolder(id: string, name: string, type: 'device' | 'channel' = 'channel'): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setObjectNotExistsAsync(id, { type, common: { name }, native: {} });\n\t\tthis.ensuredFolders.add(id);\n\t}\n\n\tprivate async ensurePath(fullId: string): Promise<void> {\n\t\tconst parts = fullId.split('.');\n\t\tlet acc = parts[0];\n\t\tfor (let i = 1; i < parts.length - 1; i++) {\n\t\t\tacc += `.${parts[i]}`;\n\t\t\tif (!this.ensuredFolders.has(acc)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(acc, { type: 'channel', common: { name: parts[i] }, native: {} });\n\t\t\t\tthis.ensuredFolders.add(acc);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate guessRole(id: string, val: unknown): ioBroker.CommonType {\n\t\tif (typeof val === 'string' && /^https?:\\/\\//i.test(val)) {\n\t\t\treturn 'string';\n\t\t}\n\t\treturn 'string';\n\t}\n\n\tprivate async writeLeaf(id: string, val: unknown): Promise<void> {\n\t\tconst t = typeof val;\n\t\tlet common: ioBroker.StateCommon;\n\t\tif (t === 'boolean') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'boolean', role: 'indicator', read: true, write: false };\n\t\t} else if (t === 'number') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'number', role: 'value', read: true, write: false };\n\t\t} else {\n\t\t\tconst role = typeof val === 'string' && /^https?:\\/\\//i.test(val) ? 'text.url' : 'text';\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'string', role, read: true, write: false };\n\t\t}\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, { type: 'state', common, native: {} });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tawait this.setStateAsync(id, { val: (val === undefined ? null : val) as ioBroker.StateValue, ack: true });\n\t}\n\n\tprivate async flattenWrite(obj: unknown, prefix: string, depth: number): Promise<void> {\n\t\tconst maxDepth = Math.max(1, Math.min(10, this.config.maxDepth || 6));\n\t\tconst maxArray = Math.max(1, Math.min(500, this.config.maxArray || 30));\n\t\tif (depth > maxDepth) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj === null || obj === undefined) {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof obj === 'object') {\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tif (obj.length > maxArray) {\n\t\t\t\t\tawait this.writeLeaf(`${prefix}.count`, obj.length);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\t\t\tawait this.flattenWrite(obj[i], `${prefix}.${i}`, depth + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const k of Object.keys(obj)) {\n\t\t\t\t\tif (SKIP_KEYS.includes(k)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.flattenWrite((obj as Record<string, unknown>)[k], `${prefix}.${sanitize(k)}`, depth + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t}\n\t}\n\n\tprivate async ensureControl(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\trole: 'button' | 'switch',\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'boolean', role, read: role === 'switch', write: true, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate ensureButton(id: string, name: string, entry: RegistryEntry): Promise<void> {\n\t\treturn this.ensureControl(id, name, entry, 'button');\n\t}\n\n\tprivate async ensureSelector(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\tstates: Record<number, string>,\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'number', role: 'level', read: true, write: true, states },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: 0, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate async fetchSnapshotB64(oid: number | string, snapId: string): Promise<void> {\n\t\tconst imgRes = await this.apiGetBuffer(`/photo.jpg?oid=${oid}`);\n\t\tif (imgRes.ok && imgRes.data) {\n\t\t\tawait this.setStateAsync(snapId, {\n\t\t\t\tval: `data:image/jpeg;base64,${imgRes.data.toString('base64')}`,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async ensureFlag(id: string, name: string): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.ensurePath(id);\n\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name, type: 'boolean', role: 'indicator', read: true, write: false, def: false },\n\t\t\tnative: {},\n\t\t});\n\t\tthis.ensuredFolders.add(id);\n\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t}\n\n\tprivate async pulse(id: string): Promise<void> {\n\t\tawait this.setStateAsync(id, { val: true, ack: true });\n\t\tthis.setTimeout(() => this.setStateAsync(id, { val: false, ack: true }).catch(() => {}), 1500);\n\t}\n\n\t// ---- system structure ----\n\n\tprivate async buildSystem(): Promise<void> {\n\t\tawait this.ensureFolder('system', 'System', 'channel');\n\t\tawait this.writeLeaf('system.online', false);\n\t\tawait this.writeLeaf('system.lastUpdate', '');\n\t\tawait this.writeLeaf('system.lastPoll', 0);\n\t\tawait this.writeLeaf('system.cameraCount', 0);\n\n\t\tif (this.config.enableSystemControls) {\n\t\t\tawait this.ensureFolder('system.control', 'Control', 'channel');\n\t\t\tfor (const c of SYS_COMMANDS) {\n\t\t\t\tawait this.ensureButton(`system.control.${c.id}`, c.name, { kind: 'sys', path: c.path });\n\t\t\t}\n\t\t\tawait this.ensureFolder('system.profile', 'Profile', 'channel');\n\t\t\tawait this.ensureSelector(\n\t\t\t\t'system.profile.selector',\n\t\t\t\t'Active profile',\n\t\t\t\t{ kind: 'setProfile' },\n\t\t\t\t{ 0: 'Home', 1: 'Away', 2: 'Night' },\n\t\t\t);\n\t\t\tif (!this.ensuredFolders.has('system.profile.list')) {\n\t\t\t\tawait this.setObjectNotExistsAsync('system.profile.list', {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Available profiles (JSON)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'json',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add('system.profile.list');\n\t\t\t\tawait this.setStateAsync('system.profile.list', { val: '[]', ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---- camera aspect detection ----\n\n\tprivate async detectAspect(d: Device): Promise<void> {\n\t\tif (this.camAspect[d.oid] !== undefined) {\n\t\t\treturn;\n\t\t}\n\t\tlet wh = findWH(d.raw, 0);\n\t\tif (!wh) {\n\t\t\tconst res = await this.apiGet(`/command/getObject?oid=${d.oid}&ot=2`);\n\t\t\tconst j = asJson(res.data);\n\t\t\tif (j) {\n\t\t\t\twh = findWH(j, 0);\n\t\t\t}\n\t\t}\n\t\tthis.camAspect[d.oid] = wh ? `${wh[0]}/${wh[1]}` : '';\n\t\tif (wh) {\n\t\t\tthis.log.debug(`cam ${d.oid} resolution ${wh[0]}x${wh[1]} -> AR ${this.camAspect[d.oid]}`);\n\t\t}\n\t}\n\n\t// ---- device folder name ----\n\n\tprivate deviceFolder(d: Device): string {\n\t\treturn `${d.ot === 1 ? 'mic' : 'cam'}_${sanitize(d.oid)}_${sanitize(d.name)}`;\n\t}\n\n\t// ---- device status data points ----\n\n\tprivate readonly STATUS_DPS = [\n\t\t{ key: 'recording', role: 'indicator.working', name: 'Active recording' },\n\t\t{ key: 'online', role: 'indicator.reachable', name: 'Online' },\n\t\t{ key: 'connected', role: 'indicator.connected', name: 'Stream connected' },\n\t\t{ key: 'detected', role: 'indicator', name: 'Motion detected' },\n\t\t{ key: 'alerted', role: 'indicator.alarm', name: 'Alert active' },\n\t] as const;\n\n\tprivate async writeStatusDps(d: Device, fid: string): Promise<void> {\n\t\tconst data = d.raw.data as Record<string, unknown> | undefined;\n\t\tif (!data || typeof data !== 'object') {\n\t\t\treturn;\n\t\t}\n\t\tconst sfid = `${fid}.status`;\n\t\tif (!this.ensuredFolders.has(sfid)) {\n\t\t\tawait this.ensureFolder(sfid, 'Status', 'channel');\n\t\t}\n\t\tfor (const dp of this.STATUS_DPS) {\n\t\t\tif (!(dp.key in data)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = `${sfid}.${dp.key}`;\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: dp.name, type: 'boolean', role: dp.role, read: true, write: false, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: !!data[dp.key], ack: true });\n\t\t}\n\t}\n\n\t// ---- build device data points ----\n\n\tprivate async buildDevice(d: Device): Promise<void> {\n\t\tconst fid = this.deviceFolder(d);\n\t\tthis.devById.set(d.oid, d);\n\n\t\tawait this.ensureFolder(fid, d.name, 'device');\n\t\tif (d.ot === 2) {\n\t\t\tawait this.detectAspect(d);\n\t\t}\n\t\tawait this.flattenWrite(d.raw, fid, 0);\n\t\tawait this.writeStatusDps(d, fid);\n\n\t\tawait this.ensureFolder(`${fid}.control`, 'Control', 'channel');\n\t\tfor (const c of CAM_COMMANDS) {\n\t\t\tif (c.id === 'snapshot' && d.ot !== 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.${c.id}`, c.name, {\n\t\t\t\tkind: 'cam',\n\t\t\t\tpath: c.path,\n\t\t\t\tparams: [...c.params],\n\t\t\t\toid: d.oid,\n\t\t\t\tot: d.ot,\n\t\t\t});\n\t\t}\n\n\t\tif (this.config.enablePtz && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.control.ptz`, 'PTZ', 'channel');\n\t\t\tfor (const p of PTZ_DIRS) {\n\t\t\t\tconst cid = `${fid}.control.ptz.${p.id}`;\n\t\t\t\tif (p.hold) {\n\t\t\t\t\tawait this.ensureControl(\n\t\t\t\t\t\tcid,\n\t\t\t\t\t\t`PTZ ${p.id} (hold)`,\n\t\t\t\t\t\t{ kind: 'ptzHold', oid: d.oid, dir: p.dir },\n\t\t\t\t\t\t'switch',\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.ensureButton(cid, `PTZ ${p.id}`, { kind: 'ptz', oid: d.oid, dir: p.dir });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.config.enableUrls && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.urls`, 'URLs', 'channel');\n\t\t\tawait this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);\n\t\t}\n\n\t\tif (d.ot === 2) {\n\t\t\tconst snapId = `${fid}.snapshot_b64`;\n\t\t\tif (!this.ensuredFolders.has(snapId)) {\n\t\t\t\tawait this.ensurePath(snapId);\n\t\t\t\tawait this.setObjectNotExistsAsync(snapId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Snapshot (Base64)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(snapId, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(snapId);\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.refreshSnapshotB64`, 'Refresh snapshot (Base64)', {\n\t\t\t\tkind: 'snapshotB64',\n\t\t\t\toid: d.oid,\n\t\t\t\tfid,\n\t\t\t});\n\t\t\tif (this.config.enableSnapshotB64) {\n\t\t\t\tawait this.fetchSnapshotB64(d.oid, snapId);\n\t\t\t}\n\t\t}\n\n\t\tawait this.updateCameraEvents(d, fid);\n\t}\n\n\t// ---- event formatting ----\n\n\tprivate fmtEvent(\n\t\tev: Record<string, unknown>,\n\t\toid: number | string,\n\t): {\n\t\tfn: string;\n\t\tsizeMB: number;\n\t\tdur: string;\n\t\ttag: string;\n\t\tdate: string;\n\t\ttime: string;\n\t\tthumb: string;\n\t\tvideo: string;\n\t} {\n\t\tconst e = ev as AgentDvrEvent;\n\t\tconst fn = e.fn ?? '';\n\t\tconst dot = fn.lastIndexOf('.');\n\t\tconst jpg = `${dot > 0 ? fn.slice(0, dot) : fn}_large.jpg`;\n\t\tconst sizeMB = e.sb ? Math.round((Number(e.sb) / 1048576) * 100) / 100 : 0;\n\t\tconst dur = e.d != null ? String(e.d) : '';\n\t\tconst tag = e.tg ?? '';\n\t\tconst ms = (parseFloat(String(e.c ?? 0)) - 621355968000000000) / 10000;\n\t\tconst dt = new Date(ms);\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst date = `${two(dt.getDate())}.${two(dt.getMonth() + 1)}.`;\n\t\tconst time = `${two(dt.getHours())}:${two(dt.getMinutes())}`;\n\t\tconst thumb = `${this.baseUrl}/fileThumb.jpg?oid=${oid}&fn=${encodeURIComponent(jpg)}`;\n\t\tconst video = `${this.baseUrl}/streamFile.cgi?oid=${oid}&ot=2&fn=${encodeURIComponent(fn)}`;\n\t\treturn { fn, sizeMB, dur, tag, date, time, thumb, video };\n\t}\n\n\t// ---- gallery HTML builders ----\n\n\tprivate effectiveMinCol(): number {\n\t\tconst sizeMap: Record<string, number> = { small: 120, medium: 180, large: 240 };\n\t\tconst ts = this.config.widgetThumbSize;\n\t\treturn ts && sizeMap[ts] ? sizeMap[ts] : this.config.widgetMinCol || 150;\n\t}\n\n\tprivate async pruneStaleDevices(activeFolders: Set<string>): Promise<void> {\n\t\tconst allObjs = await this.getAdapterObjectsAsync();\n\t\tconst stale: string[] = [];\n\t\tfor (const fullId of Object.keys(allObjs)) {\n\t\t\tconst obj = allObjs[fullId];\n\t\t\tif (obj.type !== 'device') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst rel = fullId.slice(this.namespace.length + 1);\n\t\t\tif (/^(cam|mic)_/.test(rel) && !activeFolders.has(rel)) {\n\t\t\t\tstale.push(rel);\n\t\t\t}\n\t\t}\n\t\tfor (const rel of stale) {\n\t\t\tthis.log.info(`[agent-dvr] removing stale device: ${rel}`);\n\t\t\tawait this.delObjectAsync(rel, { recursive: true });\n\t\t\t// clean up internal cache\n\t\t\tfor (const [oid, d] of this.devById) {\n\t\t\t\tif (this.deviceFolder(d) === rel) {\n\t\t\t\t\tthis.devById.delete(oid);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sortedEvents(events: Record<string, unknown>[]): Record<string, unknown>[] {\n\t\t// newest-first by default; widgetSortNewest=false reverses to oldest-first\n\t\treturn this.config.widgetSortNewest === false ? [...events].reverse() : events;\n\t}\n\n\tprivate buildGalleryHtml(d: Device, events: Record<string, unknown>[]): string {\n\t\treturn (this.config.widgetMode || 'nojs') === 'js'\n\t\t\t? this.buildGalleryHtmlJs(d, events)\n\t\t\t: this.buildGalleryHtmlNojs(d, events);\n\t}\n\n\tprivate buildGalleryHtmlNojs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showTags = this.config.widgetShowTags;\n\t\tconst pos = (this.config.widgetTagPosition || 'bottom-left').split('-');\n\t\tconst tagStyle = `${pos[0]}:5px;${pos[1]}:5px`;\n\t\tconst playerUrl = (this.config.widgetPlayerUrl || '').trim();\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\n\t\tconst items = this.sortedEvents(events)\n\t\t\t.map((ev, i) => {\n\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\tconst id = `adv${sanitize(oid)}_${i}`;\n\t\t\t\tconst badge =\n\t\t\t\t\tshowTags && p.tag ? `<span class=\"advtag\" style=\"${tagStyle}\">${escHtml(p.tag)}</span>` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg\"><img src=\"${p.thumb}\" loading=\"lazy\" alt=\"\">${badge}<span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${escHtml(p.date)} ${escHtml(p.time)}<br>${escHtml(p.dur)}s &middot; ${escHtml(p.sizeMB)} MB</span>`;\n\t\t\t\tif (playerUrl) {\n\t\t\t\t\tconst href = playerUrl\n\t\t\t\t\t\t.replace(/{video}/g, encodeURIComponent(p.video))\n\t\t\t\t\t\t.replace(/{videoRaw}/g, p.video)\n\t\t\t\t\t\t.replace(/{fn}/g, encodeURIComponent(p.fn))\n\t\t\t\t\t\t.replace(/{date}/g, encodeURIComponent(p.date))\n\t\t\t\t\t\t.replace(/{time}/g, encodeURIComponent(p.time))\n\t\t\t\t\t\t.replace(/{duration}/g, encodeURIComponent(p.dur))\n\t\t\t\t\t\t.replace(/{size}/g, encodeURIComponent(String(p.sizeMB)))\n\t\t\t\t\t\t.replace(/{tags}/g, encodeURIComponent(p.tag));\n\t\t\t\t\treturn `<a class=\"advcell\" href=\"${escHtml(href)}\" target=\"_blank\" rel=\"noopener\">${inner}</a>`;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">&#10005;</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${p.video}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${escHtml(p.date)} ${escHtml(p.time)} &middot; ${escHtml(p.dur)}s &middot; ${escHtml(p.sizeMB)} MB${\n\t\t\t\t\t\tp.tag ? ` &middot; ${escHtml(p.tag)}` : ''\n\t\t\t\t\t} &middot; <a href=\"${p.video}\" download target=\"_blank\">${this.wt.download}</a></div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\n\t\tconst gridClass = compact ? 'advgrid advcompact' : 'advgrid';\n\t\tconst grid = items\n\t\t\t? `<div class=\"${gridClass}\">${items}</div>`\n\t\t\t: `<div class=\"advempty\">${this.wt.noRecordings}</div>`;\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn `<style>${galleryCss(minCol, maxW, compact, colors)}</style>${grid}`;\n\t}\n\n\tprivate buildGalleryHtmlJs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showSearch = this.config.widgetShowSearch !== false;\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst defaultTag = (this.config.widgetDefaultTag || '').trim();\n\t\tconst items = this.sortedEvents(events).map(ev => {\n\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\treturn {\n\t\t\t\tfn: p.fn,\n\t\t\t\tdate: p.date,\n\t\t\t\ttime: p.time,\n\t\t\t\tdur: p.dur,\n\t\t\t\tsize: p.sizeMB,\n\t\t\t\ttag: p.tag,\n\t\t\t\tthumb: p.thumb,\n\t\t\t\tvideo: p.video,\n\t\t\t};\n\t\t});\n\t\tconst cfg = {\n\t\t\tmin_col: minCol,\n\t\t\tshow_tags: !!this.config.widgetShowTags,\n\t\t\tmax_modal_width: maxW,\n\t\t\tlive_aspect: this.camAspect[oid] || this.config.widgetLiveAspect || '',\n\t\t\tplayer_url: (this.config.widgetPlayerUrl || '').trim(),\n\t\t\ttag_position: this.config.widgetTagPosition || 'bottom-left',\n\t\t\tcompact,\n\t\t\tdefault_tag: defaultTag,\n\t\t\tlabels: { noRecordings: this.wt.noRecordings, all: this.wt.all, live: this.wt.live },\n\t\t};\n\t\tconst data = JSON.stringify({ items, live: null, cfg }).replace(/</g, '\\\\u003c');\n\t\tconst boot = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\t\tconst searchHtml = showSearch\n\t\t\t? `<input class=\"advsearchjs\" type=\"text\" placeholder=\"${escHtml(this.wt.search)}\">`\n\t\t\t: '';\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn (\n\t\t\t`<style>${galleryCssJs(minCol, compact, colors)}</style>` +\n\t\t\t`<div class=\"advroot\"><script type=\"application/json\" class=\"advdata\">${data}</script>` +\n\t\t\t`<div class=\"advbar\">${searchHtml}<div class=\"advtagsjs\"></div></div>` +\n\t\t\t`<div class=\"advgridjs\"></div></div>` +\n\t\t\t`<script type=\"text/plain\" class=\"advcode\">${ADV_CLIENT_CODE}</script>` +\n\t\t\t`<img alt=\"\" src=\"${boot}\" style=\"display:none\" onload=\"(function(){if(window.ADVscan){window.ADVscan();return;}var c=document.querySelector('script.advcode');if(!c)return;var s=document.createElement('script');s.textContent=c.textContent;document.body.appendChild(s);})()\">`\n\t\t);\n\t}\n\n\tprivate buildOverviewHtml(cams: Device[]): string {\n\t\tconst ts = Date.now();\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\t\tconst tiles = cams\n\t\t\t.map(d => {\n\t\t\t\tconst oid = d.oid;\n\t\t\t\tconst id = `advlive${sanitize(oid)}`;\n\t\t\t\tconst grab = `${this.baseUrl}/grab.jpg?oid=${oid}&ot=2&maintainAR=1&ts=${ts}`;\n\t\t\t\tconst webm = `${this.baseUrl}/video.webm?oid=${oid}&ot=2`;\n\t\t\t\tconst name = escHtml(d.name || `Camera ${oid}`);\n\t\t\t\tconst arRaw = this.camAspect[oid] || this.config.widgetLiveAspect || '';\n\t\t\t\tconst ar = arRaw ? String(arRaw).replace('/', ' / ') : '';\n\t\t\t\tconst fix = ar ? ' advimgfix' : '';\n\t\t\t\tconst arStyle = ar ? ` style=\"aspect-ratio:${ar}\"` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg${fix}\"${arStyle}><img src=\"${grab}\" loading=\"lazy\" alt=\"\">` +\n\t\t\t\t\t`<span class=\"advtag\" style=\"top:5px;left:5px\">&#9679; ${escHtml(this.wt.live)}</span><span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${name}</span>`;\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">&#10005;</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${webm}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${name} &middot; Live</div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\t\tconst grid = tiles ? `<div class=\"advgrid\">${tiles}</div>` : `<div class=\"advempty\">No cameras</div>`;\n\t\treturn `<style>${galleryCss(minCol, maxW)}</style>${grid}`;\n\t}\n\n\t// ---- event data points ----\n\n\tprivate async writeEventDps(d: Device, fid: string, events: Record<string, unknown>[]): Promise<void> {\n\t\tconst oid = d.oid;\n\t\tawait this.ensureFolder(`${fid}.events`, 'Events', 'channel');\n\t\tawait this.ensureFolder(`${fid}.events.last`, 'Last event', 'channel');\n\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst now = new Date();\n\t\tconst td = `${two(now.getDate())}.${two(now.getMonth() + 1)}.`;\n\t\tconst todayCount = events.filter(ev => this.fmtEvent(ev, oid).date === td).length;\n\n\t\tawait this.writeLeaf(`${fid}.events.count`, events.length);\n\t\tawait this.writeLeaf(`${fid}.events.today`, todayCount);\n\n\t\tif (events.length) {\n\t\t\tconst p = this.fmtEvent(events[0], oid);\n\t\t\tconst tsMs = (parseFloat(String((events[0] as AgentDvrEvent).c ?? 0)) - 621355968000000000) / 10000;\n\t\t\tawait this.writeLeaf(`${fid}.events.last.time`, `${p.date} ${p.time}`);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.timestamp`, Math.round(tsMs));\n\t\t\tawait this.writeLeaf(`${fid}.events.last.tag`, p.tag);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.duration`, p.dur ? parseFloat(p.dur) : 0);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.size_mb`, p.sizeMB);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.thumb`, p.thumb);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.video`, p.video);\n\t\t}\n\n\t\t// JSON list for web UI \u2014 browser never needs to talk to AgentDVR for recordings\n\t\tconst jsonId = `${fid}.events.json`;\n\t\tif (!this.ensuredFolders.has(jsonId)) {\n\t\t\tawait this.ensurePath(jsonId);\n\t\t\tawait this.setObjectNotExistsAsync(jsonId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: 'Recordings list (web UI)', type: 'string', role: 'json', read: true, write: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tthis.ensuredFolders.add(jsonId);\n\t\t}\n\t\tawait this.setStateAsync(jsonId, {\n\t\t\tval: JSON.stringify(\n\t\t\t\tevents.slice(0, Math.max(1, this.config.widgetAnzahl || 50)).map(ev => {\n\t\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdate: p.date,\n\t\t\t\t\t\ttime: p.time,\n\t\t\t\t\t\tdur: p.dur,\n\t\t\t\t\t\tsize: p.sizeMB,\n\t\t\t\t\t\ttag: p.tag,\n\t\t\t\t\t\tthumb: p.thumb,\n\t\t\t\t\t\tvideo: p.video,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t),\n\t\t\tack: true,\n\t\t});\n\n\t\tawait this.ensureFlag(`${fid}.events.new`, 'New event');\n\n\t\tif (this.config.enablePush) {\n\t\t\tconst pid = `${fid}.events.pushTrigger`;\n\t\t\tif (!this.ensuredFolders.has(pid)) {\n\t\t\t\tawait this.ensurePath(pid);\n\t\t\t\tawait this.setObjectNotExistsAsync(pid, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Push trigger (AgentDVR action)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'text',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(pid, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(pid);\n\t\t\t}\n\t\t\tthis.registry.set(pid, { kind: 'push', oid, fid });\n\t\t}\n\n\t\tconst ignore = (this.config.eventTagsIgnore || 'detected')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim().toLowerCase())\n\t\t\t.filter(Boolean);\n\t\tconst tokensOf = (s: string): string[] =>\n\t\t\ts\n\t\t\t\t.toLowerCase()\n\t\t\t\t.split(/[,\\s]+/)\n\t\t\t\t.filter(Boolean);\n\n\t\tfor (const kw of (this.config.eventTags || '')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(Boolean)) {\n\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(kw)}`, `Detected: ${kw}`);\n\t\t}\n\n\t\tif (this.config.eventTagsDynamic) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const ev of events) {\n\t\t\t\ttokensOf((ev as AgentDvrEvent).tg ?? '').forEach(t => seen.add(t));\n\t\t\t}\n\t\t\tfor (const t of seen) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(t)}`, `Detected: ${t}`);\n\t\t\t}\n\t\t}\n\n\t\tlet newCount = 0;\n\t\tif (events.length) {\n\t\t\tconst prev = this.lastEventFn[oid];\n\t\t\tif (prev !== undefined) {\n\t\t\t\tconst i = events.findIndex(e => (e as AgentDvrEvent).fn === prev);\n\t\t\t\tnewCount = i === -1 ? events.length : i;\n\t\t\t}\n\t\t\tthis.lastEventFn[oid] = (events[0] as AgentDvrEvent).fn ?? '';\n\t\t}\n\n\t\tif (newCount > 0) {\n\t\t\tawait this.pulse(`${fid}.events.new`);\n\t\t\tconst tags = new Set<string>();\n\t\t\tfor (let i = 0; i < newCount && i < events.length; i++) {\n\t\t\t\ttokensOf((events[i] as AgentDvrEvent).tg ?? '').forEach(t => tags.add(t));\n\t\t\t}\n\t\t\tfor (const t of tags) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst tid = `${fid}.events.detected_${sanitize(t)}`;\n\t\t\t\tawait this.ensureFlag(tid, `Detected: ${t}`);\n\t\t\t\tawait this.pulse(tid);\n\t\t\t}\n\t\t\tthis.log.debug(`${newCount} new event(s) cam ${oid} [${[...tags].join(',')}]`);\n\t\t}\n\t}\n\n\t// ---- camera events + widget ----\n\n\tprivate async updateCameraEvents(d: Device, fid: string): Promise<void> {\n\t\tif (d.ot !== 2) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.config.enableWidget && !this.config.enableEventDps) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.eventBusy[d.oid]) {\n\t\t\treturn;\n\t\t}\n\t\tthis.eventBusy[d.oid] = true;\n\t\ttry {\n\t\t\tconst evRes = await this.apiGet(`/q/getEvents?oid=${d.oid}&ot=2`);\n\t\t\tconst evJson = asJson(evRes.data);\n\t\t\tif (!evJson) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst events = (\n\t\t\t\tArray.isArray(evJson.events) ? evJson.events : Array.isArray(evJson) ? evJson : []\n\t\t\t) as Record<string, unknown>[];\n\n\t\t\tif (this.config.enableEventDps) {\n\t\t\t\tawait this.writeEventDps(d, fid, events);\n\t\t\t}\n\n\t\t\tif (this.config.enableWidget) {\n\t\t\t\tconst wId = `${fid}.widget`;\n\t\t\t\tif (!this.ensuredFolders.has(wId)) {\n\t\t\t\t\tawait this.ensurePath(wId);\n\t\t\t\t\tawait this.setObjectNotExistsAsync(wId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'HTML gallery widget',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(wId);\n\t\t\t\t}\n\t\t\t\tconst ev = events.slice(0, Math.max(1, this.config.widgetAnzahl || 50));\n\t\t\t\tconst f = (ev[0] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst l = (ev[ev.length - 1] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst sig = `${ev.length}|${f.fn ?? ''}|${l.fn ?? ''}`;\n\t\t\t\tif (this.widgetSig[wId] !== sig) {\n\t\t\t\t\tawait this.setStateAsync(wId, { val: this.buildGalleryHtml(d, ev), ack: true });\n\t\t\t\t\tthis.widgetSig[wId] = sig;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.eventBusy[d.oid] = false;\n\t\t}\n\t}\n\n\tprivate pushRefresh(oid: number | string): void {\n\t\tconst d = this.devById.get(oid);\n\t\tif (!d) {\n\t\t\tthis.log.warn(`Push: camera ${oid} unknown (available after first poll)`);\n\t\t\treturn;\n\t\t}\n\t\tconst fid = this.deviceFolder(d);\n\t\tfor (const ms of [0, 1500, 3500, 6000]) {\n\t\t\tthis.setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tthis.updateCameraEvents(d, fid).catch(e =>\n\t\t\t\t\t\tthis.log.warn(`Push refresh error: ${(e as Error).message}`),\n\t\t\t\t\t),\n\t\t\t\tms,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- main poll ----\n\n\tprivate async poll(): Promise<void> {\n\t\tconst res = await this.apiGet('/command/getObjects');\n\t\tconst json = asJson(res.data);\n\n\t\tif (!res.ok || !json) {\n\t\t\tawait this.setStateAsync('info.connection', false, true);\n\t\t\tawait this.setStateAsync('system.online', { val: false, ack: true });\n\t\t\tthis.log.warn(`AgentDVR unreachable: ${res.error || 'invalid response'}`);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.setStateAsync('info.connection', true, true);\n\t\tawait this.setStateAsync('system.online', { val: true, ack: true });\n\n\t\tif (json.settings) {\n\t\t\tawait this.flattenWrite(json.settings, 'system.settings', 0);\n\t\t}\n\n\t\tif (this.config.storeRawJson) {\n\t\t\tconst clean: Record<string, unknown> = { ...json };\n\t\t\tdelete clean.icons;\n\t\t\tawait this.writeLeaf('system.raw_getObjects', JSON.stringify(clean).slice(0, 60000));\n\t\t}\n\n\t\tconst devices = findDevices(json);\n\t\tawait this.setStateAsync('system.cameraCount', { val: devices.filter(d => d.ot === 2).length, ack: true });\n\n\t\tconst activeFolders = new Set(devices.map(d => this.deviceFolder(d)));\n\t\tfor (const d of devices) {\n\t\t\tawait this.buildDevice(d);\n\t\t}\n\t\tawait this.pruneStaleDevices(activeFolders);\n\n\t\tconst stats = asJson((await this.apiGet('/command/getSystemStats')).data);\n\t\tif (stats) {\n\t\t\tawait this.flattenWrite(stats, 'system.stats', 0);\n\t\t\tconst gb = parseSizeGb(stats.disk_free);\n\t\t\tif (gb !== null) {\n\t\t\t\tawait this.writeLeaf('system.disk_free_gb', gb);\n\t\t\t}\n\t\t}\n\n\t\tconst status = asJson((await this.apiGet('/command/getStatus')).data);\n\t\tif (status) {\n\t\t\tawait this.flattenWrite(status, 'system.status', 0);\n\t\t}\n\n\t\tif (this.config.enableSystemControls && Array.isArray(json.profiles)) {\n\t\t\tconst states: Record<number, string> = {};\n\t\t\tlet activeInd: number | null = null;\n\t\t\tfor (const p of json.profiles) {\n\t\t\t\tif (p && typeof p === 'object') {\n\t\t\t\t\tconst po = p as Record<string, unknown>;\n\t\t\t\t\tconst ind = po.id ?? po.ind ?? po.index;\n\t\t\t\t\tconst pname = po.name;\n\t\t\t\t\tif (typeof ind === 'number' && (typeof pname === 'string' || typeof pname === 'number')) {\n\t\t\t\t\t\tstates[ind] = String(pname);\n\t\t\t\t\t\tif (po.active === true) {\n\t\t\t\t\t\t\tactiveInd = ind;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Object.keys(states).length > 0) {\n\t\t\t\tconst sig = JSON.stringify(states);\n\t\t\t\tif (sig !== this.profileSig) {\n\t\t\t\t\tthis.profileSig = sig;\n\t\t\t\t\tawait this.extendObjectAsync('system.profile.selector', { common: { states } });\n\t\t\t\t\tawait this.setStateAsync('system.profile.list', { val: sig, ack: true });\n\t\t\t\t}\n\t\t\t\tif (activeInd !== null) {\n\t\t\t\t\tawait this.setStateAsync('system.profile.selector', { val: activeInd, ack: true });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.config.enableOverview) {\n\t\t\tconst cams = devices.filter(d => d.ot === 2);\n\t\t\tconst ovId = 'overview';\n\t\t\tif (!this.ensuredFolders.has(ovId)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(ovId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Overview (all cameras)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add(ovId);\n\t\t\t}\n\t\t\tawait this.setStateAsync(ovId, { val: this.buildOverviewHtml(cams), ack: true });\n\t\t}\n\n\t\tawait this.setStateAsync('system.lastUpdate', { val: new Date().toISOString(), ack: true });\n\t\tawait this.setStateAsync('system.lastPoll', { val: Date.now(), ack: true });\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.refreshTimer !== undefined) {\n\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = undefined;\n\t\t}\n\t\tthis.refreshTimer = this.setTimeout(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Refresh error: ${(e as Error).message}`)),\n\t\t\t1500,\n\t\t);\n\t}\n\n\t// ---- command execution ----\n\n\tprivate ptzUrl(oid: number | string, dir: number): string {\n\t\treturn `/ptz.cgi?oid=${encodeURIComponent(String(oid))}&dir=${dir}`;\n\t}\n\n\tprivate buildCommandUrl(entry: RegistryEntry): string {\n\t\tif (entry.kind === 'ptz') {\n\t\t\treturn this.ptzUrl(entry.oid!, entry.dir!);\n\t\t}\n\t\tif (entry.kind === 'sys') {\n\t\t\treturn entry.path as string;\n\t\t}\n\t\tconst qs: string[] = [];\n\t\tfor (const p of entry.params || []) {\n\t\t\tif (p === 'oid') {\n\t\t\t\tqs.push(`oid=${encodeURIComponent(String(entry.oid))}`);\n\t\t\t} else if (p === 'ot') {\n\t\t\t\tqs.push(`ot=${encodeURIComponent(String(entry.ot))}`);\n\t\t\t}\n\t\t}\n\t\treturn (entry.path || '') + (qs.length ? `?${qs.join('&')}` : '');\n\t}\n\n\tprivate async clearPtzSiblings(stateId: string): Promise<void> {\n\t\tconst prefix = stateId.slice(0, stateId.lastIndexOf('.') + 1);\n\t\tfor (const p of PTZ_DIRS) {\n\t\t\tif (!p.hold) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst sid = prefix + p.id;\n\t\t\tif (sid !== stateId) {\n\t\t\t\tawait this.setStateAsync(sid, { val: false, ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async runCommand(relId: string, entry: RegistryEntry, val: ioBroker.StateValue): Promise<void> {\n\t\tif (entry.kind === 'setProfile') {\n\t\t\tconst ind = typeof val === 'number' ? val : parseInt(String(val ?? ''), 10);\n\t\t\tif (!isNaN(ind)) {\n\t\t\t\tconst url = `/command/setProfile?ind=${ind}`;\n\t\t\t\tconst cmdRes = await this.apiGet(url);\n\t\t\t\tif (cmdRes.ok) {\n\t\t\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t\t\t\tawait this.setStateAsync(relId, { val: ind, ack: true });\n\t\t\t\t} else {\n\t\t\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t\t\t}\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'snapshotB64') {\n\t\t\tconst snapId = `${entry.fid}.snapshot_b64`;\n\t\t\tawait this.fetchSnapshotB64(entry.oid!, snapId);\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'push') {\n\t\t\tthis.log.info(`Push trigger cam ${entry.oid}`);\n\t\t\tawait this.setStateAsync(relId, { val: '', ack: true });\n\t\t\tthis.pushRefresh(entry.oid!);\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'ptzHold') {\n\t\t\tconst oid = entry.oid!;\n\t\t\tconst startMove = async (): Promise<void> => {\n\t\t\t\tawait this.clearPtzSiblings(relId);\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, entry.dir!));\n\t\t\t\tthis.ptzActive.set(oid, relId);\n\t\t\t\tawait this.setStateAsync(relId, { val: true, ack: true });\n\t\t\t};\n\t\t\tconst stopMove = async (): Promise<void> => {\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, 11));\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tthis.ptzActive.delete(oid);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\t};\n\t\t\tif (val) {\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tawait stopMove();\n\t\t\t\t} else {\n\t\t\t\t\tawait startMove();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait stopMove();\n\t\t\t}\n\t\t\tthis.scheduleRefresh();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!val) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'sys' && entry.path === null) {\n\t\t\tawait this.poll().catch(e => this.log.warn(`Manual refresh error: ${(e as Error).message}`));\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = this.buildCommandUrl(entry);\n\t\tconst cmdRes = await this.apiGet(url);\n\t\tif (cmdRes.ok) {\n\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t} else {\n\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t}\n\n\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\tthis.scheduleRefresh();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AgentDvr(options);\n} else {\n\t(() => new AgentDvr())();\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["url", "cmdRes"]
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "agent-dvr",
4
- "version": "0.0.4",
4
+ "version": "0.0.6",
5
5
  "news": {
6
+ "0.0.6": {
7
+ "en": "add Live Dashboard and go2rtc WebRTC documentation to README",
8
+ "de": "Live-Dashboard- und go2rtc-WebRTC-Dokumentation zur README hinzugefügt",
9
+ "ru": "добавлена документация Live Dashboard и go2rtc WebRTC в README",
10
+ "pt": "documentação do Live Dashboard e go2rtc WebRTC adicionada ao README",
11
+ "nl": "Live Dashboard en go2rtc WebRTC documentatie toegevoegd aan README",
12
+ "fr": "documentation Live Dashboard et go2rtc WebRTC ajoutée au README",
13
+ "it": "documentazione Live Dashboard e go2rtc WebRTC aggiunta al README",
14
+ "es": "documentación de Live Dashboard y go2rtc WebRTC añadida al README",
15
+ "pl": "dodano dokumentację Live Dashboard i go2rtc WebRTC do README",
16
+ "uk": "додано документацію Live Dashboard і go2rtc WebRTC до README",
17
+ "zh-cn": "README 中新增 Live Dashboard 和 go2rtc WebRTC 文档"
18
+ },
19
+ "0.0.5": {
20
+ "en": "go2rtc WebRTC integration (admin table mapping, ioBroker WS proxy); auto-delete stale cameras; fix recording prev/next order",
21
+ "de": "go2rtc WebRTC-Integration (Admin-Tabellen-Mapping, ioBroker WS-Proxy); gelöschte Kameras werden automatisch entfernt; Vor/Zurück-Reihenfolge bei Aufnahmen korrigiert",
22
+ "ru": "интеграция go2rtc WebRTC (таблица в admin, WS-прокси через ioBroker); автоудаление устаревших камер; исправлен порядок кнопок Пред/След для записей",
23
+ "pt": "integração go2rtc WebRTC (tabela no admin, proxy WS via ioBroker); remoção automática de câmeras obsoletas; ordem anterior/próximo nas gravações corrigida",
24
+ "nl": "go2rtc WebRTC-integratie (admintabel, ioBroker WS-proxy); automatisch verwijderen van verouderde camera's; volgorde vorige/volgende opnames gecorrigeerd",
25
+ "fr": "intégration go2rtc WebRTC (table admin, proxy WS ioBroker); suppression automatique des caméras obsolètes; ordre précédent/suivant des enregistrements corrigé",
26
+ "it": "integrazione go2rtc WebRTC (tabella admin, proxy WS ioBroker); eliminazione automatica telecamere obsolete; ordine precedente/successivo registrazioni corretto",
27
+ "es": "integración go2rtc WebRTC (tabla en admin, proxy WS ioBroker); eliminación automática de cámaras obsoletas; orden anterior/siguiente en grabaciones corregido",
28
+ "pl": "integracja go2rtc WebRTC (tabela w admin, proxy WS ioBroker); automatyczne usuwanie nieaktywnych kamer; poprawiona kolejność poprzedni/następny nagrań",
29
+ "uk": "інтеграція go2rtc WebRTC (таблиця в admin, WS-проксі через ioBroker); автовидалення застарілих камер; виправлено порядок кнопок Попередній/Наступний для записів",
30
+ "zh-cn": "go2rtc WebRTC 集成(管理表格映射,ioBroker WS 代理);自动删除过时摄像头;修正录像上一个/下一个顺序"
31
+ },
6
32
  "0.0.4": {
7
33
  "en": "fix DP roles: snapshot_b64 role state, profile selector role level",
8
34
  "de": "DP-Rollen korrigiert: snapshot_b64 role state, Profil-Selektor role level",
@@ -82,8 +108,14 @@
82
108
  "uk": "Підключає ioBroker до AgentDVR: автоматично виявляє камери, відображає всі значення пристроїв як точки даних, забезпечує тригери в режимі реального часу для нових записів та створює адаптивну HTML-галерею з додатковим пошуком та фільтрацією тегів.",
83
109
  "zh-cn": "将 ioBroker 连接到 AgentDVR:自动发现摄像头,将所有设备值镜像为数据点,在新录像时提供实时触发,并生成具有可选搜索和标签过滤功能的响应式 HTML 图库。"
84
110
  },
85
- "authors": ["ipod86 <david@graef.email>"],
86
- "keywords": ["Agentdvr", "ispy", "ptz"],
111
+ "authors": [
112
+ "ipod86 <david@graef.email>"
113
+ ],
114
+ "keywords": [
115
+ "Agentdvr",
116
+ "ispy",
117
+ "ptz"
118
+ ],
87
119
  "licenseInformation": {
88
120
  "type": "free",
89
121
  "license": "MIT"
@@ -97,6 +129,7 @@
97
129
  "tier": 3,
98
130
  "mode": "daemon",
99
131
  "type": "alarm",
132
+ "messagebox": true,
100
133
  "compact": true,
101
134
  "connectionType": "local",
102
135
  "dataSource": "poll",
@@ -111,11 +144,19 @@
111
144
  "globalDependencies": [
112
145
  {
113
146
  "admin": ">=7.6.20"
147
+ },
148
+ {
149
+ "web": ">=3.0.0"
114
150
  }
115
- ]
151
+ ],
152
+ "webExtension": "lib/web.js"
116
153
  },
117
- "protectedNative": ["pass"],
118
- "encryptedNative": ["pass"],
154
+ "protectedNative": [
155
+ "pass"
156
+ ],
157
+ "encryptedNative": [
158
+ "pass"
159
+ ],
119
160
  "native": {
120
161
  "ip": "192.168.1.100",
121
162
  "port": 8090,
@@ -144,7 +185,36 @@
144
185
  "maxArray": 30,
145
186
  "eventTagsDynamic": true,
146
187
  "eventTagsIgnore": "detected",
147
- "eventTags": ""
188
+ "eventTags": "",
189
+ "webInstance": "*",
190
+ "widgetShowSearch": true,
191
+ "widgetSortNewest": true,
192
+ "widgetDefaultTag": "",
193
+ "widgetThumbSize": "medium",
194
+ "widgetCompact": false,
195
+ "dashDefaultView": "live",
196
+ "dashShowOffline": true,
197
+ "dashGridCols": 0,
198
+ "dashBtnsVisible": false,
199
+ "dashTagPosition": "top-right",
200
+ "dashRefreshSec": 60,
201
+ "dashStreamReconnect": true,
202
+ "widgetColorCardBg": "rgba(127,127,127,0.15)",
203
+ "widgetColorTagBg": "rgba(0,0,0,0.55)",
204
+ "widgetColorTagText": "#ffffff",
205
+ "widgetColorAccent": "#8ab4f8",
206
+ "widgetColorModalBg": "#1c1c1e",
207
+ "widgetBorderRadius": 8,
208
+ "go2rtcEnabled": false,
209
+ "go2rtcUrl": "",
210
+ "go2rtcMapping": [],
211
+ "dashColorBg": "#080b0f",
212
+ "dashColorSurface": "#0d1117",
213
+ "dashColorAccent": "#2563eb",
214
+ "dashColorText": "#dde4ef",
215
+ "dashColorBorder": "#1e2a38",
216
+ "dashColorOnline": "#22c55e",
217
+ "dashColorOffline": "#ef4444"
148
218
  },
149
219
  "objects": [],
150
220
  "instanceObjects": [