@kedem/okdb 1.0.1 → 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.
Files changed (193) hide show
  1. package/bin/okdb.js +1 -1
  2. package/keys/public.pem +3 -0
  3. package/okdb.js +1 -1
  4. package/package.json +2 -2
  5. package/public/admin-app.js +1 -1
  6. package/public/components/admin-route-host.ok.js +1 -1
  7. package/public/components/env-picker.ok.js +1 -1
  8. package/public/components/field-path-input.ok.js +1 -1
  9. package/public/components/geo-map.ok.js +1 -1
  10. package/public/components/ok-cron-input.ok.js +1 -1
  11. package/public/components/ok-dropzone.ok.js +1 -1
  12. package/public/components/ok-js-input.ok.js +1 -1
  13. package/public/components/ok-json-input.ok.js +1 -1
  14. package/public/components/ok-text-monaco-input.ok.js +1 -1
  15. package/public/components/theme-toggle.ok.js +1 -1
  16. package/public/login-app.js +1 -1
  17. package/public/modules/ok.js +1 -1
  18. package/public/sections/api/parts/api-endpoint.ok.js +1 -1
  19. package/public/sections/auth/modals/create-token-modal.ok.js +1 -1
  20. package/public/sections/auth/modals/edit-token-modal.ok.js +1 -1
  21. package/public/sections/auth/modals/perm-info-popover.ok.js +1 -1
  22. package/public/sections/auth/parts/token-detail.ok.js +1 -1
  23. package/public/sections/auth/parts/token-list.ok.js +1 -1
  24. package/public/sections/db/modals/add-item-modal.ok.js +1 -1
  25. package/public/sections/db/modals/create-env-modal.ok.js +1 -1
  26. package/public/sections/db/modals/create-fts-modal.ok.js +1 -1
  27. package/public/sections/db/modals/create-index-modal.ok.js +1 -1
  28. package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -1
  29. package/public/sections/db/modals/demo-env-modal.ok.js +1 -1
  30. package/public/sections/db/modals/remove-env-modal.ok.js +1 -1
  31. package/public/sections/db/modals/schema-edit-modal.ok.js +1 -1
  32. package/public/sections/db/parts/db-overview.ok.js +1 -1
  33. package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -1
  34. package/public/sections/db/parts/edit-row.ok.js +1 -1
  35. package/public/sections/db/parts/tm-timeline.ok.js +1 -1
  36. package/public/sections/db/parts/type-changelog.ok.js +1 -1
  37. package/public/sections/db/parts/type-list.ok.js +1 -1
  38. package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -1
  39. package/public/sections/db/parts/type-schema-tab.ok.js +1 -1
  40. package/public/sections/db/parts/type-viewer.ok.js +1 -1
  41. package/public/sections/db/parts/type-violations-tab.ok.js +1 -1
  42. package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -1
  43. package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -1
  44. package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -1
  45. package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -1
  46. package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -1
  47. package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -1
  48. package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -1
  49. package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -1
  50. package/public/sections/embeddings/parts/embed-overview.ok.js +1 -1
  51. package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -1
  52. package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -1
  53. package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -1
  54. package/public/sections/embeddings/parts/engines-overview.ok.js +1 -1
  55. package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -1
  56. package/public/sections/engines/engine-panel-shared-style.js +1 -1
  57. package/public/sections/engines/engine-ui-utils.js +1 -1
  58. package/public/sections/engines/modals/engine-modal.ok.js +1 -1
  59. package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -1
  60. package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -1
  61. package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -1
  62. package/public/sections/engines/parts/engine-resource-card.ok.js +1 -1
  63. package/public/sections/engines/parts/engine-row-item.ok.js +1 -1
  64. package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -1
  65. package/public/sections/files/parts/files-blob-status.ok.js +1 -1
  66. package/public/sections/files/parts/files-collection-list.ok.js +1 -1
  67. package/public/sections/files/parts/files-collection-panel.ok.js +1 -1
  68. package/public/sections/files/parts/files-file-list.ok.js +1 -1
  69. package/public/sections/files/parts/files-overview.ok.js +1 -1
  70. package/public/sections/files/parts/files-path-browser.ok.js +1 -1
  71. package/public/sections/files/parts/files-upload-panel.ok.js +1 -1
  72. package/public/sections/functions/modals/function-modal.ok.js +1 -1
  73. package/public/sections/functions/parts/function-detail.ok.js +1 -1
  74. package/public/sections/functions/parts/function-logs.ok.js +1 -1
  75. package/public/sections/functions/parts/function-runner.ok.js +1 -1
  76. package/public/sections/functions/parts/functions-list.ok.js +1 -1
  77. package/public/sections/license/parts/license-panel.ok.js +1 -1
  78. package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -1
  79. package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -1
  80. package/public/sections/queue/modals/edit-job-modal.ok.js +1 -1
  81. package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -1
  82. package/public/sections/queue/modals/job-type-modal.ok.js +1 -1
  83. package/public/sections/queue/parts/ok-job-form.ok.js +1 -1
  84. package/public/sections/queue/parts/queue-buckets.ok.js +1 -1
  85. package/public/sections/queue/parts/queue-job-types.ok.js +1 -1
  86. package/public/sections/queue/parts/queue-jobs.ok.js +1 -1
  87. package/public/sections/queue/parts/queue-types.ok.js +1 -1
  88. package/public/sections/queue/parts/queue-workers.ok.js +1 -1
  89. package/public/sections/sync/parts/sync-node-detail.ok.js +1 -1
  90. package/public/sections/sync/parts/sync-retention.ok.js +1 -1
  91. package/public/sections/sync/parts/sync-topology.ok.js +1 -1
  92. package/public/sections/system/modals/data-ops-modal.ok.js +1 -1
  93. package/public/sections/system/parts/system-api-panel.ok.js +1 -1
  94. package/public/sections/system/parts/system-auth-panel.ok.js +1 -1
  95. package/public/sections/system/parts/system-log-history.ok.js +1 -1
  96. package/public/sections/system/parts/system-log.ok.js +1 -1
  97. package/public/sections/system/parts/system-status.ok.js +1 -1
  98. package/public/sections/system/parts/system-sync-panel.ok.js +1 -1
  99. package/public/sections/views/modals/create-view-modal.ok.js +1 -1
  100. package/public/sections/views/parts/view-detail.ok.js +1 -1
  101. package/public/sections/views/parts/views-list.ok.js +1 -1
  102. package/public/sections/views/parts/views-overview.ok.js +1 -1
  103. package/public/setup-app.js +1 -1
  104. package/public/stores/auth-store.js +1 -1
  105. package/public/stores/events-store.js +1 -1
  106. package/public/stores/functions-store.js +1 -1
  107. package/public/stores/okdb-store.js +1 -1
  108. package/public/stores/theme-store.js +1 -1
  109. package/public/util/permissions.js +1 -1
  110. package/public/util/sift-schema.js +1 -1
  111. package/public/vendor/okjs/ok.esm.min.js +1 -2
  112. package/public/vendor/okjs/toolkit/behavior/async.ok.js +1 -1
  113. package/public/vendor/okjs/toolkit/components/ok-chart.ok.js +1 -1
  114. package/public/vendor/okjs/toolkit/components/ok-doc-viewer.ok.js +1 -1
  115. package/public/vendor/okjs/toolkit/components/ok-marked.ok.js +1 -1
  116. package/public/vendor/okjs/toolkit/components/ok-monaco.ok.js +1 -1
  117. package/public/vendor/okjs/toolkit/core/ok-layer-service.ok.js +1 -1
  118. package/public/vendor/okjs/toolkit/core/ok-layer.ok.js +1 -1
  119. package/public/vendor/okjs/toolkit/core/ok-overlay.ok.js +1 -1
  120. package/public/vendor/okjs/toolkit/core/ok-sandbox.ok.js +1 -1
  121. package/public/vendor/okjs/toolkit/core/transition.ok.js +1 -1
  122. package/public/vendor/okjs/toolkit/core/virtualized.ok.js +1 -1
  123. package/public/vendor/okjs/toolkit/devtools/ok-console-service.ok.js +1 -1
  124. package/public/vendor/okjs/toolkit/devtools/ok-console.ok.js +1 -1
  125. package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor-service.ok.js +1 -1
  126. package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor.ok.js +1 -1
  127. package/public/vendor/okjs/toolkit/devtools/ok-inspector-service.ok.js +1 -1
  128. package/public/vendor/okjs/toolkit/devtools/ok-inspector.ok.js +1 -1
  129. package/public/vendor/okjs/toolkit/devtools/ok-js-tree.ok.js +1 -1
  130. package/public/vendor/okjs/toolkit/devtools/ok-timeline-service.ok.js +1 -1
  131. package/public/vendor/okjs/toolkit/devtools/ok-timeline.ok.js +1 -1
  132. package/public/vendor/okjs/toolkit/docs/doc-viewer.ok.js +1 -1
  133. package/public/vendor/okjs/toolkit/editor/ok-live-component.ok.js +1 -1
  134. package/public/vendor/okjs/toolkit/editor/ok-live-example.ok.js +1 -1
  135. package/public/vendor/okjs/toolkit/editor/ok-live-shell.ok.js +1 -1
  136. package/public/vendor/okjs/toolkit/elements/ok-dropdown.ok.js +1 -1
  137. package/public/vendor/okjs/toolkit/elements/ok-icon.ok.js +1 -1
  138. package/public/vendor/okjs/toolkit/elements/ok-select.ok.js +1 -1
  139. package/public/vendor/okjs/toolkit/elements/ok-table.ok.js +1 -1
  140. package/public/vendor/okjs/toolkit/errors/ok-crash-boundary.ok.js +1 -1
  141. package/public/vendor/okjs/toolkit/errors/ok-crash-info.ok.js +1 -1
  142. package/public/vendor/okjs/toolkit/i18n/i18n-editor-examples.ok.js +1 -1
  143. package/public/vendor/okjs/toolkit/i18n/i18n-editor.ok.js +1 -1
  144. package/public/vendor/okjs/toolkit/i18n/i18n-key-editor-tips.ok.js +1 -1
  145. package/public/vendor/okjs/toolkit/i18n/i18n-key-editor.ok.js +1 -1
  146. package/public/vendor/okjs/toolkit/i18n/i18n-service.ok.js +1 -1
  147. package/public/vendor/okjs/toolkit/i18n/ok-i18n.js +1 -1
  148. package/public/vendor/okjs/toolkit/interaction/ok-contextmenu.ok.js +1 -1
  149. package/public/vendor/okjs/toolkit/interaction/ok-dismiss-service.ok.js +1 -1
  150. package/public/vendor/okjs/toolkit/interaction/ok-draggable.ok.js +1 -1
  151. package/public/vendor/okjs/toolkit/interaction/ok-flyover-panel.ok.js +1 -1
  152. package/public/vendor/okjs/toolkit/interaction/ok-flyover.ok.js +1 -1
  153. package/public/vendor/okjs/toolkit/interaction/ok-highlight-service.ok.js +1 -1
  154. package/public/vendor/okjs/toolkit/interaction/ok-highlight.ok.js +1 -1
  155. package/public/vendor/okjs/toolkit/interaction/ok-hotkeys-service.ok.js +1 -1
  156. package/public/vendor/okjs/toolkit/interaction/ok-picker-service.ok.js +1 -1
  157. package/public/vendor/okjs/toolkit/interaction/ok-popout-service.ok.js +1 -1
  158. package/public/vendor/okjs/toolkit/interaction/ok-popout.ok.js +1 -1
  159. package/public/vendor/okjs/toolkit/interaction/ok-portal-service.ok.js +1 -1
  160. package/public/vendor/okjs/toolkit/interaction/ok-submenu.ok.js +1 -1
  161. package/public/vendor/okjs/toolkit/layout/ok-resizer.ok.js +1 -1
  162. package/public/vendor/okjs/toolkit/manifest.js +1 -1
  163. package/public/vendor/okjs/toolkit/modals/ok-modal-service.ok.js +1 -1
  164. package/public/vendor/okjs/toolkit/modals/ok-modal.ok.js +1 -1
  165. package/public/vendor/okjs/toolkit/modals/ok-toast-service.ok.js +1 -1
  166. package/public/vendor/okjs/toolkit/modals/ok-window.ok.js +1 -1
  167. package/public/vendor/okjs/toolkit/navigation/hash-router.ok.js +1 -1
  168. package/public/vendor/okjs/toolkit/navigation/history-router.ok.js +1 -1
  169. package/public/vendor/okjs/toolkit/navigation/router.ok.js +1 -1
  170. package/public/vendor/okjs/toolkit/sync/reactive-sync-service.ok.js +1 -1
  171. package/public/vendor/okjs/toolkit/sync/reactive-sync.js +1 -1
  172. package/public/vendor/okjs/toolkit/theming/blocks/ok-design-button.css.js +1 -1
  173. package/public/vendor/okjs/toolkit/theming/blocks/ok-design-input.css.js +1 -1
  174. package/public/vendor/okjs/toolkit/theming/ok-design-style.js +1 -1
  175. package/public/vendor/okjs/toolkit/theming/ok-design-vars.js +1 -1
  176. package/public/vendor/okjs/toolkit/theming/ok-design.ok.js +1 -1
  177. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-input.ok.js +1 -1
  178. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-service.ok.js +1 -1
  179. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-style.js +1 -1
  180. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-utils.js +1 -1
  181. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-variable.ok.js +1 -1
  182. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-vm.js +1 -1
  183. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor.ok.js +1 -1
  184. package/public/vendor/okjs/toolkit/theming/ok-theme.ok.js +1 -1
  185. package/public/view-models/type-query-vm.js +1 -1
  186. package/okdb-data/default/data.mdb +0 -0
  187. package/okdb-data/default/lock.mdb +0 -0
  188. package/okdb-data/~log/data.mdb +0 -0
  189. package/okdb-data/~log/lock.mdb +0 -0
  190. package/okdb-data/~system/data.mdb +0 -0
  191. package/okdb-data/~system/lock.mdb +0 -0
  192. package/public/images/logo.png +0 -0
  193. package/public/images/logo.svg +0 -333
