@64mb/freelens-power 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/out/main/ai-ipc.js +34 -3
- package/out/main/ai-ipc.js.map +1 -1
- package/out/main/common/power-logs-limits.js +227 -0
- package/out/main/common/power-logs-limits.js.map +1 -0
- package/out/main/common/power-logs.js +32 -0
- package/out/main/common/power-logs.js.map +1 -0
- package/out/main/common/resource-search.js +61 -0
- package/out/main/common/resource-search.js.map +1 -0
- package/out/main/common/store/logs-preferences-store.js +45 -0
- package/out/main/common/store/logs-preferences-store.js.map +1 -0
- package/out/main/common/store/monitoring-preferences-store.js +5 -0
- package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
- package/out/main/dashboard-icon-cache.js +1 -1
- package/out/main/index.js +6 -0
- package/out/main/index.js.map +1 -1
- package/out/main/power-logs-budget.js +126 -0
- package/out/main/power-logs-budget.js.map +1 -0
- package/out/main/power-logs-child.js +86 -0
- package/out/main/power-logs-child.js.map +1 -0
- package/out/main/power-logs-database.js +179 -0
- package/out/main/power-logs-database.js.map +1 -0
- package/out/main/power-logs-ipc.js +275 -0
- package/out/main/power-logs-ipc.js.map +1 -0
- package/out/main/power-logs-query-child.js +23 -0
- package/out/main/power-logs-query-child.js.map +1 -0
- package/out/main/power-logs-query.js +127 -0
- package/out/main/power-logs-query.js.map +1 -0
- package/out/main/power-logs-worker.js +215 -0
- package/out/main/power-logs-worker.js.map +1 -0
- package/out/main/resource-search-database.js +209 -0
- package/out/main/resource-search-database.js.map +1 -0
- package/out/main/resource-search-worker.js +56 -0
- package/out/main/resource-search-worker.js.map +1 -0
- package/out/main/resource-search.js +155 -0
- package/out/main/resource-search.js.map +1 -0
- package/out/renderer/ai-logs-sql.js +27 -0
- package/out/renderer/ai-logs-sql.js.map +1 -0
- package/out/renderer/ai-message.js +48 -27
- package/out/renderer/ai-message.js.map +1 -1
- package/out/renderer/ai-terminal-context.js +50 -40
- package/out/renderer/ai-terminal-context.js.map +1 -1
- package/out/renderer/ai.js +15 -2
- package/out/renderer/ai.js.map +1 -1
- package/out/renderer/appearance.js +2 -1
- package/out/renderer/appearance.js.map +1 -1
- package/out/renderer/gateway-relationships-client.js +107 -0
- package/out/renderer/gateway-relationships-client.js.map +1 -0
- package/out/renderer/index.js +67 -29
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/power-log-json.js +29 -0
- package/out/renderer/power-log-json.js.map +1 -0
- package/out/renderer/power-logs-client.js +35 -0
- package/out/renderer/power-logs-client.js.map +1 -0
- package/out/renderer/power-logs-collector.js +316 -0
- package/out/renderer/power-logs-collector.js.map +1 -0
- package/out/renderer/power-logs-entrypoints.js +201 -0
- package/out/renderer/power-logs-entrypoints.js.map +1 -0
- package/out/renderer/power-logs-sql-row.js +52 -0
- package/out/renderer/power-logs-sql-row.js.map +1 -0
- package/out/renderer/power-logs-transport.js +122 -0
- package/out/renderer/power-logs-transport.js.map +1 -0
- package/out/renderer/power-logs.css.js +116 -0
- package/out/renderer/power-logs.css.js.map +1 -0
- package/out/renderer/power-logs.js +1352 -0
- package/out/renderer/power-logs.js.map +1 -0
- package/out/renderer/preferences/logs-preferences.js +93 -0
- package/out/renderer/preferences/logs-preferences.js.map +1 -0
- package/out/renderer/preferences/monitoring-preferences.js +10 -0
- package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +24 -10
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/resource-relationships.css.js +1 -1
- package/out/renderer/resource-relationships.css.js.map +1 -1
- package/out/renderer/resource-relationships.js +46 -8
- package/out/renderer/resource-relationships.js.map +1 -1
- package/out/renderer/resource-search-client.js +116 -0
- package/out/renderer/resource-search-client.js.map +1 -0
- package/out/renderer/resource-search-discovery.js +79 -0
- package/out/renderer/resource-search-discovery.js.map +1 -0
- package/out/renderer/resource-search-model.js +2 -1
- package/out/renderer/resource-search-model.js.map +1 -1
- package/out/renderer/resource-search-routing.js +78 -0
- package/out/renderer/resource-search-routing.js.map +1 -0
- package/out/renderer/resource-search-sync.js +199 -0
- package/out/renderer/resource-search-sync.js.map +1 -0
- package/out/renderer/resource-search.js +279 -54
- package/out/renderer/resource-search.js.map +1 -1
- package/out/renderer/src/common/gateway-relationships.js +122 -0
- package/out/renderer/src/common/gateway-relationships.js.map +1 -0
- package/out/renderer/src/common/power-log-parser.js +114 -0
- package/out/renderer/src/common/power-log-parser.js.map +1 -0
- package/out/renderer/src/common/power-logs-ai.js +56 -0
- package/out/renderer/src/common/power-logs-ai.js.map +1 -0
- package/out/renderer/src/common/power-logs-limits.js +227 -0
- package/out/renderer/src/common/power-logs-limits.js.map +1 -0
- package/out/renderer/src/common/power-logs.js +32 -0
- package/out/renderer/src/common/power-logs.js.map +1 -0
- package/out/renderer/src/common/resource-relationships.js +8 -0
- package/out/renderer/src/common/resource-relationships.js.map +1 -1
- package/out/renderer/src/common/resource-search.js +6 -0
- package/out/renderer/src/common/resource-search.js.map +1 -0
- package/out/renderer/src/common/store/logs-preferences-store.js +45 -0
- package/out/renderer/src/common/store/logs-preferences-store.js.map +1 -0
- package/out/renderer/src/common/store/monitoring-preferences-store.js +5 -0
- package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
- package/package.json +8 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power-logs.js","names":[],"sources":["../../src/renderer/power-logs.tsx"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport {\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { formatDateTime } from \"../common/date-time\";\nimport {\n POWER_LOGS_LIMITS as L,\n type LogCapture,\n type LogLevel,\n type LogQueryResult,\n type LogRecord,\n type LogSource,\n type LogTarget,\n} from \"../common/power-logs\";\nimport { powerLogLineEvidence, powerLogQueryEvidence } from \"../common/power-logs-ai\";\nimport { applyPowerLogsLimits, normalizePowerLogsLimits } from \"../common/power-logs-limits\";\nimport { LogsPreferencesStore } from \"../common/store/logs-preferences-store\";\nimport { explainDiagnosticFinding } from \"./ai-diagnostic-handoff\";\nimport { DiagnosticExplainButton } from \"./diagnostic-explain-button\";\nimport { LogJson } from \"./power-log-json\";\nimport { powerLogsStyles } from \"./power-logs.css\";\nimport { createPowerLogsClient } from \"./power-logs-client\";\nimport { collectHistoricalLogs, type LiveLogCoverage, resolveLogSources, startLiveLogs } from \"./power-logs-collector\";\nimport { openPowerLogs, parsePowerLogsTarget } from \"./power-logs-entrypoints\";\nimport { sqlRowDetails } from \"./power-logs-sql-row\";\nimport { createPowerLogsTransport } from \"./power-logs-transport\";\nimport { searchContextId } from \"./resource-search-client\";\n\nconst Icon = (props: { material: string; size?: number }) => (\n <span aria-hidden=\"true\" style={{ display: \"inline-flex\" }}>\n <Renderer.Component.Icon {...props} />\n </span>\n);\nconst sourceKey = (r: Pick<LogRecord, \"pod\" | \"container\" | \"previous\">) =>\n `${r.pod} / ${r.container}${r.previous ? \" (previous)\" : \"\"}`;\nconst levels: LogLevel[] = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", \"unknown\"];\nconst examples = [\n [\"Recent\", \"SELECT message, level, container, pod, timestamp FROM logs ORDER BY timestamp DESC NULLS LAST LIMIT 200\"],\n [\n \"Errors\",\n \"SELECT pod, container, count(*) AS errors FROM logs WHERE level IN ('error','fatal') GROUP BY pod, container ORDER BY errors DESC\",\n ],\n [\n \"Timeline\",\n \"SELECT strftime('%Y-%m-%d %H:%M', timestamp / 1000, 'unixepoch') AS minute, level, count(*) AS lines FROM logs GROUP BY minute, level ORDER BY minute\",\n ],\n [\n \"JSON\",\n \"SELECT pod, json_extract(fieldsJson, '$.message') AS message FROM logs WHERE fieldsJson IS NOT NULL LIMIT 100\",\n ],\n] as const;\nconst sqlColumnWidth = (column: string) =>\n column === \"message\" || column === \"fieldsJson\" ? 360 : column === \"level\" ? 90 : 200;\ntype ViewRecord = LogRecord & { key: number; bytes: number };\n\nfunction initialTarget(): LogTarget | undefined {\n try {\n return parsePowerLogsTarget(JSON.parse(new URLSearchParams(window.location.search).get(\"target\") ?? \"null\"));\n } catch {\n return;\n }\n}\nfunction initialSource(container: unknown = new URLSearchParams(window.location.search).get(\"container\")): string {\n return typeof container === \"string\" && /^[a-z0-9](?:[-a-z0-9]*[a-z0-9])?$/.test(container) && container.length <= 63\n ? `container:${container}`\n : \"\";\n}\n\nfunction LogSelect({\n label,\n value,\n options,\n onChange,\n disabled = false,\n renderOption,\n onKeyDown,\n}: {\n label: string;\n value: string;\n options: { value: string; label: string }[];\n onChange(value: string): void;\n disabled?: boolean;\n onKeyDown?: (event: ReactKeyboardEvent) => void;\n renderOption?: (option: { value: string; label: string }, context: \"menu\" | \"value\") => ReactNode;\n}) {\n return (\n <span className=\"power-logs-select\" data-source-select={label === \"Container source\" || undefined}>\n <Renderer.Component.Select\n aria-label={label}\n value={value}\n options={options}\n formatOptionLabel={(option, meta) =>\n renderOption ? (\n renderOption(option, meta.context)\n ) : label === \"Log level\" && option.value ? (\n <span className=\"power-logs-level-label\" data-level={option.value}>\n {option.label}\n </span>\n ) : (\n option.label\n )\n }\n isDisabled={disabled}\n onKeyDown={onKeyDown}\n tabSelectsValue={false}\n isClearable={false}\n menuPosition=\"fixed\"\n menuPortalTarget={document.body}\n styles={{\n menu: (base) => (label === \"Container source\" ? { ...base, width: \"100%\", maxWidth: \"100%\" } : base),\n menuList: (base) => (label === \"Container source\" ? { ...base, width: \"100%\", maxWidth: \"100%\" } : base),\n option: (base) => (label === \"Container source\" ? { ...base, whiteSpace: \"normal\" } : base),\n menuPortal: (base) => {\n if (label !== \"Container source\" && label !== \"Capture snapshot\") return { ...base, zIndex: 10000 };\n const width = Math.min(label === \"Capture snapshot\" ? 620 : 560, window.innerWidth - 32);\n return {\n ...base,\n zIndex: 10000,\n width,\n left: Math.max(\n 16,\n Math.min(typeof base.left === \"number\" ? base.left : 16, window.innerWidth - width - 16),\n ),\n };\n },\n }}\n onChange={(option) => {\n if (option) onChange(option.value);\n }}\n />\n </span>\n );\n}\n\nconst SourcePicker = observer(() => {\n const stores = [\n Renderer.K8sApi.podsStore,\n Renderer.K8sApi.deploymentStore,\n Renderer.K8sApi.daemonSetStore,\n Renderer.K8sApi.statefulSetStore,\n Renderer.K8sApi.replicaSetStore,\n Renderer.K8sApi.jobStore,\n Renderer.K8sApi.cronJobStore,\n ];\n const targets = stores.flatMap((store) =>\n store.getItems().flatMap((object) => {\n const target = parsePowerLogsTarget({ kind: object.kind, ...object.metadata });\n return target ? [target] : [];\n }),\n );\n const [value, setValue] = useState(\"\");\n const sorted = [...targets].sort((a, b) =>\n `${a.namespace}/${a.kind}/${a.name}`.localeCompare(`${b.namespace}/${b.kind}/${b.name}`),\n );\n return (\n <div className=\"power-logs-source\">\n <span>Resource</span>\n <LogSelect\n label=\"Resource\"\n value={value}\n onChange={setValue}\n options={[\n { value: \"\", label: \"Choose a loaded pod or workload\" },\n ...sorted.map((target) => ({\n value: target.uid,\n label: `${target.namespace} / ${target.kind} / ${target.name}`,\n })),\n ]}\n />\n <button\n type=\"button\"\n disabled={!targets.some((target) => target.uid === value)}\n onClick={() => {\n const target = targets.find((t) => t.uid === value);\n if (target) openPowerLogs(target);\n }}\n >\n <Icon material=\"subject\" size={16} /> Open logs\n </button>\n </div>\n );\n});\n\nfunction LogRows({\n records,\n selected,\n onSelect,\n follow,\n setFollow,\n compact,\n}: {\n records: ViewRecord[];\n selected?: number;\n onSelect(record: ViewRecord): void;\n follow: boolean;\n setFollow(value: boolean): void;\n compact: boolean;\n}) {\n const viewport = useRef<HTMLDivElement>(null);\n const [top, setTop] = useState(0);\n const [height, setHeight] = useState(400);\n useEffect(() => {\n const element = viewport.current;\n if (!element) return;\n const resize = new ResizeObserver(() => setHeight(element.clientHeight));\n resize.observe(element);\n return () => resize.disconnect();\n }, []);\n useLayoutEffect(() => {\n if (follow && viewport.current) {\n viewport.current.scrollTop = viewport.current.scrollHeight;\n setTop(viewport.current.scrollTop);\n }\n }, [records, follow, compact]);\n const rowHeight = compact ? 24 : 34;\n const start = Math.max(0, Math.floor(top / rowHeight) - 5);\n const visible = records.slice(start, start + Math.ceil(height / rowHeight) + 10);\n return (\n <div className=\"power-logs-viewer\">\n <div\n className=\"power-logs-stream\"\n ref={viewport}\n aria-label=\"Log lines\"\n onScroll={(event) => {\n const el = event.currentTarget;\n setTop(el.scrollTop);\n if (el.scrollHeight - el.scrollTop - el.clientHeight > 60) setFollow(false);\n }}\n >\n {records.length === 0 ? (\n <div className=\"power-logs-empty\">No matching log lines</div>\n ) : (\n <div style={{ height: records.length * rowHeight, position: \"relative\" }}>\n {visible.map((record, i) => (\n <button\n type=\"button\"\n className=\"power-log-row\"\n data-level={record.level}\n aria-pressed={selected === record.key}\n style={{ top: (start + i) * rowHeight, height: rowHeight }}\n key={record.key}\n onClick={() => onSelect(record)}\n >\n <span title={record.timestamp !== null ? formatDateTime(record.timestamp) : \"Timestamp unavailable\"}>\n {record.timestamp !== null ? formatDateTime(record.timestamp).slice(-8) : \"—\"}\n </span>\n <span className=\"power-log-level\">{record.level}</span>\n <span className=\"power-log-origin\" title={sourceKey(record)}>\n {record.container}\n {record.previous ? \" (previous)\" : \"\"} · {record.pod}\n </span>\n <span>{record.message}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction LogDetails({ record, jsonColumn, onClose }: { record: LogRecord; jsonColumn?: string; onClose: () => void }) {\n const structuredFields = useMemo(() => {\n if (!record?.fieldsJson) return \"\";\n try {\n return JSON.stringify(JSON.parse(record.fieldsJson), null, 2);\n } catch {\n return record.fieldsJson;\n }\n }, [record?.fieldsJson]);\n return (\n <aside className=\"power-logs-detail\" aria-label=\"Log line details\">\n <header>\n <strong>Line details</strong>\n <button\n className=\"power-logs-detail-close\"\n aria-label=\"Close line details\"\n title=\"Close line details\"\n onClick={onClose}\n >\n <Icon material=\"close\" size={16} />\n </button>\n </header>\n <p className=\"power-logs-muted\">{[record.pod && sourceKey(record), record.level].filter(Boolean).join(\" · \")}</p>\n {record.message && <pre>{record.message}</pre>}\n {record.fieldsJson && (\n <>\n <strong>{jsonColumn ? `Structured fields · ${jsonColumn}` : \"Structured fields\"}</strong>\n <LogJson text={structuredFields} />\n </>\n )}\n </aside>\n );\n}\n\nfunction Workspace({ clusterId, contextId }: { clusterId: string; contextId: string }) {\n const client = useMemo(() => createPowerLogsClient({ clusterId, contextId }), [clusterId, contextId]);\n const [target, setTarget] = useState(initialTarget);\n const [records, setRecords] = useState<ViewRecord[]>([]);\n const [sources, setSources] = useState<LogSource[]>([]);\n const [notes, setNotes] = useState<string[]>([]);\n const [status, setStatus] = useState(\"Choose a resource to read its logs\");\n const [error, setError] = useState(\"\");\n const [tab, setTab] = useState<\"live\" | \"captures\">(\"live\");\n const [text, setText] = useState(\"\");\n const [level, setLevel] = useState(\"\");\n const [source, setSource] = useState(initialSource);\n const preferences = LogsPreferencesStore.getInstanceOrCreate<LogsPreferencesStore>();\n const limits = normalizePowerLogsLimits(preferences.limits);\n useEffect(() => {\n applyPowerLogsLimits(preferences.limits);\n }, [preferences.limits]);\n const [compact, setCompact] = useState(preferences.compactRows === true);\n const [selected, setSelected] = useState<ViewRecord>();\n const [selectedSqlRow, setSelectedSqlRow] = useState<\n ReturnType<typeof sqlRowDetails> & { row: LogQueryResult[\"rows\"][number] }\n >();\n const [liveCoverage, setLiveCoverage] = useState<LiveLogCoverage>();\n const [live, setLive] = useState(false);\n const [follow, setFollow] = useState(true);\n const [busy, setBusy] = useState(false);\n const [captures, setCaptures] = useState<LogCapture[]>([]);\n const [captureId, setCaptureId] = useState(\"\");\n const captureSelection = useRef(captureId);\n captureSelection.current = captureId;\n const deleting = useRef(new Set<string>());\n const [deletingCount, setDeletingCount] = useState(0);\n const [capturing, setCapturing] = useState<LogCapture>();\n const [capturePending, setCapturePending] = useState(false);\n const [captureMinutes, setCaptureMinutes] = useState(15);\n const [previous, setPrevious] = useState(false);\n const [sql, setSql] = useState<string>(examples[0][1]);\n const [result, setResult] = useState<LogQueryResult>();\n const [resultEvidence, setResultEvidence] = useState<{ capture: LogCapture; sql: string }>();\n const [resultPage, setResultPage] = useState(0);\n const [queryId, setQueryId] = useState(\"\");\n const captureOptions = useRef<HTMLDetailsElement>(null);\n useEffect(() => {\n const outside = (event: PointerEvent) => {\n if (\n !captureOptions.current?.contains(event.target as Node) &&\n !(event.target as Element)?.closest?.(\".Select__menu\")\n ) {\n if (captureOptions.current) captureOptions.current.open = false;\n }\n };\n const escape = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || event.defaultPrevented || (event.target as Element)?.closest?.(\".Select\")) return;\n if (captureOptions.current?.open) captureOptions.current.open = false;\n else {\n setSelected(undefined);\n setSelectedSqlRow(undefined);\n }\n };\n window.addEventListener(\"pointerdown\", outside);\n window.addEventListener(\"keydown\", escape);\n return () => {\n window.removeEventListener(\"pointerdown\", outside);\n window.removeEventListener(\"keydown\", escape);\n };\n }, []);\n const historyController = useRef<AbortController>();\n const liveController = useRef<AbortController>();\n const captureController = useRef<AbortController>();\n const queryRef = useRef(\"\");\n const epoch = useRef(0);\n const alive = useRef(true);\n const sequence = useRef(0);\n const recordsRef = useRef(records);\n recordsRef.current = records;\n const pending = useRef<LogRecord[]>([]);\n const flushTimer = useRef<ReturnType<typeof setTimeout>>();\n const refreshCaptures = () =>\n client\n .list()\n .then((value) => {\n if (alive.current) setCaptures(value);\n })\n .catch(() => {\n if (alive.current) setError(\"Temporary captures are unavailable\");\n });\n const stopLive = () => {\n liveController.current?.abort();\n liveController.current = undefined;\n setLive(false);\n };\n const flush = () => {\n clearTimeout(flushTimer.current);\n flushTimer.current = undefined;\n const batch = pending.current;\n pending.current = [];\n if (!batch.length || !alive.current) return;\n const next = batch.map((record) => ({\n ...record,\n key: ++sequence.current,\n bytes: Buffer.byteLength(JSON.stringify(record)),\n }));\n setRecords((current) => {\n const combined = [...current, ...next];\n let bytes = combined.reduce((sum, r) => sum + r.bytes, 0);\n let start = 0;\n while (combined.length - start > L.liveRows || bytes > L.liveBytes) bytes -= combined[start++].bytes;\n return combined.slice(start).sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0) || a.key - b.key);\n });\n };\n const appendView = (batch: LogRecord[]) => {\n if (!alive.current) return;\n pending.current.push(...batch);\n if (pending.current.length > 1000) flush();\n else flushTimer.current ??= setTimeout(flush, 80);\n };\n useEffect(() => {\n alive.current = true;\n const onTarget = (event: Event) => {\n const next = parsePowerLogsTarget((event as CustomEvent).detail);\n if (next) {\n if (queryRef.current) {\n void client.cancel(queryRef.current).catch(() => {});\n queryRef.current = \"\";\n setQueryId(\"\");\n }\n setSource(initialSource((event as CustomEvent).detail.container));\n setTarget(next);\n }\n };\n window.addEventListener(\"power-logs-target\", onTarget);\n void refreshCaptures();\n const timer = setInterval(() => void refreshCaptures(), 30000);\n return () => {\n alive.current = false;\n epoch.current++;\n clearInterval(timer);\n clearTimeout(flushTimer.current);\n historyController.current?.abort();\n liveController.current?.abort();\n captureController.current?.abort();\n if (queryRef.current) void client.cancel(queryRef.current).catch(() => {});\n window.removeEventListener(\"power-logs-target\", onTarget);\n };\n }, [client]);\n const readHistory = async () => {\n if (!target) return;\n const currentEpoch = ++epoch.current;\n historyController.current?.abort();\n stopLive();\n const controller = new AbortController();\n historyController.current = controller;\n clearTimeout(flushTimer.current);\n flushTimer.current = undefined;\n pending.current = [];\n setBusy(true);\n setRecords([]);\n setSelected(undefined);\n setError(\"\");\n setNotes([]);\n setStatus(\"Discovering owned containers…\");\n try {\n const transport = createPowerLogsTransport(clusterId);\n const discovery = await resolveLogSources(target, transport, controller.signal);\n if (controller.signal.aborted || currentEpoch !== epoch.current) return;\n setSources(discovery.sources);\n setNotes(discovery.notes);\n setStatus(`Reading ${discovery.sources.length} container sources…`);\n const history = await collectHistoricalLogs(discovery.sources, transport, {\n signal: controller.signal,\n tailLines: L.historyLines,\n limitBytes: L.historyBytes,\n onRecords: (batch) => {\n if (currentEpoch === epoch.current) appendView(batch);\n },\n });\n if (controller.signal.aborted || currentEpoch !== epoch.current) return;\n flush();\n setNotes([...new Set([...discovery.notes, ...history.notes])]);\n setStatus(\n `${discovery.sources.length} sources · last ${limits.historyLines.toLocaleString()} lines per container, up to ${limits.historyBytes / 1048576} MiB each`,\n );\n } catch {\n if (alive.current && currentEpoch === epoch.current)\n setError(\n controller.signal.aborted\n ? \"Log loading stopped\"\n : \"Could not read this resource's logs. Check permissions and whether it still exists.\",\n );\n } finally {\n if (alive.current && currentEpoch === epoch.current) setBusy(false);\n }\n };\n useEffect(() => {\n setText(\"\");\n setSources([]);\n setTab(\"live\");\n void readHistory();\n }, [target?.uid]);\n const toggleLive = () => {\n if (live) {\n stopLive();\n return;\n }\n setLive(true);\n };\n const sourceIdentity = sources.map((item) => `${item.podUid}/${item.container}`).join(\";\");\n useEffect(() => {\n if (!live || !sources.length) return;\n const controller = new AbortController();\n liveController.current = controller;\n const collector = startLiveLogs(sources, createPowerLogsTransport(clusterId), {\n signal: controller.signal,\n tailLines: L.historyLines,\n initialRecords: recordsRef.current,\n onRecords: appendView,\n onCoverage: (coverage) => {\n if (alive.current && liveController.current === controller)\n setLiveCoverage({ ...coverage, notes: [...coverage.notes] });\n },\n });\n setLiveCoverage({ ...collector.coverage });\n void collector.done.finally(() => {\n if (alive.current && !controller.signal.aborted && liveController.current === controller) {\n liveController.current = undefined;\n setLive(false);\n }\n });\n return () => {\n controller.abort();\n if (liveController.current === controller) liveController.current = undefined;\n };\n }, [live, sourceIdentity]);\n useEffect(() => {\n if (!live || !target) return;\n const controller = new AbortController();\n const startingEpoch = epoch.current;\n let refreshing = false;\n const timer = setInterval(() => {\n if (refreshing) return;\n refreshing = true;\n void resolveLogSources(target, createPowerLogsTransport(clusterId), controller.signal)\n .then((discovery) => {\n if (controller.signal.aborted || epoch.current !== startingEpoch) return;\n setSources(discovery.sources);\n setNotes(discovery.notes);\n setStatus(`${discovery.sources.length} sources · ownership inventory refreshed`);\n })\n .catch(() => {\n if (!controller.signal.aborted && alive.current && epoch.current === startingEpoch) {\n stopLive();\n setNotes((current) => [\n ...new Set([\n ...current,\n \"Workload inventory changed or became unavailable. Refresh before following logs again.\",\n ]),\n ]);\n }\n })\n .finally(() => {\n refreshing = false;\n });\n }, 30000);\n return () => {\n clearInterval(timer);\n controller.abort();\n };\n }, [live, target?.uid]);\n const capture = async () => {\n if (!target || captureController.current || queryRef.current) return;\n setCapturePending(true);\n const controller = new AbortController();\n captureController.current = controller;\n let current: LogCapture | undefined;\n let partial = false;\n let captureNotes: string[] = [];\n setError(\"\");\n stopLive();\n try {\n current = await client.create(target);\n setCapturing(current);\n const transport = createPowerLogsTransport(clusterId);\n const discovery = await resolveLogSources(target, transport, controller.signal);\n captureNotes = discovery.notes;\n partial = discovery.partial;\n const captureSources = previous\n ? [...discovery.sources, ...discovery.sources.map((item) => ({ ...item, previous: true }))]\n : discovery.sources;\n const boundary = current.createdAt;\n const history = await collectHistoricalLogs(captureSources, transport, {\n signal: controller.signal,\n tailLines: L.captureSourceLines,\n sinceTime: new Date(boundary - captureMinutes * 60000).toISOString(),\n limitBytes: L.captureSourceBytes,\n onRecords: async (batch) => {\n if (batch.some((record) => record.timestamp === null)) {\n partial = true;\n captureNotes.push(\"Some records have no timestamp and their capture window cannot be verified\");\n }\n batch = batch.filter(\n (record) =>\n record.timestamp === null ||\n (record.timestamp <= boundary && record.timestamp >= boundary - captureMinutes * 60000),\n );\n for (let offset = 0; offset < batch.length; ) {\n const chunk: LogRecord[] = [];\n let bytes = 2;\n while (offset < batch.length && chunk.length < L.batchRows) {\n const record = batch[offset];\n const size = Buffer.byteLength(JSON.stringify(record)) + 1;\n if (chunk.length && bytes + size > L.batchBytes) break;\n chunk.push(record);\n bytes += size;\n offset++;\n }\n if (controller.signal.aborted) throw new Error(\"Capture stopped\");\n try {\n current = await client.append(current!.id, chunk);\n if (alive.current) setCapturing(current);\n } catch {\n controller.abort();\n throw new Error(\"Capture reached its storage limit or became unavailable\");\n }\n }\n },\n });\n partial ||= history.partial;\n captureNotes.push(...history.notes);\n } catch {\n partial = true;\n captureNotes.push(\"Collection stopped or a source was unavailable; this snapshot may be incomplete\");\n } finally {\n if (current) {\n try {\n const saved = await client.finish(\n current.id,\n partial || controller.signal.aborted,\n [...new Set(captureNotes)].slice(0, 20),\n );\n if (alive.current) {\n setCaptureId(saved.id);\n setCaptures((items) => [saved, ...items.filter((item) => item.id !== saved.id)]);\n setTab(\"captures\");\n setSql(examples[0][1]);\n void runQuery(saved, examples[0][1]);\n }\n } catch {\n if (alive.current) setError(\"The temporary capture could not be finalized\");\n }\n } else if (alive.current)\n setError(\"Could not create a capture. Delete an old snapshot or check the log service.\");\n if (alive.current) {\n setCapturing(undefined);\n setCapturePending(false);\n void refreshCaptures();\n }\n captureController.current = undefined;\n }\n };\n const runQuery = async (selectedCapture?: LogCapture, query = sql) => {\n if (queryRef.current || (!selectedCapture && captureController.current)) return;\n const captured = selectedCapture ?? captures.find((item) => item.id === captureId);\n if (!captured || captured.state === \"collecting\" || deleting.current.has(captured.id)) return;\n const id = randomUUID();\n queryRef.current = id;\n setQueryId(id);\n setError(\"\");\n setResult(undefined);\n setSelectedSqlRow(undefined);\n setResultEvidence({ capture: captured, sql: query });\n setResultPage(0);\n try {\n const value = await client.query(captured.id, id, query);\n if (alive.current && queryRef.current === id) {\n if (value.error) setError(value.error);\n else setResult(value);\n }\n } catch {\n if (alive.current && queryRef.current === id)\n setError(\n \"Query stopped or failed. Use one read-only SELECT or EXPLAIN; external files, networking and extensions are disabled.\",\n );\n } finally {\n if (queryRef.current === id) {\n if (alive.current) setQueryId(\"\");\n queryRef.current = \"\";\n }\n }\n };\n const filtered = useMemo(\n () =>\n records.filter(\n (record) =>\n (!text || record.message.toLocaleLowerCase().includes(text.toLocaleLowerCase())) &&\n (!level || record.level === level) &&\n (!source ||\n (source.startsWith(\"container:\") ? record.container === source.slice(10) : sourceKey(record) === source)),\n ),\n [records, text, level, source],\n );\n const chosenCapture = captures.find((item) => item.id === captureId);\n const collectionNotes = tab === \"live\" ? [...new Set([...notes, ...(live ? (liveCoverage?.notes ?? []) : [])])] : [];\n useEffect(() => {\n window.dispatchEvent(new CustomEvent(\"power-logs-workspace-change\", { detail: { active: true } }));\n return () => {\n window.dispatchEvent(new CustomEvent(\"power-logs-workspace-change\", { detail: { active: false } }));\n };\n }, []);\n useEffect(() => {\n const insert = (event: Event) => {\n const sql = (event as CustomEvent<{ sql?: unknown }>).detail?.sql;\n if (typeof sql !== \"string\" || !sql.trim() || sql.length > 65536) return;\n setTab(\"captures\");\n setSql(sql);\n setSelectedSqlRow(undefined);\n if (!captureId) {\n const latest = captures.find((item) => item.state !== \"collecting\" && item.target.uid === target?.uid);\n if (latest) setCaptureId(latest.id);\n }\n requestAnimationFrame(() => document.getElementById(\"power-logs-sql\")?.focus());\n };\n window.addEventListener(\"power-logs-sql-draft\", insert);\n return () => window.removeEventListener(\"power-logs-sql-draft\", insert);\n }, [captureId, captures, target?.uid]);\n const attachAi = () => {\n const resource =\n tab === \"captures\"\n ? result && resultEvidence\n ? resultEvidence.capture.target\n : (chosenCapture?.target ?? target)\n : target;\n const summary =\n tab === \"captures\" && result && resultEvidence\n ? powerLogQueryEvidence(\n resultEvidence.capture,\n resultEvidence.sql,\n selectedSqlRow ? { ...result, rows: [selectedSqlRow.row], truncated: false } : result,\n )\n : tab === \"live\" && selected\n ? powerLogLineEvidence(resource, selected)\n : JSON.stringify({\n target: resource,\n ...(tab === \"captures\"\n ? { sql, rows: [], state: \"Draft query, not executed\" }\n : { status, sources: sources.length }),\n });\n if (\n !explainDiagnosticFinding({\n clusterId,\n title: tab === \"captures\" ? (selectedSqlRow ? \"SQL row\" : \"SQL query\") : selected ? \"Log line\" : \"Power Logs\",\n summary: summary.slice(0, 6000),\n ...(resource ? { resource: { kind: resource.kind, name: resource.name, namespace: resource.namespace } } : {}),\n })\n )\n window.dispatchEvent(new Event(\"power-ai-open-only\"));\n };\n const deleteCapture = async (id: string) => {\n if (deleting.current.has(id) || queryRef.current || captureController.current) return;\n deleting.current.add(id);\n setDeletingCount(deleting.current.size);\n try {\n await client.delete(id);\n if (id === captureSelection.current) {\n setCaptureId(\"\");\n setResult(undefined);\n setResultEvidence(undefined);\n setSelectedSqlRow(undefined);\n }\n await refreshCaptures();\n } catch {\n setError(\"Could not delete capture\");\n } finally {\n deleting.current.delete(id);\n if (alive.current) setDeletingCount(deleting.current.size);\n }\n };\n const native = () => {\n const first = sources[0];\n const pod = Renderer.K8sApi.podsStore\n .getItems()\n .find((item) =>\n target?.kind === \"Pod\" ? item.metadata.uid === target.uid : item.metadata.uid === first?.podUid,\n );\n const requested = source.startsWith(\"container:\")\n ? source.slice(10)\n : sources.find((item) => sourceKey(item) === source)?.container;\n const defaultContainer = pod?.metadata.annotations?.[\"kubectl.kubernetes.io/default-container\"];\n const container =\n pod?.getAllContainers().find((item) => item.name === (requested ?? defaultContainer)) ??\n pod?.getAllContainers()[0];\n if (pod && container)\n Renderer.Component.logTabStore.createPodTab({ selectedPod: pod, selectedContainer: container });\n else setError(\"Open the Pod in the native resource view to use its Logs action\");\n };\n return (\n <div className=\"power-logs\" data-testid=\"power-logs-page\" data-compact={compact || undefined}>\n <style>{powerLogsStyles}</style>\n <header>\n <h1 className=\"power-logs-page-title\">Power Logs</h1>\n <div\n className=\"power-logs-tabs\"\n role=\"tablist\"\n aria-label=\"Log workspace\"\n onKeyDown={(event) => {\n if (![\"ArrowLeft\", \"ArrowRight\", \"Home\", \"End\"].includes(event.key)) return;\n const tabs = [...event.currentTarget.querySelectorAll<HTMLButtonElement>(\"[role=tab]\")];\n const index = tabs.indexOf(document.activeElement as HTMLButtonElement);\n if (index < 0) return;\n event.preventDefault();\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? tabs.length - 1\n : (index + (event.key === \"ArrowRight\" ? 1 : -1) + tabs.length) % tabs.length;\n tabs[next]?.focus();\n tabs[next]?.click();\n }}\n >\n <button role=\"tab\" aria-selected={tab === \"live\"} onClick={() => setTab(\"live\")}>\n <Icon material=\"subject\" size={16} /> Live view\n </button>\n <button\n role=\"tab\"\n aria-selected={tab === \"captures\"}\n onClick={() => {\n setTab(\"captures\");\n const latest = captures.find(\n (item) => item.state !== \"collecting\" && (!target || item.target.uid === target.uid),\n );\n if (!captureId && latest && !capturePending) {\n setCaptureId(latest.id);\n setSql(examples[0][1]);\n void runQuery(latest, examples[0][1]);\n }\n void refreshCaptures();\n }}\n >\n <Icon material=\"code\" size={16} /> SQL\n </button>\n </div>\n\n <div className=\"power-logs-actions\">\n <div className=\"power-logs-toolbar power-logs-capture\">\n <details ref={captureOptions} className=\"power-logs-options\">\n <summary title={`Capture window: ${captureMinutes} minutes`}>\n <Icon material=\"tune\" size={16} /> Options\n </summary>\n <div>\n {\" \"}\n <label>\n Capture window\n <LogSelect\n label=\"Capture window\"\n value={String(captureMinutes)}\n onChange={(value) => setCaptureMinutes(Number(value))}\n options={[\n { value: \"5\", label: \"5 minutes\" },\n { value: \"15\", label: \"15 minutes\" },\n { value: \"60\", label: \"1 hour\" },\n ]}\n />\n </label>\n <Renderer.Component.Switch checked={previous} onChange={setPrevious}>\n Include previous containers\n </Renderer.Component.Switch>\n <Renderer.Component.Switch\n checked={compact}\n onChange={(value) => {\n setCompact(value);\n preferences.compactRows = value;\n }}\n >\n Compact density\n </Renderer.Component.Switch>\n </div>\n </details>\n {tab === \"captures\" && (\n <button\n type=\"button\"\n disabled={!target || capturePending || busy || !!queryId || deletingCount > 0}\n onClick={() => void capture()}\n >\n <Icon material=\"save_alt\" size={16} /> Capture logs\n </button>\n )}\n {capturePending && (\n <>\n <span role=\"status\" className=\"power-logs-muted\">\n {capturing\n ? `${capturing.rows.toLocaleString()} lines · ${(capturing.bytes / 1048576).toFixed(1)} MiB`\n : \"Preparing capture…\"}\n </span>\n <button type=\"button\" onClick={() => captureController.current?.abort()}>\n <Icon material=\"stop\" size={16} /> Stop & keep partial\n </button>\n </>\n )}\n </div>\n\n <DiagnosticExplainButton aria-label=\"Open AI assistant\" title=\"Open AI assistant\" onClick={attachAi}>\n <Icon material=\"chat_bubble_outline\" size={16} /> AI\n </DiagnosticExplainButton>\n {tab === \"live\" && (\n <button type=\"button\" disabled={!target || busy} onClick={() => void readHistory()}>\n <Icon material=\"refresh\" size={16} /> Refresh\n </button>\n )}\n {target?.kind === \"Pod\" && (\n <button type=\"button\" aria-label=\"Native logs\" title=\"Native logs\" onClick={native}>\n <Renderer.Component.Icon material=\"open_in_new\" size={16} tooltip=\"Native logs\" tooltipOverrideDisabled />\n </button>\n )}\n </div>\n </header>\n {target ? (\n <div\n className=\"power-logs-target power-logs-muted\"\n title={`${target.kind} / ${target.name} · ${target.namespace} · UID ${target.uid}`}\n >\n <strong>\n {target.kind} / {target.name}\n </strong>{\" \"}\n · {target.namespace}\n </div>\n ) : (\n <SourcePicker />\n )}\n {error && (\n <div role=\"alert\" className=\"power-logs-notice power-logs-error\">\n {error}\n </div>\n )}\n {tab === \"live\" ? (\n <>\n <div className=\"power-logs-filters\">\n <input\n aria-label=\"Search log messages\"\n placeholder=\"Search messages…\"\n value={text}\n maxLength={300}\n onChange={(event) => setText(event.target.value)}\n />\n <LogSelect\n label=\"Log level\"\n value={level}\n onChange={setLevel}\n options={[\n { value: \"\", label: \"All levels\" },\n ...levels.map((value) => ({ value, label: value.toUpperCase() })),\n ]}\n />\n <LogSelect\n label=\"Container source\"\n renderOption={(option, context) => {\n if (context !== \"menu\") return <span title={option.label}>{option.label}</span>;\n const item = sources.find((item) => sourceKey(item) === option.value);\n return (\n <span className=\"power-logs-source-option\" title={option.label}>\n <Icon material={item ? \"view_in_ar\" : \"layers\"} size={16} />\n <span className=\"power-logs-option-text\">\n <strong>{item ? item.pod : option.value ? \"All pods\" : option.label}</strong>\n <small>\n {option.value\n ? `Container · ${item?.container ?? option.value.slice(10)}`\n : \"Every pod and container\"}\n {item?.previous ? \" · Previous\" : \"\"}\n </small>\n </span>\n <span className=\"power-logs-source-check\" aria-hidden=\"true\">\n {source === option.value && <Icon material=\"check\" size={16} />}\n </span>\n </span>\n );\n }}\n value={source}\n onChange={setSource}\n options={[\n { value: \"\", label: `All sources (${sources.length})` },\n ...[...new Set(sources.map((item) => item.container))].map((container) => ({\n value: `container:${container}`,\n label: `All pods / ${container}`,\n })),\n ...[...new Set(sources.map(sourceKey))].map((value) => ({ value, label: value })),\n ]}\n />\n <button\n type=\"button\"\n disabled={!sources.length || busy || capturePending}\n aria-pressed={live}\n onClick={toggleLive}\n >\n <Icon material={live ? \"pause\" : \"play_arrow\"} size={16} /> {live ? \"Pause\" : \"Live\"}\n </button>\n <button type=\"button\" aria-pressed={follow} onClick={() => setFollow(!follow)}>\n <Icon material=\"vertical_align_bottom\" size={16} /> Follow tail\n </button>\n {busy && (\n <button onClick={() => historyController.current?.abort()} type=\"button\">\n <Icon material=\"stop\" size={16} /> Stop loading\n </button>\n )}\n </div>\n <div\n className=\"power-logs-muted power-logs-status\"\n role=\"status\"\n title={`${status} · Viewer retains up to ${limits.liveRows.toLocaleString()} lines / ${limits.liveBytes / 1048576} MiB`}\n >\n <span>{filtered.length.toLocaleString()} matching lines</span> · {status}\n {liveCoverage && live ? ` · ${liveCoverage.active}/${liveCoverage.total} active sources` : \"\"} · Viewer\n retains up to {limits.liveRows.toLocaleString()} lines / {limits.liveBytes / 1048576} MiB\n </div>\n <div className=\"power-logs-workspace\">\n <LogRows\n records={filtered}\n selected={selected?.key}\n onSelect={setSelected}\n follow={follow}\n setFollow={setFollow}\n compact={compact}\n />\n {selected && <LogDetails record={selected} onClose={() => setSelected(undefined)} />}\n </div>\n </>\n ) : (\n <>\n <div className=\"power-logs-toolbar power-logs-snapshot-bar\">\n <LogSelect\n label=\"Capture snapshot\"\n onKeyDown={(event) => {\n if (\n event.key !== \"Delete\" ||\n !event.altKey ||\n ((event.target as HTMLInputElement).value ?? \"\").length > 0\n )\n return;\n const button = document.querySelector<HTMLButtonElement>(\n \".Select__menu .Select__option--is-focused [data-capture-delete]\",\n );\n if (button && !button.disabled) {\n event.preventDefault();\n event.stopPropagation();\n void deleteCapture(button.dataset.captureDelete!);\n }\n }}\n renderOption={(option, context) => {\n const item = captures.find((item) => item.id === option.value);\n if (context !== \"menu\" || !item) return option.label;\n return (\n <span className=\"power-logs-snapshot-option\" title={option.label}>\n <span className=\"power-logs-option-text\">\n <strong>{item.target.name}</strong>\n <small>\n {formatDateTime(item.createdAt)} · {item.rows.toLocaleString()} lines ·{\" \"}\n {item.state[0].toUpperCase()}\n {item.state.slice(1)}\n </small>\n </span>\n <button\n type=\"button\"\n aria-label={`Delete snapshot ${item.target.name}`}\n title=\"Delete snapshot (Alt+Delete)\"\n data-capture-delete={item.id}\n onKeyDown={(event) => event.stopPropagation()}\n disabled={!!queryId || capturePending || deletingCount > 0 || item.state === \"collecting\"}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void deleteCapture(item.id);\n }}\n >\n <Renderer.Component.Icon\n material=\"delete_outline\"\n size={16}\n tooltip=\"Delete snapshot\"\n tooltipOverrideDisabled\n />\n </button>\n </span>\n );\n }}\n value={captureId}\n disabled={!!queryId || capturePending || deletingCount > 0}\n onChange={(value) => {\n setCaptureId(value);\n setResult(undefined);\n setResultEvidence(undefined);\n setSelectedSqlRow(undefined);\n const snapshot = captures.find((item) => item.id === value);\n if (snapshot) {\n setSql(examples[0][1]);\n void runQuery(snapshot, examples[0][1]);\n }\n }}\n options={[\n { value: \"\", label: \"Choose a snapshot\" },\n ...captures.map((item) => ({\n value: item.id,\n label: `${item.target.name} · ${formatDateTime(item.createdAt)} · ${item.rows.toLocaleString()} lines · ${item.state[0].toUpperCase()}${item.state.slice(1)}`,\n })),\n ]}\n />\n <button\n type=\"button\"\n disabled={!captureId || !!queryId || deleting.current.has(captureId)}\n title=\"Export JSON Lines (NDJSON)\"\n onClick={() => {\n void client.export(captureId).catch(() => setError(\"Could not export capture\"));\n }}\n >\n <Icon material=\"download\" size={16} /> Export JSON\n </button>\n </div>\n {!!chosenCapture?.notes.length && (\n <details className=\"power-logs-snapshot-notes power-logs-muted\">\n <summary>Snapshot notes ({chosenCapture.notes.length})</summary>\n {chosenCapture.notes.map((note) => (\n <div key={note}>{note}</div>\n ))}\n </details>\n )}\n <div className=\"power-logs-toolbar power-logs-sql-tools\">\n <label\n htmlFor=\"power-logs-sql\"\n title={`Read-only SELECT · ${limits.queryMs / 1000} s · ${limits.resultRows.toLocaleString()} rows · Schema: logs(timestamp INTEGER in milliseconds, pod, podUid, container, level, message, fieldsJson, previous INTEGER 0 or 1)`}\n >\n SQL query\n </label>\n <button\n type=\"button\"\n disabled={\n !chosenCapture ||\n !!queryId ||\n capturePending ||\n deleting.current.has(captureId) ||\n chosenCapture.state === \"collecting\"\n }\n onClick={() => void runQuery()}\n >\n <Icon material=\"play_arrow\" size={16} /> Run query\n </button>\n {queryId && (\n <button\n type=\"button\"\n onClick={() => {\n void client.cancel(queryId).catch(() => setError(\"Could not cancel query\"));\n }}\n >\n <Icon material=\"stop\" size={16} /> Cancel\n </button>\n )}\n {examples.map(([title, query]) => (\n <button type=\"button\" key={title} onClick={() => setSql(query)}>\n <Icon\n material={\n title === \"Recent\"\n ? \"history\"\n : title === \"Errors\"\n ? \"error_outline\"\n : title === \"Timeline\"\n ? \"timeline\"\n : \"data_object\"\n }\n size={16}\n />{\" \"}\n SQL: {title}\n </button>\n ))}\n </div>\n <textarea\n rows={2}\n id=\"power-logs-sql\"\n value={sql}\n maxLength={65536}\n onChange={(event) => setSql(event.target.value)}\n spellCheck={false}\n />\n {result ? (\n <>\n <div className=\"power-logs-toolbar power-logs-results-bar\">\n <span role=\"status\" className=\"power-logs-muted\">\n {result.rows.length} rows · {result.elapsedMs} ms{result.truncated ? \" · Result truncated\" : \"\"}\n </span>\n </div>\n <div className=\"power-logs-workspace\">\n <div className=\"power-logs-results\">\n <table\n style={{\n minWidth:\n result.columns.length > 3\n ? result.columns.reduce((width, column) => width + sqlColumnWidth(column), 0)\n : undefined,\n }}\n >\n <colgroup>\n {result.columns.map((column, i) => (\n <col\n key={i}\n style={{\n width: result.columns.length > 3 ? sqlColumnWidth(column) : undefined,\n }}\n />\n ))}\n </colgroup>\n <thead>\n <tr>\n {result.columns.map((column, i) => (\n <th key={i} data-column={column}>\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {result.rows.slice(resultPage * 50, (resultPage + 1) * 50).map((row, i) => (\n <tr\n key={i}\n tabIndex={0}\n aria-label={`Open SQL row ${resultPage * 50 + i + 1}`}\n onClick={() => setSelectedSqlRow({ ...sqlRowDetails(result.columns, row), row })}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setSelectedSqlRow({ ...sqlRowDetails(result.columns, row), row });\n }\n }}\n >\n {row.map((cell, j) => (\n <td\n key={j}\n data-column={result.columns[j]}\n data-level={result.columns[j] === \"level\" ? String(cell) : undefined}\n >\n <span className=\"power-logs-cell\" title={cell === null ? \"NULL\" : String(cell)}>\n {cell === null ? \"NULL\" : String(cell)}\n </span>\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n {result.rows.length === 0 && (\n <div className=\"power-logs-empty\">\n {chosenCapture?.rows === 0\n ? \"This snapshot contains no log lines. Try a longer capture window.\"\n : \"This query returned no rows. Adjust the query or choose SQL: Recent.\"}\n </div>\n )}\n </div>\n {selectedSqlRow && (\n <LogDetails\n record={selectedSqlRow.record}\n jsonColumn={selectedSqlRow.jsonColumn}\n onClose={() => setSelectedSqlRow(undefined)}\n />\n )}\n </div>\n {result.rows.length > 50 && (\n <nav className=\"power-logs-toolbar power-logs-pagination\" aria-label=\"SQL result pages\">\n <button\n type=\"button\"\n aria-label=\"Previous page\"\n title=\"Previous page\"\n disabled={resultPage === 0}\n onClick={() => {\n setResultPage(resultPage - 1);\n setSelectedSqlRow(undefined);\n }}\n >\n <Icon material=\"chevron_left\" size={16} />\n </button>\n <span className=\"power-logs-muted\">\n Page {resultPage + 1} / {Math.max(1, Math.ceil(result.rows.length / 50))}\n </span>\n <button\n type=\"button\"\n aria-label=\"Next page\"\n title=\"Next page\"\n disabled={(resultPage + 1) * 50 >= result.rows.length}\n onClick={() => {\n setResultPage(resultPage + 1);\n setSelectedSqlRow(undefined);\n }}\n >\n <Icon material=\"chevron_right\" size={16} />\n </button>\n </nav>\n )}\n </>\n ) : (\n <div className=\"power-logs-results power-logs-empty\">\n {queryId\n ? \"Running query…\"\n : captures.length === 0\n ? \"Capture logs to create a temporary snapshot for SQL.\"\n : \"Choose a snapshot to preview its logs.\"}\n </div>\n )}\n </>\n )}\n <div className=\"power-logs-muted power-logs-footer\">\n <span\n className=\"power-logs-caption\"\n title={`Gentle collection: ${limits.requestsPerSecond} requests/s, ${limits.bytesPerSecond / 1048576} MiB/s. Captures: ${limits.captureSourceLines.toLocaleString()} lines / ${limits.captureSourceBytes / 1048576} MiB per source, ${limits.captureBytes / 1048576} MiB total. Up to ${limits.captures} snapshots retained for ${limits.ttlMs / 60000} minutes.`}\n >\n Gentle collection · {limits.requestsPerSecond} requests/s · {limits.bytesPerSecond / 1048576} MiB/s · Captures\n limited to {limits.captureSourceLines.toLocaleString()} lines / {limits.captureSourceBytes / 1048576} MiB per\n source and {limits.captureBytes / 1048576} MiB total · Up to {limits.captures} temporary snapshots, retained\n for {limits.ttlMs / 60000} min\n </span>\n {collectionNotes.length > 0 && (\n <span role=\"note\" className=\"power-logs-notice power-logs-collection-note\" title={collectionNotes.join(\"\\n\")}>\n <Icon material=\"warning_amber\" size={14} />\n <span>{collectionNotes.join(\" · \")}</span>\n </span>\n )}\n </div>\n </div>\n );\n}\n\nconst ObservedWorkspace = observer(Workspace);\n\nexport const PowerLogsPage = observer(() => {\n const enabled = LogsPreferencesStore.getInstanceOrCreate<LogsPreferencesStore>().enabled;\n const clusterId = Renderer.Catalog.activeCluster.get()?.metadata.uid;\n if (!enabled || !clusterId)\n return (\n <div className=\"power-logs\">\n <style>{powerLogsStyles}</style>\n <h1>Power Logs</h1>\n <p>Enable Power Logs in Power settings and open a cluster to view logs.</p>\n </div>\n );\n const contextId = searchContextId();\n return <ObservedWorkspace key={`${clusterId}:${contextId}`} clusterId={clusterId} contextId={contextId} />;\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoCA,IAAM,QAAQ,UACZ,oCAAA,IAAC,QAAD;CAAM,eAAY;CAAO,OAAO,EAAE,SAAS,cAAc;WACvD,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB,EAAyB,GAAI,MAAQ,CAAA;AACjC,CAAA;AAER,IAAM,aAAa,MACjB,GAAG,EAAE,IAAI,KAAK,EAAE,YAAY,EAAE,WAAW,gBAAgB;AAC3D,IAAM,SAAqB;CAAC;CAAS;CAAS;CAAQ;CAAQ;CAAS;CAAS;AAAS;AACzF,IAAM,WAAW;CACf,CAAC,UAAU,yGAAyG;CACpH,CACE,UACA,mIACF;CACA,CACE,YACA,uJACF;CACA,CACE,QACA,+GACF;AACF;AACA,IAAM,kBAAkB,WACtB,WAAW,aAAa,WAAW,eAAe,MAAM,WAAW,UAAU,KAAK;AAGpF,SAAS,gBAAuC;CAC9C,IAAI;EACF,OAAO,+BAAA,qBAAqB,KAAK,MAAM,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAAC,CAAC,IAAI,QAAQ,KAAK,MAAM,CAAC;CAC7G,QAAQ;EACN;CACF;AACF;AACA,SAAS,cAAc,YAAqB,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAAC,CAAC,IAAI,WAAW,GAAW;CAChH,OAAO,OAAO,cAAc,YAAY,oCAAoC,KAAK,SAAS,KAAK,UAAU,UAAU,KAC/G,aAAa,cACb;AACN;AAEA,SAAS,UAAU,EACjB,OACA,OACA,SACA,UACA,WAAW,OACX,cACA,aASC;CACD,OACE,oCAAA,IAAC,QAAD;EAAM,WAAU;EAAoB,sBAAoB,UAAU,sBAAsB,KAAA;YACtF,oCAAA,IAAC,mBAAA,SAAS,UAAU,QAApB;GACE,cAAY;GACL;GACE;GACT,oBAAoB,QAAQ,SAC1B,eACE,aAAa,QAAQ,KAAK,OAAO,IAC/B,UAAU,eAAe,OAAO,QAClC,oCAAA,IAAC,QAAD;IAAM,WAAU;IAAyB,cAAY,OAAO;cACzD,OAAO;GACJ,CAAA,IAEN,OAAO;GAGX,YAAY;GACD;GACX,iBAAiB;GACjB,aAAa;GACb,cAAa;GACb,kBAAkB,SAAS;GAC3B,QAAQ;IACN,OAAO,SAAU,UAAU,qBAAqB;KAAE,GAAG;KAAM,OAAO;KAAQ,UAAU;IAAO,IAAI;IAC/F,WAAW,SAAU,UAAU,qBAAqB;KAAE,GAAG;KAAM,OAAO;KAAQ,UAAU;IAAO,IAAI;IACnG,SAAS,SAAU,UAAU,qBAAqB;KAAE,GAAG;KAAM,YAAY;IAAS,IAAI;IACtF,aAAa,SAAS;KACpB,IAAI,UAAU,sBAAsB,UAAU,oBAAoB,OAAO;MAAE,GAAG;MAAM,QAAQ;KAAM;KAClG,MAAM,QAAQ,KAAK,IAAI,UAAU,qBAAqB,MAAM,KAAK,OAAO,aAAa,EAAE;KACvF,OAAO;MACL,GAAG;MACH,QAAQ;MACR;MACA,MAAM,KAAK,IACT,IACA,KAAK,IAAI,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,IAAI,OAAO,aAAa,QAAQ,EAAE,CACzF;KACF;IACF;GACF;GACA,WAAW,WAAW;IACpB,IAAI,QAAQ,SAAS,OAAO,KAAK;GACnC;EACD,CAAA;CACG,CAAA;AAEV;AAEA,IAAM,eAAe,oCAAA,eAAe;CAUlC,MAAM,UAAU;EARd,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;EAChB,mBAAA,SAAS,OAAO;CAEF,CAAA,CAAO,SAAS,UAC9B,MAAM,SAAS,CAAC,CAAC,SAAS,WAAW;EACnC,MAAM,SAAS,+BAAA,qBAAqB;GAAE,MAAM,OAAO;GAAM,GAAG,OAAO;EAAS,CAAC;EAC7E,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC;CAC9B,CAAC,CACH;CACA,MAAM,CAAC,OAAO,YAAY,+BAAA,SAAS,EAAE;CACrC,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,MACnC,GAAG,EAAE,UAAU,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,cAAc,GAAG,EAAE,UAAU,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,CACzF;CACA,OACE,oCAAA,KAAC,OAAD;EAAK,WAAU;YAAf;GACE,oCAAA,IAAC,QAAD,EAAA,UAAM,WAAc,CAAA;GACpB,oCAAA,IAAC,WAAD;IACE,OAAM;IACC;IACP,UAAU;IACV,SAAS,CACP;KAAE,OAAO;KAAI,OAAO;IAAkC,GACtD,GAAG,OAAO,KAAK,YAAY;KACzB,OAAO,OAAO;KACd,OAAO,GAAG,OAAO,UAAU,KAAK,OAAO,KAAK,KAAK,OAAO;IAC1D,EAAE,CACJ;GACD,CAAA;GACD,oCAAA,KAAC,UAAD;IACE,MAAK;IACL,UAAU,CAAC,QAAQ,MAAM,WAAW,OAAO,QAAQ,KAAK;IACxD,eAAe;KACb,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,QAAQ,KAAK;KAClD,IAAI,QAAQ,+BAAA,cAAc,MAAM;IAClC;cANF,CAQE,oCAAA,IAAC,MAAD;KAAM,UAAS;KAAU,MAAM;IAAK,CAAA,GAAC,YAC/B;;EACL;;AAET,CAAC;AAED,SAAS,QAAQ,EACf,SACA,UACA,UACA,QACA,WACA,WAQC;CACD,MAAM,WAAW,+BAAA,OAAuB,IAAI;CAC5C,MAAM,CAAC,KAAK,UAAU,+BAAA,SAAS,CAAC;CAChC,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAS,GAAG;CACxC,+BAAA,gBAAgB;EACd,MAAM,UAAU,SAAS;EACzB,IAAI,CAAC,SAAS;EACd,MAAM,SAAS,IAAI,qBAAqB,UAAU,QAAQ,YAAY,CAAC;EACvE,OAAO,QAAQ,OAAO;EACtB,aAAa,OAAO,WAAW;CACjC,GAAG,CAAC,CAAC;CACL,+BAAA,sBAAsB;EACpB,IAAI,UAAU,SAAS,SAAS;GAC9B,SAAS,QAAQ,YAAY,SAAS,QAAQ;GAC9C,OAAO,SAAS,QAAQ,SAAS;EACnC;CACF,GAAG;EAAC;EAAS;EAAQ;CAAO,CAAC;CAC7B,MAAM,YAAY,UAAU,KAAK;CACjC,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,SAAS,IAAI,CAAC;CACzD,MAAM,UAAU,QAAQ,MAAM,OAAO,QAAQ,KAAK,KAAK,SAAS,SAAS,IAAI,EAAE;CAC/E,OACE,oCAAA,IAAC,OAAD;EAAK,WAAU;YACb,oCAAA,IAAC,OAAD;GACE,WAAU;GACV,KAAK;GACL,cAAW;GACX,WAAW,UAAU;IACnB,MAAM,KAAK,MAAM;IACjB,OAAO,GAAG,SAAS;IACnB,IAAI,GAAG,eAAe,GAAG,YAAY,GAAG,eAAe,IAAI,UAAU,KAAK;GAC5E;aAEC,QAAQ,WAAW,IAClB,oCAAA,IAAC,OAAD;IAAK,WAAU;cAAmB;GAA0B,CAAA,IAE5D,oCAAA,IAAC,OAAD;IAAK,OAAO;KAAE,QAAQ,QAAQ,SAAS;KAAW,UAAU;IAAW;cACpE,QAAQ,KAAK,QAAQ,MACpB,oCAAA,KAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,cAAY,OAAO;KACnB,gBAAc,aAAa,OAAO;KAClC,OAAO;MAAE,MAAM,QAAQ,KAAK;MAAW,QAAQ;KAAU;KAEzD,eAAe,SAAS,MAAM;eAPhC;MASE,oCAAA,IAAC,QAAD;OAAM,OAAO,OAAO,cAAc,OAAO,kBAAA,eAAe,OAAO,SAAS,IAAI;iBACzE,OAAO,cAAc,OAAO,kBAAA,eAAe,OAAO,SAAS,CAAC,CAAC,MAAM,EAAE,IAAI;MACtE,CAAA;MACN,oCAAA,IAAC,QAAD;OAAM,WAAU;iBAAmB,OAAO;MAAY,CAAA;MACtD,oCAAA,KAAC,QAAD;OAAM,WAAU;OAAmB,OAAO,UAAU,MAAM;iBAA1D;QACG,OAAO;QACP,OAAO,WAAW,gBAAgB;QAAG;QAAI,OAAO;OAC7C;;MACN,oCAAA,IAAC,QAAD,EAAA,UAAO,OAAO,QAAc,CAAA;KACtB;OAZD,OAAO,GAYN,CACT;GACE,CAAA;EAEJ,CAAA;CACF,CAAA;AAET;AAEA,SAAS,WAAW,EAAE,QAAQ,YAAY,WAA4E;CACpH,MAAM,mBAAmB,+BAAA,cAAc;EACrC,IAAI,CAAC,QAAQ,YAAY,OAAO;EAChC,IAAI;GACF,OAAO,KAAK,UAAU,KAAK,MAAM,OAAO,UAAU,GAAG,MAAM,CAAC;EAC9D,QAAQ;GACN,OAAO,OAAO;EAChB;CACF,GAAG,CAAC,QAAQ,UAAU,CAAC;CACvB,OACE,oCAAA,KAAC,SAAD;EAAO,WAAU;EAAoB,cAAW;YAAhD;GACE,oCAAA,KAAC,UAAD,EAAA,UAAA,CACE,oCAAA,IAAC,UAAD,EAAA,UAAQ,eAAoB,CAAA,GAC5B,oCAAA,IAAC,UAAD;IACE,WAAU;IACV,cAAW;IACX,OAAM;IACN,SAAS;cAET,oCAAA,IAAC,MAAD;KAAM,UAAS;KAAQ,MAAM;IAAK,CAAA;GAC5B,CAAA,CACF,EAAA,CAAA;GACR,oCAAA,IAAC,KAAD;IAAG,WAAU;cAAoB,CAAC,OAAO,OAAO,UAAU,MAAM,GAAG,OAAO,KAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;GAAK,CAAA;GAC/G,OAAO,WAAW,oCAAA,IAAC,OAAD,EAAA,UAAM,OAAO,QAAa,CAAA;GAC5C,OAAO,cACN,oCAAA,KAAA,oBAAA,UAAA,EAAA,UAAA,CACE,oCAAA,IAAC,UAAD,EAAA,UAAS,aAAa,uBAAuB,eAAe,oBAA4B,CAAA,GACxF,oCAAA,IAAC,uBAAA,SAAD,EAAS,MAAM,iBAAmB,CAAA,CAClC,EAAA,CAAA;EAEC;;AAEX;AAEA,SAAS,UAAU,EAAE,WAAW,aAAuD;CACrF,MAAM,SAAS,+BAAA,cAAc,0BAAA,sBAAsB;EAAE;EAAW;CAAU,CAAC,GAAG,CAAC,WAAW,SAAS,CAAC;CACpG,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAS,aAAa;CAClD,MAAM,CAAC,SAAS,cAAc,+BAAA,SAAuB,CAAC,CAAC;CACvD,MAAM,CAAC,SAAS,cAAc,+BAAA,SAAsB,CAAC,CAAC;CACtD,MAAM,CAAC,OAAO,YAAY,+BAAA,SAAmB,CAAC,CAAC;CAC/C,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAS,oCAAoC;CACzE,MAAM,CAAC,OAAO,YAAY,+BAAA,SAAS,EAAE;CACrC,MAAM,CAAC,KAAK,UAAU,+BAAA,SAA8B,MAAM;CAC1D,MAAM,CAAC,MAAM,WAAW,+BAAA,SAAS,EAAE;CACnC,MAAM,CAAC,OAAO,YAAY,+BAAA,SAAS,EAAE;CACrC,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAS,aAAa;CAClD,MAAM,cAAc,+BAAA,qBAAqB,oBAA0C;CACnF,MAAM,SAAS,0BAAA,yBAAyB,YAAY,MAAM;CAC1D,+BAAA,gBAAgB;EACd,0BAAA,qBAAqB,YAAY,MAAM;CACzC,GAAG,CAAC,YAAY,MAAM,CAAC;CACvB,MAAM,CAAC,SAAS,cAAc,+BAAA,SAAS,YAAY,gBAAgB,IAAI;CACvE,MAAM,CAAC,UAAU,eAAe,+BAAA,SAAqB;CACrD,MAAM,CAAC,gBAAgB,qBAAqB,+BAAA,SAE1C;CACF,MAAM,CAAC,cAAc,mBAAmB,+BAAA,SAA0B;CAClE,MAAM,CAAC,MAAM,WAAW,+BAAA,SAAS,KAAK;CACtC,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAS,IAAI;CACzC,MAAM,CAAC,MAAM,WAAW,+BAAA,SAAS,KAAK;CACtC,MAAM,CAAC,UAAU,eAAe,+BAAA,SAAuB,CAAC,CAAC;CACzD,MAAM,CAAC,WAAW,gBAAgB,+BAAA,SAAS,EAAE;CAC7C,MAAM,mBAAmB,+BAAA,OAAO,SAAS;CACzC,iBAAiB,UAAU;CAC3B,MAAM,WAAW,+BAAA,uBAAO,IAAI,IAAY,CAAC;CACzC,MAAM,CAAC,eAAe,oBAAoB,+BAAA,SAAS,CAAC;CACpD,MAAM,CAAC,WAAW,gBAAgB,+BAAA,SAAqB;CACvD,MAAM,CAAC,gBAAgB,qBAAqB,+BAAA,SAAS,KAAK;CAC1D,MAAM,CAAC,gBAAgB,qBAAqB,+BAAA,SAAS,EAAE;CACvD,MAAM,CAAC,UAAU,eAAe,+BAAA,SAAS,KAAK;CAC9C,MAAM,CAAC,KAAK,UAAU,+BAAA,SAAiB,SAAS,EAAE,CAAC,EAAE;CACrD,MAAM,CAAC,QAAQ,aAAa,+BAAA,SAAyB;CACrD,MAAM,CAAC,gBAAgB,qBAAqB,+BAAA,SAA+C;CAC3F,MAAM,CAAC,YAAY,iBAAiB,+BAAA,SAAS,CAAC;CAC9C,MAAM,CAAC,SAAS,cAAc,+BAAA,SAAS,EAAE;CACzC,MAAM,iBAAiB,+BAAA,OAA2B,IAAI;CACtD,+BAAA,gBAAgB;EACd,MAAM,WAAW,UAAwB;GACvC,IACE,CAAC,eAAe,SAAS,SAAS,MAAM,MAAc,KACtD,CAAE,MAAM,QAAoB,UAAU,eAAe;QAEjD,eAAe,SAAS,eAAe,QAAQ,OAAO;GAAA;EAE9D;EACA,MAAM,UAAU,UAAyB;GACvC,IAAI,MAAM,QAAQ,YAAY,MAAM,oBAAqB,MAAM,QAAoB,UAAU,SAAS,GAAG;GACzG,IAAI,eAAe,SAAS,MAAM,eAAe,QAAQ,OAAO;QAC3D;IACH,YAAY,KAAA,CAAS;IACrB,kBAAkB,KAAA,CAAS;GAC7B;EACF;EACA,OAAO,iBAAiB,eAAe,OAAO;EAC9C,OAAO,iBAAiB,WAAW,MAAM;EACzC,aAAa;GACX,OAAO,oBAAoB,eAAe,OAAO;GACjD,OAAO,oBAAoB,WAAW,MAAM;EAC9C;CACF,GAAG,CAAC,CAAC;CACL,MAAM,oBAAoB,+BAAA,OAAwB;CAClD,MAAM,iBAAiB,+BAAA,OAAwB;CAC/C,MAAM,oBAAoB,+BAAA,OAAwB;CAClD,MAAM,WAAW,+BAAA,OAAO,EAAE;CAC1B,MAAM,QAAQ,+BAAA,OAAO,CAAC;CACtB,MAAM,QAAQ,+BAAA,OAAO,IAAI;CACzB,MAAM,WAAW,+BAAA,OAAO,CAAC;CACzB,MAAM,aAAa,+BAAA,OAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,UAAU,+BAAA,OAAoB,CAAC,CAAC;CACtC,MAAM,aAAa,+BAAA,OAAsC;CACzD,MAAM,wBACJ,OACG,KAAK,CAAC,CACN,MAAM,UAAU;EACf,IAAI,MAAM,SAAS,YAAY,KAAK;CACtC,CAAC,CAAC,CACD,YAAY;EACX,IAAI,MAAM,SAAS,SAAS,oCAAoC;CAClE,CAAC;CACL,MAAM,iBAAiB;EACrB,eAAe,SAAS,MAAM;EAC9B,eAAe,UAAU,KAAA;EACzB,QAAQ,KAAK;CACf;CACA,MAAM,cAAc;EAClB,aAAa,WAAW,OAAO;EAC/B,WAAW,UAAU,KAAA;EACrB,MAAM,QAAQ,QAAQ;EACtB,QAAQ,UAAU,CAAC;EACnB,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,SAAS;EACrC,MAAM,OAAO,MAAM,KAAK,YAAY;GAClC,GAAG;GACH,KAAK,EAAE,SAAS;GAChB,OAAO,OAAO,WAAW,KAAK,UAAU,MAAM,CAAC;EACjD,EAAE;EACF,YAAY,YAAY;GACtB,MAAM,WAAW,CAAC,GAAG,SAAS,GAAG,IAAI;GACrC,IAAI,QAAQ,SAAS,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;GACxD,IAAI,QAAQ;GACZ,OAAO,SAAS,SAAS,QAAQ,mBAAA,kBAAE,YAAY,QAAQ,mBAAA,kBAAE,WAAW,SAAS,SAAS,QAAQ,CAAC;GAC/F,OAAO,SAAS,MAAM,KAAK,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,aAAa,MAAM,EAAE,aAAa,MAAM,EAAE,MAAM,EAAE,GAAG;EACtG,CAAC;CACH;CACA,MAAM,cAAc,UAAuB;EACzC,IAAI,CAAC,MAAM,SAAS;EACpB,QAAQ,QAAQ,KAAK,GAAG,KAAK;EAC7B,IAAI,QAAQ,QAAQ,SAAS,KAAM,MAAM;OACpC,WAAW,YAAY,WAAW,OAAO,EAAE;CAClD;CACA,+BAAA,gBAAgB;EACd,MAAM,UAAU;EAChB,MAAM,YAAY,UAAiB;GACjC,MAAM,OAAO,+BAAA,qBAAsB,MAAsB,MAAM;GAC/D,IAAI,MAAM;IACR,IAAI,SAAS,SAAS;KACpB,OAAY,OAAO,SAAS,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;KACnD,SAAS,UAAU;KACnB,WAAW,EAAE;IACf;IACA,UAAU,cAAe,MAAsB,OAAO,SAAS,CAAC;IAChE,UAAU,IAAI;GAChB;EACF;EACA,OAAO,iBAAiB,qBAAqB,QAAQ;EACrD,gBAAqB;EACrB,MAAM,QAAQ,kBAAkB,KAAK,gBAAgB,GAAG,GAAK;EAC7D,aAAa;GACX,MAAM,UAAU;GAChB,MAAM;GACN,cAAc,KAAK;GACnB,aAAa,WAAW,OAAO;GAC/B,kBAAkB,SAAS,MAAM;GACjC,eAAe,SAAS,MAAM;GAC9B,kBAAkB,SAAS,MAAM;GACjC,IAAI,SAAS,SAAS,OAAY,OAAO,SAAS,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;GACzE,OAAO,oBAAoB,qBAAqB,QAAQ;EAC1D;CACF,GAAG,CAAC,MAAM,CAAC;CACX,MAAM,cAAc,YAAY;EAC9B,IAAI,CAAC,QAAQ;EACb,MAAM,eAAe,EAAE,MAAM;EAC7B,kBAAkB,SAAS,MAAM;EACjC,SAAS;EACT,MAAM,aAAa,IAAI,gBAAgB;EACvC,kBAAkB,UAAU;EAC5B,aAAa,WAAW,OAAO;EAC/B,WAAW,UAAU,KAAA;EACrB,QAAQ,UAAU,CAAC;EACnB,QAAQ,IAAI;EACZ,WAAW,CAAC,CAAC;EACb,YAAY,KAAA,CAAS;EACrB,SAAS,EAAE;EACX,SAAS,CAAC,CAAC;EACX,UAAU,+BAA+B;EACzC,IAAI;GACF,MAAM,YAAY,6BAAA,yBAAyB,SAAS;GACpD,MAAM,YAAY,MAAM,6BAAA,kBAAkB,QAAQ,WAAW,WAAW,MAAM;GAC9E,IAAI,WAAW,OAAO,WAAW,iBAAiB,MAAM,SAAS;GACjE,WAAW,UAAU,OAAO;GAC5B,SAAS,UAAU,KAAK;GACxB,UAAU,WAAW,UAAU,QAAQ,OAAO,oBAAoB;GAClE,MAAM,UAAU,MAAM,6BAAA,sBAAsB,UAAU,SAAS,WAAW;IACxE,QAAQ,WAAW;IACnB,WAAW,mBAAA,kBAAE;IACb,YAAY,mBAAA,kBAAE;IACd,YAAY,UAAU;KACpB,IAAI,iBAAiB,MAAM,SAAS,WAAW,KAAK;IACtD;GACF,CAAC;GACD,IAAI,WAAW,OAAO,WAAW,iBAAiB,MAAM,SAAS;GACjE,MAAM;GACN,SAAS,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,UAAU,OAAO,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC;GAC7D,UACE,GAAG,UAAU,QAAQ,OAAO,kBAAkB,OAAO,aAAa,eAAe,EAAE,8BAA8B,OAAO,eAAe,QAAQ,UACjJ;EACF,QAAQ;GACN,IAAI,MAAM,WAAW,iBAAiB,MAAM,SAC1C,SACE,WAAW,OAAO,UACd,wBACA,qFACN;EACJ,UAAU;GACR,IAAI,MAAM,WAAW,iBAAiB,MAAM,SAAS,QAAQ,KAAK;EACpE;CACF;CACA,+BAAA,gBAAgB;EACd,QAAQ,EAAE;EACV,WAAW,CAAC,CAAC;EACb,OAAO,MAAM;EACb,YAAiB;CACnB,GAAG,CAAC,QAAQ,GAAG,CAAC;CAChB,MAAM,mBAAmB;EACvB,IAAI,MAAM;GACR,SAAS;GACT;EACF;EACA,QAAQ,IAAI;CACd;CAEA,+BAAA,gBAAgB;EACd,IAAI,CAAC,QAAQ,CAAC,QAAQ,QAAQ;EAC9B,MAAM,aAAa,IAAI,gBAAgB;EACvC,eAAe,UAAU;EACzB,MAAM,YAAY,6BAAA,cAAc,SAAS,6BAAA,yBAAyB,SAAS,GAAG;GAC5E,QAAQ,WAAW;GACnB,WAAW,mBAAA,kBAAE;GACb,gBAAgB,WAAW;GAC3B,WAAW;GACX,aAAa,aAAa;IACxB,IAAI,MAAM,WAAW,eAAe,YAAY,YAC9C,gBAAgB;KAAE,GAAG;KAAU,OAAO,CAAC,GAAG,SAAS,KAAK;IAAE,CAAC;GAC/D;EACF,CAAC;EACD,gBAAgB,EAAE,GAAG,UAAU,SAAS,CAAC;EACzC,UAAe,KAAK,cAAc;GAChC,IAAI,MAAM,WAAW,CAAC,WAAW,OAAO,WAAW,eAAe,YAAY,YAAY;IACxF,eAAe,UAAU,KAAA;IACzB,QAAQ,KAAK;GACf;EACF,CAAC;EACD,aAAa;GACX,WAAW,MAAM;GACjB,IAAI,eAAe,YAAY,YAAY,eAAe,UAAU,KAAA;EACtE;CACF,GAAG,CAAC,MA1BmB,QAAQ,KAAK,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,WAAW,CAAC,CAAC,KAAK,GA0B5E,CAAc,CAAC;CACzB,+BAAA,gBAAgB;EACd,IAAI,CAAC,QAAQ,CAAC,QAAQ;EACtB,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,gBAAgB,MAAM;EAC5B,IAAI,aAAa;EACjB,MAAM,QAAQ,kBAAkB;GAC9B,IAAI,YAAY;GAChB,aAAa;GACb,6BAAK,kBAAkB,QAAQ,6BAAA,yBAAyB,SAAS,GAAG,WAAW,MAAM,CAAC,CACnF,MAAM,cAAc;IACnB,IAAI,WAAW,OAAO,WAAW,MAAM,YAAY,eAAe;IAClE,WAAW,UAAU,OAAO;IAC5B,SAAS,UAAU,KAAK;IACxB,UAAU,GAAG,UAAU,QAAQ,OAAO,yCAAyC;GACjF,CAAC,CAAC,CACD,YAAY;IACX,IAAI,CAAC,WAAW,OAAO,WAAW,MAAM,WAAW,MAAM,YAAY,eAAe;KAClF,SAAS;KACT,UAAU,YAAY,CACpB,mBAAG,IAAI,IAAI,CACT,GAAG,SACH,wFACF,CAAC,CACH,CAAC;IACH;GACF,CAAC,CAAC,CACD,cAAc;IACb,aAAa;GACf,CAAC;EACL,GAAG,GAAK;EACR,aAAa;GACX,cAAc,KAAK;GACnB,WAAW,MAAM;EACnB;CACF,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC;CACtB,MAAM,UAAU,YAAY;EAC1B,IAAI,CAAC,UAAU,kBAAkB,WAAW,SAAS,SAAS;EAC9D,kBAAkB,IAAI;EACtB,MAAM,aAAa,IAAI,gBAAgB;EACvC,kBAAkB,UAAU;EAC5B,IAAI;EACJ,IAAI,UAAU;EACd,IAAI,eAAyB,CAAC;EAC9B,SAAS,EAAE;EACX,SAAS;EACT,IAAI;GACF,UAAU,MAAM,OAAO,OAAO,MAAM;GACpC,aAAa,OAAO;GACpB,MAAM,YAAY,6BAAA,yBAAyB,SAAS;GACpD,MAAM,YAAY,MAAM,6BAAA,kBAAkB,QAAQ,WAAW,WAAW,MAAM;GAC9E,eAAe,UAAU;GACzB,UAAU,UAAU;GACpB,MAAM,iBAAiB,WACnB,CAAC,GAAG,UAAU,SAAS,GAAG,UAAU,QAAQ,KAAK,UAAU;IAAE,GAAG;IAAM,UAAU;GAAK,EAAE,CAAC,IACxF,UAAU;GACd,MAAM,WAAW,QAAQ;GACzB,MAAM,UAAU,MAAM,6BAAA,sBAAsB,gBAAgB,WAAW;IACrE,QAAQ,WAAW;IACnB,WAAW,mBAAA,kBAAE;IACb,4BAAW,IAAI,KAAK,WAAW,iBAAiB,GAAK,EAAA,CAAE,YAAY;IACnE,YAAY,mBAAA,kBAAE;IACd,WAAW,OAAO,UAAU;KAC1B,IAAI,MAAM,MAAM,WAAW,OAAO,cAAc,IAAI,GAAG;MACrD,UAAU;MACV,aAAa,KAAK,4EAA4E;KAChG;KACA,QAAQ,MAAM,QACX,WACC,OAAO,cAAc,QACpB,OAAO,aAAa,YAAY,OAAO,aAAa,WAAW,iBAAiB,GACrF;KACA,KAAK,IAAI,SAAS,GAAG,SAAS,MAAM,SAAU;MAC5C,MAAM,QAAqB,CAAC;MAC5B,IAAI,QAAQ;MACZ,OAAO,SAAS,MAAM,UAAU,MAAM,SAAS,mBAAA,kBAAE,WAAW;OAC1D,MAAM,SAAS,MAAM;OACrB,MAAM,OAAO,OAAO,WAAW,KAAK,UAAU,MAAM,CAAC,IAAI;OACzD,IAAI,MAAM,UAAU,QAAQ,OAAO,mBAAA,kBAAE,YAAY;OACjD,MAAM,KAAK,MAAM;OACjB,SAAS;OACT;MACF;MACA,IAAI,WAAW,OAAO,SAAS,MAAM,IAAI,MAAM,iBAAiB;MAChE,IAAI;OACF,UAAU,MAAM,OAAO,OAAO,QAAS,IAAI,KAAK;OAChD,IAAI,MAAM,SAAS,aAAa,OAAO;MACzC,QAAQ;OACN,WAAW,MAAM;OACjB,MAAM,IAAI,MAAM,yDAAyD;MAC3E;KACF;IACF;GACF,CAAC;GACD,YAAY,QAAQ;GACpB,aAAa,KAAK,GAAG,QAAQ,KAAK;EACpC,QAAQ;GACN,UAAU;GACV,aAAa,KAAK,iFAAiF;EACrG,UAAU;GACR,IAAI,SACF,IAAI;IACF,MAAM,QAAQ,MAAM,OAAO,OACzB,QAAQ,IACR,WAAW,WAAW,OAAO,SAC7B,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CACxC;IACA,IAAI,MAAM,SAAS;KACjB,aAAa,MAAM,EAAE;KACrB,aAAa,UAAU,CAAC,OAAO,GAAG,MAAM,QAAQ,SAAS,KAAK,OAAO,MAAM,EAAE,CAAC,CAAC;KAC/E,OAAO,UAAU;KACjB,OAAO,SAAS,EAAE,CAAC,EAAE;KACrB,SAAc,OAAO,SAAS,EAAE,CAAC,EAAE;IACrC;GACF,QAAQ;IACN,IAAI,MAAM,SAAS,SAAS,8CAA8C;GAC5E;QACK,IAAI,MAAM,SACf,SAAS,8EAA8E;GACzF,IAAI,MAAM,SAAS;IACjB,aAAa,KAAA,CAAS;IACtB,kBAAkB,KAAK;IACvB,gBAAqB;GACvB;GACA,kBAAkB,UAAU,KAAA;EAC9B;CACF;CACA,MAAM,WAAW,OAAO,iBAA8B,QAAQ,QAAQ;EACpE,IAAI,SAAS,WAAY,CAAC,mBAAmB,kBAAkB,SAAU;EACzE,MAAM,WAAW,mBAAmB,SAAS,MAAM,SAAS,KAAK,OAAO,SAAS;EACjF,IAAI,CAAC,YAAY,SAAS,UAAU,gBAAgB,SAAS,QAAQ,IAAI,SAAS,EAAE,GAAG;EACvF,MAAM,MAAA,GAAA,YAAA,WAAA,CAAgB;EACtB,SAAS,UAAU;EACnB,WAAW,EAAE;EACb,SAAS,EAAE;EACX,UAAU,KAAA,CAAS;EACnB,kBAAkB,KAAA,CAAS;EAC3B,kBAAkB;GAAE,SAAS;GAAU,KAAK;EAAM,CAAC;EACnD,cAAc,CAAC;EACf,IAAI;GACF,MAAM,QAAQ,MAAM,OAAO,MAAM,SAAS,IAAI,IAAI,KAAK;GACvD,IAAI,MAAM,WAAW,SAAS,YAAY,IACxC,IAAI,MAAM,OAAO,SAAS,MAAM,KAAK;QAChC,UAAU,KAAK;EAExB,QAAQ;GACN,IAAI,MAAM,WAAW,SAAS,YAAY,IACxC,SACE,uHACF;EACJ,UAAU;GACR,IAAI,SAAS,YAAY,IAAI;IAC3B,IAAI,MAAM,SAAS,WAAW,EAAE;IAChC,SAAS,UAAU;GACrB;EACF;CACF;CACA,MAAM,WAAW,+BAAA,cAEb,QAAQ,QACL,YACE,CAAC,QAAQ,OAAO,QAAQ,kBAAkB,CAAC,CAAC,SAAS,KAAK,kBAAkB,CAAC,OAC7E,CAAC,SAAS,OAAO,UAAU,WAC3B,CAAC,WACC,OAAO,WAAW,YAAY,IAAI,OAAO,cAAc,OAAO,MAAM,EAAE,IAAI,UAAU,MAAM,MAAM,QACvG,GACF;EAAC;EAAS;EAAM;EAAO;CAAM,CAC/B;CACA,MAAM,gBAAgB,SAAS,MAAM,SAAS,KAAK,OAAO,SAAS;CACnE,MAAM,kBAAkB,QAAQ,SAAS,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,OAAO,GAAI,OAAQ,cAAc,SAAS,CAAC,IAAK,CAAC,CAAE,CAAC,CAAC,IAAI,CAAC;CACnH,+BAAA,gBAAgB;EACd,OAAO,cAAc,IAAI,YAAY,+BAA+B,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,CAAC,CAAC;EACjG,aAAa;GACX,OAAO,cAAc,IAAI,YAAY,+BAA+B,EAAE,QAAQ,EAAE,QAAQ,MAAM,EAAE,CAAC,CAAC;EACpG;CACF,GAAG,CAAC,CAAC;CACL,+BAAA,gBAAgB;EACd,MAAM,UAAU,UAAiB;GAC/B,MAAM,MAAO,MAAyC,QAAQ;GAC9D,IAAI,OAAO,QAAQ,YAAY,CAAC,IAAI,KAAK,KAAK,IAAI,SAAS,OAAO;GAClE,OAAO,UAAU;GACjB,OAAO,GAAG;GACV,kBAAkB,KAAA,CAAS;GAC3B,IAAI,CAAC,WAAW;IACd,MAAM,SAAS,SAAS,MAAM,SAAS,KAAK,UAAU,gBAAgB,KAAK,OAAO,QAAQ,QAAQ,GAAG;IACrG,IAAI,QAAQ,aAAa,OAAO,EAAE;GACpC;GACA,4BAA4B,SAAS,eAAe,gBAAgB,CAAC,EAAE,MAAM,CAAC;EAChF;EACA,OAAO,iBAAiB,wBAAwB,MAAM;EACtD,aAAa,OAAO,oBAAoB,wBAAwB,MAAM;CACxE,GAAG;EAAC;EAAW;EAAU,QAAQ;CAAG,CAAC;CACrC,MAAM,iBAAiB;EACrB,MAAM,WACJ,QAAQ,aACJ,UAAU,iBACR,eAAe,QAAQ,SACtB,eAAe,UAAU,SAC5B;EACN,MAAM,UACJ,QAAQ,cAAc,UAAU,iBAC5B,sBAAA,sBACE,eAAe,SACf,eAAe,KACf,iBAAiB;GAAE,GAAG;GAAQ,MAAM,CAAC,eAAe,GAAG;GAAG,WAAW;EAAM,IAAI,MACjF,IACA,QAAQ,UAAU,WAChB,sBAAA,qBAAqB,UAAU,QAAQ,IACvC,KAAK,UAAU;GACb,QAAQ;GACR,GAAI,QAAQ,aACR;IAAE;IAAK,MAAM,CAAC;IAAG,OAAO;GAA4B,IACpD;IAAE;IAAQ,SAAS,QAAQ;GAAO;EACxC,CAAC;EACT,IACE,CAAC,8BAAA,yBAAyB;GACxB;GACA,OAAO,QAAQ,aAAc,iBAAiB,YAAY,cAAe,WAAW,aAAa;GACjG,SAAS,QAAQ,MAAM,GAAG,GAAI;GAC9B,GAAI,WAAW,EAAE,UAAU;IAAE,MAAM,SAAS;IAAM,MAAM,SAAS;IAAM,WAAW,SAAS;GAAU,EAAE,IAAI,CAAC;EAC9G,CAAC,GAED,OAAO,cAAc,IAAI,MAAM,oBAAoB,CAAC;CACxD;CACA,MAAM,gBAAgB,OAAO,OAAe;EAC1C,IAAI,SAAS,QAAQ,IAAI,EAAE,KAAK,SAAS,WAAW,kBAAkB,SAAS;EAC/E,SAAS,QAAQ,IAAI,EAAE;EACvB,iBAAiB,SAAS,QAAQ,IAAI;EACtC,IAAI;GACF,MAAM,OAAO,OAAO,EAAE;GACtB,IAAI,OAAO,iBAAiB,SAAS;IACnC,aAAa,EAAE;IACf,UAAU,KAAA,CAAS;IACnB,kBAAkB,KAAA,CAAS;IAC3B,kBAAkB,KAAA,CAAS;GAC7B;GACA,MAAM,gBAAgB;EACxB,QAAQ;GACN,SAAS,0BAA0B;EACrC,UAAU;GACR,SAAS,QAAQ,OAAO,EAAE;GAC1B,IAAI,MAAM,SAAS,iBAAiB,SAAS,QAAQ,IAAI;EAC3D;CACF;CACA,MAAM,eAAe;EACnB,MAAM,QAAQ,QAAQ;EACtB,MAAM,MAAM,mBAAA,SAAS,OAAO,UACzB,SAAS,CAAC,CACV,MAAM,SACL,QAAQ,SAAS,QAAQ,KAAK,SAAS,QAAQ,OAAO,MAAM,KAAK,SAAS,QAAQ,OAAO,MAC3F;EACF,MAAM,YAAY,OAAO,WAAW,YAAY,IAC5C,OAAO,MAAM,EAAE,IACf,QAAQ,MAAM,SAAS,UAAU,IAAI,MAAM,MAAM,CAAC,EAAE;EACxD,MAAM,mBAAmB,KAAK,SAAS,cAAc;EACrD,MAAM,YACJ,KAAK,iBAAiB,CAAC,CAAC,MAAM,SAAS,KAAK,UAAU,aAAa,iBAAiB,KACpF,KAAK,iBAAiB,CAAC,CAAC;EAC1B,IAAI,OAAO,WACT,mBAAA,SAAS,UAAU,YAAY,aAAa;GAAE,aAAa;GAAK,mBAAmB;EAAU,CAAC;OAC3F,SAAS,iEAAiE;CACjF;CACA,OACE,oCAAA,KAAC,OAAD;EAAK,WAAU;EAAa,eAAY;EAAkB,gBAAc,WAAW,KAAA;YAAnF;GACE,oCAAA,IAAC,SAAD,EAAA,UAAQ,uBAAA,gBAAuB,CAAA;GAC/B,oCAAA,KAAC,UAAD,EAAA,UAAA;IACE,oCAAA,IAAC,MAAD;KAAI,WAAU;eAAwB;IAAc,CAAA;IACpD,oCAAA,KAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,cAAW;KACX,YAAY,UAAU;MACpB,IAAI,CAAC;OAAC;OAAa;OAAc;OAAQ;MAAK,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG;MACrE,MAAM,OAAO,CAAC,GAAG,MAAM,cAAc,iBAAoC,YAAY,CAAC;MACtF,MAAM,QAAQ,KAAK,QAAQ,SAAS,aAAkC;MACtE,IAAI,QAAQ,GAAG;MACf,MAAM,eAAe;MACrB,MAAM,OACJ,MAAM,QAAQ,SACV,IACA,MAAM,QAAQ,QACZ,KAAK,SAAS,KACb,SAAS,MAAM,QAAQ,eAAe,IAAI,MAAM,KAAK,UAAU,KAAK;MAC7E,KAAK,KAAK,EAAE,MAAM;MAClB,KAAK,KAAK,EAAE,MAAM;KACpB;eAlBF,CAoBE,oCAAA,KAAC,UAAD;MAAQ,MAAK;MAAM,iBAAe,QAAQ;MAAQ,eAAe,OAAO,MAAM;gBAA9E,CACE,oCAAA,IAAC,MAAD;OAAM,UAAS;OAAU,MAAM;MAAK,CAAA,GAAC,YAC/B;SACR,oCAAA,KAAC,UAAD;MACE,MAAK;MACL,iBAAe,QAAQ;MACvB,eAAe;OACb,OAAO,UAAU;OACjB,MAAM,SAAS,SAAS,MACrB,SAAS,KAAK,UAAU,iBAAiB,CAAC,UAAU,KAAK,OAAO,QAAQ,OAAO,IAClF;OACA,IAAI,CAAC,aAAa,UAAU,CAAC,gBAAgB;QAC3C,aAAa,OAAO,EAAE;QACtB,OAAO,SAAS,EAAE,CAAC,EAAE;QACrB,SAAc,QAAQ,SAAS,EAAE,CAAC,EAAE;OACtC;OACA,gBAAqB;MACvB;gBAdF,CAgBE,oCAAA,IAAC,MAAD;OAAM,UAAS;OAAO,MAAM;MAAK,CAAA,GAAC,MAC5B;OACL;;IAEL,oCAAA,KAAC,OAAD;KAAK,WAAU;eAAf;MACE,oCAAA,KAAC,OAAD;OAAK,WAAU;iBAAf;QACE,oCAAA,KAAC,WAAD;SAAS,KAAK;SAAgB,WAAU;mBAAxC,CACE,oCAAA,KAAC,WAAD;UAAS,OAAO,mBAAmB,eAAe;oBAAlD,CACE,oCAAA,IAAC,MAAD;WAAM,UAAS;WAAO,MAAM;UAAK,CAAA,GAAC,UAC3B;aACT,oCAAA,KAAC,OAAD,EAAA,UAAA;UACG;UACD,oCAAA,KAAC,SAAD,EAAA,UAAA,CAAO,kBAEL,oCAAA,IAAC,WAAD;WACE,OAAM;WACN,OAAO,OAAO,cAAc;WAC5B,WAAW,UAAU,kBAAkB,OAAO,KAAK,CAAC;WACpD,SAAS;YACP;aAAE,OAAO;aAAK,OAAO;YAAY;YACjC;aAAE,OAAO;aAAM,OAAO;YAAa;YACnC;aAAE,OAAO;aAAM,OAAO;YAAS;WACjC;UACD,CAAA,CACI,EAAA,CAAA;UACP,oCAAA,IAAC,mBAAA,SAAS,UAAU,QAApB;WAA2B,SAAS;WAAU,UAAU;qBAAa;UAE1C,CAAA;UAC3B,oCAAA,IAAC,mBAAA,SAAS,UAAU,QAApB;WACE,SAAS;WACT,WAAW,UAAU;YACnB,WAAW,KAAK;YAChB,YAAY,cAAc;WAC5B;qBACD;UAE0B,CAAA;SACxB,EAAA,CAAA,CACE;;QACR,QAAQ,cACP,oCAAA,KAAC,UAAD;SACE,MAAK;SACL,UAAU,CAAC,UAAU,kBAAkB,QAAQ,CAAC,CAAC,WAAW,gBAAgB;SAC5E,eAAe,KAAK,QAAQ;mBAH9B,CAKE,oCAAA,IAAC,MAAD;UAAM,UAAS;UAAW,MAAM;SAAK,CAAA,GAAC,eAChC;;QAET,kBACC,oCAAA,KAAA,oBAAA,UAAA,EAAA,UAAA,CACE,oCAAA,IAAC,QAAD;SAAM,MAAK;SAAS,WAAU;mBAC3B,YACG,GAAG,UAAU,KAAK,eAAe,EAAE,YAAY,UAAU,QAAQ,QAAA,CAAS,QAAQ,CAAC,EAAE,QACrF;QACA,CAAA,GACN,oCAAA,KAAC,UAAD;SAAQ,MAAK;SAAS,eAAe,kBAAkB,SAAS,MAAM;mBAAtE,CACE,oCAAA,IAAC,MAAD;UAAM,UAAS;UAAO,MAAM;SAAK,CAAA,GAAC,sBAC5B;UACR,EAAA,CAAA;OAED;;MAEL,oCAAA,KAAC,kCAAA,yBAAD;OAAyB,cAAW;OAAoB,OAAM;OAAoB,SAAS;iBAA3F,CACE,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAsB,MAAM;OAAK,CAAA,GAAC,KAC1B;;MACxB,QAAQ,UACP,oCAAA,KAAC,UAAD;OAAQ,MAAK;OAAS,UAAU,CAAC,UAAU;OAAM,eAAe,KAAK,YAAY;iBAAjF,CACE,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAU,MAAM;OAAK,CAAA,GAAC,UAC/B;;MAET,QAAQ,SAAS,SAChB,oCAAA,IAAC,UAAD;OAAQ,MAAK;OAAS,cAAW;OAAc,OAAM;OAAc,SAAS;iBAC1E,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;QAAyB,UAAS;QAAc,MAAM;QAAI,SAAQ;QAAc,yBAAA;OAAyB,CAAA;MACnG,CAAA;KAEP;;GACC,EAAA,CAAA;GACP,SACC,oCAAA,KAAC,OAAD;IACE,WAAU;IACV,OAAO,GAAG,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,OAAO,UAAU,SAAS,OAAO;cAF/E;KAIE,oCAAA,KAAC,UAAD,EAAA,UAAA;MACG,OAAO;MAAK;MAAI,OAAO;KAClB,EAAA,CAAA;KAAE;KAAI;KACX,OAAO;IACP;QAEL,oCAAA,IAAC,cAAD,CAAe,CAAA;GAEhB,SACC,oCAAA,IAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;cACzB;GACE,CAAA;GAEN,QAAQ,SACP,oCAAA,KAAA,oBAAA,UAAA,EAAA,UAAA;IACE,oCAAA,KAAC,OAAD;KAAK,WAAU;eAAf;MACE,oCAAA,IAAC,SAAD;OACE,cAAW;OACX,aAAY;OACZ,OAAO;OACP,WAAW;OACX,WAAW,UAAU,QAAQ,MAAM,OAAO,KAAK;MAChD,CAAA;MACD,oCAAA,IAAC,WAAD;OACE,OAAM;OACN,OAAO;OACP,UAAU;OACV,SAAS,CACP;QAAE,OAAO;QAAI,OAAO;OAAa,GACjC,GAAG,OAAO,KAAK,WAAW;QAAE;QAAO,OAAO,MAAM,YAAY;OAAE,EAAE,CAClE;MACD,CAAA;MACD,oCAAA,IAAC,WAAD;OACE,OAAM;OACN,eAAe,QAAQ,YAAY;QACjC,IAAI,YAAY,QAAQ,OAAO,oCAAA,IAAC,QAAD;SAAM,OAAO,OAAO;mBAAQ,OAAO;QAAY,CAAA;QAC9E,MAAM,OAAO,QAAQ,MAAM,SAAS,UAAU,IAAI,MAAM,OAAO,KAAK;QACpE,OACE,oCAAA,KAAC,QAAD;SAAM,WAAU;SAA2B,OAAO,OAAO;mBAAzD;UACE,oCAAA,IAAC,MAAD;WAAM,UAAU,OAAO,eAAe;WAAU,MAAM;UAAK,CAAA;UAC3D,oCAAA,KAAC,QAAD;WAAM,WAAU;qBAAhB,CACE,oCAAA,IAAC,UAAD,EAAA,UAAS,OAAO,KAAK,MAAM,OAAO,QAAQ,aAAa,OAAO,MAAc,CAAA,GAC5E,oCAAA,KAAC,SAAD,EAAA,UAAA,CACG,OAAO,QACJ,eAAe,MAAM,aAAa,OAAO,MAAM,MAAM,EAAE,MACvD,2BACH,MAAM,WAAW,gBAAgB,EAC7B,EAAA,CAAA,CACH;;UACN,oCAAA,IAAC,QAAD;WAAM,WAAU;WAA0B,eAAY;qBACnD,WAAW,OAAO,SAAS,oCAAA,IAAC,MAAD;YAAM,UAAS;YAAQ,MAAM;WAAK,CAAA;UAC1D,CAAA;SACF;;OAEV;OACA,OAAO;OACP,UAAU;OACV,SAAS;QACP;SAAE,OAAO;SAAI,OAAO,gBAAgB,QAAQ,OAAO;QAAG;QACtD,GAAG,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,eAAe;SACzE,OAAO,aAAa;SACpB,OAAO,cAAc;QACvB,EAAE;QACF,GAAG,CAAC,GAAG,IAAI,IAAI,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,WAAW;SAAE;SAAO,OAAO;QAAM,EAAE;OAClF;MACD,CAAA;MACD,oCAAA,KAAC,UAAD;OACE,MAAK;OACL,UAAU,CAAC,QAAQ,UAAU,QAAQ;OACrC,gBAAc;OACd,SAAS;iBAJX;QAME,oCAAA,IAAC,MAAD;SAAM,UAAU,OAAO,UAAU;SAAc,MAAM;QAAK,CAAA;QAAC;QAAE,OAAO,UAAU;OACxE;;MACR,oCAAA,KAAC,UAAD;OAAQ,MAAK;OAAS,gBAAc;OAAQ,eAAe,UAAU,CAAC,MAAM;iBAA5E,CACE,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAwB,MAAM;OAAK,CAAA,GAAC,cAC7C;;MACP,QACC,oCAAA,KAAC,UAAD;OAAQ,eAAe,kBAAkB,SAAS,MAAM;OAAG,MAAK;iBAAhE,CACE,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAO,MAAM;OAAK,CAAA,GAAC,eAC5B;;KAEP;;IACL,oCAAA,KAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,OAAO,GAAG,OAAO,0BAA0B,OAAO,SAAS,eAAe,EAAE,WAAW,OAAO,YAAY,QAAQ;eAHpH;MAKE,oCAAA,KAAC,QAAD,EAAA,UAAA,CAAO,SAAS,OAAO,eAAe,GAAE,iBAAqB,EAAA,CAAA;MAAC;MAAI;MACjE,gBAAgB,OAAO,MAAM,aAAa,OAAO,GAAG,aAAa,MAAM,mBAAmB;MAAG;MAC/E,OAAO,SAAS,eAAe;MAAE;MAAU,OAAO,YAAY;MAAQ;KAClF;;IACL,oCAAA,KAAC,OAAD;KAAK,WAAU;eAAf,CACE,oCAAA,IAAC,SAAD;MACE,SAAS;MACT,UAAU,UAAU;MACpB,UAAU;MACF;MACG;MACF;KACV,CAAA,GACA,YAAY,oCAAA,IAAC,YAAD;MAAY,QAAQ;MAAU,eAAe,YAAY,KAAA,CAAS;KAAI,CAAA,CAChF;;GACL,EAAA,CAAA,IAEF,oCAAA,KAAA,oBAAA,UAAA,EAAA,UAAA;IACE,oCAAA,KAAC,OAAD;KAAK,WAAU;eAAf,CACE,oCAAA,IAAC,WAAD;MACE,OAAM;MACN,YAAY,UAAU;OACpB,IACE,MAAM,QAAQ,YACd,CAAC,MAAM,WACL,MAAM,OAA4B,SAAS,GAAA,CAAI,SAAS,GAE1D;OACF,MAAM,SAAS,SAAS,cACtB,iEACF;OACA,IAAI,UAAU,CAAC,OAAO,UAAU;QAC9B,MAAM,eAAe;QACrB,MAAM,gBAAgB;QACtB,cAAmB,OAAO,QAAQ,aAAc;OAClD;MACF;MACA,eAAe,QAAQ,YAAY;OACjC,MAAM,OAAO,SAAS,MAAM,SAAS,KAAK,OAAO,OAAO,KAAK;OAC7D,IAAI,YAAY,UAAU,CAAC,MAAM,OAAO,OAAO;OAC/C,OACE,oCAAA,KAAC,QAAD;QAAM,WAAU;QAA6B,OAAO,OAAO;kBAA3D,CACE,oCAAA,KAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,oCAAA,IAAC,UAAD,EAAA,UAAS,KAAK,OAAO,KAAa,CAAA,GAClC,oCAAA,KAAC,SAAD,EAAA,UAAA;UACG,kBAAA,eAAe,KAAK,SAAS;UAAE;UAAI,KAAK,KAAK,eAAe;UAAE;UAAS;UACvE,KAAK,MAAM,EAAE,CAAC,YAAY;UAC1B,KAAK,MAAM,MAAM,CAAC;SACd,EAAA,CAAA,CACH;YACN,oCAAA,IAAC,UAAD;SACE,MAAK;SACL,cAAY,mBAAmB,KAAK,OAAO;SAC3C,OAAM;SACN,uBAAqB,KAAK;SAC1B,YAAY,UAAU,MAAM,gBAAgB;SAC5C,UAAU,CAAC,CAAC,WAAW,kBAAkB,gBAAgB,KAAK,KAAK,UAAU;SAC7E,cAAc,UAAU;UACtB,MAAM,eAAe;UACrB,MAAM,gBAAgB;SACxB;SACA,UAAU,UAAU;UAClB,MAAM,eAAe;UACrB,MAAM,gBAAgB;UACtB,cAAmB,KAAK,EAAE;SAC5B;mBAEA,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;UACE,UAAS;UACT,MAAM;UACN,SAAQ;UACR,yBAAA;SACD,CAAA;QACK,CAAA,CACJ;;MAEV;MACA,OAAO;MACP,UAAU,CAAC,CAAC,WAAW,kBAAkB,gBAAgB;MACzD,WAAW,UAAU;OACnB,aAAa,KAAK;OAClB,UAAU,KAAA,CAAS;OACnB,kBAAkB,KAAA,CAAS;OAC3B,kBAAkB,KAAA,CAAS;OAC3B,MAAM,WAAW,SAAS,MAAM,SAAS,KAAK,OAAO,KAAK;OAC1D,IAAI,UAAU;QACZ,OAAO,SAAS,EAAE,CAAC,EAAE;QACrB,SAAc,UAAU,SAAS,EAAE,CAAC,EAAE;OACxC;MACF;MACA,SAAS,CACP;OAAE,OAAO;OAAI,OAAO;MAAoB,GACxC,GAAG,SAAS,KAAK,UAAU;OACzB,OAAO,KAAK;OACZ,OAAO,GAAG,KAAK,OAAO,KAAK,KAAK,kBAAA,eAAe,KAAK,SAAS,EAAE,KAAK,KAAK,KAAK,eAAe,EAAE,WAAW,KAAK,MAAM,EAAE,CAAC,YAAY,IAAI,KAAK,MAAM,MAAM,CAAC;MAC5J,EAAE,CACJ;KACD,CAAA,GACD,oCAAA,KAAC,UAAD;MACE,MAAK;MACL,UAAU,CAAC,aAAa,CAAC,CAAC,WAAW,SAAS,QAAQ,IAAI,SAAS;MACnE,OAAM;MACN,eAAe;OACb,OAAY,OAAO,SAAS,CAAC,CAAC,YAAY,SAAS,0BAA0B,CAAC;MAChF;gBANF,CAQE,oCAAA,IAAC,MAAD;OAAM,UAAS;OAAW,MAAM;MAAK,CAAA,GAAC,cAChC;OACL;;IACJ,CAAC,CAAC,eAAe,MAAM,UACtB,oCAAA,KAAC,WAAD;KAAS,WAAU;eAAnB,CACE,oCAAA,KAAC,WAAD,EAAA,UAAA;MAAS;MAAiB,cAAc,MAAM;MAAO;KAAU,EAAA,CAAA,GAC9D,cAAc,MAAM,KAAK,SACxB,oCAAA,IAAC,OAAD,EAAA,UAAiB,KAAU,GAAjB,IAAiB,CAC5B,CACM;;IAEX,oCAAA,KAAC,OAAD;KAAK,WAAU;eAAf;MACE,oCAAA,IAAC,SAAD;OACE,SAAQ;OACR,OAAO,sBAAsB,OAAO,UAAU,IAAK,OAAO,OAAO,WAAW,eAAe,EAAE;iBAC9F;MAEM,CAAA;MACP,oCAAA,KAAC,UAAD;OACE,MAAK;OACL,UACE,CAAC,iBACD,CAAC,CAAC,WACF,kBACA,SAAS,QAAQ,IAAI,SAAS,KAC9B,cAAc,UAAU;OAE1B,eAAe,KAAK,SAAS;iBAT/B,CAWE,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAa,MAAM;OAAK,CAAA,GAAC,YAClC;;MACP,WACC,oCAAA,KAAC,UAAD;OACE,MAAK;OACL,eAAe;QACb,OAAY,OAAO,OAAO,CAAC,CAAC,YAAY,SAAS,wBAAwB,CAAC;OAC5E;iBAJF,CAME,oCAAA,IAAC,MAAD;QAAM,UAAS;QAAO,MAAM;OAAK,CAAA,GAAC,SAC5B;;MAET,SAAS,KAAK,CAAC,OAAO,WACrB,oCAAA,KAAC,UAAD;OAAQ,MAAK;OAAqB,eAAe,OAAO,KAAK;iBAA7D;QACE,oCAAA,IAAC,MAAD;SACE,UACE,UAAU,WACN,YACA,UAAU,WACR,kBACA,UAAU,aACR,aACA;SAEV,MAAM;QACP,CAAA;QAAE;QAAI;QACD;OACA;SAdmB,KAcnB,CACT;KACE;;IACL,oCAAA,IAAC,YAAD;KACE,MAAM;KACN,IAAG;KACH,OAAO;KACP,WAAW;KACX,WAAW,UAAU,OAAO,MAAM,OAAO,KAAK;KAC9C,YAAY;IACb,CAAA;IACA,SACC,oCAAA,KAAA,oBAAA,UAAA,EAAA,UAAA;KACE,oCAAA,IAAC,OAAD;MAAK,WAAU;gBACb,oCAAA,KAAC,QAAD;OAAM,MAAK;OAAS,WAAU;iBAA9B;QACG,OAAO,KAAK;QAAO;QAAS,OAAO;QAAU;QAAI,OAAO,YAAY,wBAAwB;OACzF;;KACH,CAAA;KACL,oCAAA,KAAC,OAAD;MAAK,WAAU;gBAAf,CACE,oCAAA,KAAC,OAAD;OAAK,WAAU;iBAAf,CACE,oCAAA,KAAC,SAAD;QACE,OAAO,EACL,UACE,OAAO,QAAQ,SAAS,IACpB,OAAO,QAAQ,QAAQ,OAAO,WAAW,QAAQ,eAAe,MAAM,GAAG,CAAC,IAC1E,KAAA,EACR;kBANF;SAQE,oCAAA,IAAC,YAAD,EAAA,UACG,OAAO,QAAQ,KAAK,QAAQ,MAC3B,oCAAA,IAAC,OAAD,EAEE,OAAO,EACL,OAAO,OAAO,QAAQ,SAAS,IAAI,eAAe,MAAM,IAAI,KAAA,EAC9D,EACD,GAJM,CAIN,CACF,EACO,CAAA;SACV,oCAAA,IAAC,SAAD,EAAA,UACE,oCAAA,IAAC,MAAD,EAAA,UACG,OAAO,QAAQ,KAAK,QAAQ,MAC3B,oCAAA,IAAC,MAAD;UAAY,eAAa;oBACtB;SACC,GAFK,CAEL,CACL,EACC,CAAA,EACC,CAAA;SACP,oCAAA,IAAC,SAAD,EAAA,UACG,OAAO,KAAK,MAAM,aAAa,KAAK,aAAa,KAAK,EAAE,CAAC,CAAC,KAAK,KAAK,MACnE,oCAAA,IAAC,MAAD;UAEE,UAAU;UACV,cAAY,gBAAgB,aAAa,KAAK,IAAI;UAClD,eAAe,kBAAkB;WAAE,GAAG,2BAAA,cAAc,OAAO,SAAS,GAAG;WAAG;UAAI,CAAC;UAC/E,YAAY,UAAU;WACpB,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;YAC9C,MAAM,eAAe;YACrB,kBAAkB;aAAE,GAAG,2BAAA,cAAc,OAAO,SAAS,GAAG;aAAG;YAAI,CAAC;WAClE;UACF;oBAEC,IAAI,KAAK,MAAM,MACd,oCAAA,IAAC,MAAD;WAEE,eAAa,OAAO,QAAQ;WAC5B,cAAY,OAAO,QAAQ,OAAO,UAAU,OAAO,IAAI,IAAI,KAAA;qBAE3D,oCAAA,IAAC,QAAD;YAAM,WAAU;YAAkB,OAAO,SAAS,OAAO,SAAS,OAAO,IAAI;sBAC1E,SAAS,OAAO,SAAS,OAAO,IAAI;WACjC,CAAA;UACJ,GAPG,CAOH,CACL;SACC,GAtBG,CAsBH,CACL,EACI,CAAA;QACF;WACN,OAAO,KAAK,WAAW,KACtB,oCAAA,IAAC,OAAD;QAAK,WAAU;kBACZ,eAAe,SAAS,IACrB,sEACA;OACD,CAAA,CAEJ;UACJ,kBACC,oCAAA,IAAC,YAAD;OACE,QAAQ,eAAe;OACvB,YAAY,eAAe;OAC3B,eAAe,kBAAkB,KAAA,CAAS;MAC3C,CAAA,CAEA;;KACJ,OAAO,KAAK,SAAS,MACpB,oCAAA,KAAC,OAAD;MAAK,WAAU;MAA2C,cAAW;gBAArE;OACE,oCAAA,IAAC,UAAD;QACE,MAAK;QACL,cAAW;QACX,OAAM;QACN,UAAU,eAAe;QACzB,eAAe;SACb,cAAc,aAAa,CAAC;SAC5B,kBAAkB,KAAA,CAAS;QAC7B;kBAEA,oCAAA,IAAC,MAAD;SAAM,UAAS;SAAe,MAAM;QAAK,CAAA;OACnC,CAAA;OACR,oCAAA,KAAC,QAAD;QAAM,WAAU;kBAAhB;SAAmC;SAC3B,aAAa;SAAE;SAAI,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,KAAK,SAAS,EAAE,CAAC;QACnE;;OACN,oCAAA,IAAC,UAAD;QACE,MAAK;QACL,cAAW;QACX,OAAM;QACN,WAAW,aAAa,KAAK,MAAM,OAAO,KAAK;QAC/C,eAAe;SACb,cAAc,aAAa,CAAC;SAC5B,kBAAkB,KAAA,CAAS;QAC7B;kBAEA,oCAAA,IAAC,MAAD;SAAM,UAAS;SAAgB,MAAM;QAAK,CAAA;OACpC,CAAA;MACL;;IAEP,EAAA,CAAA,IAEF,oCAAA,IAAC,OAAD;KAAK,WAAU;eACZ,UACG,mBACA,SAAS,WAAW,IAClB,yDACA;IACH,CAAA;GAEP,EAAA,CAAA;GAEJ,oCAAA,KAAC,OAAD;IAAK,WAAU;cAAf,CACE,oCAAA,KAAC,QAAD;KACE,WAAU;KACV,OAAO,sBAAsB,OAAO,kBAAkB,eAAe,OAAO,iBAAiB,QAAQ,oBAAoB,OAAO,mBAAmB,eAAe,EAAE,WAAW,OAAO,qBAAqB,QAAQ,mBAAmB,OAAO,eAAe,QAAQ,oBAAoB,OAAO,SAAS,0BAA0B,OAAO,QAAQ,IAAM;eAFzV;MAGC;MACsB,OAAO;MAAkB;MAAe,OAAO,iBAAiB;MAAQ;MACjF,OAAO,mBAAmB,eAAe;MAAE;MAAU,OAAO,qBAAqB;MAAQ;MACzF,OAAO,eAAe;MAAQ;MAAoB,OAAO;MAAS;MACzE,OAAO,QAAQ;MAAM;KACtB;QACL,gBAAgB,SAAS,KACxB,oCAAA,KAAC,QAAD;KAAM,MAAK;KAAO,WAAU;KAA+C,OAAO,gBAAgB,KAAK,IAAI;eAA3G,CACE,oCAAA,IAAC,MAAD;MAAM,UAAS;MAAgB,MAAM;KAAK,CAAA,GAC1C,oCAAA,IAAC,QAAD,EAAA,UAAO,gBAAgB,KAAK,KAAK,EAAQ,CAAA,CACrC;MAEL;;EACF;;AAET;AAEA,IAAM,oBAAoB,oCAAA,SAAS,SAAS;AAE5C,IAAa,gBAAgB,oCAAA,eAAe;CAC1C,MAAM,UAAU,+BAAA,qBAAqB,oBAA0C,CAAC,CAAC;CACjF,MAAM,YAAY,mBAAA,SAAS,QAAQ,cAAc,IAAI,CAAC,EAAE,SAAS;CACjE,IAAI,CAAC,WAAW,CAAC,WACf,OACE,oCAAA,KAAC,OAAD;EAAK,WAAU;YAAf;GACE,oCAAA,IAAC,SAAD,EAAA,UAAQ,uBAAA,gBAAuB,CAAA;GAC/B,oCAAA,IAAC,MAAD,EAAA,UAAI,aAAc,CAAA;GAClB,oCAAA,IAAC,KAAD,EAAA,UAAG,uEAAuE,CAAA;EACvE;;CAET,MAAM,YAAY,+BAAA,gBAAgB;CAClC,OAAO,oCAAA,IAAC,mBAAD;EAAgE;EAAsB;CAAY,GAA1E,GAAG,UAAU,GAAG,WAA0D;AAC3G,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const require_extensions = require("../_virtual/_global-external_@freelensapp/extensions.js");
|
|
2
|
+
const require__global_external_mobx_react = require("../_virtual/_global-external_mobx-react.js");
|
|
3
|
+
const require_power_logs = require("../src/common/power-logs.js");
|
|
4
|
+
const require_power_logs_limits = require("../src/common/power-logs-limits.js");
|
|
5
|
+
const require_logs_preferences_store = require("../src/common/store/logs-preferences-store.js");
|
|
6
|
+
const require__global_external_react = require("../_virtual/_global-external_react.js");
|
|
7
|
+
const require_jsx_runtime = require("../_virtual/_global-external_react/jsx-runtime.js");
|
|
8
|
+
//#region src/renderer/preferences/logs-preferences.tsx
|
|
9
|
+
var LogLimitInput = require__global_external_mobx_react.observer(function LogLimitInput({ field, preferences }) {
|
|
10
|
+
const scale = field.scale ?? 1;
|
|
11
|
+
const value = preferences.limits[field.key];
|
|
12
|
+
const [draft, setDraft] = require__global_external_react.useState(String(value / scale));
|
|
13
|
+
require__global_external_react.useEffect(() => setDraft(String(value / scale)), [value, scale]);
|
|
14
|
+
const commit = () => {
|
|
15
|
+
const next = draft.trim() === "" ? value : Number(draft) * scale;
|
|
16
|
+
preferences.limits = require_power_logs_limits.normalizePowerLogsLimits({
|
|
17
|
+
...preferences.limits,
|
|
18
|
+
[field.key]: Number.isFinite(next) ? next : value
|
|
19
|
+
});
|
|
20
|
+
require_power_logs_limits.applyPowerLogsLimits(preferences.limits);
|
|
21
|
+
setDraft(String(preferences.limits[field.key] / scale));
|
|
22
|
+
};
|
|
23
|
+
return /* @__PURE__ */ require_jsx_runtime.jsxs("label", {
|
|
24
|
+
className: "power-log-limit",
|
|
25
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: field.label }), /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
26
|
+
className: "power-log-limit-value",
|
|
27
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Input, {
|
|
28
|
+
"aria-label": `${field.group}: ${field.label}`,
|
|
29
|
+
type: "number",
|
|
30
|
+
value: draft,
|
|
31
|
+
min: field.min / scale,
|
|
32
|
+
max: field.max / scale,
|
|
33
|
+
step: "any",
|
|
34
|
+
onChange: setDraft,
|
|
35
|
+
onBlur: commit,
|
|
36
|
+
onSubmit: commit
|
|
37
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: field.unit })]
|
|
38
|
+
})]
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
var LogsPreferences = require__global_external_mobx_react.observer(() => {
|
|
42
|
+
const preferences = require_logs_preferences_store.LogsPreferencesStore.getInstanceOrCreate();
|
|
43
|
+
return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
44
|
+
style: {
|
|
45
|
+
display: "grid",
|
|
46
|
+
gap: 20
|
|
47
|
+
},
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Switch, {
|
|
50
|
+
checked: preferences.enabled,
|
|
51
|
+
onChange: (value) => {
|
|
52
|
+
preferences.enabled = value;
|
|
53
|
+
},
|
|
54
|
+
children: "Use Power Logs"
|
|
55
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
56
|
+
className: "power-settings-hint",
|
|
57
|
+
children: "Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled. Temporary captures follow the retention settings below and are deleted when Power Logs stops."
|
|
58
|
+
})] }),
|
|
59
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: `.power-log-limit-groups{display:grid;gap:20px}.power-log-limit-groups fieldset{min-width:0;border:1px solid var(--borderFaintColor);border-radius:6px;padding:16px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px}.power-log-limit-groups legend{padding:0 6px;color:var(--textColorAccent)}.power-log-limit{display:flex;flex-direction:column;gap:6px;min-width:0}.power-log-limit-value{display:flex;align-items:center;gap:8px;color:var(--textColorSecondary);font-size:12px}.power-log-limit-value .Input{min-width:0;flex:1}.power-log-limit-value input{width:100%;min-width:0}@container power-preferences(max-width:480px){.power-log-limit-groups fieldset{grid-template-columns:1fr}}` }),
|
|
60
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
61
|
+
className: "power-settings-hint",
|
|
62
|
+
children: "Changes apply to new requests, captures and SQL queries. Existing captures retain their capacity and expiry."
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
65
|
+
className: "power-log-limit-groups",
|
|
66
|
+
children: [...new Set(require_power_logs_limits.LOG_LIMIT_FIELDS.map((field) => field.group))].map((group) => /* @__PURE__ */ require_jsx_runtime.jsxs("fieldset", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("legend", { children: group }), require_power_logs_limits.LOG_LIMIT_FIELDS.filter((field) => field.group === group).map((field) => /* @__PURE__ */ require_jsx_runtime.jsx(LogLimitInput, {
|
|
67
|
+
field,
|
|
68
|
+
preferences
|
|
69
|
+
}, field.key))] }, group))
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
72
|
+
style: {
|
|
73
|
+
display: "flex",
|
|
74
|
+
justifyContent: "flex-end"
|
|
75
|
+
},
|
|
76
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs(require_extensions.Renderer.Component.Button, {
|
|
77
|
+
onClick: () => {
|
|
78
|
+
preferences.limits = { ...require_power_logs.POWER_LOGS_DEFAULT_LIMITS };
|
|
79
|
+
require_power_logs_limits.applyPowerLogsLimits(preferences.limits);
|
|
80
|
+
},
|
|
81
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
|
|
82
|
+
material: "restore",
|
|
83
|
+
size: 16
|
|
84
|
+
}), " Reset log limits"]
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
//#endregion
|
|
91
|
+
exports.LogsPreferences = LogsPreferences;
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=logs-preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs-preferences.js","names":[],"sources":["../../../src/renderer/preferences/logs-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { POWER_LOGS_DEFAULT_LIMITS } from \"../../common/power-logs\";\nimport {\n applyPowerLogsLimits,\n LOG_LIMIT_FIELDS,\n type LogLimitField,\n normalizePowerLogsLimits,\n} from \"../../common/power-logs-limits\";\nimport { LogsPreferencesStore } from \"../../common/store/logs-preferences-store\";\n\nconst LogLimitInput = observer(function LogLimitInput({\n field,\n preferences,\n}: {\n field: LogLimitField;\n preferences: LogsPreferencesStore;\n}) {\n const scale = field.scale ?? 1;\n const value = preferences.limits[field.key];\n const [draft, setDraft] = useState(String(value / scale));\n useEffect(() => setDraft(String(value / scale)), [value, scale]);\n const commit = () => {\n const next = draft.trim() === \"\" ? value : Number(draft) * scale;\n preferences.limits = normalizePowerLogsLimits({\n ...preferences.limits,\n [field.key]: Number.isFinite(next) ? next : value,\n });\n applyPowerLogsLimits(preferences.limits);\n setDraft(String(preferences.limits[field.key] / scale));\n };\n return (\n <label className=\"power-log-limit\">\n <span>{field.label}</span>\n <span className=\"power-log-limit-value\">\n <Renderer.Component.Input\n aria-label={`${field.group}: ${field.label}`}\n type=\"number\"\n value={draft}\n min={field.min / scale}\n max={field.max / scale}\n step=\"any\"\n onChange={setDraft}\n onBlur={commit}\n onSubmit={commit}\n />\n <span>{field.unit}</span>\n </span>\n </label>\n );\n});\n\nexport const LogsPreferences = observer(() => {\n const preferences = LogsPreferencesStore.getInstanceOrCreate<LogsPreferencesStore>();\n return (\n <div style={{ display: \"grid\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Use Power Logs\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled.\n Temporary captures follow the retention settings below and are deleted when Power Logs stops.\n </div>\n </div>\n <style>{`.power-log-limit-groups{display:grid;gap:20px}.power-log-limit-groups fieldset{min-width:0;border:1px solid var(--borderFaintColor);border-radius:6px;padding:16px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px}.power-log-limit-groups legend{padding:0 6px;color:var(--textColorAccent)}.power-log-limit{display:flex;flex-direction:column;gap:6px;min-width:0}.power-log-limit-value{display:flex;align-items:center;gap:8px;color:var(--textColorSecondary);font-size:12px}.power-log-limit-value .Input{min-width:0;flex:1}.power-log-limit-value input{width:100%;min-width:0}@container power-preferences(max-width:480px){.power-log-limit-groups fieldset{grid-template-columns:1fr}}`}</style>\n <div className=\"power-settings-hint\">\n Changes apply to new requests, captures and SQL queries. Existing captures retain their capacity and expiry.\n </div>\n <div className=\"power-log-limit-groups\">\n {[...new Set(LOG_LIMIT_FIELDS.map((field) => field.group))].map((group) => (\n <fieldset key={group}>\n <legend>{group}</legend>\n {LOG_LIMIT_FIELDS.filter((field) => field.group === group).map((field) => (\n <LogLimitInput key={field.key} field={field} preferences={preferences} />\n ))}\n </fieldset>\n ))}\n </div>\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <Renderer.Component.Button\n onClick={() => {\n preferences.limits = { ...POWER_LOGS_DEFAULT_LIMITS };\n applyPowerLogsLimits(preferences.limits);\n }}\n >\n <Renderer.Component.Icon material=\"restore\" size={16} /> Reset log limits\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":";;;;;;;;AAYA,IAAM,gBAAgB,oCAAA,SAAS,SAAS,cAAc,EACpD,OACA,eAIC;CACD,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,QAAQ,YAAY,OAAO,MAAM;CACvC,MAAM,CAAC,OAAO,YAAY,+BAAA,SAAS,OAAO,QAAQ,KAAK,CAAC;CACxD,+BAAA,gBAAgB,SAAS,OAAO,QAAQ,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC;CAC/D,MAAM,eAAe;EACnB,MAAM,OAAO,MAAM,KAAK,MAAM,KAAK,QAAQ,OAAO,KAAK,IAAI;EAC3D,YAAY,SAAS,0BAAA,yBAAyB;GAC5C,GAAG,YAAY;IACd,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,OAAO;EAC9C,CAAC;EACD,0BAAA,qBAAqB,YAAY,MAAM;EACvC,SAAS,OAAO,YAAY,OAAO,MAAM,OAAO,KAAK,CAAC;CACxD;CACA,OACE,oCAAA,KAAC,SAAD;EAAO,WAAU;YAAjB,CACE,oCAAA,IAAC,QAAD,EAAA,UAAO,MAAM,MAAY,CAAA,GACzB,oCAAA,KAAC,QAAD;GAAM,WAAU;aAAhB,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,OAApB;IACE,cAAY,GAAG,MAAM,MAAM,IAAI,MAAM;IACrC,MAAK;IACL,OAAO;IACP,KAAK,MAAM,MAAM;IACjB,KAAK,MAAM,MAAM;IACjB,MAAK;IACL,UAAU;IACV,QAAQ;IACR,UAAU;GACX,CAAA,GACD,oCAAA,IAAC,QAAD,EAAA,UAAO,MAAM,KAAW,CAAA,CACpB;IACD;;AAEX,CAAC;AAED,IAAa,kBAAkB,oCAAA,eAAe;CAC5C,MAAM,cAAc,+BAAA,qBAAqB,oBAA0C;CACnF,OACE,oCAAA,KAAC,OAAD;EAAK,OAAO;GAAE,SAAS;GAAQ,KAAK;EAAG;YAAvC;GACE,oCAAA,KAAC,OAAD,EAAA,UAAA,CACE,oCAAA,IAAC,mBAAA,SAAS,UAAU,QAApB;IACE,SAAS,YAAY;IACrB,WAAW,UAAU;KACnB,YAAY,UAAU;IACxB;cACD;GAE0B,CAAA,GAC3B,oCAAA,IAAC,OAAD;IAAK,WAAU;cAAsB;GAGhC,CAAA,CACF,EAAA,CAAA;GACL,oCAAA,IAAC,SAAD,EAAA,UAAQ,8rBAAqsB,CAAA;GAC7sB,oCAAA,IAAC,OAAD;IAAK,WAAU;cAAsB;GAEhC,CAAA;GACL,oCAAA,IAAC,OAAD;IAAK,WAAU;cACZ,CAAC,GAAG,IAAI,IAAI,0BAAA,iBAAiB,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,UAC/D,oCAAA,KAAC,YAAD,EAAA,UAAA,CACE,oCAAA,IAAC,UAAD,EAAA,UAAS,MAAc,CAAA,GACtB,0BAAA,iBAAiB,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC,CAAC,KAAK,UAC9D,oCAAA,IAAC,eAAD;KAAsC;KAAoB;IAAc,GAApD,MAAM,GAA8C,CACzE,CACO,EAAA,GALK,KAKL,CACX;GACE,CAAA;GACL,oCAAA,IAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,gBAAgB;IAAW;cACxD,oCAAA,KAAC,mBAAA,SAAS,UAAU,QAApB;KACE,eAAe;MACb,YAAY,SAAS,EAAE,GAAG,mBAAA,0BAA0B;MACpD,0BAAA,qBAAqB,YAAY,MAAM;KACzC;eAJF,CAME,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;MAAyB,UAAS;MAAU,MAAM;KAAK,CAAA,GAAC,mBAC/B;;GACxB,CAAA;EACF;;AAET,CAAC"}
|
|
@@ -46,6 +46,16 @@ var MonitoringPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
46
46
|
className: "power-settings-hint",
|
|
47
47
|
children: "Focused resource connections from API evidence, with links to related objects."
|
|
48
48
|
})] }),
|
|
49
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Switch, {
|
|
50
|
+
checked: preferences.resourceSearchEnabled,
|
|
51
|
+
onChange: (value) => {
|
|
52
|
+
preferences.resourceSearchEnabled = value;
|
|
53
|
+
},
|
|
54
|
+
children: "Enable resource search (Shift–Shift)"
|
|
55
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
56
|
+
className: "power-settings-hint",
|
|
57
|
+
children: "Search resources with Shift–Shift. Turning this off stops keyboard search and background indexing."
|
|
58
|
+
})] }),
|
|
49
59
|
/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Switch, {
|
|
50
60
|
checked: preferences.enabled,
|
|
51
61
|
onChange: (value) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitoring-preferences.js","names":[],"sources":["../../../src/renderer/preferences/monitoring-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { HISTORY_MAX_BYTES, type HistoryStatus } from \"../../common/monitoring-history\";\nimport { MonitoringPreferencesStore } from \"../../common/store/monitoring-preferences-store\";\nimport { monitoringHistory } from \"../monitoring-history\";\n\nexport const MonitoringPreferences = observer(() => {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const [status, setStatus] = useState<HistoryStatus>();\n const refresh = () => {\n void monitoringHistory\n .status()\n .then(setStatus)\n .catch(() =>\n setStatus({\n available: false,\n enabled: preferences.historyEnabled,\n bytes: 0,\n samples: 0,\n error: \"History service unavailable\",\n }),\n );\n };\n useEffect(refresh, [preferences.historyEnabled]);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.diagnosticsVisible}\n onChange={(value) => {\n preferences.diagnosticsVisible = value;\n }}\n >\n Show Diagnostics in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">Resource consumers, application events and Pending diagnostics.</div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.relationshipsVisible}\n onChange={(value) => {\n preferences.relationshipsVisible = value;\n }}\n >\n Show Relationships in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Focused resource connections from API evidence, with links to related objects.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Metrics-server monitoring\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n CPU/RAM charts for clusters, nodes and pods. Keeps 30 minutes of live samples.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.historyEnabled}\n onChange={(value) => {\n preferences.historyEnabled = value;\n }}\n >\n Keep local history\n </Renderer.Component.Switch>\n <div\n className=\"power-settings-hint\"\n title=\"SQLite storage. Collects while the cluster view is active. Resolution: 30 seconds for 2 hours, 5 minutes for 24 hours, 30 minutes for 7 days. Disabling preserves saved history.\"\n >\n Up to 7 days, limited to 100 MiB.\n </div>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ flex: 1, minWidth: 0 }} role=\"status\">\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"baseline\", gap: 12 }}>\n <span>Local storage</span>\n <span style={{ fontVariantNumeric: \"tabular-nums\", color: \"var(--textColorSecondary)\" }}>\n {status?.available\n ? `${(status.bytes / 1024 / 1024).toFixed(2)} / ${HISTORY_MAX_BYTES / 1024 / 1024} MiB`\n : \"— / 100 MiB\"}\n </span>\n </div>\n {status?.available && (\n <div\n role=\"progressbar\"\n aria-label=\"Local history storage\"\n aria-valuemin={0}\n aria-valuemax={HISTORY_MAX_BYTES}\n aria-valuenow={status.bytes}\n aria-valuetext={`${(status.bytes / 1024 / 1024).toFixed(2)} of 100 MiB`}\n style={{ height: 4, marginTop: 8, borderRadius: 2, overflow: \"hidden\", background: \"var(--borderColor)\" }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, (status.bytes / HISTORY_MAX_BYTES) * 100))}%`,\n background: \"var(--primary)\",\n transition: \"width 180ms ease\",\n }}\n />\n </div>\n )}\n <div className=\"power-settings-hint\" style={{ marginTop: 6 }}>\n {status?.error ??\n (status?.available\n ? `${status.samples.toLocaleString()} metric buckets · 7-day retention`\n : \"Checking history storage…\")}\n </div>\n </div>\n <Renderer.Component.Button\n style={{\n flexShrink: 0,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 6,\n height: 30,\n padding: \"0 10px\",\n fontSize: 12,\n lineHeight: \"16px\",\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n background: \"var(--contentColor)\",\n color: \"var(--textColorSecondary)\",\n }}\n title=\"Delete locally collected metric history without changing other settings\"\n onClick={() => {\n void monitoringHistory\n .clear()\n .then(refresh)\n .catch(() =>\n setStatus((previous) => ({\n available: previous?.available ?? false,\n enabled: preferences.historyEnabled,\n bytes: previous?.bytes ?? 0,\n samples: previous?.samples ?? 0,\n error: \"Unable to clear local history. Try again.\",\n })),\n );\n }}\n >\n <Renderer.Component.Icon material=\"delete_outline\" size={14} />\n <span>Clear</span>\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"monitoring-preferences.js","names":[],"sources":["../../../src/renderer/preferences/monitoring-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { HISTORY_MAX_BYTES, type HistoryStatus } from \"../../common/monitoring-history\";\nimport { MonitoringPreferencesStore } from \"../../common/store/monitoring-preferences-store\";\nimport { monitoringHistory } from \"../monitoring-history\";\n\nexport const MonitoringPreferences = observer(() => {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const [status, setStatus] = useState<HistoryStatus>();\n const refresh = () => {\n void monitoringHistory\n .status()\n .then(setStatus)\n .catch(() =>\n setStatus({\n available: false,\n enabled: preferences.historyEnabled,\n bytes: 0,\n samples: 0,\n error: \"History service unavailable\",\n }),\n );\n };\n useEffect(refresh, [preferences.historyEnabled]);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.diagnosticsVisible}\n onChange={(value) => {\n preferences.diagnosticsVisible = value;\n }}\n >\n Show Diagnostics in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">Resource consumers, application events and Pending diagnostics.</div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.relationshipsVisible}\n onChange={(value) => {\n preferences.relationshipsVisible = value;\n }}\n >\n Show Relationships in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Focused resource connections from API evidence, with links to related objects.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.resourceSearchEnabled}\n onChange={(value) => {\n preferences.resourceSearchEnabled = value;\n }}\n >\n Enable resource search (Shift–Shift)\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Search resources with Shift–Shift. Turning this off stops keyboard search and background indexing.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Metrics-server monitoring\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n CPU/RAM charts for clusters, nodes and pods. Keeps 30 minutes of live samples.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.historyEnabled}\n onChange={(value) => {\n preferences.historyEnabled = value;\n }}\n >\n Keep local history\n </Renderer.Component.Switch>\n <div\n className=\"power-settings-hint\"\n title=\"SQLite storage. Collects while the cluster view is active. Resolution: 30 seconds for 2 hours, 5 minutes for 24 hours, 30 minutes for 7 days. Disabling preserves saved history.\"\n >\n Up to 7 days, limited to 100 MiB.\n </div>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ flex: 1, minWidth: 0 }} role=\"status\">\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"baseline\", gap: 12 }}>\n <span>Local storage</span>\n <span style={{ fontVariantNumeric: \"tabular-nums\", color: \"var(--textColorSecondary)\" }}>\n {status?.available\n ? `${(status.bytes / 1024 / 1024).toFixed(2)} / ${HISTORY_MAX_BYTES / 1024 / 1024} MiB`\n : \"— / 100 MiB\"}\n </span>\n </div>\n {status?.available && (\n <div\n role=\"progressbar\"\n aria-label=\"Local history storage\"\n aria-valuemin={0}\n aria-valuemax={HISTORY_MAX_BYTES}\n aria-valuenow={status.bytes}\n aria-valuetext={`${(status.bytes / 1024 / 1024).toFixed(2)} of 100 MiB`}\n style={{ height: 4, marginTop: 8, borderRadius: 2, overflow: \"hidden\", background: \"var(--borderColor)\" }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, (status.bytes / HISTORY_MAX_BYTES) * 100))}%`,\n background: \"var(--primary)\",\n transition: \"width 180ms ease\",\n }}\n />\n </div>\n )}\n <div className=\"power-settings-hint\" style={{ marginTop: 6 }}>\n {status?.error ??\n (status?.available\n ? `${status.samples.toLocaleString()} metric buckets · 7-day retention`\n : \"Checking history storage…\")}\n </div>\n </div>\n <Renderer.Component.Button\n style={{\n flexShrink: 0,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 6,\n height: 30,\n padding: \"0 10px\",\n fontSize: 12,\n lineHeight: \"16px\",\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n background: \"var(--contentColor)\",\n color: \"var(--textColorSecondary)\",\n }}\n title=\"Delete locally collected metric history without changing other settings\"\n onClick={() => {\n void monitoringHistory\n .clear()\n .then(refresh)\n .catch(() =>\n setStatus((previous) => ({\n available: previous?.available ?? false,\n enabled: preferences.historyEnabled,\n bytes: previous?.bytes ?? 0,\n samples: previous?.samples ?? 0,\n error: \"Unable to clear local history. Try again.\",\n })),\n );\n }}\n >\n <Renderer.Component.Icon material=\"delete_outline\" size={14} />\n <span>Clear</span>\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ const require_jsx_runtime = require("../_virtual/_global-external_react/jsx-runt
|
|
|
4
4
|
const require_ai_preferences = require("./ai-preferences.js");
|
|
5
5
|
const require_appearance_preferences = require("./appearance-preferences.js");
|
|
6
6
|
const require_dashboard_preferences = require("./dashboard-preferences.js");
|
|
7
|
+
const require_logs_preferences = require("./logs-preferences.js");
|
|
7
8
|
const require_monitoring_preferences = require("./monitoring-preferences.js");
|
|
8
9
|
const require_node_shell_preferences = require("./node-shell-preferences.js");
|
|
9
10
|
const require_power_preferences = require("./power-preferences.js");
|
|
@@ -16,13 +17,13 @@ var styles = `
|
|
|
16
17
|
#freelens-power-settings > .SubTitle,
|
|
17
18
|
#freelens-power-settings > .hint,
|
|
18
19
|
#freelens-power-settings + hr { display: none; }
|
|
19
|
-
.freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; }
|
|
20
|
+
.freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; container: power-preferences / inline-size; }
|
|
20
21
|
.freelens-power-preferences .power-preferences-section-links {
|
|
21
|
-
display:
|
|
22
|
+
display:flex; align-items:center; width:100%; gap:8px; overflow-x:auto;
|
|
22
23
|
}
|
|
23
24
|
:root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link {
|
|
24
25
|
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
25
|
-
width:
|
|
26
|
+
flex:1 0 auto; width:auto; min-width:max-content; min-height:32px; padding:4px 2px;
|
|
26
27
|
border: 0; border-radius: 4px; background: transparent; box-shadow: none;
|
|
27
28
|
color: var(--textColorSecondary); text-transform: none; white-space: nowrap; cursor: pointer;
|
|
28
29
|
}
|
|
@@ -36,12 +37,7 @@ var styles = `
|
|
|
36
37
|
color: var(--primary); background: transparent; box-shadow: none;
|
|
37
38
|
outline: 2px solid var(--primary); outline-offset: 2px;
|
|
38
39
|
}
|
|
39
|
-
@
|
|
40
|
-
.freelens-power-preferences .power-preferences-section-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
41
|
-
}
|
|
42
|
-
@media (max-width: 360px) {
|
|
43
|
-
.freelens-power-preferences .power-preferences-section-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
44
|
-
}
|
|
40
|
+
@container power-preferences (max-width:660px) { .power-preferences-section-links { font-size:12px; } }
|
|
45
41
|
.freelens-power-preferences section[id] { scroll-margin-top: 16px; }
|
|
46
42
|
.freelens-power-preferences section {
|
|
47
43
|
padding: 24px; border: 1px solid var(--borderFaintColor);
|
|
@@ -93,9 +89,14 @@ var sectionLinks = [
|
|
|
93
89
|
title: "Monitoring",
|
|
94
90
|
icon: "show_chart"
|
|
95
91
|
},
|
|
92
|
+
{
|
|
93
|
+
id: "logs",
|
|
94
|
+
title: "Logs",
|
|
95
|
+
icon: "subject"
|
|
96
|
+
},
|
|
96
97
|
{
|
|
97
98
|
id: "shell",
|
|
98
|
-
title: "
|
|
99
|
+
title: "Shell",
|
|
99
100
|
icon: "vpn_key"
|
|
100
101
|
},
|
|
101
102
|
{
|
|
@@ -123,6 +124,7 @@ var PowerPreferences = () => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
|
123
124
|
"aria-label": "Settings sections",
|
|
124
125
|
children: sectionLinks.map(({ id, title, icon }) => /* @__PURE__ */ require_jsx_runtime.jsxs(require_extensions.Renderer.Component.Button, {
|
|
125
126
|
className: "power-settings-section-link",
|
|
127
|
+
"aria-label": title,
|
|
126
128
|
title: `Jump to ${title} settings`,
|
|
127
129
|
onClick: (event) => {
|
|
128
130
|
event.preventDefault();
|
|
@@ -205,6 +207,18 @@ var PowerPreferences = () => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
|
205
207
|
}), " Monitoring"]
|
|
206
208
|
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_monitoring_preferences.MonitoringPreferences, {})]
|
|
207
209
|
}),
|
|
210
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("section", {
|
|
211
|
+
id: "freelens-power-logs-section",
|
|
212
|
+
tabIndex: -1,
|
|
213
|
+
"aria-labelledby": "freelens-power-logs-title",
|
|
214
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsxs("h3", {
|
|
215
|
+
id: "freelens-power-logs-title",
|
|
216
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
|
|
217
|
+
material: "subject",
|
|
218
|
+
size: 20
|
|
219
|
+
}), " Power Logs"]
|
|
220
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_logs_preferences.LogsPreferences, {})]
|
|
221
|
+
}),
|
|
208
222
|
/* @__PURE__ */ require_jsx_runtime.jsxs("section", {
|
|
209
223
|
id: "freelens-power-shell-section",
|
|
210
224
|
tabIndex: -1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { EXTENSION_ID } from \"../../common/extension-info\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; }\n .freelens-power-preferences .power-preferences-section-links {\n display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); width: 100%; gap: 8px;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n width: 100%; min-width: 0; min-height: 32px; padding: 4px 2px;\n border: 0; border-radius: 4px; background: transparent; box-shadow: none;\n color: var(--textColorSecondary); text-transform: none; white-space: nowrap; cursor: pointer;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:hover {\n color: var(--primary); background: transparent; box-shadow: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link::before {\n content: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:focus-visible {\n color: var(--primary); background: transparent; box-shadow: none;\n outline: 2px solid var(--primary); outline-offset: 2px;\n }\n @media (max-width: 600px) {\n .freelens-power-preferences .power-preferences-section-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n }\n @media (max-width: 360px) {\n .freelens-power-preferences .power-preferences-section-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n }\n .freelens-power-preferences section[id] { scroll-margin-top: 16px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nconst sectionLinks = [\n { id: \"safety\", title: \"Safety\", icon: \"lock_outline\" },\n { id: \"appearance\", title: \"Appearance\", icon: \"palette\" },\n { id: \"monitoring\", title: \"Monitoring\", icon: \"show_chart\" },\n { id: \"shell\", title: \"Node shell\", icon: \"vpn_key\" },\n { id: \"ai\", title: \"AI\", icon: \"chat_bubble_outline\" },\n { id: \"dashboard\", title: \"Dashboard\", icon: \"dashboard\" },\n];\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <nav className=\"power-preferences-section-links\" aria-label=\"Settings sections\">\n {sectionLinks.map(({ id, title, icon }) => (\n <Renderer.Component.Button\n key={id}\n className=\"power-settings-section-link\"\n title={`Jump to ${title} settings`}\n onClick={(event) => {\n event.preventDefault();\n const section = document.getElementById(`freelens-power-${id}-section`);\n requestAnimationFrame(() => {\n if (!section?.isConnected) return;\n section.focus({ preventScroll: true });\n section.scrollIntoView({ block: \"start\", behavior: \"instant\" });\n });\n }}\n >\n <Renderer.Component.Icon material={icon} size={16} /> {title}\n </Renderer.Component.Button>\n ))}\n </nav>\n <section id=\"freelens-power-safety-section\" tabIndex={-1} aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section id=\"freelens-power-appearance-section\" tabIndex={-1} aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", marginTop: 20 }}>\n <Renderer.Component.Button\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => Renderer.Navigation.navigate(`/extension/${EXTENSION_ID}/cluster-icons`)}\n title=\"Create matching icons for your saved clusters\"\n >\n <Renderer.Component.Icon material=\"palette\" size={16} /> Cluster icons\n </Renderer.Component.Button>\n </div>\n </section>\n <section id=\"freelens-power-monitoring-section\" tabIndex={-1} aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section id=\"freelens-power-shell-section\" tabIndex={-1} aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section id=\"freelens-power-ai-section\" tabIndex={-1} aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section id=\"freelens-power-dashboard-section\" tabIndex={-1} aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { EXTENSION_ID } from \"../../common/extension-info\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { LogsPreferences } from \"./logs-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; container: power-preferences / inline-size; }\n .freelens-power-preferences .power-preferences-section-links {\n display:flex; align-items:center; width:100%; gap:8px; overflow-x:auto;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n flex:1 0 auto; width:auto; min-width:max-content; min-height:32px; padding:4px 2px;\n border: 0; border-radius: 4px; background: transparent; box-shadow: none;\n color: var(--textColorSecondary); text-transform: none; white-space: nowrap; cursor: pointer;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:hover {\n color: var(--primary); background: transparent; box-shadow: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link::before {\n content: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:focus-visible {\n color: var(--primary); background: transparent; box-shadow: none;\n outline: 2px solid var(--primary); outline-offset: 2px;\n }\n @container power-preferences (max-width:660px) { .power-preferences-section-links { font-size:12px; } }\n .freelens-power-preferences section[id] { scroll-margin-top: 16px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nconst sectionLinks = [\n { id: \"safety\", title: \"Safety\", icon: \"lock_outline\" },\n { id: \"appearance\", title: \"Appearance\", icon: \"palette\" },\n { id: \"monitoring\", title: \"Monitoring\", icon: \"show_chart\" },\n { id: \"logs\", title: \"Logs\", icon: \"subject\" },\n { id: \"shell\", title: \"Shell\", icon: \"vpn_key\" },\n { id: \"ai\", title: \"AI\", icon: \"chat_bubble_outline\" },\n { id: \"dashboard\", title: \"Dashboard\", icon: \"dashboard\" },\n];\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <nav className=\"power-preferences-section-links\" aria-label=\"Settings sections\">\n {sectionLinks.map(({ id, title, icon }) => (\n <Renderer.Component.Button\n key={id}\n className=\"power-settings-section-link\"\n aria-label={title}\n title={`Jump to ${title} settings`}\n onClick={(event) => {\n event.preventDefault();\n const section = document.getElementById(`freelens-power-${id}-section`);\n requestAnimationFrame(() => {\n if (!section?.isConnected) return;\n section.focus({ preventScroll: true });\n section.scrollIntoView({ block: \"start\", behavior: \"instant\" });\n });\n }}\n >\n <Renderer.Component.Icon material={icon} size={16} /> {title}\n </Renderer.Component.Button>\n ))}\n </nav>\n <section id=\"freelens-power-safety-section\" tabIndex={-1} aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section id=\"freelens-power-appearance-section\" tabIndex={-1} aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", marginTop: 20 }}>\n <Renderer.Component.Button\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => Renderer.Navigation.navigate(`/extension/${EXTENSION_ID}/cluster-icons`)}\n title=\"Create matching icons for your saved clusters\"\n >\n <Renderer.Component.Icon material=\"palette\" size={16} /> Cluster icons\n </Renderer.Component.Button>\n </div>\n </section>\n <section id=\"freelens-power-monitoring-section\" tabIndex={-1} aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section id=\"freelens-power-logs-section\" tabIndex={-1} aria-labelledby=\"freelens-power-logs-title\">\n <h3 id=\"freelens-power-logs-title\">\n <Renderer.Component.Icon material=\"subject\" size={20} /> Power Logs\n </h3>\n <LogsPreferences />\n </section>\n <section id=\"freelens-power-shell-section\" tabIndex={-1} aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section id=\"freelens-power-ai-section\" tabIndex={-1} aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section id=\"freelens-power-dashboard-section\" tabIndex={-1} aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/renderer/resource-relationships.css.ts
|
|
2
2
|
var resourceRelationshipsStyles = `
|
|
3
|
-
.power-relationships{height:100%;overflow:auto;box-sizing:border-box;min-width:0;padding:24px;max-width:1550px;margin:auto;color:var(--textColorPrimary)}.power-relationships h2{margin:0}.power-relationships .page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:8px}.power-relationships .intro{color:var(--textColorSecondary);max-width:900px;line-height:1.6}.power-relationships .controls{display:flex;gap:24px;align-items:end;flex-wrap:wrap;margin:24px 0}.power-relationships .control{min-width:200px;flex:1;max-width:340px}.power-relationships .control>span{display:block;font-size:12px;margin-bottom:8px;color:var(--textColorSecondary)}.power-relationships button{min-height:32px;cursor:pointer}.power-relationships .refresh{background:transparent;border:1px solid var(--borderColor);border-radius:5px;padding:5px 10px;color:var(--textColorPrimary);display:flex;align-items:center;gap:8px}.power-relationships .notice{padding:14px 16px;background:var(--contentColor);border:1px solid var(--borderColor);border-radius:7px;margin:16px 0;line-height:1.6}.power-relationships .warning{color:var(--colorWarning)}.power-relationships .healthy{color:var(--colorOk)}.power-relationships .neutral{color:var(--textColorSecondary)}.power-relationships .graph-scroll{min-width:0;max-width:100%;overflow:auto;margin-top:24px}.power-relationships .graph{min-width:1000px;display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));column-gap:64px;row-gap:16px;position:relative;padding:6px 2px 56px}.power-relationships .graph.hide-upstreams{min-width:740px;grid-template-columns:repeat(3,minmax(180px,1fr))}.power-relationships .graph-option{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex-shrink:0;min-height:32px;padding:5px 10px;border:1px solid var(--borderColor);border-radius:5px;background:transparent;color:var(--textColorPrimary);font:inherit;cursor:pointer;transition:background-color .15s,border-color .15s}.power-relationships .graph-option[aria-pressed="true"]{background:color-mix(in srgb,var(--primary) 14%,var(--contentColor));border-color:var(--primary);color:var(--primary)}.power-relationships .graph-option:hover,.power-relationships .refresh:hover{background:color-mix(in srgb,var(--primary) 10%,var(--contentColor))}.power-relationships .graph-option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-relationships .column{position:relative;min-width:0;display:grid;grid-row:1/-1;grid-template-rows:subgrid}.power-relationships .column>h3{font-size:13px;margin:0;color:var(--textColorSecondary);font-weight:500}.power-relationships .card{background:var(--contentColor);border:1px solid var(--borderColor);border-radius:8px;padding:14px;margin:0;position:relative;z-index:1;overflow-wrap:anywhere}.power-relationships .card-kind{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-name{font-size:14px;font-weight:600;color:var(--textColorPrimary);text-align:left;background:transparent;border:0;padding:0;max-width:100%}.power-relationships .resource-name:hover{color:var(--primary)}.power-relationships .card p{font-size:12px;line-height:1.5;margin:6px 0 0}.power-relationships .relation-label{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-connections{position:absolute;inset:0;overflow:visible;pointer-events:none;color:var(--textColorSecondary)}.power-relationships .connection{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;opacity:.55;transition:opacity .15s,stroke .15s,stroke-width .15s}.power-relationships .connection.highlighted{opacity:1;stroke:var(--primary);stroke-width:2.5}.power-relationships .connection.dimmed{opacity:.12}.power-relationships .scope{max-width:68ch;margin-top:8px;color:var(--textColorSecondary);font-size:12px;line-height:1.6}.power-relationships .scope>span{display:block;margin-top:3px}.power-relationships details{margin-top:16px}.power-relationships summary{cursor:pointer;min-height:32px}.power-relationships .edge-list{columns:2;line-height:1.7;font-size:12px;list-style:none;padding:0}.power-relationships .empty{padding:28px;border:1px dashed var(--borderColor);border-radius:8px;color:var(--textColorSecondary);text-align:center}.power-relationships .relationship-summary{padding:16px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}.power-relationships .ports{margin-left:auto;justify-content:flex-end;display:flex;gap:12px;flex-wrap:wrap;font-size:12px}.power-relationships .ports span{padding:4px 8px;border-radius:4px;background:var(--contentColor);border:1px solid var(--borderColor)}@media(max-width:900px){.power-relationships{padding:16px}.power-relationships .controls{gap:16px}.power-relationships .edge-list{columns:1}}`;
|
|
3
|
+
.power-relationships{height:100%;overflow:auto;box-sizing:border-box;min-width:0;padding:24px;max-width:1550px;margin:auto;color:var(--textColorPrimary)}.power-relationships h2{margin:0}.power-relationships .page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:8px}.power-relationships .intro{color:var(--textColorSecondary);max-width:900px;line-height:1.6}.power-relationships .controls{display:flex;gap:24px;align-items:end;flex-wrap:wrap;margin:24px 0}.power-relationships .control{min-width:200px;flex:1;max-width:340px}.power-relationships .control>span{display:block;font-size:12px;margin-bottom:8px;color:var(--textColorSecondary)}.power-relationships button{min-height:32px;cursor:pointer}.power-relationships .refresh{background:transparent;border:1px solid var(--borderColor);border-radius:5px;padding:5px 10px;color:var(--textColorPrimary);display:flex;align-items:center;gap:8px}.power-relationships .notice{padding:14px 16px;background:var(--contentColor);border:1px solid var(--borderColor);border-radius:7px;margin:16px 0;line-height:1.6}.power-relationships .warning{color:var(--colorWarning)}.power-relationships .healthy{color:var(--colorOk)}.power-relationships .neutral{color:var(--textColorSecondary)}.power-relationships .graph-scroll{min-width:0;max-width:100%;overflow:auto;margin-top:24px}.power-relationships .graph{min-width:1000px;display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));column-gap:64px;row-gap:16px;position:relative;padding:6px 2px 56px}.power-relationships .graph.upstream-gutter{padding-left:42px}.power-relationships .gateway-evidence{font-size:11px}.power-relationships .gateway-evidence summary{min-height:24px}.power-relationships .graph.hide-upstreams{min-width:740px;grid-template-columns:repeat(3,minmax(180px,1fr))}.power-relationships .graph-option{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex-shrink:0;min-height:32px;padding:5px 10px;border:1px solid var(--borderColor);border-radius:5px;background:transparent;color:var(--textColorPrimary);font:inherit;cursor:pointer;transition:background-color .15s,border-color .15s}.power-relationships .graph-option[aria-pressed="true"]{background:color-mix(in srgb,var(--primary) 14%,var(--contentColor));border-color:var(--primary);color:var(--primary)}.power-relationships .graph-option:hover,.power-relationships .refresh:hover{background:color-mix(in srgb,var(--primary) 10%,var(--contentColor))}.power-relationships .graph-option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-relationships .column{position:relative;min-width:0;display:grid;grid-row:1/-1;grid-template-rows:subgrid}.power-relationships .column>h3{font-size:13px;margin:0;color:var(--textColorSecondary);font-weight:500}.power-relationships .card{background:var(--contentColor);border:1px solid var(--borderColor);border-radius:8px;padding:14px;margin:0;position:relative;z-index:1;overflow-wrap:anywhere}.power-relationships .card-kind{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-name{font-size:14px;font-weight:600;color:var(--textColorPrimary);text-align:left;background:transparent;border:0;padding:0;max-width:100%}.power-relationships .resource-name:hover{color:var(--primary)}.power-relationships .card p{font-size:12px;line-height:1.5;margin:6px 0 0}.power-relationships .relation-label{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-connections{position:absolute;inset:0;overflow:visible;pointer-events:none;color:var(--textColorSecondary)}.power-relationships .connection{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;opacity:.55;transition:opacity .15s,stroke .15s,stroke-width .15s}.power-relationships .connection.highlighted{opacity:1;stroke:var(--primary);stroke-width:2.5}.power-relationships .connection.dimmed{opacity:.12}.power-relationships .scope{max-width:68ch;margin-top:8px;color:var(--textColorSecondary);font-size:12px;line-height:1.6}.power-relationships .scope>span{display:block;margin-top:3px}.power-relationships details{margin-top:16px}.power-relationships summary{cursor:pointer;min-height:32px}.power-relationships .edge-list{columns:2;line-height:1.7;font-size:12px;list-style:none;padding:0}.power-relationships .empty{padding:28px;border:1px dashed var(--borderColor);border-radius:8px;color:var(--textColorSecondary);text-align:center}.power-relationships .relationship-summary{padding:16px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}.power-relationships .ports{margin-left:auto;justify-content:flex-end;display:flex;gap:12px;flex-wrap:wrap;font-size:12px}.power-relationships .ports span{padding:4px 8px;border-radius:4px;background:var(--contentColor);border:1px solid var(--borderColor)}@media(max-width:900px){.power-relationships{padding:16px}.power-relationships .controls{gap:16px}.power-relationships .edge-list{columns:1}}`;
|
|
4
4
|
//#endregion
|
|
5
5
|
exports.resourceRelationshipsStyles = resourceRelationshipsStyles;
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-relationships.css.js","names":[],"sources":["../../src/renderer/resource-relationships.css.ts"],"sourcesContent":["export const resourceRelationshipsStyles = `\n.power-relationships{height:100%;overflow:auto;box-sizing:border-box;min-width:0;padding:24px;max-width:1550px;margin:auto;color:var(--textColorPrimary)}.power-relationships h2{margin:0}.power-relationships .page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:8px}.power-relationships .intro{color:var(--textColorSecondary);max-width:900px;line-height:1.6}.power-relationships .controls{display:flex;gap:24px;align-items:end;flex-wrap:wrap;margin:24px 0}.power-relationships .control{min-width:200px;flex:1;max-width:340px}.power-relationships .control>span{display:block;font-size:12px;margin-bottom:8px;color:var(--textColorSecondary)}.power-relationships button{min-height:32px;cursor:pointer}.power-relationships .refresh{background:transparent;border:1px solid var(--borderColor);border-radius:5px;padding:5px 10px;color:var(--textColorPrimary);display:flex;align-items:center;gap:8px}.power-relationships .notice{padding:14px 16px;background:var(--contentColor);border:1px solid var(--borderColor);border-radius:7px;margin:16px 0;line-height:1.6}.power-relationships .warning{color:var(--colorWarning)}.power-relationships .healthy{color:var(--colorOk)}.power-relationships .neutral{color:var(--textColorSecondary)}.power-relationships .graph-scroll{min-width:0;max-width:100%;overflow:auto;margin-top:24px}.power-relationships .graph{min-width:1000px;display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));column-gap:64px;row-gap:16px;position:relative;padding:6px 2px 56px}.power-relationships .graph.hide-upstreams{min-width:740px;grid-template-columns:repeat(3,minmax(180px,1fr))}.power-relationships .graph-option{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex-shrink:0;min-height:32px;padding:5px 10px;border:1px solid var(--borderColor);border-radius:5px;background:transparent;color:var(--textColorPrimary);font:inherit;cursor:pointer;transition:background-color .15s,border-color .15s}.power-relationships .graph-option[aria-pressed=\"true\"]{background:color-mix(in srgb,var(--primary) 14%,var(--contentColor));border-color:var(--primary);color:var(--primary)}.power-relationships .graph-option:hover,.power-relationships .refresh:hover{background:color-mix(in srgb,var(--primary) 10%,var(--contentColor))}.power-relationships .graph-option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-relationships .column{position:relative;min-width:0;display:grid;grid-row:1/-1;grid-template-rows:subgrid}.power-relationships .column>h3{font-size:13px;margin:0;color:var(--textColorSecondary);font-weight:500}.power-relationships .card{background:var(--contentColor);border:1px solid var(--borderColor);border-radius:8px;padding:14px;margin:0;position:relative;z-index:1;overflow-wrap:anywhere}.power-relationships .card-kind{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-name{font-size:14px;font-weight:600;color:var(--textColorPrimary);text-align:left;background:transparent;border:0;padding:0;max-width:100%}.power-relationships .resource-name:hover{color:var(--primary)}.power-relationships .card p{font-size:12px;line-height:1.5;margin:6px 0 0}.power-relationships .relation-label{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-connections{position:absolute;inset:0;overflow:visible;pointer-events:none;color:var(--textColorSecondary)}.power-relationships .connection{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;opacity:.55;transition:opacity .15s,stroke .15s,stroke-width .15s}.power-relationships .connection.highlighted{opacity:1;stroke:var(--primary);stroke-width:2.5}.power-relationships .connection.dimmed{opacity:.12}.power-relationships .scope{max-width:68ch;margin-top:8px;color:var(--textColorSecondary);font-size:12px;line-height:1.6}.power-relationships .scope>span{display:block;margin-top:3px}.power-relationships details{margin-top:16px}.power-relationships summary{cursor:pointer;min-height:32px}.power-relationships .edge-list{columns:2;line-height:1.7;font-size:12px;list-style:none;padding:0}.power-relationships .empty{padding:28px;border:1px dashed var(--borderColor);border-radius:8px;color:var(--textColorSecondary);text-align:center}.power-relationships .relationship-summary{padding:16px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}.power-relationships .ports{margin-left:auto;justify-content:flex-end;display:flex;gap:12px;flex-wrap:wrap;font-size:12px}.power-relationships .ports span{padding:4px 8px;border-radius:4px;background:var(--contentColor);border:1px solid var(--borderColor)}@media(max-width:900px){.power-relationships{padding:16px}.power-relationships .controls{gap:16px}.power-relationships .edge-list{columns:1}}`;\n"],"mappings":";AAAA,IAAa,8BAA8B"}
|
|
1
|
+
{"version":3,"file":"resource-relationships.css.js","names":[],"sources":["../../src/renderer/resource-relationships.css.ts"],"sourcesContent":["export const resourceRelationshipsStyles = `\n.power-relationships{height:100%;overflow:auto;box-sizing:border-box;min-width:0;padding:24px;max-width:1550px;margin:auto;color:var(--textColorPrimary)}.power-relationships h2{margin:0}.power-relationships .page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:8px}.power-relationships .intro{color:var(--textColorSecondary);max-width:900px;line-height:1.6}.power-relationships .controls{display:flex;gap:24px;align-items:end;flex-wrap:wrap;margin:24px 0}.power-relationships .control{min-width:200px;flex:1;max-width:340px}.power-relationships .control>span{display:block;font-size:12px;margin-bottom:8px;color:var(--textColorSecondary)}.power-relationships button{min-height:32px;cursor:pointer}.power-relationships .refresh{background:transparent;border:1px solid var(--borderColor);border-radius:5px;padding:5px 10px;color:var(--textColorPrimary);display:flex;align-items:center;gap:8px}.power-relationships .notice{padding:14px 16px;background:var(--contentColor);border:1px solid var(--borderColor);border-radius:7px;margin:16px 0;line-height:1.6}.power-relationships .warning{color:var(--colorWarning)}.power-relationships .healthy{color:var(--colorOk)}.power-relationships .neutral{color:var(--textColorSecondary)}.power-relationships .graph-scroll{min-width:0;max-width:100%;overflow:auto;margin-top:24px}.power-relationships .graph{min-width:1000px;display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));column-gap:64px;row-gap:16px;position:relative;padding:6px 2px 56px}.power-relationships .graph.upstream-gutter{padding-left:42px}.power-relationships .gateway-evidence{font-size:11px}.power-relationships .gateway-evidence summary{min-height:24px}.power-relationships .graph.hide-upstreams{min-width:740px;grid-template-columns:repeat(3,minmax(180px,1fr))}.power-relationships .graph-option{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex-shrink:0;min-height:32px;padding:5px 10px;border:1px solid var(--borderColor);border-radius:5px;background:transparent;color:var(--textColorPrimary);font:inherit;cursor:pointer;transition:background-color .15s,border-color .15s}.power-relationships .graph-option[aria-pressed=\"true\"]{background:color-mix(in srgb,var(--primary) 14%,var(--contentColor));border-color:var(--primary);color:var(--primary)}.power-relationships .graph-option:hover,.power-relationships .refresh:hover{background:color-mix(in srgb,var(--primary) 10%,var(--contentColor))}.power-relationships .graph-option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-relationships .column{position:relative;min-width:0;display:grid;grid-row:1/-1;grid-template-rows:subgrid}.power-relationships .column>h3{font-size:13px;margin:0;color:var(--textColorSecondary);font-weight:500}.power-relationships .card{background:var(--contentColor);border:1px solid var(--borderColor);border-radius:8px;padding:14px;margin:0;position:relative;z-index:1;overflow-wrap:anywhere}.power-relationships .card-kind{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-name{font-size:14px;font-weight:600;color:var(--textColorPrimary);text-align:left;background:transparent;border:0;padding:0;max-width:100%}.power-relationships .resource-name:hover{color:var(--primary)}.power-relationships .card p{font-size:12px;line-height:1.5;margin:6px 0 0}.power-relationships .relation-label{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-connections{position:absolute;inset:0;overflow:visible;pointer-events:none;color:var(--textColorSecondary)}.power-relationships .connection{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;opacity:.55;transition:opacity .15s,stroke .15s,stroke-width .15s}.power-relationships .connection.highlighted{opacity:1;stroke:var(--primary);stroke-width:2.5}.power-relationships .connection.dimmed{opacity:.12}.power-relationships .scope{max-width:68ch;margin-top:8px;color:var(--textColorSecondary);font-size:12px;line-height:1.6}.power-relationships .scope>span{display:block;margin-top:3px}.power-relationships details{margin-top:16px}.power-relationships summary{cursor:pointer;min-height:32px}.power-relationships .edge-list{columns:2;line-height:1.7;font-size:12px;list-style:none;padding:0}.power-relationships .empty{padding:28px;border:1px dashed var(--borderColor);border-radius:8px;color:var(--textColorSecondary);text-align:center}.power-relationships .relationship-summary{padding:16px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}.power-relationships .ports{margin-left:auto;justify-content:flex-end;display:flex;gap:12px;flex-wrap:wrap;font-size:12px}.power-relationships .ports span{padding:4px 8px;border-radius:4px;background:var(--contentColor);border:1px solid var(--borderColor)}@media(max-width:900px){.power-relationships{padding:16px}.power-relationships .controls{gap:16px}.power-relationships .edge-list{columns:1}}`;\n"],"mappings":";AAAA,IAAa,8BAA8B"}
|