@kedem/okdb 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/okdb.js +1 -1
- package/keys/public.pem +3 -0
- package/okdb.js +1 -1
- package/package.json +2 -2
- package/public/admin-app.js +1 -1
- package/public/components/admin-route-host.ok.js +1 -1
- package/public/components/env-picker.ok.js +1 -1
- package/public/components/field-path-input.ok.js +1 -1
- package/public/components/geo-map.ok.js +1 -1
- package/public/components/ok-cron-input.ok.js +1 -1
- package/public/components/ok-dropzone.ok.js +1 -1
- package/public/components/ok-js-input.ok.js +1 -1
- package/public/components/ok-json-input.ok.js +1 -1
- package/public/components/ok-text-monaco-input.ok.js +1 -1
- package/public/components/theme-toggle.ok.js +1 -1
- package/public/login-app.js +1 -1
- package/public/modules/ok.js +1 -1
- package/public/sections/api/parts/api-endpoint.ok.js +1 -1
- package/public/sections/auth/modals/create-token-modal.ok.js +1 -1
- package/public/sections/auth/modals/edit-token-modal.ok.js +1 -1
- package/public/sections/auth/modals/perm-info-popover.ok.js +1 -1
- package/public/sections/auth/parts/token-detail.ok.js +1 -1
- package/public/sections/auth/parts/token-list.ok.js +1 -1
- package/public/sections/db/modals/add-item-modal.ok.js +1 -1
- package/public/sections/db/modals/create-env-modal.ok.js +1 -1
- package/public/sections/db/modals/create-fts-modal.ok.js +1 -1
- package/public/sections/db/modals/create-index-modal.ok.js +1 -1
- package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -1
- package/public/sections/db/modals/demo-env-modal.ok.js +1 -1
- package/public/sections/db/modals/remove-env-modal.ok.js +1 -1
- package/public/sections/db/modals/schema-edit-modal.ok.js +1 -1
- package/public/sections/db/parts/db-overview.ok.js +1 -1
- package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -1
- package/public/sections/db/parts/edit-row.ok.js +1 -1
- package/public/sections/db/parts/tm-timeline.ok.js +1 -1
- package/public/sections/db/parts/type-changelog.ok.js +1 -1
- package/public/sections/db/parts/type-list.ok.js +1 -1
- package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -1
- package/public/sections/db/parts/type-schema-tab.ok.js +1 -1
- package/public/sections/db/parts/type-viewer.ok.js +1 -1
- package/public/sections/db/parts/type-violations-tab.ok.js +1 -1
- package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-overview.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/engines-overview.ok.js +1 -1
- package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -1
- package/public/sections/engines/engine-panel-shared-style.js +1 -1
- package/public/sections/engines/engine-ui-utils.js +1 -1
- package/public/sections/engines/modals/engine-modal.ok.js +1 -1
- package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -1
- package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -1
- package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -1
- package/public/sections/engines/parts/engine-resource-card.ok.js +1 -1
- package/public/sections/engines/parts/engine-row-item.ok.js +1 -1
- package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -1
- package/public/sections/files/parts/files-blob-status.ok.js +1 -1
- package/public/sections/files/parts/files-collection-list.ok.js +1 -1
- package/public/sections/files/parts/files-collection-panel.ok.js +1 -1
- package/public/sections/files/parts/files-file-list.ok.js +1 -1
- package/public/sections/files/parts/files-overview.ok.js +1 -1
- package/public/sections/files/parts/files-path-browser.ok.js +1 -1
- package/public/sections/files/parts/files-upload-panel.ok.js +1 -1
- package/public/sections/functions/modals/function-modal.ok.js +1 -1
- package/public/sections/functions/parts/function-detail.ok.js +1 -1
- package/public/sections/functions/parts/function-logs.ok.js +1 -1
- package/public/sections/functions/parts/function-runner.ok.js +1 -1
- package/public/sections/functions/parts/functions-list.ok.js +1 -1
- package/public/sections/license/parts/license-panel.ok.js +1 -1
- package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -1
- package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -1
- package/public/sections/queue/modals/edit-job-modal.ok.js +1 -1
- package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -1
- package/public/sections/queue/modals/job-type-modal.ok.js +1 -1
- package/public/sections/queue/parts/ok-job-form.ok.js +1 -1
- package/public/sections/queue/parts/queue-buckets.ok.js +1 -1
- package/public/sections/queue/parts/queue-job-types.ok.js +1 -1
- package/public/sections/queue/parts/queue-jobs.ok.js +1 -1
- package/public/sections/queue/parts/queue-types.ok.js +1 -1
- package/public/sections/queue/parts/queue-workers.ok.js +1 -1
- package/public/sections/sync/parts/sync-node-detail.ok.js +1 -1
- package/public/sections/sync/parts/sync-retention.ok.js +1 -1
- package/public/sections/sync/parts/sync-topology.ok.js +1 -1
- package/public/sections/system/modals/data-ops-modal.ok.js +1 -1
- package/public/sections/system/parts/system-api-panel.ok.js +1 -1
- package/public/sections/system/parts/system-auth-panel.ok.js +1 -1
- package/public/sections/system/parts/system-log-history.ok.js +1 -1
- package/public/sections/system/parts/system-log.ok.js +1 -1
- package/public/sections/system/parts/system-status.ok.js +1 -1
- package/public/sections/system/parts/system-sync-panel.ok.js +1 -1
- package/public/sections/views/modals/create-view-modal.ok.js +1 -1
- package/public/sections/views/parts/view-detail.ok.js +1 -1
- package/public/sections/views/parts/views-list.ok.js +1 -1
- package/public/sections/views/parts/views-overview.ok.js +1 -1
- package/public/setup-app.js +1 -1
- package/public/stores/auth-store.js +1 -1
- package/public/stores/events-store.js +1 -1
- package/public/stores/functions-store.js +1 -1
- package/public/stores/okdb-store.js +1 -1
- package/public/stores/theme-store.js +1 -1
- package/public/util/permissions.js +1 -1
- package/public/util/sift-schema.js +1 -1
- package/public/vendor/okjs/ok.esm.min.js +1 -2
- package/public/vendor/okjs/toolkit/behavior/async.ok.js +1 -1
- package/public/vendor/okjs/toolkit/components/ok-chart.ok.js +1 -1
- package/public/vendor/okjs/toolkit/components/ok-doc-viewer.ok.js +1 -1
- package/public/vendor/okjs/toolkit/components/ok-marked.ok.js +1 -1
- package/public/vendor/okjs/toolkit/components/ok-monaco.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/ok-layer-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/ok-layer.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/ok-overlay.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/ok-sandbox.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/transition.ok.js +1 -1
- package/public/vendor/okjs/toolkit/core/virtualized.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-console-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-console.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-inspector-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-inspector.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-js-tree.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-timeline-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/devtools/ok-timeline.ok.js +1 -1
- package/public/vendor/okjs/toolkit/docs/doc-viewer.ok.js +1 -1
- package/public/vendor/okjs/toolkit/editor/ok-live-component.ok.js +1 -1
- package/public/vendor/okjs/toolkit/editor/ok-live-example.ok.js +1 -1
- package/public/vendor/okjs/toolkit/editor/ok-live-shell.ok.js +1 -1
- package/public/vendor/okjs/toolkit/elements/ok-dropdown.ok.js +1 -1
- package/public/vendor/okjs/toolkit/elements/ok-icon.ok.js +1 -1
- package/public/vendor/okjs/toolkit/elements/ok-select.ok.js +1 -1
- package/public/vendor/okjs/toolkit/elements/ok-table.ok.js +1 -1
- package/public/vendor/okjs/toolkit/errors/ok-crash-boundary.ok.js +1 -1
- package/public/vendor/okjs/toolkit/errors/ok-crash-info.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/i18n-editor-examples.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/i18n-editor.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/i18n-key-editor-tips.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/i18n-key-editor.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/i18n-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/i18n/ok-i18n.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-contextmenu.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-dismiss-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-draggable.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-flyover-panel.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-flyover.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-highlight-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-highlight.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-hotkeys-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-picker-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-popout-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-popout.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-portal-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/interaction/ok-submenu.ok.js +1 -1
- package/public/vendor/okjs/toolkit/layout/ok-resizer.ok.js +1 -1
- package/public/vendor/okjs/toolkit/manifest.js +1 -1
- package/public/vendor/okjs/toolkit/modals/ok-modal-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/modals/ok-modal.ok.js +1 -1
- package/public/vendor/okjs/toolkit/modals/ok-toast-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/modals/ok-window.ok.js +1 -1
- package/public/vendor/okjs/toolkit/navigation/hash-router.ok.js +1 -1
- package/public/vendor/okjs/toolkit/navigation/history-router.ok.js +1 -1
- package/public/vendor/okjs/toolkit/navigation/router.ok.js +1 -1
- package/public/vendor/okjs/toolkit/sync/reactive-sync-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/sync/reactive-sync.js +1 -1
- package/public/vendor/okjs/toolkit/theming/blocks/ok-design-button.css.js +1 -1
- package/public/vendor/okjs/toolkit/theming/blocks/ok-design-input.css.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-design-style.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-design-vars.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-design.ok.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-input.ok.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-service.ok.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-style.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-utils.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-variable.ok.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-vm.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor.ok.js +1 -1
- package/public/vendor/okjs/toolkit/theming/ok-theme.ok.js +1 -1
- package/public/view-models/type-query-vm.js +1 -1
- package/public/images/logo.png +0 -0
- package/public/images/logo.svg +0 -333
|
@@ -1 +1 @@
|
|
|
1
|
-
const _0x4a43e5=_0x10b9;function _0x10b9(_0x1672db,_0x2e5d23){_0x1672db=_0x1672db-0x158;const _0x38cf6a=_0x38cf();let _0x10b9e0=_0x38cf6a[_0x1672db];return _0x10b9e0;}(function(_0x54531a,_0x34cfdc){const _0x5e457b=_0x10b9,_0x4ecd2d=_0x54531a();while(!![]){try{const _0x2a0304=-parseInt(_0x5e457b(0x213))/0x1+-parseInt(_0x5e457b(0x1d2))/0x2+parseInt(_0x5e457b(0x159))/0x3*(parseInt(_0x5e457b(0x1c3))/0x4)+-parseInt(_0x5e457b(0x1bd))/0x5*(parseInt(_0x5e457b(0x1d7))/0x6)+parseInt(_0x5e457b(0x18d))/0x7*(-parseInt(_0x5e457b(0x21e))/0x8)+-parseInt(_0x5e457b(0x216))/0x9*(-parseInt(_0x5e457b(0x191))/0xa)+parseInt(_0x5e457b(0x1bf))/0xb;if(_0x2a0304===_0x34cfdc)break;else _0x4ecd2d['push'](_0x4ecd2d['shift']());}catch(_0x585c35){_0x4ecd2d['push'](_0x4ecd2d['shift']());}}}(_0x38cf,0x4f0ca));export default{'tag':_0x4a43e5(0x1a9),'unwrap':!0x0,'context':_0x15953a=>({'w':0x384,'h':0x1f4,'layout':{'cx':0x0,'cy':0x0,'r':0x0,'pos':{}},'_ro':null,'_tick':null,'now':Date['now'](),'selectedNodeId':null,'selectedLinkKey':null,'hoveredLinkKey':null,'hoveredNodeId':null,'lastUpdatedAt':null,'autoRefresh':!0x0,'autoRefreshIntervalMs':0x1388,'_autoRefreshTimer':null,'loadingTopology':!0x1,'editingLink':null,'linkEditDir':_0x4a43e5(0x205),'linkEditEnvs':null,'linkEditEnabled':!0x0,'savingLink':!0x1,'panX':0x0,'panY':0x0,'zoom':0x1,'_drag':null,'_customPos':{},'_svgEl':null,'_groupEl':null,'_applyTransform'(){const _0x3466c7=_0x4a43e5;this[_0x3466c7(0x208)]||(this[_0x3466c7(0x208)]=this['_svgEl']?.[_0x3466c7(0x166)](_0x3466c7(0x1e7))),this[_0x3466c7(0x208)]&&this['_groupEl'][_0x3466c7(0x1b0)](_0x3466c7(0x1b9),_0x3466c7(0x20d)+this[_0x3466c7(0x1ab)]+','+this[_0x3466c7(0x20e)]+_0x3466c7(0x1e6)+this['zoom']+')');},'_px2vb'(){const _0x1f03f3=_0x4a43e5;if(!this[_0x1f03f3(0x221)])return{'sx':0x1,'sy':0x1};const _0x51937f=this[_0x1f03f3(0x221)][_0x1f03f3(0x1af)]();return{'sx':this['w']/(_0x51937f[_0x1f03f3(0x19f)]||0x1),'sy':this['h']/(_0x51937f[_0x1f03f3(0x211)]||0x1)};},'_onWheel'(_0x3f07af){const _0x512fd5=_0x4a43e5;if(!this[_0x512fd5(0x221)])return;const _0x3d9868=this['_svgEl']['getBoundingClientRect'](),{sx:_0x58671a,sy:_0xb7019d}=this[_0x512fd5(0x1fa)](),_0x179dda=(_0x3f07af[_0x512fd5(0x1d9)]-_0x3d9868[_0x512fd5(0x1c2)])*_0x58671a,_0x1c2b03=(_0x3f07af['clientY']-_0x3d9868[_0x512fd5(0x1ff)])*_0xb7019d,_0x3db30d=_0x3f07af[_0x512fd5(0x169)]<0x0?1.12:0x1/1.12,_0x300e7c=Math[_0x512fd5(0x180)](0.1,Math[_0x512fd5(0x176)](0x8,this['zoom']*_0x3db30d)),_0x4ca67f=_0x300e7c/this[_0x512fd5(0x158)];this[_0x512fd5(0x1ab)]=_0x179dda+(this[_0x512fd5(0x1ab)]-_0x179dda)*_0x4ca67f,this[_0x512fd5(0x20e)]=_0x1c2b03+(this[_0x512fd5(0x20e)]-_0x1c2b03)*_0x4ca67f,this['zoom']=_0x300e7c,this[_0x512fd5(0x15c)]();},'_onSvgMousedown'(_0x1faa02){const _0x1fec68=_0x4a43e5;if(0x0!==_0x1faa02[_0x1fec68(0x1ae)])return;_0x1faa02[_0x1fec68(0x1c9)]();let _0x55c6ea=null,_0x3730d0=_0x1faa02[_0x1fec68(0x1f4)];for(;_0x3730d0&&_0x3730d0!==this[_0x1fec68(0x221)];){if(_0x3730d0['id']&&_0x3730d0['id'][_0x1fec68(0x16a)]('nd-')){_0x55c6ea=_0x3730d0['id'][_0x1fec68(0x223)](0x3);break;}_0x3730d0=_0x3730d0[_0x1fec68(0x21d)];}if(_0x55c6ea){const _0x375192=this[_0x1fec68(0x221)][_0x1fec68(0x1af)](),{sx:_0x4437de,sy:_0x52866a}=this[_0x1fec68(0x1fa)](),_0x7466df=(_0x1faa02[_0x1fec68(0x1d9)]-_0x375192[_0x1fec68(0x1c2)])*_0x4437de,_0x5103ba=(_0x1faa02[_0x1fec68(0x17b)]-_0x375192[_0x1fec68(0x1ff)])*_0x52866a,_0x1c8bef=(_0x7466df-this[_0x1fec68(0x1ab)])/this[_0x1fec68(0x158)],_0x5d5f1e=(_0x5103ba-this[_0x1fec68(0x20e)])/this[_0x1fec68(0x158)],_0x2d88e6=this[_0x1fec68(0x183)](_0x55c6ea)||{'x':_0x1c8bef,'y':_0x5d5f1e};this[_0x1fec68(0x225)]={'type':_0x1fec68(0x217),'id':_0x55c6ea,'ox':_0x1c8bef-_0x2d88e6['x'],'oy':_0x5d5f1e-_0x2d88e6['y']};}else this['_drag']={'type':'pan','sx':_0x1faa02[_0x1fec68(0x1d9)],'sy':_0x1faa02['clientY'],'px':this[_0x1fec68(0x1ab)],'py':this[_0x1fec68(0x20e)]};this[_0x1fec68(0x221)]&&(this[_0x1fec68(0x221)][_0x1fec68(0x190)][_0x1fec68(0x17d)]='grabbing');},'_onMousemove'(_0x3ce3e9){const _0x2fd6b9=_0x4a43e5;if(!this[_0x2fd6b9(0x225)])return;const {sx:_0x3095b7,sy:_0x345f5c}=this[_0x2fd6b9(0x1fa)]();if(_0x2fd6b9(0x18b)===this[_0x2fd6b9(0x225)]['type'])this[_0x2fd6b9(0x1ab)]=this[_0x2fd6b9(0x225)]['px']+(_0x3ce3e9[_0x2fd6b9(0x1d9)]-this[_0x2fd6b9(0x225)]['sx'])*_0x3095b7,this[_0x2fd6b9(0x20e)]=this['_drag']['py']+(_0x3ce3e9[_0x2fd6b9(0x17b)]-this[_0x2fd6b9(0x225)]['sy'])*_0x345f5c,this[_0x2fd6b9(0x15c)]();else{const _0x364c45=this[_0x2fd6b9(0x221)][_0x2fd6b9(0x1af)](),_0x23001d=(_0x3ce3e9[_0x2fd6b9(0x1d9)]-_0x364c45[_0x2fd6b9(0x1c2)])*_0x3095b7,_0x3f62e6=(_0x3ce3e9[_0x2fd6b9(0x17b)]-_0x364c45['top'])*_0x345f5c,_0xb2db71=(_0x23001d-this['panX'])/this[_0x2fd6b9(0x158)],_0x4884f7=(_0x3f62e6-this[_0x2fd6b9(0x20e)])/this['zoom'];this[_0x2fd6b9(0x161)]={...this[_0x2fd6b9(0x161)],[this['_drag']['id']]:{'x':_0xb2db71-this[_0x2fd6b9(0x225)]['ox'],'y':_0x4884f7-this[_0x2fd6b9(0x225)]['oy']}},this[_0x2fd6b9(0x21a)]();}},'_onMouseup'(){const _0x29b065=_0x4a43e5;this[_0x29b065(0x225)]=null,this[_0x29b065(0x221)]&&(this[_0x29b065(0x221)][_0x29b065(0x190)][_0x29b065(0x17d)]='grab');},get 'externalSelectedNodeId'(){return _0x15953a['$attr']['selected_node_id']??null;},get 'selfId'(){return _0x15953a['$attr']['self_id'];},get 'topology'(){const _0x316d94=_0x4a43e5;return _0x15953a[_0x316d94(0x1f1)][_0x316d94(0x1db)]||{};},get 'availableEnvs'(){const _0x5baa7d=_0x4a43e5;return _0x15953a[_0x5baa7d(0x1f1)][_0x5baa7d(0x210)]||[];},get 'envButtons'(){const _0x4e725f=_0x4a43e5,_0x3fc3e6=this['linkEditEnvs'];return(_0x15953a[_0x4e725f(0x1f1)]['available_envs']||[])[_0x4e725f(0x1bc)](_0x2e1c8e=>({'name':_0x2e1c8e,'style':null===_0x3fc3e6||Array['isArray'](_0x3fc3e6)&&_0x3fc3e6[_0x4e725f(0x174)](_0x2e1c8e)?_0x4e725f(0x1f6):''}));},get 'dirButtons'(){const _0x5b5331=_0x4a43e5,_0x3a13ee=this[_0x5b5331(0x188)];if(!_0x3a13ee)return[];const _0x4f6e21=_0x3a13ee['lo']['slice'](0x0,0x6),_0x2fa57b=_0x3a13ee['hi']['slice'](0x0,0x6),_0x443ef7=this[_0x5b5331(0x195)];return[{'canon':_0x5b5331(0x205),'label':_0x4f6e21+_0x5b5331(0x21b)+_0x2fa57b},{'canon':'lo_to_hi','label':_0x4f6e21+_0x5b5331(0x18c)+_0x2fa57b},{'canon':'hi_to_lo','label':_0x2fa57b+'\x20→\x20'+_0x4f6e21}][_0x5b5331(0x1bc)](_0x106aa6=>({..._0x106aa6,'style':_0x106aa6[_0x5b5331(0x17c)]===_0x443ef7?'border-color:var(--accent);color:var(--accent)':''}));},get 'nodes'(){const _0xa0f622=_0x4a43e5;return Object[_0xa0f622(0x1d5)](this[_0xa0f622(0x1db)]||{})['filter'](_0x2fdf9b=>_0x2fdf9b&&null!=_0x2fdf9b['id'])[_0xa0f622(0x1d4)]((_0x4344bd,_0x193827)=>String(_0x4344bd['id'])[_0xa0f622(0x1cc)](String(_0x193827['id'])));},get 'nodeList'(){const _0x31685c=_0x4a43e5;return this[_0x31685c(0x200)][_0x31685c(0x1bc)](_0x434533=>{const _0x103552=this['_customPos'][_0x434533['id']]||this['layout']['pos']?.[_0x434533['id']]||{'x':this['w']/0x2,'y':this['h']/0x2};return{..._0x434533,'px':_0x103552['x'],'py':_0x103552['y']};});},get 'links'(){const _0xc7991e=_0x4a43e5,_0x242dfe=this['topology']||{},_0x4b41ef=_0x242dfe[this['selfId']]||Object[_0xc7991e(0x1d5)](_0x242dfe)[_0xc7991e(0x1f7)](_0x1b98d3=>null!=_0x1b98d3?.[_0xc7991e(0x18f)]),_0x1a608f=_0x4b41ef?.[_0xc7991e(0x18f)]||{},_0x163ca7=new Map(),_0x2d55a2=(_0x22f7fe,_0x5939a6)=>({'status':_0x22f7fe[_0xc7991e(0x165)]||_0xc7991e(0x1ad),'backlog':Math[_0xc7991e(0x180)](0x0,Number(_0x5939a6??0x0)-Number(_0x22f7fe[_0xc7991e(0x1b2)]??0x0)),'last_seen':_0x22f7fe['last_seen']??null,'last_error':_0x22f7fe[_0xc7991e(0x192)]??null});for(const _0x3ff9f in _0x242dfe){const _0xe05bb5=_0x242dfe[_0x3ff9f];if(_0xe05bb5?.[_0xc7991e(0x1ac)])for(const _0x1eee5f in _0xe05bb5[_0xc7991e(0x1ac)]){const _0x4d8148=_0x3ff9f<_0x1eee5f?_0x3ff9f:_0x1eee5f,_0x1d0466=_0x3ff9f<_0x1eee5f?_0x1eee5f:_0x3ff9f,_0x3a3780=_0x4d8148+':'+_0x1d0466;_0x163ca7['has'](_0x3a3780)||_0x163ca7['set'](_0x3a3780,{'lo':_0x4d8148,'hi':_0x1d0466,'lo_pull':null,'hi_pull':null});const _0x44d6aa=_0x163ca7[_0xc7991e(0x182)](_0x3a3780),_0x1ff56e=_0xe05bb5[_0xc7991e(0x1ac)][_0x1eee5f];_0x3ff9f===_0x4d8148?_0x44d6aa[_0xc7991e(0x1dd)]=_0x2d55a2(_0x1ff56e,_0x242dfe[_0x1eee5f]?.[_0xc7991e(0x1b2)]):_0x44d6aa['hi_pull']=_0x2d55a2(_0x1ff56e,_0x242dfe[_0x1eee5f]?.[_0xc7991e(0x1b2)]);}}for(const _0x174840 in _0x1a608f)if(_0x1a608f[_0x174840]&&!_0x163ca7[_0xc7991e(0x1c6)](_0x174840)){const _0x31cf82=_0x1a608f[_0x174840];_0x163ca7['set'](_0x174840,{'lo':_0x31cf82['node_lo'],'hi':_0x31cf82['node_hi'],'lo_pull':null,'hi_pull':null});}return[..._0x163ca7['entries']()][_0xc7991e(0x1bc)](([_0x2d8ca9,_0x1f2383])=>({'key':_0x2d8ca9,'lo':_0x1f2383['lo'],'hi':_0x1f2383['hi'],'link':_0x1a608f[_0x2d8ca9]||null,'lo_pull':_0x1f2383[_0xc7991e(0x1dd)],'hi_pull':_0x1f2383[_0xc7991e(0x1b1)]}));},'_linkConfig'(_0x6e99b){const _0x1222c2=_0x4a43e5,_0x1cff3f=(this[_0x1222c2(0x1db)]||{})[this[_0x1222c2(0x21f)]];return _0x1cff3f?.[_0x1222c2(0x18f)]?.[_0x6e99b]||null;},'_linkHealth'(_0x3e470c){const _0x7117a2=_0x4a43e5;if(_0x3e470c[_0x7117a2(0x207)]&&!_0x3e470c[_0x7117a2(0x207)]['enabled'])return _0x7117a2(0x178);const _0xdcac51=_0x3e470c[_0x7117a2(0x207)]?.[_0x7117a2(0x1fb)]??_0x7117a2(0x205),_0x3c5d6c=[];'both'!==_0xdcac51&&_0x7117a2(0x21c)!==_0xdcac51||_0x3c5d6c[_0x7117a2(0x16d)](_0x3e470c[_0x7117a2(0x1b1)]),'both'!==_0xdcac51&&'hi_to_lo'!==_0xdcac51||_0x3c5d6c[_0x7117a2(0x16d)](_0x3e470c[_0x7117a2(0x1dd)]);const _0x37a174=[_0x7117a2(0x19b),_0x7117a2(0x16f),_0x7117a2(0x202),'behind',_0x7117a2(0x218),'stale','ok'];let _0x4d02a5='stale';for(const _0x275045 of _0x3c5d6c){const _0x2baa9b=this[_0x7117a2(0x171)](_0x275045);_0x37a174[_0x7117a2(0x15f)](_0x2baa9b)<_0x37a174[_0x7117a2(0x15f)](_0x4d02a5)&&(_0x4d02a5=_0x2baa9b);}return _0x4d02a5;},'_pullHealth'(_0x28c6d7){const _0x1f711e=_0x4a43e5;if(!_0x28c6d7)return _0x1f711e(0x184);if(_0x1f711e(0x218)===_0x28c6d7['status'])return _0x1f711e(0x218);if(_0x28c6d7[_0x1f711e(0x1b5)]){const _0x2b439c=this['now']-Number(_0x28c6d7[_0x1f711e(0x1b5)]);return _0x28c6d7[_0x1f711e(0x1e9)]>0x32?_0x1f711e(0x16f):_0x28c6d7['backlog']>0x5?_0x1f711e(0x202):_0x28c6d7[_0x1f711e(0x1e9)]>0x0?'behind':_0x2b439c>0x7530?_0x1f711e(0x184):'ok';}return _0x28c6d7['last_error']?_0x1f711e(0x19b):'stale';},'_healthMarker':_0x221180=>'error'===_0x221180?'err':'reconciling'===_0x221180?_0x4a43e5(0x1f2):_0x4a43e5(0x16f)===_0x221180?_0x4a43e5(0x16f):'lag-med'===_0x221180||_0x4a43e5(0x15b)===_0x221180||_0x4a43e5(0x184)===_0x221180?'lag-med':'ok','_linkDirLabel'(_0x29a60f){const _0x535503=_0x4a43e5;if(!_0x29a60f['link'])return _0x29a60f['lo']['slice'](0x0,0x6)+'\x20⇄\x20'+_0x29a60f['hi']['slice'](0x0,0x6)+_0x535503(0x1f8);if(!_0x29a60f[_0x535503(0x207)][_0x535503(0x1d0)])return _0x535503(0x178);const _0xca40d0=_0x29a60f['lo']['slice'](0x0,0x6),_0x115997=_0x29a60f['hi'][_0x535503(0x223)](0x0,0x6);switch(_0x29a60f['link'][_0x535503(0x1fb)]){case _0x535503(0x205):return _0xca40d0+'\x20⇄\x20'+_0x115997;case _0x535503(0x21c):return _0xca40d0+_0x535503(0x18c)+_0x115997;case'hi_to_lo':return _0x115997+_0x535503(0x18c)+_0xca40d0;default:return _0x29a60f[_0x535503(0x207)][_0x535503(0x1fb)];}},get 'selection'(){const _0x291457=_0x4a43e5;if(this[_0x291457(0x20a)]){const _0x27cd4b=this[_0x291457(0x18f)][_0x291457(0x1f7)](_0x3d9439=>_0x3d9439[_0x291457(0x163)]===this['selectedLinkKey'])||null;if(_0x27cd4b)return{'type':_0x291457(0x207),'data':_0x27cd4b};}if(this[_0x291457(0x181)]){const _0x50c874=this[_0x291457(0x1db)][this['selectedNodeId']]||null;return _0x50c874?{'type':_0x291457(0x217),'id':this[_0x291457(0x181)],'data':_0x50c874}:null;}return null;},get 'freshnessLabel'(){const _0x7df670=_0x4a43e5;if(!this[_0x7df670(0x1ee)])return'never';const _0x135b2a=this[_0x7df670(0x222)]-this['lastUpdatedAt'];return _0x135b2a<0x5dc?_0x7df670(0x222):_0x135b2a<0x1388?_0x7df670(0x164):_0x135b2a<0x3a98?'recent':Math[_0x7df670(0x1d8)](_0x135b2a/0x3e8)+'s\x20ago';},get 'freshnessClass'(){const _0x1ee452=_0x4a43e5;if(!this[_0x1ee452(0x1ee)])return _0x1ee452(0x1ea);const _0x42f6db=this['now']-this[_0x1ee452(0x1ee)];return _0x42f6db<0x1388?_0x1ee452(0x1e0):_0x42f6db<0x3a98?'fresh-ok':_0x1ee452(0x1ea);},'_recomputeLayout'(){const _0x55e54f=_0x4a43e5,_0x2bdc44=this[_0x55e54f(0x200)],_0x1709c5=this['w']/0x2,_0x2fa0b3=this['h']/0x2,_0x5bf22f=Math['max'](0x50,Math[_0x55e54f(0x176)](_0x1709c5,_0x2fa0b3)-this['nodeRadius']()-0x3c),_0x5d4661={},_0x53c50b=_0x2bdc44[_0x55e54f(0x1da)]||0x1;_0x2bdc44[_0x55e54f(0x1e3)]((_0x263156,_0x3e417d)=>{const _0x104fa7=_0x55e54f;if(0x1===_0x53c50b)return void(_0x5d4661[_0x263156['id']]={'x':_0x1709c5,'y':_0x2fa0b3});const _0x3bfb2d=0x2===_0x53c50b?0x0===_0x3e417d?Math['PI']:0x0:_0x3e417d/_0x53c50b*Math['PI']*0x2-Math['PI']/0x2;_0x5d4661[_0x263156['id']]={'x':_0x1709c5+_0x5bf22f*Math[_0x104fa7(0x1d3)](_0x3bfb2d),'y':_0x2fa0b3+_0x5bf22f*Math[_0x104fa7(0x19a)](_0x3bfb2d)};}),this[_0x55e54f(0x1a6)]={'cx':_0x1709c5,'cy':_0x2fa0b3,'r':_0x5bf22f,'pos':_0x5d4661};},'_measure'(){const _0x4d60a1=_0x4a43e5,_0x259a37=(this[_0x4d60a1(0x221)]||_0x15953a['$el'])['getBoundingClientRect']();this['w']=Math[_0x4d60a1(0x180)](0x12c,_0x259a37[_0x4d60a1(0x19f)]||0x384),this['h']=Math['max'](0xc8,_0x259a37[_0x4d60a1(0x211)]||0x1f4),this['_recomputeLayout']();},'_effectivePos'(_0xf3dda){const _0x4662a2=_0x4a43e5;return this[_0x4662a2(0x161)][_0xf3dda]||this[_0x4662a2(0x1a6)]['pos']?.[_0xf3dda]||null;},'fitView'(){const _0x45ade7=_0x4a43e5;this['_measure']();const _0x11d823=this[_0x45ade7(0x200)];if(!_0x11d823[_0x45ade7(0x1da)])return;let _0x2287c2=0x1/0x0,_0x22cf34=0x1/0x0,_0x4dd328=-0x1/0x0,_0x2df4fd=-0x1/0x0;for(const _0x1f8884 of _0x11d823){const _0x39fe28=this['_effectivePos'](_0x1f8884['id']);_0x39fe28&&(_0x2287c2=Math[_0x45ade7(0x176)](_0x2287c2,_0x39fe28['x']),_0x22cf34=Math[_0x45ade7(0x176)](_0x22cf34,_0x39fe28['y']),_0x4dd328=Math[_0x45ade7(0x180)](_0x4dd328,_0x39fe28['x']),_0x2df4fd=Math[_0x45ade7(0x180)](_0x2df4fd,_0x39fe28['y']));}if(!isFinite(_0x2287c2))return;const _0x46c7d2=this[_0x45ade7(0x1c0)]()+0x3c;_0x2287c2-=_0x46c7d2,_0x22cf34-=_0x46c7d2,_0x4dd328+=_0x46c7d2,_0x2df4fd+=_0x46c7d2;const _0x29319b=_0x4dd328-_0x2287c2,_0x219148=_0x2df4fd-_0x22cf34,_0x5ba9d5=0.88*Math[_0x45ade7(0x176)](this['w']/_0x29319b,this['h']/_0x219148,0x3);this['zoom']=_0x5ba9d5,this[_0x45ade7(0x1ab)]=this['w']/0x2-(_0x2287c2+_0x29319b/0x2)*_0x5ba9d5,this['panY']=this['h']/0x2-(_0x22cf34+_0x219148/0x2)*_0x5ba9d5,this['_applyTransform']();},'resetLayout'(){const _0x3a7769=_0x4a43e5;this[_0x3a7769(0x161)]={};try{localStorage[_0x3a7769(0x1cb)]('okdb-topo-pos');}catch{}this[_0x3a7769(0x1b6)]();},'_savePositions'(){const _0x34c63b=_0x4a43e5;try{localStorage[_0x34c63b(0x1e1)](_0x34c63b(0x194),JSON[_0x34c63b(0x1e4)](this[_0x34c63b(0x161)]));}catch{}},'_loadPositions'(){const _0x2278bd=_0x4a43e5;try{const _0x52b477=localStorage['getItem'](_0x2278bd(0x194));_0x52b477&&(this[_0x2278bd(0x161)]=JSON['parse'](_0x52b477));}catch{}},'nodeRadius':()=>0x16,'linkPath'(_0x47857e){const _0x67a02c=_0x4a43e5,_0x372437=this[_0x67a02c(0x183)](_0x47857e['lo']),_0x533857=this[_0x67a02c(0x183)](_0x47857e['hi']);if(!_0x372437||!_0x533857)return'';const _0x1c8438=_0x533857['x']-_0x372437['x'],_0xc9f869=_0x533857['y']-_0x372437['y'],_0x2d092f=Math['sqrt'](_0x1c8438*_0x1c8438+_0xc9f869*_0xc9f869)||0x1,_0x1e8bc3=this[_0x67a02c(0x1c0)]();return'M\x20'+(_0x372437['x']+_0x1c8438/_0x2d092f*_0x1e8bc3)+'\x20'+(_0x372437['y']+_0xc9f869/_0x2d092f*_0x1e8bc3)+_0x67a02c(0x1f3)+(_0x533857['x']-_0x1c8438/_0x2d092f*_0x1e8bc3)+'\x20'+(_0x533857['y']-_0xc9f869/_0x2d092f*_0x1e8bc3);},'reconciling':!0x1,'reconcilingTarget':null,async 'refreshTopology'(){const _0x4b8daa=_0x4a43e5;if(!this[_0x4b8daa(0x20f)]){this[_0x4b8daa(0x20f)]=!0x0;try{const _0x375ca4=await fetch('/api/sync/topology'),_0x219362=await _0x375ca4['json'](),_0x293686=_0x219362[_0x4b8daa(0x17a)]??_0x219362;_0x15953a[_0x4b8daa(0x1f1)][_0x4b8daa(0x1db)]=_0x293686[_0x4b8daa(0x1db)]??_0x293686,_0x15953a[_0x4b8daa(0x1f1)][_0x4b8daa(0x210)]=_0x293686['availableEnvs']??[],this[_0x4b8daa(0x1ee)]=Date[_0x4b8daa(0x222)]();}catch(_0x156331){console['error']('refresh\x20failed',_0x156331);}finally{this[_0x4b8daa(0x20f)]=!0x1;}}},async 'reconcileAll'(){const _0x550684=_0x4a43e5;if(!this[_0x550684(0x218)]){this['reconciling']=!0x0,this[_0x550684(0x1ef)]=_0x550684(0x185);try{await fetch(_0x550684(0x1b8),{'method':_0x550684(0x1ec)}),await this[_0x550684(0x17f)]();}finally{this[_0x550684(0x218)]=!0x1,this['reconcilingTarget']=null;}}},async 'reconcileNode'(_0x201d35){const _0x5ee106=_0x4a43e5;if(!this[_0x5ee106(0x218)]){this[_0x5ee106(0x218)]=!0x0,this['reconcilingTarget']=_0x201d35;try{_0x201d35===this[_0x5ee106(0x21f)]?await fetch(_0x5ee106(0x206),{'method':'POST'}):await fetch(this[_0x5ee106(0x1db)][_0x201d35]?.[_0x5ee106(0x196)]+_0x5ee106(0x206),{'method':_0x5ee106(0x1ec)}),await this[_0x5ee106(0x17f)]();}finally{this[_0x5ee106(0x218)]=!0x1,this['reconcilingTarget']=null;}}},async 'reconcileLink'(_0x4e47de){const _0x1c4d96=_0x4a43e5;if(this[_0x1c4d96(0x218)])return;this['reconciling']=!0x0,this[_0x1c4d96(0x1ef)]=_0x4e47de[_0x1c4d96(0x163)];const _0x131567=_0x4e47de['lo']===this[_0x1c4d96(0x21f)]?_0x4e47de['hi']:_0x4e47de['lo'];try{await fetch('/api/sync/reconcile-peer',{'method':_0x1c4d96(0x1ec),'headers':{'Content-Type':_0x1c4d96(0x179)},'body':JSON[_0x1c4d96(0x1e4)]({'peer_id':_0x131567})}),await this[_0x1c4d96(0x17f)]();}finally{this['reconciling']=!0x1,this[_0x1c4d96(0x1ef)]=null;}},'openLinkEditor'(_0xa85a56){const _0x473af9=_0x4a43e5;this[_0x473af9(0x188)]=_0xa85a56,this[_0x473af9(0x195)]=_0xa85a56[_0x473af9(0x207)]?.[_0x473af9(0x1fb)]??_0x473af9(0x205),this[_0x473af9(0x1a4)]=_0xa85a56[_0x473af9(0x207)]?.[_0x473af9(0x1a5)]??null,this['linkEditEnabled']=!0x1!==_0xa85a56['link']?.['enabled'];},'closeLinkEditor'(){const _0x298aa9=_0x4a43e5;this[_0x298aa9(0x188)]=null;},'toggleLinkEnv'(_0x3309d){const _0x21748c=_0x4a43e5;if(null===this[_0x21748c(0x1a4)])this[_0x21748c(0x1a4)]=this['availableEnvs']['filter'](_0x4897f9=>_0x4897f9!==_0x3309d);else{const _0x3b9a10=new Set(this[_0x21748c(0x1a4)]);_0x3b9a10[_0x21748c(0x1c6)](_0x3309d)?_0x3b9a10['delete'](_0x3309d):_0x3b9a10[_0x21748c(0x19d)](_0x3309d);const _0x49584d=[..._0x3b9a10];this['linkEditEnvs']=_0x49584d['length']===this['availableEnvs'][_0x21748c(0x1da)]?null:_0x49584d;}},async 'saveLink'(){const _0x4bba0c=_0x4a43e5;if(!this[_0x4bba0c(0x188)]||this[_0x4bba0c(0x1a7)])return;this[_0x4bba0c(0x1a7)]=!0x0;const _0xec4a8d=this['editingLink'];try{const _0x50a35d=await fetch(_0x4bba0c(0x1c7)+_0xec4a8d['lo']+'/'+_0xec4a8d['hi'],{'method':_0x4bba0c(0x201),'headers':{'Content-Type':_0x4bba0c(0x179)},'body':JSON['stringify']({'direction':this[_0x4bba0c(0x195)],'envs':this[_0x4bba0c(0x1a4)],'enabled':this[_0x4bba0c(0x1a0)]})});if(!_0x50a35d['ok']){const _0x2af442=await _0x50a35d[_0x4bba0c(0x1f0)]();throw new Error(_0x2af442?.['error']?.[_0x4bba0c(0x18a)]||_0x4bba0c(0x19c));}this['closeLinkEditor'](),await this[_0x4bba0c(0x17f)]();}catch(_0x61fcbb){alert(_0x61fcbb[_0x4bba0c(0x18a)]);}finally{this[_0x4bba0c(0x1a7)]=!0x1;}},async 'deleteLink'(){const _0x3df017=_0x4a43e5;if(!this['editingLink']||this[_0x3df017(0x1a7)])return;if(!confirm(_0x3df017(0x16e)))return;this['savingLink']=!0x0;const _0x3bf2c8=this[_0x3df017(0x188)];try{await fetch('/api/sync/links/'+_0x3bf2c8['lo']+'/'+_0x3bf2c8['hi'],{'method':_0x3df017(0x199)}),this[_0x3df017(0x1eb)](),await this[_0x3df017(0x17f)]();}catch(_0x307b3e){alert(_0x307b3e[_0x3df017(0x18a)]);}finally{this[_0x3df017(0x1a7)]=!0x1;}},'deselect'(){const _0x8c205e=_0x4a43e5;this[_0x8c205e(0x181)]=null,this[_0x8c205e(0x20a)]=null,this[_0x8c205e(0x1b4)]=null,this['hoveredNodeId']=null,this['editingLink']=null,_0x15953a[_0x8c205e(0x1b3)]?.(_0x8c205e(0x172),null),_0x15953a[_0x8c205e(0x1b3)]?.('selectLink',null);},'pickNode'(_0x26c5e9){const _0x3bd40f=_0x4a43e5;this[_0x3bd40f(0x181)]=_0x26c5e9,this['selectedLinkKey']=null,this['editingLink']=null,_0x15953a[_0x3bd40f(0x1b3)]?.(_0x3bd40f(0x172),_0x26c5e9),_0x15953a['$dispatch']?.(_0x3bd40f(0x1f5),null);},'pickLink'(_0x3f144b){const _0x348adf=_0x4a43e5,_0x5337f6=this[_0x348adf(0x18f)][_0x348adf(0x1f7)](_0x294895=>_0x294895[_0x348adf(0x163)]===_0x3f144b)||null;if(_0x5337f6&&(!this[_0x348adf(0x181)]||_0x5337f6['lo']===this[_0x348adf(0x181)]||_0x5337f6['hi']===this[_0x348adf(0x181)])){if(this[_0x348adf(0x20a)]===_0x3f144b)return this[_0x348adf(0x20a)]=null,this[_0x348adf(0x188)]=null,void _0x15953a[_0x348adf(0x1b3)]?.(_0x348adf(0x1f5),null);this[_0x348adf(0x20a)]=_0x3f144b,this[_0x348adf(0x181)]||(this['selectedNodeId']=_0x5337f6['lo'],_0x15953a['$dispatch']?.(_0x348adf(0x172),this[_0x348adf(0x181)])),_0x15953a['$dispatch']?.(_0x348adf(0x1f5),_0x3f144b);}},async 'copy'(_0x2ba80f){const _0x58ee9c=_0x4a43e5;try{await navigator[_0x58ee9c(0x1dc)][_0x58ee9c(0x20b)](String(_0x2ba80f??''));}catch(_0xfb9f26){}},'_sPointerEventsFor'(_0x2baefa){const _0x5969a4=_0x4a43e5;return this[_0x5969a4(0x181)]&&_0x2baefa['lo']!==this[_0x5969a4(0x181)]&&_0x2baefa['hi']!==this[_0x5969a4(0x181)]?_0x5969a4(0x177):_0x5969a4(0x1fc);},'_sEnabledBadge':_0x3529dd=>_0x3529dd?'color:var(--ok)':_0x4a43e5(0x203),'_sEnabledBtn':_0x331a1c=>_0x331a1c?_0x4a43e5(0x1fd):_0x4a43e5(0x1a2),'nodeHealth'(_0x4da8e6){const _0x44829f=_0x4a43e5,_0x1aac57=this['links'][_0x44829f(0x1fe)](_0x5c90e3=>_0x5c90e3['lo']===_0x4da8e6||_0x5c90e3['hi']===_0x4da8e6);if(!_0x1aac57[_0x44829f(0x1da)])return'ok';const _0x5f19ff=_0x1aac57[_0x44829f(0x1bc)](_0x48a9c7=>this[_0x44829f(0x17e)](_0x48a9c7));return _0x5f19ff[_0x44829f(0x174)](_0x44829f(0x19b))?'error':_0x5f19ff[_0x44829f(0x174)](_0x44829f(0x16f))?_0x44829f(0x16b):_0x5f19ff[_0x44829f(0x174)]('lag-med')?'lagging':_0x5f19ff[_0x44829f(0x174)]('behind')?_0x44829f(0x15b):_0x5f19ff[_0x44829f(0x1cd)](_0x8bb64a=>_0x44829f(0x184)===_0x8bb64a||_0x44829f(0x178)===_0x8bb64a)?_0x44829f(0x184):'ok';},'isLinkInteractable'(_0x3e514f){const _0x221676=_0x4a43e5;return!this[_0x221676(0x181)]||_0x3e514f['lo']===this[_0x221676(0x181)]||_0x3e514f['hi']===this['selectedNodeId'];},'isActiveLink'(_0xd11bd1){const _0x1adccd=_0x4a43e5;return this[_0x1adccd(0x20a)]===_0xd11bd1[_0x1adccd(0x163)]||this[_0x1adccd(0x1b4)]===_0xd11bd1[_0x1adccd(0x163)]&&this['isLinkInteractable'](_0xd11bd1);},'nodeClass'(_0x4381dc){const _0x3b341a=_0x4a43e5;let _0x21e935='nd';const _0x4cf01f=this[_0x3b341a(0x181)],_0x1cdfea=this[_0x3b341a(0x1a1)];if(_0x4cf01f&&_0x4cf01f!==_0x4381dc['id']&&(_0x21e935+=_0x3b341a(0x219)),_0x4cf01f===_0x4381dc['id']&&(_0x21e935+=_0x3b341a(0x1b7)),this[_0x3b341a(0x20a)]){const _0x1408ff=this['links'][_0x3b341a(0x1f7)](_0x31d456=>_0x31d456[_0x3b341a(0x163)]===this[_0x3b341a(0x20a)]);!_0x1408ff||_0x1408ff['lo']!==_0x4381dc['id']&&_0x1408ff['hi']!==_0x4381dc['id']||_0x4cf01f===_0x4381dc['id']||(_0x21e935+=_0x3b341a(0x1df));}_0x4cf01f||_0x1cdfea!==_0x4381dc['id']||(_0x21e935+=_0x3b341a(0x20c));const _0x555744=this[_0x3b341a(0x175)](_0x4381dc['id']);return'error'===_0x555744?_0x21e935+=_0x3b341a(0x209):_0x3b341a(0x16b)===_0x555744?_0x21e935+=_0x3b341a(0x1cf):_0x3b341a(0x16c)===_0x555744?_0x21e935+=_0x3b341a(0x1aa):_0x3b341a(0x15b)===_0x555744?_0x21e935+=_0x3b341a(0x1a8):_0x3b341a(0x184)===_0x555744&&(_0x21e935+=_0x3b341a(0x189)),_0x21e935;},'linkClass'(_0x3b72a6){const _0xa2aa8d=_0x4a43e5;let _0x1e4120='ln';const _0x31ee1b=this[_0xa2aa8d(0x20a)]===_0x3b72a6[_0xa2aa8d(0x163)],_0x2b6135=this[_0xa2aa8d(0x1b4)]===_0x3b72a6['key']&&this[_0xa2aa8d(0x1ce)](_0x3b72a6);switch(this[_0xa2aa8d(0x1ce)](_0x3b72a6)||_0x31ee1b||(_0x1e4120+=_0xa2aa8d(0x15d)),_0x31ee1b?_0x1e4120+='\x20ln-selected':_0x2b6135&&(_0x1e4120+='\x20ln-hover'),this['_linkHealth'](_0x3b72a6)){case'disabled':_0x1e4120+=_0xa2aa8d(0x220);break;case'error':_0x1e4120+='\x20ln-err';break;case _0xa2aa8d(0x218):_0x1e4120+='\x20ln-rec';break;case'lag-high':_0x1e4120+=_0xa2aa8d(0x1a3);break;case _0xa2aa8d(0x202):_0x1e4120+=_0xa2aa8d(0x15a);break;case _0xa2aa8d(0x15b):_0x1e4120+=_0xa2aa8d(0x1c5);break;case _0xa2aa8d(0x184):_0x1e4120+=_0xa2aa8d(0x18e);break;default:_0x1e4120+=_0xa2aa8d(0x1bb);}return _0x1e4120;},'linkMarker'(_0x1cbdd6){const _0x3147d4=_0x4a43e5,_0x167e00=_0x1cbdd6[_0x3147d4(0x207)]?.['direction']??'both';return _0x3147d4(0x205)!==_0x167e00&&_0x3147d4(0x21c)!==_0x167e00?'':_0x1cbdd6['link']&&!_0x1cbdd6[_0x3147d4(0x207)][_0x3147d4(0x1d0)]?_0x3147d4(0x1c8):'url(#arrow-'+this[_0x3147d4(0x1de)](this[_0x3147d4(0x171)](_0x1cbdd6['hi_pull']))+')';},'linkStartMarker'(_0x5e0fe8){const _0x23983b=_0x4a43e5,_0x5dec82=_0x5e0fe8['link']?.[_0x23983b(0x1fb)]??_0x23983b(0x205);return _0x23983b(0x205)!==_0x5dec82&&_0x23983b(0x197)!==_0x5dec82?'':_0x5e0fe8[_0x23983b(0x207)]&&!_0x5e0fe8[_0x23983b(0x207)][_0x23983b(0x1d0)]?_0x23983b(0x1c4):'url(#arrow-rev-'+this[_0x23983b(0x1de)](this[_0x23983b(0x171)](_0x5e0fe8[_0x23983b(0x1dd)]))+')';}}),'mount'(_0x3e986c){const _0x29308c=_0x4a43e5;this[_0x29308c(0x221)]=_0x3e986c[_0x29308c(0x204)][_0x29308c(0x166)]('svg'),this[_0x29308c(0x208)]=this[_0x29308c(0x221)]?.[_0x29308c(0x166)](_0x29308c(0x1e7)),this[_0x29308c(0x221)]&&(this[_0x29308c(0x221)][_0x29308c(0x190)][_0x29308c(0x17d)]=_0x29308c(0x187)),this[_0x29308c(0x1e2)](),this[_0x29308c(0x1d6)](),this['_ro']=new ResizeObserver(()=>this[_0x29308c(0x1b6)]()),this[_0x29308c(0x168)]['observe'](_0x3e986c[_0x29308c(0x204)]),this[_0x29308c(0x1ca)]=setInterval(()=>{const _0x151586=_0x29308c;this[_0x151586(0x222)]=Date[_0x151586(0x222)]();},0x3e8),this[_0x29308c(0x17f)]()[_0x29308c(0x186)](()=>this[_0x29308c(0x1b6)]()),this[_0x29308c(0x167)]=_0x11198c=>{const _0x1f7f00=_0x29308c;_0x11198c[_0x1f7f00(0x1c9)](),this[_0x1f7f00(0x198)](_0x11198c);},this[_0x29308c(0x221)]&&this[_0x29308c(0x221)][_0x29308c(0x215)](_0x29308c(0x1e8),this[_0x29308c(0x167)],{'passive':!0x1}),this[_0x29308c(0x1be)]=_0x4ce6f0=>this['_onSvgMousedown'](_0x4ce6f0),this['_svgEl']&&this[_0x29308c(0x221)][_0x29308c(0x215)](_0x29308c(0x1ba),this[_0x29308c(0x1be)]),this[_0x29308c(0x160)]=_0x5c63a4=>this[_0x29308c(0x162)](_0x5c63a4),this['_mouseupCb']=()=>this[_0x29308c(0x170)](),window[_0x29308c(0x215)]('mousemove',this['_mousemoveCb']),window[_0x29308c(0x215)](_0x29308c(0x19e),this[_0x29308c(0x214)]),this[_0x29308c(0x1d1)]=()=>{const _0x493dcf=_0x29308c;document['hidden']||this[_0x493dcf(0x17f)]();},document[_0x29308c(0x215)](_0x29308c(0x1c1),this[_0x29308c(0x1d1)]),this[_0x29308c(0x173)]&&(this['_autoRefreshTimer']=setInterval(()=>this[_0x29308c(0x17f)](),this['autoRefreshIntervalMs'])),this[_0x29308c(0x181)]=this[_0x29308c(0x193)],_0x3e986c[_0x29308c(0x1e5)](()=>_0x3e986c['$attr'][_0x29308c(0x15e)],_0x32994d=>{const _0x597afd=_0x29308c;this[_0x597afd(0x181)]=_0x32994d??null,_0x32994d||(this[_0x597afd(0x20a)]=null);});},'unmount'(){const _0x35fab9=_0x4a43e5;this[_0x35fab9(0x168)]?.[_0x35fab9(0x1f9)](),clearInterval(this[_0x35fab9(0x1ca)]),clearInterval(this[_0x35fab9(0x212)]),this[_0x35fab9(0x221)]&&(this[_0x35fab9(0x221)][_0x35fab9(0x1ed)](_0x35fab9(0x1e8),this[_0x35fab9(0x167)]),this[_0x35fab9(0x221)][_0x35fab9(0x1ed)]('mousedown',this[_0x35fab9(0x1be)])),window[_0x35fab9(0x1ed)]('mousemove',this[_0x35fab9(0x160)]),window[_0x35fab9(0x1ed)]('mouseup',this[_0x35fab9(0x214)]),document[_0x35fab9(0x1ed)](_0x35fab9(0x1c1),this[_0x35fab9(0x1d1)]);},'template':_0x4a43e5(0x224)};function _0x38cf(){const _0xa9b2ff=['clientY','canon','cursor','_linkHealth','refreshTopology','max','selectedNodeId','get','_effectivePos','stale','all','then','grab','editingLink','\x20nd-stale','message','pan','\x20→\x20','413749XVCXkF','\x20ln-stale','links','style','202610BwJWPL','last_error','externalSelectedNodeId','okdb-topo-pos','linkEditDir','address','hi_to_lo','_onWheel','DELETE','sin','error','Save\x20failed','add','mouseup','width','linkEditEnabled','hoveredNodeId','border-color:var(--dis);color:var(--dis)','\x20ln-lag-high','linkEditEnvs','envs','layout','savingLink','\x20nd-behind','sync-topology','\x20nd-lag','panX','peers','idle','button','getBoundingClientRect','setAttribute','hi_pull','clock','$dispatch','hoveredLinkKey','last_seen','fitView','\x20nd-sel','/api/sync/reconcile-all','transform','mousedown','\x20ln-ok','map','5CDsYtV','_mousedownCb','9115887rawOJG','nodeRadius','visibilitychange','left','134672EqdNxI','url(#arrow-rev-disabled)','\x20ln-behind-light','has','/api/sync/links/','url(#arrow-disabled)','preventDefault','_tick','removeItem','localeCompare','every','isLinkInteractable','\x20nd-critical','enabled','_visibilityHandler','1273834ImusrS','cos','sort','values','_loadPositions','1999338HVQihs','floor','clientX','length','topology','clipboard','lo_pull','_healthMarker','\x20nd-sel2','fresh-now','setItem','_measure','forEach','stringify','$watch',')\x20scale(','.topo-g','wheel','backlog','fresh-stale','closeLinkEditor','POST','removeEventListener','lastUpdatedAt','reconcilingTarget','json','$attr','rec','\x20L\x20','target','selectLink','border-color:var(--accent);color:var(--accent);background:var(--bg)','find','\x20(mesh)','disconnect','_px2vb','direction','pointer-events:stroke;cursor:pointer','border-color:var(--ok);color:var(--ok)','filter','top','nodes','PUT','lag-med','color:var(--dis);opacity:0.7','$el','both','/api/sync/reconcile','link','_groupEl','\x20nd-err','selectedLinkKey','writeText','\x20nd-hover','translate(','panY','loadingTopology','available_envs','height','_autoRefreshTimer','211804DUUYFq','_mouseupCb','addEventListener','99HrUjnn','node','reconciling','\x20nd-dim','_savePositions','\x20⇄\x20','lo_to_hi','parentElement','16rhNUrH','selfId','\x20ln-disabled','_svgEl','now','slice','<div\x20style=\x22--bg:var(--okdb-app-bg-deep);\x20--panel:var(--okdb-app-surface);\x20--panel2:var(--okdb-app-bg-deep);\x20--border:var(--okdb-app-border);\x20--border2:var(--okdb-app-surface-2);\x0a\x20\x20--text:var(--okdb-app-fg);\x20--muted:var(--okdb-app-fg-muted);\x20--accent:var(--okdb-accent);\x20--ok:var(--okdb-success);\x20--rec:var(--okdb-accent);\x0a\x20\x20--warn:var(--okdb-warning);\x20--bad:var(--okdb-danger);\x20--err:var(--okdb-danger);\x20--dis:var(--okdb-app-fg-subtle);\x0a\x20\x20border:1px\x20solid\x20var(--border);\x20border-radius:12px;\x20background:var(--bg);\x20color:var(--text);\x0a\x20\x20display:flex;\x20flex-direction:column;\x20flex:1;\x20position:relative;\x20overflow:hidden;\x0a\x20\x20font-family:\x20ui-monospace,\x20monospace;\x22><div\x20style=\x22padding:12px\x2014px;display:flex;justify-content:space-between;border-bottom:1px\x20solid\x20var(--border2);background:var(--panel);align-items:center;\x22><div\x20style=\x22display:flex;align-items:center;gap:10px;\x22><div\x20style=\x22font-weight:700;letter-spacing:0.8px;color:var(--accent);\x22>NETWORK_TOPOLOGY</div><button\x20@click=\x22reconcileAll()\x22\x20:disabled=\x22reconciling\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;\x22><span\x20style=\x22display:flex;align-items:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===\x27all\x27?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===\x27all\x27?\x27RECONCILING\x27:\x27RECONCILE\x20ALL\x27}}</span></button>\x20<button\x20@click=\x22refreshTopology()\x22\x20:disabled=\x22loadingTopology\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22>REFRESH</button>\x20<button\x20@click=\x22fitView()\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22\x20title=\x22Fit\x20all\x20nodes\x20into\x20view\x22>FIT</button>\x20<button\x20@click=\x22resetLayout()\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22\x20title=\x22Reset\x20node\x20positions\x22>RESET</button>\x20<span\x20:style=\x22{opacity:loadingTopology?1:0}\x22\x20class=\x22spinner\x22/></div><div\x20style=\x22display:flex;align-items:center;gap:12px;font-size:11px;\x22><span\x20:class=\x22freshnessClass\x22>updated:\x20{{freshnessLabel}}</span>\x20<span\x20style=\x22opacity:0.75;\x22>{{nodes.length}}\x20NODES\x20//\x20{{links.length}}\x20LINKS</span></div></div><div\x20style=\x22flex:1;position:relative;\x22><svg\x20:viewBox=\x22\x270\x200\x20\x27+w+\x27\x20\x27+h\x22\x20style=\x22width:100%;height:100%;\x22><rect\x20:width=\x22w\x22\x20:height=\x22h\x22\x20fill=\x22transparent\x22\x20style=\x22pointer-events:all\x22\x20@click=\x22deselect()\x22/><defs><marker\x20id=\x22arrow-ok\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--ok)\x22/></marker><marker\x20id=\x22arrow-rec\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--rec)\x22/></marker><marker\x20id=\x22arrow-err\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--err)\x22/></marker><marker\x20id=\x22arrow-lag-med\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--warn)\x22/></marker><marker\x20id=\x22arrow-lag-high\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--bad)\x22/></marker><marker\x20id=\x22arrow-disabled\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--dis)\x22/></marker><marker\x20id=\x22arrow-rev-ok\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--ok)\x22/></marker><marker\x20id=\x22arrow-rev-rec\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--rec)\x22/></marker><marker\x20id=\x22arrow-rev-err\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--err)\x22/></marker><marker\x20id=\x22arrow-rev-lag-med\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--warn)\x22/></marker><marker\x20id=\x22arrow-rev-lag-high\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--bad)\x22/></marker><marker\x20id=\x22arrow-rev-disabled\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--dis)\x22/></marker></defs><style>.ln\x20{\x20fill:none;\x20stroke-width:1.9;\x20opacity:0.70;\x20transition:opacity\x200.14s,stroke-width\x200.14s,filter\x200.14s;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-ok\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--ok);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-behind-light\x20{\x20stroke:var(--okdb-info);\x20opacity:0.8;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-rec\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--rec);\x20stroke-dasharray:4\x203;\x20animation:dash\x201.1s\x20linear\x20infinite;\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.5));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-lag-med\x20\x20\x20\x20\x20\x20{\x20stroke:var(--warn);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-lag-high\x20\x20\x20\x20\x20{\x20stroke:var(--bad);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-err\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--err);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-stale\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--okdb-app-fg-subtle);\x20opacity:0.5;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-disabled\x20\x20\x20\x20\x20{\x20stroke:var(--dis);\x20stroke-dasharray:6\x204;\x20opacity:0.45;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-dim\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20opacity:0.08;\x20filter:none\x20!important;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-hover\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke-width:3.0;\x20opacity:1;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-selected\x20\x20\x20\x20\x20{\x20stroke:var(--accent)\x20!important;\x20stroke-width:5.2\x20!important;\x20opacity:1\x20!important;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.9))\x20drop-shadow(0\x200\x2010px\x20rgba(77,163,255,0.35));\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd\x20circle\x20{\x20fill:var(--bg);\x20stroke:var(--border);\x20stroke-width:2;\x20transition:stroke\x200.14s,stroke-width\x200.14s,filter\x200.14s,opacity\x200.14s;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd\x20text\x20\x20\x20{\x20fill:var(--muted);\x20font-size:11px;\x20pointer-events:none;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-hover\x20\x20circle\x20{\x20stroke:rgba(77,163,255,0.8);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-sel\x20\x20\x20\x20circle\x20{\x20stroke:var(--accent);\x20stroke-width:3.4;\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.75))\x20drop-shadow(0\x200\x2010px\x20rgba(77,163,255,0.25));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-sel2\x20\x20\x20circle\x20{\x20stroke:rgba(77,163,255,0.75);\x20stroke-width:3.0;\x20filter:drop-shadow(0\x200\x206px\x20rgba(77,163,255,0.25));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-dim\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20opacity:0.22;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-err\x20\x20\x20\x20circle\x20\x20{\x20stroke:var(--err);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-stale\x20\x20circle\x20\x20{\x20stroke:var(--okdb-app-fg-subtle);\x20stroke-width:2;\x20opacity:0.7;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-behind\x20circle\x20\x20{\x20stroke:var(--okdb-info);\x20stroke-width:2.5;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-lag\x20\x20\x20\x20circle\x20\x20{\x20stroke:var(--warn);\x20stroke-width:3;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-critical\x20circle\x20{\x20stroke:var(--bad);\x20stroke-width:3.5;\x20filter:drop-shadow(0\x200\x206px\x20rgba(255,77,77,0.5));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-now\x20\x20\x20{\x20color:var(--ok);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-ok\x20\x20\x20\x20{\x20color:var(--okdb-info);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-stale\x20{\x20color:var(--warn);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.spinner\x20{\x20display:inline-block;\x20width:12px;\x20height:12px;\x20border:2px\x20solid\x20rgba(77,163,255,0.2);\x20border-top:2px\x20solid\x20var(--accent);\x20border-radius:50%;\x20animation:spin\x200.8s\x20linear\x20infinite;\x20flex-shrink:0;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20@keyframes\x20dash\x20{\x20to\x20{\x20stroke-dashoffset:-14;\x20}\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20@keyframes\x20spin\x20\x20{\x20to\x20{\x20transform:rotate(360deg);\x20}\x20}</style><g\x20class=\x22topo-g\x22><for\x20:=\x22links\x22\x20let:l><if\x20:=\x22!isActiveLink(l)\x22><g><path\x20:d=\x22linkPath(l)\x22\x20stroke=\x22transparent\x22\x20stroke-width=\x2214\x22\x20fill=\x22none\x22\x20:style=\x22_sPointerEventsFor(l)\x22\x20@mouseenter=\x22isLinkInteractable(l)?(hoveredLinkKey=l.key):null\x22\x20@mouseleave=\x22hoveredLinkKey=null\x22\x20@click=\x22pickLink(l.key)\x22/><path\x20:d=\x22linkPath(l)\x22\x20:class=\x22linkClass(l)\x22\x20:marker-end=\x22linkMarker(l)\x22\x20:marker-start=\x22linkStartMarker(l)\x22><title>{{l.lo.slice(0,8)}}\x20↔\x20{{l.hi.slice(0,8)}}\x20direction:\x20{{l.link\x20?\x20l.link.direction\x20:\x20\x27mesh\x27}}\x20enabled:\x20{{l.link\x20?\x20l.link.enabled\x20:\x20true}}\x20envs:\x20{{l.link\x20&&\x20l.link.envs\x20?\x20l.link.envs.join(\x27,\x20\x27)\x20:\x20\x27all\x27}}</title></path></g></if></for><for\x20:=\x22nodeList\x22\x20let:n><g\x20:id=\x22\x27nd-\x27+n.id\x22\x20:transform=\x22\x27translate(\x27+n.px+\x27,\x27+n.py+\x27)\x27\x22\x20:class=\x22nodeClass(n)\x22\x20@mouseenter=\x22hoveredNodeId=n.id\x22\x20@mouseleave=\x22hoveredNodeId=null\x22\x20@click=\x22pickNode(n.id)\x22><circle\x20:r=\x22nodeRadius()\x22/><text\x20text-anchor=\x22middle\x22\x20dy=\x224\x22>{{n.id.slice(0,6)}}</text><title>{{n.id}}\x20clock:\x20{{n.clock\x20??\x20\x27--\x27}}\x20addr:\x20{{n.address\x20??\x20\x27—\x27}}</title></g></for><for\x20:=\x22links\x22\x20let:l><if\x20:=\x22isActiveLink(l)\x22><g><path\x20:d=\x22linkPath(l)\x22\x20stroke=\x22transparent\x22\x20stroke-width=\x2216\x22\x20fill=\x22none\x22\x20:style=\x22_sPointerEventsFor(l)\x22\x20@mouseenter=\x22isLinkInteractable(l)?(hoveredLinkKey=l.key):null\x22\x20@mouseleave=\x22hoveredLinkKey=null\x22\x20@click=\x22pickLink(l.key)\x22/><path\x20:d=\x22linkPath(l)\x22\x20:class=\x22linkClass(l)\x22\x20:marker-end=\x22linkMarker(l)\x22\x20:marker-start=\x22linkStartMarker(l)\x22/></g></if></for></g></svg><if\x20:=\x22selection\x20||\x20editingLink\x22><div\x20style=\x22position:absolute;top:18px;right:18px;width:320px;background:var(--panel);border:1px\x20solid\x20var(--border);border-radius:12px;padding:16px;box-shadow:0\x2016px\x2034px\x20rgba(0,0,0,0.45);border-left:4px\x20solid\x20var(--accent);\x22><div\x20style=\x22display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;\x22><span\x20style=\x22font-size:10px;background:var(--bg);padding:3px\x207px;border-radius:6px;color:var(--accent);letter-spacing:0.6px;\x22>{{editingLink\x20?\x20\x27LINK_CONFIG\x27\x20:\x20selection.type.toUpperCase()}}\x20</span><span\x20@click=\x22editingLink\x20?\x20closeLinkEditor()\x20:\x20deselect()\x22\x20style=\x22cursor:pointer;opacity:0.7;font-size:16px;line-height:12px;\x22>×</span></div><if\x20:=\x22!editingLink\x20&&\x20selection\x20&&\x20selection.type\x20===\x20\x27node\x27\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;\x22><div\x20style=\x22color:var(--text);font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\x22>{{selection.id}}</div><button\x20@click=\x22copy(selection.id)\x22\x20style=\x22border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);font-size:11px;padding:4px\x208px;border-radius:8px;cursor:pointer;\x22>copy</button></div><div\x20style=\x22display:grid;grid-template-columns:92px\x201fr;row-gap:8px;column-gap:10px;\x22><div\x20style=\x22opacity:0.65;\x22>Clock</div><div>{{selection.data.clock??\x27--\x27}}</div><div\x20style=\x22opacity:0.65;\x22>Addr</div><div\x20style=\x22font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\x22>{{selection.data.address||\x27N/A\x27}}</div><div\x20style=\x22opacity:0.65;\x22>Status</div><div\x20:style=\x22selection.data.error?\x27color:var(--err)\x27:\x27color:var(--ok)\x27\x22>{{selection.data.error?(\x27ERR:\x20\x27+selection.data.error):\x27OK\x27}}</div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Tags</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:6px;\x22><if\x20:=\x22!(selection.data.tags\x20||\x20[]).length\x22><span\x20style=\x22font-size:11px;opacity:0.45;\x22>No\x20tags</span></if><for\x20:=\x22selection.data.tags\x20||\x20[]\x22\x20let:tag><span\x20style=\x22font-size:10px;padding:2px\x208px;border-radius:999px;border:1px\x20solid\x20var(--okdb-accent-soft-border);color:var(--okdb-accent);background:var(--okdb-accent-soft-bg);\x22>{{tag}}</span></for></div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Available\x20envs</div><div\x20style=\x22font-size:11px;color:var(--muted);line-height:1.5;word-break:break-word;\x22>{{(selection.data.availableEnvs\x20||\x20[]).join(\x27,\x20\x27)\x20||\x20\x27—\x27}}</div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Outbound\x20peers</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:6px;\x22><for\x20:=\x22Object.keys(selection.data.peers||{})\x22\x20let:pid><span\x20style=\x22font-size:11px;padding:3px\x207px;border:1px\x20solid\x20var(--border);background:var(--panel2);border-radius:999px;color:var(--muted);\x22>{{pid.slice(0,8)}}</span></for></div></div><div\x20style=\x22margin-top:14px;\x22><button\x20@click=\x22reconcileNode(selection.id)\x22\x20:disabled=\x22reconciling\x22\x20style=\x22width:100%;box-sizing:border-box;padding:6px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===selection.id?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===selection.id?\x27RECONCILING\x27:\x27RECONCILE\x20NODE\x27}}</span></button></div></div></if><if\x20:=\x22!editingLink\x20&&\x20selection\x20&&\x20selection.type\x20===\x20\x27link\x27\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22margin-bottom:12px;\x22><div\x20style=\x22display:flex;align-items:center;gap:8px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;font-size:12px;font-weight:700;\x22>{{selection.data.lo.slice(0,8)}}</span>\x20<span\x20style=\x22font-size:16px;color:var(--accent);\x22>{{selection.data.link\x20?\x20(selection.data.link.direction\x20===\x20\x27lo_to_hi\x27\x20?\x20\x27→\x27\x20:\x20selection.data.link.direction\x20===\x20\x27hi_to_lo\x27\x20?\x20\x27←\x27\x20:\x20\x27⇄\x27)\x20:\x20\x27⇄\x27}}\x20</span><span\x20style=\x22font-family:monospace;font-size:12px;font-weight:700;\x22>{{selection.data.hi.slice(0,8)}}</span><if\x20:=\x22selection.data.link\x22><span\x20style=\x22font-size:11px;margin-left:4px;\x22\x20:style=\x22_sEnabledBadge(selection.data.link.enabled)\x22>{{selection.data.link.enabled\x20?\x20\x27●\x20on\x27\x20:\x20\x27○\x20off\x27}}</span></if></div><if\x20:=\x22selection.data.link\x20&&\x20selection.data.link.envs\x22><div\x20style=\x22font-size:11px;opacity:0.45;\x22>envs:\x20{{selection.data.link.envs.join(\x27,\x20\x27)}}</div></if><if\x20:=\x22!selection.data.link\x22><div\x20style=\x22font-size:11px;opacity:0.45;\x22>no\x20link\x20config\x20—\x20mesh\x20(legacy)</div></if></div><div\x20style=\x22border:1px\x20solid\x20var(--border2);border-radius:8px;overflow:hidden;margin-bottom:12px;font-size:11px;\x22><if\x20:=\x22!selection.data.link\x20||\x20selection.data.link.direction\x20===\x20\x27both\x27\x20||\x20selection.data.link.direction\x20===\x20\x27lo_to_hi\x27\x22><div\x20style=\x22padding:9px\x2011px;border-bottom:1px\x20solid\x20var(--bg);\x22><div\x20style=\x22display:flex;align-items:center;gap:6px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.lo.slice(0,6)}}</span>\x20<span\x20style=\x22color:var(--accent);\x22>→</span>\x20<span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.hi.slice(0,6)}}</span>\x20<span\x20style=\x22opacity:0.4;\x22>(hi\x20receives\x20from\x20lo)</span></div><div\x20style=\x22display:grid;grid-template-columns:70px\x201fr;row-gap:4px;gap:6px;opacity:0.85;\x22><span\x20style=\x22opacity:0.5;\x22>status</span>\x20<span>{{selection.data.hi_pull\x20?\x20selection.data.hi_pull.status\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>backlog</span>\x20<span>{{selection.data.hi_pull\x20?\x20selection.data.hi_pull.backlog\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>last\x20seen</span>\x20<span>{{selection.data.hi_pull\x20&&\x20selection.data.hi_pull.last_seen\x20?\x20(Math.round((now\x20-\x20selection.data.hi_pull.last_seen)/1000)\x20+\x20\x27s\x20ago\x27)\x20:\x20\x27—\x27}}</span><if\x20:=\x22selection.data.hi_pull\x20&&\x20selection.data.hi_pull.last_error\x22><span\x20style=\x22opacity:0.5;\x22>error</span>\x20<span\x20style=\x22color:var(--err);\x22>{{selection.data.hi_pull.last_error}}</span></if></div></div></if><if\x20:=\x22!selection.data.link\x20||\x20selection.data.link.direction\x20===\x20\x27both\x27\x20||\x20selection.data.link.direction\x20===\x20\x27hi_to_lo\x27\x22><div\x20style=\x22padding:9px\x2011px;\x22><div\x20style=\x22display:flex;align-items:center;gap:6px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.hi.slice(0,6)}}</span>\x20<span\x20style=\x22color:var(--accent);\x22>→</span>\x20<span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.lo.slice(0,6)}}</span>\x20<span\x20style=\x22opacity:0.4;\x22>(lo\x20receives\x20from\x20hi)</span></div><div\x20style=\x22display:grid;grid-template-columns:70px\x201fr;row-gap:4px;gap:6px;opacity:0.85;\x22><span\x20style=\x22opacity:0.5;\x22>status</span>\x20<span>{{selection.data.lo_pull\x20?\x20selection.data.lo_pull.status\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>backlog</span>\x20<span>{{selection.data.lo_pull\x20?\x20selection.data.lo_pull.backlog\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>last\x20seen</span>\x20<span>{{selection.data.lo_pull\x20&&\x20selection.data.lo_pull.last_seen\x20?\x20(Math.round((now\x20-\x20selection.data.lo_pull.last_seen)/1000)\x20+\x20\x27s\x20ago\x27)\x20:\x20\x27—\x27}}</span><if\x20:=\x22selection.data.lo_pull\x20&&\x20selection.data.lo_pull.last_error\x22><span\x20style=\x22opacity:0.5;\x22>error</span>\x20<span\x20style=\x22color:var(--err);\x22>{{selection.data.lo_pull.last_error}}</span></if></div></div></if></div><div\x20style=\x22display:flex;flex-direction:column;gap:7px;\x22><button\x20@click=\x22reconcileLink(selection.data)\x22\x20:disabled=\x22reconciling\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===selection.data.key?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===selection.data.key\x20?\x20\x27Reconciling…\x27\x20:\x20\x27Reconcile\x27}}</span></button>\x20<button\x20@click=\x22openLinkEditor(selection.data)\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:12px;\x22>✎\x20Configure\x20Link</button></div></div></if><if\x20:=\x22editingLink\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-family:monospace;font-size:11px;opacity:0.5;margin-bottom:2px;\x22>link\x20id</div><div\x20style=\x22font-family:monospace;font-size:11px;\x22>{{editingLink.key}}</div></div><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-size:11px;opacity:0.5;margin-bottom:7px;\x22>Direction</div><div\x20style=\x22display:flex;flex-direction:column;gap:5px;\x22><for\x20:=\x22dirButtons\x22\x20let:btn><button\x20@click=\x22linkEditDir\x20=\x20btn.canon\x22\x20:style=\x22btn.style\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px\x2010px;border-radius:7px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:12px;font-family:monospace;text-align:left;\x22>{{btn.label}}</button></for></div></div><if\x20:=\x22availableEnvs.length\x22><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-size:11px;opacity:0.5;margin-bottom:7px;\x22>Data\x20envs\x20—\x20{{linkEditEnvs\x20===\x20null\x20?\x20\x27all\x27\x20:\x20linkEditEnvs.length\x20+\x20\x27\x20selected\x27}}</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:5px;\x22><for\x20:=\x22envButtons\x22\x20let:btn><button\x20@click=\x22toggleLinkEnv(btn.name)\x22\x20:style=\x22btn.style\x22\x20style=\x22padding:4px\x2010px;border-radius:6px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:11px;\x22>{{btn.name}}</button></for></div></div></if><div\x20style=\x22margin-bottom:16px;display:flex;align-items:center;gap:10px;\x22><span\x20style=\x22font-size:11px;opacity:0.5;\x22>Enabled</span>\x20<button\x20@click=\x22linkEditEnabled=!linkEditEnabled\x22\x20:style=\x22_sEnabledBtn(linkEditEnabled)\x22\x20style=\x22padding:4px\x2012px;border-radius:6px;border:1px\x20solid;background:var(--panel2);cursor:pointer;font-size:11px;\x22>{{linkEditEnabled\x20?\x20\x27●\x20ON\x27\x20:\x20\x27○\x20OFF\x27}}</button></div><div\x20style=\x22display:flex;gap:8px;\x22><button\x20@click=\x22saveLink()\x22\x20:disabled=\x22savingLink\x22\x20style=\x22flex:1;padding:8px;border-radius:8px;border:1px\x20solid\x20var(--accent);background:rgba(77,163,255,0.1);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:5px;\x22><span\x20:style=\x22savingLink?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20Save</span></button>\x20<button\x20@click=\x22deleteLink()\x22\x20:disabled=\x22savingLink\x22\x20style=\x22padding:8px\x2014px;border-radius:8px;border:1px\x20solid\x20#3d1a1a;background:rgba(255,59,48,0.08);color:var(--err);cursor:pointer;font-size:12px;\x22>Remove</button></div></div></if></div></if></div><div\x20style=\x22padding:9px\x2014px;background:var(--bg);border-top:1px\x20solid\x20var(--border2);display:flex;gap:16px;font-size:11px;align-items:center;flex-wrap:wrap;opacity:0.9;\x22><span><span\x20style=\x22color:var(--ok);\x22>●</span>\x20synced</span>\x20<span><span\x20style=\x22color:var(--okdb-info);\x22>●</span>\x20behind</span>\x20<span><span\x20style=\x22color:var(--rec);\x22>●</span>\x20reconciling</span>\x20<span><span\x20style=\x22color:var(--warn);\x22>●</span>\x20lag</span>\x20<span><span\x20style=\x22color:var(--err);\x22>●</span>\x20error</span>\x20<span><span\x20style=\x22color:var(--dis);\x22>●</span>\x20disabled</span>\x20<span\x20style=\x22opacity:0.4;\x22>⇄\x20both\x20→\x20send\x20←\x20receive\x20--\x20disabled\x20(click\x20to\x20inspect)</span></div></div>','_drag','zoom','51lAEYxG','\x20ln-lag-med','behind','_applyTransform','\x20ln-dim','selected_node_id','indexOf','_mousemoveCb','_customPos','_onMousemove','key','few\x20seconds\x20ago','status','querySelector','_wheelCb','_ro','deltaY','startsWith','critical','lagging','push','Remove\x20this\x20data\x20link?\x20Nodes\x20stay\x20connected\x20but\x20data\x20will\x20stop\x20syncing.','lag-high','_onMouseup','_pullHealth','select','autoRefresh','includes','nodeHealth','min','pointer-events:none','disabled','application/json','data'];_0x38cf=function(){return _0xa9b2ff;};return _0x38cf();}
|
|
1
|
+
const _0xd27273=_0x51ef;(function(_0x9c289,_0x1a32d2){const _0x2d984d=_0x51ef,_0x146e66=_0x9c289();while(!![]){try{const _0x4bd275=-parseInt(_0x2d984d(0x18c))/0x1*(-parseInt(_0x2d984d(0x184))/0x2)+-parseInt(_0x2d984d(0x191))/0x3*(parseInt(_0x2d984d(0x150))/0x4)+parseInt(_0x2d984d(0xdb))/0x5*(-parseInt(_0x2d984d(0x199))/0x6)+-parseInt(_0x2d984d(0x104))/0x7+parseInt(_0x2d984d(0x181))/0x8+parseInt(_0x2d984d(0x14f))/0x9+parseInt(_0x2d984d(0xfa))/0xa*(parseInt(_0x2d984d(0x183))/0xb);if(_0x4bd275===_0x1a32d2)break;else _0x146e66['push'](_0x146e66['shift']());}catch(_0x43ab97){_0x146e66['push'](_0x146e66['shift']());}}}(_0x28ed,0x36d7f));export default{'tag':_0xd27273(0x15c),'unwrap':!0x0,'context':_0x57a432=>({'w':0x384,'h':0x1f4,'layout':{'cx':0x0,'cy':0x0,'r':0x0,'pos':{}},'_ro':null,'_tick':null,'now':Date['now'](),'selectedNodeId':null,'selectedLinkKey':null,'hoveredLinkKey':null,'hoveredNodeId':null,'lastUpdatedAt':null,'autoRefresh':!0x0,'autoRefreshIntervalMs':0x1388,'_autoRefreshTimer':null,'loadingTopology':!0x1,'editingLink':null,'linkEditDir':'both','linkEditEnvs':null,'linkEditEnabled':!0x0,'savingLink':!0x1,'panX':0x0,'panY':0x0,'zoom':0x1,'_drag':null,'_customPos':{},'_svgEl':null,'_groupEl':null,'_applyTransform'(){const _0x1c09fe=_0xd27273;this[_0x1c09fe(0xfe)]||(this[_0x1c09fe(0xfe)]=this[_0x1c09fe(0x141)]?.[_0x1c09fe(0xec)]('.topo-g')),this[_0x1c09fe(0xfe)]&&this[_0x1c09fe(0xfe)][_0x1c09fe(0x17c)](_0x1c09fe(0x107),_0x1c09fe(0x14c)+this[_0x1c09fe(0x119)]+','+this[_0x1c09fe(0x103)]+')\x20scale('+this[_0x1c09fe(0xdf)]+')');},'_px2vb'(){const _0xadcf06=_0xd27273;if(!this[_0xadcf06(0x141)])return{'sx':0x1,'sy':0x1};const _0x3df705=this[_0xadcf06(0x141)]['getBoundingClientRect']();return{'sx':this['w']/(_0x3df705['width']||0x1),'sy':this['h']/(_0x3df705[_0xadcf06(0xd4)]||0x1)};},'_onWheel'(_0x5a8dfa){const _0x214703=_0xd27273;if(!this[_0x214703(0x141)])return;const _0x117a70=this[_0x214703(0x141)]['getBoundingClientRect'](),{sx:_0xa323aa,sy:_0x1e74d4}=this['_px2vb'](),_0x28ecd1=(_0x5a8dfa[_0x214703(0x13b)]-_0x117a70[_0x214703(0x13a)])*_0xa323aa,_0x2f709d=(_0x5a8dfa[_0x214703(0x101)]-_0x117a70[_0x214703(0xed)])*_0x1e74d4,_0x310c21=_0x5a8dfa[_0x214703(0x187)]<0x0?1.12:0x1/1.12,_0x49b536=Math[_0x214703(0xe6)](0.1,Math[_0x214703(0x177)](0x8,this[_0x214703(0xdf)]*_0x310c21)),_0x2fa66f=_0x49b536/this[_0x214703(0xdf)];this['panX']=_0x28ecd1+(this[_0x214703(0x119)]-_0x28ecd1)*_0x2fa66f,this[_0x214703(0x103)]=_0x2f709d+(this[_0x214703(0x103)]-_0x2f709d)*_0x2fa66f,this[_0x214703(0xdf)]=_0x49b536,this[_0x214703(0xfd)]();},'_onSvgMousedown'(_0x33b751){const _0x27aac6=_0xd27273;if(0x0!==_0x33b751[_0x27aac6(0x116)])return;_0x33b751[_0x27aac6(0x106)]();let _0x42ec5e=null,_0x1fe3e7=_0x33b751[_0x27aac6(0x144)];for(;_0x1fe3e7&&_0x1fe3e7!==this['_svgEl'];){if(_0x1fe3e7['id']&&_0x1fe3e7['id'][_0x27aac6(0x131)](_0x27aac6(0x148))){_0x42ec5e=_0x1fe3e7['id']['slice'](0x3);break;}_0x1fe3e7=_0x1fe3e7[_0x27aac6(0x166)];}if(_0x42ec5e){const _0x9aba2f=this[_0x27aac6(0x141)][_0x27aac6(0x15a)](),{sx:_0x1d64dd,sy:_0x315989}=this[_0x27aac6(0x112)](),_0x5070d2=(_0x33b751[_0x27aac6(0x13b)]-_0x9aba2f['left'])*_0x1d64dd,_0x4be013=(_0x33b751[_0x27aac6(0x101)]-_0x9aba2f['top'])*_0x315989,_0x5cfb0f=(_0x5070d2-this['panX'])/this[_0x27aac6(0xdf)],_0x59841a=(_0x4be013-this['panY'])/this[_0x27aac6(0xdf)],_0x5d12e1=this['_effectivePos'](_0x42ec5e)||{'x':_0x5cfb0f,'y':_0x59841a};this[_0x27aac6(0x157)]={'type':_0x27aac6(0x140),'id':_0x42ec5e,'ox':_0x5cfb0f-_0x5d12e1['x'],'oy':_0x59841a-_0x5d12e1['y']};}else this['_drag']={'type':'pan','sx':_0x33b751[_0x27aac6(0x13b)],'sy':_0x33b751[_0x27aac6(0x101)],'px':this[_0x27aac6(0x119)],'py':this[_0x27aac6(0x103)]};this[_0x27aac6(0x141)]&&(this[_0x27aac6(0x141)][_0x27aac6(0x193)]['cursor']=_0x27aac6(0x188));},'_onMousemove'(_0x551fc4){const _0x3b5be1=_0xd27273;if(!this[_0x3b5be1(0x157)])return;const {sx:_0x1e659c,sy:_0x1c103f}=this[_0x3b5be1(0x112)]();if(_0x3b5be1(0x19f)===this[_0x3b5be1(0x157)][_0x3b5be1(0x10d)])this[_0x3b5be1(0x119)]=this[_0x3b5be1(0x157)]['px']+(_0x551fc4[_0x3b5be1(0x13b)]-this[_0x3b5be1(0x157)]['sx'])*_0x1e659c,this[_0x3b5be1(0x103)]=this['_drag']['py']+(_0x551fc4[_0x3b5be1(0x101)]-this[_0x3b5be1(0x157)]['sy'])*_0x1c103f,this[_0x3b5be1(0xfd)]();else{const _0xff101c=this[_0x3b5be1(0x141)][_0x3b5be1(0x15a)](),_0x5849a2=(_0x551fc4['clientX']-_0xff101c[_0x3b5be1(0x13a)])*_0x1e659c,_0x156f4f=(_0x551fc4[_0x3b5be1(0x101)]-_0xff101c['top'])*_0x1c103f,_0x31042d=(_0x5849a2-this[_0x3b5be1(0x119)])/this['zoom'],_0x2926a5=(_0x156f4f-this[_0x3b5be1(0x103)])/this[_0x3b5be1(0xdf)];this['_customPos']={...this['_customPos'],[this[_0x3b5be1(0x157)]['id']]:{'x':_0x31042d-this[_0x3b5be1(0x157)]['ox'],'y':_0x2926a5-this[_0x3b5be1(0x157)]['oy']}},this[_0x3b5be1(0xf8)]();}},'_onMouseup'(){const _0x3eb74f=_0xd27273;this[_0x3eb74f(0x157)]=null,this['_svgEl']&&(this['_svgEl'][_0x3eb74f(0x193)]['cursor']=_0x3eb74f(0xe0));},get 'externalSelectedNodeId'(){return _0x57a432['$attr']['selected_node_id']??null;},get 'selfId'(){const _0x459c99=_0xd27273;return _0x57a432['$attr'][_0x459c99(0x100)];},get 'topology'(){const _0x10fb7c=_0xd27273;return _0x57a432[_0x10fb7c(0x1a3)]['topology']||{};},get 'availableEnvs'(){const _0x4e7c1d=_0xd27273;return _0x57a432[_0x4e7c1d(0x1a3)]['available_envs']||[];},get 'envButtons'(){const _0x3ee16f=_0xd27273,_0x41864f=this[_0x3ee16f(0x198)];return(_0x57a432[_0x3ee16f(0x1a3)]['available_envs']||[])[_0x3ee16f(0x165)](_0x26bea0=>({'name':_0x26bea0,'style':null===_0x41864f||Array['isArray'](_0x41864f)&&_0x41864f['includes'](_0x26bea0)?_0x3ee16f(0xd3):''}));},get 'dirButtons'(){const _0xf31090=_0xd27273,_0x2f938c=this[_0xf31090(0x178)];if(!_0x2f938c)return[];const _0x3c987c=_0x2f938c['lo']['slice'](0x0,0x6),_0x20f3eb=_0x2f938c['hi'][_0xf31090(0x12d)](0x0,0x6),_0x1f6b1e=this[_0xf31090(0xfb)];return[{'canon':_0xf31090(0x1a0),'label':_0x3c987c+_0xf31090(0x186)+_0x20f3eb},{'canon':_0xf31090(0x17a),'label':_0x3c987c+_0xf31090(0x173)+_0x20f3eb},{'canon':_0xf31090(0x16e),'label':_0x20f3eb+'\x20→\x20'+_0x3c987c}][_0xf31090(0x165)](_0x411d95=>({..._0x411d95,'style':_0x411d95[_0xf31090(0x176)]===_0x1f6b1e?_0xf31090(0x10f):''}));},get 'nodes'(){const _0x49f03f=_0xd27273;return Object[_0x49f03f(0x142)](this[_0x49f03f(0x147)]||{})[_0x49f03f(0x15b)](_0x117028=>_0x117028&&null!=_0x117028['id'])[_0x49f03f(0xff)]((_0x5196af,_0x22af38)=>String(_0x5196af['id'])[_0x49f03f(0x160)](String(_0x22af38['id'])));},get 'nodeList'(){const _0x5e4d98=_0xd27273;return this[_0x5e4d98(0xe2)][_0x5e4d98(0x165)](_0x562438=>{const _0x2bda2c=_0x5e4d98,_0x4b14dc=this[_0x2bda2c(0x10e)][_0x562438['id']]||this[_0x2bda2c(0x16d)]['pos']?.[_0x562438['id']]||{'x':this['w']/0x2,'y':this['h']/0x2};return{..._0x562438,'px':_0x4b14dc['x'],'py':_0x4b14dc['y']};});},get 'links'(){const _0x103ff8=_0xd27273,_0x4ba700=this[_0x103ff8(0x147)]||{},_0x47778b=_0x4ba700[this[_0x103ff8(0x12c)]]||Object['values'](_0x4ba700)[_0x103ff8(0x136)](_0x32cc2d=>null!=_0x32cc2d?.[_0x103ff8(0xf9)]),_0x1ddf88=_0x47778b?.[_0x103ff8(0xf9)]||{},_0x175c33=new Map(),_0x73283e=(_0x1ff220,_0x554dff)=>({'status':_0x1ff220['status']||_0x103ff8(0x12e),'backlog':Math[_0x103ff8(0xe6)](0x0,Number(_0x554dff??0x0)-Number(_0x1ff220[_0x103ff8(0x182)]??0x0)),'last_seen':_0x1ff220[_0x103ff8(0x14e)]??null,'last_error':_0x1ff220[_0x103ff8(0x17e)]??null});for(const _0x29e336 in _0x4ba700){const _0x437b29=_0x4ba700[_0x29e336];if(_0x437b29?.[_0x103ff8(0x192)])for(const _0x448abb in _0x437b29[_0x103ff8(0x192)]){const _0x1478e8=_0x29e336<_0x448abb?_0x29e336:_0x448abb,_0x409fb7=_0x29e336<_0x448abb?_0x448abb:_0x29e336,_0x4b0aaf=_0x1478e8+':'+_0x409fb7;_0x175c33[_0x103ff8(0x125)](_0x4b0aaf)||_0x175c33['set'](_0x4b0aaf,{'lo':_0x1478e8,'hi':_0x409fb7,'lo_pull':null,'hi_pull':null});const _0x432351=_0x175c33[_0x103ff8(0xf1)](_0x4b0aaf),_0x56415f=_0x437b29[_0x103ff8(0x192)][_0x448abb];_0x29e336===_0x1478e8?_0x432351[_0x103ff8(0x1a4)]=_0x73283e(_0x56415f,_0x4ba700[_0x448abb]?.['clock']):_0x432351[_0x103ff8(0x114)]=_0x73283e(_0x56415f,_0x4ba700[_0x448abb]?.[_0x103ff8(0x182)]);}}for(const _0x3409e5 in _0x1ddf88)if(_0x1ddf88[_0x3409e5]&&!_0x175c33[_0x103ff8(0x125)](_0x3409e5)){const _0x5752ff=_0x1ddf88[_0x3409e5];_0x175c33[_0x103ff8(0x130)](_0x3409e5,{'lo':_0x5752ff['node_lo'],'hi':_0x5752ff[_0x103ff8(0x168)],'lo_pull':null,'hi_pull':null});}return[..._0x175c33[_0x103ff8(0x149)]()][_0x103ff8(0x165)](([_0x309ff9,_0x180467])=>({'key':_0x309ff9,'lo':_0x180467['lo'],'hi':_0x180467['hi'],'link':_0x1ddf88[_0x309ff9]||null,'lo_pull':_0x180467[_0x103ff8(0x1a4)],'hi_pull':_0x180467[_0x103ff8(0x114)]}));},'_linkConfig'(_0xd139e9){const _0x35357f=_0xd27273,_0x1ef5e9=(this[_0x35357f(0x147)]||{})[this[_0x35357f(0x12c)]];return _0x1ef5e9?.['links']?.[_0xd139e9]||null;},'_linkHealth'(_0x4170fe){const _0x3e34e2=_0xd27273;if(_0x4170fe[_0x3e34e2(0x120)]&&!_0x4170fe['link']['enabled'])return _0x3e34e2(0x134);const _0x255fb6=_0x4170fe[_0x3e34e2(0x120)]?.[_0x3e34e2(0x169)]??'both',_0x5b8734=[];_0x3e34e2(0x1a0)!==_0x255fb6&&_0x3e34e2(0x17a)!==_0x255fb6||_0x5b8734['push'](_0x4170fe[_0x3e34e2(0x114)]),_0x3e34e2(0x1a0)!==_0x255fb6&&'hi_to_lo'!==_0x255fb6||_0x5b8734[_0x3e34e2(0xcd)](_0x4170fe['lo_pull']);const _0x59ab5e=[_0x3e34e2(0x1a5),_0x3e34e2(0xcf),_0x3e34e2(0x1a2),_0x3e34e2(0x164),'reconciling',_0x3e34e2(0x185),'ok'];let _0x34a1b0=_0x3e34e2(0x185);for(const _0x47f07c of _0x5b8734){const _0x4ba1d1=this['_pullHealth'](_0x47f07c);_0x59ab5e['indexOf'](_0x4ba1d1)<_0x59ab5e[_0x3e34e2(0xe4)](_0x34a1b0)&&(_0x34a1b0=_0x4ba1d1);}return _0x34a1b0;},'_pullHealth'(_0x3d2c80){const _0x3bff30=_0xd27273;if(!_0x3d2c80)return _0x3bff30(0x185);if(_0x3bff30(0x16f)===_0x3d2c80[_0x3bff30(0xfc)])return _0x3bff30(0x16f);if(_0x3d2c80['last_seen']){const _0x3955ce=this[_0x3bff30(0x137)]-Number(_0x3d2c80['last_seen']);return _0x3d2c80['backlog']>0x32?_0x3bff30(0xcf):_0x3d2c80[_0x3bff30(0x167)]>0x5?'lag-med':_0x3d2c80[_0x3bff30(0x167)]>0x0?_0x3bff30(0x164):_0x3955ce>0x7530?'stale':'ok';}return _0x3d2c80[_0x3bff30(0x17e)]?_0x3bff30(0x1a5):_0x3bff30(0x185);},'_healthMarker':_0x2ce3cf=>'error'===_0x2ce3cf?'err':'reconciling'===_0x2ce3cf?'rec':_0xd27273(0xcf)===_0x2ce3cf?'lag-high':'lag-med'===_0x2ce3cf||_0xd27273(0x164)===_0x2ce3cf||_0xd27273(0x185)===_0x2ce3cf?_0xd27273(0x1a2):'ok','_linkDirLabel'(_0x118f42){const _0x2eb027=_0xd27273;if(!_0x118f42[_0x2eb027(0x120)])return _0x118f42['lo'][_0x2eb027(0x12d)](0x0,0x6)+_0x2eb027(0x186)+_0x118f42['hi'][_0x2eb027(0x12d)](0x0,0x6)+_0x2eb027(0x159);if(!_0x118f42[_0x2eb027(0x120)][_0x2eb027(0x12a)])return'disabled';const _0x13572d=_0x118f42['lo'][_0x2eb027(0x12d)](0x0,0x6),_0x51a23a=_0x118f42['hi'][_0x2eb027(0x12d)](0x0,0x6);switch(_0x118f42['link'][_0x2eb027(0x169)]){case _0x2eb027(0x1a0):return _0x13572d+_0x2eb027(0x186)+_0x51a23a;case _0x2eb027(0x17a):return _0x13572d+_0x2eb027(0x173)+_0x51a23a;case _0x2eb027(0x16e):return _0x51a23a+_0x2eb027(0x173)+_0x13572d;default:return _0x118f42[_0x2eb027(0x120)][_0x2eb027(0x169)];}},get 'selection'(){const _0x147f95=_0xd27273;if(this[_0x147f95(0x17f)]){const _0x4c6a6e=this['links'][_0x147f95(0x136)](_0x4532fd=>_0x4532fd['key']===this[_0x147f95(0x17f)])||null;if(_0x4c6a6e)return{'type':'link','data':_0x4c6a6e};}if(this['selectedNodeId']){const _0x54a613=this[_0x147f95(0x147)][this[_0x147f95(0xce)]]||null;return _0x54a613?{'type':'node','id':this['selectedNodeId'],'data':_0x54a613}:null;}return null;},get 'freshnessLabel'(){const _0x471eb2=_0xd27273;if(!this[_0x471eb2(0x13e)])return'never';const _0x40cf87=this[_0x471eb2(0x137)]-this[_0x471eb2(0x13e)];return _0x40cf87<0x5dc?_0x471eb2(0x137):_0x40cf87<0x1388?_0x471eb2(0x11f):_0x40cf87<0x3a98?'recent':Math[_0x471eb2(0x156)](_0x40cf87/0x3e8)+'s\x20ago';},get 'freshnessClass'(){const _0x304d64=_0xd27273;if(!this['lastUpdatedAt'])return _0x304d64(0x143);const _0x6f1e5e=this[_0x304d64(0x137)]-this[_0x304d64(0x13e)];return _0x6f1e5e<0x1388?_0x304d64(0x17d):_0x6f1e5e<0x3a98?'fresh-ok':_0x304d64(0x143);},'_recomputeLayout'(){const _0x3fd1b5=_0xd27273,_0x526526=this[_0x3fd1b5(0xe2)],_0x422770=this['w']/0x2,_0x4f58d0=this['h']/0x2,_0x338e55=Math[_0x3fd1b5(0xe6)](0x50,Math[_0x3fd1b5(0x177)](_0x422770,_0x4f58d0)-this['nodeRadius']()-0x3c),_0x4251c2={},_0x1f3868=_0x526526[_0x3fd1b5(0x146)]||0x1;_0x526526['forEach']((_0x24d196,_0x5edeb5)=>{const _0x4a6e62=_0x3fd1b5;if(0x1===_0x1f3868)return void(_0x4251c2[_0x24d196['id']]={'x':_0x422770,'y':_0x4f58d0});const _0x225c3c=0x2===_0x1f3868?0x0===_0x5edeb5?Math['PI']:0x0:_0x5edeb5/_0x1f3868*Math['PI']*0x2-Math['PI']/0x2;_0x4251c2[_0x24d196['id']]={'x':_0x422770+_0x338e55*Math[_0x4a6e62(0xf3)](_0x225c3c),'y':_0x4f58d0+_0x338e55*Math[_0x4a6e62(0x1a1)](_0x225c3c)};}),this[_0x3fd1b5(0x16d)]={'cx':_0x422770,'cy':_0x4f58d0,'r':_0x338e55,'pos':_0x4251c2};},'_measure'(){const _0x3cbd45=_0xd27273,_0x5bc5d9=(this['_svgEl']||_0x57a432[_0x3cbd45(0xd2)])[_0x3cbd45(0x15a)]();this['w']=Math[_0x3cbd45(0xe6)](0x12c,_0x5bc5d9[_0x3cbd45(0x102)]||0x384),this['h']=Math[_0x3cbd45(0xe6)](0xc8,_0x5bc5d9['height']||0x1f4),this['_recomputeLayout']();},'_effectivePos'(_0x33e1bf){const _0x29ce16=_0xd27273;return this[_0x29ce16(0x10e)][_0x33e1bf]||this[_0x29ce16(0x16d)]['pos']?.[_0x33e1bf]||null;},'fitView'(){const _0x56519f=_0xd27273;this[_0x56519f(0x163)]();const _0x5b4128=this[_0x56519f(0xe2)];if(!_0x5b4128[_0x56519f(0x146)])return;let _0x3b0054=0x1/0x0,_0x420769=0x1/0x0,_0x38f924=-0x1/0x0,_0x21d450=-0x1/0x0;for(const _0xe3b277 of _0x5b4128){const _0xa1df79=this['_effectivePos'](_0xe3b277['id']);_0xa1df79&&(_0x3b0054=Math[_0x56519f(0x177)](_0x3b0054,_0xa1df79['x']),_0x420769=Math[_0x56519f(0x177)](_0x420769,_0xa1df79['y']),_0x38f924=Math['max'](_0x38f924,_0xa1df79['x']),_0x21d450=Math[_0x56519f(0xe6)](_0x21d450,_0xa1df79['y']));}if(!isFinite(_0x3b0054))return;const _0x95e68c=this[_0x56519f(0x11c)]()+0x3c;_0x3b0054-=_0x95e68c,_0x420769-=_0x95e68c,_0x38f924+=_0x95e68c,_0x21d450+=_0x95e68c;const _0x450a9f=_0x38f924-_0x3b0054,_0x4e8e31=_0x21d450-_0x420769,_0x18d8d1=0.88*Math[_0x56519f(0x177)](this['w']/_0x450a9f,this['h']/_0x4e8e31,0x3);this[_0x56519f(0xdf)]=_0x18d8d1,this['panX']=this['w']/0x2-(_0x3b0054+_0x450a9f/0x2)*_0x18d8d1,this[_0x56519f(0x103)]=this['h']/0x2-(_0x420769+_0x4e8e31/0x2)*_0x18d8d1,this[_0x56519f(0xfd)]();},'resetLayout'(){const _0x464c9d=_0xd27273;this[_0x464c9d(0x10e)]={};try{localStorage[_0x464c9d(0x13f)]('okdb-topo-pos');}catch{}this['fitView']();},'_savePositions'(){const _0x59e423=_0xd27273;try{localStorage['setItem'](_0x59e423(0x115),JSON['stringify'](this[_0x59e423(0x10e)]));}catch{}},'_loadPositions'(){const _0x47427f=_0xd27273;try{const _0x1c9a6e=localStorage[_0x47427f(0xd7)](_0x47427f(0x115));_0x1c9a6e&&(this['_customPos']=JSON[_0x47427f(0x132)](_0x1c9a6e));}catch{}},'nodeRadius':()=>0x16,'linkPath'(_0x2ea972){const _0x9e1ab7=_0xd27273,_0x29583b=this['_effectivePos'](_0x2ea972['lo']),_0x470930=this[_0x9e1ab7(0x124)](_0x2ea972['hi']);if(!_0x29583b||!_0x470930)return'';const _0x4a56a2=_0x470930['x']-_0x29583b['x'],_0x24189f=_0x470930['y']-_0x29583b['y'],_0x16e5b4=Math[_0x9e1ab7(0x175)](_0x4a56a2*_0x4a56a2+_0x24189f*_0x24189f)||0x1,_0x2d808c=this['nodeRadius']();return'M\x20'+(_0x29583b['x']+_0x4a56a2/_0x16e5b4*_0x2d808c)+'\x20'+(_0x29583b['y']+_0x24189f/_0x16e5b4*_0x2d808c)+_0x9e1ab7(0x12f)+(_0x470930['x']-_0x4a56a2/_0x16e5b4*_0x2d808c)+'\x20'+(_0x470930['y']-_0x24189f/_0x16e5b4*_0x2d808c);},'reconciling':!0x1,'reconcilingTarget':null,async 'refreshTopology'(){const _0x32e1f0=_0xd27273;if(!this[_0x32e1f0(0x151)]){this[_0x32e1f0(0x151)]=!0x0;try{const _0x3407b0=await fetch(_0x32e1f0(0xde)),_0x1d5a00=await _0x3407b0[_0x32e1f0(0x14b)](),_0x14d00a=_0x1d5a00[_0x32e1f0(0x127)]??_0x1d5a00;_0x57a432[_0x32e1f0(0x1a3)][_0x32e1f0(0x147)]=_0x14d00a['topology']??_0x14d00a,_0x57a432[_0x32e1f0(0x1a3)][_0x32e1f0(0x18a)]=_0x14d00a[_0x32e1f0(0x171)]??[],this['lastUpdatedAt']=Date['now']();}catch(_0x5102c8){console[_0x32e1f0(0x1a5)]('refresh\x20failed',_0x5102c8);}finally{this['loadingTopology']=!0x1;}}},async 'reconcileAll'(){const _0x5c5166=_0xd27273;if(!this[_0x5c5166(0x16f)]){this[_0x5c5166(0x16f)]=!0x0,this[_0x5c5166(0x158)]=_0x5c5166(0x19a);try{await fetch('/api/sync/reconcile-all',{'method':_0x5c5166(0x113)}),await this['refreshTopology']();}finally{this[_0x5c5166(0x16f)]=!0x1,this[_0x5c5166(0x158)]=null;}}},async 'reconcileNode'(_0x2e4986){const _0x3dae1f=_0xd27273;if(!this['reconciling']){this[_0x3dae1f(0x16f)]=!0x0,this['reconcilingTarget']=_0x2e4986;try{_0x2e4986===this['selfId']?await fetch(_0x3dae1f(0x196),{'method':_0x3dae1f(0x113)}):await fetch(this['topology'][_0x2e4986]?.['address']+_0x3dae1f(0x196),{'method':_0x3dae1f(0x113)}),await this[_0x3dae1f(0xd5)]();}finally{this[_0x3dae1f(0x16f)]=!0x1,this[_0x3dae1f(0x158)]=null;}}},async 'reconcileLink'(_0x5e44a1){const _0x3069dc=_0xd27273;if(this[_0x3069dc(0x16f)])return;this[_0x3069dc(0x16f)]=!0x0,this['reconcilingTarget']=_0x5e44a1[_0x3069dc(0x11e)];const _0x13b4d3=_0x5e44a1['lo']===this['selfId']?_0x5e44a1['hi']:_0x5e44a1['lo'];try{await fetch(_0x3069dc(0x154),{'method':'POST','headers':{'Content-Type':_0x3069dc(0x15d)},'body':JSON[_0x3069dc(0x194)]({'peer_id':_0x13b4d3})}),await this[_0x3069dc(0xd5)]();}finally{this[_0x3069dc(0x16f)]=!0x1,this[_0x3069dc(0x158)]=null;}},'openLinkEditor'(_0x4c53f0){const _0x54847b=_0xd27273;this['editingLink']=_0x4c53f0,this[_0x54847b(0xfb)]=_0x4c53f0['link']?.[_0x54847b(0x169)]??_0x54847b(0x1a0),this[_0x54847b(0x198)]=_0x4c53f0[_0x54847b(0x120)]?.[_0x54847b(0x161)]??null,this['linkEditEnabled']=!0x1!==_0x4c53f0[_0x54847b(0x120)]?.[_0x54847b(0x12a)];},'closeLinkEditor'(){this['editingLink']=null;},'toggleLinkEnv'(_0x4a3c07){const _0x2f2ccb=_0xd27273;if(null===this['linkEditEnvs'])this[_0x2f2ccb(0x198)]=this[_0x2f2ccb(0x171)][_0x2f2ccb(0x15b)](_0x3e7919=>_0x3e7919!==_0x4a3c07);else{const _0xd6195e=new Set(this['linkEditEnvs']);_0xd6195e['has'](_0x4a3c07)?_0xd6195e[_0x2f2ccb(0x19e)](_0x4a3c07):_0xd6195e[_0x2f2ccb(0x123)](_0x4a3c07);const _0x3af173=[..._0xd6195e];this[_0x2f2ccb(0x198)]=_0x3af173[_0x2f2ccb(0x146)]===this[_0x2f2ccb(0x171)][_0x2f2ccb(0x146)]?null:_0x3af173;}},async 'saveLink'(){const _0x32c717=_0xd27273;if(!this['editingLink']||this['savingLink'])return;this[_0x32c717(0x170)]=!0x0;const _0x11a4b7=this[_0x32c717(0x178)];try{const _0x23f85c=await fetch(_0x32c717(0x14a)+_0x11a4b7['lo']+'/'+_0x11a4b7['hi'],{'method':_0x32c717(0x11a),'headers':{'Content-Type':'application/json'},'body':JSON[_0x32c717(0x194)]({'direction':this[_0x32c717(0xfb)],'envs':this[_0x32c717(0x198)],'enabled':this[_0x32c717(0x111)]})});if(!_0x23f85c['ok']){const _0x4db9f4=await _0x23f85c[_0x32c717(0x14b)]();throw new Error(_0x4db9f4?.[_0x32c717(0x1a5)]?.['message']||_0x32c717(0x109));}this[_0x32c717(0x128)](),await this[_0x32c717(0xd5)]();}catch(_0x3c6ab7){alert(_0x3c6ab7[_0x32c717(0x105)]);}finally{this['savingLink']=!0x1;}},async 'deleteLink'(){const _0x1bb4e9=_0xd27273;if(!this['editingLink']||this[_0x1bb4e9(0x170)])return;if(!confirm(_0x1bb4e9(0xda)))return;this[_0x1bb4e9(0x170)]=!0x0;const _0x4bcffa=this[_0x1bb4e9(0x178)];try{await fetch(_0x1bb4e9(0x14a)+_0x4bcffa['lo']+'/'+_0x4bcffa['hi'],{'method':_0x1bb4e9(0xeb)}),this[_0x1bb4e9(0x128)](),await this[_0x1bb4e9(0xd5)]();}catch(_0x15af23){alert(_0x15af23[_0x1bb4e9(0x105)]);}finally{this[_0x1bb4e9(0x170)]=!0x1;}},'deselect'(){const _0x194842=_0xd27273;this['selectedNodeId']=null,this[_0x194842(0x17f)]=null,this[_0x194842(0x179)]=null,this['hoveredNodeId']=null,this[_0x194842(0x178)]=null,_0x57a432[_0x194842(0x13d)]?.(_0x194842(0x11d),null),_0x57a432[_0x194842(0x13d)]?.(_0x194842(0xd1),null);},'pickNode'(_0x491283){const _0x235deb=_0xd27273;this['selectedNodeId']=_0x491283,this[_0x235deb(0x17f)]=null,this[_0x235deb(0x178)]=null,_0x57a432['$dispatch']?.(_0x235deb(0x11d),_0x491283),_0x57a432[_0x235deb(0x13d)]?.(_0x235deb(0xd1),null);},'pickLink'(_0x45c2bb){const _0x462fae=_0xd27273,_0x4b1397=this[_0x462fae(0xf9)]['find'](_0x230bfe=>_0x230bfe[_0x462fae(0x11e)]===_0x45c2bb)||null;if(_0x4b1397&&(!this[_0x462fae(0xce)]||_0x4b1397['lo']===this['selectedNodeId']||_0x4b1397['hi']===this[_0x462fae(0xce)])){if(this['selectedLinkKey']===_0x45c2bb)return this[_0x462fae(0x17f)]=null,this[_0x462fae(0x178)]=null,void _0x57a432[_0x462fae(0x13d)]?.(_0x462fae(0xd1),null);this['selectedLinkKey']=_0x45c2bb,this[_0x462fae(0xce)]||(this['selectedNodeId']=_0x4b1397['lo'],_0x57a432[_0x462fae(0x13d)]?.(_0x462fae(0x11d),this['selectedNodeId'])),_0x57a432['$dispatch']?.(_0x462fae(0xd1),_0x45c2bb);}},async 'copy'(_0xbb012f){const _0x3f8690=_0xd27273;try{await navigator[_0x3f8690(0x18d)]['writeText'](String(_0xbb012f??''));}catch(_0x10646f){}},'_sPointerEventsFor'(_0x4feb62){const _0x5e2224=_0xd27273;return this[_0x5e2224(0xce)]&&_0x4feb62['lo']!==this[_0x5e2224(0xce)]&&_0x4feb62['hi']!==this['selectedNodeId']?_0x5e2224(0x12b):_0x5e2224(0xdc);},'_sEnabledBadge':_0x34f794=>_0x34f794?_0xd27273(0x11b):_0xd27273(0x162),'_sEnabledBtn':_0x2c3456=>_0x2c3456?_0xd27273(0x129):_0xd27273(0x18f),'nodeHealth'(_0x4a2743){const _0x33d747=_0xd27273,_0x3e0fa9=this[_0x33d747(0xf9)]['filter'](_0x44c189=>_0x44c189['lo']===_0x4a2743||_0x44c189['hi']===_0x4a2743);if(!_0x3e0fa9[_0x33d747(0x146)])return'ok';const _0x51ee36=_0x3e0fa9[_0x33d747(0x165)](_0x29a569=>this['_linkHealth'](_0x29a569));return _0x51ee36[_0x33d747(0x16b)](_0x33d747(0x1a5))?_0x33d747(0x1a5):_0x51ee36[_0x33d747(0x16b)](_0x33d747(0xcf))?'critical':_0x51ee36[_0x33d747(0x16b)](_0x33d747(0x1a2))?'lagging':_0x51ee36[_0x33d747(0x16b)]('behind')?'behind':_0x51ee36[_0x33d747(0x122)](_0x538774=>_0x33d747(0x185)===_0x538774||_0x33d747(0x134)===_0x538774)?_0x33d747(0x185):'ok';},'isLinkInteractable'(_0x192449){const _0x3e4d6a=_0xd27273;return!this[_0x3e4d6a(0xce)]||_0x192449['lo']===this[_0x3e4d6a(0xce)]||_0x192449['hi']===this[_0x3e4d6a(0xce)];},'isActiveLink'(_0x3611b4){const _0x504894=_0xd27273;return this[_0x504894(0x17f)]===_0x3611b4[_0x504894(0x11e)]||this[_0x504894(0x179)]===_0x3611b4[_0x504894(0x11e)]&&this[_0x504894(0xd9)](_0x3611b4);},'nodeClass'(_0x851985){const _0x2000d8=_0xd27273;let _0x193136='nd';const _0x19ec0c=this['selectedNodeId'],_0x46cadd=this[_0x2000d8(0x15f)];if(_0x19ec0c&&_0x19ec0c!==_0x851985['id']&&(_0x193136+=_0x2000d8(0x118)),_0x19ec0c===_0x851985['id']&&(_0x193136+=_0x2000d8(0x10b)),this[_0x2000d8(0x17f)]){const _0xb07f51=this[_0x2000d8(0xf9)]['find'](_0x2b2651=>_0x2b2651[_0x2000d8(0x11e)]===this['selectedLinkKey']);!_0xb07f51||_0xb07f51['lo']!==_0x851985['id']&&_0xb07f51['hi']!==_0x851985['id']||_0x19ec0c===_0x851985['id']||(_0x193136+='\x20nd-sel2');}_0x19ec0c||_0x46cadd!==_0x851985['id']||(_0x193136+=_0x2000d8(0x133));const _0x4752f4=this['nodeHealth'](_0x851985['id']);return'error'===_0x4752f4?_0x193136+=_0x2000d8(0x19d):_0x2000d8(0x10a)===_0x4752f4?_0x193136+=_0x2000d8(0x14d):'lagging'===_0x4752f4?_0x193136+=_0x2000d8(0x126):_0x2000d8(0x164)===_0x4752f4?_0x193136+=_0x2000d8(0xf0):'stale'===_0x4752f4&&(_0x193136+=_0x2000d8(0xd8)),_0x193136;},'linkClass'(_0x10ed4c){const _0x29992d=_0xd27273;let _0x3488d5='ln';const _0x65d00c=this[_0x29992d(0x17f)]===_0x10ed4c['key'],_0x18fe69=this[_0x29992d(0x179)]===_0x10ed4c[_0x29992d(0x11e)]&&this[_0x29992d(0xd9)](_0x10ed4c);switch(this[_0x29992d(0xd9)](_0x10ed4c)||_0x65d00c||(_0x3488d5+=_0x29992d(0x17b)),_0x65d00c?_0x3488d5+=_0x29992d(0xf4):_0x18fe69&&(_0x3488d5+=_0x29992d(0xe5)),this[_0x29992d(0x153)](_0x10ed4c)){case _0x29992d(0x134):_0x3488d5+=_0x29992d(0x18b);break;case _0x29992d(0x1a5):_0x3488d5+=_0x29992d(0x10c);break;case _0x29992d(0x16f):_0x3488d5+=_0x29992d(0xe1);break;case _0x29992d(0xcf):_0x3488d5+=_0x29992d(0xd0);break;case _0x29992d(0x1a2):_0x3488d5+=_0x29992d(0x174);break;case'behind':_0x3488d5+=_0x29992d(0xf7);break;case _0x29992d(0x185):_0x3488d5+='\x20ln-stale';break;default:_0x3488d5+=_0x29992d(0xef);}return _0x3488d5;},'linkMarker'(_0x2c9870){const _0x2095b3=_0xd27273,_0x40708c=_0x2c9870['link']?.[_0x2095b3(0x169)]??_0x2095b3(0x1a0);return _0x2095b3(0x1a0)!==_0x40708c&&_0x2095b3(0x17a)!==_0x40708c?'':_0x2c9870['link']&&!_0x2c9870['link']['enabled']?_0x2095b3(0xea):_0x2095b3(0xe7)+this[_0x2095b3(0x195)](this[_0x2095b3(0xe8)](_0x2c9870[_0x2095b3(0x114)]))+')';},'linkStartMarker'(_0x2a1755){const _0x2dc8a6=_0xd27273,_0x5a80e3=_0x2a1755[_0x2dc8a6(0x120)]?.[_0x2dc8a6(0x169)]??_0x2dc8a6(0x1a0);return _0x2dc8a6(0x1a0)!==_0x5a80e3&&'hi_to_lo'!==_0x5a80e3?'':_0x2a1755[_0x2dc8a6(0x120)]&&!_0x2a1755[_0x2dc8a6(0x120)]['enabled']?_0x2dc8a6(0x19b):_0x2dc8a6(0x139)+this['_healthMarker'](this[_0x2dc8a6(0xe8)](_0x2a1755['lo_pull']))+')';}}),'mount'(_0x51cb80){const _0x33d89a=_0xd27273;this['_svgEl']=_0x51cb80[_0x33d89a(0xd2)]['querySelector'](_0x33d89a(0x145)),this[_0x33d89a(0xfe)]=this[_0x33d89a(0x141)]?.['querySelector'](_0x33d89a(0x138)),this[_0x33d89a(0x141)]&&(this[_0x33d89a(0x141)][_0x33d89a(0x193)][_0x33d89a(0x197)]=_0x33d89a(0xe0)),this[_0x33d89a(0x163)](),this[_0x33d89a(0xdd)](),this['_ro']=new ResizeObserver(()=>this[_0x33d89a(0x189)]()),this[_0x33d89a(0x135)][_0x33d89a(0xf5)](_0x51cb80[_0x33d89a(0xd2)]),this[_0x33d89a(0xf6)]=setInterval(()=>{const _0x268461=_0x33d89a;this[_0x268461(0x137)]=Date[_0x268461(0x137)]();},0x3e8),this['refreshTopology']()['then'](()=>this[_0x33d89a(0x189)]()),this[_0x33d89a(0x110)]=_0x346e01=>{const _0x44af29=_0x33d89a;_0x346e01[_0x44af29(0x106)](),this[_0x44af29(0x172)](_0x346e01);},this[_0x33d89a(0x141)]&&this['_svgEl'][_0x33d89a(0x117)](_0x33d89a(0x13c),this[_0x33d89a(0x110)],{'passive':!0x1}),this[_0x33d89a(0x180)]=_0x672f4a=>this[_0x33d89a(0x152)](_0x672f4a),this['_svgEl']&&this[_0x33d89a(0x141)][_0x33d89a(0x117)]('mousedown',this[_0x33d89a(0x180)]),this['_mousemoveCb']=_0x3f04ee=>this[_0x33d89a(0xee)](_0x3f04ee),this[_0x33d89a(0x16a)]=()=>this[_0x33d89a(0xe9)](),window['addEventListener'](_0x33d89a(0x121),this[_0x33d89a(0x18e)]),window['addEventListener']('mouseup',this[_0x33d89a(0x16a)]),this[_0x33d89a(0xd6)]=()=>{const _0x569222=_0x33d89a;document['hidden']||this[_0x569222(0xd5)]();},document[_0x33d89a(0x117)](_0x33d89a(0x190),this[_0x33d89a(0xd6)]),this['autoRefresh']&&(this[_0x33d89a(0x15e)]=setInterval(()=>this[_0x33d89a(0xd5)](),this['autoRefreshIntervalMs'])),this[_0x33d89a(0xce)]=this[_0x33d89a(0xe3)],_0x51cb80['$watch'](()=>_0x51cb80[_0x33d89a(0x1a3)][_0x33d89a(0x155)],_0x3c3223=>{const _0x2a2efd=_0x33d89a;this[_0x2a2efd(0xce)]=_0x3c3223??null,_0x3c3223||(this[_0x2a2efd(0x17f)]=null);});},'unmount'(){const _0x5e3ff0=_0xd27273;this['_ro']?.[_0x5e3ff0(0x108)](),clearInterval(this[_0x5e3ff0(0xf6)]),clearInterval(this[_0x5e3ff0(0x15e)]),this[_0x5e3ff0(0x141)]&&(this[_0x5e3ff0(0x141)][_0x5e3ff0(0x16c)](_0x5e3ff0(0x13c),this[_0x5e3ff0(0x110)]),this[_0x5e3ff0(0x141)]['removeEventListener'](_0x5e3ff0(0x19c),this[_0x5e3ff0(0x180)])),window[_0x5e3ff0(0x16c)](_0x5e3ff0(0x121),this[_0x5e3ff0(0x18e)]),window[_0x5e3ff0(0x16c)](_0x5e3ff0(0xf2),this[_0x5e3ff0(0x16a)]),document[_0x5e3ff0(0x16c)](_0x5e3ff0(0x190),this[_0x5e3ff0(0xd6)]);},'template':'<div\x20style=\x22--bg:var(--okdb-app-bg-deep);\x20--panel:var(--okdb-app-surface);\x20--panel2:var(--okdb-app-bg-deep);\x20--border:var(--okdb-app-border);\x20--border2:var(--okdb-app-surface-2);\x0a\x20\x20--text:var(--okdb-app-fg);\x20--muted:var(--okdb-app-fg-muted);\x20--accent:var(--okdb-accent);\x20--ok:var(--okdb-success);\x20--rec:var(--okdb-accent);\x0a\x20\x20--warn:var(--okdb-warning);\x20--bad:var(--okdb-danger);\x20--err:var(--okdb-danger);\x20--dis:var(--okdb-app-fg-subtle);\x0a\x20\x20border:1px\x20solid\x20var(--border);\x20border-radius:12px;\x20background:var(--bg);\x20color:var(--text);\x0a\x20\x20display:flex;\x20flex-direction:column;\x20flex:1;\x20position:relative;\x20overflow:hidden;\x0a\x20\x20font-family:\x20ui-monospace,\x20monospace;\x22><div\x20style=\x22padding:12px\x2014px;display:flex;justify-content:space-between;border-bottom:1px\x20solid\x20var(--border2);background:var(--panel);align-items:center;\x22><div\x20style=\x22display:flex;align-items:center;gap:10px;\x22><div\x20style=\x22font-weight:700;letter-spacing:0.8px;color:var(--accent);\x22>NETWORK_TOPOLOGY</div><button\x20@click=\x22reconcileAll()\x22\x20:disabled=\x22reconciling\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;\x22><span\x20style=\x22display:flex;align-items:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===\x27all\x27?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===\x27all\x27?\x27RECONCILING\x27:\x27RECONCILE\x20ALL\x27}}</span></button>\x20<button\x20@click=\x22refreshTopology()\x22\x20:disabled=\x22loadingTopology\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22>REFRESH</button>\x20<button\x20@click=\x22fitView()\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22\x20title=\x22Fit\x20all\x20nodes\x20into\x20view\x22>FIT</button>\x20<button\x20@click=\x22resetLayout()\x22\x20style=\x22font-size:11px;padding:4px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;\x22\x20title=\x22Reset\x20node\x20positions\x22>RESET</button>\x20<span\x20:style=\x22{opacity:loadingTopology?1:0}\x22\x20class=\x22spinner\x22/></div><div\x20style=\x22display:flex;align-items:center;gap:12px;font-size:11px;\x22><span\x20:class=\x22freshnessClass\x22>updated:\x20{{freshnessLabel}}</span>\x20<span\x20style=\x22opacity:0.75;\x22>{{nodes.length}}\x20NODES\x20//\x20{{links.length}}\x20LINKS</span></div></div><div\x20style=\x22flex:1;position:relative;\x22><svg\x20:viewBox=\x22\x270\x200\x20\x27+w+\x27\x20\x27+h\x22\x20style=\x22width:100%;height:100%;\x22><rect\x20:width=\x22w\x22\x20:height=\x22h\x22\x20fill=\x22transparent\x22\x20style=\x22pointer-events:all\x22\x20@click=\x22deselect()\x22/><defs><marker\x20id=\x22arrow-ok\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--ok)\x22/></marker><marker\x20id=\x22arrow-rec\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--rec)\x22/></marker><marker\x20id=\x22arrow-err\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--err)\x22/></marker><marker\x20id=\x22arrow-lag-med\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--warn)\x22/></marker><marker\x20id=\x22arrow-lag-high\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--bad)\x22/></marker><marker\x20id=\x22arrow-disabled\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--dis)\x22/></marker><marker\x20id=\x22arrow-rev-ok\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--ok)\x22/></marker><marker\x20id=\x22arrow-rev-rec\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--rec)\x22/></marker><marker\x20id=\x22arrow-rev-err\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--err)\x22/></marker><marker\x20id=\x22arrow-rev-lag-med\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--warn)\x22/></marker><marker\x20id=\x22arrow-rev-lag-high\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--bad)\x22/></marker><marker\x20id=\x22arrow-rev-disabled\x22\x20viewBox=\x220\x200\x2010\x2010\x22\x20refX=\x2210\x22\x20refY=\x225\x22\x20markerWidth=\x226\x22\x20markerHeight=\x226\x22\x20orient=\x22auto-start-reverse\x22><path\x20d=\x22M\x200\x200\x20L\x2010\x205\x20L\x200\x2010\x20z\x22\x20fill=\x22var(--dis)\x22/></marker></defs><style>.ln\x20{\x20fill:none;\x20stroke-width:1.9;\x20opacity:0.70;\x20transition:opacity\x200.14s,stroke-width\x200.14s,filter\x200.14s;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-ok\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--ok);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-behind-light\x20{\x20stroke:var(--okdb-info);\x20opacity:0.8;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-rec\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--rec);\x20stroke-dasharray:4\x203;\x20animation:dash\x201.1s\x20linear\x20infinite;\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.5));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-lag-med\x20\x20\x20\x20\x20\x20{\x20stroke:var(--warn);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-lag-high\x20\x20\x20\x20\x20{\x20stroke:var(--bad);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-err\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--err);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-stale\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke:var(--okdb-app-fg-subtle);\x20opacity:0.5;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-disabled\x20\x20\x20\x20\x20{\x20stroke:var(--dis);\x20stroke-dasharray:6\x204;\x20opacity:0.45;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-dim\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20opacity:0.08;\x20filter:none\x20!important;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-hover\x20\x20\x20\x20\x20\x20\x20\x20{\x20stroke-width:3.0;\x20opacity:1;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.ln-selected\x20\x20\x20\x20\x20{\x20stroke:var(--accent)\x20!important;\x20stroke-width:5.2\x20!important;\x20opacity:1\x20!important;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.9))\x20drop-shadow(0\x200\x2010px\x20rgba(77,163,255,0.35));\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd\x20circle\x20{\x20fill:var(--bg);\x20stroke:var(--border);\x20stroke-width:2;\x20transition:stroke\x200.14s,stroke-width\x200.14s,filter\x200.14s,opacity\x200.14s;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd\x20text\x20\x20\x20{\x20fill:var(--muted);\x20font-size:11px;\x20pointer-events:none;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-hover\x20\x20circle\x20{\x20stroke:rgba(77,163,255,0.8);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-sel\x20\x20\x20\x20circle\x20{\x20stroke:var(--accent);\x20stroke-width:3.4;\x20filter:drop-shadow(0\x200\x204px\x20rgba(77,163,255,0.75))\x20drop-shadow(0\x200\x2010px\x20rgba(77,163,255,0.25));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-sel2\x20\x20\x20circle\x20{\x20stroke:rgba(77,163,255,0.75);\x20stroke-width:3.0;\x20filter:drop-shadow(0\x200\x206px\x20rgba(77,163,255,0.25));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-dim\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{\x20opacity:0.22;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-err\x20\x20\x20\x20circle\x20\x20{\x20stroke:var(--err);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-stale\x20\x20circle\x20\x20{\x20stroke:var(--okdb-app-fg-subtle);\x20stroke-width:2;\x20opacity:0.7;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-behind\x20circle\x20\x20{\x20stroke:var(--okdb-info);\x20stroke-width:2.5;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-lag\x20\x20\x20\x20circle\x20\x20{\x20stroke:var(--warn);\x20stroke-width:3;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.nd-critical\x20circle\x20{\x20stroke:var(--bad);\x20stroke-width:3.5;\x20filter:drop-shadow(0\x200\x206px\x20rgba(255,77,77,0.5));\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-now\x20\x20\x20{\x20color:var(--ok);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-ok\x20\x20\x20\x20{\x20color:var(--okdb-info);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.fresh-stale\x20{\x20color:var(--warn);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20.spinner\x20{\x20display:inline-block;\x20width:12px;\x20height:12px;\x20border:2px\x20solid\x20rgba(77,163,255,0.2);\x20border-top:2px\x20solid\x20var(--accent);\x20border-radius:50%;\x20animation:spin\x200.8s\x20linear\x20infinite;\x20flex-shrink:0;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20@keyframes\x20dash\x20{\x20to\x20{\x20stroke-dashoffset:-14;\x20}\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20@keyframes\x20spin\x20\x20{\x20to\x20{\x20transform:rotate(360deg);\x20}\x20}</style><g\x20class=\x22topo-g\x22><for\x20:=\x22links\x22\x20let:l><if\x20:=\x22!isActiveLink(l)\x22><g><path\x20:d=\x22linkPath(l)\x22\x20stroke=\x22transparent\x22\x20stroke-width=\x2214\x22\x20fill=\x22none\x22\x20:style=\x22_sPointerEventsFor(l)\x22\x20@mouseenter=\x22isLinkInteractable(l)?(hoveredLinkKey=l.key):null\x22\x20@mouseleave=\x22hoveredLinkKey=null\x22\x20@click=\x22pickLink(l.key)\x22/><path\x20:d=\x22linkPath(l)\x22\x20:class=\x22linkClass(l)\x22\x20:marker-end=\x22linkMarker(l)\x22\x20:marker-start=\x22linkStartMarker(l)\x22><title>{{l.lo.slice(0,8)}}\x20↔\x20{{l.hi.slice(0,8)}}\x20direction:\x20{{l.link\x20?\x20l.link.direction\x20:\x20\x27mesh\x27}}\x20enabled:\x20{{l.link\x20?\x20l.link.enabled\x20:\x20true}}\x20envs:\x20{{l.link\x20&&\x20l.link.envs\x20?\x20l.link.envs.join(\x27,\x20\x27)\x20:\x20\x27all\x27}}</title></path></g></if></for><for\x20:=\x22nodeList\x22\x20let:n><g\x20:id=\x22\x27nd-\x27+n.id\x22\x20:transform=\x22\x27translate(\x27+n.px+\x27,\x27+n.py+\x27)\x27\x22\x20:class=\x22nodeClass(n)\x22\x20@mouseenter=\x22hoveredNodeId=n.id\x22\x20@mouseleave=\x22hoveredNodeId=null\x22\x20@click=\x22pickNode(n.id)\x22><circle\x20:r=\x22nodeRadius()\x22/><text\x20text-anchor=\x22middle\x22\x20dy=\x224\x22>{{n.id.slice(0,6)}}</text><title>{{n.id}}\x20clock:\x20{{n.clock\x20??\x20\x27--\x27}}\x20addr:\x20{{n.address\x20??\x20\x27—\x27}}</title></g></for><for\x20:=\x22links\x22\x20let:l><if\x20:=\x22isActiveLink(l)\x22><g><path\x20:d=\x22linkPath(l)\x22\x20stroke=\x22transparent\x22\x20stroke-width=\x2216\x22\x20fill=\x22none\x22\x20:style=\x22_sPointerEventsFor(l)\x22\x20@mouseenter=\x22isLinkInteractable(l)?(hoveredLinkKey=l.key):null\x22\x20@mouseleave=\x22hoveredLinkKey=null\x22\x20@click=\x22pickLink(l.key)\x22/><path\x20:d=\x22linkPath(l)\x22\x20:class=\x22linkClass(l)\x22\x20:marker-end=\x22linkMarker(l)\x22\x20:marker-start=\x22linkStartMarker(l)\x22/></g></if></for></g></svg><if\x20:=\x22selection\x20||\x20editingLink\x22><div\x20style=\x22position:absolute;top:18px;right:18px;width:320px;background:var(--panel);border:1px\x20solid\x20var(--border);border-radius:12px;padding:16px;box-shadow:0\x2016px\x2034px\x20rgba(0,0,0,0.45);border-left:4px\x20solid\x20var(--accent);\x22><div\x20style=\x22display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;\x22><span\x20style=\x22font-size:10px;background:var(--bg);padding:3px\x207px;border-radius:6px;color:var(--accent);letter-spacing:0.6px;\x22>{{editingLink\x20?\x20\x27LINK_CONFIG\x27\x20:\x20selection.type.toUpperCase()}}\x20</span><span\x20@click=\x22editingLink\x20?\x20closeLinkEditor()\x20:\x20deselect()\x22\x20style=\x22cursor:pointer;opacity:0.7;font-size:16px;line-height:12px;\x22>×</span></div><if\x20:=\x22!editingLink\x20&&\x20selection\x20&&\x20selection.type\x20===\x20\x27node\x27\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;\x22><div\x20style=\x22color:var(--text);font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\x22>{{selection.id}}</div><button\x20@click=\x22copy(selection.id)\x22\x20style=\x22border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);font-size:11px;padding:4px\x208px;border-radius:8px;cursor:pointer;\x22>copy</button></div><div\x20style=\x22display:grid;grid-template-columns:92px\x201fr;row-gap:8px;column-gap:10px;\x22><div\x20style=\x22opacity:0.65;\x22>Clock</div><div>{{selection.data.clock??\x27--\x27}}</div><div\x20style=\x22opacity:0.65;\x22>Addr</div><div\x20style=\x22font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\x22>{{selection.data.address||\x27N/A\x27}}</div><div\x20style=\x22opacity:0.65;\x22>Status</div><div\x20:style=\x22selection.data.error?\x27color:var(--err)\x27:\x27color:var(--ok)\x27\x22>{{selection.data.error?(\x27ERR:\x20\x27+selection.data.error):\x27OK\x27}}</div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Tags</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:6px;\x22><if\x20:=\x22!(selection.data.tags\x20||\x20[]).length\x22><span\x20style=\x22font-size:11px;opacity:0.45;\x22>No\x20tags</span></if><for\x20:=\x22selection.data.tags\x20||\x20[]\x22\x20let:tag><span\x20style=\x22font-size:10px;padding:2px\x208px;border-radius:999px;border:1px\x20solid\x20var(--okdb-accent-soft-border);color:var(--okdb-accent);background:var(--okdb-accent-soft-bg);\x22>{{tag}}</span></for></div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Available\x20envs</div><div\x20style=\x22font-size:11px;color:var(--muted);line-height:1.5;word-break:break-word;\x22>{{(selection.data.availableEnvs\x20||\x20[]).join(\x27,\x20\x27)\x20||\x20\x27—\x27}}</div></div><div\x20style=\x22margin-top:12px;border-top:1px\x20solid\x20var(--border2);padding-top:10px;\x22><div\x20style=\x22font-size:11px;opacity:0.7;margin-bottom:6px;\x22>Outbound\x20peers</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:6px;\x22><for\x20:=\x22Object.keys(selection.data.peers||{})\x22\x20let:pid><span\x20style=\x22font-size:11px;padding:3px\x207px;border:1px\x20solid\x20var(--border);background:var(--panel2);border-radius:999px;color:var(--muted);\x22>{{pid.slice(0,8)}}</span></for></div></div><div\x20style=\x22margin-top:14px;\x22><button\x20@click=\x22reconcileNode(selection.id)\x22\x20:disabled=\x22reconciling\x22\x20style=\x22width:100%;box-sizing:border-box;padding:6px\x2010px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===selection.id?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===selection.id?\x27RECONCILING\x27:\x27RECONCILE\x20NODE\x27}}</span></button></div></div></if><if\x20:=\x22!editingLink\x20&&\x20selection\x20&&\x20selection.type\x20===\x20\x27link\x27\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22margin-bottom:12px;\x22><div\x20style=\x22display:flex;align-items:center;gap:8px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;font-size:12px;font-weight:700;\x22>{{selection.data.lo.slice(0,8)}}</span>\x20<span\x20style=\x22font-size:16px;color:var(--accent);\x22>{{selection.data.link\x20?\x20(selection.data.link.direction\x20===\x20\x27lo_to_hi\x27\x20?\x20\x27→\x27\x20:\x20selection.data.link.direction\x20===\x20\x27hi_to_lo\x27\x20?\x20\x27←\x27\x20:\x20\x27⇄\x27)\x20:\x20\x27⇄\x27}}\x20</span><span\x20style=\x22font-family:monospace;font-size:12px;font-weight:700;\x22>{{selection.data.hi.slice(0,8)}}</span><if\x20:=\x22selection.data.link\x22><span\x20style=\x22font-size:11px;margin-left:4px;\x22\x20:style=\x22_sEnabledBadge(selection.data.link.enabled)\x22>{{selection.data.link.enabled\x20?\x20\x27●\x20on\x27\x20:\x20\x27○\x20off\x27}}</span></if></div><if\x20:=\x22selection.data.link\x20&&\x20selection.data.link.envs\x22><div\x20style=\x22font-size:11px;opacity:0.45;\x22>envs:\x20{{selection.data.link.envs.join(\x27,\x20\x27)}}</div></if><if\x20:=\x22!selection.data.link\x22><div\x20style=\x22font-size:11px;opacity:0.45;\x22>no\x20link\x20config\x20—\x20mesh\x20(legacy)</div></if></div><div\x20style=\x22border:1px\x20solid\x20var(--border2);border-radius:8px;overflow:hidden;margin-bottom:12px;font-size:11px;\x22><if\x20:=\x22!selection.data.link\x20||\x20selection.data.link.direction\x20===\x20\x27both\x27\x20||\x20selection.data.link.direction\x20===\x20\x27lo_to_hi\x27\x22><div\x20style=\x22padding:9px\x2011px;border-bottom:1px\x20solid\x20var(--bg);\x22><div\x20style=\x22display:flex;align-items:center;gap:6px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.lo.slice(0,6)}}</span>\x20<span\x20style=\x22color:var(--accent);\x22>→</span>\x20<span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.hi.slice(0,6)}}</span>\x20<span\x20style=\x22opacity:0.4;\x22>(hi\x20receives\x20from\x20lo)</span></div><div\x20style=\x22display:grid;grid-template-columns:70px\x201fr;row-gap:4px;gap:6px;opacity:0.85;\x22><span\x20style=\x22opacity:0.5;\x22>status</span>\x20<span>{{selection.data.hi_pull\x20?\x20selection.data.hi_pull.status\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>backlog</span>\x20<span>{{selection.data.hi_pull\x20?\x20selection.data.hi_pull.backlog\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>last\x20seen</span>\x20<span>{{selection.data.hi_pull\x20&&\x20selection.data.hi_pull.last_seen\x20?\x20(Math.round((now\x20-\x20selection.data.hi_pull.last_seen)/1000)\x20+\x20\x27s\x20ago\x27)\x20:\x20\x27—\x27}}</span><if\x20:=\x22selection.data.hi_pull\x20&&\x20selection.data.hi_pull.last_error\x22><span\x20style=\x22opacity:0.5;\x22>error</span>\x20<span\x20style=\x22color:var(--err);\x22>{{selection.data.hi_pull.last_error}}</span></if></div></div></if><if\x20:=\x22!selection.data.link\x20||\x20selection.data.link.direction\x20===\x20\x27both\x27\x20||\x20selection.data.link.direction\x20===\x20\x27hi_to_lo\x27\x22><div\x20style=\x22padding:9px\x2011px;\x22><div\x20style=\x22display:flex;align-items:center;gap:6px;margin-bottom:6px;\x22><span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.hi.slice(0,6)}}</span>\x20<span\x20style=\x22color:var(--accent);\x22>→</span>\x20<span\x20style=\x22font-family:monospace;opacity:0.7;\x22>{{selection.data.lo.slice(0,6)}}</span>\x20<span\x20style=\x22opacity:0.4;\x22>(lo\x20receives\x20from\x20hi)</span></div><div\x20style=\x22display:grid;grid-template-columns:70px\x201fr;row-gap:4px;gap:6px;opacity:0.85;\x22><span\x20style=\x22opacity:0.5;\x22>status</span>\x20<span>{{selection.data.lo_pull\x20?\x20selection.data.lo_pull.status\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>backlog</span>\x20<span>{{selection.data.lo_pull\x20?\x20selection.data.lo_pull.backlog\x20:\x20\x27—\x27}}</span>\x20<span\x20style=\x22opacity:0.5;\x22>last\x20seen</span>\x20<span>{{selection.data.lo_pull\x20&&\x20selection.data.lo_pull.last_seen\x20?\x20(Math.round((now\x20-\x20selection.data.lo_pull.last_seen)/1000)\x20+\x20\x27s\x20ago\x27)\x20:\x20\x27—\x27}}</span><if\x20:=\x22selection.data.lo_pull\x20&&\x20selection.data.lo_pull.last_error\x22><span\x20style=\x22opacity:0.5;\x22>error</span>\x20<span\x20style=\x22color:var(--err);\x22>{{selection.data.lo_pull.last_error}}</span></if></div></div></if></div><div\x20style=\x22display:flex;flex-direction:column;gap:7px;\x22><button\x20@click=\x22reconcileLink(selection.data)\x22\x20:disabled=\x22reconciling\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:6px;\x22><span\x20:style=\x22reconcilingTarget===selection.data.key?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20{{reconcilingTarget===selection.data.key\x20?\x20\x27Reconciling…\x27\x20:\x20\x27Reconcile\x27}}</span></button>\x20<button\x20@click=\x22openLinkEditor(selection.data)\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px;border-radius:8px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:12px;\x22>✎\x20Configure\x20Link</button></div></div></if><if\x20:=\x22editingLink\x22><div\x20style=\x22font-size:13px;\x22><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-family:monospace;font-size:11px;opacity:0.5;margin-bottom:2px;\x22>link\x20id</div><div\x20style=\x22font-family:monospace;font-size:11px;\x22>{{editingLink.key}}</div></div><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-size:11px;opacity:0.5;margin-bottom:7px;\x22>Direction</div><div\x20style=\x22display:flex;flex-direction:column;gap:5px;\x22><for\x20:=\x22dirButtons\x22\x20let:btn><button\x20@click=\x22linkEditDir\x20=\x20btn.canon\x22\x20:style=\x22btn.style\x22\x20style=\x22width:100%;box-sizing:border-box;padding:7px\x2010px;border-radius:7px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:12px;font-family:monospace;text-align:left;\x22>{{btn.label}}</button></for></div></div><if\x20:=\x22availableEnvs.length\x22><div\x20style=\x22margin-bottom:14px;\x22><div\x20style=\x22font-size:11px;opacity:0.5;margin-bottom:7px;\x22>Data\x20envs\x20—\x20{{linkEditEnvs\x20===\x20null\x20?\x20\x27all\x27\x20:\x20linkEditEnvs.length\x20+\x20\x27\x20selected\x27}}</div><div\x20style=\x22display:flex;flex-wrap:wrap;gap:5px;\x22><for\x20:=\x22envButtons\x22\x20let:btn><button\x20@click=\x22toggleLinkEnv(btn.name)\x22\x20:style=\x22btn.style\x22\x20style=\x22padding:4px\x2010px;border-radius:6px;border:1px\x20solid\x20var(--border);background:var(--panel2);color:var(--muted);cursor:pointer;font-size:11px;\x22>{{btn.name}}</button></for></div></div></if><div\x20style=\x22margin-bottom:16px;display:flex;align-items:center;gap:10px;\x22><span\x20style=\x22font-size:11px;opacity:0.5;\x22>Enabled</span>\x20<button\x20@click=\x22linkEditEnabled=!linkEditEnabled\x22\x20:style=\x22_sEnabledBtn(linkEditEnabled)\x22\x20style=\x22padding:4px\x2012px;border-radius:6px;border:1px\x20solid;background:var(--panel2);cursor:pointer;font-size:11px;\x22>{{linkEditEnabled\x20?\x20\x27●\x20ON\x27\x20:\x20\x27○\x20OFF\x27}}</button></div><div\x20style=\x22display:flex;gap:8px;\x22><button\x20@click=\x22saveLink()\x22\x20:disabled=\x22savingLink\x22\x20style=\x22flex:1;padding:8px;border-radius:8px;border:1px\x20solid\x20var(--accent);background:rgba(77,163,255,0.1);color:var(--accent);cursor:pointer;font-size:12px;\x22><span\x20style=\x22display:flex;align-items:center;justify-content:center;gap:5px;\x22><span\x20:style=\x22savingLink?\x27display:inline-block\x27:\x27display:none\x27\x22\x20class=\x22spinner\x22/>\x20Save</span></button>\x20<button\x20@click=\x22deleteLink()\x22\x20:disabled=\x22savingLink\x22\x20style=\x22padding:8px\x2014px;border-radius:8px;border:1px\x20solid\x20#3d1a1a;background:rgba(255,59,48,0.08);color:var(--err);cursor:pointer;font-size:12px;\x22>Remove</button></div></div></if></div></if></div><div\x20style=\x22padding:9px\x2014px;background:var(--bg);border-top:1px\x20solid\x20var(--border2);display:flex;gap:16px;font-size:11px;align-items:center;flex-wrap:wrap;opacity:0.9;\x22><span><span\x20style=\x22color:var(--ok);\x22>●</span>\x20synced</span>\x20<span><span\x20style=\x22color:var(--okdb-info);\x22>●</span>\x20behind</span>\x20<span><span\x20style=\x22color:var(--rec);\x22>●</span>\x20reconciling</span>\x20<span><span\x20style=\x22color:var(--warn);\x22>●</span>\x20lag</span>\x20<span><span\x20style=\x22color:var(--err);\x22>●</span>\x20error</span>\x20<span><span\x20style=\x22color:var(--dis);\x22>●</span>\x20disabled</span>\x20<span\x20style=\x22opacity:0.4;\x22>⇄\x20both\x20→\x20send\x20←\x20receive\x20--\x20disabled\x20(click\x20to\x20inspect)</span></div></div>'};function _0x51ef(_0x4c017b,_0x562af6){_0x4c017b=_0x4c017b-0xcd;const _0x28ede2=_0x28ed();let _0x51efd4=_0x28ede2[_0x4c017b];return _0x51efd4;}function _0x28ed(){const _0x461ab1=['button','addEventListener','\x20nd-dim','panX','PUT','color:var(--ok)','nodeRadius','select','key','few\x20seconds\x20ago','link','mousemove','every','add','_effectivePos','has','\x20nd-lag','data','closeLinkEditor','border-color:var(--ok);color:var(--ok)','enabled','pointer-events:none','selfId','slice','idle','\x20L\x20','set','startsWith','parse','\x20nd-hover','disabled','_ro','find','now','.topo-g','url(#arrow-rev-','left','clientX','wheel','$dispatch','lastUpdatedAt','removeItem','node','_svgEl','values','fresh-stale','target','svg','length','topology','nd-','entries','/api/sync/links/','json','translate(','\x20nd-critical','last_seen','3892059JJSXGp','6132KCPmBi','loadingTopology','_onSvgMousedown','_linkHealth','/api/sync/reconcile-peer','selected_node_id','floor','_drag','reconcilingTarget','\x20(mesh)','getBoundingClientRect','filter','sync-topology','application/json','_autoRefreshTimer','hoveredNodeId','localeCompare','envs','color:var(--dis);opacity:0.7','_measure','behind','map','parentElement','backlog','node_hi','direction','_mouseupCb','includes','removeEventListener','layout','hi_to_lo','reconciling','savingLink','availableEnvs','_onWheel','\x20→\x20','\x20ln-lag-med','sqrt','canon','min','editingLink','hoveredLinkKey','lo_to_hi','\x20ln-dim','setAttribute','fresh-now','last_error','selectedLinkKey','_mousedownCb','1745216PuoYwP','clock','988317IKkbcQ','338072unTSNJ','stale','\x20⇄\x20','deltaY','grabbing','fitView','available_envs','\x20ln-disabled','1rFWLmH','clipboard','_mousemoveCb','border-color:var(--dis);color:var(--dis)','visibilitychange','207koSYDO','peers','style','stringify','_healthMarker','/api/sync/reconcile','cursor','linkEditEnvs','1200138HnwzAu','all','url(#arrow-rev-disabled)','mousedown','\x20nd-err','delete','pan','both','sin','lag-med','$attr','lo_pull','error','push','selectedNodeId','lag-high','\x20ln-lag-high','selectLink','$el','border-color:var(--accent);color:var(--accent);background:var(--bg)','height','refreshTopology','_visibilityHandler','getItem','\x20nd-stale','isLinkInteractable','Remove\x20this\x20data\x20link?\x20Nodes\x20stay\x20connected\x20but\x20data\x20will\x20stop\x20syncing.','5PsLdss','pointer-events:stroke;cursor:pointer','_loadPositions','/api/sync/topology','zoom','grab','\x20ln-rec','nodes','externalSelectedNodeId','indexOf','\x20ln-hover','max','url(#arrow-','_pullHealth','_onMouseup','url(#arrow-disabled)','DELETE','querySelector','top','_onMousemove','\x20ln-ok','\x20nd-behind','get','mouseup','cos','\x20ln-selected','observe','_tick','\x20ln-behind-light','_savePositions','links','10kubURI','linkEditDir','status','_applyTransform','_groupEl','sort','self_id','clientY','width','panY','2653329DlHQVX','message','preventDefault','transform','disconnect','Save\x20failed','critical','\x20nd-sel','\x20ln-err','type','_customPos','border-color:var(--accent);color:var(--accent)','_wheelCb','linkEditEnabled','_px2vb','POST','hi_pull','okdb-topo-pos'];_0x28ed=function(){return _0x461ab1;};return _0x28ed();}
|