@@ -1 +1 @@
1
- function _0x15a2(){const _0x2ceb39=['setItem','1163368RBnNTG','externalSelectedNodeId','topology','_mousemoveCb','envs','node','node_hi','_recomputeLayout','hoveredLinkKey','fresh-stale','\x20ln-disabled','left','selfId','cos','/api/sync/reconcile-peer','lo_to_hi','_customPos','zoom','type','refreshTopology','application/json','lag-med','status','/api/sync/links/','selectLink','few\x20seconds\x20ago','_onSvgMousedown','direction','includes','json','wheel','\x20nd-lag','min','\x20→\x20','set','rec','\x20nd-critical','sin','_autoRefreshTimer','Remove\x20this\x20data\x20link?\x20Nodes\x20stay\x20connected\x20but\x20data\x20will\x20stop\x20syncing.','addEventListener','now','\x20nd-stale','$dispatch','has','both','translate(','length','idle','indexOf','disabled','\x20ln-lag-high','_onMouseup','panY','lo_pull','push','floor','\x20nd-hover','stringify','select','startsWith','selectedLinkKey','all','hoveredNodeId','color:var(--dis);opacity:0.7','_wheelCb','autoRefresh','lag-high','mousedown','hi_to_lo','isLinkInteractable','Save\x20failed','_onWheel','last_seen','removeEventListener','style','_mousedownCb','disconnect','3425260gFlLng','reconciling','height','577550oIposY','key','stale','12256006OnHxhv','.topo-g','fresh-ok','transform','loadingTopology','pointer-events:none','_effectivePos','editingLink','slice','okdb-topo-pos','savingLink','last_error','_healthMarker','enabled','backlog',')\x20scale(','588201pyoymB','nodeRadius','$attr','preventDefault','_groupEl','nodes','color:var(--ok)','getItem','/api/sync/reconcile','svg','hi_pull','get','lastUpdatedAt','_drag','_savePositions','map','mousemove','/api/sync/topology','available_envs','\x20ln-stale','_applyTransform','parse','\x20nd-dim','_svgEl','canon','visibilitychange','sort','getBoundingClientRect','clientY','message','\x20(mesh)','mouseup','links','removeItem','layout','sqrt','linkEditEnabled','url(#arrow-rev-','_ro','refresh\x20failed','selected_node_id','$el','\x20ln-rec','_mouseupCb','selectedNodeId','address','url(#arrow-disabled)','pan','_px2vb','lagging','self_id','clock','fitView','critical','querySelector','find','width','POST','error','deltaY','nodeHealth','clientX','$watch','\x20ln-err','writeText','availableEnvs','8157420IhQrpP','forEach','linkEditEnvs','clipboard','35145ytZcsZ','behind','\x20L\x20','delete','top','panX','filter','url(#arrow-','values','grabbing','_pullHealth','node_lo','\x20ln-dim','_visibilityHandler','parentElement','grab','cursor','_tick','reconcilingTarget','_measure','observe','max','border-color:var(--dis);color:var(--dis)','linkEditDir','link','DELETE','setAttribute','border-color:var(--accent);color:var(--accent);background:var(--bg)','pos','\x20⇄\x20','fresh-now','<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>'];_0x15a2=function(){return _0x2ceb39;};return _0x15a2();}const _0x4a26d6=_0x3111;function _0x3111(_0x14d4a3,_0x106efd){_0x14d4a3=_0x14d4a3-0xba;const _0x15a23b=_0x15a2();let _0x3111ba=_0x15a23b[_0x14d4a3];return _0x3111ba;}(function(_0x504811,_0x1e5e47){const _0xc1ed=_0x3111,_0x21d417=_0x504811();while(!![]){try{const _0x294e9d=-parseInt(_0xc1ed(0x152))/0x1+-parseInt(_0xc1ed(0xee))/0x2+-parseInt(_0xc1ed(0xcd))/0x3+-parseInt(_0xc1ed(0x13c))/0x4+-parseInt(_0xc1ed(0x13f))/0x5+parseInt(_0xc1ed(0xc9))/0x6+parseInt(_0xc1ed(0x142))/0x7;if(_0x294e9d===_0x1e5e47)break;else _0x21d417['push'](_0x21d417['shift']());}catch(_0x32f5a0){_0x21d417['push'](_0x21d417['shift']());}}}(_0x15a2,0xe9a4b));export default{'tag':'sync-topology','unwrap':!0x0,'context':_0x18a441=>({'w':0x384,'h':0x1f4,'layout':{'cx':0x0,'cy':0x0,'r':0x0,'pos':{}},'_ro':null,'_tick':null,'now':Date[_0x4a26d6(0x117)](),'selectedNodeId':null,'selectedLinkKey':null,'hoveredLinkKey':null,'hoveredNodeId':null,'lastUpdatedAt':null,'autoRefresh':!0x0,'autoRefreshIntervalMs':0x1388,'_autoRefreshTimer':null,'loadingTopology':!0x1,'editingLink':null,'linkEditDir':_0x4a26d6(0x11b),'linkEditEnvs':null,'linkEditEnabled':!0x0,'savingLink':!0x1,'panX':0x0,'panY':0x0,'zoom':0x1,'_drag':null,'_customPos':{},'_svgEl':null,'_groupEl':null,'_applyTransform'(){const _0x542513=_0x4a26d6;this['_groupEl']||(this[_0x542513(0x156)]=this[_0x542513(0x169)]?.[_0x542513(0xbd)](_0x542513(0x143))),this[_0x542513(0x156)]&&this[_0x542513(0x156)][_0x542513(0xe7)](_0x542513(0x145),_0x542513(0x11c)+this[_0x542513(0xd2)]+','+this['panY']+_0x542513(0x151)+this['zoom']+')');},'_px2vb'(){const _0x17e13e=_0x4a26d6;if(!this['_svgEl'])return{'sx':0x1,'sy':0x1};const _0x2a8ecf=this[_0x17e13e(0x169)][_0x17e13e(0x16d)]();return{'sx':this['w']/(_0x2a8ecf[_0x17e13e(0xbf)]||0x1),'sy':this['h']/(_0x2a8ecf[_0x17e13e(0x13e)]||0x1)};},'_onWheel'(_0x2cfbd5){const _0x254d32=_0x4a26d6;if(!this['_svgEl'])return;const _0xc19cd8=this[_0x254d32(0x169)][_0x254d32(0x16d)](),{sx:_0x3d5760,sy:_0x25af5d}=this['_px2vb'](),_0x38e12d=(_0x2cfbd5[_0x254d32(0xc4)]-_0xc19cd8['left'])*_0x3d5760,_0x341ba7=(_0x2cfbd5['clientY']-_0xc19cd8[_0x254d32(0xd1)])*_0x25af5d,_0x452a1c=_0x2cfbd5[_0x254d32(0xc2)]<0x0?1.12:0x1/1.12,_0x185291=Math[_0x254d32(0xe2)](0.1,Math[_0x254d32(0x10e)](0x8,this[_0x254d32(0xff)]*_0x452a1c)),_0x27dab7=_0x185291/this['zoom'];this[_0x254d32(0xd2)]=_0x38e12d+(this[_0x254d32(0xd2)]-_0x38e12d)*_0x27dab7,this[_0x254d32(0x123)]=_0x341ba7+(this[_0x254d32(0x123)]-_0x341ba7)*_0x27dab7,this[_0x254d32(0xff)]=_0x185291,this[_0x254d32(0x166)]();},'_onSvgMousedown'(_0x18386e){const _0xbc9fdc=_0x4a26d6;if(0x0!==_0x18386e['button'])return;_0x18386e[_0xbc9fdc(0x155)]();let _0x1333a2=null,_0x3677eb=_0x18386e['target'];for(;_0x3677eb&&_0x3677eb!==this[_0xbc9fdc(0x169)];){if(_0x3677eb['id']&&_0x3677eb['id'][_0xbc9fdc(0x12a)]('nd-')){_0x1333a2=_0x3677eb['id'][_0xbc9fdc(0x14a)](0x3);break;}_0x3677eb=_0x3677eb[_0xbc9fdc(0xdb)];}if(_0x1333a2){const _0x4d67aa=this[_0xbc9fdc(0x169)][_0xbc9fdc(0x16d)](),{sx:_0x1300a4,sy:_0x21e68b}=this[_0xbc9fdc(0x182)](),_0x1bcc44=(_0x18386e[_0xbc9fdc(0xc4)]-_0x4d67aa[_0xbc9fdc(0xf9)])*_0x1300a4,_0x42c0cc=(_0x18386e[_0xbc9fdc(0x16e)]-_0x4d67aa[_0xbc9fdc(0xd1)])*_0x21e68b,_0x42cf3b=(_0x1bcc44-this['panX'])/this[_0xbc9fdc(0xff)],_0x580d84=(_0x42c0cc-this[_0xbc9fdc(0x123)])/this[_0xbc9fdc(0xff)],_0x170ef3=this[_0xbc9fdc(0x148)](_0x1333a2)||{'x':_0x42cf3b,'y':_0x580d84};this[_0xbc9fdc(0x15f)]={'type':_0xbc9fdc(0xf3),'id':_0x1333a2,'ox':_0x42cf3b-_0x170ef3['x'],'oy':_0x580d84-_0x170ef3['y']};}else this['_drag']={'type':_0xbc9fdc(0x181),'sx':_0x18386e['clientX'],'sy':_0x18386e[_0xbc9fdc(0x16e)],'px':this[_0xbc9fdc(0xd2)],'py':this['panY']};this[_0xbc9fdc(0x169)]&&(this[_0xbc9fdc(0x169)][_0xbc9fdc(0x139)][_0xbc9fdc(0xdd)]=_0xbc9fdc(0xd6));},'_onMousemove'(_0x26f495){const _0x1e1c54=_0x4a26d6;if(!this[_0x1e1c54(0x15f)])return;const {sx:_0x4838d7,sy:_0x56089d}=this[_0x1e1c54(0x182)]();if(_0x1e1c54(0x181)===this['_drag'][_0x1e1c54(0x100)])this[_0x1e1c54(0xd2)]=this['_drag']['px']+(_0x26f495[_0x1e1c54(0xc4)]-this['_drag']['sx'])*_0x4838d7,this[_0x1e1c54(0x123)]=this[_0x1e1c54(0x15f)]['py']+(_0x26f495[_0x1e1c54(0x16e)]-this[_0x1e1c54(0x15f)]['sy'])*_0x56089d,this[_0x1e1c54(0x166)]();else{const _0xe18dbe=this[_0x1e1c54(0x169)][_0x1e1c54(0x16d)](),_0x424a82=(_0x26f495[_0x1e1c54(0xc4)]-_0xe18dbe[_0x1e1c54(0xf9)])*_0x4838d7,_0x13fa24=(_0x26f495[_0x1e1c54(0x16e)]-_0xe18dbe[_0x1e1c54(0xd1)])*_0x56089d,_0x440d4b=(_0x424a82-this[_0x1e1c54(0xd2)])/this[_0x1e1c54(0xff)],_0x2a3808=(_0x13fa24-this[_0x1e1c54(0x123)])/this[_0x1e1c54(0xff)];this['_customPos']={...this['_customPos'],[this[_0x1e1c54(0x15f)]['id']]:{'x':_0x440d4b-this[_0x1e1c54(0x15f)]['ox'],'y':_0x2a3808-this[_0x1e1c54(0x15f)]['oy']}},this[_0x1e1c54(0x160)]();}},'_onMouseup'(){const _0x547cfd=_0x4a26d6;this[_0x547cfd(0x15f)]=null,this['_svgEl']&&(this['_svgEl']['style'][_0x547cfd(0xdd)]=_0x547cfd(0xdc));},get 'externalSelectedNodeId'(){const _0x29de75=_0x4a26d6;return _0x18a441['$attr'][_0x29de75(0x17a)]??null;},get 'selfId'(){const _0x56ed28=_0x4a26d6;return _0x18a441[_0x56ed28(0x154)][_0x56ed28(0x184)];},get 'topology'(){const _0x2aa8b7=_0x4a26d6;return _0x18a441[_0x2aa8b7(0x154)]['topology']||{};},get 'availableEnvs'(){const _0x28c3cd=_0x4a26d6;return _0x18a441[_0x28c3cd(0x154)][_0x28c3cd(0x164)]||[];},get 'envButtons'(){const _0x4d2865=_0x4a26d6,_0x453e63=this[_0x4d2865(0xcb)];return(_0x18a441[_0x4d2865(0x154)][_0x4d2865(0x164)]||[])[_0x4d2865(0x161)](_0x26130c=>({'name':_0x26130c,'style':null===_0x453e63||Array['isArray'](_0x453e63)&&_0x453e63[_0x4d2865(0x10a)](_0x26130c)?_0x4d2865(0xe8):''}));},get 'dirButtons'(){const _0x26296a=_0x4a26d6,_0x49610e=this['editingLink'];if(!_0x49610e)return[];const _0x500e96=_0x49610e['lo']['slice'](0x0,0x6),_0xe769b5=_0x49610e['hi'][_0x26296a(0x14a)](0x0,0x6),_0x5365f2=this['linkEditDir'];return[{'canon':_0x26296a(0x11b),'label':_0x500e96+_0x26296a(0xea)+_0xe769b5},{'canon':_0x26296a(0xfd),'label':_0x500e96+_0x26296a(0x10f)+_0xe769b5},{'canon':_0x26296a(0x133),'label':_0xe769b5+'\x20→\x20'+_0x500e96}][_0x26296a(0x161)](_0x53843a=>({..._0x53843a,'style':_0x53843a[_0x26296a(0x16a)]===_0x5365f2?'border-color:var(--accent);color:var(--accent)':''}));},get 'nodes'(){const _0x7adb1d=_0x4a26d6;return Object[_0x7adb1d(0xd5)](this['topology']||{})[_0x7adb1d(0xd3)](_0x4b30de=>_0x4b30de&&null!=_0x4b30de['id'])[_0x7adb1d(0x16c)]((_0x572c48,_0x1bcf03)=>String(_0x572c48['id'])['localeCompare'](String(_0x1bcf03['id'])));},get 'nodeList'(){const _0x7a600a=_0x4a26d6;return this[_0x7a600a(0x157)][_0x7a600a(0x161)](_0x59aabb=>{const _0x4238ed=_0x7a600a,_0x1c4c71=this['_customPos'][_0x59aabb['id']]||this[_0x4238ed(0x174)]['pos']?.[_0x59aabb['id']]||{'x':this['w']/0x2,'y':this['h']/0x2};return{..._0x59aabb,'px':_0x1c4c71['x'],'py':_0x1c4c71['y']};});},get 'links'(){const _0x4d82db=_0x4a26d6,_0x259a07=this[_0x4d82db(0xf0)]||{},_0x472bb4=_0x259a07[this[_0x4d82db(0xfa)]]||Object[_0x4d82db(0xd5)](_0x259a07)['find'](_0x34bb7b=>null!=_0x34bb7b?.[_0x4d82db(0x172)]),_0xd00e00=_0x472bb4?.['links']||{},_0x2c0a53=new Map(),_0x4af9a6=(_0x565eae,_0x5058d1)=>({'status':_0x565eae['status']||_0x4d82db(0x11e),'backlog':Math['max'](0x0,Number(_0x5058d1??0x0)-Number(_0x565eae[_0x4d82db(0xba)]??0x0)),'last_seen':_0x565eae[_0x4d82db(0x137)]??null,'last_error':_0x565eae[_0x4d82db(0x14d)]??null});for(const _0xc3c1ff in _0x259a07){const _0x372dd9=_0x259a07[_0xc3c1ff];if(_0x372dd9?.['peers'])for(const _0x55c54b in _0x372dd9['peers']){const _0x509ecd=_0xc3c1ff<_0x55c54b?_0xc3c1ff:_0x55c54b,_0x832bad=_0xc3c1ff<_0x55c54b?_0x55c54b:_0xc3c1ff,_0x3c56a0=_0x509ecd+':'+_0x832bad;_0x2c0a53[_0x4d82db(0x11a)](_0x3c56a0)||_0x2c0a53[_0x4d82db(0x110)](_0x3c56a0,{'lo':_0x509ecd,'hi':_0x832bad,'lo_pull':null,'hi_pull':null});const _0x11e04c=_0x2c0a53[_0x4d82db(0x15d)](_0x3c56a0),_0x4f61f9=_0x372dd9['peers'][_0x55c54b];_0xc3c1ff===_0x509ecd?_0x11e04c[_0x4d82db(0x124)]=_0x4af9a6(_0x4f61f9,_0x259a07[_0x55c54b]?.[_0x4d82db(0xba)]):_0x11e04c[_0x4d82db(0x15c)]=_0x4af9a6(_0x4f61f9,_0x259a07[_0x55c54b]?.[_0x4d82db(0xba)]);}}for(const _0x47d608 in _0xd00e00)if(_0xd00e00[_0x47d608]&&!_0x2c0a53[_0x4d82db(0x11a)](_0x47d608)){const _0x5ddb2c=_0xd00e00[_0x47d608];_0x2c0a53[_0x4d82db(0x110)](_0x47d608,{'lo':_0x5ddb2c[_0x4d82db(0xd8)],'hi':_0x5ddb2c[_0x4d82db(0xf4)],'lo_pull':null,'hi_pull':null});}return[..._0x2c0a53['entries']()]['map'](([_0x2fc3e7,_0x5d1e03])=>({'key':_0x2fc3e7,'lo':_0x5d1e03['lo'],'hi':_0x5d1e03['hi'],'link':_0xd00e00[_0x2fc3e7]||null,'lo_pull':_0x5d1e03['lo_pull'],'hi_pull':_0x5d1e03['hi_pull']}));},'_linkConfig'(_0x1bc225){const _0x35531b=_0x4a26d6,_0x2ba74f=(this[_0x35531b(0xf0)]||{})[this[_0x35531b(0xfa)]];return _0x2ba74f?.[_0x35531b(0x172)]?.[_0x1bc225]||null;},'_linkHealth'(_0x41a7cd){const _0x1c517e=_0x4a26d6;if(_0x41a7cd['link']&&!_0x41a7cd[_0x1c517e(0xe5)][_0x1c517e(0x14f)])return'disabled';const _0x101242=_0x41a7cd[_0x1c517e(0xe5)]?.[_0x1c517e(0x109)]??'both',_0x497a1e=[];'both'!==_0x101242&&'lo_to_hi'!==_0x101242||_0x497a1e[_0x1c517e(0x125)](_0x41a7cd['hi_pull']),_0x1c517e(0x11b)!==_0x101242&&_0x1c517e(0x133)!==_0x101242||_0x497a1e[_0x1c517e(0x125)](_0x41a7cd[_0x1c517e(0x124)]);const _0x4cff43=['error',_0x1c517e(0x131),'lag-med',_0x1c517e(0xce),_0x1c517e(0x13d),'stale','ok'];let _0x3c58d1=_0x1c517e(0x141);for(const _0x2b6ea3 of _0x497a1e){const _0x2804d0=this[_0x1c517e(0xd7)](_0x2b6ea3);_0x4cff43[_0x1c517e(0x11f)](_0x2804d0)<_0x4cff43[_0x1c517e(0x11f)](_0x3c58d1)&&(_0x3c58d1=_0x2804d0);}return _0x3c58d1;},'_pullHealth'(_0x23a388){const _0x5d6b65=_0x4a26d6;if(!_0x23a388)return _0x5d6b65(0x141);if(_0x5d6b65(0x13d)===_0x23a388[_0x5d6b65(0x104)])return _0x5d6b65(0x13d);if(_0x23a388[_0x5d6b65(0x137)]){const _0x5009b8=this[_0x5d6b65(0x117)]-Number(_0x23a388[_0x5d6b65(0x137)]);return _0x23a388[_0x5d6b65(0x150)]>0x32?_0x5d6b65(0x131):_0x23a388[_0x5d6b65(0x150)]>0x5?'lag-med':_0x23a388[_0x5d6b65(0x150)]>0x0?'behind':_0x5009b8>0x7530?_0x5d6b65(0x141):'ok';}return _0x23a388[_0x5d6b65(0x14d)]?_0x5d6b65(0xc1):_0x5d6b65(0x141);},'_healthMarker':_0x341170=>'error'===_0x341170?'err':'reconciling'===_0x341170?_0x4a26d6(0x111):_0x4a26d6(0x131)===_0x341170?_0x4a26d6(0x131):_0x4a26d6(0x103)===_0x341170||_0x4a26d6(0xce)===_0x341170||_0x4a26d6(0x141)===_0x341170?'lag-med':'ok','_linkDirLabel'(_0x274e53){const _0x1276cc=_0x4a26d6;if(!_0x274e53['link'])return _0x274e53['lo'][_0x1276cc(0x14a)](0x0,0x6)+_0x1276cc(0xea)+_0x274e53['hi'][_0x1276cc(0x14a)](0x0,0x6)+_0x1276cc(0x170);if(!_0x274e53['link'][_0x1276cc(0x14f)])return'disabled';const _0x3c770c=_0x274e53['lo'][_0x1276cc(0x14a)](0x0,0x6),_0x2ff9f3=_0x274e53['hi'][_0x1276cc(0x14a)](0x0,0x6);switch(_0x274e53[_0x1276cc(0xe5)][_0x1276cc(0x109)]){case _0x1276cc(0x11b):return _0x3c770c+'\x20⇄\x20'+_0x2ff9f3;case _0x1276cc(0xfd):return _0x3c770c+_0x1276cc(0x10f)+_0x2ff9f3;case _0x1276cc(0x133):return _0x2ff9f3+_0x1276cc(0x10f)+_0x3c770c;default:return _0x274e53[_0x1276cc(0xe5)]['direction'];}},get 'selection'(){const _0x5a125d=_0x4a26d6;if(this[_0x5a125d(0x12b)]){const _0x192bea=this['links'][_0x5a125d(0xbe)](_0x193b00=>_0x193b00['key']===this[_0x5a125d(0x12b)])||null;if(_0x192bea)return{'type':_0x5a125d(0xe5),'data':_0x192bea};}if(this['selectedNodeId']){const _0x5e875e=this[_0x5a125d(0xf0)][this[_0x5a125d(0x17e)]]||null;return _0x5e875e?{'type':_0x5a125d(0xf3),'id':this[_0x5a125d(0x17e)],'data':_0x5e875e}:null;}return null;},get 'freshnessLabel'(){const _0x1314c7=_0x4a26d6;if(!this['lastUpdatedAt'])return'never';const _0x144872=this['now']-this[_0x1314c7(0x15e)];return _0x144872<0x5dc?'now':_0x144872<0x1388?_0x1314c7(0x107):_0x144872<0x3a98?'recent':Math[_0x1314c7(0x126)](_0x144872/0x3e8)+'s\x20ago';},get 'freshnessClass'(){const _0x37e482=_0x4a26d6;if(!this[_0x37e482(0x15e)])return'fresh-stale';const _0x5472d7=this['now']-this[_0x37e482(0x15e)];return _0x5472d7<0x1388?_0x37e482(0xeb):_0x5472d7<0x3a98?_0x37e482(0x144):_0x37e482(0xf7);},'_recomputeLayout'(){const _0x5a7f11=_0x4a26d6,_0x2807a6=this[_0x5a7f11(0x157)],_0x397b2a=this['w']/0x2,_0x188dcd=this['h']/0x2,_0x515dd2=Math[_0x5a7f11(0xe2)](0x50,Math[_0x5a7f11(0x10e)](_0x397b2a,_0x188dcd)-this[_0x5a7f11(0x153)]()-0x3c),_0x23d73f={},_0x569cd2=_0x2807a6[_0x5a7f11(0x11d)]||0x1;_0x2807a6[_0x5a7f11(0xca)]((_0x95bf5e,_0x2e7f52)=>{const _0x17f6fa=_0x5a7f11;if(0x1===_0x569cd2)return void(_0x23d73f[_0x95bf5e['id']]={'x':_0x397b2a,'y':_0x188dcd});const _0x49691d=0x2===_0x569cd2?0x0===_0x2e7f52?Math['PI']:0x0:_0x2e7f52/_0x569cd2*Math['PI']*0x2-Math['PI']/0x2;_0x23d73f[_0x95bf5e['id']]={'x':_0x397b2a+_0x515dd2*Math[_0x17f6fa(0xfb)](_0x49691d),'y':_0x188dcd+_0x515dd2*Math[_0x17f6fa(0x113)](_0x49691d)};}),this[_0x5a7f11(0x174)]={'cx':_0x397b2a,'cy':_0x188dcd,'r':_0x515dd2,'pos':_0x23d73f};},'_measure'(){const _0x217e95=_0x4a26d6,_0x38caa7=(this[_0x217e95(0x169)]||_0x18a441[_0x217e95(0x17b)])[_0x217e95(0x16d)]();this['w']=Math[_0x217e95(0xe2)](0x12c,_0x38caa7[_0x217e95(0xbf)]||0x384),this['h']=Math[_0x217e95(0xe2)](0xc8,_0x38caa7[_0x217e95(0x13e)]||0x1f4),this[_0x217e95(0xf5)]();},'_effectivePos'(_0x5e9ac8){const _0x120efa=_0x4a26d6;return this[_0x120efa(0xfe)][_0x5e9ac8]||this['layout'][_0x120efa(0xe9)]?.[_0x5e9ac8]||null;},'fitView'(){const _0x4c3153=_0x4a26d6;this[_0x4c3153(0xe0)]();const _0x285268=this[_0x4c3153(0x157)];if(!_0x285268[_0x4c3153(0x11d)])return;let _0x2c37dd=0x1/0x0,_0x347a6b=0x1/0x0,_0x4891fd=-0x1/0x0,_0x2b9568=-0x1/0x0;for(const _0x54a6f9 of _0x285268){const _0x53b0bc=this[_0x4c3153(0x148)](_0x54a6f9['id']);_0x53b0bc&&(_0x2c37dd=Math['min'](_0x2c37dd,_0x53b0bc['x']),_0x347a6b=Math['min'](_0x347a6b,_0x53b0bc['y']),_0x4891fd=Math[_0x4c3153(0xe2)](_0x4891fd,_0x53b0bc['x']),_0x2b9568=Math[_0x4c3153(0xe2)](_0x2b9568,_0x53b0bc['y']));}if(!isFinite(_0x2c37dd))return;const _0x17967d=this[_0x4c3153(0x153)]()+0x3c;_0x2c37dd-=_0x17967d,_0x347a6b-=_0x17967d,_0x4891fd+=_0x17967d,_0x2b9568+=_0x17967d;const _0x5b457d=_0x4891fd-_0x2c37dd,_0x1d2fb6=_0x2b9568-_0x347a6b,_0x173e35=0.88*Math['min'](this['w']/_0x5b457d,this['h']/_0x1d2fb6,0x3);this[_0x4c3153(0xff)]=_0x173e35,this[_0x4c3153(0xd2)]=this['w']/0x2-(_0x2c37dd+_0x5b457d/0x2)*_0x173e35,this['panY']=this['h']/0x2-(_0x347a6b+_0x1d2fb6/0x2)*_0x173e35,this['_applyTransform']();},'resetLayout'(){const _0x4cb462=_0x4a26d6;this['_customPos']={};try{localStorage[_0x4cb462(0x173)](_0x4cb462(0x14b));}catch{}this['fitView']();},'_savePositions'(){const _0x11061e=_0x4a26d6;try{localStorage[_0x11061e(0xed)](_0x11061e(0x14b),JSON[_0x11061e(0x128)](this[_0x11061e(0xfe)]));}catch{}},'_loadPositions'(){const _0x10cced=_0x4a26d6;try{const _0x111bc5=localStorage[_0x10cced(0x159)](_0x10cced(0x14b));_0x111bc5&&(this['_customPos']=JSON[_0x10cced(0x167)](_0x111bc5));}catch{}},'nodeRadius':()=>0x16,'linkPath'(_0x3c79b7){const _0x4875cf=_0x4a26d6,_0x129848=this['_effectivePos'](_0x3c79b7['lo']),_0x3ba664=this[_0x4875cf(0x148)](_0x3c79b7['hi']);if(!_0x129848||!_0x3ba664)return'';const _0x2de9b5=_0x3ba664['x']-_0x129848['x'],_0x244871=_0x3ba664['y']-_0x129848['y'],_0x1bec33=Math[_0x4875cf(0x175)](_0x2de9b5*_0x2de9b5+_0x244871*_0x244871)||0x1,_0x1d453c=this['nodeRadius']();return'M\x20'+(_0x129848['x']+_0x2de9b5/_0x1bec33*_0x1d453c)+'\x20'+(_0x129848['y']+_0x244871/_0x1bec33*_0x1d453c)+_0x4875cf(0xcf)+(_0x3ba664['x']-_0x2de9b5/_0x1bec33*_0x1d453c)+'\x20'+(_0x3ba664['y']-_0x244871/_0x1bec33*_0x1d453c);},'reconciling':!0x1,'reconcilingTarget':null,async 'refreshTopology'(){const _0x554412=_0x4a26d6;if(!this['loadingTopology']){this[_0x554412(0x146)]=!0x0;try{const _0x2d6199=await fetch(_0x554412(0x163)),_0x18722a=await _0x2d6199[_0x554412(0x10b)](),_0x1148b7=_0x18722a['data']??_0x18722a;_0x18a441[_0x554412(0x154)][_0x554412(0xf0)]=_0x1148b7[_0x554412(0xf0)]??_0x1148b7,_0x18a441[_0x554412(0x154)][_0x554412(0x164)]=_0x1148b7[_0x554412(0xc8)]??[],this['lastUpdatedAt']=Date['now']();}catch(_0x41e1ca){console[_0x554412(0xc1)](_0x554412(0x179),_0x41e1ca);}finally{this[_0x554412(0x146)]=!0x1;}}},async 'reconcileAll'(){const _0xb48cf7=_0x4a26d6;if(!this[_0xb48cf7(0x13d)]){this[_0xb48cf7(0x13d)]=!0x0,this[_0xb48cf7(0xdf)]=_0xb48cf7(0x12c);try{await fetch('/api/sync/reconcile-all',{'method':_0xb48cf7(0xc0)}),await this[_0xb48cf7(0x101)]();}finally{this['reconciling']=!0x1,this[_0xb48cf7(0xdf)]=null;}}},async 'reconcileNode'(_0x3792b4){const _0x500803=_0x4a26d6;if(!this[_0x500803(0x13d)]){this[_0x500803(0x13d)]=!0x0,this[_0x500803(0xdf)]=_0x3792b4;try{_0x3792b4===this['selfId']?await fetch(_0x500803(0x15a),{'method':_0x500803(0xc0)}):await fetch(this[_0x500803(0xf0)][_0x3792b4]?.[_0x500803(0x17f)]+_0x500803(0x15a),{'method':_0x500803(0xc0)}),await this[_0x500803(0x101)]();}finally{this[_0x500803(0x13d)]=!0x1,this[_0x500803(0xdf)]=null;}}},async 'reconcileLink'(_0x4d6b0d){const _0x4ff58f=_0x4a26d6;if(this[_0x4ff58f(0x13d)])return;this['reconciling']=!0x0,this['reconcilingTarget']=_0x4d6b0d[_0x4ff58f(0x140)];const _0x914ce4=_0x4d6b0d['lo']===this[_0x4ff58f(0xfa)]?_0x4d6b0d['hi']:_0x4d6b0d['lo'];try{await fetch(_0x4ff58f(0xfc),{'method':_0x4ff58f(0xc0),'headers':{'Content-Type':_0x4ff58f(0x102)},'body':JSON[_0x4ff58f(0x128)]({'peer_id':_0x914ce4})}),await this[_0x4ff58f(0x101)]();}finally{this[_0x4ff58f(0x13d)]=!0x1,this['reconcilingTarget']=null;}},'openLinkEditor'(_0x242e36){const _0x11e22b=_0x4a26d6;this[_0x11e22b(0x149)]=_0x242e36,this['linkEditDir']=_0x242e36['link']?.[_0x11e22b(0x109)]??_0x11e22b(0x11b),this[_0x11e22b(0xcb)]=_0x242e36[_0x11e22b(0xe5)]?.[_0x11e22b(0xf2)]??null,this['linkEditEnabled']=!0x1!==_0x242e36[_0x11e22b(0xe5)]?.[_0x11e22b(0x14f)];},'closeLinkEditor'(){const _0x859f1f=_0x4a26d6;this[_0x859f1f(0x149)]=null;},'toggleLinkEnv'(_0x4fc8af){const _0x568084=_0x4a26d6;if(null===this[_0x568084(0xcb)])this[_0x568084(0xcb)]=this[_0x568084(0xc8)][_0x568084(0xd3)](_0x30ceaa=>_0x30ceaa!==_0x4fc8af);else{const _0x2146ea=new Set(this['linkEditEnvs']);_0x2146ea[_0x568084(0x11a)](_0x4fc8af)?_0x2146ea[_0x568084(0xd0)](_0x4fc8af):_0x2146ea['add'](_0x4fc8af);const _0x5c9043=[..._0x2146ea];this[_0x568084(0xcb)]=_0x5c9043['length']===this[_0x568084(0xc8)][_0x568084(0x11d)]?null:_0x5c9043;}},async 'saveLink'(){const _0x5b90c6=_0x4a26d6;if(!this[_0x5b90c6(0x149)]||this[_0x5b90c6(0x14c)])return;this['savingLink']=!0x0;const _0x2f8a41=this[_0x5b90c6(0x149)];try{const _0x57ef17=await fetch(_0x5b90c6(0x105)+_0x2f8a41['lo']+'/'+_0x2f8a41['hi'],{'method':'PUT','headers':{'Content-Type':_0x5b90c6(0x102)},'body':JSON['stringify']({'direction':this[_0x5b90c6(0xe4)],'envs':this[_0x5b90c6(0xcb)],'enabled':this[_0x5b90c6(0x176)]})});if(!_0x57ef17['ok']){const _0x5300e0=await _0x57ef17[_0x5b90c6(0x10b)]();throw new Error(_0x5300e0?.['error']?.['message']||_0x5b90c6(0x135));}this['closeLinkEditor'](),await this['refreshTopology']();}catch(_0x5acfc7){alert(_0x5acfc7[_0x5b90c6(0x16f)]);}finally{this[_0x5b90c6(0x14c)]=!0x1;}},async 'deleteLink'(){const _0x7e3014=_0x4a26d6;if(!this['editingLink']||this[_0x7e3014(0x14c)])return;if(!confirm(_0x7e3014(0x115)))return;this[_0x7e3014(0x14c)]=!0x0;const _0xa4479c=this['editingLink'];try{await fetch(_0x7e3014(0x105)+_0xa4479c['lo']+'/'+_0xa4479c['hi'],{'method':_0x7e3014(0xe6)}),this['closeLinkEditor'](),await this[_0x7e3014(0x101)]();}catch(_0x541433){alert(_0x541433[_0x7e3014(0x16f)]);}finally{this[_0x7e3014(0x14c)]=!0x1;}},'deselect'(){const _0x3b9d22=_0x4a26d6;this[_0x3b9d22(0x17e)]=null,this[_0x3b9d22(0x12b)]=null,this[_0x3b9d22(0xf6)]=null,this[_0x3b9d22(0x12d)]=null,this[_0x3b9d22(0x149)]=null,_0x18a441['$dispatch']?.(_0x3b9d22(0x129),null),_0x18a441[_0x3b9d22(0x119)]?.(_0x3b9d22(0x106),null);},'pickNode'(_0x47e756){const _0xc99840=_0x4a26d6;this['selectedNodeId']=_0x47e756,this[_0xc99840(0x12b)]=null,this[_0xc99840(0x149)]=null,_0x18a441[_0xc99840(0x119)]?.(_0xc99840(0x129),_0x47e756),_0x18a441[_0xc99840(0x119)]?.(_0xc99840(0x106),null);},'pickLink'(_0xb95794){const _0x5ba91d=_0x4a26d6,_0x202625=this[_0x5ba91d(0x172)]['find'](_0x4ae165=>_0x4ae165['key']===_0xb95794)||null;if(_0x202625&&(!this[_0x5ba91d(0x17e)]||_0x202625['lo']===this[_0x5ba91d(0x17e)]||_0x202625['hi']===this[_0x5ba91d(0x17e)])){if(this[_0x5ba91d(0x12b)]===_0xb95794)return this[_0x5ba91d(0x12b)]=null,this[_0x5ba91d(0x149)]=null,void _0x18a441[_0x5ba91d(0x119)]?.(_0x5ba91d(0x106),null);this['selectedLinkKey']=_0xb95794,this[_0x5ba91d(0x17e)]||(this[_0x5ba91d(0x17e)]=_0x202625['lo'],_0x18a441[_0x5ba91d(0x119)]?.(_0x5ba91d(0x129),this[_0x5ba91d(0x17e)])),_0x18a441[_0x5ba91d(0x119)]?.('selectLink',_0xb95794);}},async 'copy'(_0x14f665){const _0x1d7641=_0x4a26d6;try{await navigator[_0x1d7641(0xcc)][_0x1d7641(0xc7)](String(_0x14f665??''));}catch(_0x562234){}},'_sPointerEventsFor'(_0xab1ab8){const _0xb0395=_0x4a26d6;return this[_0xb0395(0x17e)]&&_0xab1ab8['lo']!==this[_0xb0395(0x17e)]&&_0xab1ab8['hi']!==this[_0xb0395(0x17e)]?_0xb0395(0x147):'pointer-events:stroke;cursor:pointer';},'_sEnabledBadge':_0x1a5f43=>_0x1a5f43?_0x4a26d6(0x158):_0x4a26d6(0x12e),'_sEnabledBtn':_0x1f6184=>_0x1f6184?'border-color:var(--ok);color:var(--ok)':_0x4a26d6(0xe3),'nodeHealth'(_0xe6c4e1){const _0x4ccb51=_0x4a26d6,_0x325882=this[_0x4ccb51(0x172)][_0x4ccb51(0xd3)](_0x75de49=>_0x75de49['lo']===_0xe6c4e1||_0x75de49['hi']===_0xe6c4e1);if(!_0x325882['length'])return'ok';const _0x389e52=_0x325882['map'](_0x1bd27c=>this['_linkHealth'](_0x1bd27c));return _0x389e52['includes'](_0x4ccb51(0xc1))?_0x4ccb51(0xc1):_0x389e52[_0x4ccb51(0x10a)](_0x4ccb51(0x131))?_0x4ccb51(0xbc):_0x389e52['includes'](_0x4ccb51(0x103))?'lagging':_0x389e52[_0x4ccb51(0x10a)](_0x4ccb51(0xce))?_0x4ccb51(0xce):_0x389e52['every'](_0x26ca13=>_0x4ccb51(0x141)===_0x26ca13||'disabled'===_0x26ca13)?_0x4ccb51(0x141):'ok';},'isLinkInteractable'(_0x1d5e92){const _0x50c41d=_0x4a26d6;return!this[_0x50c41d(0x17e)]||_0x1d5e92['lo']===this[_0x50c41d(0x17e)]||_0x1d5e92['hi']===this[_0x50c41d(0x17e)];},'isActiveLink'(_0x1f7855){const _0x35db12=_0x4a26d6;return this['selectedLinkKey']===_0x1f7855[_0x35db12(0x140)]||this[_0x35db12(0xf6)]===_0x1f7855[_0x35db12(0x140)]&&this['isLinkInteractable'](_0x1f7855);},'nodeClass'(_0x26e4b9){const _0x535bd1=_0x4a26d6;let _0x2790ff='nd';const _0x7e2ad5=this[_0x535bd1(0x17e)],_0x4160ab=this[_0x535bd1(0x12d)];if(_0x7e2ad5&&_0x7e2ad5!==_0x26e4b9['id']&&(_0x2790ff+=_0x535bd1(0x168)),_0x7e2ad5===_0x26e4b9['id']&&(_0x2790ff+='\x20nd-sel'),this[_0x535bd1(0x12b)]){const _0x5bc90a=this[_0x535bd1(0x172)]['find'](_0x4d4f5e=>_0x4d4f5e[_0x535bd1(0x140)]===this[_0x535bd1(0x12b)]);!_0x5bc90a||_0x5bc90a['lo']!==_0x26e4b9['id']&&_0x5bc90a['hi']!==_0x26e4b9['id']||_0x7e2ad5===_0x26e4b9['id']||(_0x2790ff+='\x20nd-sel2');}_0x7e2ad5||_0x4160ab!==_0x26e4b9['id']||(_0x2790ff+=_0x535bd1(0x127));const _0x1d5343=this[_0x535bd1(0xc3)](_0x26e4b9['id']);return _0x535bd1(0xc1)===_0x1d5343?_0x2790ff+='\x20nd-err':'critical'===_0x1d5343?_0x2790ff+=_0x535bd1(0x112):_0x535bd1(0x183)===_0x1d5343?_0x2790ff+=_0x535bd1(0x10d):_0x535bd1(0xce)===_0x1d5343?_0x2790ff+='\x20nd-behind':_0x535bd1(0x141)===_0x1d5343&&(_0x2790ff+=_0x535bd1(0x118)),_0x2790ff;},'linkClass'(_0x16f893){const _0x9c2f77=_0x4a26d6;let _0x23ee21='ln';const _0x23ea79=this[_0x9c2f77(0x12b)]===_0x16f893[_0x9c2f77(0x140)],_0x2c5f87=this[_0x9c2f77(0xf6)]===_0x16f893[_0x9c2f77(0x140)]&&this[_0x9c2f77(0x134)](_0x16f893);switch(this[_0x9c2f77(0x134)](_0x16f893)||_0x23ea79||(_0x23ee21+=_0x9c2f77(0xd9)),_0x23ea79?_0x23ee21+='\x20ln-selected':_0x2c5f87&&(_0x23ee21+='\x20ln-hover'),this['_linkHealth'](_0x16f893)){case _0x9c2f77(0x120):_0x23ee21+=_0x9c2f77(0xf8);break;case'error':_0x23ee21+=_0x9c2f77(0xc6);break;case _0x9c2f77(0x13d):_0x23ee21+=_0x9c2f77(0x17c);break;case _0x9c2f77(0x131):_0x23ee21+=_0x9c2f77(0x121);break;case'lag-med':_0x23ee21+='\x20ln-lag-med';break;case _0x9c2f77(0xce):_0x23ee21+='\x20ln-behind-light';break;case _0x9c2f77(0x141):_0x23ee21+=_0x9c2f77(0x165);break;default:_0x23ee21+='\x20ln-ok';}return _0x23ee21;},'linkMarker'(_0x116f3e){const _0x108d90=_0x4a26d6,_0x2ad1be=_0x116f3e[_0x108d90(0xe5)]?.['direction']??_0x108d90(0x11b);return _0x108d90(0x11b)!==_0x2ad1be&&'lo_to_hi'!==_0x2ad1be?'':_0x116f3e[_0x108d90(0xe5)]&&!_0x116f3e[_0x108d90(0xe5)]['enabled']?_0x108d90(0x180):_0x108d90(0xd4)+this['_healthMarker'](this[_0x108d90(0xd7)](_0x116f3e[_0x108d90(0x15c)]))+')';},'linkStartMarker'(_0x55e932){const _0x270615=_0x4a26d6,_0x23fc32=_0x55e932[_0x270615(0xe5)]?.['direction']??_0x270615(0x11b);return _0x270615(0x11b)!==_0x23fc32&&_0x270615(0x133)!==_0x23fc32?'':_0x55e932['link']&&!_0x55e932[_0x270615(0xe5)][_0x270615(0x14f)]?'url(#arrow-rev-disabled)':_0x270615(0x177)+this[_0x270615(0x14e)](this[_0x270615(0xd7)](_0x55e932[_0x270615(0x124)]))+')';}}),'mount'(_0x3e43e2){const _0x232a89=_0x4a26d6;this[_0x232a89(0x169)]=_0x3e43e2[_0x232a89(0x17b)]['querySelector'](_0x232a89(0x15b)),this[_0x232a89(0x156)]=this[_0x232a89(0x169)]?.[_0x232a89(0xbd)](_0x232a89(0x143)),this[_0x232a89(0x169)]&&(this[_0x232a89(0x169)][_0x232a89(0x139)]['cursor']=_0x232a89(0xdc)),this[_0x232a89(0xe0)](),this['_loadPositions'](),this[_0x232a89(0x178)]=new ResizeObserver(()=>this[_0x232a89(0xbb)]()),this[_0x232a89(0x178)][_0x232a89(0xe1)](_0x3e43e2[_0x232a89(0x17b)]),this[_0x232a89(0xde)]=setInterval(()=>{const _0x37d48d=_0x232a89;this[_0x37d48d(0x117)]=Date[_0x37d48d(0x117)]();},0x3e8),this['refreshTopology']()['then'](()=>this[_0x232a89(0xbb)]()),this[_0x232a89(0x12f)]=_0x5cf059=>{const _0x5a4ef6=_0x232a89;_0x5cf059[_0x5a4ef6(0x155)](),this[_0x5a4ef6(0x136)](_0x5cf059);},this[_0x232a89(0x169)]&&this[_0x232a89(0x169)][_0x232a89(0x116)](_0x232a89(0x10c),this['_wheelCb'],{'passive':!0x1}),this['_mousedownCb']=_0x33e6f8=>this[_0x232a89(0x108)](_0x33e6f8),this['_svgEl']&&this[_0x232a89(0x169)][_0x232a89(0x116)](_0x232a89(0x132),this[_0x232a89(0x13a)]),this['_mousemoveCb']=_0x53b9db=>this['_onMousemove'](_0x53b9db),this[_0x232a89(0x17d)]=()=>this[_0x232a89(0x122)](),window['addEventListener']('mousemove',this[_0x232a89(0xf1)]),window['addEventListener'](_0x232a89(0x171),this['_mouseupCb']),this[_0x232a89(0xda)]=()=>{const _0x9397de=_0x232a89;document['hidden']||this[_0x9397de(0x101)]();},document[_0x232a89(0x116)](_0x232a89(0x16b),this[_0x232a89(0xda)]),this[_0x232a89(0x130)]&&(this[_0x232a89(0x114)]=setInterval(()=>this[_0x232a89(0x101)](),this['autoRefreshIntervalMs'])),this[_0x232a89(0x17e)]=this[_0x232a89(0xef)],_0x3e43e2[_0x232a89(0xc5)](()=>_0x3e43e2[_0x232a89(0x154)][_0x232a89(0x17a)],_0xcfc93b=>{const _0x1ae585=_0x232a89;this[_0x1ae585(0x17e)]=_0xcfc93b??null,_0xcfc93b||(this[_0x1ae585(0x12b)]=null);});},'unmount'(){const _0x433893=_0x4a26d6;this[_0x433893(0x178)]?.[_0x433893(0x13b)](),clearInterval(this[_0x433893(0xde)]),clearInterval(this[_0x433893(0x114)]),this[_0x433893(0x169)]&&(this['_svgEl'][_0x433893(0x138)](_0x433893(0x10c),this['_wheelCb']),this['_svgEl'][_0x433893(0x138)](_0x433893(0x132),this['_mousedownCb'])),window['removeEventListener'](_0x433893(0x162),this[_0x433893(0xf1)]),window['removeEventListener']('mouseup',this[_0x433893(0x17d)]),document[_0x433893(0x138)](_0x433893(0x16b),this[_0x433893(0xda)]);},'template':_0x4a26d6(0xec)};
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();}